force-3d-graph 1.3.6 → 1.3.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.
@@ -1,8 +1,8 @@
1
- var ot = Object.defineProperty;
2
- var nt = (h, e, s) => e in h ? ot(h, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : h[e] = s;
3
- var l = (h, e, s) => nt(h, typeof e != "symbol" ? e + "" : e, s);
4
- import * as y from "three";
5
- import { EventDispatcher as at, Vector3 as S, MOUSE as $, TOUCH as G, Spherical as ze, Quaternion as ke, Vector2 as k, Ray as rt, Plane as lt, MathUtils as ct } from "three";
1
+ var it = Object.defineProperty;
2
+ var ot = (d, e, s) => e in d ? it(d, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : d[e] = s;
3
+ var l = (d, e, s) => ot(d, typeof e != "symbol" ? e + "" : e, s);
4
+ import * as x from "three";
5
+ import { EventDispatcher as nt, Vector3 as S, MOUSE as j, TOUCH as $, Spherical as Se, Quaternion as ze, Vector2 as k, Ray as at, Plane as rt, MathUtils as lt } from "three";
6
6
  const P = {
7
7
  backgroundColor: 657930,
8
8
  cameraPosition: { x: 0, y: 0, z: 80 },
@@ -32,96 +32,96 @@ const P = {
32
32
  targetFPS: 60,
33
33
  maxVisibleNodes: 1e4
34
34
  };
35
- var X = /* @__PURE__ */ ((h) => (h[h.HIGH = 0] = "HIGH", h[h.MEDIUM = 1] = "MEDIUM", h[h.LOW = 2] = "LOW", h))(X || {});
36
- function dt() {
37
- const h = document.createElement("div");
38
- return h.id = "force-graph-3d-container", h.style.cssText = `
35
+ var _ = /* @__PURE__ */ ((d) => (d[d.HIGH = 0] = "HIGH", d[d.MEDIUM = 1] = "MEDIUM", d[d.LOW = 2] = "LOW", d))(_ || {});
36
+ function ct() {
37
+ const d = document.createElement("div");
38
+ return d.id = "force-graph-3d-container", d.style.cssText = `
39
39
  width: 100%;
40
40
  height: 100%;
41
41
  position: absolute;
42
42
  top: 0;
43
43
  left: 0;
44
44
  overflow: hidden;
45
- `, document.body.appendChild(h), h;
45
+ `, document.body.appendChild(d), d;
46
46
  }
47
- function ht(h) {
48
- return h && h instanceof HTMLElement ? h : (console.warn("[ForceGraph3D] No container provided, creating one automatically"), dt());
47
+ function ht(d) {
48
+ return d && d instanceof HTMLElement ? d : (console.warn("[ForceGraph3D] No container provided, creating one automatically"), ct());
49
49
  }
50
- function Te(h) {
51
- const e = h.getBoundingClientRect();
50
+ function ke(d) {
51
+ const e = d.getBoundingClientRect();
52
52
  return {
53
53
  width: e.width || window.innerWidth,
54
54
  height: e.height || window.innerHeight
55
55
  };
56
56
  }
57
- function De(h) {
58
- if (!h || typeof h != "object")
57
+ function Fe(d) {
58
+ if (!d || typeof d != "object")
59
59
  return console.warn("[ForceGraph3D] Invalid node: must be an object"), !1;
60
- const e = h;
61
- return typeof e.id != "string" || e.id.trim() === "" ? (console.warn("[ForceGraph3D] Invalid node: id must be a non-empty string"), !1) : typeof e.label != "string" ? (console.warn("[ForceGraph3D] Invalid node: label must be a string"), !1) : e.color !== void 0 && typeof e.color != "number" ? (console.warn("[ForceGraph3D] Invalid node: color must be a number (hex)"), !1) : e.position !== void 0 && !gt(e.position) ? (console.warn("[ForceGraph3D] Invalid node: position must have x, y, z numbers"), !1) : !0;
60
+ const e = d;
61
+ return typeof e.id != "string" || e.id.trim() === "" ? (console.warn("[ForceGraph3D] Invalid node: id must be a non-empty string"), !1) : typeof e.label != "string" ? (console.warn("[ForceGraph3D] Invalid node: label must be a string"), !1) : e.color !== void 0 && typeof e.color != "number" ? (console.warn("[ForceGraph3D] Invalid node: color must be a number (hex)"), !1) : e.position !== void 0 && !pt(e.position) ? (console.warn("[ForceGraph3D] Invalid node: position must have x, y, z numbers"), !1) : !0;
62
62
  }
63
- function He(h) {
64
- if (!h || typeof h != "object")
63
+ function De(d) {
64
+ if (!d || typeof d != "object")
65
65
  return console.warn("[ForceGraph3D] Invalid edge: must be an object"), !1;
66
- const e = h;
66
+ const e = d;
67
67
  return typeof e.source != "string" || e.source.trim() === "" ? (console.warn("[ForceGraph3D] Invalid edge: source must be a non-empty string"), !1) : typeof e.target != "string" || e.target.trim() === "" ? (console.warn("[ForceGraph3D] Invalid edge: target must be a non-empty string"), !1) : !0;
68
68
  }
69
- function pt(h) {
70
- return typeof h != "string" || h.trim() === "" ? (console.warn("[ForceGraph3D] Invalid node ID: must be a non-empty string"), !1) : !0;
69
+ function dt(d) {
70
+ return typeof d != "string" || d.trim() === "" ? (console.warn("[ForceGraph3D] Invalid node ID: must be a non-empty string"), !1) : !0;
71
71
  }
72
- function gt(h) {
73
- if (!h || typeof h != "object") return !1;
74
- const e = h;
72
+ function pt(d) {
73
+ if (!d || typeof d != "object") return !1;
74
+ const e = d;
75
75
  return typeof e.x == "number" && typeof e.y == "number" && typeof e.z == "number";
76
76
  }
77
- function H(h, e) {
78
- return h === e ? `${h}-${e}` : h < e ? `${h}-${e}` : `${e}-${h}`;
77
+ function Dt(d, e) {
78
+ return d === e ? `${d}-${e}` : d < e ? `${d}-${e}` : `${e}-${d}`;
79
79
  }
80
- const Pe = { type: "change" }, ce = { type: "start" }, Le = { type: "end" }, J = new rt(), Re = new lt(), ut = Math.cos(70 * ct.DEG2RAD);
81
- class ft extends at {
80
+ const Te = { type: "change" }, le = { type: "start" }, Pe = { type: "end" }, Q = new at(), Re = new rt(), gt = Math.cos(70 * lt.DEG2RAD);
81
+ class ut extends nt {
82
82
  constructor(e, s) {
83
- super(), this.object = e, this.domElement = s, this.domElement.style.touchAction = "none", this.enabled = !0, this.target = new S(), this.cursor = new S(), this.minDistance = 0, this.maxDistance = 1 / 0, this.minZoom = 0, this.maxZoom = 1 / 0, this.minTargetRadius = 0, this.maxTargetRadius = 1 / 0, this.minPolarAngle = 0, this.maxPolarAngle = Math.PI, this.minAzimuthAngle = -1 / 0, this.maxAzimuthAngle = 1 / 0, this.enableDamping = !1, this.dampingFactor = 0.05, this.enableZoom = !0, this.zoomSpeed = 1, this.enableRotate = !0, this.rotateSpeed = 1, this.enablePan = !0, this.panSpeed = 1, this.screenSpacePanning = !0, this.keyPanSpeed = 7, this.zoomToCursor = !1, this.autoRotate = !1, this.autoRotateSpeed = 2, this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" }, this.mouseButtons = { LEFT: $.ROTATE, MIDDLE: $.DOLLY, RIGHT: $.PAN }, this.touches = { ONE: G.ROTATE, TWO: G.DOLLY_PAN }, this.target0 = this.target.clone(), this.position0 = this.object.position.clone(), this.zoom0 = this.object.zoom, this._domElementKeyEvents = null, this.getPolarAngle = function() {
83
+ super(), this.object = e, this.domElement = s, this.domElement.style.touchAction = "none", this.enabled = !0, this.target = new S(), this.cursor = new S(), this.minDistance = 0, this.maxDistance = 1 / 0, this.minZoom = 0, this.maxZoom = 1 / 0, this.minTargetRadius = 0, this.maxTargetRadius = 1 / 0, this.minPolarAngle = 0, this.maxPolarAngle = Math.PI, this.minAzimuthAngle = -1 / 0, this.maxAzimuthAngle = 1 / 0, this.enableDamping = !1, this.dampingFactor = 0.05, this.enableZoom = !0, this.zoomSpeed = 1, this.enableRotate = !0, this.rotateSpeed = 1, this.enablePan = !0, this.panSpeed = 1, this.screenSpacePanning = !0, this.keyPanSpeed = 7, this.zoomToCursor = !1, this.autoRotate = !1, this.autoRotateSpeed = 2, this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" }, this.mouseButtons = { LEFT: j.ROTATE, MIDDLE: j.DOLLY, RIGHT: j.PAN }, this.touches = { ONE: $.ROTATE, TWO: $.DOLLY_PAN }, this.target0 = this.target.clone(), this.position0 = this.object.position.clone(), this.zoom0 = this.object.zoom, this._domElementKeyEvents = null, this.getPolarAngle = function() {
84
84
  return r.phi;
85
85
  }, this.getAzimuthalAngle = function() {
86
86
  return r.theta;
87
87
  }, this.getDistance = function() {
88
88
  return this.object.position.distanceTo(this.target);
89
- }, this.listenToKeyEvents = function(n) {
90
- n.addEventListener("keydown", re), this._domElementKeyEvents = n;
89
+ }, this.listenToKeyEvents = function(a) {
90
+ a.addEventListener("keydown", ae), this._domElementKeyEvents = a;
91
91
  }, this.stopListenToKeyEvents = function() {
92
- this._domElementKeyEvents.removeEventListener("keydown", re), this._domElementKeyEvents = null;
92
+ this._domElementKeyEvents.removeEventListener("keydown", ae), this._domElementKeyEvents = null;
93
93
  }, this.saveState = function() {
94
94
  t.target0.copy(t.target), t.position0.copy(t.object.position), t.zoom0 = t.object.zoom;
95
95
  }, this.reset = function() {
96
- t.target.copy(t.target0), t.object.position.copy(t.position0), t.object.zoom = t.zoom0, t.object.updateProjectionMatrix(), t.dispatchEvent(Pe), t.update(), o = i.NONE;
96
+ t.target.copy(t.target0), t.object.position.copy(t.position0), t.object.zoom = t.zoom0, t.object.updateProjectionMatrix(), t.dispatchEvent(Te), t.update(), o = i.NONE;
97
97
  }, this.update = function() {
98
- const n = new S(), g = new ke().setFromUnitVectors(e.up, new S(0, 1, 0)), v = g.clone().invert(), w = new S(), C = new ke(), F = new S(), z = 2 * Math.PI;
99
- return function(it = null) {
100
- const Se = t.object.position;
101
- n.copy(Se).sub(t.target), n.applyQuaternion(g), r.setFromVector3(n), t.autoRotate && o === i.NONE && B(Ae(it)), t.enableDamping ? (r.theta += c.theta * t.dampingFactor, r.phi += c.phi * t.dampingFactor) : (r.theta += c.theta, r.phi += c.phi);
102
- let R = t.minAzimuthAngle, I = t.maxAzimuthAngle;
103
- isFinite(R) && isFinite(I) && (R < -Math.PI ? R += z : R > Math.PI && (R -= z), I < -Math.PI ? I += z : I > Math.PI && (I -= z), R <= I ? r.theta = Math.max(R, Math.min(I, r.theta)) : r.theta = r.theta > (R + I) / 2 ? Math.max(R, r.theta) : Math.min(I, r.theta)), r.phi = Math.max(t.minPolarAngle, Math.min(t.maxPolarAngle, r.phi)), r.makeSafe(), t.enableDamping === !0 ? t.target.addScaledVector(p, t.dampingFactor) : t.target.add(p), t.target.sub(t.cursor), t.target.clampLength(t.minTargetRadius, t.maxTargetRadius), t.target.add(t.cursor), t.zoomToCursor && D || t.object.isOrthographicCamera ? r.radius = ne(r.radius) : r.radius = ne(r.radius * d), n.setFromSpherical(r), n.applyQuaternion(v), Se.copy(t.target).add(n), t.object.lookAt(t.target), t.enableDamping === !0 ? (c.theta *= 1 - t.dampingFactor, c.phi *= 1 - t.dampingFactor, p.multiplyScalar(1 - t.dampingFactor)) : (c.set(0, 0, 0), p.set(0, 0, 0));
104
- let le = !1;
98
+ const a = new S(), g = new ze().setFromUnitVectors(e.up, new S(0, 1, 0)), v = g.clone().invert(), M = new S(), C = new ze(), F = new S(), z = 2 * Math.PI;
99
+ return function(st = null) {
100
+ const Ne = t.object.position;
101
+ a.copy(Ne).sub(t.target), a.applyQuaternion(g), r.setFromVector3(a), t.autoRotate && o === i.NONE && Y(He(st)), t.enableDamping ? (r.theta += h.theta * t.dampingFactor, r.phi += h.phi * t.dampingFactor) : (r.theta += h.theta, r.phi += h.phi);
102
+ let L = t.minAzimuthAngle, I = t.maxAzimuthAngle;
103
+ isFinite(L) && isFinite(I) && (L < -Math.PI ? L += z : L > Math.PI && (L -= z), I < -Math.PI ? I += z : I > Math.PI && (I -= z), L <= I ? r.theta = Math.max(L, Math.min(I, r.theta)) : r.theta = r.theta > (L + I) / 2 ? Math.max(L, r.theta) : Math.min(I, r.theta)), r.phi = Math.max(t.minPolarAngle, Math.min(t.maxPolarAngle, r.phi)), r.makeSafe(), t.enableDamping === !0 ? t.target.addScaledVector(p, t.dampingFactor) : t.target.add(p), t.target.sub(t.cursor), t.target.clampLength(t.minTargetRadius, t.maxTargetRadius), t.target.add(t.cursor), t.zoomToCursor && D || t.object.isOrthographicCamera ? r.radius = oe(r.radius) : r.radius = oe(r.radius * c), a.setFromSpherical(r), a.applyQuaternion(v), Ne.copy(t.target).add(a), t.object.lookAt(t.target), t.enableDamping === !0 ? (h.theta *= 1 - t.dampingFactor, h.phi *= 1 - t.dampingFactor, p.multiplyScalar(1 - t.dampingFactor)) : (h.set(0, 0, 0), p.set(0, 0, 0));
104
+ let re = !1;
105
105
  if (t.zoomToCursor && D) {
106
- let U = null;
106
+ let K = null;
107
107
  if (t.object.isPerspectiveCamera) {
108
- const _ = n.length();
109
- U = ne(_ * d);
110
- const Q = _ - U;
111
- t.object.position.addScaledVector(Y, Q), t.object.updateMatrixWorld();
108
+ const U = a.length();
109
+ K = oe(U * c);
110
+ const Z = U - K;
111
+ t.object.position.addScaledVector(G, Z), t.object.updateMatrixWorld();
112
112
  } else if (t.object.isOrthographicCamera) {
113
- const _ = new S(T.x, T.y, 0);
114
- _.unproject(t.object), t.object.zoom = Math.max(t.minZoom, Math.min(t.maxZoom, t.object.zoom / d)), t.object.updateProjectionMatrix(), le = !0;
115
- const Q = new S(T.x, T.y, 0);
116
- Q.unproject(t.object), t.object.position.sub(Q).add(_), t.object.updateMatrixWorld(), U = n.length();
113
+ const U = new S(T.x, T.y, 0);
114
+ U.unproject(t.object), t.object.zoom = Math.max(t.minZoom, Math.min(t.maxZoom, t.object.zoom / c)), t.object.updateProjectionMatrix(), re = !0;
115
+ const Z = new S(T.x, T.y, 0);
116
+ Z.unproject(t.object), t.object.position.sub(Z).add(U), t.object.updateMatrixWorld(), K = a.length();
117
117
  } else
118
118
  console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."), t.zoomToCursor = !1;
119
- U !== null && (this.screenSpacePanning ? t.target.set(0, 0, -1).transformDirection(t.object.matrix).multiplyScalar(U).add(t.object.position) : (J.origin.copy(t.object.position), J.direction.set(0, 0, -1).transformDirection(t.object.matrix), Math.abs(t.object.up.dot(J.direction)) < ut ? e.lookAt(t.target) : (Re.setFromNormalAndCoplanarPoint(t.object.up, t.target), J.intersectPlane(Re, t.target))));
120
- } else t.object.isOrthographicCamera && (t.object.zoom = Math.max(t.minZoom, Math.min(t.maxZoom, t.object.zoom / d)), t.object.updateProjectionMatrix(), le = !0);
121
- return d = 1, D = !1, le || w.distanceToSquared(t.object.position) > a || 8 * (1 - C.dot(t.object.quaternion)) > a || F.distanceToSquared(t.target) > 0 ? (t.dispatchEvent(Pe), w.copy(t.object.position), C.copy(t.object.quaternion), F.copy(t.target), !0) : !1;
119
+ K !== null && (this.screenSpacePanning ? t.target.set(0, 0, -1).transformDirection(t.object.matrix).multiplyScalar(K).add(t.object.position) : (Q.origin.copy(t.object.position), Q.direction.set(0, 0, -1).transformDirection(t.object.matrix), Math.abs(t.object.up.dot(Q.direction)) < gt ? e.lookAt(t.target) : (Re.setFromNormalAndCoplanarPoint(t.object.up, t.target), Q.intersectPlane(Re, t.target))));
120
+ } else t.object.isOrthographicCamera && (t.object.zoom = Math.max(t.minZoom, Math.min(t.maxZoom, t.object.zoom / c)), t.object.updateProjectionMatrix(), re = !0);
121
+ return c = 1, D = !1, re || M.distanceToSquared(t.object.position) > n || 8 * (1 - C.dot(t.object.quaternion)) > n || F.distanceToSquared(t.target) > 0 ? (t.dispatchEvent(Te), M.copy(t.object.position), C.copy(t.object.quaternion), F.copy(t.target), !0) : !1;
122
122
  };
123
123
  }(), this.dispose = function() {
124
- t.domElement.removeEventListener("contextmenu", Ce), t.domElement.removeEventListener("pointerdown", Me), t.domElement.removeEventListener("pointercancel", K), t.domElement.removeEventListener("wheel", we), t.domElement.removeEventListener("pointermove", ae), t.domElement.removeEventListener("pointerup", K), t._domElementKeyEvents !== null && (t._domElementKeyEvents.removeEventListener("keydown", re), t._domElementKeyEvents = null);
124
+ t.domElement.removeEventListener("contextmenu", Ee), t.domElement.removeEventListener("pointerdown", ve), t.domElement.removeEventListener("pointercancel", B), t.domElement.removeEventListener("wheel", we), t.domElement.removeEventListener("pointermove", ne), t.domElement.removeEventListener("pointerup", B), t._domElementKeyEvents !== null && (t._domElementKeyEvents.removeEventListener("keydown", ae), t._domElementKeyEvents = null);
125
125
  };
126
126
  const t = this, i = {
127
127
  NONE: -1,
@@ -134,174 +134,174 @@ class ft extends at {
134
134
  TOUCH_DOLLY_ROTATE: 6
135
135
  };
136
136
  let o = i.NONE;
137
- const a = 1e-6, r = new ze(), c = new ze();
138
- let d = 1;
139
- const p = new S(), x = new k(), m = new k(), u = new k(), f = new k(), b = new k(), M = new k(), N = new k(), O = new k(), L = new k(), Y = new S(), T = new k();
137
+ const n = 1e-6, r = new Se(), h = new Se();
138
+ let c = 1;
139
+ const p = new S(), f = new k(), m = new k(), u = new k(), y = new k(), b = new k(), w = new k(), N = new k(), O = new k(), R = new k(), G = new S(), T = new k();
140
140
  let D = !1;
141
- const E = [], q = {};
142
- let se = !1;
143
- function Ae(n) {
144
- return n !== null ? 2 * Math.PI / 60 * t.autoRotateSpeed * n : 2 * Math.PI / 60 / 60 * t.autoRotateSpeed;
141
+ const E = [], V = {};
142
+ let te = !1;
143
+ function He(a) {
144
+ return a !== null ? 2 * Math.PI / 60 * t.autoRotateSpeed * a : 2 * Math.PI / 60 / 60 * t.autoRotateSpeed;
145
145
  }
146
- function W(n) {
147
- const g = Math.abs(n * 0.01);
146
+ function q(a) {
147
+ const g = Math.abs(a * 0.01);
148
148
  return Math.pow(0.95, t.zoomSpeed * g);
149
149
  }
150
- function B(n) {
151
- c.theta -= n;
150
+ function Y(a) {
151
+ h.theta -= a;
152
152
  }
153
- function Z(n) {
154
- c.phi -= n;
153
+ function W(a) {
154
+ h.phi -= a;
155
155
  }
156
- const de = function() {
157
- const n = new S();
158
- return function(v, w) {
159
- n.setFromMatrixColumn(w, 0), n.multiplyScalar(-v), p.add(n);
156
+ const ce = function() {
157
+ const a = new S();
158
+ return function(v, M) {
159
+ a.setFromMatrixColumn(M, 0), a.multiplyScalar(-v), p.add(a);
160
160
  };
161
161
  }(), he = function() {
162
- const n = new S();
163
- return function(v, w) {
164
- t.screenSpacePanning === !0 ? n.setFromMatrixColumn(w, 1) : (n.setFromMatrixColumn(w, 0), n.crossVectors(t.object.up, n)), n.multiplyScalar(v), p.add(n);
162
+ const a = new S();
163
+ return function(v, M) {
164
+ t.screenSpacePanning === !0 ? a.setFromMatrixColumn(M, 1) : (a.setFromMatrixColumn(M, 0), a.crossVectors(t.object.up, a)), a.multiplyScalar(v), p.add(a);
165
165
  };
166
- }(), A = function() {
167
- const n = new S();
168
- return function(v, w) {
166
+ }(), H = function() {
167
+ const a = new S();
168
+ return function(v, M) {
169
169
  const C = t.domElement;
170
170
  if (t.object.isPerspectiveCamera) {
171
171
  const F = t.object.position;
172
- n.copy(F).sub(t.target);
173
- let z = n.length();
174
- z *= Math.tan(t.object.fov / 2 * Math.PI / 180), de(2 * v * z / C.clientHeight, t.object.matrix), he(2 * w * z / C.clientHeight, t.object.matrix);
175
- } else t.object.isOrthographicCamera ? (de(v * (t.object.right - t.object.left) / t.object.zoom / C.clientWidth, t.object.matrix), he(w * (t.object.top - t.object.bottom) / t.object.zoom / C.clientHeight, t.object.matrix)) : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."), t.enablePan = !1);
172
+ a.copy(F).sub(t.target);
173
+ let z = a.length();
174
+ z *= Math.tan(t.object.fov / 2 * Math.PI / 180), ce(2 * v * z / C.clientHeight, t.object.matrix), he(2 * M * z / C.clientHeight, t.object.matrix);
175
+ } else t.object.isOrthographicCamera ? (ce(v * (t.object.right - t.object.left) / t.object.zoom / C.clientWidth, t.object.matrix), he(M * (t.object.top - t.object.bottom) / t.object.zoom / C.clientHeight, t.object.matrix)) : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."), t.enablePan = !1);
176
176
  };
177
177
  }();
178
- function ie(n) {
179
- t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? d /= n : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
178
+ function se(a) {
179
+ t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? c /= a : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
180
180
  }
181
- function pe(n) {
182
- t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? d *= n : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
181
+ function de(a) {
182
+ t.object.isPerspectiveCamera || t.object.isOrthographicCamera ? c *= a : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), t.enableZoom = !1);
183
183
  }
184
- function oe(n, g) {
184
+ function ie(a, g) {
185
185
  if (!t.zoomToCursor)
186
186
  return;
187
187
  D = !0;
188
- const v = t.domElement.getBoundingClientRect(), w = n - v.left, C = g - v.top, F = v.width, z = v.height;
189
- T.x = w / F * 2 - 1, T.y = -(C / z) * 2 + 1, Y.set(T.x, T.y, 1).unproject(t.object).sub(t.object.position).normalize();
188
+ const v = t.domElement.getBoundingClientRect(), M = a - v.left, C = g - v.top, F = v.width, z = v.height;
189
+ T.x = M / F * 2 - 1, T.y = -(C / z) * 2 + 1, G.set(T.x, T.y, 1).unproject(t.object).sub(t.object.position).normalize();
190
190
  }
191
- function ne(n) {
192
- return Math.max(t.minDistance, Math.min(t.maxDistance, n));
191
+ function oe(a) {
192
+ return Math.max(t.minDistance, Math.min(t.maxDistance, a));
193
193
  }
194
- function ge(n) {
195
- x.set(n.clientX, n.clientY);
194
+ function pe(a) {
195
+ f.set(a.clientX, a.clientY);
196
196
  }
197
- function je(n) {
198
- oe(n.clientX, n.clientX), N.set(n.clientX, n.clientY);
197
+ function Ae(a) {
198
+ ie(a.clientX, a.clientX), N.set(a.clientX, a.clientY);
199
199
  }
200
- function ue(n) {
201
- f.set(n.clientX, n.clientY);
200
+ function ge(a) {
201
+ y.set(a.clientX, a.clientY);
202
202
  }
203
- function $e(n) {
204
- m.set(n.clientX, n.clientY), u.subVectors(m, x).multiplyScalar(t.rotateSpeed);
203
+ function je(a) {
204
+ m.set(a.clientX, a.clientY), u.subVectors(m, f).multiplyScalar(t.rotateSpeed);
205
205
  const g = t.domElement;
206
- B(2 * Math.PI * u.x / g.clientHeight), Z(2 * Math.PI * u.y / g.clientHeight), x.copy(m), t.update();
206
+ Y(2 * Math.PI * u.x / g.clientHeight), W(2 * Math.PI * u.y / g.clientHeight), f.copy(m), t.update();
207
207
  }
208
- function Ge(n) {
209
- O.set(n.clientX, n.clientY), L.subVectors(O, N), L.y > 0 ? ie(W(L.y)) : L.y < 0 && pe(W(L.y)), N.copy(O), t.update();
208
+ function $e(a) {
209
+ O.set(a.clientX, a.clientY), R.subVectors(O, N), R.y > 0 ? se(q(R.y)) : R.y < 0 && de(q(R.y)), N.copy(O), t.update();
210
210
  }
211
- function Ye(n) {
212
- b.set(n.clientX, n.clientY), M.subVectors(b, f).multiplyScalar(t.panSpeed), A(M.x, M.y), f.copy(b), t.update();
211
+ function Ge(a) {
212
+ b.set(a.clientX, a.clientY), w.subVectors(b, y).multiplyScalar(t.panSpeed), H(w.x, w.y), y.copy(b), t.update();
213
213
  }
214
- function Be(n) {
215
- oe(n.clientX, n.clientY), n.deltaY < 0 ? pe(W(n.deltaY)) : n.deltaY > 0 && ie(W(n.deltaY)), t.update();
214
+ function Ye(a) {
215
+ ie(a.clientX, a.clientY), a.deltaY < 0 ? de(q(a.deltaY)) : a.deltaY > 0 && se(q(a.deltaY)), t.update();
216
216
  }
217
- function Ke(n) {
217
+ function Be(a) {
218
218
  let g = !1;
219
- switch (n.code) {
219
+ switch (a.code) {
220
220
  case t.keys.UP:
221
- n.ctrlKey || n.metaKey || n.shiftKey ? Z(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(0, t.keyPanSpeed), g = !0;
221
+ a.ctrlKey || a.metaKey || a.shiftKey ? W(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : H(0, t.keyPanSpeed), g = !0;
222
222
  break;
223
223
  case t.keys.BOTTOM:
224
- n.ctrlKey || n.metaKey || n.shiftKey ? Z(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(0, -t.keyPanSpeed), g = !0;
224
+ a.ctrlKey || a.metaKey || a.shiftKey ? W(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : H(0, -t.keyPanSpeed), g = !0;
225
225
  break;
226
226
  case t.keys.LEFT:
227
- n.ctrlKey || n.metaKey || n.shiftKey ? B(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(t.keyPanSpeed, 0), g = !0;
227
+ a.ctrlKey || a.metaKey || a.shiftKey ? Y(2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : H(t.keyPanSpeed, 0), g = !0;
228
228
  break;
229
229
  case t.keys.RIGHT:
230
- n.ctrlKey || n.metaKey || n.shiftKey ? B(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : A(-t.keyPanSpeed, 0), g = !0;
230
+ a.ctrlKey || a.metaKey || a.shiftKey ? Y(-2 * Math.PI * t.rotateSpeed / t.domElement.clientHeight) : H(-t.keyPanSpeed, 0), g = !0;
231
231
  break;
232
232
  }
233
- g && (n.preventDefault(), t.update());
233
+ g && (a.preventDefault(), t.update());
234
234
  }
235
- function fe(n) {
235
+ function ue(a) {
236
236
  if (E.length === 1)
237
- x.set(n.pageX, n.pageY);
237
+ f.set(a.pageX, a.pageY);
238
238
  else {
239
- const g = j(n), v = 0.5 * (n.pageX + g.x), w = 0.5 * (n.pageY + g.y);
240
- x.set(v, w);
239
+ const g = A(a), v = 0.5 * (a.pageX + g.x), M = 0.5 * (a.pageY + g.y);
240
+ f.set(v, M);
241
241
  }
242
242
  }
243
- function me(n) {
243
+ function fe(a) {
244
244
  if (E.length === 1)
245
- f.set(n.pageX, n.pageY);
245
+ y.set(a.pageX, a.pageY);
246
246
  else {
247
- const g = j(n), v = 0.5 * (n.pageX + g.x), w = 0.5 * (n.pageY + g.y);
248
- f.set(v, w);
247
+ const g = A(a), v = 0.5 * (a.pageX + g.x), M = 0.5 * (a.pageY + g.y);
248
+ y.set(v, M);
249
249
  }
250
250
  }
251
- function ye(n) {
252
- const g = j(n), v = n.pageX - g.x, w = n.pageY - g.y, C = Math.sqrt(v * v + w * w);
251
+ function me(a) {
252
+ const g = A(a), v = a.pageX - g.x, M = a.pageY - g.y, C = Math.sqrt(v * v + M * M);
253
253
  N.set(0, C);
254
254
  }
255
- function Ue(n) {
256
- t.enableZoom && ye(n), t.enablePan && me(n);
255
+ function Ke(a) {
256
+ t.enableZoom && me(a), t.enablePan && fe(a);
257
257
  }
258
- function _e(n) {
259
- t.enableZoom && ye(n), t.enableRotate && fe(n);
258
+ function Ue(a) {
259
+ t.enableZoom && me(a), t.enableRotate && ue(a);
260
260
  }
261
- function xe(n) {
261
+ function ye(a) {
262
262
  if (E.length == 1)
263
- m.set(n.pageX, n.pageY);
263
+ m.set(a.pageX, a.pageY);
264
264
  else {
265
- const v = j(n), w = 0.5 * (n.pageX + v.x), C = 0.5 * (n.pageY + v.y);
266
- m.set(w, C);
265
+ const v = A(a), M = 0.5 * (a.pageX + v.x), C = 0.5 * (a.pageY + v.y);
266
+ m.set(M, C);
267
267
  }
268
- u.subVectors(m, x).multiplyScalar(t.rotateSpeed);
268
+ u.subVectors(m, f).multiplyScalar(t.rotateSpeed);
269
269
  const g = t.domElement;
270
- B(2 * Math.PI * u.x / g.clientHeight), Z(2 * Math.PI * u.y / g.clientHeight), x.copy(m);
270
+ Y(2 * Math.PI * u.x / g.clientHeight), W(2 * Math.PI * u.y / g.clientHeight), f.copy(m);
271
271
  }
272
- function be(n) {
272
+ function xe(a) {
273
273
  if (E.length === 1)
274
- b.set(n.pageX, n.pageY);
274
+ b.set(a.pageX, a.pageY);
275
275
  else {
276
- const g = j(n), v = 0.5 * (n.pageX + g.x), w = 0.5 * (n.pageY + g.y);
277
- b.set(v, w);
276
+ const g = A(a), v = 0.5 * (a.pageX + g.x), M = 0.5 * (a.pageY + g.y);
277
+ b.set(v, M);
278
278
  }
279
- M.subVectors(b, f).multiplyScalar(t.panSpeed), A(M.x, M.y), f.copy(b);
279
+ w.subVectors(b, y).multiplyScalar(t.panSpeed), H(w.x, w.y), y.copy(b);
280
280
  }
281
- function ve(n) {
282
- const g = j(n), v = n.pageX - g.x, w = n.pageY - g.y, C = Math.sqrt(v * v + w * w);
283
- O.set(0, C), L.set(0, Math.pow(O.y / N.y, t.zoomSpeed)), ie(L.y), N.copy(O);
284
- const F = (n.pageX + g.x) * 0.5, z = (n.pageY + g.y) * 0.5;
285
- oe(F, z);
281
+ function be(a) {
282
+ const g = A(a), v = a.pageX - g.x, M = a.pageY - g.y, C = Math.sqrt(v * v + M * M);
283
+ O.set(0, C), R.set(0, Math.pow(O.y / N.y, t.zoomSpeed)), se(R.y), N.copy(O);
284
+ const F = (a.pageX + g.x) * 0.5, z = (a.pageY + g.y) * 0.5;
285
+ ie(F, z);
286
286
  }
287
- function Xe(n) {
288
- t.enableZoom && ve(n), t.enablePan && be(n);
287
+ function _e(a) {
288
+ t.enableZoom && be(a), t.enablePan && xe(a);
289
289
  }
290
- function Ve(n) {
291
- t.enableZoom && ve(n), t.enableRotate && xe(n);
290
+ function Xe(a) {
291
+ t.enableZoom && be(a), t.enableRotate && ye(a);
292
292
  }
293
- function Me(n) {
294
- t.enabled !== !1 && (E.length === 0 && (t.domElement.setPointerCapture(n.pointerId), t.domElement.addEventListener("pointermove", ae), t.domElement.addEventListener("pointerup", K)), tt(n), n.pointerType === "touch" ? Je(n) : qe(n));
293
+ function ve(a) {
294
+ t.enabled !== !1 && (E.length === 0 && (t.domElement.setPointerCapture(a.pointerId), t.domElement.addEventListener("pointermove", ne), t.domElement.addEventListener("pointerup", B)), et(a), a.pointerType === "touch" ? Qe(a) : Ve(a));
295
295
  }
296
- function ae(n) {
297
- t.enabled !== !1 && (n.pointerType === "touch" ? et(n) : We(n));
296
+ function ne(a) {
297
+ t.enabled !== !1 && (a.pointerType === "touch" ? Je(a) : qe(a));
298
298
  }
299
- function K(n) {
300
- st(n), E.length === 0 && (t.domElement.releasePointerCapture(n.pointerId), t.domElement.removeEventListener("pointermove", ae), t.domElement.removeEventListener("pointerup", K)), t.dispatchEvent(Le), o = i.NONE;
299
+ function B(a) {
300
+ tt(a), E.length === 0 && (t.domElement.releasePointerCapture(a.pointerId), t.domElement.removeEventListener("pointermove", ne), t.domElement.removeEventListener("pointerup", B)), t.dispatchEvent(Pe), o = i.NONE;
301
301
  }
302
- function qe(n) {
302
+ function Ve(a) {
303
303
  let g;
304
- switch (n.button) {
304
+ switch (a.button) {
305
305
  case 0:
306
306
  g = t.mouseButtons.LEFT;
307
307
  break;
@@ -315,57 +315,57 @@ class ft extends at {
315
315
  g = -1;
316
316
  }
317
317
  switch (g) {
318
- case $.DOLLY:
318
+ case j.DOLLY:
319
319
  if (t.enableZoom === !1) return;
320
- je(n), o = i.DOLLY;
320
+ Ae(a), o = i.DOLLY;
321
321
  break;
322
- case $.ROTATE:
323
- if (n.ctrlKey || n.metaKey || n.shiftKey) {
322
+ case j.ROTATE:
323
+ if (a.ctrlKey || a.metaKey || a.shiftKey) {
324
324
  if (t.enablePan === !1) return;
325
- ue(n), o = i.PAN;
325
+ ge(a), o = i.PAN;
326
326
  } else {
327
327
  if (t.enableRotate === !1) return;
328
- ge(n), o = i.ROTATE;
328
+ pe(a), o = i.ROTATE;
329
329
  }
330
330
  break;
331
- case $.PAN:
332
- if (n.ctrlKey || n.metaKey || n.shiftKey) {
331
+ case j.PAN:
332
+ if (a.ctrlKey || a.metaKey || a.shiftKey) {
333
333
  if (t.enableRotate === !1) return;
334
- ge(n), o = i.ROTATE;
334
+ pe(a), o = i.ROTATE;
335
335
  } else {
336
336
  if (t.enablePan === !1) return;
337
- ue(n), o = i.PAN;
337
+ ge(a), o = i.PAN;
338
338
  }
339
339
  break;
340
340
  default:
341
341
  o = i.NONE;
342
342
  }
343
- o !== i.NONE && t.dispatchEvent(ce);
343
+ o !== i.NONE && t.dispatchEvent(le);
344
344
  }
345
- function We(n) {
345
+ function qe(a) {
346
346
  switch (o) {
347
347
  case i.ROTATE:
348
348
  if (t.enableRotate === !1) return;
349
- $e(n);
349
+ je(a);
350
350
  break;
351
351
  case i.DOLLY:
352
352
  if (t.enableZoom === !1) return;
353
- Ge(n);
353
+ $e(a);
354
354
  break;
355
355
  case i.PAN:
356
356
  if (t.enablePan === !1) return;
357
- Ye(n);
357
+ Ge(a);
358
358
  break;
359
359
  }
360
360
  }
361
- function we(n) {
362
- t.enabled === !1 || t.enableZoom === !1 || o !== i.NONE || (n.preventDefault(), t.dispatchEvent(ce), Be(Ze(n)), t.dispatchEvent(Le));
361
+ function we(a) {
362
+ t.enabled === !1 || t.enableZoom === !1 || o !== i.NONE || (a.preventDefault(), t.dispatchEvent(le), Ye(We(a)), t.dispatchEvent(Pe));
363
363
  }
364
- function Ze(n) {
365
- const g = n.deltaMode, v = {
366
- clientX: n.clientX,
367
- clientY: n.clientY,
368
- deltaY: n.deltaY
364
+ function We(a) {
365
+ const g = a.deltaMode, v = {
366
+ clientX: a.clientX,
367
+ clientY: a.clientY,
368
+ deltaY: a.deltaY
369
369
  };
370
370
  switch (g) {
371
371
  case 1:
@@ -375,28 +375,28 @@ class ft extends at {
375
375
  v.deltaY *= 100;
376
376
  break;
377
377
  }
378
- return n.ctrlKey && !se && (v.deltaY *= 10), v;
378
+ return a.ctrlKey && !te && (v.deltaY *= 10), v;
379
379
  }
380
- function Qe(n) {
381
- n.key === "Control" && (se = !0, document.addEventListener("keyup", Ee, { passive: !0, capture: !0 }));
380
+ function Ze(a) {
381
+ a.key === "Control" && (te = !0, document.addEventListener("keyup", Me, { passive: !0, capture: !0 }));
382
382
  }
383
- function Ee(n) {
384
- n.key === "Control" && (se = !1, document.removeEventListener("keyup", Ee, { passive: !0, capture: !0 }));
383
+ function Me(a) {
384
+ a.key === "Control" && (te = !1, document.removeEventListener("keyup", Me, { passive: !0, capture: !0 }));
385
385
  }
386
- function re(n) {
387
- t.enabled === !1 || t.enablePan === !1 || Ke(n);
386
+ function ae(a) {
387
+ t.enabled === !1 || t.enablePan === !1 || Be(a);
388
388
  }
389
- function Je(n) {
390
- switch (Ne(n), E.length) {
389
+ function Qe(a) {
390
+ switch (Ce(a), E.length) {
391
391
  case 1:
392
392
  switch (t.touches.ONE) {
393
- case G.ROTATE:
393
+ case $.ROTATE:
394
394
  if (t.enableRotate === !1) return;
395
- fe(n), o = i.TOUCH_ROTATE;
395
+ ue(a), o = i.TOUCH_ROTATE;
396
396
  break;
397
- case G.PAN:
397
+ case $.PAN:
398
398
  if (t.enablePan === !1) return;
399
- me(n), o = i.TOUCH_PAN;
399
+ fe(a), o = i.TOUCH_PAN;
400
400
  break;
401
401
  default:
402
402
  o = i.NONE;
@@ -404,13 +404,13 @@ class ft extends at {
404
404
  break;
405
405
  case 2:
406
406
  switch (t.touches.TWO) {
407
- case G.DOLLY_PAN:
407
+ case $.DOLLY_PAN:
408
408
  if (t.enableZoom === !1 && t.enablePan === !1) return;
409
- Ue(n), o = i.TOUCH_DOLLY_PAN;
409
+ Ke(a), o = i.TOUCH_DOLLY_PAN;
410
410
  break;
411
- case G.DOLLY_ROTATE:
411
+ case $.DOLLY_ROTATE:
412
412
  if (t.enableZoom === !1 && t.enableRotate === !1) return;
413
- _e(n), o = i.TOUCH_DOLLY_ROTATE;
413
+ Ue(a), o = i.TOUCH_DOLLY_ROTATE;
414
414
  break;
415
415
  default:
416
416
  o = i.NONE;
@@ -419,56 +419,56 @@ class ft extends at {
419
419
  default:
420
420
  o = i.NONE;
421
421
  }
422
- o !== i.NONE && t.dispatchEvent(ce);
422
+ o !== i.NONE && t.dispatchEvent(le);
423
423
  }
424
- function et(n) {
425
- switch (Ne(n), o) {
424
+ function Je(a) {
425
+ switch (Ce(a), o) {
426
426
  case i.TOUCH_ROTATE:
427
427
  if (t.enableRotate === !1) return;
428
- xe(n), t.update();
428
+ ye(a), t.update();
429
429
  break;
430
430
  case i.TOUCH_PAN:
431
431
  if (t.enablePan === !1) return;
432
- be(n), t.update();
432
+ xe(a), t.update();
433
433
  break;
434
434
  case i.TOUCH_DOLLY_PAN:
435
435
  if (t.enableZoom === !1 && t.enablePan === !1) return;
436
- Xe(n), t.update();
436
+ _e(a), t.update();
437
437
  break;
438
438
  case i.TOUCH_DOLLY_ROTATE:
439
439
  if (t.enableZoom === !1 && t.enableRotate === !1) return;
440
- Ve(n), t.update();
440
+ Xe(a), t.update();
441
441
  break;
442
442
  default:
443
443
  o = i.NONE;
444
444
  }
445
445
  }
446
- function Ce(n) {
447
- t.enabled !== !1 && n.preventDefault();
446
+ function Ee(a) {
447
+ t.enabled !== !1 && a.preventDefault();
448
448
  }
449
- function tt(n) {
450
- E.push(n.pointerId);
449
+ function et(a) {
450
+ E.push(a.pointerId);
451
451
  }
452
- function st(n) {
453
- delete q[n.pointerId];
452
+ function tt(a) {
453
+ delete V[a.pointerId];
454
454
  for (let g = 0; g < E.length; g++)
455
- if (E[g] == n.pointerId) {
455
+ if (E[g] == a.pointerId) {
456
456
  E.splice(g, 1);
457
457
  return;
458
458
  }
459
459
  }
460
- function Ne(n) {
461
- let g = q[n.pointerId];
462
- g === void 0 && (g = new k(), q[n.pointerId] = g), g.set(n.pageX, n.pageY);
460
+ function Ce(a) {
461
+ let g = V[a.pointerId];
462
+ g === void 0 && (g = new k(), V[a.pointerId] = g), g.set(a.pageX, a.pageY);
463
463
  }
464
- function j(n) {
465
- const g = n.pointerId === E[0] ? E[1] : E[0];
466
- return q[g];
464
+ function A(a) {
465
+ const g = a.pointerId === E[0] ? E[1] : E[0];
466
+ return V[g];
467
467
  }
468
- t.domElement.addEventListener("contextmenu", Ce), t.domElement.addEventListener("pointerdown", Me), t.domElement.addEventListener("pointercancel", K), t.domElement.addEventListener("wheel", we, { passive: !1 }), document.addEventListener("keydown", Qe, { passive: !0, capture: !0 }), this.update();
468
+ t.domElement.addEventListener("contextmenu", Ee), t.domElement.addEventListener("pointerdown", ve), t.domElement.addEventListener("pointercancel", B), t.domElement.addEventListener("wheel", we, { passive: !1 }), document.addEventListener("keydown", Ze, { passive: !0, capture: !0 }), this.update();
469
469
  }
470
470
  }
471
- class mt {
471
+ class ft {
472
472
  constructor(e, s) {
473
473
  l(this, "scene");
474
474
  l(this, "camera");
@@ -476,42 +476,42 @@ class mt {
476
476
  l(this, "controls");
477
477
  l(this, "container");
478
478
  l(this, "resizeHandler");
479
- this.container = e, this.scene = new y.Scene(), this.scene.background = new y.Color(
479
+ this.container = e, this.scene = new x.Scene(), this.scene.background = new x.Color(
480
480
  s.backgroundColor ?? 657930
481
481
  );
482
- const { width: t, height: i } = Te(e), o = s.cameraFov ?? 75;
483
- this.camera = new y.PerspectiveCamera(o, t / i, 0.1, 2e3);
484
- const a = s.cameraPosition ?? { x: 0, y: 0, z: 80 };
485
- this.camera.position.set(a.x, a.y, a.z), this.renderer = new y.WebGLRenderer({
482
+ const { width: t, height: i } = ke(e), o = s.cameraFov ?? 75;
483
+ this.camera = new x.PerspectiveCamera(o, t / i, 0.1, 2e3);
484
+ const n = s.cameraPosition ?? { x: 0, y: 0, z: 80 };
485
+ this.camera.position.set(n.x, n.y, n.z), this.renderer = new x.WebGLRenderer({
486
486
  antialias: !0,
487
487
  alpha: !0,
488
488
  powerPreference: "high-performance"
489
- }), this.renderer.setSize(t, i), this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)), this.renderer.toneMapping = y.ACESFilmicToneMapping, this.renderer.toneMappingExposure = 1, this.renderer.shadowMap.enabled = !0, this.renderer.shadowMap.type = y.PCFSoftShadowMap, e.appendChild(this.renderer.domElement), this.controls = new ft(this.camera, this.renderer.domElement), this.controls.enableDamping = !0, this.controls.dampingFactor = 0.05, this.controls.rotateSpeed = 0.8, this.controls.zoomSpeed = 1.2, this.controls.minDistance = 10, this.controls.maxDistance = 2e3, this.setupLighting(), this.resizeHandler = this.onWindowResize.bind(this), window.addEventListener("resize", this.resizeHandler);
489
+ }), this.renderer.setSize(t, i), this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)), this.renderer.toneMapping = x.ACESFilmicToneMapping, this.renderer.toneMappingExposure = 1, this.renderer.shadowMap.enabled = !0, this.renderer.shadowMap.type = x.PCFSoftShadowMap, e.appendChild(this.renderer.domElement), this.controls = new ut(this.camera, this.renderer.domElement), this.controls.enableDamping = !0, this.controls.dampingFactor = 0.05, this.controls.rotateSpeed = 0.8, this.controls.zoomSpeed = 1.2, this.controls.minDistance = 10, this.controls.maxDistance = 2e3, this.setupLighting(), this.resizeHandler = this.onWindowResize.bind(this), window.addEventListener("resize", this.resizeHandler);
490
490
  }
491
491
  /**
492
492
  * Sets up scene lighting for gradient glass on dark background
493
493
  */
494
494
  setupLighting() {
495
- const e = new y.AmbientLight(16777215, 0.4);
495
+ const e = new x.AmbientLight(16777215, 0.4);
496
496
  this.scene.add(e);
497
- const s = new y.DirectionalLight(16777215, 0.9);
497
+ const s = new x.DirectionalLight(16777215, 0.9);
498
498
  s.position.set(50, 60, 40), s.castShadow = !0, s.shadow.mapSize.width = 1024, s.shadow.mapSize.height = 1024, this.scene.add(s);
499
- const t = new y.DirectionalLight(16773344, 0.4);
499
+ const t = new x.DirectionalLight(16773344, 0.4);
500
500
  t.position.set(-50, 30, -40), this.scene.add(t);
501
- const i = new y.DirectionalLight(16777215, 0.3);
501
+ const i = new x.DirectionalLight(16777215, 0.3);
502
502
  i.position.set(0, -30, -50), this.scene.add(i);
503
- const o = new y.PointLight(16750950, 0.5, 150);
503
+ const o = new x.PointLight(16750950, 0.5, 150);
504
504
  o.position.set(40, 20, 40), this.scene.add(o);
505
- const a = new y.PointLight(16764057, 0.4, 150);
506
- a.position.set(-40, -20, 40), this.scene.add(a);
507
- const r = new y.PointLight(6724095, 0.2, 100);
505
+ const n = new x.PointLight(16764057, 0.4, 150);
506
+ n.position.set(-40, -20, 40), this.scene.add(n);
507
+ const r = new x.PointLight(6724095, 0.2, 100);
508
508
  r.position.set(0, 40, -40), this.scene.add(r);
509
509
  }
510
510
  /**
511
511
  * Handle window resize
512
512
  */
513
513
  onWindowResize() {
514
- const { width: e, height: s } = Te(this.container);
514
+ const { width: e, height: s } = ke(this.container);
515
515
  this.camera.aspect = e / s, this.camera.updateProjectionMatrix(), this.renderer.setSize(e, s);
516
516
  }
517
517
  /**
@@ -546,7 +546,7 @@ class mt {
546
546
  * Gets the camera's forward direction
547
547
  */
548
548
  getCameraDirection() {
549
- const e = new y.Vector3();
549
+ const e = new x.Vector3();
550
550
  return this.camera.getWorldDirection(e), e;
551
551
  }
552
552
  /**
@@ -559,7 +559,7 @@ class mt {
559
559
  }
560
560
  }
561
561
  }
562
- const V = class V {
562
+ const X = class X {
563
563
  constructor(e, s) {
564
564
  l(this, "sceneManager");
565
565
  l(this, "nodeFactory");
@@ -578,18 +578,18 @@ const V = class V {
578
578
  * Call this before adding nodes in bulk.
579
579
  */
580
580
  static setExpectedNodeCount(e) {
581
- V.expectedNodeCount = e;
581
+ X.expectedNodeCount = e;
582
582
  }
583
583
  /**
584
584
  * Adds a node to the graph
585
585
  * @returns true if added, false if node already exists or invalid
586
586
  */
587
587
  addNode(e, s = 0) {
588
- if (!De(e))
588
+ if (!Fe(e))
589
589
  return !1;
590
590
  if (this.nodes.has(e.id))
591
591
  return console.warn(`[ForceGraph3D] Node with id "${e.id}" already exists`), !1;
592
- const t = Math.max(50, Math.cbrt(V.expectedNodeCount) * 10), i = e.position ?? {
592
+ const t = Math.max(50, Math.cbrt(X.expectedNodeCount) * 10), i = e.position ?? {
593
593
  x: (Math.random() - 0.5) * t,
594
594
  y: (Math.random() - 0.5) * t,
595
595
  z: (Math.random() - 0.5) * t
@@ -598,11 +598,11 @@ const V = class V {
598
598
  position: i,
599
599
  velocity: { x: 0, y: 0, z: 0 },
600
600
  mass: 1
601
- }, a = this.nodeFactory.createNode(
601
+ }, n = this.nodeFactory.createNode(
602
602
  { ...e, position: i },
603
603
  s
604
604
  );
605
- return this.sceneManager.add(a.group), this.nodes.set(e.id, o), this.nodeObjects.set(e.id, a), !0;
605
+ return this.sceneManager.add(n.group), this.nodes.set(e.id, o), this.nodeObjects.set(e.id, n), !0;
606
606
  }
607
607
  /**
608
608
  * Removes a node from the graph
@@ -693,16 +693,23 @@ const V = class V {
693
693
  }
694
694
  };
695
695
  // Scale spawn volume with expected graph size
696
- l(V, "expectedNodeCount", 100);
697
- let te = V;
698
- class yt {
696
+ l(X, "expectedNodeCount", 100);
697
+ let ee = X;
698
+ class mt {
699
699
  constructor(e, s, t) {
700
700
  l(this, "sceneManager");
701
701
  l(this, "nodeManager");
702
702
  l(this, "edgeFactory");
703
+ // Full relationship list (includes duplicates between same pair)
703
704
  l(this, "edges", []);
705
+ // One visual line per directed pair (source -> target)
704
706
  l(this, "edgeObjects", []);
707
+ // Tracks which directed pairs currently have at least one relationship
705
708
  l(this, "edgeKeySet", /* @__PURE__ */ new Set());
709
+ // Maps directed pair key to the relationship list for that pair
710
+ l(this, "edgeGroups", /* @__PURE__ */ new Map());
711
+ // Maps directed pair key to the corresponding visual line
712
+ l(this, "edgeObjectMap", /* @__PURE__ */ new Map());
706
713
  l(this, "highlightedEdgeKey", null);
707
714
  this.sceneManager = e, this.nodeManager = s, this.edgeFactory = t;
708
715
  }
@@ -710,68 +717,92 @@ class yt {
710
717
  * Checks if an edge exists
711
718
  */
712
719
  hasEdge(e, s) {
713
- const t = H(e, s);
720
+ const t = this.createDirectedEdgeKey(e, s);
714
721
  return this.edgeKeySet.has(t);
715
722
  }
716
723
  /**
717
724
  * Adds an edge to the graph
718
- * @returns true if added, false if edge already exists or nodes don't exist
725
+ * @returns true if added, false if invalid or nodes don't exist
719
726
  */
720
727
  addEdge(e) {
721
- if (!He(e))
728
+ if (!De(e))
722
729
  return !1;
723
730
  if (!this.nodeManager.hasNode(e.source))
724
731
  return console.warn(`[ForceGraph3D] Source node "${e.source}" does not exist`), !1;
725
732
  if (!this.nodeManager.hasNode(e.target))
726
733
  return console.warn(`[ForceGraph3D] Target node "${e.target}" does not exist`), !1;
727
- const s = H(e.source, e.target);
728
- if (this.edgeKeySet.has(s))
729
- return console.warn(`[ForceGraph3D] Edge "${e.source}" -> "${e.target}" already exists`), !1;
730
- const t = this.nodeManager.getNode(e.source), i = this.nodeManager.getNode(e.target), o = this.edgeFactory.createEdge(
734
+ const s = this.nodeManager.getNode(e.source), t = this.nodeManager.getNode(e.target), i = this.createDirectedEdgeKey(e.source, e.target);
735
+ this.edges.push(e);
736
+ const o = this.edgeGroups.get(i);
737
+ if (o) {
738
+ o.push(e);
739
+ const r = this.edgeObjectMap.get(i);
740
+ return r && this.updateEdgeUserData(r, o, s, t), !0;
741
+ }
742
+ const n = this.edgeFactory.createEdge(
731
743
  e,
744
+ s,
732
745
  t,
733
- i,
734
- t.position,
735
- i.position
746
+ s.position,
747
+ t.position
736
748
  );
737
- return this.sceneManager.add(o.line), this.edges.push(e), this.edgeObjects.push(o), this.edgeKeySet.add(s), !0;
749
+ return this.sceneManager.add(n.line), this.edgeGroups.set(i, [e]), this.edgeObjectMap.set(i, n), this.edgeObjects.push(n), this.edgeKeySet.add(i), this.updateEdgeUserData(n, [e], s, t), !0;
738
750
  }
739
751
  /**
740
752
  * Removes an edge from the graph
753
+ * Removes one relationship instance for source -> target.
741
754
  * @returns true if removed, false if not found
742
755
  */
743
756
  removeEdge(e, s) {
744
- const t = H(e, s);
757
+ const t = this.createDirectedEdgeKey(e, s);
745
758
  if (!this.edgeKeySet.has(t))
746
759
  return !1;
747
760
  const i = this.edges.findIndex(
748
- (a) => H(a.source, a.target) === t
761
+ (c) => c.source === e && c.target === s
749
762
  );
750
763
  if (i === -1)
751
764
  return !1;
752
- const o = this.edgeObjects[i];
753
- return this.sceneManager.remove(o.line), this.edgeFactory.disposeEdge(o), this.edges.splice(i, 1), this.edgeObjects.splice(i, 1), this.edgeKeySet.delete(t), this.highlightedEdgeKey === t && (this.highlightedEdgeKey = null), !0;
765
+ const o = this.edges[i];
766
+ this.edges.splice(i, 1);
767
+ const n = this.edgeGroups.get(t);
768
+ if (!n)
769
+ return !0;
770
+ const r = n.findIndex((c) => c === o);
771
+ if (r !== -1)
772
+ n.splice(r, 1);
773
+ else {
774
+ const c = n.findIndex((p) => p.source === e && p.target === s);
775
+ c !== -1 && n.splice(c, 1);
776
+ }
777
+ const h = this.edgeObjectMap.get(t);
778
+ if (!h)
779
+ return !0;
780
+ if (n.length === 0) {
781
+ this.sceneManager.remove(h.line), this.edgeFactory.disposeEdge(h);
782
+ const c = this.edgeObjects.findIndex((p) => p === h);
783
+ c !== -1 && this.edgeObjects.splice(c, 1), this.edgeGroups.delete(t), this.edgeObjectMap.delete(t), this.edgeKeySet.delete(t), this.highlightedEdgeKey === t && (this.highlightedEdgeKey = null);
784
+ } else {
785
+ const c = this.nodeManager.getNode(e), p = this.nodeManager.getNode(s);
786
+ c && p && this.updateEdgeUserData(h, n, c, p);
787
+ }
788
+ return !0;
754
789
  }
755
790
  /**
756
791
  * Highlights an edge
757
792
  */
758
793
  highlightEdge(e, s) {
759
- const t = H(e, s);
794
+ const t = this.createDirectedEdgeKey(e, s);
760
795
  this.highlightedEdgeKey && this.highlightedEdgeKey !== t && this.unhighlightCurrentEdge();
761
- const i = this.edges.findIndex(
762
- (o) => H(o.source, o.target) === t
763
- );
764
- i !== -1 && (this.edgeFactory.highlightEdge(this.edgeObjects[i]), this.highlightedEdgeKey = t);
796
+ const i = this.edgeObjectMap.get(t);
797
+ i && (this.edgeFactory.highlightEdge(i), this.highlightedEdgeKey = t);
765
798
  }
766
799
  /**
767
800
  * Unhighlights the currently highlighted edge
768
801
  */
769
802
  unhighlightCurrentEdge() {
770
803
  if (!this.highlightedEdgeKey) return;
771
- const e = this.edges.findIndex(
772
- (s) => H(s.source, s.target) === this.highlightedEdgeKey
773
- );
774
- e !== -1 && this.edgeFactory.unhighlightEdge(this.edgeObjects[e]), this.highlightedEdgeKey = null;
804
+ const e = this.edgeObjectMap.get(this.highlightedEdgeKey);
805
+ e && this.edgeFactory.unhighlightEdge(e), this.highlightedEdgeKey = null;
775
806
  }
776
807
  /**
777
808
  * Removes all edges connected to a node
@@ -803,12 +834,12 @@ class yt {
803
834
  * Updates all edge positions based on current node positions
804
835
  */
805
836
  updateEdgePositions() {
806
- this.edgeObjects.forEach((e, s) => {
807
- const t = this.edges[s], i = this.nodeManager.getNode(t.source), o = this.nodeManager.getNode(t.target);
808
- i && o && this.edgeFactory.updateEdgePositions(
837
+ this.edgeObjects.forEach((e) => {
838
+ const s = this.nodeManager.getNode(e.source), t = this.nodeManager.getNode(e.target);
839
+ s && t && this.edgeFactory.updateEdgePositions(
809
840
  e,
810
- i.position,
811
- o.position
841
+ s.position,
842
+ t.position
812
843
  );
813
844
  });
814
845
  }
@@ -836,7 +867,29 @@ class yt {
836
867
  clear() {
837
868
  this.edgeObjects.forEach((e) => {
838
869
  this.sceneManager.remove(e.line), this.edgeFactory.disposeEdge(e);
839
- }), this.edges = [], this.edgeObjects = [], this.edgeKeySet.clear(), this.highlightedEdgeKey = null;
870
+ }), this.edges = [], this.edgeObjects = [], this.edgeKeySet.clear(), this.edgeGroups.clear(), this.edgeObjectMap.clear(), this.highlightedEdgeKey = null;
871
+ }
872
+ /**
873
+ * Creates a directed key (source -> target)
874
+ */
875
+ createDirectedEdgeKey(e, s) {
876
+ return `${e}->${s}`;
877
+ }
878
+ /**
879
+ * Syncs relationship metadata to the line for hover/click UI
880
+ */
881
+ updateEdgeUserData(e, s, t, i) {
882
+ const o = s[0];
883
+ e.line.userData = {
884
+ ...e.line.userData,
885
+ source: e.source,
886
+ target: e.target,
887
+ edge: o,
888
+ relationships: [...s],
889
+ relationshipCount: s.length,
890
+ sourceNode: t,
891
+ targetNode: i
892
+ };
840
893
  }
841
894
  /**
842
895
  * Dispose resources
@@ -845,7 +898,7 @@ class yt {
845
898
  this.clear();
846
899
  }
847
900
  }
848
- class Ie {
901
+ class Le {
849
902
  constructor(e, s, t = {}) {
850
903
  l(this, "nodes");
851
904
  l(this, "edges");
@@ -885,8 +938,8 @@ class Ie {
885
938
  let s = 0, t = null;
886
939
  for (const [i, o] of e) {
887
940
  o > s && (s = o, t = i);
888
- const a = this.nodes.get(i);
889
- a && (a.mass = 1 + Math.log2(1 + o));
941
+ const n = this.nodes.get(i);
942
+ n && (n.mass = 1 + Math.log2(1 + o));
890
943
  }
891
944
  if (console.log(`[ForceGraph3D] Hub detected: id="${t}", degree=${s}, threshold=10`), t && s > 10) {
892
945
  this.pinnedNodeId = t;
@@ -918,13 +971,13 @@ class Ie {
918
971
  const e = Array.from(this.nodes.values()), s = e.length, t = this.getEffectiveRepulsion();
919
972
  for (let i = 0; i < s; i++) {
920
973
  const o = e[i];
921
- for (let a = i + 1; a < s; a++) {
922
- const r = e[a], c = r.position.x - o.position.x, d = r.position.y - o.position.y, p = r.position.z - o.position.z;
923
- let x = c * c + d * d + p * p;
924
- if (x > this.REPULSION_CUTOFF_SQ) continue;
925
- x < 0.01 && (x = 0.01);
926
- const m = Math.sqrt(x), u = t * this.alpha / x, f = c / m * u, b = d / m * u, M = p / m * u;
927
- o.velocity.x -= f / o.mass, o.velocity.y -= b / o.mass, o.velocity.z -= M / o.mass, r.velocity.x += f / r.mass, r.velocity.y += b / r.mass, r.velocity.z += M / r.mass;
974
+ for (let n = i + 1; n < s; n++) {
975
+ const r = e[n], h = r.position.x - o.position.x, c = r.position.y - o.position.y, p = r.position.z - o.position.z;
976
+ let f = h * h + c * c + p * p;
977
+ if (f > this.REPULSION_CUTOFF_SQ) continue;
978
+ f < 0.01 && (f = 0.01);
979
+ const m = Math.sqrt(f), u = t * this.alpha / f, y = h / m * u, b = c / m * u, w = p / m * u;
980
+ o.velocity.x -= y / o.mass, o.velocity.y -= b / o.mass, o.velocity.z -= w / o.mass, r.velocity.x += y / r.mass, r.velocity.y += b / r.mass, r.velocity.z += w / r.mass;
928
981
  }
929
982
  }
930
983
  }
@@ -932,7 +985,7 @@ class Ie {
932
985
  * Barnes-Hut approximation - O(n log n)
933
986
  */
934
987
  calculateRepulsionBarnesHut() {
935
- const e = Array.from(this.nodes.values()), s = new xt(e);
988
+ const e = Array.from(this.nodes.values()), s = new yt(e);
936
989
  for (const t of e)
937
990
  this.calculateForceFromOctree(t, s.root);
938
991
  }
@@ -945,26 +998,26 @@ class Ie {
945
998
  return;
946
999
  }
947
1000
  if (s.mass === 0) return;
948
- const t = s.centerOfMass.x - e.position.x, i = s.centerOfMass.y - e.position.y, o = s.centerOfMass.z - e.position.z, a = t * t + i * i + o * o;
949
- if (a > this.REPULSION_CUTOFF_SQ) return;
950
- const r = Math.sqrt(a), c = this.getEffectiveRepulsion();
1001
+ const t = s.centerOfMass.x - e.position.x, i = s.centerOfMass.y - e.position.y, o = s.centerOfMass.z - e.position.z, n = t * t + i * i + o * o;
1002
+ if (n > this.REPULSION_CUTOFF_SQ) return;
1003
+ const r = Math.sqrt(n), h = this.getEffectiveRepulsion();
951
1004
  if (r > 0 && s.size / r < this.barnesHutTheta) {
952
- const d = Math.max(a, 0.01), p = c * this.alpha * s.mass / d;
1005
+ const c = Math.max(n, 0.01), p = h * this.alpha * s.mass / c;
953
1006
  e.velocity.x -= t / r * p / e.mass, e.velocity.y -= i / r * p / e.mass, e.velocity.z -= o / r * p / e.mass;
954
1007
  } else
955
- for (const d of s.children)
956
- d && this.calculateForceFromOctree(e, d);
1008
+ for (const c of s.children)
1009
+ c && this.calculateForceFromOctree(e, c);
957
1010
  }
958
1011
  /**
959
1012
  * Apply repulsion between two nodes (with cutoff)
960
1013
  */
961
1014
  applyRepulsionBetween(e, s) {
962
1015
  const t = s.position.x - e.position.x, i = s.position.y - e.position.y, o = s.position.z - e.position.z;
963
- let a = t * t + i * i + o * o;
964
- if (a > this.REPULSION_CUTOFF_SQ) return;
965
- a < 0.01 && (a = 0.01);
966
- const r = Math.sqrt(a), d = this.getEffectiveRepulsion() * this.alpha / a;
967
- e.velocity.x -= t / r * d / e.mass, e.velocity.y -= i / r * d / e.mass, e.velocity.z -= o / r * d / e.mass;
1016
+ let n = t * t + i * i + o * o;
1017
+ if (n > this.REPULSION_CUTOFF_SQ) return;
1018
+ n < 0.01 && (n = 0.01);
1019
+ const r = Math.sqrt(n), c = this.getEffectiveRepulsion() * this.alpha / n;
1020
+ e.velocity.x -= t / r * c / e.mass, e.velocity.y -= i / r * c / e.mass, e.velocity.z -= o / r * c / e.mass;
968
1021
  }
969
1022
  /**
970
1023
  * Calculate attraction forces along edges
@@ -974,10 +1027,10 @@ class Ie {
974
1027
  for (const t of this.edges) {
975
1028
  const i = this.nodes.get(t.source), o = this.nodes.get(t.target);
976
1029
  if (!i || !o) continue;
977
- const a = o.position.x - i.position.x, r = o.position.y - i.position.y, c = o.position.z - i.position.z, d = Math.sqrt(a * a + r * r + c * c);
978
- if (d < 0.01) continue;
979
- const x = (d - 15) * this.attractionStrength * s * this.alpha, m = a / d * x, u = r / d * x, f = c / d * x;
980
- i.velocity.x += m / i.mass, i.velocity.y += u / i.mass, i.velocity.z += f / i.mass, o.velocity.x -= m / o.mass, o.velocity.y -= u / o.mass, o.velocity.z -= f / o.mass;
1030
+ const n = o.position.x - i.position.x, r = o.position.y - i.position.y, h = o.position.z - i.position.z, c = Math.sqrt(n * n + r * r + h * h);
1031
+ if (c < 0.01) continue;
1032
+ const f = (c - 15) * this.attractionStrength * s * this.alpha, m = n / c * f, u = r / c * f, y = h / c * f;
1033
+ i.velocity.x += m / i.mass, i.velocity.y += u / i.mass, i.velocity.z += y / i.mass, o.velocity.x -= m / o.mass, o.velocity.y -= u / o.mass, o.velocity.z -= y / o.mass;
981
1034
  }
982
1035
  }
983
1036
  /**
@@ -1034,7 +1087,7 @@ class Ie {
1034
1087
  e.repulsionStrength !== void 0 && (this.repulsionStrength = e.repulsionStrength), e.attractionStrength !== void 0 && (this.attractionStrength = e.attractionStrength), e.damping !== void 0 && (this.damping = e.damping);
1035
1088
  }
1036
1089
  }
1037
- class xt {
1090
+ class yt {
1038
1091
  constructor(e) {
1039
1092
  l(this, "root");
1040
1093
  const s = this.calculateBounds(e);
@@ -1070,54 +1123,54 @@ class xt {
1070
1123
  };
1071
1124
  if (e.length === 1 || t > 20) {
1072
1125
  let u = 0;
1073
- const f = { x: 0, y: 0, z: 0 };
1126
+ const y = { x: 0, y: 0, z: 0 };
1074
1127
  for (const b of e)
1075
- u += b.mass, f.x += b.position.x * b.mass, f.y += b.position.y * b.mass, f.z += b.position.z * b.mass;
1076
- return u > 0 && (f.x /= u, f.y /= u, f.z /= u), {
1128
+ u += b.mass, y.x += b.position.x * b.mass, y.y += b.position.y * b.mass, y.z += b.position.z * b.mass;
1129
+ return u > 0 && (y.x /= u, y.y /= u, y.z /= u), {
1077
1130
  bounds: s,
1078
1131
  size: i,
1079
- centerOfMass: f,
1132
+ centerOfMass: y,
1080
1133
  mass: u,
1081
1134
  isLeaf: !0,
1082
1135
  node: e[0],
1083
1136
  children: []
1084
1137
  };
1085
1138
  }
1086
- const o = (s.min.x + s.max.x) / 2, a = (s.min.y + s.max.y) / 2, r = (s.min.z + s.max.z) / 2, c = [[], [], [], [], [], [], [], []];
1139
+ const o = (s.min.x + s.max.x) / 2, n = (s.min.y + s.max.y) / 2, r = (s.min.z + s.max.z) / 2, h = [[], [], [], [], [], [], [], []];
1087
1140
  for (const u of e) {
1088
- const f = (u.position.x >= o ? 1 : 0) + (u.position.y >= a ? 2 : 0) + (u.position.z >= r ? 4 : 0);
1089
- c[f].push(u);
1090
- }
1091
- const d = [
1092
- { min: { x: s.min.x, y: s.min.y, z: s.min.z }, max: { x: o, y: a, z: r } },
1093
- { min: { x: o, y: s.min.y, z: s.min.z }, max: { x: s.max.x, y: a, z: r } },
1094
- { min: { x: s.min.x, y: a, z: s.min.z }, max: { x: o, y: s.max.y, z: r } },
1095
- { min: { x: o, y: a, z: s.min.z }, max: { x: s.max.x, y: s.max.y, z: r } },
1096
- { min: { x: s.min.x, y: s.min.y, z: r }, max: { x: o, y: a, z: s.max.z } },
1097
- { min: { x: o, y: s.min.y, z: r }, max: { x: s.max.x, y: a, z: s.max.z } },
1098
- { min: { x: s.min.x, y: a, z: r }, max: { x: o, y: s.max.y, z: s.max.z } },
1099
- { min: { x: o, y: a, z: r }, max: { x: s.max.x, y: s.max.y, z: s.max.z } }
1141
+ const y = (u.position.x >= o ? 1 : 0) + (u.position.y >= n ? 2 : 0) + (u.position.z >= r ? 4 : 0);
1142
+ h[y].push(u);
1143
+ }
1144
+ const c = [
1145
+ { min: { x: s.min.x, y: s.min.y, z: s.min.z }, max: { x: o, y: n, z: r } },
1146
+ { min: { x: o, y: s.min.y, z: s.min.z }, max: { x: s.max.x, y: n, z: r } },
1147
+ { min: { x: s.min.x, y: n, z: s.min.z }, max: { x: o, y: s.max.y, z: r } },
1148
+ { min: { x: o, y: n, z: s.min.z }, max: { x: s.max.x, y: s.max.y, z: r } },
1149
+ { min: { x: s.min.x, y: s.min.y, z: r }, max: { x: o, y: n, z: s.max.z } },
1150
+ { min: { x: o, y: s.min.y, z: r }, max: { x: s.max.x, y: n, z: s.max.z } },
1151
+ { min: { x: s.min.x, y: n, z: r }, max: { x: o, y: s.max.y, z: s.max.z } },
1152
+ { min: { x: o, y: n, z: r }, max: { x: s.max.x, y: s.max.y, z: s.max.z } }
1100
1153
  ], p = [];
1101
- let x = 0;
1154
+ let f = 0;
1102
1155
  const m = { x: 0, y: 0, z: 0 };
1103
1156
  for (let u = 0; u < 8; u++)
1104
- if (c[u].length > 0) {
1105
- const f = this.buildTree(c[u], d[u], t + 1);
1106
- p.push(f), x += f.mass, m.x += f.centerOfMass.x * f.mass, m.y += f.centerOfMass.y * f.mass, m.z += f.centerOfMass.z * f.mass;
1157
+ if (h[u].length > 0) {
1158
+ const y = this.buildTree(h[u], c[u], t + 1);
1159
+ p.push(y), f += y.mass, m.x += y.centerOfMass.x * y.mass, m.y += y.centerOfMass.y * y.mass, m.z += y.centerOfMass.z * y.mass;
1107
1160
  } else
1108
1161
  p.push(null);
1109
- return x > 0 && (m.x /= x, m.y /= x, m.z /= x), {
1162
+ return f > 0 && (m.x /= f, m.y /= f, m.z /= f), {
1110
1163
  bounds: s,
1111
1164
  size: i,
1112
1165
  centerOfMass: m,
1113
- mass: x,
1166
+ mass: f,
1114
1167
  isLeaf: !1,
1115
1168
  node: null,
1116
1169
  children: p
1117
1170
  };
1118
1171
  }
1119
1172
  }
1120
- class bt {
1173
+ class xt {
1121
1174
  constructor(e, s, t, i = 60) {
1122
1175
  l(this, "sceneManager");
1123
1176
  l(this, "animationId", null);
@@ -1182,7 +1235,7 @@ class bt {
1182
1235
  this.stop();
1183
1236
  }
1184
1237
  }
1185
- class vt {
1238
+ class bt {
1186
1239
  constructor() {
1187
1240
  l(this, "envMap", null);
1188
1241
  l(this, "materialCache", /* @__PURE__ */ new Map());
@@ -1223,7 +1276,7 @@ class vt {
1223
1276
  for (const i of t) {
1224
1277
  const o = document.createElement("canvas");
1225
1278
  o.width = 256, o.height = 256;
1226
- const a = o.getContext("2d"), r = a.createRadialGradient(
1279
+ const n = o.getContext("2d"), r = n.createRadialGradient(
1227
1280
  256 / 2,
1228
1281
  256 / 2,
1229
1282
  0,
@@ -1231,15 +1284,15 @@ class vt {
1231
1284
  256 / 2,
1232
1285
  256 * 0.8
1233
1286
  );
1234
- r.addColorStop(0, i.colors[0]), r.addColorStop(0.5, i.colors[1]), r.addColorStop(1, i.colors[2]), a.fillStyle = r, a.fillRect(0, 0, 256, 256);
1235
- const c = a.getImageData(0, 0, 256, 256);
1236
- for (let d = 0; d < c.data.length; d += 4) {
1287
+ r.addColorStop(0, i.colors[0]), r.addColorStop(0.5, i.colors[1]), r.addColorStop(1, i.colors[2]), n.fillStyle = r, n.fillRect(0, 0, 256, 256);
1288
+ const h = n.getImageData(0, 0, 256, 256);
1289
+ for (let c = 0; c < h.data.length; c += 4) {
1237
1290
  const p = (Math.random() - 0.5) * 5;
1238
- c.data[d] = Math.min(255, Math.max(0, c.data[d] + p)), c.data[d + 1] = Math.min(255, Math.max(0, c.data[d + 1] + p)), c.data[d + 2] = Math.min(255, Math.max(0, c.data[d + 2] + p));
1291
+ h.data[c] = Math.min(255, Math.max(0, h.data[c] + p)), h.data[c + 1] = Math.min(255, Math.max(0, h.data[c + 1] + p)), h.data[c + 2] = Math.min(255, Math.max(0, h.data[c + 2] + p));
1239
1292
  }
1240
- a.putImageData(c, 0, 0), s.push(o);
1293
+ n.putImageData(h, 0, 0), s.push(o);
1241
1294
  }
1242
- this.envMap = new y.CubeTexture(s.map((i) => {
1295
+ this.envMap = new x.CubeTexture(s.map((i) => {
1243
1296
  const o = new Image();
1244
1297
  return o.src = i.toDataURL(), o;
1245
1298
  })), this.envMap.needsUpdate = !0;
@@ -1258,11 +1311,11 @@ class vt {
1258
1311
  const t = "glass-single";
1259
1312
  if (this.materialCache.has(t))
1260
1313
  return this.materialCache.get(t).clone();
1261
- const i = new y.Color(16750950), o = new y.ShaderMaterial({
1314
+ const i = new x.Color(16750950), o = new x.ShaderMaterial({
1262
1315
  uniforms: {
1263
1316
  uColor: { value: i },
1264
1317
  uEnvMap: { value: this.envMap },
1265
- uGlowColor: { value: new y.Color(16777215) },
1318
+ uGlowColor: { value: new x.Color(16777215) },
1266
1319
  uGlowIntensity: { value: 0.8 },
1267
1320
  uReflectivity: { value: 0.4 },
1268
1321
  uFresnelPower: { value: 2.5 }
@@ -1328,9 +1381,9 @@ class vt {
1328
1381
  }
1329
1382
  `,
1330
1383
  transparent: !0,
1331
- side: y.FrontSide,
1384
+ side: x.FrontSide,
1332
1385
  depthWrite: !0,
1333
- blending: y.NormalBlending
1386
+ blending: x.NormalBlending
1334
1387
  });
1335
1388
  return this.materialCache.set(t, o), o.clone();
1336
1389
  }
@@ -1338,7 +1391,7 @@ class vt {
1338
1391
  * Creates material for edges (light color for dark background)
1339
1392
  */
1340
1393
  createEdgeMaterial(e = 6710886, s = 0.4) {
1341
- return new y.LineBasicMaterial({
1394
+ return new x.LineBasicMaterial({
1342
1395
  color: e,
1343
1396
  transparent: !0,
1344
1397
  opacity: s,
@@ -1349,7 +1402,7 @@ class vt {
1349
1402
  * Creates highlighted edge material
1350
1403
  */
1351
1404
  createHighlightedEdgeMaterial() {
1352
- return new y.LineBasicMaterial({
1405
+ return new x.LineBasicMaterial({
1353
1406
  color: 16750950,
1354
1407
  // Tangerine highlight
1355
1408
  transparent: !1,
@@ -1363,10 +1416,10 @@ class vt {
1363
1416
  createLabelMaterial(e, s = 24) {
1364
1417
  const t = document.createElement("canvas"), i = t.getContext("2d");
1365
1418
  i.font = `600 ${s}px Inter, -apple-system, sans-serif`;
1366
- const a = i.measureText(e).width;
1367
- t.width = Math.max(128, a + 24), t.height = s + 20, i.clearRect(0, 0, t.width, t.height), i.font = `600 ${s}px Inter, -apple-system, sans-serif`, i.textAlign = "center", i.textBaseline = "middle", i.shadowColor = "rgba(0, 0, 0, 0.8)", i.shadowBlur = 4, i.shadowOffsetX = 1, i.shadowOffsetY = 1, i.fillStyle = "rgba(255, 255, 255, 0.95)", i.fillText(e, t.width / 2, t.height / 2);
1368
- const r = new y.CanvasTexture(t);
1369
- return r.needsUpdate = !0, new y.SpriteMaterial({
1419
+ const n = i.measureText(e).width;
1420
+ t.width = Math.max(128, n + 24), t.height = s + 20, i.clearRect(0, 0, t.width, t.height), i.font = `600 ${s}px Inter, -apple-system, sans-serif`, i.textAlign = "center", i.textBaseline = "middle", i.shadowColor = "rgba(0, 0, 0, 0.8)", i.shadowBlur = 4, i.shadowOffsetX = 1, i.shadowOffsetY = 1, i.fillStyle = "rgba(255, 255, 255, 0.95)", i.fillText(e, t.width / 2, t.height / 2);
1421
+ const r = new x.CanvasTexture(t);
1422
+ return r.needsUpdate = !0, new x.SpriteMaterial({
1370
1423
  map: r,
1371
1424
  transparent: !0,
1372
1425
  depthTest: !1,
@@ -1386,7 +1439,7 @@ class vt {
1386
1439
  this.materialCache.forEach((e) => e.dispose()), this.materialCache.clear(), this.envMap && this.envMap.dispose();
1387
1440
  }
1388
1441
  }
1389
- class Mt {
1442
+ class vt {
1390
1443
  constructor(e, s = 2, t = [32, 16, 8], i = 16750950) {
1391
1444
  l(this, "materialFactory");
1392
1445
  l(this, "geometryCache", /* @__PURE__ */ new Map());
@@ -1403,7 +1456,7 @@ class Mt {
1403
1456
  const t = `lod-${s}`;
1404
1457
  this.geometryCache.set(
1405
1458
  t,
1406
- new y.SphereGeometry(this.nodeRadius, e, e)
1459
+ new x.SphereGeometry(this.nodeRadius, e, e)
1407
1460
  );
1408
1461
  });
1409
1462
  }
@@ -1418,21 +1471,21 @@ class Mt {
1418
1471
  * Creates a node visual (glass ball + label)
1419
1472
  */
1420
1473
  createNode(e, s = 0) {
1421
- const t = new y.Group();
1474
+ const t = new x.Group();
1422
1475
  t.name = `node-${e.id}`, t.userData = { nodeId: e.id, nodeData: e };
1423
1476
  const i = this.getGeometry(s), o = this.materialFactory.createGlassMaterial(
1424
1477
  e.color ?? this.defaultNodeColor
1425
- ), a = new y.Mesh(i, o);
1426
- a.castShadow = !0, a.receiveShadow = !0, t.add(a);
1427
- const r = this.materialFactory.createLabelMaterial(e.label), c = new y.Sprite(r);
1428
- return c.position.y = this.nodeRadius + 1.5, c.scale.set(4, 1, 1), t.add(c), e.position && t.position.set(
1478
+ ), n = new x.Mesh(i, o);
1479
+ n.castShadow = !0, n.receiveShadow = !0, t.add(n);
1480
+ const r = this.materialFactory.createLabelMaterial(e.label), h = new x.Sprite(r);
1481
+ return h.position.y = this.nodeRadius + 1.5, h.scale.set(4, 1, 1), t.add(h), e.position && t.position.set(
1429
1482
  e.position.x,
1430
1483
  e.position.y,
1431
1484
  e.position.z
1432
1485
  ), {
1433
1486
  group: t,
1434
- sphere: a,
1435
- label: c,
1487
+ sphere: n,
1488
+ label: h,
1436
1489
  lodLevel: s
1437
1490
  };
1438
1491
  }
@@ -1448,19 +1501,19 @@ class Mt {
1448
1501
  * Updates the color of a node
1449
1502
  */
1450
1503
  updateNodeColor(e, s) {
1451
- e.sphere.material instanceof y.Material && e.sphere.material.dispose(), e.sphere.material = this.materialFactory.createGlassMaterial(s);
1504
+ e.sphere.material instanceof x.Material && e.sphere.material.dispose(), e.sphere.material = this.materialFactory.createGlassMaterial(s);
1452
1505
  }
1453
1506
  /**
1454
1507
  * Updates the label of a node
1455
1508
  */
1456
1509
  updateNodeLabel(e, s) {
1457
- e.label.material instanceof y.SpriteMaterial && (e.label.material.map && e.label.material.map.dispose(), e.label.material.dispose()), e.label.material = this.materialFactory.createLabelMaterial(s);
1510
+ e.label.material instanceof x.SpriteMaterial && (e.label.material.map && e.label.material.map.dispose(), e.label.material.dispose()), e.label.material = this.materialFactory.createLabelMaterial(s);
1458
1511
  }
1459
1512
  /**
1460
1513
  * Disposes a node's resources
1461
1514
  */
1462
1515
  disposeNode(e) {
1463
- e.sphere.material instanceof y.Material && e.sphere.material.dispose(), e.label.material instanceof y.SpriteMaterial && (e.label.material.map && e.label.material.map.dispose(), e.label.material.dispose());
1516
+ e.sphere.material instanceof x.Material && e.sphere.material.dispose(), e.label.material instanceof x.SpriteMaterial && (e.label.material.map && e.label.material.map.dispose(), e.label.material.dispose());
1464
1517
  }
1465
1518
  /**
1466
1519
  * Dispose factory resources
@@ -1497,7 +1550,7 @@ class wt {
1497
1550
  * Creates an edge line between two positions
1498
1551
  */
1499
1552
  createEdge(e, s, t, i, o) {
1500
- const a = new y.BufferGeometry(), r = new Float32Array([
1553
+ const n = new x.BufferGeometry(), r = new Float32Array([
1501
1554
  i.x,
1502
1555
  i.y,
1503
1556
  i.z,
@@ -1505,16 +1558,16 @@ class wt {
1505
1558
  o.y,
1506
1559
  o.z
1507
1560
  ]);
1508
- a.setAttribute("position", new y.BufferAttribute(r, 3));
1509
- const c = this.getDefaultMaterial().clone(), d = new y.Line(a, c);
1510
- return d.name = `edge-${e.source}-${e.target}`, d.userData = {
1561
+ n.setAttribute("position", new x.BufferAttribute(r, 3));
1562
+ const h = this.getDefaultMaterial().clone(), c = new x.Line(n, h);
1563
+ return c.name = `edge-${e.source}-${e.target}`, c.userData = {
1511
1564
  source: e.source,
1512
1565
  target: e.target,
1513
1566
  edge: e,
1514
1567
  sourceNode: s,
1515
1568
  targetNode: t
1516
- }, d.frustumCulled = !0, {
1517
- line: d,
1569
+ }, c.frustumCulled = !0, {
1570
+ line: c,
1518
1571
  source: e.source,
1519
1572
  target: e.target
1520
1573
  };
@@ -1523,13 +1576,13 @@ class wt {
1523
1576
  * Highlights an edge
1524
1577
  */
1525
1578
  highlightEdge(e) {
1526
- e.line.material instanceof y.Material && e.line.material.dispose(), e.line.material = this.getHighlightMaterial().clone();
1579
+ e.line.material instanceof x.Material && e.line.material.dispose(), e.line.material = this.getHighlightMaterial().clone();
1527
1580
  }
1528
1581
  /**
1529
1582
  * Resets an edge to default appearance
1530
1583
  */
1531
1584
  unhighlightEdge(e) {
1532
- e.line.material instanceof y.Material && e.line.material.dispose(), e.line.material = this.getDefaultMaterial().clone();
1585
+ e.line.material instanceof x.Material && e.line.material.dispose(), e.line.material = this.getDefaultMaterial().clone();
1533
1586
  }
1534
1587
  /**
1535
1588
  * Updates an edge's positions
@@ -1542,7 +1595,7 @@ class wt {
1542
1595
  * Disposes an edge's resources
1543
1596
  */
1544
1597
  disposeEdge(e) {
1545
- e.line.geometry.dispose(), e.line.material instanceof y.Material && e.line.material.dispose();
1598
+ e.line.geometry.dispose(), e.line.material instanceof x.Material && e.line.material.dispose();
1546
1599
  }
1547
1600
  /**
1548
1601
  * Dispose factory resources
@@ -1551,7 +1604,7 @@ class wt {
1551
1604
  this.defaultMaterial && this.defaultMaterial.dispose(), this.highlightMaterial && this.highlightMaterial.dispose();
1552
1605
  }
1553
1606
  }
1554
- class Et {
1607
+ class Mt {
1555
1608
  constructor(e, s = [50, 100, 200], t = !0) {
1556
1609
  l(this, "camera");
1557
1610
  l(this, "lodDistances");
@@ -1563,9 +1616,9 @@ class Et {
1563
1616
  */
1564
1617
  getLODLevel(e) {
1565
1618
  if (!this.enabled)
1566
- return X.HIGH;
1619
+ return _.HIGH;
1567
1620
  const s = e.x - this.camera.position.x, t = e.y - this.camera.position.y, i = e.z - this.camera.position.z, o = Math.sqrt(s * s + t * t + i * i);
1568
- return o < this.lodDistances[0] ? X.HIGH : o < this.lodDistances[1] ? X.MEDIUM : X.LOW;
1621
+ return o < this.lodDistances[0] ? _.HIGH : o < this.lodDistances[1] ? _.MEDIUM : _.LOW;
1569
1622
  }
1570
1623
  /**
1571
1624
  * Checks if a node should be visible based on distance
@@ -1587,13 +1640,13 @@ class Et {
1587
1640
  this.enabled = e;
1588
1641
  }
1589
1642
  }
1590
- class Ct {
1643
+ class Et {
1591
1644
  constructor(e, s = !0) {
1592
1645
  l(this, "camera");
1593
1646
  l(this, "frustum");
1594
1647
  l(this, "projScreenMatrix");
1595
1648
  l(this, "enabled");
1596
- this.camera = e, this.frustum = new y.Frustum(), this.projScreenMatrix = new y.Matrix4(), this.enabled = s;
1649
+ this.camera = e, this.frustum = new x.Frustum(), this.projScreenMatrix = new x.Matrix4(), this.enabled = s;
1597
1650
  }
1598
1651
  /**
1599
1652
  * Updates the frustum from the camera
@@ -1609,7 +1662,7 @@ class Ct {
1609
1662
  */
1610
1663
  isPointVisible(e) {
1611
1664
  if (!this.enabled) return !0;
1612
- const s = new y.Vector3(e.x, e.y, e.z);
1665
+ const s = new x.Vector3(e.x, e.y, e.z);
1613
1666
  return this.frustum.containsPoint(s);
1614
1667
  }
1615
1668
  /**
@@ -1617,8 +1670,8 @@ class Ct {
1617
1670
  */
1618
1671
  isSphereVisible(e, s) {
1619
1672
  if (!this.enabled) return !0;
1620
- const t = new y.Sphere(
1621
- new y.Vector3(e.x, e.y, e.z),
1673
+ const t = new x.Sphere(
1674
+ new x.Vector3(e.x, e.y, e.z),
1622
1675
  s
1623
1676
  );
1624
1677
  return this.frustum.intersectsSphere(t);
@@ -1628,14 +1681,14 @@ class Ct {
1628
1681
  */
1629
1682
  isLineVisible(e, s) {
1630
1683
  if (!this.enabled) return !0;
1631
- const t = new y.Vector3(e.x, e.y, e.z), i = new y.Vector3(s.x, s.y, s.z);
1684
+ const t = new x.Vector3(e.x, e.y, e.z), i = new x.Vector3(s.x, s.y, s.z);
1632
1685
  if (this.frustum.containsPoint(t) || this.frustum.containsPoint(i))
1633
1686
  return !0;
1634
- const o = new y.Vector3(
1687
+ const o = new x.Vector3(
1635
1688
  (e.x + s.x) / 2,
1636
1689
  (e.y + s.y) / 2,
1637
1690
  (e.z + s.z) / 2
1638
- ), a = o.distanceTo(t), r = new y.Sphere(o, a);
1691
+ ), n = o.distanceTo(t), r = new x.Sphere(o, n);
1639
1692
  return this.frustum.intersectsSphere(r);
1640
1693
  }
1641
1694
  /**
@@ -1645,7 +1698,7 @@ class Ct {
1645
1698
  this.enabled = e;
1646
1699
  }
1647
1700
  }
1648
- class Nt {
1701
+ class Ct {
1649
1702
  constructor(e, s) {
1650
1703
  l(this, "sceneManager");
1651
1704
  l(this, "raycaster");
@@ -1659,7 +1712,7 @@ class Nt {
1659
1712
  l(this, "hoveredEdgeKey", null);
1660
1713
  l(this, "nodeObjects", []);
1661
1714
  l(this, "edgeObjects", []);
1662
- this.sceneManager = e, this.container = s, this.raycaster = new y.Raycaster(), this.raycaster.params.Line = { threshold: 1.5 }, this.mouse = new y.Vector2(), this.handleClick = this.handleClick.bind(this), this.handleMouseMove = this.handleMouseMove.bind(this), s.addEventListener("click", this.handleClick), s.addEventListener("mousemove", this.handleMouseMove);
1715
+ this.sceneManager = e, this.container = s, this.raycaster = new x.Raycaster(), this.raycaster.params.Line = { threshold: 1.5 }, this.mouse = new x.Vector2(), this.handleClick = this.handleClick.bind(this), this.handleMouseMove = this.handleMouseMove.bind(this), s.addEventListener("click", this.handleClick), s.addEventListener("mousemove", this.handleMouseMove);
1663
1716
  }
1664
1717
  /**
1665
1718
  * Updates the list of node objects to raycast against
@@ -1748,13 +1801,17 @@ class Nt {
1748
1801
  const t = this.raycaster.intersectObjects(this.edgeObjects, !1);
1749
1802
  if (t.length > 0) {
1750
1803
  const i = t[0].object, o = i.userData;
1751
- if (o != null && o.edge && (o != null && o.sourceNode) && (o != null && o.targetNode))
1804
+ if (o != null && o.edge && (o != null && o.sourceNode) && (o != null && o.targetNode)) {
1805
+ const n = Array.isArray(o.relationships) ? o.relationships : [o.edge];
1752
1806
  return {
1753
1807
  edge: o.edge,
1808
+ relationships: n,
1809
+ relationshipCount: typeof o.relationshipCount == "number" ? o.relationshipCount : n.length,
1754
1810
  sourceNode: o.sourceNode,
1755
1811
  targetNode: o.targetNode,
1756
1812
  edgeLine: i
1757
1813
  };
1814
+ }
1758
1815
  }
1759
1816
  return null;
1760
1817
  }
@@ -1767,11 +1824,11 @@ class Nt {
1767
1824
  this.mouse.x = (e - t.left) / t.width * 2 - 1, this.mouse.y = -((s - t.top) / t.height) * 2 + 1, this.raycaster.setFromCamera(this.mouse, this.sceneManager.camera);
1768
1825
  const i = this.raycaster.intersectObjects(this.nodeObjects, !0);
1769
1826
  if (i.length > 0) {
1770
- let a = i[0].object;
1771
- for (; a; ) {
1772
- if ((o = a.userData) != null && o.nodeId)
1773
- return a.userData.nodeId;
1774
- a = a.parent;
1827
+ let n = i[0].object;
1828
+ for (; n; ) {
1829
+ if ((o = n.userData) != null && o.nodeId)
1830
+ return n.userData.nodeId;
1831
+ n = n.parent;
1775
1832
  }
1776
1833
  }
1777
1834
  return null;
@@ -1783,7 +1840,7 @@ class Nt {
1783
1840
  this.container.removeEventListener("click", this.handleClick), this.container.removeEventListener("mousemove", this.handleMouseMove);
1784
1841
  }
1785
1842
  }
1786
- class St {
1843
+ class Nt {
1787
1844
  constructor(e) {
1788
1845
  l(this, "container");
1789
1846
  l(this, "panel", null);
@@ -1806,17 +1863,15 @@ class St {
1806
1863
  width: 280px;
1807
1864
  max-height: 80vh;
1808
1865
  overflow-y: auto;
1809
- background: rgba(15, 15, 25, 0.85);
1866
+ background: rgba(255, 255, 255, 0.08);
1810
1867
  backdrop-filter: blur(20px);
1811
1868
  -webkit-backdrop-filter: blur(20px);
1812
- border: 1px solid rgba(255, 255, 255, 0.1);
1813
- border-radius: 16px;
1869
+ border: 1px solid rgba(255, 255, 255, 0.12);
1870
+ border-radius: 12px;
1814
1871
  padding: 24px;
1815
1872
  color: white;
1816
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
1817
- box-shadow:
1818
- 0 8px 32px rgba(0, 0, 0, 0.4),
1819
- inset 0 0 0 1px rgba(255, 255, 255, 0.05);
1873
+ font-family: inherit;
1874
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
1820
1875
  z-index: 1000;
1821
1876
  opacity: 0;
1822
1877
  pointer-events: none;
@@ -1852,16 +1907,9 @@ class St {
1852
1907
  if (!this.panel) return;
1853
1908
  this.currentNodeId = e.id;
1854
1909
  let t;
1855
- this.panelTemplate ? t = this.panelTemplate(e, s) : t = this.generateDefaultContent(e, s), this.panel.innerHTML = t;
1856
- const i = this.panel.querySelector('[data-action="expand"]'), o = this.panel.querySelector("[data-depth-select]");
1857
- i && this.onExpand && i.addEventListener("click", () => {
1858
- if (this.currentNodeId) {
1859
- const r = o ? parseInt(o.value, 10) : 1;
1860
- this.onExpand(this.currentNodeId, r);
1861
- }
1862
- });
1863
- const a = this.panel.querySelector('[data-action="close"]');
1864
- a && a.addEventListener("click", () => {
1910
+ this.panelTemplate ? t = this.panelTemplate(e, s) : t = this.generateDefaultContent(e, s), this.panel.innerHTML = t, this.onExpand;
1911
+ const i = this.panel.querySelector('[data-action="close"]');
1912
+ i && i.addEventListener("click", () => {
1865
1913
  this.hide();
1866
1914
  }), this.panel.style.opacity = "1", this.panel.style.pointerEvents = "auto", this.panel.style.transform = "translateY(-50%) translateX(0)", this.visible = !0;
1867
1915
  }
@@ -1874,8 +1922,8 @@ class St {
1874
1922
  <style>
1875
1923
  .force-graph-panel h2 {
1876
1924
  margin: 0 0 16px 0;
1877
- font-size: 20px;
1878
- font-weight: 600;
1925
+ font-size: 19px;
1926
+ font-weight: 650;
1879
1927
  letter-spacing: -0.5px;
1880
1928
  display: flex;
1881
1929
  align-items: center;
@@ -1893,13 +1941,13 @@ class St {
1893
1941
  height: 12px;
1894
1942
  border-radius: 50%;
1895
1943
  background: ${t};
1896
- box-shadow: 0 0 10px ${t}80;
1944
+ box-shadow: 0 0 12px ${t}80;
1897
1945
  }
1898
1946
  .force-graph-panel .info-row {
1899
1947
  display: flex;
1900
1948
  justify-content: space-between;
1901
1949
  padding: 8px 0;
1902
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
1950
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
1903
1951
  font-size: 13px;
1904
1952
  }
1905
1953
  .force-graph-panel .info-row:last-child {
@@ -1919,51 +1967,27 @@ class St {
1919
1967
  }
1920
1968
  .force-graph-panel .neighbors-section {
1921
1969
  margin-top: 16px;
1970
+ padding: 10px;
1971
+ background: rgba(255, 255, 255, 0.04);
1972
+ border: 1px solid rgba(255, 255, 255, 0.08);
1973
+ border-radius: 10px;
1922
1974
  }
1923
1975
  .force-graph-panel .neighbors-title {
1924
1976
  font-size: 12px;
1925
1977
  text-transform: uppercase;
1926
1978
  letter-spacing: 1px;
1927
- color: rgba(255, 255, 255, 0.5);
1979
+ color: rgba(255, 255, 255, 0.55);
1928
1980
  margin-bottom: 8px;
1929
1981
  }
1930
1982
  .force-graph-panel .neighbor-chip {
1931
1983
  display: inline-block;
1932
1984
  padding: 4px 10px;
1933
1985
  margin: 2px;
1934
- background: rgba(255, 255, 255, 0.1);
1986
+ background: rgba(255, 255, 255, 0.08);
1987
+ border: 1px solid rgba(255, 255, 255, 0.12);
1935
1988
  border-radius: 12px;
1936
1989
  font-size: 12px;
1937
1990
  }
1938
- .force-graph-panel .depth-selector {
1939
- margin-top: 16px;
1940
- margin-bottom: 8px;
1941
- }
1942
- .force-graph-panel .depth-label {
1943
- font-size: 12px;
1944
- color: rgba(255, 255, 255, 0.6);
1945
- margin-bottom: 6px;
1946
- text-transform: uppercase;
1947
- letter-spacing: 0.5px;
1948
- }
1949
- .force-graph-panel select {
1950
- width: 100%;
1951
- padding: 8px 12px;
1952
- background: rgba(255, 255, 255, 0.1);
1953
- border: 1px solid rgba(255, 255, 255, 0.15);
1954
- border-radius: 6px;
1955
- color: white;
1956
- font-size: 13px;
1957
- cursor: pointer;
1958
- outline: none;
1959
- transition: all 0.2s ease;
1960
- }
1961
- .force-graph-panel select:hover {
1962
- background: rgba(255, 255, 255, 0.15);
1963
- }
1964
- .force-graph-panel select:focus {
1965
- border-color: rgba(96, 165, 250, 0.5);
1966
- }
1967
1991
  .force-graph-panel .btn-row {
1968
1992
  display: flex;
1969
1993
  gap: 8px;
@@ -1972,28 +1996,24 @@ class St {
1972
1996
  .force-graph-panel button {
1973
1997
  flex: 1;
1974
1998
  padding: 10px 16px;
1975
- border: none;
1999
+ border: 1px solid rgba(255, 255, 255, 0.12);
1976
2000
  border-radius: 8px;
1977
2001
  font-size: 13px;
1978
- font-weight: 500;
2002
+ font-weight: 600;
1979
2003
  cursor: pointer;
1980
2004
  transition: all 0.2s ease;
1981
2005
  }
1982
- .force-graph-panel .btn-expand {
1983
- background: linear-gradient(135deg, #60a5fa, #a78bfa);
1984
- color: white;
1985
- }
1986
- .force-graph-panel .btn-expand:hover {
1987
- transform: translateY(-1px);
1988
- box-shadow: 0 4px 12px rgba(96, 165, 250, 0.4);
1989
- }
1990
2006
  .force-graph-panel .btn-close {
1991
- background: rgba(255, 255, 255, 0.1);
2007
+ background: rgba(255, 255, 255, 0.08);
1992
2008
  color: rgba(255, 255, 255, 0.8);
1993
2009
  }
1994
2010
  .force-graph-panel .btn-close:hover {
1995
- background: rgba(255, 255, 255, 0.15);
2011
+ background: rgba(255, 255, 255, 0.12);
1996
2012
  }
2013
+ .force-graph-panel::-webkit-scrollbar { width: 6px; }
2014
+ .force-graph-panel::-webkit-scrollbar-track { background: transparent; }
2015
+ .force-graph-panel::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.15); border-radius: 3px; }
2016
+ .force-graph-panel::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.25); }
1997
2017
  </style>
1998
2018
 
1999
2019
  <h2>
@@ -2021,18 +2041,7 @@ class St {
2021
2041
  </div>
2022
2042
  ` : ""}
2023
2043
 
2024
- <div class="depth-selector">
2025
- <div class="depth-label">Expansion Depth</div>
2026
- <select data-depth-select>
2027
- <option value="1">1 Level</option>
2028
- <option value="2">2 Levels</option>
2029
- <option value="3" selected>3 Levels</option>
2030
- </select>
2031
- </div>
2032
-
2033
-
2034
2044
  <div class="btn-row">
2035
- <button class="btn-expand" data-action="expand">Expand</button>
2036
2045
  <button class="btn-close" data-action="close">Close</button>
2037
2046
  </div>
2038
2047
  `;
@@ -2069,7 +2078,7 @@ class St {
2069
2078
  this.panel && this.panel.parentNode && this.panel.parentNode.removeChild(this.panel), this.panel = null;
2070
2079
  }
2071
2080
  }
2072
- class zt {
2081
+ class St {
2073
2082
  constructor(e) {
2074
2083
  l(this, "container");
2075
2084
  l(this, "panel", null);
@@ -2092,17 +2101,15 @@ class zt {
2092
2101
  width: 300px;
2093
2102
  max-height: 80vh;
2094
2103
  overflow-y: auto;
2095
- background: rgba(15, 15, 25, 0.85);
2104
+ background: rgba(255, 255, 255, 0.08);
2096
2105
  backdrop-filter: blur(20px);
2097
2106
  -webkit-backdrop-filter: blur(20px);
2098
- border: 1px solid rgba(255, 255, 255, 0.1);
2099
- border-radius: 16px;
2107
+ border: 1px solid rgba(255, 255, 255, 0.12);
2108
+ border-radius: 12px;
2100
2109
  padding: 24px;
2101
2110
  color: white;
2102
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
2103
- box-shadow:
2104
- 0 8px 32px rgba(0, 0, 0, 0.4),
2105
- inset 0 0 0 1px rgba(255, 255, 255, 0.05);
2111
+ font-family: inherit;
2112
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
2106
2113
  z-index: 1000;
2107
2114
  opacity: 0;
2108
2115
  pointer-events: none;
@@ -2130,29 +2137,34 @@ class zt {
2130
2137
  /**
2131
2138
  * Shows the panel with edge/relationship information
2132
2139
  */
2133
- show(e, s, t) {
2140
+ show(e, s, t, i = [e]) {
2134
2141
  if (!this.panel) return;
2135
2142
  this.currentEdgeKey = `${e.source}-${e.target}`;
2136
- let i;
2137
- this.panelTemplate ? i = this.panelTemplate(e, s, t) : i = this.generateDefaultContent(e, s, t), this.panel.innerHTML = i;
2138
- const o = this.panel.querySelector('[data-action="close"]');
2139
- o && o.addEventListener("click", () => {
2143
+ let o;
2144
+ this.panelTemplate ? o = this.panelTemplate(e, s, t) : o = this.generateDefaultContent(e, s, t, i), this.panel.innerHTML = o;
2145
+ const n = this.panel.querySelector('[data-action="close"]');
2146
+ n && n.addEventListener("click", () => {
2140
2147
  this.hide(), this.onClose && this.onClose();
2141
2148
  });
2142
- const a = this.panel.querySelector('[data-action="goto-source"]');
2143
- a && this.onNodeClick && a.addEventListener("click", () => {
2149
+ const r = this.panel.querySelector('[data-action="goto-source"]');
2150
+ r && this.onNodeClick && r.addEventListener("click", () => {
2144
2151
  this.onNodeClick && this.onNodeClick(e.source);
2145
2152
  });
2146
- const r = this.panel.querySelector('[data-action="goto-target"]');
2147
- r && this.onNodeClick && r.addEventListener("click", () => {
2153
+ const h = this.panel.querySelector('[data-action="goto-target"]');
2154
+ h && this.onNodeClick && h.addEventListener("click", () => {
2148
2155
  this.onNodeClick && this.onNodeClick(e.target);
2149
2156
  }), this.panel.style.opacity = "1", this.panel.style.pointerEvents = "auto", this.panel.style.transform = "translateY(-50%) translateX(0)", this.visible = !0;
2150
2157
  }
2151
2158
  /**
2152
2159
  * Generates default panel content
2153
2160
  */
2154
- generateDefaultContent(e, s, t) {
2155
- const i = s.color ? `#${s.color.toString(16).padStart(6, "0")}` : "#ff9966", o = t.color ? `#${t.color.toString(16).padStart(6, "0")}` : "#ff9966", a = e.relationship || "connected to";
2161
+ generateDefaultContent(e, s, t, i = [e]) {
2162
+ const o = s.color ? `#${s.color.toString(16).padStart(6, "0")}` : "#ff9966", n = t.color ? `#${t.color.toString(16).padStart(6, "0")}` : "#ff9966", r = this.getRelationshipLabel(e), h = i.length > 0 ? i : [e], c = this.summarizeRelationships(h), p = c.slice(0, 10).map((m) => `
2163
+ <div class="relationship-item">
2164
+ <span class="relationship-item-label">${this.escapeHtml(m.label)}</span>
2165
+ <span class="relationship-item-count">${m.count}</span>
2166
+ </div>
2167
+ `).join(""), f = c.length - Math.min(c.length, 10);
2156
2168
  return `
2157
2169
  <style>
2158
2170
  .force-graph-edge-panel .panel-header {
@@ -2162,28 +2174,72 @@ class zt {
2162
2174
  margin-bottom: 20px;
2163
2175
  }
2164
2176
  .force-graph-edge-panel .panel-title {
2165
- font-size: 14px;
2177
+ font-size: 12px;
2166
2178
  text-transform: uppercase;
2167
2179
  letter-spacing: 1px;
2168
- color: rgba(255, 255, 255, 0.6);
2180
+ color: rgba(255, 255, 255, 0.55);
2169
2181
  margin: 0;
2170
2182
  }
2171
2183
  .force-graph-edge-panel .relationship-section {
2172
- background: rgba(255, 255, 255, 0.05);
2184
+ background: rgba(255, 255, 255, 0.04);
2185
+ border: 1px solid rgba(255, 255, 255, 0.08);
2173
2186
  border-radius: 12px;
2174
2187
  padding: 16px;
2175
2188
  text-align: center;
2176
- margin-bottom: 20px;
2189
+ margin-bottom: 14px;
2177
2190
  }
2178
2191
  .force-graph-edge-panel .relationship-label {
2179
2192
  font-size: 18px;
2180
2193
  font-weight: 600;
2181
- color: #a78bfa;
2194
+ color: rgba(255, 153, 102, 0.95);
2182
2195
  letter-spacing: 0.5px;
2183
2196
  }
2197
+ .force-graph-edge-panel .relationship-count {
2198
+ margin-top: 6px;
2199
+ font-size: 11px;
2200
+ text-transform: uppercase;
2201
+ letter-spacing: 0.8px;
2202
+ color: rgba(255, 255, 255, 0.6);
2203
+ }
2204
+ .force-graph-edge-panel .relationship-list {
2205
+ margin-bottom: 16px;
2206
+ max-height: 190px;
2207
+ overflow-y: auto;
2208
+ padding-right: 4px;
2209
+ }
2210
+ .force-graph-edge-panel .relationship-item {
2211
+ display: flex;
2212
+ justify-content: space-between;
2213
+ gap: 12px;
2214
+ padding: 8px 10px;
2215
+ background: rgba(255, 255, 255, 0.04);
2216
+ border: 1px solid rgba(255, 255, 255, 0.08);
2217
+ border-radius: 8px;
2218
+ margin-bottom: 6px;
2219
+ }
2220
+ .force-graph-edge-panel .relationship-item-label {
2221
+ font-size: 12px;
2222
+ color: rgba(255, 255, 255, 0.88);
2223
+ overflow: hidden;
2224
+ text-overflow: ellipsis;
2225
+ white-space: nowrap;
2226
+ }
2227
+ .force-graph-edge-panel .relationship-item-count {
2228
+ font-size: 12px;
2229
+ font-weight: 700;
2230
+ color: rgba(255, 153, 102, 0.95);
2231
+ min-width: 24px;
2232
+ text-align: right;
2233
+ }
2234
+ .force-graph-edge-panel .relationship-more {
2235
+ font-size: 11px;
2236
+ color: rgba(255, 255, 255, 0.45);
2237
+ text-align: center;
2238
+ margin-top: 2px;
2239
+ }
2184
2240
  .force-graph-edge-panel .node-card {
2185
- background: rgba(255, 255, 255, 0.05);
2186
- border: 1px solid rgba(255, 255, 255, 0.1);
2241
+ background: rgba(255, 255, 255, 0.06);
2242
+ border: 1px solid rgba(255, 255, 255, 0.12);
2187
2243
  border-radius: 12px;
2188
2244
  padding: 14px;
2189
2245
  margin-bottom: 12px;
@@ -2192,8 +2248,9 @@ class zt {
2192
2248
  }
2193
2249
  .force-graph-edge-panel .node-card:hover {
2194
2250
  background: rgba(255, 255, 255, 0.1);
2195
- border-color: rgba(255, 255, 255, 0.2);
2251
+ border-color: rgba(255, 153, 102, 0.35);
2196
2252
  transform: translateX(4px);
2253
+ box-shadow: 0 0 15px rgba(255, 153, 102, 0.15);
2197
2254
  }
2198
2255
  .force-graph-edge-panel .node-card-header {
2199
2256
  display: flex;
@@ -2230,18 +2287,18 @@ class zt {
2230
2287
  .force-graph-edge-panel .btn-close {
2231
2288
  width: 100%;
2232
2289
  padding: 12px 16px;
2233
- border: none;
2290
+ border: 1px solid rgba(255, 255, 255, 0.12);
2234
2291
  border-radius: 8px;
2235
2292
  font-size: 13px;
2236
- font-weight: 500;
2293
+ font-weight: 600;
2237
2294
  cursor: pointer;
2238
2295
  transition: all 0.2s ease;
2239
- background: rgba(255, 255, 255, 0.1);
2296
+ background: rgba(255, 255, 255, 0.08);
2240
2297
  color: rgba(255, 255, 255, 0.8);
2241
2298
  margin-top: 16px;
2242
2299
  }
2243
2300
  .force-graph-edge-panel .btn-close:hover {
2244
- background: rgba(255, 255, 255, 0.15);
2301
+ background: rgba(255, 255, 255, 0.12);
2245
2302
  }
2246
2303
  .force-graph-edge-panel .hint-text {
2247
2304
  font-size: 11px;
@@ -2249,6 +2306,10 @@ class zt {
2249
2306
  text-align: center;
2250
2307
  margin-top: 8px;
2251
2308
  }
2309
+ .force-graph-edge-panel .relationship-list::-webkit-scrollbar { width: 6px; }
2310
+ .force-graph-edge-panel .relationship-list::-webkit-scrollbar-track { background: transparent; }
2311
+ .force-graph-edge-panel .relationship-list::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.15); border-radius: 3px; }
2312
+ .force-graph-edge-panel .relationship-list::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.25); }
2252
2313
  </style>
2253
2314
 
2254
2315
  <div class="panel-header">
@@ -2256,13 +2317,19 @@ class zt {
2256
2317
  </div>
2257
2318
 
2258
2319
  <div class="relationship-section">
2259
- <span class="relationship-label">${this.escapeHtml(a)}</span>
2320
+ <span class="relationship-label">${this.escapeHtml(r)}</span>
2321
+ <div class="relationship-count">${h.length} relationships</div>
2322
+ </div>
2323
+
2324
+ <div class="relationship-list">
2325
+ ${p}
2326
+ ${f > 0 ? `<div class="relationship-more">+ ${f} more</div>` : ""}
2260
2327
  </div>
2261
2328
 
2262
2329
  <div class="node-card" data-action="goto-source" title="Click to focus on ${this.escapeHtml(s.label)}">
2263
2330
  <div class="node-type">Source</div>
2264
2331
  <div class="node-card-header">
2265
- <span class="color-dot" style="background: ${i}; box-shadow: 0 0 8px ${i}80;"></span>
2332
+ <span class="color-dot" style="background: ${o}; box-shadow: 0 0 8px ${o}80;"></span>
2266
2333
  <span class="node-label">${this.escapeHtml(s.label)}</span>
2267
2334
  </div>
2268
2335
  </div>
@@ -2272,7 +2339,7 @@ class zt {
2272
2339
  <div class="node-card" data-action="goto-target" title="Click to focus on ${this.escapeHtml(t.label)}">
2273
2340
  <div class="node-type">Target</div>
2274
2341
  <div class="node-card-header">
2275
- <span class="color-dot" style="background: ${o}; box-shadow: 0 0 8px ${o}80;"></span>
2342
+ <span class="color-dot" style="background: ${n}; box-shadow: 0 0 8px ${n}80;"></span>
2276
2343
  <span class="node-label">${this.escapeHtml(t.label)}</span>
2277
2344
  </div>
2278
2345
  </div>
@@ -2289,6 +2356,17 @@ class zt {
2289
2356
  const s = document.createElement("div");
2290
2357
  return s.textContent = e, s.innerHTML;
2291
2358
  }
2359
+ getRelationshipLabel(e) {
2360
+ return e.relationship || e.label || "connected to";
2361
+ }
2362
+ summarizeRelationships(e) {
2363
+ const s = /* @__PURE__ */ new Map();
2364
+ for (const t of e) {
2365
+ const i = this.getRelationshipLabel(t);
2366
+ s.set(i, (s.get(i) || 0) + 1);
2367
+ }
2368
+ return Array.from(s.entries()).map(([t, i]) => ({ label: t, count: i })).sort((t, i) => i.count - t.count);
2369
+ }
2292
2370
  /**
2293
2371
  * Hides the panel
2294
2372
  */
@@ -2314,7 +2392,7 @@ class zt {
2314
2392
  this.panel && this.panel.parentNode && this.panel.parentNode.removeChild(this.panel), this.panel = null;
2315
2393
  }
2316
2394
  }
2317
- class kt {
2395
+ class zt {
2318
2396
  constructor() {
2319
2397
  l(this, "tooltip", null);
2320
2398
  l(this, "visible", !1);
@@ -2361,28 +2439,51 @@ class kt {
2361
2439
  positionTooltip(e, s) {
2362
2440
  if (!this.tooltip) return;
2363
2441
  const t = this.tooltip.getBoundingClientRect(), i = window.innerWidth, o = window.innerHeight;
2364
- let a = e + 15, r = s + 15;
2365
- a + t.width > i - 10 && (a = e - t.width - 15), r + t.height > o - 10 && (r = s - t.height - 15), a < 10 && (a = 10), r < 10 && (r = 10), this.tooltip.style.left = `${a}px`, this.tooltip.style.top = `${r}px`;
2442
+ let n = e + 15, r = s + 15;
2443
+ n + t.width > i - 10 && (n = e - t.width - 15), r + t.height > o - 10 && (r = s - t.height - 15), n < 10 && (n = 10), r < 10 && (r = 10), this.tooltip.style.left = `${n}px`, this.tooltip.style.top = `${r}px`;
2366
2444
  }
2367
2445
  /**
2368
2446
  * Shows the tooltip with edge info
2369
2447
  */
2370
- show(e, s, t, i, o) {
2448
+ show(e, s, t, i, o, n = [e]) {
2371
2449
  if (!this.tooltip) return;
2372
- const a = e.relationship || "connected to";
2373
- this.tooltip.innerHTML = `
2374
- <div style="display: flex; flex-direction: column; gap: 4px;">
2375
- <div style="display: flex; align-items: center; gap: 6px; flex-wrap: wrap;">
2376
- <span style="font-weight: 600; color: #ff9966;">${this.escapeHtml(s.label)}</span>
2377
- </div>
2378
- <div style="color: rgba(255, 255, 255, 0.6); font-style: italic; font-size: 12px; padding-left: 8px;">
2379
- ↳ ${this.escapeHtml(a)}
2450
+ const r = n.length > 0 ? n : [e], h = this.summarizeRelationships(r), c = r.length;
2451
+ if (c <= 1) {
2452
+ const p = this.getRelationshipLabel(r[0]);
2453
+ this.tooltip.innerHTML = `
2454
+ <div style="display: flex; flex-direction: column; gap: 4px;">
2455
+ <div style="display: flex; align-items: center; gap: 6px; flex-wrap: wrap;">
2456
+ <span style="font-weight: 600; color: #ff9966;">${this.escapeHtml(s.label)}</span>
2457
+ </div>
2458
+ <div style="color: rgba(255, 255, 255, 0.6); font-style: italic; font-size: 12px; padding-left: 8px;">
2459
+ ↳ ${this.escapeHtml(p)}
2460
+ </div>
2461
+ <div style="display: flex; align-items: center; gap: 6px; flex-wrap: wrap;">
2462
+ <span style="font-weight: 600; color: #ff9966;">${this.escapeHtml(t.label)}</span>
2463
+ </div>
2380
2464
  </div>
2381
- <div style="display: flex; align-items: center; gap: 6px; flex-wrap: wrap;">
2382
- <span style="font-weight: 600; color: #ff9966;">${this.escapeHtml(t.label)}</span>
2465
+ `;
2466
+ } else {
2467
+ const p = h.slice(0, 4), f = h.length - p.length, m = p.map((u) => `<div style="display:flex; justify-content:space-between; gap:10px; font-size:12px; color: rgba(255,255,255,0.8);">
2468
+ <span style="overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">${this.escapeHtml(u.label)}</span>
2469
+ <span style="color: rgba(255,153,102,0.9); font-weight:600;">${u.count}</span>
2470
+ </div>`).join("");
2471
+ this.tooltip.innerHTML = `
2472
+ <div style="display:flex; flex-direction:column; gap:8px; min-width:220px;">
2473
+ <div style="font-size:13px; font-weight:600; color:#ff9966;">
2474
+ ${this.escapeHtml(s.label)} → ${this.escapeHtml(t.label)}
2475
+ </div>
2476
+ <div style="font-size:11px; letter-spacing:0.4px; text-transform:uppercase; color: rgba(255,255,255,0.6);">
2477
+ ${c} relationships
2478
+ </div>
2479
+ <div style="display:flex; flex-direction:column; gap:4px;">
2480
+ ${m}
2481
+ </div>
2482
+ ${f > 0 ? `<div style="font-size:11px; color: rgba(255,255,255,0.45);">+ ${f} more</div>` : ""}
2383
2483
  </div>
2384
- </div>
2385
- `, this.positionTooltip(i, o), this.tooltip.style.opacity = "1", this.tooltip.style.transform = "translateY(0)", this.visible = !0;
2484
+ `;
2485
+ }
2486
+ this.positionTooltip(i, o), this.tooltip.style.opacity = "1", this.tooltip.style.transform = "translateY(0)", this.visible = !0;
2386
2487
  }
2387
2488
  /**
2388
2489
  * Updates tooltip position (called externally on mouse move)
@@ -2409,6 +2510,17 @@ class kt {
2409
2510
  const s = document.createElement("div");
2410
2511
  return s.textContent = e, s.innerHTML;
2411
2512
  }
2513
+ getRelationshipLabel(e) {
2514
+ return e.relationship || e.label || "connected to";
2515
+ }
2516
+ summarizeRelationships(e) {
2517
+ const s = /* @__PURE__ */ new Map();
2518
+ for (const t of e) {
2519
+ const i = this.getRelationshipLabel(t);
2520
+ s.set(i, (s.get(i) || 0) + 1);
2521
+ }
2522
+ return Array.from(s.entries()).map(([t, i]) => ({ label: t, count: i })).sort((t, i) => i.count - t.count);
2523
+ }
2412
2524
  /**
2413
2525
  * Dispose the tooltip
2414
2526
  */
@@ -2416,7 +2528,7 @@ class kt {
2416
2528
  this.tooltip && this.tooltip.parentNode && this.tooltip.parentNode.removeChild(this.tooltip), this.tooltip = null;
2417
2529
  }
2418
2530
  }
2419
- class Tt {
2531
+ class kt {
2420
2532
  constructor(e, s) {
2421
2533
  l(this, "container");
2422
2534
  l(this, "searchContainer", null);
@@ -2561,24 +2673,24 @@ class Tt {
2561
2673
  }
2562
2674
  let i = "";
2563
2675
  s.length > 0 && (i += '<div class="f3d-search-section-header">Nodes</div>', s.slice(0, 10).forEach((o) => {
2564
- const a = o.type || "Node";
2676
+ const n = o.type || "Node";
2565
2677
  i += `
2566
2678
  <div class="f3d-search-result-item" data-node-id="${this.escapeHtml(o.id)}">
2567
2679
  <div class="f3d-result-label">${this.escapeHtml(o.label)}</div>
2568
- <div class="f3d-result-type">${this.escapeHtml(a)}</div>
2680
+ <div class="f3d-result-type">${this.escapeHtml(n)}</div>
2569
2681
  </div>
2570
2682
  `;
2571
- }), s.length > 10 && (i += `<div class="f3d-no-results">+ ${s.length - 10} more nodes</div>`)), t.length > 0 && (i += '<div class="f3d-search-section-header">Relationships</div>', t.slice(0, 5).forEach(({ edge: o, sourceNode: a, targetNode: r }) => {
2683
+ }), s.length > 10 && (i += `<div class="f3d-no-results">+ ${s.length - 10} more nodes</div>`)), t.length > 0 && (i += '<div class="f3d-search-section-header">Relationships</div>', t.slice(0, 5).forEach(({ edge: o, sourceNode: n, targetNode: r }) => {
2572
2684
  i += `
2573
2685
  <div class="f3d-search-result-item" data-node-id="${this.escapeHtml(o.source)}">
2574
- <div class="f3d-result-label">${this.escapeHtml(a.label)} → ${this.escapeHtml(r.label)}</div>
2686
+ <div class="f3d-result-label">${this.escapeHtml(n.label)} → ${this.escapeHtml(r.label)}</div>
2575
2687
  <div class="f3d-result-relationship">${this.escapeHtml(o.relationship || "connected")}</div>
2576
2688
  </div>
2577
2689
  `;
2578
2690
  }), t.length > 5 && (i += `<div class="f3d-no-results">+ ${t.length - 5} more relationships</div>`)), this.searchResults.innerHTML = i, this.searchResults.style.display = "block", this.searchResults.querySelectorAll(".f3d-search-result-item").forEach((o) => {
2579
2691
  o.addEventListener("click", () => {
2580
- const a = o.dataset.nodeId;
2581
- a && (this.onResultClick(a), this.searchResults && (this.searchResults.style.display = "none"), this.searchInput && this.searchInput.blur());
2692
+ const n = o.dataset.nodeId;
2693
+ n && (this.onResultClick(n), this.searchResults && (this.searchResults.style.display = "none"), this.searchInput && this.searchInput.blur());
2582
2694
  });
2583
2695
  });
2584
2696
  }
@@ -2590,7 +2702,7 @@ class Tt {
2590
2702
  this.searchContainer && this.searchContainer.parentNode && this.searchContainer.parentNode.removeChild(this.searchContainer);
2591
2703
  }
2592
2704
  }
2593
- class Pt {
2705
+ class Tt {
2594
2706
  constructor(e, s) {
2595
2707
  l(this, "container");
2596
2708
  l(this, "toggleContainer", null);
@@ -2682,7 +2794,7 @@ class Pt {
2682
2794
  this.toggleContainer && this.toggleContainer.parentNode && this.toggleContainer.parentNode.removeChild(this.toggleContainer);
2683
2795
  }
2684
2796
  }
2685
- class Lt {
2797
+ class Pt {
2686
2798
  constructor(e) {
2687
2799
  l(this, "container");
2688
2800
  l(this, "legendContainer", null);
@@ -2778,7 +2890,7 @@ const Rt = {
2778
2890
  damping: 0.85
2779
2891
  // Fast energy dissipation
2780
2892
  };
2781
- class It {
2893
+ class Lt {
2782
2894
  constructor(e, s = {}) {
2783
2895
  l(this, "container");
2784
2896
  l(this, "canvas");
@@ -2818,21 +2930,21 @@ class It {
2818
2930
  setupInteractions() {
2819
2931
  this.canvas.addEventListener("wheel", (e) => {
2820
2932
  e.preventDefault();
2821
- const s = this.canvas.getBoundingClientRect(), t = e.clientX - s.left, i = e.clientY - s.top, o = e.deltaY > 0 ? 0.9 : 1.1, a = Math.max(0.1, Math.min(5, this.transform.scale * o)), r = a / this.transform.scale;
2822
- this.transform.x = t - (t - this.transform.x) * r, this.transform.y = i - (i - this.transform.y) * r, this.transform.scale = a;
2933
+ const s = this.canvas.getBoundingClientRect(), t = e.clientX - s.left, i = e.clientY - s.top, o = e.deltaY > 0 ? 0.9 : 1.1, n = Math.max(0.1, Math.min(5, this.transform.scale * o)), r = n / this.transform.scale;
2934
+ this.transform.x = t - (t - this.transform.x) * r, this.transform.y = i - (i - this.transform.y) * r, this.transform.scale = n;
2823
2935
  }), this.canvas.addEventListener("mousedown", (e) => {
2824
- const s = this.canvas.getBoundingClientRect(), t = e.clientX - s.left, i = e.clientY - s.top, o = this.screenToWorld(t, i), a = this.findNodeAt(o.x, o.y);
2825
- this.dragStartPos = { x: e.clientX, y: e.clientY }, a ? (this.isDragging = !0, this.draggedNode = a, this.canvas.style.cursor = "grabbing", this.isSimulating = !0) : (this.isPanning = !0, this.canvas.style.cursor = "grabbing"), this.lastMousePos = { x: e.clientX, y: e.clientY };
2936
+ const s = this.canvas.getBoundingClientRect(), t = e.clientX - s.left, i = e.clientY - s.top, o = this.screenToWorld(t, i), n = this.findNodeAt(o.x, o.y);
2937
+ this.dragStartPos = { x: e.clientX, y: e.clientY }, n ? (this.isDragging = !0, this.draggedNode = n, this.canvas.style.cursor = "grabbing", this.isSimulating = !0) : (this.isPanning = !0, this.canvas.style.cursor = "grabbing"), this.lastMousePos = { x: e.clientX, y: e.clientY };
2826
2938
  }), this.canvas.addEventListener("mousemove", (e) => {
2827
2939
  const s = this.canvas.getBoundingClientRect(), t = e.clientX - s.left, i = e.clientY - s.top, o = this.screenToWorld(t, i);
2828
2940
  if (this.isDragging && this.draggedNode)
2829
2941
  this.draggedNode.x = o.x, this.draggedNode.y = o.y, this.draggedNode.vx = 0, this.draggedNode.vy = 0;
2830
2942
  else if (this.isPanning) {
2831
- const a = e.clientX - this.lastMousePos.x, r = e.clientY - this.lastMousePos.y;
2832
- this.transform.x += a, this.transform.y += r, this.lastMousePos = { x: e.clientX, y: e.clientY };
2943
+ const n = e.clientX - this.lastMousePos.x, r = e.clientY - this.lastMousePos.y;
2944
+ this.transform.x += n, this.transform.y += r, this.lastMousePos = { x: e.clientX, y: e.clientY };
2833
2945
  } else {
2834
- const a = this.findNodeAt(o.x, o.y);
2835
- if (a !== this.hoveredNode && (this.hoveredNode = a, a ? (this.hoveredEdge && (this.hoveredEdge = null, this.options.onEdgeHover && this.options.onEdgeHover(null)), this.canvas.style.cursor = "pointer", this.options.onNodeHover && this.options.onNodeHover(a.data)) : this.options.onNodeHover && this.options.onNodeHover(null)), !a) {
2946
+ const n = this.findNodeAt(o.x, o.y);
2947
+ if (n !== this.hoveredNode && (this.hoveredNode = n, n ? (this.hoveredEdge && (this.hoveredEdge = null, this.options.onEdgeHover && this.options.onEdgeHover(null)), this.canvas.style.cursor = "pointer", this.options.onNodeHover && this.options.onNodeHover(n.data)) : this.options.onNodeHover && this.options.onNodeHover(null)), !n) {
2836
2948
  const r = this.findEdgeAt(o.x, o.y);
2837
2949
  r !== this.hoveredEdge && (this.hoveredEdge = r, this.canvas.style.cursor = r ? "pointer" : "grab", this.options.onEdgeHover && this.options.onEdgeHover(r ? r.data : null, e));
2838
2950
  }
@@ -2842,7 +2954,7 @@ class It {
2842
2954
  if (this.isDragging && this.draggedNode)
2843
2955
  i && this.options.onNodeClick && (this.selectedNode = this.draggedNode, this.options.onNodeClick(this.draggedNode.data));
2844
2956
  else if (i) {
2845
- const o = this.canvas.getBoundingClientRect(), a = this.screenToWorld(e.clientX - o.left, e.clientY - o.top), r = this.findEdgeAt(a.x, a.y);
2957
+ const o = this.canvas.getBoundingClientRect(), n = this.screenToWorld(e.clientX - o.left, e.clientY - o.top), r = this.findEdgeAt(n.x, n.y);
2846
2958
  r && this.options.onEdgeClick && this.options.onEdgeClick(r.data);
2847
2959
  }
2848
2960
  this.isDragging = !1, this.isPanning = !1, this.draggedNode = null, this.canvas.style.cursor = this.hoveredNode ? "pointer" : "grab";
@@ -2866,12 +2978,12 @@ class It {
2866
2978
  }
2867
2979
  findEdgeAt(e, s) {
2868
2980
  for (const i of this.edges) {
2869
- const o = this.nodes.get(i.source), a = this.nodes.get(i.target);
2870
- if (!o || !a) continue;
2871
- const r = a.x - o.x, c = a.y - o.y, d = r * r + c * c;
2872
- if (d === 0) continue;
2873
- const p = Math.max(0, Math.min(1, ((e - o.x) * r + (s - o.y) * c) / d)), x = o.x + p * r, m = o.y + p * c, u = e - x, f = s - m;
2874
- if (Math.sqrt(u * u + f * f) < 12)
2981
+ const o = this.nodes.get(i.source), n = this.nodes.get(i.target);
2982
+ if (!o || !n) continue;
2983
+ const r = n.x - o.x, h = n.y - o.y, c = r * r + h * h;
2984
+ if (c === 0) continue;
2985
+ const p = Math.max(0, Math.min(1, ((e - o.x) * r + (s - o.y) * h) / c)), f = o.x + p * r, m = o.y + p * h, u = e - f, y = s - m;
2986
+ if (Math.sqrt(u * u + y * y) < 12)
2875
2987
  return i;
2876
2988
  }
2877
2989
  return null;
@@ -2888,29 +3000,29 @@ class It {
2888
3000
  const t = 60, i = 5;
2889
3001
  let o = 0;
2890
3002
  for (let r = 0; r < s; r++)
2891
- for (let c = r + 1; c < s; c++) {
2892
- const d = e[r], p = e[c];
2893
- let x = p.x - d.x, m = p.y - d.y, u = Math.sqrt(x * x + m * m);
3003
+ for (let h = r + 1; h < s; h++) {
3004
+ const c = e[r], p = e[h];
3005
+ let f = p.x - c.x, m = p.y - c.y, u = Math.sqrt(f * f + m * m);
2894
3006
  if (u < t * 3) {
2895
3007
  u < 1 && (u = 1);
2896
- const f = this.options.repulsionStrength / (u * u), b = x / u * f, M = m / u * f;
2897
- d.vx -= b, d.vy -= M, p.vx += b, p.vy += M;
3008
+ const y = this.options.repulsionStrength / (u * u), b = f / u * y, w = m / u * y;
3009
+ c.vx -= b, c.vy -= w, p.vx += b, p.vy += w;
2898
3010
  }
2899
3011
  }
2900
- const a = 80;
3012
+ const n = 80;
2901
3013
  for (const r of this.edges) {
2902
- const c = this.nodes.get(r.source), d = this.nodes.get(r.target);
2903
- if (!c || !d) continue;
2904
- let p = d.x - c.x, x = d.y - c.y, m = Math.sqrt(p * p + x * x);
3014
+ const h = this.nodes.get(r.source), c = this.nodes.get(r.target);
3015
+ if (!h || !c) continue;
3016
+ let p = c.x - h.x, f = c.y - h.y, m = Math.sqrt(p * p + f * f);
2905
3017
  m < 1 && (m = 1);
2906
- const f = (m - a) * this.options.attractionStrength, b = p / m * f, M = x / m * f;
2907
- c.vx += b, c.vy += M, d.vx -= b, d.vy -= M;
3018
+ const y = (m - n) * this.options.attractionStrength, b = p / m * y, w = f / m * y;
3019
+ h.vx += b, h.vy += w, c.vx -= b, c.vy -= w;
2908
3020
  }
2909
3021
  for (const r of e) {
2910
3022
  if (this.draggedNode === r) continue;
2911
3023
  r.vx *= this.options.damping, r.vy *= this.options.damping;
2912
- const c = Math.sqrt(r.vx * r.vx + r.vy * r.vy);
2913
- c > i && (r.vx = r.vx / c * i, r.vy = r.vy / c * i), r.x += r.vx, r.y += r.vy, o += r.vx * r.vx + r.vy * r.vy;
3024
+ const h = Math.sqrt(r.vx * r.vx + r.vy * r.vy);
3025
+ h > i && (r.vx = r.vx / h * i, r.vy = r.vy / h * i), r.x += r.vx, r.y += r.vy, o += r.vx * r.vx + r.vy * r.vy;
2914
3026
  }
2915
3027
  o < 0.01 && !this.draggedNode && (this.isSimulating = !1);
2916
3028
  }
@@ -2919,49 +3031,49 @@ class It {
2919
3031
  e.fillStyle = this.options.backgroundColor, e.fillRect(0, 0, s, t), this.renderGrid(s, t), e.save(), e.translate(this.transform.x, this.transform.y), e.scale(this.transform.scale, this.transform.scale), this.renderEdges(), this.renderNodes(), e.restore();
2920
3032
  }
2921
3033
  renderGrid(e, s) {
2922
- const t = this.ctx, i = 40 * this.transform.scale, o = 1.5, a = this.transform.x % i, r = this.transform.y % i;
3034
+ const t = this.ctx, i = 40 * this.transform.scale, o = 1.5, n = this.transform.x % i, r = this.transform.y % i;
2923
3035
  t.fillStyle = this.options.gridColor;
2924
- for (let c = a; c < e; c += i)
2925
- for (let d = r; d < s; d += i)
2926
- t.beginPath(), t.arc(c, d, o, 0, Math.PI * 2), t.fill();
3036
+ for (let h = n; h < e; h += i)
3037
+ for (let c = r; c < s; c += i)
3038
+ t.beginPath(), t.arc(h, c, o, 0, Math.PI * 2), t.fill();
2927
3039
  }
2928
3040
  renderEdges() {
2929
3041
  const e = this.ctx;
2930
3042
  for (const s of this.edges) {
2931
3043
  const t = this.nodes.get(s.source), i = this.nodes.get(s.target);
2932
3044
  if (!t || !i) continue;
2933
- const o = s === this.hoveredEdge, a = e.createLinearGradient(t.x, t.y, i.x, i.y);
2934
- o ? (a.addColorStop(0, "rgba(255, 153, 102, 0.8)"), a.addColorStop(0.5, "rgba(255, 255, 255, 0.5)"), a.addColorStop(1, "rgba(102, 153, 255, 0.8)"), e.lineWidth = 3) : (a.addColorStop(0, "rgba(255, 153, 102, 0.3)"), a.addColorStop(0.5, "rgba(255, 255, 255, 0.15)"), a.addColorStop(1, "rgba(102, 153, 255, 0.3)"), e.lineWidth = 1.5), e.beginPath(), e.moveTo(t.x, t.y), e.lineTo(i.x, i.y), e.strokeStyle = a, e.stroke();
3045
+ const o = s === this.hoveredEdge, n = e.createLinearGradient(t.x, t.y, i.x, i.y);
3046
+ o ? (n.addColorStop(0, "rgba(255, 153, 102, 0.8)"), n.addColorStop(0.5, "rgba(255, 255, 255, 0.5)"), n.addColorStop(1, "rgba(102, 153, 255, 0.8)"), e.lineWidth = 3) : (n.addColorStop(0, "rgba(255, 153, 102, 0.3)"), n.addColorStop(0.5, "rgba(255, 255, 255, 0.15)"), n.addColorStop(1, "rgba(102, 153, 255, 0.3)"), e.lineWidth = 1.5), e.beginPath(), e.moveTo(t.x, t.y), e.lineTo(i.x, i.y), e.strokeStyle = n, e.stroke();
2935
3047
  }
2936
3048
  }
2937
3049
  renderNodes() {
2938
3050
  const e = this.ctx;
2939
3051
  for (const s of this.nodes.values()) {
2940
- const t = s === this.hoveredNode, i = s === this.selectedNode, o = this.hoveredEdge && (s.data.id === this.hoveredEdge.source || s.data.id === this.hoveredEdge.target), a = s.radius * (t ? 1.1 : 1);
3052
+ const t = s === this.hoveredNode, i = s === this.selectedNode, o = this.hoveredEdge && (s.data.id === this.hoveredEdge.source || s.data.id === this.hoveredEdge.target), n = s.radius * (t ? 1.1 : 1);
2941
3053
  if (t || i || o) {
2942
- const f = e.createRadialGradient(
3054
+ const y = e.createRadialGradient(
2943
3055
  s.x,
2944
3056
  s.y,
2945
- a * 0.5,
3057
+ n * 0.5,
2946
3058
  s.x,
2947
3059
  s.y,
2948
- a * 2
3060
+ n * 2
2949
3061
  ), b = t || i ? 0.4 : 0.25;
2950
- f.addColorStop(0, `rgba(255, 153, 102, ${b})`), f.addColorStop(1, "rgba(255, 153, 102, 0)"), e.fillStyle = f, e.beginPath(), e.arc(s.x, s.y, a * 2, 0, Math.PI * 2), e.fill();
3062
+ y.addColorStop(0, `rgba(255, 153, 102, ${b})`), y.addColorStop(1, "rgba(255, 153, 102, 0)"), e.fillStyle = y, e.beginPath(), e.arc(s.x, s.y, n * 2, 0, Math.PI * 2), e.fill();
2951
3063
  }
2952
3064
  const r = e.createRadialGradient(
2953
- s.x - a * 0.3,
2954
- s.y - a * 0.3,
3065
+ s.x - n * 0.3,
3066
+ s.y - n * 0.3,
2955
3067
  0,
2956
3068
  s.x,
2957
3069
  s.y,
2958
- a
2959
- ), c = s.color >> 16 & 255, d = s.color >> 8 & 255, p = s.color & 255;
2960
- r.addColorStop(0, `rgba(${Math.min(255, c + 60)}, ${Math.min(255, d + 60)}, ${Math.min(255, p + 60)}, 0.95)`), r.addColorStop(0.7, `rgba(${c}, ${d}, ${p}, 0.9)`), r.addColorStop(1, `rgba(${Math.max(0, c - 40)}, ${Math.max(0, d - 40)}, ${Math.max(0, p - 40)}, 0.85)`), e.beginPath(), e.arc(s.x, s.y, a, 0, Math.PI * 2), e.fillStyle = r, e.fill(), e.strokeStyle = "rgba(255, 255, 255, 0.2)", e.lineWidth = 1, e.stroke(), e.beginPath(), e.arc(s.x - a * 0.25, s.y - a * 0.25, a * 0.3, 0, Math.PI * 2), e.fillStyle = "rgba(255, 255, 255, 0.15)", e.fill(), e.fillStyle = "white", e.font = "600 11px Inter, -apple-system, BlinkMacSystemFont, sans-serif", e.textAlign = "center", e.textBaseline = "middle";
2961
- const x = a * 1.6;
3070
+ n
3071
+ ), h = s.color >> 16 & 255, c = s.color >> 8 & 255, p = s.color & 255;
3072
+ r.addColorStop(0, `rgba(${Math.min(255, h + 60)}, ${Math.min(255, c + 60)}, ${Math.min(255, p + 60)}, 0.95)`), r.addColorStop(0.7, `rgba(${h}, ${c}, ${p}, 0.9)`), r.addColorStop(1, `rgba(${Math.max(0, h - 40)}, ${Math.max(0, c - 40)}, ${Math.max(0, p - 40)}, 0.85)`), e.beginPath(), e.arc(s.x, s.y, n, 0, Math.PI * 2), e.fillStyle = r, e.fill(), e.strokeStyle = "rgba(255, 255, 255, 0.2)", e.lineWidth = 1, e.stroke(), e.beginPath(), e.arc(s.x - n * 0.25, s.y - n * 0.25, n * 0.3, 0, Math.PI * 2), e.fillStyle = "rgba(255, 255, 255, 0.15)", e.fill(), e.fillStyle = "white", e.font = "600 11px Inter, -apple-system, BlinkMacSystemFont, sans-serif", e.textAlign = "center", e.textBaseline = "middle";
3073
+ const f = n * 1.6;
2962
3074
  let m = s.label, u = e.measureText(m).width;
2963
- if (u > x) {
2964
- for (; u > x && m.length > 3; )
3075
+ if (u > f) {
3076
+ for (; u > f && m.length > 3; )
2965
3077
  m = m.slice(0, -1), u = e.measureText(m + "...").width;
2966
3078
  m += "...";
2967
3079
  }
@@ -3064,11 +3176,11 @@ class It {
3064
3176
  focusOnNode(e) {
3065
3177
  const s = this.nodes.get(e);
3066
3178
  if (!s) return;
3067
- const t = this.canvas.width / 2 / (window.devicePixelRatio || 1) - s.x * this.transform.scale, i = this.canvas.height / 2 / (window.devicePixelRatio || 1) - s.y * this.transform.scale, o = this.transform.x, a = this.transform.y, r = 500, c = performance.now(), d = () => {
3068
- const p = performance.now() - c, x = Math.min(p / r, 1), m = 1 - Math.pow(1 - x, 3);
3069
- this.transform.x = o + (t - o) * m, this.transform.y = a + (i - a) * m, x < 1 ? requestAnimationFrame(d) : this.selectedNode = s;
3179
+ const t = this.canvas.width / 2 / (window.devicePixelRatio || 1) - s.x * this.transform.scale, i = this.canvas.height / 2 / (window.devicePixelRatio || 1) - s.y * this.transform.scale, o = this.transform.x, n = this.transform.y, r = 500, h = performance.now(), c = () => {
3180
+ const p = performance.now() - h, f = Math.min(p / r, 1), m = 1 - Math.pow(1 - f, 3);
3181
+ this.transform.x = o + (t - o) * m, this.transform.y = n + (i - n) * m, f < 1 ? requestAnimationFrame(c) : this.selectedNode = s;
3070
3182
  };
3071
- d();
3183
+ c();
3072
3184
  }
3073
3185
  /**
3074
3186
  * Updates node positions from 3D data
@@ -3146,7 +3258,7 @@ class Ht {
3146
3258
  l(this, "devControls", null);
3147
3259
  l(this, "viewMode", "3d");
3148
3260
  l(this, "graphData", null);
3149
- this.options = { ...P, ...s }, this.container = ht(e), this.materialFactory = new vt(), this.nodeFactory = new Mt(
3261
+ this.options = { ...P, ...s }, this.container = ht(e), this.materialFactory = new bt(), this.nodeFactory = new vt(
3150
3262
  this.materialFactory,
3151
3263
  this.options.nodeRadius ?? P.nodeRadius,
3152
3264
  this.options.lodSegments ?? P.lodSegments,
@@ -3155,14 +3267,14 @@ class Ht {
3155
3267
  this.materialFactory,
3156
3268
  this.options.edgeColor ?? P.edgeColor,
3157
3269
  this.options.edgeOpacity ?? P.edgeOpacity
3158
- ), this.sceneManager = new mt(this.container, this.options), this.lodManager = new Et(
3270
+ ), this.sceneManager = new ft(this.container, this.options), this.lodManager = new Mt(
3159
3271
  this.sceneManager.camera,
3160
3272
  this.options.lodDistances ?? P.lodDistances,
3161
3273
  this.options.enableLOD ?? P.enableLOD
3162
- ), this.frustumCuller = new Ct(
3274
+ ), this.frustumCuller = new Et(
3163
3275
  this.sceneManager.camera,
3164
3276
  this.options.enableEdgeCulling ?? P.enableEdgeCulling
3165
- ), this.nodeManager = new te(this.sceneManager, this.nodeFactory), this.edgeManager = new yt(this.sceneManager, this.nodeManager, this.edgeFactory), this.graphEngine = new Ie(
3277
+ ), this.nodeManager = new ee(this.sceneManager, this.nodeFactory), this.edgeManager = new mt(this.sceneManager, this.nodeManager, this.edgeFactory), this.graphEngine = new Le(
3166
3278
  this.nodeManager.getAllNodes(),
3167
3279
  this.edgeManager.getAllEdges(),
3168
3280
  {
@@ -3172,16 +3284,16 @@ class Ht {
3172
3284
  useBarnesHut: this.options.useBarnesHut,
3173
3285
  barnesHutTheta: this.options.barnesHutTheta
3174
3286
  }
3175
- ), this.rendererManager = new bt(
3287
+ ), this.rendererManager = new xt(
3176
3288
  this.sceneManager,
3177
3289
  () => this.onSimulate(),
3178
3290
  () => this.onRender(),
3179
3291
  this.options.targetFPS ?? P.targetFPS
3180
- ), this.raycasterManager = new Nt(this.sceneManager, this.container), this.panelManager = new St(this.container), this.edgePanelManager = new zt(this.container), this.edgeTooltipManager = new kt(), this.edgePanelManager.setNodeClickCallback((t) => {
3292
+ ), this.raycasterManager = new Ct(this.sceneManager, this.container), this.panelManager = new Nt(this.container), this.edgePanelManager = new St(this.container), this.edgeTooltipManager = new zt(), this.edgePanelManager.setNodeClickCallback((t) => {
3181
3293
  this.edgePanelManager.hide(), this.focusOnNode(t), setTimeout(() => {
3182
3294
  this.showNodePanel(t);
3183
3295
  }, 400);
3184
- }), this.options.showSearch !== !1 && (this.searchManager = new Tt(this.container, {
3296
+ }), this.options.showSearch !== !1 && (this.searchManager = new kt(this.container, {
3185
3297
  placeholder: this.options.searchPlaceholder,
3186
3298
  onSearch: (t) => ({
3187
3299
  nodeResults: this.searchNodes(t),
@@ -3192,12 +3304,12 @@ class Ht {
3192
3304
  this.showNodePanel(t);
3193
3305
  }, 400);
3194
3306
  }
3195
- })), this.options.showViewToggle !== !1 && (this.viewMode = this.options.initialViewMode || "3d", this.viewToggleManager = new Pt(this.container, {
3307
+ })), this.options.showViewToggle !== !1 && (this.viewMode = this.options.initialViewMode || "3d", this.viewToggleManager = new Tt(this.container, {
3196
3308
  initialMode: this.viewMode,
3197
3309
  onViewChange: (t) => {
3198
3310
  this.switchView(t);
3199
3311
  }
3200
- })), this.options.showLegend !== !1 && (this.legendManager = new Lt(this.container), this.updateLegendCounts()), this.setupCallbacks(), this.rendererManager.start(), this.initialized = !0, this.emit("ready");
3312
+ })), this.options.showLegend !== !1 && (this.legendManager = new Pt(this.container), this.updateLegendCounts()), this.setupCallbacks(), this.rendererManager.start(), this.initialized = !0, this.emit("ready");
3201
3313
  }
3202
3314
  /**
3203
3315
  * Sets up internal callbacks
@@ -3220,7 +3332,14 @@ class Ht {
3220
3332
  if (e) {
3221
3333
  this.edgeManager.highlightEdge(e.edge.source, e.edge.target);
3222
3334
  const s = this.container.getBoundingClientRect(), t = s.left + s.width / 2, i = s.top + s.height / 2;
3223
- this.edgeTooltipManager.show(e.edge, e.sourceNode, e.targetNode, t, i), this.options.onEdgeHover && this.options.onEdgeHover(e.edge, e.sourceNode, e.targetNode), this.emit("edgeHover", e.edge, e.sourceNode, e.targetNode);
3335
+ this.edgeTooltipManager.show(
3336
+ e.edge,
3337
+ e.sourceNode,
3338
+ e.targetNode,
3339
+ t,
3340
+ i,
3341
+ e.relationships
3342
+ ), this.options.onEdgeHover && this.options.onEdgeHover(e.edge, e.sourceNode, e.targetNode), this.emit("edgeHover", e.edge, e.sourceNode, e.targetNode);
3224
3343
  } else
3225
3344
  this.edgeManager.unhighlightCurrentEdge(), this.edgeTooltipManager.hide(), this.options.onEdgeHover && this.options.onEdgeHover(null, null, null), this.emit("edgeHover", null, null, null);
3226
3345
  }
@@ -3236,7 +3355,7 @@ class Ht {
3236
3355
  * Handles edge click
3237
3356
  */
3238
3357
  onEdgeClick(e) {
3239
- this.panelManager.hide(), this.edgeTooltipManager.hide(), this.edgeManager.highlightEdge(e.edge.source, e.edge.target), this.edgePanelManager.show(e.edge, e.sourceNode, e.targetNode), this.focusOnEdge(e.edge.source, e.edge.target), this.emit("edgeClick", e.edge, e.sourceNode, e.targetNode);
3358
+ this.panelManager.hide(), this.edgeTooltipManager.hide(), this.edgeManager.highlightEdge(e.edge.source, e.edge.target), this.edgePanelManager.show(e.edge, e.sourceNode, e.targetNode, e.relationships), this.focusOnEdge(e.edge.source, e.edge.target), this.emit("edgeClick", e.edge, e.sourceNode, e.targetNode);
3240
3359
  }
3241
3360
  /**
3242
3361
  * Called every simulation step
@@ -3269,8 +3388,8 @@ class Ht {
3269
3388
  * Sets the graph data
3270
3389
  */
3271
3390
  setData(e) {
3272
- var a;
3273
- const s = (a = e.data) != null && a.nodes ? e.data : e, i = (s.edges || s.links || []).map((r) => ({
3391
+ var n;
3392
+ const s = (n = e.data) != null && n.nodes ? e.data : e, i = (s.edges || s.links || []).map((r) => ({
3274
3393
  ...r,
3275
3394
  relationship: r.relationship || r.label || "related_to"
3276
3395
  })), o = {
@@ -3278,14 +3397,14 @@ class Ht {
3278
3397
  edges: i
3279
3398
  };
3280
3399
  if (this.graphData = o, this.edgeManager.clear(), this.nodeManager.clear(), o.nodes && Array.isArray(o.nodes)) {
3281
- te.setExpectedNodeCount(o.nodes.length);
3400
+ ee.setExpectedNodeCount(o.nodes.length);
3282
3401
  for (const r of o.nodes)
3283
3402
  this.addNode(r);
3284
3403
  }
3285
3404
  if (o.edges && Array.isArray(o.edges))
3286
3405
  for (const r of o.edges)
3287
3406
  this.addEdge(r);
3288
- this.graphEngine = new Ie(
3407
+ this.graphEngine = new Le(
3289
3408
  this.nodeManager.getAllNodes(),
3290
3409
  this.edgeManager.getAllEdges(),
3291
3410
  {
@@ -3302,7 +3421,7 @@ class Ht {
3302
3421
  * @returns true if added, false if node already exists or invalid
3303
3422
  */
3304
3423
  addNode(e) {
3305
- if (!De(e))
3424
+ if (!Fe(e))
3306
3425
  return !1;
3307
3426
  const s = this.nodeManager.addNode(e);
3308
3427
  return s && (this.graphEngine.restart(), this.forceGraph2D && this.forceGraph2D.addNode(e), this.options.onNodeAdd && this.options.onNodeAdd(e), this.emit("nodeAdd", e), this.updateLegendCounts()), s;
@@ -3312,7 +3431,7 @@ class Ht {
3312
3431
  * @returns true if removed, false if not found
3313
3432
  */
3314
3433
  removeNode(e) {
3315
- if (!pt(e))
3434
+ if (!dt(e))
3316
3435
  return !1;
3317
3436
  this.edgeManager.removeEdgesForNode(e);
3318
3437
  const s = this.nodeManager.removeNode(e);
@@ -3326,10 +3445,10 @@ class Ht {
3326
3445
  }
3327
3446
  /**
3328
3447
  * Adds an edge to the graph
3329
- * @returns true if added, false if edge already exists or nodes don't exist
3448
+ * @returns true if added, false if invalid or nodes don't exist
3330
3449
  */
3331
3450
  addEdge(e) {
3332
- if (!He(e))
3451
+ if (!De(e))
3333
3452
  return !1;
3334
3453
  const s = this.edgeManager.addEdge(e);
3335
3454
  return s && (this.graphEngine.setEdges(this.edgeManager.getAllEdges()), this.graphEngine.restart(), this.forceGraph2D && this.forceGraph2D.addEdge(e), this.options.onEdgeAdd && this.options.onEdgeAdd(e), this.emit("edgeAdd", e), this.updateLegendCounts()), s;
@@ -3355,11 +3474,11 @@ class Ht {
3355
3474
  try {
3356
3475
  const o = await i(e, s);
3357
3476
  if (o.nodes && Array.isArray(o.nodes))
3358
- for (const a of o.nodes)
3359
- this.addNode(a);
3477
+ for (const n of o.nodes)
3478
+ this.addNode(n);
3360
3479
  if (o.edges && Array.isArray(o.edges))
3361
- for (const a of o.edges)
3362
- this.addEdge(a);
3480
+ for (const n of o.edges)
3481
+ this.addEdge(n);
3363
3482
  return this.panelManager.hide(), this.emit("expand", e, o), !0;
3364
3483
  } catch (o) {
3365
3484
  return console.error("[ForceGraph3D] Error expanding node:", o), !1;
@@ -3409,13 +3528,13 @@ class Ht {
3409
3528
  console.warn(`[ForceGraph3D] Node "${e}" not found`);
3410
3529
  return;
3411
3530
  }
3412
- const i = t.position, o = this.sceneManager.camera, a = this.sceneManager.controls, r = o.position.clone().sub(a.target).normalize(), c = {
3531
+ const i = t.position, o = this.sceneManager.camera, n = this.sceneManager.controls, r = o.position.clone().sub(n.target).normalize(), h = {
3413
3532
  x: i.x + r.x * s,
3414
3533
  y: i.y + r.y * s,
3415
3534
  z: i.z + r.z * s
3416
- }, d = { x: o.position.x, y: o.position.y, z: o.position.z }, p = { x: a.target.x, y: a.target.y, z: a.target.z }, x = 800, m = performance.now(), u = () => {
3417
- const f = performance.now() - m, b = Math.min(f / x, 1), M = 1 - Math.pow(1 - b, 3);
3418
- o.position.x = d.x + (c.x - d.x) * M, o.position.y = d.y + (c.y - d.y) * M, o.position.z = d.z + (c.z - d.z) * M, a.target.x = p.x + (i.x - p.x) * M, a.target.y = p.y + (i.y - p.y) * M, a.target.z = p.z + (i.z - p.z) * M, a.update(), b < 1 && requestAnimationFrame(u);
3535
+ }, c = { x: o.position.x, y: o.position.y, z: o.position.z }, p = { x: n.target.x, y: n.target.y, z: n.target.z }, f = 800, m = performance.now(), u = () => {
3536
+ const y = performance.now() - m, b = Math.min(y / f, 1), w = 1 - Math.pow(1 - b, 3);
3537
+ o.position.x = c.x + (h.x - c.x) * w, o.position.y = c.y + (h.y - c.y) * w, o.position.z = c.z + (h.z - c.z) * w, n.target.x = p.x + (i.x - p.x) * w, n.target.y = p.y + (i.y - p.y) * w, n.target.z = p.z + (i.z - p.z) * w, n.update(), b < 1 && requestAnimationFrame(u);
3419
3538
  };
3420
3539
  u();
3421
3540
  }
@@ -3429,19 +3548,19 @@ class Ht {
3429
3548
  console.warn(`[ForceGraph3D] Could not find nodes for edge "${e}" -> "${s}"`);
3430
3549
  return;
3431
3550
  }
3432
- const a = this.sceneManager.camera, r = this.sceneManager.controls, c = {
3551
+ const n = this.sceneManager.camera, r = this.sceneManager.controls, h = {
3433
3552
  x: (i.position.x + o.position.x) / 2,
3434
3553
  y: (i.position.y + o.position.y) / 2,
3435
3554
  z: (i.position.z + o.position.z) / 2
3436
- }, d = o.position.x - i.position.x, p = o.position.y - i.position.y, x = o.position.z - i.position.z, m = Math.sqrt(d * d + p * p + x * x), u = Math.max(m * t, 40), f = a.position.clone().sub(r.target).normalize(), b = {
3437
- x: c.x + f.x * u,
3438
- y: c.y + f.y * u,
3439
- z: c.z + f.z * u
3440
- }, M = { x: a.position.x, y: a.position.y, z: a.position.z }, N = { x: r.target.x, y: r.target.y, z: r.target.z }, O = 800, L = performance.now(), Y = () => {
3441
- const T = performance.now() - L, D = Math.min(T / O, 1), E = 1 - Math.pow(1 - D, 3);
3442
- a.position.x = M.x + (b.x - M.x) * E, a.position.y = M.y + (b.y - M.y) * E, a.position.z = M.z + (b.z - M.z) * E, r.target.x = N.x + (c.x - N.x) * E, r.target.y = N.y + (c.y - N.y) * E, r.target.z = N.z + (c.z - N.z) * E, r.update(), D < 1 && requestAnimationFrame(Y);
3555
+ }, c = o.position.x - i.position.x, p = o.position.y - i.position.y, f = o.position.z - i.position.z, m = Math.sqrt(c * c + p * p + f * f), u = Math.max(m * t, 40), y = n.position.clone().sub(r.target).normalize(), b = {
3556
+ x: h.x + y.x * u,
3557
+ y: h.y + y.y * u,
3558
+ z: h.z + y.z * u
3559
+ }, w = { x: n.position.x, y: n.position.y, z: n.position.z }, N = { x: r.target.x, y: r.target.y, z: r.target.z }, O = 800, R = performance.now(), G = () => {
3560
+ const T = performance.now() - R, D = Math.min(T / O, 1), E = 1 - Math.pow(1 - D, 3);
3561
+ n.position.x = w.x + (b.x - w.x) * E, n.position.y = w.y + (b.y - w.y) * E, n.position.z = w.z + (b.z - w.z) * E, r.target.x = N.x + (h.x - N.x) * E, r.target.y = N.y + (h.y - N.y) * E, r.target.z = N.z + (h.z - N.z) * E, r.update(), D < 1 && requestAnimationFrame(G);
3443
3562
  };
3444
- Y();
3563
+ G();
3445
3564
  }
3446
3565
  /**
3447
3566
  * Shows the info panel for a specific node
@@ -3464,9 +3583,9 @@ class Ht {
3464
3583
  return [];
3465
3584
  const s = e.toLowerCase().trim(), t = this.nodeManager.getAllNodes(), i = [];
3466
3585
  return t.forEach((o) => {
3467
- var d, p, x;
3468
- const a = (d = o.label) == null ? void 0 : d.toLowerCase().includes(s), r = (p = o.id) == null ? void 0 : p.toLowerCase().includes(s), c = (x = o.type) == null ? void 0 : x.toLowerCase().includes(s);
3469
- (a || r || c) && i.push(o);
3586
+ var c, p, f;
3587
+ const n = (c = o.label) == null ? void 0 : c.toLowerCase().includes(s), r = (p = o.id) == null ? void 0 : p.toLowerCase().includes(s), h = (f = o.type) == null ? void 0 : f.toLowerCase().includes(s);
3588
+ (n || r || h) && i.push(o);
3470
3589
  }), i;
3471
3590
  }
3472
3591
  /**
@@ -3478,10 +3597,10 @@ class Ht {
3478
3597
  if (!e || e.trim() === "")
3479
3598
  return [];
3480
3599
  const s = e.toLowerCase().trim(), t = this.edgeManager.getAllEdges(), i = [];
3481
- for (const a of t)
3482
- if ((o = a.relationship) == null ? void 0 : o.toLowerCase().includes(s)) {
3483
- const c = this.nodeManager.getNode(a.source), d = this.nodeManager.getNode(a.target);
3484
- c && d && i.push({ edge: a, sourceNode: c, targetNode: d });
3600
+ for (const n of t)
3601
+ if ((o = n.relationship) == null ? void 0 : o.toLowerCase().includes(s)) {
3602
+ const h = this.nodeManager.getNode(n.source), c = this.nodeManager.getNode(n.target);
3603
+ h && c && i.push({ edge: n, sourceNode: h, targetNode: c });
3485
3604
  }
3486
3605
  return i;
3487
3606
  }
@@ -3514,7 +3633,7 @@ class Ht {
3514
3633
  * Switches between 2D and 3D view modes
3515
3634
  */
3516
3635
  switchView(e) {
3517
- this.viewMode !== e && (this.viewMode = e, this.panelManager.hide(), this.edgePanelManager.hide(), this.edgeTooltipManager.hide(), e === "2d" ? (this.sceneManager.renderer.domElement.style.display = "none", this.rendererManager.stop(), this.forceGraph2D ? (this.forceGraph2D.show(), this.forceGraph2D.syncFrom3D(this.nodeManager.getAllNodes())) : (this.forceGraph2D = new It(this.container, {
3636
+ this.viewMode !== e && (this.viewMode = e, this.panelManager.hide(), this.edgePanelManager.hide(), this.edgeTooltipManager.hide(), e === "2d" ? (this.sceneManager.renderer.domElement.style.display = "none", this.rendererManager.stop(), this.forceGraph2D ? (this.forceGraph2D.show(), this.forceGraph2D.syncFrom3D(this.nodeManager.getAllNodes())) : (this.forceGraph2D = new Lt(this.container, {
3518
3637
  backgroundColor: "#0a0a0a",
3519
3638
  nodeRadius: 24,
3520
3639
  onNodeClick: (s) => {
@@ -3526,19 +3645,31 @@ class Ht {
3526
3645
  onEdgeHover: (s, t) => {
3527
3646
  if (s && t) {
3528
3647
  const i = this.nodeManager.getNode(s.source), o = this.nodeManager.getNode(s.target);
3529
- i && o && this.edgeTooltipManager.show(
3530
- s,
3531
- i,
3532
- o,
3533
- t.clientX,
3534
- t.clientY
3535
- );
3648
+ if (i && o) {
3649
+ const n = this.edgeManager.getAllEdges().filter((r) => r.source === s.source && r.target === s.target);
3650
+ this.edgeTooltipManager.show(
3651
+ s,
3652
+ i,
3653
+ o,
3654
+ t.clientX,
3655
+ t.clientY,
3656
+ n.length > 0 ? n : [s]
3657
+ );
3658
+ }
3536
3659
  } else
3537
3660
  this.edgeTooltipManager.hide();
3538
3661
  },
3539
3662
  onEdgeClick: (s) => {
3540
3663
  const t = this.nodeManager.getNode(s.source), i = this.nodeManager.getNode(s.target);
3541
- t && i && this.edgePanelManager.show(s, t, i);
3664
+ if (t && i) {
3665
+ const o = this.edgeManager.getAllEdges().filter((n) => n.source === s.source && n.target === s.target);
3666
+ this.edgePanelManager.show(
3667
+ s,
3668
+ t,
3669
+ i,
3670
+ o.length > 0 ? o : [s]
3671
+ );
3672
+ }
3542
3673
  }
3543
3674
  }), this.graphData && (this.forceGraph2D.setData(this.graphData), this.forceGraph2D.syncFrom3D(this.nodeManager.getAllNodes())))) : (this.forceGraph2D && this.forceGraph2D.hide(), this.sceneManager.renderer.domElement.style.display = "block", this.rendererManager.start()), this.emit("viewChange", e));
3544
3675
  }
@@ -3639,8 +3770,8 @@ class Ht {
3639
3770
  const i = parseFloat(t.value) / 100;
3640
3771
  this.setPhysicsParams({ damping: i }), this.devControls.querySelector("#dev-damping-val").textContent = i.toFixed(2);
3641
3772
  }), setInterval(() => {
3642
- const i = this.devControls.querySelector("#dev-node-count"), o = this.devControls.querySelector("#dev-edge-count"), a = this.devControls.querySelector("#dev-fps");
3643
- i && (i.textContent = this.getNodeCount().toString()), o && (o.textContent = this.getEdgeCount().toString()), a && (a.textContent = this.rendererManager.getFPS().toString());
3773
+ const i = this.devControls.querySelector("#dev-node-count"), o = this.devControls.querySelector("#dev-edge-count"), n = this.devControls.querySelector("#dev-fps");
3774
+ i && (i.textContent = this.getNodeCount().toString()), o && (o.textContent = this.getEdgeCount().toString()), n && (n.textContent = this.rendererManager.getFPS().toString());
3644
3775
  }, 500);
3645
3776
  }
3646
3777
  /**
@@ -3650,7 +3781,7 @@ class Ht {
3650
3781
  this.rendererManager.dispose(), this.panelManager.dispose(), this.raycasterManager.dispose(), this.edgeTooltipManager.dispose(), this.searchManager && this.searchManager.dispose(), this.viewToggleManager && this.viewToggleManager.dispose(), this.legendManager && this.legendManager.dispose(), this.forceGraph2D && this.forceGraph2D.dispose(), this.edgeManager.dispose(), this.nodeManager.dispose(), this.nodeFactory.dispose(), this.materialFactory.dispose(), this.sceneManager.dispose(), this.devControls && this.devControls.parentNode && this.devControls.parentNode.removeChild(this.devControls), this.eventCallbacks.clear(), this.initialized = !1;
3651
3782
  }
3652
3783
  }
3653
- const Oe = [
3784
+ const Ie = [
3654
3785
  "Alpha",
3655
3786
  "Beta",
3656
3787
  "Gamma",
@@ -3681,7 +3812,7 @@ const Oe = [
3681
3812
  "Link",
3682
3813
  "Point",
3683
3814
  "Vertex"
3684
- ], ee = [
3815
+ ], J = [
3685
3816
  "connects to",
3686
3817
  "links with",
3687
3818
  "relates to",
@@ -3692,7 +3823,7 @@ const Oe = [
3692
3823
  "partners with",
3693
3824
  "collaborates with",
3694
3825
  "supports"
3695
- ], Fe = [
3826
+ ], Oe = [
3696
3827
  16777215,
3697
3828
  // White
3698
3829
  16750950,
@@ -3704,14 +3835,14 @@ const Oe = [
3704
3835
  16746564
3705
3836
  // Darker tangerine
3706
3837
  ];
3707
- function At(h = 30) {
3838
+ function At(d = 30) {
3708
3839
  const e = [], s = [];
3709
- for (let i = 0; i < h; i++) {
3710
- const o = i < Oe.length ? Oe[i] : `Node ${i + 1}`;
3840
+ for (let i = 0; i < d; i++) {
3841
+ const o = i < Ie.length ? Ie[i] : `Node ${i + 1}`;
3711
3842
  e.push({
3712
3843
  id: `node-${i}`,
3713
3844
  label: o,
3714
- color: Fe[i % Fe.length],
3845
+ color: Oe[i % Oe.length],
3715
3846
  position: {
3716
3847
  x: (Math.random() - 0.5) * 60,
3717
3848
  y: (Math.random() - 0.5) * 60,
@@ -3719,52 +3850,52 @@ function At(h = 30) {
3719
3850
  }
3720
3851
  });
3721
3852
  }
3722
- for (let i = 1; i < h; i++) {
3853
+ for (let i = 1; i < d; i++) {
3723
3854
  const o = Math.floor(Math.random() * i);
3724
3855
  s.push({
3725
3856
  source: `node-${i}`,
3726
3857
  target: `node-${o}`,
3727
- relationship: ee[Math.floor(Math.random() * ee.length)]
3858
+ relationship: J[Math.floor(Math.random() * J.length)]
3728
3859
  });
3729
3860
  }
3730
- const t = Math.floor(h * 0.5);
3861
+ const t = Math.floor(d * 0.5);
3731
3862
  for (let i = 0; i < t; i++) {
3732
- const o = Math.floor(Math.random() * h);
3733
- let a = Math.floor(Math.random() * h);
3734
- o === a && (a = (a + 1) % h);
3735
- const r = `node-${o}`, c = `node-${a}`;
3863
+ const o = Math.floor(Math.random() * d);
3864
+ let n = Math.floor(Math.random() * d);
3865
+ o === n && (n = (n + 1) % d);
3866
+ const r = `node-${o}`, h = `node-${n}`;
3736
3867
  s.some(
3737
- (p) => p.source === r && p.target === c || p.source === c && p.target === r
3868
+ (p) => p.source === r && p.target === h || p.source === h && p.target === r
3738
3869
  ) || s.push({
3739
3870
  source: r,
3740
- target: c,
3741
- relationship: ee[Math.floor(Math.random() * ee.length)]
3871
+ target: h,
3872
+ relationship: J[Math.floor(Math.random() * J.length)]
3742
3873
  });
3743
3874
  }
3744
3875
  return { nodes: e, edges: s };
3745
3876
  }
3746
- function jt(h = 1e3) {
3747
- const e = [], s = [], t = Math.ceil(h / 50), i = [];
3877
+ function jt(d = 1e3) {
3878
+ const e = [], s = [], t = Math.ceil(d / 50), i = [];
3748
3879
  for (let o = 0; o < t; o++)
3749
3880
  i.push({
3750
3881
  x: (Math.random() - 0.5) * 200,
3751
3882
  y: (Math.random() - 0.5) * 200,
3752
3883
  z: (Math.random() - 0.5) * 200
3753
3884
  });
3754
- for (let o = 0; o < h; o++) {
3755
- const a = i[o % t];
3885
+ for (let o = 0; o < d; o++) {
3886
+ const n = i[o % t];
3756
3887
  e.push({
3757
3888
  id: `node-${o}`,
3758
3889
  label: `N${o}`,
3759
3890
  position: {
3760
- x: a.x + (Math.random() - 0.5) * 40,
3761
- y: a.y + (Math.random() - 0.5) * 40,
3762
- z: a.z + (Math.random() - 0.5) * 40
3891
+ x: n.x + (Math.random() - 0.5) * 40,
3892
+ y: n.y + (Math.random() - 0.5) * 40,
3893
+ z: n.z + (Math.random() - 0.5) * 40
3763
3894
  }
3764
3895
  });
3765
3896
  }
3766
- for (let o = 1; o < h; o++) {
3767
- const a = Math.floor(o / 50) * 50, r = a === 0 ? Math.floor(Math.random() * o) : a + Math.floor(Math.random() * Math.min(o - a, 50));
3897
+ for (let o = 1; o < d; o++) {
3898
+ const n = Math.floor(o / 50) * 50, r = n === 0 ? Math.floor(Math.random() * o) : n + Math.floor(Math.random() * Math.min(o - n, 50));
3768
3899
  s.push({
3769
3900
  source: `node-${o}`,
3770
3901
  target: `node-${Math.min(r, o - 1)}`,
@@ -3772,9 +3903,9 @@ function jt(h = 1e3) {
3772
3903
  });
3773
3904
  }
3774
3905
  for (let o = 1; o < t; o++) {
3775
- const a = o * 50, r = (o - 1) * 50 + Math.floor(Math.random() * 50);
3906
+ const n = o * 50, r = (o - 1) * 50 + Math.floor(Math.random() * 50);
3776
3907
  s.push({
3777
- source: `node-${a}`,
3908
+ source: `node-${n}`,
3778
3909
  target: `node-${r}`,
3779
3910
  relationship: "bridges to"
3780
3911
  });
@@ -3784,11 +3915,11 @@ function jt(h = 1e3) {
3784
3915
  export {
3785
3916
  P as DEFAULT_OPTIONS,
3786
3917
  Ht as ForceGraph3D,
3787
- X as LODLevel,
3788
- H as createEdgeKey,
3918
+ _ as LODLevel,
3919
+ Dt as createEdgeKey,
3789
3920
  jt as generateLargeSampleData,
3790
3921
  At as generateSampleData,
3791
- He as validateEdgeData,
3792
- De as validateNodeData
3922
+ De as validateEdgeData,
3923
+ Fe as validateNodeData
3793
3924
  };
3794
3925
  //# sourceMappingURL=force-3d-graph.js.map