@cocorof/graphier 1.3.3 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -44,7 +44,10 @@ const DEFAULT_LAYOUT = {
44
44
  alphaDecay: "auto",
45
45
  velocityDecay: 0.4,
46
46
  settledThreshold: 5e-3,
47
- spreadFactor: "auto"
47
+ spreadFactor: "auto",
48
+ dimensions: 3,
49
+ clusterBy: null,
50
+ clusterStrength: 0.05
48
51
  };
49
52
  function hexToRgb(hex) {
50
53
  const c2 = hex.replace("#", "");
@@ -56,6 +59,14 @@ function rgbToHex(r, g, b) {
56
59
  const hex = clamp(r) << 16 | clamp(g) << 8 | clamp(b);
57
60
  return "#" + hex.toString(16).padStart(6, "0");
58
61
  }
62
+ function luminance(hex) {
63
+ const [r, g, b] = hexToRgb(hex);
64
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
65
+ }
66
+ function darken(hex, factor) {
67
+ const [r, g, b] = hexToRgb(hex);
68
+ return rgbToHex(r * factor, g * factor, b * factor);
69
+ }
59
70
  function brighten(hex, factor) {
60
71
  const [r, g, b] = hexToRgb(hex);
61
72
  const t = 1 - 1 / factor;
@@ -137,10 +148,40 @@ const minimal = {
137
148
  defaultLinkColor: "#444444",
138
149
  backgroundColor: "#1a1a2e"
139
150
  };
151
+ const paper = {
152
+ nodeColors: {},
153
+ // Bright (label / highlight) colors are auto-derived: on a light
154
+ // background resolveTheme darkens instead of whitening.
155
+ nodeColorsBright: {},
156
+ linkColors: {},
157
+ defaultNodeColor: "#64748b",
158
+ defaultLinkColor: "#b3bdcc",
159
+ backgroundColor: "#f6f7f9",
160
+ blending: "normal",
161
+ palette: [
162
+ "#2563eb",
163
+ // blue
164
+ "#d97706",
165
+ // amber
166
+ "#7c3aed",
167
+ // violet
168
+ "#db2777",
169
+ // pink
170
+ "#0891b2",
171
+ // cyan
172
+ "#16a34a",
173
+ // green
174
+ "#dc2626",
175
+ // red
176
+ "#475569"
177
+ // slate
178
+ ]
179
+ };
140
180
  const PRESETS = {
141
181
  celestial,
142
182
  neon,
143
- minimal
183
+ minimal,
184
+ paper
144
185
  };
145
186
  const DEFAULT_THEME = {
146
187
  nodeColors: celestial.nodeColors ?? {},
@@ -168,6 +209,8 @@ function resolveTheme(theme) {
168
209
  const defaultLinkColor = config.defaultLinkColor ?? DEFAULT_THEME.defaultLinkColor;
169
210
  const backgroundColor = config.backgroundColor ?? DEFAULT_THEME.backgroundColor;
170
211
  const palette = config.palette ?? DEFAULT_THEME.palette;
212
+ const isLight = luminance(backgroundColor) > 0.5;
213
+ const additiveEdges = config.blending ? config.blending === "additive" : !isLight;
171
214
  const autoAssigned = /* @__PURE__ */ new Map();
172
215
  let nextPaletteIdx = 0;
173
216
  function nodeColor(type) {
@@ -179,16 +222,24 @@ function resolveTheme(theme) {
179
222
  }
180
223
  return palette[autoAssigned.get(type)];
181
224
  }
225
+ const emphasize = (c2) => isLight ? darken(c2, 0.72) : brighten(c2, 1.5);
182
226
  function nodeColorBright(type) {
183
- if (!type) return brighten(defaultNodeColor, 1.5);
227
+ if (!type) return emphasize(defaultNodeColor);
184
228
  if (nodeColorsBright[type]) return nodeColorsBright[type];
185
- return brighten(nodeColor(type), 1.5);
229
+ return emphasize(nodeColor(type));
186
230
  }
187
231
  function linkColor(type) {
188
232
  if (!type) return defaultLinkColor;
189
233
  return linkColors[type] ?? defaultLinkColor;
190
234
  }
191
- return { nodeColor, nodeColorBright, linkColor, backgroundColor };
235
+ return {
236
+ nodeColor,
237
+ nodeColorBright,
238
+ linkColor,
239
+ backgroundColor,
240
+ isLight,
241
+ additiveEdges
242
+ };
192
243
  }
193
244
  function autoSpreadFactor(n) {
194
245
  if (n <= 500) return 1;
@@ -211,6 +262,8 @@ function resolveLayoutParams(nodeCount, config) {
211
262
  const postEvery = n > 5e4 ? 5 : n > 1e4 ? 3 : 2;
212
263
  const initialRadius2 = (500 + Math.min(n, 1e4) * 0.1) * spread;
213
264
  return {
265
+ dimensions: (config == null ? void 0 : config.dimensions) === 2 ? 2 : 3,
266
+ clusterStrength: (config == null ? void 0 : config.clusterStrength) ?? 0.05,
214
267
  charge,
215
268
  distanceMax,
216
269
  theta,
@@ -222,7 +275,7 @@ function resolveLayoutParams(nodeCount, config) {
222
275
  initialRadius: initialRadius2
223
276
  };
224
277
  }
225
- const WORKER_SOURCE = '(function(){"use strict";function At(t,n,i){var e,r=1;t==null&&(t=0),n==null&&(n=0),i==null&&(i=0);function s(){var a,o=e.length,h,u=0,c=0,l=0;for(a=0;a<o;++a)h=e[a],u+=h.x||0,c+=h.y||0,l+=h.z||0;for(u=(u/o-t)*r,c=(c/o-n)*r,l=(l/o-i)*r,a=0;a<o;++a)h=e[a],u&&(h.x-=u),c&&(h.y-=c),l&&(h.z-=l)}return s.initialize=function(a){e=a},s.x=function(a){return arguments.length?(t=+a,s):t},s.y=function(a){return arguments.length?(n=+a,s):n},s.z=function(a){return arguments.length?(i=+a,s):i},s.strength=function(a){return arguments.length?(r=+a,s):r},s}function $t(t){const n=+this._x.call(null,t);return et(this.cover(n),n,t)}function et(t,n,i){if(isNaN(n))return t;var e,r=t._root,s={data:i},a=t._x0,o=t._x1,h,u,c,l,v;if(!r)return t._root=s,t;for(;r.length;)if((c=n>=(h=(a+o)/2))?a=h:o=h,e=r,!(r=r[l=+c]))return e[l]=s,t;if(u=+t._x.call(null,r.data),n===u)return s.next=r,e?e[l]=s:t._root=s,t;do e=e?e[l]=new Array(2):t._root=new Array(2),(c=n>=(h=(a+o)/2))?a=h:o=h;while((l=+c)==(v=+(u>=h)));return e[v]=r,e[l]=s,t}function mt(t){Array.isArray(t)||(t=Array.from(t));const n=t.length,i=new Float64Array(n);let e=1/0,r=-1/0;for(let s=0,a;s<n;++s)isNaN(a=+this._x.call(null,t[s]))||(i[s]=a,a<e&&(e=a),a>r&&(r=a));if(e>r)return this;this.cover(e).cover(r);for(let s=0;s<n;++s)et(this,i[s],t[s]);return this}function qt(t){if(isNaN(t=+t))return this;var n=this._x0,i=this._x1;if(isNaN(n))i=(n=Math.floor(t))+1;else{for(var e=i-n||1,r=this._root,s,a;n>t||t>=i;)switch(a=+(t<n),s=new Array(2),s[a]=r,r=s,e*=2,a){case 0:i=n+e;break;case 1:n=i-e;break}this._root&&this._root.length&&(this._root=r)}return this._x0=n,this._x1=i,this}function It(){var t=[];return this.visit(function(n){if(!n.length)do t.push(n.data);while(n=n.next)}),t}function bt(t){return arguments.length?this.cover(+t[0][0]).cover(+t[1][0]):isNaN(this._x0)?void 0:[[this._x0],[this._x1]]}function j(t,n,i){this.node=t,this.x0=n,this.x1=i}function kt(t,n){var i,e=this._x0,r,s,a=this._x1,o=[],h=this._root,u,c;for(h&&o.push(new j(h,e,a)),n==null?n=1/0:(e=t-n,a=t+n);u=o.pop();)if(!(!(h=u.node)||(r=u.x0)>a||(s=u.x1)<e))if(h.length){var l=(r+s)/2;o.push(new j(h[1],l,s),new j(h[0],r,l)),(c=+(t>=l))&&(u=o[o.length-1],o[o.length-1]=o[o.length-1-c],o[o.length-1-c]=u)}else{var v=Math.abs(t-+this._x.call(null,h.data));v<n&&(n=v,e=t-v,a=t+v,i=h.data)}return i}function Dt(t){if(isNaN(h=+this._x.call(null,t)))return this;var n,i=this._root,e,r,s,a=this._x0,o=this._x1,h,u,c,l,v;if(!i)return this;if(i.length)for(;;){if((c=h>=(u=(a+o)/2))?a=u:o=u,n=i,!(i=i[l=+c]))return this;if(!i.length)break;n[l+1&1]&&(e=n,v=l)}for(;i.data!==t;)if(r=i,!(i=i.next))return this;return(s=i.next)&&delete i.next,r?(s?r.next=s:delete r.next,this):n?(s?n[l]=s:delete n[l],(i=n[0]||n[1])&&i===(n[1]||n[0])&&!i.length&&(e?e[v]=i:this._root=i),this):(this._root=s,this)}function Et(t){for(var n=0,i=t.length;n<i;++n)this.remove(t[n]);return this}function Tt(){return this._root}function jt(){var t=0;return this.visit(function(n){if(!n.length)do++t;while(n=n.next)}),t}function Pt(t){var n=[],i,e=this._root,r,s,a;for(e&&n.push(new j(e,this._x0,this._x1));i=n.pop();)if(!t(e=i.node,s=i.x0,a=i.x1)&&e.length){var o=(s+a)/2;(r=e[1])&&n.push(new j(r,o,a)),(r=e[0])&&n.push(new j(r,s,o))}return this}function Ft(t){var n=[],i=[],e;for(this._root&&n.push(new j(this._root,this._x0,this._x1));e=n.pop();){var r=e.node;if(r.length){var s,a=e.x0,o=e.x1,h=(a+o)/2;(s=r[0])&&n.push(new j(s,a,h)),(s=r[1])&&n.push(new j(s,h,o))}i.push(e)}for(;e=i.pop();)t(e.node,e.x0,e.x1);return this}function Ot(t){return t[0]}function St(t){return arguments.length?(this._x=t,this):this._x}function rt(t,n){var i=new G(n??Ot,NaN,NaN);return t==null?i:i.addAll(t)}function G(t,n,i){this._x=t,this._x0=n,this._x1=i,this._root=void 0}function st(t){for(var n={data:t.data},i=n;t=t.next;)i=i.next={data:t.data};return n}var k=rt.prototype=G.prototype;k.copy=function(){var t=new G(this._x,this._x0,this._x1),n=this._root,i,e;if(!n)return t;if(!n.length)return t._root=st(n),t;for(i=[{source:n,target:t._root=new Array(2)}];n=i.pop();)for(var r=0;r<2;++r)(e=n.source[r])&&(e.length?i.push({source:e,target:n.target[r]=new Array(2)}):n.target[r]=st(e));return t},k.add=$t,k.addAll=mt,k.cover=qt,k.data=It,k.extent=bt,k.find=kt,k.remove=Dt,k.removeAll=Et,k.root=Tt,k.size=jt,k.visit=Pt,k.visitAfter=Ft,k.x=St;function Rt(t){const n=+this._x.call(null,t),i=+this._y.call(null,t);return at(this.cover(n,i),n,i,t)}function at(t,n,i,e){if(isNaN(n)||isNaN(i))return t;var r,s=t._root,a={data:e},o=t._x0,h=t._y0,u=t._x1,c=t._y1,l,v,y,_,N,p,f,d;if(!s)return t._root=a,t;for(;s.length;)if((N=n>=(l=(o+u)/2))?o=l:u=l,(p=i>=(v=(h+c)/2))?h=v:c=v,r=s,!(s=s[f=p<<1|N]))return r[f]=a,t;if(y=+t._x.call(null,s.data),_=+t._y.call(null,s.data),n===y&&i===_)return a.next=s,r?r[f]=a:t._root=a,t;do r=r?r[f]=new Array(4):t._root=new Array(4),(N=n>=(l=(o+u)/2))?o=l:u=l,(p=i>=(v=(h+c)/2))?h=v:c=v;while((f=p<<1|N)===(d=(_>=v)<<1|y>=l));return r[d]=s,r[f]=a,t}function Xt(t){var n,i,e=t.length,r,s,a=new Array(e),o=new Array(e),h=1/0,u=1/0,c=-1/0,l=-1/0;for(i=0;i<e;++i)isNaN(r=+this._x.call(null,n=t[i]))||isNaN(s=+this._y.call(null,n))||(a[i]=r,o[i]=s,r<h&&(h=r),r>c&&(c=r),s<u&&(u=s),s>l&&(l=s));if(h>c||u>l)return this;for(this.cover(h,u).cover(c,l),i=0;i<e;++i)at(this,a[i],o[i],t[i]);return this}function Bt(t,n){if(isNaN(t=+t)||isNaN(n=+n))return this;var i=this._x0,e=this._y0,r=this._x1,s=this._y1;if(isNaN(i))r=(i=Math.floor(t))+1,s=(e=Math.floor(n))+1;else{for(var a=r-i||1,o=this._root,h,u;i>t||t>=r||e>n||n>=s;)switch(u=(n<e)<<1|t<i,h=new Array(4),h[u]=o,o=h,a*=2,u){case 0:r=i+a,s=e+a;break;case 1:i=r-a,s=e+a;break;case 2:r=i+a,e=s-a;break;case 3:i=r-a,e=s-a;break}this._root&&this._root.length&&(this._root=o)}return this._x0=i,this._y0=e,this._x1=r,this._y1=s,this}function Ct(){var t=[];return this.visit(function(n){if(!n.length)do t.push(n.data);while(n=n.next)}),t}function Lt(t){return arguments.length?this.cover(+t[0][0],+t[0][1]).cover(+t[1][0],+t[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]}function I(t,n,i,e,r){this.node=t,this.x0=n,this.y0=i,this.x1=e,this.y1=r}function Yt(t,n,i){var e,r=this._x0,s=this._y0,a,o,h,u,c=this._x1,l=this._y1,v=[],y=this._root,_,N;for(y&&v.push(new I(y,r,s,c,l)),i==null?i=1/0:(r=t-i,s=n-i,c=t+i,l=n+i,i*=i);_=v.pop();)if(!(!(y=_.node)||(a=_.x0)>c||(o=_.y0)>l||(h=_.x1)<r||(u=_.y1)<s))if(y.length){var p=(a+h)/2,f=(o+u)/2;v.push(new I(y[3],p,f,h,u),new I(y[2],a,f,p,u),new I(y[1],p,o,h,f),new I(y[0],a,o,p,f)),(N=(n>=f)<<1|t>=p)&&(_=v[v.length-1],v[v.length-1]=v[v.length-1-N],v[v.length-1-N]=_)}else{var d=t-+this._x.call(null,y.data),w=n-+this._y.call(null,y.data),g=d*d+w*w;if(g<i){var x=Math.sqrt(i=g);r=t-x,s=n-x,c=t+x,l=n+x,e=y.data}}return e}function Ht(t){if(isNaN(c=+this._x.call(null,t))||isNaN(l=+this._y.call(null,t)))return this;var n,i=this._root,e,r,s,a=this._x0,o=this._y0,h=this._x1,u=this._y1,c,l,v,y,_,N,p,f;if(!i)return this;if(i.length)for(;;){if((_=c>=(v=(a+h)/2))?a=v:h=v,(N=l>=(y=(o+u)/2))?o=y:u=y,n=i,!(i=i[p=N<<1|_]))return this;if(!i.length)break;(n[p+1&3]||n[p+2&3]||n[p+3&3])&&(e=n,f=p)}for(;i.data!==t;)if(r=i,!(i=i.next))return this;return(s=i.next)&&delete i.next,r?(s?r.next=s:delete r.next,this):n?(s?n[p]=s:delete n[p],(i=n[0]||n[1]||n[2]||n[3])&&i===(n[3]||n[2]||n[1]||n[0])&&!i.length&&(e?e[f]=i:this._root=i),this):(this._root=s,this)}function Qt(t){for(var n=0,i=t.length;n<i;++n)this.remove(t[n]);return this}function Wt(){return this._root}function Zt(){var t=0;return this.visit(function(n){if(!n.length)do++t;while(n=n.next)}),t}function Gt(t){var n=[],i,e=this._root,r,s,a,o,h;for(e&&n.push(new I(e,this._x0,this._y0,this._x1,this._y1));i=n.pop();)if(!t(e=i.node,s=i.x0,a=i.y0,o=i.x1,h=i.y1)&&e.length){var u=(s+o)/2,c=(a+h)/2;(r=e[3])&&n.push(new I(r,u,c,o,h)),(r=e[2])&&n.push(new I(r,s,c,u,h)),(r=e[1])&&n.push(new I(r,u,a,o,c)),(r=e[0])&&n.push(new I(r,s,a,u,c))}return this}function Jt(t){var n=[],i=[],e;for(this._root&&n.push(new I(this._root,this._x0,this._y0,this._x1,this._y1));e=n.pop();){var r=e.node;if(r.length){var s,a=e.x0,o=e.y0,h=e.x1,u=e.y1,c=(a+h)/2,l=(o+u)/2;(s=r[0])&&n.push(new I(s,a,o,c,l)),(s=r[1])&&n.push(new I(s,c,o,h,l)),(s=r[2])&&n.push(new I(s,a,l,c,u)),(s=r[3])&&n.push(new I(s,c,l,h,u))}i.push(e)}for(;e=i.pop();)t(e.node,e.x0,e.y0,e.x1,e.y1);return this}function Kt(t){return t[0]}function Ut(t){return arguments.length?(this._x=t,this):this._x}function Vt(t){return t[1]}function tn(t){return arguments.length?(this._y=t,this):this._y}function ht(t,n,i){var e=new J(n??Kt,i??Vt,NaN,NaN,NaN,NaN);return t==null?e:e.addAll(t)}function J(t,n,i,e,r,s){this._x=t,this._y=n,this._x0=i,this._y0=e,this._x1=r,this._y1=s,this._root=void 0}function ot(t){for(var n={data:t.data},i=n;t=t.next;)i=i.next={data:t.data};return n}var b=ht.prototype=J.prototype;b.copy=function(){var t=new J(this._x,this._y,this._x0,this._y0,this._x1,this._y1),n=this._root,i,e;if(!n)return t;if(!n.length)return t._root=ot(n),t;for(i=[{source:n,target:t._root=new Array(4)}];n=i.pop();)for(var r=0;r<4;++r)(e=n.source[r])&&(e.length?i.push({source:e,target:n.target[r]=new Array(4)}):n.target[r]=ot(e));return t},b.add=Rt,b.addAll=Xt,b.cover=Bt,b.data=Ct,b.extent=Lt,b.find=Yt,b.remove=Ht,b.removeAll=Qt,b.root=Wt,b.size=Zt,b.visit=Gt,b.visitAfter=Jt,b.x=Ut,b.y=tn;function nn(t){const n=+this._x.call(null,t),i=+this._y.call(null,t),e=+this._z.call(null,t);return ft(this.cover(n,i,e),n,i,e,t)}function ft(t,n,i,e,r){if(isNaN(n)||isNaN(i)||isNaN(e))return t;var s,a=t._root,o={data:r},h=t._x0,u=t._y0,c=t._z0,l=t._x1,v=t._y1,y=t._z1,_,N,p,f,d,w,g,x,M,z,A;if(!a)return t._root=o,t;for(;a.length;)if((g=n>=(_=(h+l)/2))?h=_:l=_,(x=i>=(N=(u+v)/2))?u=N:v=N,(M=e>=(p=(c+y)/2))?c=p:y=p,s=a,!(a=a[z=M<<2|x<<1|g]))return s[z]=o,t;if(f=+t._x.call(null,a.data),d=+t._y.call(null,a.data),w=+t._z.call(null,a.data),n===f&&i===d&&e===w)return o.next=a,s?s[z]=o:t._root=o,t;do s=s?s[z]=new Array(8):t._root=new Array(8),(g=n>=(_=(h+l)/2))?h=_:l=_,(x=i>=(N=(u+v)/2))?u=N:v=N,(M=e>=(p=(c+y)/2))?c=p:y=p;while((z=M<<2|x<<1|g)===(A=(w>=p)<<2|(d>=N)<<1|f>=_));return s[A]=a,s[z]=o,t}function en(t){Array.isArray(t)||(t=Array.from(t));const n=t.length,i=new Float64Array(n),e=new Float64Array(n),r=new Float64Array(n);let s=1/0,a=1/0,o=1/0,h=-1/0,u=-1/0,c=-1/0;for(let l=0,v,y,_,N;l<n;++l)isNaN(y=+this._x.call(null,v=t[l]))||isNaN(_=+this._y.call(null,v))||isNaN(N=+this._z.call(null,v))||(i[l]=y,e[l]=_,r[l]=N,y<s&&(s=y),y>h&&(h=y),_<a&&(a=_),_>u&&(u=_),N<o&&(o=N),N>c&&(c=N));if(s>h||a>u||o>c)return this;this.cover(s,a,o).cover(h,u,c);for(let l=0;l<n;++l)ft(this,i[l],e[l],r[l],t[l]);return this}function rn(t,n,i){if(isNaN(t=+t)||isNaN(n=+n)||isNaN(i=+i))return this;var e=this._x0,r=this._y0,s=this._z0,a=this._x1,o=this._y1,h=this._z1;if(isNaN(e))a=(e=Math.floor(t))+1,o=(r=Math.floor(n))+1,h=(s=Math.floor(i))+1;else{for(var u=a-e||1,c=this._root,l,v;e>t||t>=a||r>n||n>=o||s>i||i>=h;)switch(v=(i<s)<<2|(n<r)<<1|t<e,l=new Array(8),l[v]=c,c=l,u*=2,v){case 0:a=e+u,o=r+u,h=s+u;break;case 1:e=a-u,o=r+u,h=s+u;break;case 2:a=e+u,r=o-u,h=s+u;break;case 3:e=a-u,r=o-u,h=s+u;break;case 4:a=e+u,o=r+u,s=h-u;break;case 5:e=a-u,o=r+u,s=h-u;break;case 6:a=e+u,r=o-u,s=h-u;break;case 7:e=a-u,r=o-u,s=h-u;break}this._root&&this._root.length&&(this._root=c)}return this._x0=e,this._y0=r,this._z0=s,this._x1=a,this._y1=o,this._z1=h,this}function sn(){var t=[];return this.visit(function(n){if(!n.length)do t.push(n.data);while(n=n.next)}),t}function an(t){return arguments.length?this.cover(+t[0][0],+t[0][1],+t[0][2]).cover(+t[1][0],+t[1][1],+t[1][2]):isNaN(this._x0)?void 0:[[this._x0,this._y0,this._z0],[this._x1,this._y1,this._z1]]}function $(t,n,i,e,r,s,a){this.node=t,this.x0=n,this.y0=i,this.z0=e,this.x1=r,this.y1=s,this.z1=a}function hn(t,n,i,e){var r,s=this._x0,a=this._y0,o=this._z0,h,u,c,l,v,y,_=this._x1,N=this._y1,p=this._z1,f=[],d=this._root,w,g;for(d&&f.push(new $(d,s,a,o,_,N,p)),e==null?e=1/0:(s=t-e,a=n-e,o=i-e,_=t+e,N=n+e,p=i+e,e*=e);w=f.pop();)if(!(!(d=w.node)||(h=w.x0)>_||(u=w.y0)>N||(c=w.z0)>p||(l=w.x1)<s||(v=w.y1)<a||(y=w.z1)<o))if(d.length){var x=(h+l)/2,M=(u+v)/2,z=(c+y)/2;f.push(new $(d[7],x,M,z,l,v,y),new $(d[6],h,M,z,x,v,y),new $(d[5],x,u,z,l,M,y),new $(d[4],h,u,z,x,M,y),new $(d[3],x,M,c,l,v,z),new $(d[2],h,M,c,x,v,z),new $(d[1],x,u,c,l,M,z),new $(d[0],h,u,c,x,M,z)),(g=(i>=z)<<2|(n>=M)<<1|t>=x)&&(w=f[f.length-1],f[f.length-1]=f[f.length-1-g],f[f.length-1-g]=w)}else{var A=t-+this._x.call(null,d.data),E=n-+this._y.call(null,d.data),T=i-+this._z.call(null,d.data),D=A*A+E*E+T*T;if(D<e){var m=Math.sqrt(e=D);s=t-m,a=n-m,o=i-m,_=t+m,N=n+m,p=i+m,r=d.data}}return r}const on=(t,n,i,e,r,s)=>Math.sqrt((t-e)**2+(n-r)**2+(i-s)**2);function fn(t,n,i,e){const r=[],s=t-e,a=n-e,o=i-e,h=t+e,u=n+e,c=i+e;return this.visit((l,v,y,_,N,p,f)=>{if(!l.length)do{const d=l.data;on(t,n,i,this._x(d),this._y(d),this._z(d))<=e&&r.push(d)}while(l=l.next);return v>h||y>u||_>c||N<s||p<a||f<o}),r}function un(t){if(isNaN(v=+this._x.call(null,t))||isNaN(y=+this._y.call(null,t))||isNaN(_=+this._z.call(null,t)))return this;var n,i=this._root,e,r,s,a=this._x0,o=this._y0,h=this._z0,u=this._x1,c=this._y1,l=this._z1,v,y,_,N,p,f,d,w,g,x,M;if(!i)return this;if(i.length)for(;;){if((d=v>=(N=(a+u)/2))?a=N:u=N,(w=y>=(p=(o+c)/2))?o=p:c=p,(g=_>=(f=(h+l)/2))?h=f:l=f,n=i,!(i=i[x=g<<2|w<<1|d]))return this;if(!i.length)break;(n[x+1&7]||n[x+2&7]||n[x+3&7]||n[x+4&7]||n[x+5&7]||n[x+6&7]||n[x+7&7])&&(e=n,M=x)}for(;i.data!==t;)if(r=i,!(i=i.next))return this;return(s=i.next)&&delete i.next,r?(s?r.next=s:delete r.next,this):n?(s?n[x]=s:delete n[x],(i=n[0]||n[1]||n[2]||n[3]||n[4]||n[5]||n[6]||n[7])&&i===(n[7]||n[6]||n[5]||n[4]||n[3]||n[2]||n[1]||n[0])&&!i.length&&(e?e[M]=i:this._root=i),this):(this._root=s,this)}function ln(t){for(var n=0,i=t.length;n<i;++n)this.remove(t[n]);return this}function cn(){return this._root}function _n(){var t=0;return this.visit(function(n){if(!n.length)do++t;while(n=n.next)}),t}function vn(t){var n=[],i,e=this._root,r,s,a,o,h,u,c;for(e&&n.push(new $(e,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1));i=n.pop();)if(!t(e=i.node,s=i.x0,a=i.y0,o=i.z0,h=i.x1,u=i.y1,c=i.z1)&&e.length){var l=(s+h)/2,v=(a+u)/2,y=(o+c)/2;(r=e[7])&&n.push(new $(r,l,v,y,h,u,c)),(r=e[6])&&n.push(new $(r,s,v,y,l,u,c)),(r=e[5])&&n.push(new $(r,l,a,y,h,v,c)),(r=e[4])&&n.push(new $(r,s,a,y,l,v,c)),(r=e[3])&&n.push(new $(r,l,v,o,h,u,y)),(r=e[2])&&n.push(new $(r,s,v,o,l,u,y)),(r=e[1])&&n.push(new $(r,l,a,o,h,v,y)),(r=e[0])&&n.push(new $(r,s,a,o,l,v,y))}return this}function xn(t){var n=[],i=[],e;for(this._root&&n.push(new $(this._root,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1));e=n.pop();){var r=e.node;if(r.length){var s,a=e.x0,o=e.y0,h=e.z0,u=e.x1,c=e.y1,l=e.z1,v=(a+u)/2,y=(o+c)/2,_=(h+l)/2;(s=r[0])&&n.push(new $(s,a,o,h,v,y,_)),(s=r[1])&&n.push(new $(s,v,o,h,u,y,_)),(s=r[2])&&n.push(new $(s,a,y,h,v,c,_)),(s=r[3])&&n.push(new $(s,v,y,h,u,c,_)),(s=r[4])&&n.push(new $(s,a,o,_,v,y,l)),(s=r[5])&&n.push(new $(s,v,o,_,u,y,l)),(s=r[6])&&n.push(new $(s,a,y,_,v,c,l)),(s=r[7])&&n.push(new $(s,v,y,_,u,c,l))}i.push(e)}for(;e=i.pop();)t(e.node,e.x0,e.y0,e.z0,e.x1,e.y1,e.z1);return this}function yn(t){return t[0]}function pn(t){return arguments.length?(this._x=t,this):this._x}function gn(t){return t[1]}function wn(t){return arguments.length?(this._y=t,this):this._y}function dn(t){return t[2]}function Nn(t){return arguments.length?(this._z=t,this):this._z}function ut(t,n,i,e){var r=new K(n??yn,i??gn,e??dn,NaN,NaN,NaN,NaN,NaN,NaN);return t==null?r:r.addAll(t)}function K(t,n,i,e,r,s,a,o,h){this._x=t,this._y=n,this._z=i,this._x0=e,this._y0=r,this._z0=s,this._x1=a,this._y1=o,this._z1=h,this._root=void 0}function lt(t){for(var n={data:t.data},i=n;t=t.next;)i=i.next={data:t.data};return n}var q=ut.prototype=K.prototype;q.copy=function(){var t=new K(this._x,this._y,this._z,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1),n=this._root,i,e;if(!n)return t;if(!n.length)return t._root=lt(n),t;for(i=[{source:n,target:t._root=new Array(8)}];n=i.pop();)for(var r=0;r<8;++r)(e=n.source[r])&&(e.length?i.push({source:e,target:n.target[r]=new Array(8)}):n.target[r]=lt(e));return t},q.add=nn,q.addAll=en,q.cover=rn,q.data=sn,q.extent=an,q.find=hn,q.findAllWithinRadius=fn,q.remove=un,q.removeAll=ln,q.root=cn,q.size=_n,q.visit=vn,q.visitAfter=xn,q.x=pn,q.y=wn,q.z=Nn;function R(t){return function(){return t}}function P(t){return(t()-.5)*1e-6}function Mn(t){return t.index}function ct(t,n){var i=t.get(n);if(!i)throw new Error("node not found: "+n);return i}function zn(t){var n=Mn,i=v,e,r=R(30),s,a,o,h,u,c,l=1;t==null&&(t=[]);function v(f){return 1/Math.min(h[f.source.index],h[f.target.index])}function y(f){for(var d=0,w=t.length;d<l;++d)for(var g=0,x,M,z,A=0,E=0,T=0,D,m;g<w;++g)x=t[g],M=x.source,z=x.target,A=z.x+z.vx-M.x-M.vx||P(c),o>1&&(E=z.y+z.vy-M.y-M.vy||P(c)),o>2&&(T=z.z+z.vz-M.z-M.vz||P(c)),D=Math.sqrt(A*A+E*E+T*T),D=(D-s[g])/D*f*e[g],A*=D,E*=D,T*=D,z.vx-=A*(m=u[g]),o>1&&(z.vy-=E*m),o>2&&(z.vz-=T*m),M.vx+=A*(m=1-m),o>1&&(M.vy+=E*m),o>2&&(M.vz+=T*m)}function _(){if(a){var f,d=a.length,w=t.length,g=new Map(a.map((M,z)=>[n(M,z,a),M])),x;for(f=0,h=new Array(d);f<w;++f)x=t[f],x.index=f,typeof x.source!="object"&&(x.source=ct(g,x.source)),typeof x.target!="object"&&(x.target=ct(g,x.target)),h[x.source.index]=(h[x.source.index]||0)+1,h[x.target.index]=(h[x.target.index]||0)+1;for(f=0,u=new Array(w);f<w;++f)x=t[f],u[f]=h[x.source.index]/(h[x.source.index]+h[x.target.index]);e=new Array(w),N(),s=new Array(w),p()}}function N(){if(a)for(var f=0,d=t.length;f<d;++f)e[f]=+i(t[f],f,t)}function p(){if(a)for(var f=0,d=t.length;f<d;++f)s[f]=+r(t[f],f,t)}return y.initialize=function(f,...d){a=f,c=d.find(w=>typeof w=="function")||Math.random,o=d.find(w=>[1,2,3].includes(w))||2,_()},y.links=function(f){return arguments.length?(t=f,_(),y):t},y.id=function(f){return arguments.length?(n=f,y):n},y.iterations=function(f){return arguments.length?(l=+f,y):l},y.strength=function(f){return arguments.length?(i=typeof f=="function"?f:R(+f),N(),y):i},y.distance=function(f){return arguments.length?(r=typeof f=="function"?f:R(+f),p(),y):r},y}var An={value:()=>{}};function _t(){for(var t=0,n=arguments.length,i={},e;t<n;++t){if(!(e=arguments[t]+"")||e in i||/[\\s.]/.test(e))throw new Error("illegal type: "+e);i[e]=[]}return new H(i)}function H(t){this._=t}function $n(t,n){return t.trim().split(/^|\\s+/).map(function(i){var e="",r=i.indexOf(".");if(r>=0&&(e=i.slice(r+1),i=i.slice(0,r)),i&&!n.hasOwnProperty(i))throw new Error("unknown type: "+i);return{type:i,name:e}})}H.prototype=_t.prototype={constructor:H,on:function(t,n){var i=this._,e=$n(t+"",i),r,s=-1,a=e.length;if(arguments.length<2){for(;++s<a;)if((r=(t=e[s]).type)&&(r=mn(i[r],t.name)))return r;return}if(n!=null&&typeof n!="function")throw new Error("invalid callback: "+n);for(;++s<a;)if(r=(t=e[s]).type)i[r]=vt(i[r],t.name,n);else if(n==null)for(r in i)i[r]=vt(i[r],t.name,null);return this},copy:function(){var t={},n=this._;for(var i in n)t[i]=n[i].slice();return new H(t)},call:function(t,n){if((r=arguments.length-2)>0)for(var i=new Array(r),e=0,r,s;e<r;++e)i[e]=arguments[e+2];if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(s=this._[t],e=0,r=s.length;e<r;++e)s[e].value.apply(n,i)},apply:function(t,n,i){if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(var e=this._[t],r=0,s=e.length;r<s;++r)e[r].value.apply(n,i)}};function mn(t,n){for(var i=0,e=t.length,r;i<e;++i)if((r=t[i]).name===n)return r.value}function vt(t,n,i){for(var e=0,r=t.length;e<r;++e)if(t[e].name===n){t[e]=An,t=t.slice(0,e).concat(t.slice(e+1));break}return i!=null&&t.push({name:n,value:i}),t}var S=0,X=0,B=0,xt=1e3,Q,C,W=0,O=0,Z=0,L=typeof performance=="object"&&performance.now?performance:Date,yt=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};function pt(){return O||(yt(qn),O=L.now()+Z)}function qn(){O=0}function U(){this._call=this._time=this._next=null}U.prototype=gt.prototype={constructor:U,restart:function(t,n,i){if(typeof t!="function")throw new TypeError("callback is not a function");i=(i==null?pt():+i)+(n==null?0:+n),!this._next&&C!==this&&(C?C._next=this:Q=this,C=this),this._call=t,this._time=i,V()},stop:function(){this._call&&(this._call=null,this._time=1/0,V())}};function gt(t,n,i){var e=new U;return e.restart(t,n,i),e}function In(){pt(),++S;for(var t=Q,n;t;)(n=O-t._time)>=0&&t._call.call(void 0,n),t=t._next;--S}function wt(){O=(W=L.now())+Z,S=X=0;try{In()}finally{S=0,kn(),O=0}}function bn(){var t=L.now(),n=t-W;n>xt&&(Z-=n,W=t)}function kn(){for(var t,n=Q,i,e=1/0;n;)n._call?(e>n._time&&(e=n._time),t=n,n=n._next):(i=n._next,n._next=null,n=t?t._next=i:Q=i);C=t,V(e)}function V(t){if(!S){X&&(X=clearTimeout(X));var n=t-O;n>24?(t<1/0&&(X=setTimeout(wt,t-L.now()-Z)),B&&(B=clearInterval(B))):(B||(W=L.now(),B=setInterval(bn,xt)),S=1,yt(wt))}}const Dn=1664525,En=1013904223,dt=4294967296;function Tn(){let t=1;return()=>(t=(Dn*t+En)%dt)/dt}var Nt=3;function tt(t){return t.x}function Mt(t){return t.y}function jn(t){return t.z}var Pn=10,Fn=Math.PI*(3-Math.sqrt(5)),On=Math.PI*20/(9+Math.sqrt(221));function Sn(t,n){n=n||2;var i=Math.min(Nt,Math.max(1,Math.round(n))),e,r=1,s=.001,a=1-Math.pow(s,1/300),o=0,h=.6,u=new Map,c=gt(y),l=_t("tick","end"),v=Tn();t==null&&(t=[]);function y(){_(),l.call("tick",e),r<s&&(c.stop(),l.call("end",e))}function _(f){var d,w=t.length,g;f===void 0&&(f=1);for(var x=0;x<f;++x)for(r+=(o-r)*a,u.forEach(function(M){M(r)}),d=0;d<w;++d)g=t[d],g.fx==null?g.x+=g.vx*=h:(g.x=g.fx,g.vx=0),i>1&&(g.fy==null?g.y+=g.vy*=h:(g.y=g.fy,g.vy=0)),i>2&&(g.fz==null?g.z+=g.vz*=h:(g.z=g.fz,g.vz=0));return e}function N(){for(var f=0,d=t.length,w;f<d;++f){if(w=t[f],w.index=f,w.fx!=null&&(w.x=w.fx),w.fy!=null&&(w.y=w.fy),w.fz!=null&&(w.z=w.fz),isNaN(w.x)||i>1&&isNaN(w.y)||i>2&&isNaN(w.z)){var g=Pn*(i>2?Math.cbrt(.5+f):i>1?Math.sqrt(.5+f):f),x=f*Fn,M=f*On;i===1?w.x=g:i===2?(w.x=g*Math.cos(x),w.y=g*Math.sin(x)):(w.x=g*Math.sin(x)*Math.cos(M),w.y=g*Math.cos(x),w.z=g*Math.sin(x)*Math.sin(M))}(isNaN(w.vx)||i>1&&isNaN(w.vy)||i>2&&isNaN(w.vz))&&(w.vx=0,i>1&&(w.vy=0),i>2&&(w.vz=0))}}function p(f){return f.initialize&&f.initialize(t,v,i),f}return N(),e={tick:_,restart:function(){return c.restart(y),e},stop:function(){return c.stop(),e},numDimensions:function(f){return arguments.length?(i=Math.min(Nt,Math.max(1,Math.round(f))),u.forEach(p),e):i},nodes:function(f){return arguments.length?(t=f,N(),u.forEach(p),e):t},alpha:function(f){return arguments.length?(r=+f,e):r},alphaMin:function(f){return arguments.length?(s=+f,e):s},alphaDecay:function(f){return arguments.length?(a=+f,e):+a},alphaTarget:function(f){return arguments.length?(o=+f,e):o},velocityDecay:function(f){return arguments.length?(h=1-f,e):1-h},randomSource:function(f){return arguments.length?(v=f,u.forEach(p),e):v},force:function(f,d){return arguments.length>1?(d==null?u.delete(f):u.set(f,p(d)),e):u.get(f)},find:function(){var f=Array.prototype.slice.call(arguments),d=f.shift()||0,w=(i>1?f.shift():null)||0,g=(i>2?f.shift():null)||0,x=f.shift()||1/0,M=0,z=t.length,A,E,T,D,m,zt;for(x*=x,M=0;M<z;++M)m=t[M],A=d-m.x,E=w-(m.y||0),T=g-(m.z||0),D=A*A+E*E+T*T,D<x&&(zt=m,x=D);return zt},on:function(f,d){return arguments.length>1?(l.on(f,d),e):l.on(f)}}}function Rn(){var t,n,i,e,r,s=R(-30),a,o=1,h=1/0,u=.81;function c(_){var N,p=t.length,f=(n===1?rt(t,tt):n===2?ht(t,tt,Mt):n===3?ut(t,tt,Mt,jn):null).visitAfter(v);for(r=_,N=0;N<p;++N)i=t[N],f.visit(y)}function l(){if(t){var _,N=t.length,p;for(a=new Array(N),_=0;_<N;++_)p=t[_],a[p.index]=+s(p,_,t)}}function v(_){var N=0,p,f,d=0,w,g,x,M,z=_.length;if(z){for(w=g=x=M=0;M<z;++M)(p=_[M])&&(f=Math.abs(p.value))&&(N+=p.value,d+=f,w+=f*(p.x||0),g+=f*(p.y||0),x+=f*(p.z||0));N*=Math.sqrt(4/z),_.x=w/d,n>1&&(_.y=g/d),n>2&&(_.z=x/d)}else{p=_,p.x=p.data.x,n>1&&(p.y=p.data.y),n>2&&(p.z=p.data.z);do N+=a[p.data.index];while(p=p.next)}_.value=N}function y(_,N,p,f,d){if(!_.value)return!0;var w=[p,f,d][n-1],g=_.x-i.x,x=n>1?_.y-i.y:0,M=n>2?_.z-i.z:0,z=w-N,A=g*g+x*x+M*M;if(z*z/u<A)return A<h&&(g===0&&(g=P(e),A+=g*g),n>1&&x===0&&(x=P(e),A+=x*x),n>2&&M===0&&(M=P(e),A+=M*M),A<o&&(A=Math.sqrt(o*A)),i.vx+=g*_.value*r/A,n>1&&(i.vy+=x*_.value*r/A),n>2&&(i.vz+=M*_.value*r/A)),!0;if(_.length||A>=h)return;(_.data!==i||_.next)&&(g===0&&(g=P(e),A+=g*g),n>1&&x===0&&(x=P(e),A+=x*x),n>2&&M===0&&(M=P(e),A+=M*M),A<o&&(A=Math.sqrt(o*A)));do _.data!==i&&(z=a[_.data.index]*r/A,i.vx+=g*z,n>1&&(i.vy+=x*z),n>2&&(i.vz+=M*z));while(_=_.next)}return c.initialize=function(_,...N){t=_,e=N.find(p=>typeof p=="function")||Math.random,n=N.find(p=>[1,2,3].includes(p))||2,l()},c.strength=function(_){return arguments.length?(s=typeof _=="function"?_:R(+_),l(),c):s},c.distanceMin=function(_){return arguments.length?(o=_*_,c):Math.sqrt(o)},c.distanceMax=function(_){return arguments.length?(h=_*_,c):Math.sqrt(h)},c.theta=function(_){return arguments.length?(u=_*_,c):Math.sqrt(u)},c}let F=null,Y=[],nt=0,it=!1;self.onmessage=t=>{const n=t.data;if(n.type==="init"){F&&F.stop(),it=!1,nt=0;const i=n.nodes.length,e=n.params,r=n.initialPositions??{};Y=n.nodes.map((a,o)=>{const h=r[a.id];if(h)return{id:a.id,index:o,x:h.x,y:h.y,z:h.z};const u=Math.random()*Math.PI*2,c=Math.acos(2*Math.random()-1),l=e.initialRadius*(.5+Math.random()*.5);return{id:a.id,index:o,x:l*Math.sin(c)*Math.cos(u),y:l*Math.sin(c)*Math.sin(u),z:l*Math.cos(c)}});const s=n.links.map(a=>({source:a.source,target:a.target}));F=Sn(Y,3).force("charge",Rn().strength(e.charge).distanceMax(e.distanceMax).theta(e.theta)).force("link",zn(s).id(a=>a.id).distance(e.linkDistance).strength(.2)).force("center",At()).alphaDecay(e.alphaDecay).velocityDecay(e.velocityDecay),F.on("tick",()=>{nt++;const a=F.alpha();if(nt%e.postEvery!==0&&a>e.settledThreshold)return;const o=new Float32Array(i*3);for(let h=0;h<i;h++)o[h*3]=Y[h].x||0,o[h*3+1]=Y[h].y||0,o[h*3+2]=Y[h].z||0;self.postMessage({type:"positions",positions:o.buffer,alpha:a},[o.buffer]),!it&&a<e.settledThreshold&&(it=!0,self.postMessage({type:"settled"}))})}n.type==="stop"&&F&&(F.stop(),F=null)}})();\n';
278
+ const WORKER_SOURCE = '(function(){"use strict";function At(t,n,i){var e,r=1;t==null&&(t=0),n==null&&(n=0),i==null&&(i=0);function s(){var o,u=e.length,h,f=0,l=0,c=0;for(o=0;o<u;++o)h=e[o],f+=h.x||0,l+=h.y||0,c+=h.z||0;for(f=(f/u-t)*r,l=(l/u-n)*r,c=(c/u-i)*r,o=0;o<u;++o)h=e[o],f&&(h.x-=f),l&&(h.y-=l),c&&(h.z-=c)}return s.initialize=function(o){e=o},s.x=function(o){return arguments.length?(t=+o,s):t},s.y=function(o){return arguments.length?(n=+o,s):n},s.z=function(o){return arguments.length?(i=+o,s):i},s.strength=function(o){return arguments.length?(r=+o,s):r},s}function $t(t){const n=+this._x.call(null,t);return et(this.cover(n),n,t)}function et(t,n,i){if(isNaN(n))return t;var e,r=t._root,s={data:i},o=t._x0,u=t._x1,h,f,l,c,v;if(!r)return t._root=s,t;for(;r.length;)if((l=n>=(h=(o+u)/2))?o=h:u=h,e=r,!(r=r[c=+l]))return e[c]=s,t;if(f=+t._x.call(null,r.data),n===f)return s.next=r,e?e[c]=s:t._root=s,t;do e=e?e[c]=new Array(2):t._root=new Array(2),(l=n>=(h=(o+u)/2))?o=h:u=h;while((c=+l)==(v=+(f>=h)));return e[v]=r,e[c]=s,t}function mt(t){Array.isArray(t)||(t=Array.from(t));const n=t.length,i=new Float64Array(n);let e=1/0,r=-1/0;for(let s=0,o;s<n;++s)isNaN(o=+this._x.call(null,t[s]))||(i[s]=o,o<e&&(e=o),o>r&&(r=o));if(e>r)return this;this.cover(e).cover(r);for(let s=0;s<n;++s)et(this,i[s],t[s]);return this}function qt(t){if(isNaN(t=+t))return this;var n=this._x0,i=this._x1;if(isNaN(n))i=(n=Math.floor(t))+1;else{for(var e=i-n||1,r=this._root,s,o;n>t||t>=i;)switch(o=+(t<n),s=new Array(2),s[o]=r,r=s,e*=2,o){case 0:i=n+e;break;case 1:n=i-e;break}this._root&&this._root.length&&(this._root=r)}return this._x0=n,this._x1=i,this}function It(){var t=[];return this.visit(function(n){if(!n.length)do t.push(n.data);while(n=n.next)}),t}function bt(t){return arguments.length?this.cover(+t[0][0]).cover(+t[1][0]):isNaN(this._x0)?void 0:[[this._x0],[this._x1]]}function P(t,n,i){this.node=t,this.x0=n,this.x1=i}function kt(t,n){var i,e=this._x0,r,s,o=this._x1,u=[],h=this._root,f,l;for(h&&u.push(new P(h,e,o)),n==null?n=1/0:(e=t-n,o=t+n);f=u.pop();)if(!(!(h=f.node)||(r=f.x0)>o||(s=f.x1)<e))if(h.length){var c=(r+s)/2;u.push(new P(h[1],c,s),new P(h[0],r,c)),(l=+(t>=c))&&(f=u[u.length-1],u[u.length-1]=u[u.length-1-l],u[u.length-1-l]=f)}else{var v=Math.abs(t-+this._x.call(null,h.data));v<n&&(n=v,e=t-v,o=t+v,i=h.data)}return i}function Dt(t){if(isNaN(h=+this._x.call(null,t)))return this;var n,i=this._root,e,r,s,o=this._x0,u=this._x1,h,f,l,c,v;if(!i)return this;if(i.length)for(;;){if((l=h>=(f=(o+u)/2))?o=f:u=f,n=i,!(i=i[c=+l]))return this;if(!i.length)break;n[c+1&1]&&(e=n,v=c)}for(;i.data!==t;)if(r=i,!(i=i.next))return this;return(s=i.next)&&delete i.next,r?(s?r.next=s:delete r.next,this):n?(s?n[c]=s:delete n[c],(i=n[0]||n[1])&&i===(n[1]||n[0])&&!i.length&&(e?e[v]=i:this._root=i),this):(this._root=s,this)}function Et(t){for(var n=0,i=t.length;n<i;++n)this.remove(t[n]);return this}function Tt(){return this._root}function jt(){var t=0;return this.visit(function(n){if(!n.length)do++t;while(n=n.next)}),t}function Pt(t){var n=[],i,e=this._root,r,s,o;for(e&&n.push(new P(e,this._x0,this._x1));i=n.pop();)if(!t(e=i.node,s=i.x0,o=i.x1)&&e.length){var u=(s+o)/2;(r=e[1])&&n.push(new P(r,u,o)),(r=e[0])&&n.push(new P(r,s,u))}return this}function Ft(t){var n=[],i=[],e;for(this._root&&n.push(new P(this._root,this._x0,this._x1));e=n.pop();){var r=e.node;if(r.length){var s,o=e.x0,u=e.x1,h=(o+u)/2;(s=r[0])&&n.push(new P(s,o,h)),(s=r[1])&&n.push(new P(s,h,u))}i.push(e)}for(;e=i.pop();)t(e.node,e.x0,e.x1);return this}function St(t){return t[0]}function Ot(t){return arguments.length?(this._x=t,this):this._x}function rt(t,n){var i=new G(n??St,NaN,NaN);return t==null?i:i.addAll(t)}function G(t,n,i){this._x=t,this._x0=n,this._x1=i,this._root=void 0}function st(t){for(var n={data:t.data},i=n;t=t.next;)i=i.next={data:t.data};return n}var k=rt.prototype=G.prototype;k.copy=function(){var t=new G(this._x,this._x0,this._x1),n=this._root,i,e;if(!n)return t;if(!n.length)return t._root=st(n),t;for(i=[{source:n,target:t._root=new Array(2)}];n=i.pop();)for(var r=0;r<2;++r)(e=n.source[r])&&(e.length?i.push({source:e,target:n.target[r]=new Array(2)}):n.target[r]=st(e));return t},k.add=$t,k.addAll=mt,k.cover=qt,k.data=It,k.extent=bt,k.find=kt,k.remove=Dt,k.removeAll=Et,k.root=Tt,k.size=jt,k.visit=Pt,k.visitAfter=Ft,k.x=Ot;function Rt(t){const n=+this._x.call(null,t),i=+this._y.call(null,t);return ot(this.cover(n,i),n,i,t)}function ot(t,n,i,e){if(isNaN(n)||isNaN(i))return t;var r,s=t._root,o={data:e},u=t._x0,h=t._y0,f=t._x1,l=t._y1,c,v,y,_,g,x,a,N;if(!s)return t._root=o,t;for(;s.length;)if((g=n>=(c=(u+f)/2))?u=c:f=c,(x=i>=(v=(h+l)/2))?h=v:l=v,r=s,!(s=s[a=x<<1|g]))return r[a]=o,t;if(y=+t._x.call(null,s.data),_=+t._y.call(null,s.data),n===y&&i===_)return o.next=s,r?r[a]=o:t._root=o,t;do r=r?r[a]=new Array(4):t._root=new Array(4),(g=n>=(c=(u+f)/2))?u=c:f=c,(x=i>=(v=(h+l)/2))?h=v:l=v;while((a=x<<1|g)===(N=(_>=v)<<1|y>=c));return r[N]=s,r[a]=o,t}function Xt(t){var n,i,e=t.length,r,s,o=new Array(e),u=new Array(e),h=1/0,f=1/0,l=-1/0,c=-1/0;for(i=0;i<e;++i)isNaN(r=+this._x.call(null,n=t[i]))||isNaN(s=+this._y.call(null,n))||(o[i]=r,u[i]=s,r<h&&(h=r),r>l&&(l=r),s<f&&(f=s),s>c&&(c=s));if(h>l||f>c)return this;for(this.cover(h,f).cover(l,c),i=0;i<e;++i)ot(this,o[i],u[i],t[i]);return this}function Bt(t,n){if(isNaN(t=+t)||isNaN(n=+n))return this;var i=this._x0,e=this._y0,r=this._x1,s=this._y1;if(isNaN(i))r=(i=Math.floor(t))+1,s=(e=Math.floor(n))+1;else{for(var o=r-i||1,u=this._root,h,f;i>t||t>=r||e>n||n>=s;)switch(f=(n<e)<<1|t<i,h=new Array(4),h[f]=u,u=h,o*=2,f){case 0:r=i+o,s=e+o;break;case 1:i=r-o,s=e+o;break;case 2:r=i+o,e=s-o;break;case 3:i=r-o,e=s-o;break}this._root&&this._root.length&&(this._root=u)}return this._x0=i,this._y0=e,this._x1=r,this._y1=s,this}function Ct(){var t=[];return this.visit(function(n){if(!n.length)do t.push(n.data);while(n=n.next)}),t}function Lt(t){return arguments.length?this.cover(+t[0][0],+t[0][1]).cover(+t[1][0],+t[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]}function I(t,n,i,e,r){this.node=t,this.x0=n,this.y0=i,this.x1=e,this.y1=r}function Yt(t,n,i){var e,r=this._x0,s=this._y0,o,u,h,f,l=this._x1,c=this._y1,v=[],y=this._root,_,g;for(y&&v.push(new I(y,r,s,l,c)),i==null?i=1/0:(r=t-i,s=n-i,l=t+i,c=n+i,i*=i);_=v.pop();)if(!(!(y=_.node)||(o=_.x0)>l||(u=_.y0)>c||(h=_.x1)<r||(f=_.y1)<s))if(y.length){var x=(o+h)/2,a=(u+f)/2;v.push(new I(y[3],x,a,h,f),new I(y[2],o,a,x,f),new I(y[1],x,u,h,a),new I(y[0],o,u,x,a)),(g=(n>=a)<<1|t>=x)&&(_=v[v.length-1],v[v.length-1]=v[v.length-1-g],v[v.length-1-g]=_)}else{var N=t-+this._x.call(null,y.data),d=n-+this._y.call(null,y.data),w=N*N+d*d;if(w<i){var p=Math.sqrt(i=w);r=t-p,s=n-p,l=t+p,c=n+p,e=y.data}}return e}function Ht(t){if(isNaN(l=+this._x.call(null,t))||isNaN(c=+this._y.call(null,t)))return this;var n,i=this._root,e,r,s,o=this._x0,u=this._y0,h=this._x1,f=this._y1,l,c,v,y,_,g,x,a;if(!i)return this;if(i.length)for(;;){if((_=l>=(v=(o+h)/2))?o=v:h=v,(g=c>=(y=(u+f)/2))?u=y:f=y,n=i,!(i=i[x=g<<1|_]))return this;if(!i.length)break;(n[x+1&3]||n[x+2&3]||n[x+3&3])&&(e=n,a=x)}for(;i.data!==t;)if(r=i,!(i=i.next))return this;return(s=i.next)&&delete i.next,r?(s?r.next=s:delete r.next,this):n?(s?n[x]=s:delete n[x],(i=n[0]||n[1]||n[2]||n[3])&&i===(n[3]||n[2]||n[1]||n[0])&&!i.length&&(e?e[a]=i:this._root=i),this):(this._root=s,this)}function Qt(t){for(var n=0,i=t.length;n<i;++n)this.remove(t[n]);return this}function Wt(){return this._root}function Zt(){var t=0;return this.visit(function(n){if(!n.length)do++t;while(n=n.next)}),t}function Gt(t){var n=[],i,e=this._root,r,s,o,u,h;for(e&&n.push(new I(e,this._x0,this._y0,this._x1,this._y1));i=n.pop();)if(!t(e=i.node,s=i.x0,o=i.y0,u=i.x1,h=i.y1)&&e.length){var f=(s+u)/2,l=(o+h)/2;(r=e[3])&&n.push(new I(r,f,l,u,h)),(r=e[2])&&n.push(new I(r,s,l,f,h)),(r=e[1])&&n.push(new I(r,f,o,u,l)),(r=e[0])&&n.push(new I(r,s,o,f,l))}return this}function Jt(t){var n=[],i=[],e;for(this._root&&n.push(new I(this._root,this._x0,this._y0,this._x1,this._y1));e=n.pop();){var r=e.node;if(r.length){var s,o=e.x0,u=e.y0,h=e.x1,f=e.y1,l=(o+h)/2,c=(u+f)/2;(s=r[0])&&n.push(new I(s,o,u,l,c)),(s=r[1])&&n.push(new I(s,l,u,h,c)),(s=r[2])&&n.push(new I(s,o,c,l,f)),(s=r[3])&&n.push(new I(s,l,c,h,f))}i.push(e)}for(;e=i.pop();)t(e.node,e.x0,e.y0,e.x1,e.y1);return this}function Kt(t){return t[0]}function Ut(t){return arguments.length?(this._x=t,this):this._x}function Vt(t){return t[1]}function tn(t){return arguments.length?(this._y=t,this):this._y}function ht(t,n,i){var e=new J(n??Kt,i??Vt,NaN,NaN,NaN,NaN);return t==null?e:e.addAll(t)}function J(t,n,i,e,r,s){this._x=t,this._y=n,this._x0=i,this._y0=e,this._x1=r,this._y1=s,this._root=void 0}function at(t){for(var n={data:t.data},i=n;t=t.next;)i=i.next={data:t.data};return n}var b=ht.prototype=J.prototype;b.copy=function(){var t=new J(this._x,this._y,this._x0,this._y0,this._x1,this._y1),n=this._root,i,e;if(!n)return t;if(!n.length)return t._root=at(n),t;for(i=[{source:n,target:t._root=new Array(4)}];n=i.pop();)for(var r=0;r<4;++r)(e=n.source[r])&&(e.length?i.push({source:e,target:n.target[r]=new Array(4)}):n.target[r]=at(e));return t},b.add=Rt,b.addAll=Xt,b.cover=Bt,b.data=Ct,b.extent=Lt,b.find=Yt,b.remove=Ht,b.removeAll=Qt,b.root=Wt,b.size=Zt,b.visit=Gt,b.visitAfter=Jt,b.x=Ut,b.y=tn;function nn(t){const n=+this._x.call(null,t),i=+this._y.call(null,t),e=+this._z.call(null,t);return ft(this.cover(n,i,e),n,i,e,t)}function ft(t,n,i,e,r){if(isNaN(n)||isNaN(i)||isNaN(e))return t;var s,o=t._root,u={data:r},h=t._x0,f=t._y0,l=t._z0,c=t._x1,v=t._y1,y=t._z1,_,g,x,a,N,d,w,p,M,z,A;if(!o)return t._root=u,t;for(;o.length;)if((w=n>=(_=(h+c)/2))?h=_:c=_,(p=i>=(g=(f+v)/2))?f=g:v=g,(M=e>=(x=(l+y)/2))?l=x:y=x,s=o,!(o=o[z=M<<2|p<<1|w]))return s[z]=u,t;if(a=+t._x.call(null,o.data),N=+t._y.call(null,o.data),d=+t._z.call(null,o.data),n===a&&i===N&&e===d)return u.next=o,s?s[z]=u:t._root=u,t;do s=s?s[z]=new Array(8):t._root=new Array(8),(w=n>=(_=(h+c)/2))?h=_:c=_,(p=i>=(g=(f+v)/2))?f=g:v=g,(M=e>=(x=(l+y)/2))?l=x:y=x;while((z=M<<2|p<<1|w)===(A=(d>=x)<<2|(N>=g)<<1|a>=_));return s[A]=o,s[z]=u,t}function en(t){Array.isArray(t)||(t=Array.from(t));const n=t.length,i=new Float64Array(n),e=new Float64Array(n),r=new Float64Array(n);let s=1/0,o=1/0,u=1/0,h=-1/0,f=-1/0,l=-1/0;for(let c=0,v,y,_,g;c<n;++c)isNaN(y=+this._x.call(null,v=t[c]))||isNaN(_=+this._y.call(null,v))||isNaN(g=+this._z.call(null,v))||(i[c]=y,e[c]=_,r[c]=g,y<s&&(s=y),y>h&&(h=y),_<o&&(o=_),_>f&&(f=_),g<u&&(u=g),g>l&&(l=g));if(s>h||o>f||u>l)return this;this.cover(s,o,u).cover(h,f,l);for(let c=0;c<n;++c)ft(this,i[c],e[c],r[c],t[c]);return this}function rn(t,n,i){if(isNaN(t=+t)||isNaN(n=+n)||isNaN(i=+i))return this;var e=this._x0,r=this._y0,s=this._z0,o=this._x1,u=this._y1,h=this._z1;if(isNaN(e))o=(e=Math.floor(t))+1,u=(r=Math.floor(n))+1,h=(s=Math.floor(i))+1;else{for(var f=o-e||1,l=this._root,c,v;e>t||t>=o||r>n||n>=u||s>i||i>=h;)switch(v=(i<s)<<2|(n<r)<<1|t<e,c=new Array(8),c[v]=l,l=c,f*=2,v){case 0:o=e+f,u=r+f,h=s+f;break;case 1:e=o-f,u=r+f,h=s+f;break;case 2:o=e+f,r=u-f,h=s+f;break;case 3:e=o-f,r=u-f,h=s+f;break;case 4:o=e+f,u=r+f,s=h-f;break;case 5:e=o-f,u=r+f,s=h-f;break;case 6:o=e+f,r=u-f,s=h-f;break;case 7:e=o-f,r=u-f,s=h-f;break}this._root&&this._root.length&&(this._root=l)}return this._x0=e,this._y0=r,this._z0=s,this._x1=o,this._y1=u,this._z1=h,this}function sn(){var t=[];return this.visit(function(n){if(!n.length)do t.push(n.data);while(n=n.next)}),t}function on(t){return arguments.length?this.cover(+t[0][0],+t[0][1],+t[0][2]).cover(+t[1][0],+t[1][1],+t[1][2]):isNaN(this._x0)?void 0:[[this._x0,this._y0,this._z0],[this._x1,this._y1,this._z1]]}function $(t,n,i,e,r,s,o){this.node=t,this.x0=n,this.y0=i,this.z0=e,this.x1=r,this.y1=s,this.z1=o}function hn(t,n,i,e){var r,s=this._x0,o=this._y0,u=this._z0,h,f,l,c,v,y,_=this._x1,g=this._y1,x=this._z1,a=[],N=this._root,d,w;for(N&&a.push(new $(N,s,o,u,_,g,x)),e==null?e=1/0:(s=t-e,o=n-e,u=i-e,_=t+e,g=n+e,x=i+e,e*=e);d=a.pop();)if(!(!(N=d.node)||(h=d.x0)>_||(f=d.y0)>g||(l=d.z0)>x||(c=d.x1)<s||(v=d.y1)<o||(y=d.z1)<u))if(N.length){var p=(h+c)/2,M=(f+v)/2,z=(l+y)/2;a.push(new $(N[7],p,M,z,c,v,y),new $(N[6],h,M,z,p,v,y),new $(N[5],p,f,z,c,M,y),new $(N[4],h,f,z,p,M,y),new $(N[3],p,M,l,c,v,z),new $(N[2],h,M,l,p,v,z),new $(N[1],p,f,l,c,M,z),new $(N[0],h,f,l,p,M,z)),(w=(i>=z)<<2|(n>=M)<<1|t>=p)&&(d=a[a.length-1],a[a.length-1]=a[a.length-1-w],a[a.length-1-w]=d)}else{var A=t-+this._x.call(null,N.data),E=n-+this._y.call(null,N.data),T=i-+this._z.call(null,N.data),D=A*A+E*E+T*T;if(D<e){var m=Math.sqrt(e=D);s=t-m,o=n-m,u=i-m,_=t+m,g=n+m,x=i+m,r=N.data}}return r}const an=(t,n,i,e,r,s)=>Math.sqrt((t-e)**2+(n-r)**2+(i-s)**2);function fn(t,n,i,e){const r=[],s=t-e,o=n-e,u=i-e,h=t+e,f=n+e,l=i+e;return this.visit((c,v,y,_,g,x,a)=>{if(!c.length)do{const N=c.data;an(t,n,i,this._x(N),this._y(N),this._z(N))<=e&&r.push(N)}while(c=c.next);return v>h||y>f||_>l||g<s||x<o||a<u}),r}function un(t){if(isNaN(v=+this._x.call(null,t))||isNaN(y=+this._y.call(null,t))||isNaN(_=+this._z.call(null,t)))return this;var n,i=this._root,e,r,s,o=this._x0,u=this._y0,h=this._z0,f=this._x1,l=this._y1,c=this._z1,v,y,_,g,x,a,N,d,w,p,M;if(!i)return this;if(i.length)for(;;){if((N=v>=(g=(o+f)/2))?o=g:f=g,(d=y>=(x=(u+l)/2))?u=x:l=x,(w=_>=(a=(h+c)/2))?h=a:c=a,n=i,!(i=i[p=w<<2|d<<1|N]))return this;if(!i.length)break;(n[p+1&7]||n[p+2&7]||n[p+3&7]||n[p+4&7]||n[p+5&7]||n[p+6&7]||n[p+7&7])&&(e=n,M=p)}for(;i.data!==t;)if(r=i,!(i=i.next))return this;return(s=i.next)&&delete i.next,r?(s?r.next=s:delete r.next,this):n?(s?n[p]=s:delete n[p],(i=n[0]||n[1]||n[2]||n[3]||n[4]||n[5]||n[6]||n[7])&&i===(n[7]||n[6]||n[5]||n[4]||n[3]||n[2]||n[1]||n[0])&&!i.length&&(e?e[M]=i:this._root=i),this):(this._root=s,this)}function ln(t){for(var n=0,i=t.length;n<i;++n)this.remove(t[n]);return this}function cn(){return this._root}function _n(){var t=0;return this.visit(function(n){if(!n.length)do++t;while(n=n.next)}),t}function vn(t){var n=[],i,e=this._root,r,s,o,u,h,f,l;for(e&&n.push(new $(e,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1));i=n.pop();)if(!t(e=i.node,s=i.x0,o=i.y0,u=i.z0,h=i.x1,f=i.y1,l=i.z1)&&e.length){var c=(s+h)/2,v=(o+f)/2,y=(u+l)/2;(r=e[7])&&n.push(new $(r,c,v,y,h,f,l)),(r=e[6])&&n.push(new $(r,s,v,y,c,f,l)),(r=e[5])&&n.push(new $(r,c,o,y,h,v,l)),(r=e[4])&&n.push(new $(r,s,o,y,c,v,l)),(r=e[3])&&n.push(new $(r,c,v,u,h,f,y)),(r=e[2])&&n.push(new $(r,s,v,u,c,f,y)),(r=e[1])&&n.push(new $(r,c,o,u,h,v,y)),(r=e[0])&&n.push(new $(r,s,o,u,c,v,y))}return this}function xn(t){var n=[],i=[],e;for(this._root&&n.push(new $(this._root,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1));e=n.pop();){var r=e.node;if(r.length){var s,o=e.x0,u=e.y0,h=e.z0,f=e.x1,l=e.y1,c=e.z1,v=(o+f)/2,y=(u+l)/2,_=(h+c)/2;(s=r[0])&&n.push(new $(s,o,u,h,v,y,_)),(s=r[1])&&n.push(new $(s,v,u,h,f,y,_)),(s=r[2])&&n.push(new $(s,o,y,h,v,l,_)),(s=r[3])&&n.push(new $(s,v,y,h,f,l,_)),(s=r[4])&&n.push(new $(s,o,u,_,v,y,c)),(s=r[5])&&n.push(new $(s,v,u,_,f,y,c)),(s=r[6])&&n.push(new $(s,o,y,_,v,l,c)),(s=r[7])&&n.push(new $(s,v,y,_,f,l,c))}i.push(e)}for(;e=i.pop();)t(e.node,e.x0,e.y0,e.z0,e.x1,e.y1,e.z1);return this}function yn(t){return t[0]}function pn(t){return arguments.length?(this._x=t,this):this._x}function gn(t){return t[1]}function wn(t){return arguments.length?(this._y=t,this):this._y}function dn(t){return t[2]}function Nn(t){return arguments.length?(this._z=t,this):this._z}function ut(t,n,i,e){var r=new K(n??yn,i??gn,e??dn,NaN,NaN,NaN,NaN,NaN,NaN);return t==null?r:r.addAll(t)}function K(t,n,i,e,r,s,o,u,h){this._x=t,this._y=n,this._z=i,this._x0=e,this._y0=r,this._z0=s,this._x1=o,this._y1=u,this._z1=h,this._root=void 0}function lt(t){for(var n={data:t.data},i=n;t=t.next;)i=i.next={data:t.data};return n}var q=ut.prototype=K.prototype;q.copy=function(){var t=new K(this._x,this._y,this._z,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1),n=this._root,i,e;if(!n)return t;if(!n.length)return t._root=lt(n),t;for(i=[{source:n,target:t._root=new Array(8)}];n=i.pop();)for(var r=0;r<8;++r)(e=n.source[r])&&(e.length?i.push({source:e,target:n.target[r]=new Array(8)}):n.target[r]=lt(e));return t},q.add=nn,q.addAll=en,q.cover=rn,q.data=sn,q.extent=on,q.find=hn,q.findAllWithinRadius=fn,q.remove=un,q.removeAll=ln,q.root=cn,q.size=_n,q.visit=vn,q.visitAfter=xn,q.x=pn,q.y=wn,q.z=Nn;function X(t){return function(){return t}}function F(t){return(t()-.5)*1e-6}function Mn(t){return t.index}function ct(t,n){var i=t.get(n);if(!i)throw new Error("node not found: "+n);return i}function zn(t){var n=Mn,i=v,e,r=X(30),s,o,u,h,f,l,c=1;t==null&&(t=[]);function v(a){return 1/Math.min(h[a.source.index],h[a.target.index])}function y(a){for(var N=0,d=t.length;N<c;++N)for(var w=0,p,M,z,A=0,E=0,T=0,D,m;w<d;++w)p=t[w],M=p.source,z=p.target,A=z.x+z.vx-M.x-M.vx||F(l),u>1&&(E=z.y+z.vy-M.y-M.vy||F(l)),u>2&&(T=z.z+z.vz-M.z-M.vz||F(l)),D=Math.sqrt(A*A+E*E+T*T),D=(D-s[w])/D*a*e[w],A*=D,E*=D,T*=D,z.vx-=A*(m=f[w]),u>1&&(z.vy-=E*m),u>2&&(z.vz-=T*m),M.vx+=A*(m=1-m),u>1&&(M.vy+=E*m),u>2&&(M.vz+=T*m)}function _(){if(o){var a,N=o.length,d=t.length,w=new Map(o.map((M,z)=>[n(M,z,o),M])),p;for(a=0,h=new Array(N);a<d;++a)p=t[a],p.index=a,typeof p.source!="object"&&(p.source=ct(w,p.source)),typeof p.target!="object"&&(p.target=ct(w,p.target)),h[p.source.index]=(h[p.source.index]||0)+1,h[p.target.index]=(h[p.target.index]||0)+1;for(a=0,f=new Array(d);a<d;++a)p=t[a],f[a]=h[p.source.index]/(h[p.source.index]+h[p.target.index]);e=new Array(d),g(),s=new Array(d),x()}}function g(){if(o)for(var a=0,N=t.length;a<N;++a)e[a]=+i(t[a],a,t)}function x(){if(o)for(var a=0,N=t.length;a<N;++a)s[a]=+r(t[a],a,t)}return y.initialize=function(a,...N){o=a,l=N.find(d=>typeof d=="function")||Math.random,u=N.find(d=>[1,2,3].includes(d))||2,_()},y.links=function(a){return arguments.length?(t=a,_(),y):t},y.id=function(a){return arguments.length?(n=a,y):n},y.iterations=function(a){return arguments.length?(c=+a,y):c},y.strength=function(a){return arguments.length?(i=typeof a=="function"?a:X(+a),g(),y):i},y.distance=function(a){return arguments.length?(r=typeof a=="function"?a:X(+a),x(),y):r},y}var An={value:()=>{}};function _t(){for(var t=0,n=arguments.length,i={},e;t<n;++t){if(!(e=arguments[t]+"")||e in i||/[\\s.]/.test(e))throw new Error("illegal type: "+e);i[e]=[]}return new H(i)}function H(t){this._=t}function $n(t,n){return t.trim().split(/^|\\s+/).map(function(i){var e="",r=i.indexOf(".");if(r>=0&&(e=i.slice(r+1),i=i.slice(0,r)),i&&!n.hasOwnProperty(i))throw new Error("unknown type: "+i);return{type:i,name:e}})}H.prototype=_t.prototype={constructor:H,on:function(t,n){var i=this._,e=$n(t+"",i),r,s=-1,o=e.length;if(arguments.length<2){for(;++s<o;)if((r=(t=e[s]).type)&&(r=mn(i[r],t.name)))return r;return}if(n!=null&&typeof n!="function")throw new Error("invalid callback: "+n);for(;++s<o;)if(r=(t=e[s]).type)i[r]=vt(i[r],t.name,n);else if(n==null)for(r in i)i[r]=vt(i[r],t.name,null);return this},copy:function(){var t={},n=this._;for(var i in n)t[i]=n[i].slice();return new H(t)},call:function(t,n){if((r=arguments.length-2)>0)for(var i=new Array(r),e=0,r,s;e<r;++e)i[e]=arguments[e+2];if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(s=this._[t],e=0,r=s.length;e<r;++e)s[e].value.apply(n,i)},apply:function(t,n,i){if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(var e=this._[t],r=0,s=e.length;r<s;++r)e[r].value.apply(n,i)}};function mn(t,n){for(var i=0,e=t.length,r;i<e;++i)if((r=t[i]).name===n)return r.value}function vt(t,n,i){for(var e=0,r=t.length;e<r;++e)if(t[e].name===n){t[e]=An,t=t.slice(0,e).concat(t.slice(e+1));break}return i!=null&&t.push({name:n,value:i}),t}var R=0,B=0,C=0,xt=1e3,Q,L,W=0,O=0,Z=0,Y=typeof performance=="object"&&performance.now?performance:Date,yt=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};function pt(){return O||(yt(qn),O=Y.now()+Z)}function qn(){O=0}function U(){this._call=this._time=this._next=null}U.prototype=gt.prototype={constructor:U,restart:function(t,n,i){if(typeof t!="function")throw new TypeError("callback is not a function");i=(i==null?pt():+i)+(n==null?0:+n),!this._next&&L!==this&&(L?L._next=this:Q=this,L=this),this._call=t,this._time=i,V()},stop:function(){this._call&&(this._call=null,this._time=1/0,V())}};function gt(t,n,i){var e=new U;return e.restart(t,n,i),e}function In(){pt(),++R;for(var t=Q,n;t;)(n=O-t._time)>=0&&t._call.call(void 0,n),t=t._next;--R}function wt(){O=(W=Y.now())+Z,R=B=0;try{In()}finally{R=0,kn(),O=0}}function bn(){var t=Y.now(),n=t-W;n>xt&&(Z-=n,W=t)}function kn(){for(var t,n=Q,i,e=1/0;n;)n._call?(e>n._time&&(e=n._time),t=n,n=n._next):(i=n._next,n._next=null,n=t?t._next=i:Q=i);L=t,V(e)}function V(t){if(!R){B&&(B=clearTimeout(B));var n=t-O;n>24?(t<1/0&&(B=setTimeout(wt,t-Y.now()-Z)),C&&(C=clearInterval(C))):(C||(W=Y.now(),C=setInterval(bn,xt)),R=1,yt(wt))}}const Dn=1664525,En=1013904223,dt=4294967296;function Tn(){let t=1;return()=>(t=(Dn*t+En)%dt)/dt}var Nt=3;function tt(t){return t.x}function Mt(t){return t.y}function jn(t){return t.z}var Pn=10,Fn=Math.PI*(3-Math.sqrt(5)),Sn=Math.PI*20/(9+Math.sqrt(221));function On(t,n){n=n||2;var i=Math.min(Nt,Math.max(1,Math.round(n))),e,r=1,s=.001,o=1-Math.pow(s,1/300),u=0,h=.6,f=new Map,l=gt(y),c=_t("tick","end"),v=Tn();t==null&&(t=[]);function y(){_(),c.call("tick",e),r<s&&(l.stop(),c.call("end",e))}function _(a){var N,d=t.length,w;a===void 0&&(a=1);for(var p=0;p<a;++p)for(r+=(u-r)*o,f.forEach(function(M){M(r)}),N=0;N<d;++N)w=t[N],w.fx==null?w.x+=w.vx*=h:(w.x=w.fx,w.vx=0),i>1&&(w.fy==null?w.y+=w.vy*=h:(w.y=w.fy,w.vy=0)),i>2&&(w.fz==null?w.z+=w.vz*=h:(w.z=w.fz,w.vz=0));return e}function g(){for(var a=0,N=t.length,d;a<N;++a){if(d=t[a],d.index=a,d.fx!=null&&(d.x=d.fx),d.fy!=null&&(d.y=d.fy),d.fz!=null&&(d.z=d.fz),isNaN(d.x)||i>1&&isNaN(d.y)||i>2&&isNaN(d.z)){var w=Pn*(i>2?Math.cbrt(.5+a):i>1?Math.sqrt(.5+a):a),p=a*Fn,M=a*Sn;i===1?d.x=w:i===2?(d.x=w*Math.cos(p),d.y=w*Math.sin(p)):(d.x=w*Math.sin(p)*Math.cos(M),d.y=w*Math.cos(p),d.z=w*Math.sin(p)*Math.sin(M))}(isNaN(d.vx)||i>1&&isNaN(d.vy)||i>2&&isNaN(d.vz))&&(d.vx=0,i>1&&(d.vy=0),i>2&&(d.vz=0))}}function x(a){return a.initialize&&a.initialize(t,v,i),a}return g(),e={tick:_,restart:function(){return l.restart(y),e},stop:function(){return l.stop(),e},numDimensions:function(a){return arguments.length?(i=Math.min(Nt,Math.max(1,Math.round(a))),f.forEach(x),e):i},nodes:function(a){return arguments.length?(t=a,g(),f.forEach(x),e):t},alpha:function(a){return arguments.length?(r=+a,e):r},alphaMin:function(a){return arguments.length?(s=+a,e):s},alphaDecay:function(a){return arguments.length?(o=+a,e):+o},alphaTarget:function(a){return arguments.length?(u=+a,e):u},velocityDecay:function(a){return arguments.length?(h=1-a,e):1-h},randomSource:function(a){return arguments.length?(v=a,f.forEach(x),e):v},force:function(a,N){return arguments.length>1?(N==null?f.delete(a):f.set(a,x(N)),e):f.get(a)},find:function(){var a=Array.prototype.slice.call(arguments),N=a.shift()||0,d=(i>1?a.shift():null)||0,w=(i>2?a.shift():null)||0,p=a.shift()||1/0,M=0,z=t.length,A,E,T,D,m,zt;for(p*=p,M=0;M<z;++M)m=t[M],A=N-m.x,E=d-(m.y||0),T=w-(m.z||0),D=A*A+E*E+T*T,D<p&&(zt=m,p=D);return zt},on:function(a,N){return arguments.length>1?(c.on(a,N),e):c.on(a)}}}function Rn(){var t,n,i,e,r,s=X(-30),o,u=1,h=1/0,f=.81;function l(_){var g,x=t.length,a=(n===1?rt(t,tt):n===2?ht(t,tt,Mt):n===3?ut(t,tt,Mt,jn):null).visitAfter(v);for(r=_,g=0;g<x;++g)i=t[g],a.visit(y)}function c(){if(t){var _,g=t.length,x;for(o=new Array(g),_=0;_<g;++_)x=t[_],o[x.index]=+s(x,_,t)}}function v(_){var g=0,x,a,N=0,d,w,p,M,z=_.length;if(z){for(d=w=p=M=0;M<z;++M)(x=_[M])&&(a=Math.abs(x.value))&&(g+=x.value,N+=a,d+=a*(x.x||0),w+=a*(x.y||0),p+=a*(x.z||0));g*=Math.sqrt(4/z),_.x=d/N,n>1&&(_.y=w/N),n>2&&(_.z=p/N)}else{x=_,x.x=x.data.x,n>1&&(x.y=x.data.y),n>2&&(x.z=x.data.z);do g+=o[x.data.index];while(x=x.next)}_.value=g}function y(_,g,x,a,N){if(!_.value)return!0;var d=[x,a,N][n-1],w=_.x-i.x,p=n>1?_.y-i.y:0,M=n>2?_.z-i.z:0,z=d-g,A=w*w+p*p+M*M;if(z*z/f<A)return A<h&&(w===0&&(w=F(e),A+=w*w),n>1&&p===0&&(p=F(e),A+=p*p),n>2&&M===0&&(M=F(e),A+=M*M),A<u&&(A=Math.sqrt(u*A)),i.vx+=w*_.value*r/A,n>1&&(i.vy+=p*_.value*r/A),n>2&&(i.vz+=M*_.value*r/A)),!0;if(_.length||A>=h)return;(_.data!==i||_.next)&&(w===0&&(w=F(e),A+=w*w),n>1&&p===0&&(p=F(e),A+=p*p),n>2&&M===0&&(M=F(e),A+=M*M),A<u&&(A=Math.sqrt(u*A)));do _.data!==i&&(z=o[_.data.index]*r/A,i.vx+=w*z,n>1&&(i.vy+=p*z),n>2&&(i.vz+=M*z));while(_=_.next)}return l.initialize=function(_,...g){t=_,e=g.find(x=>typeof x=="function")||Math.random,n=g.find(x=>[1,2,3].includes(x))||2,c()},l.strength=function(_){return arguments.length?(s=typeof _=="function"?_:X(+_),c(),l):s},l.distanceMin=function(_){return arguments.length?(u=_*_,l):Math.sqrt(u)},l.distanceMax=function(_){return arguments.length?(h=_*_,l):Math.sqrt(h)},l.theta=function(_){return arguments.length?(f=_*_,l):Math.sqrt(f)},l}let S=null,j=[],nt=0,it=!1;self.onmessage=t=>{const n=t.data;if(n.type==="init"){S&&S.stop(),it=!1,nt=0;const i=n.nodes.length,e=n.params,r=n.initialPositions??{},s=e.dimensions===2?2:3;j=n.nodes.map((h,f)=>{const l=r[h.id];if(l)return{id:h.id,index:f,x:l.x,y:l.y,z:s===2?0:l.z};const c=Math.random()*Math.PI*2,v=e.initialRadius*(.5+Math.random()*.5);if(s===2)return{id:h.id,index:f,x:v*Math.cos(c),y:v*Math.sin(c),z:0};const y=Math.acos(2*Math.random()-1);return{id:h.id,index:f,x:v*Math.sin(y)*Math.cos(c),y:v*Math.sin(y)*Math.sin(c),z:v*Math.cos(y)}});const o=n.links.map(h=>({source:h.source,target:h.target}));S=On(j,s).force("charge",Rn().strength(e.charge).distanceMax(e.distanceMax).theta(e.theta)).force("link",zn(o).id(h=>h.id).distance(e.linkDistance).strength(.2)).force("center",At()).alphaDecay(e.alphaDecay).velocityDecay(e.velocityDecay);const u=n.groups;if(u&&u.length===j.length&&e.clusterStrength>0){const h=e.clusterStrength;S.force("cluster",f=>{const l={},c={},v={},y={};for(let g=0;g<j.length;g++){const x=u[g];x<0||(l[x]=(l[x]??0)+j[g].x,c[x]=(c[x]??0)+j[g].y,v[x]=(v[x]??0)+(j[g].z||0),y[x]=(y[x]??0)+1)}const _=h*f;for(let g=0;g<j.length;g++){const x=u[g];if(x<0||!y[x])continue;const a=j[g];a.vx=(a.vx||0)+(l[x]/y[x]-a.x)*_,a.vy=(a.vy||0)+(c[x]/y[x]-a.y)*_,s===3&&(a.vz=(a.vz||0)+(v[x]/y[x]-a.z)*_)}})}S.on("tick",()=>{nt++;const h=S.alpha();if(nt%e.postEvery!==0&&h>e.settledThreshold)return;const f=new Float32Array(i*3);for(let l=0;l<i;l++)f[l*3]=j[l].x||0,f[l*3+1]=j[l].y||0,f[l*3+2]=s===2?0:j[l].z||0;self.postMessage({type:"positions",positions:f.buffer,alpha:h},[f.buffer]),!it&&h<e.settledThreshold&&(it=!0,self.postMessage({type:"settled"}))})}n.type==="stop"&&S&&(S.stop(),S=null)}})();\n';
226
279
  function createLayoutWorker() {
227
280
  const blob = new Blob([WORKER_SOURCE], { type: "application/javascript" });
228
281
  const url = URL.createObjectURL(blob);
@@ -1723,6 +1776,7 @@ function applyNodeHighlight(nodesMesh, nodes, selectedNodeId, highlightSet, them
1723
1776
  const nc = nodes.length;
1724
1777
  const tmpColor = new THREE__namespace.Color();
1725
1778
  const brightTmp = new THREE__namespace.Color();
1779
+ const bgColor = new THREE__namespace.Color(theme.backgroundColor);
1726
1780
  for (let i = 0; i < nc; i++) {
1727
1781
  const node = nodes[i];
1728
1782
  const baseColor = theme.nodeColor(node.type);
@@ -1730,13 +1784,17 @@ function applyNodeHighlight(nodesMesh, nodes, selectedNodeId, highlightSet, them
1730
1784
  if (!highlightSet) {
1731
1785
  tmpColor.set(baseColor);
1732
1786
  } else if (node.id === selectedNodeId) {
1733
- tmpColor.set(brightColor);
1734
- brightTmp.setRGB(1, 1, 1);
1735
- tmpColor.lerp(brightTmp, 0.65);
1736
- tmpColor.multiplyScalar(1.4);
1737
- tmpColor.r = Math.min(tmpColor.r, 2);
1738
- tmpColor.g = Math.min(tmpColor.g, 2);
1739
- tmpColor.b = Math.min(tmpColor.b, 2);
1787
+ if (theme.isLight) {
1788
+ tmpColor.set(brightColor);
1789
+ } else {
1790
+ tmpColor.set(brightColor);
1791
+ brightTmp.setRGB(1, 1, 1);
1792
+ tmpColor.lerp(brightTmp, 0.65);
1793
+ tmpColor.multiplyScalar(1.4);
1794
+ tmpColor.r = Math.min(tmpColor.r, 2);
1795
+ tmpColor.g = Math.min(tmpColor.g, 2);
1796
+ tmpColor.b = Math.min(tmpColor.b, 2);
1797
+ }
1740
1798
  } else if (highlightSet.has(node.id)) {
1741
1799
  const hop = highlightSet.get(node.id);
1742
1800
  if (hop === 1) {
@@ -1748,6 +1806,8 @@ function applyNodeHighlight(nodesMesh, nodes, selectedNodeId, highlightSet, them
1748
1806
  } else {
1749
1807
  tmpColor.set(baseColor).multiplyScalar(0.6);
1750
1808
  }
1809
+ } else if (theme.isLight) {
1810
+ tmpColor.set(baseColor).lerp(bgColor, 0.88);
1751
1811
  } else {
1752
1812
  tmpColor.set(baseColor).multiplyScalar(0.04);
1753
1813
  }
@@ -1765,6 +1825,7 @@ function applyEdgeHighlight(edgesMesh, links, edgeNodeIndices, edgeLinkIndices,
1765
1825
  const colorArr = colorAttr.array;
1766
1826
  const validCount = edgeNodeIndices.length;
1767
1827
  const tmpColor = new THREE__namespace.Color();
1828
+ const bgColor = new THREE__namespace.Color(theme.backgroundColor);
1768
1829
  for (let i = 0; i < validCount; i++) {
1769
1830
  const origIdx = edgeLinkIndices[i];
1770
1831
  const link = links[origIdx];
@@ -1776,13 +1837,19 @@ function applyEdgeHighlight(edgesMesh, links, edgeNodeIndices, edgeLinkIndices,
1776
1837
  const maxHopVal = Math.max(highlightSet.get(sId), highlightSet.get(tId));
1777
1838
  tmpColor.set(theme.linkColor(link == null ? void 0 : link.type));
1778
1839
  if (maxHopVal <= 1) {
1779
- tmpColor.multiplyScalar(1.8);
1780
- tmpColor.r = Math.min(tmpColor.r, 1);
1781
- tmpColor.g = Math.min(tmpColor.g, 1);
1782
- tmpColor.b = Math.min(tmpColor.b, 1);
1840
+ if (theme.isLight) {
1841
+ tmpColor.multiplyScalar(0.55);
1842
+ } else {
1843
+ tmpColor.multiplyScalar(1.8);
1844
+ tmpColor.r = Math.min(tmpColor.r, 1);
1845
+ tmpColor.g = Math.min(tmpColor.g, 1);
1846
+ tmpColor.b = Math.min(tmpColor.b, 1);
1847
+ }
1783
1848
  } else if (maxHopVal === 2) {
1784
- tmpColor.multiplyScalar(1.2);
1849
+ tmpColor.multiplyScalar(theme.isLight ? 0.8 : 1.2);
1785
1850
  }
1851
+ } else if (theme.isLight) {
1852
+ tmpColor.set(theme.linkColor(link == null ? void 0 : link.type)).lerp(bgColor, 0.85);
1786
1853
  } else {
1787
1854
  tmpColor.setRGB(0.01, 0.01, 0.02);
1788
1855
  }
@@ -1912,7 +1979,7 @@ function getOrCreateTexture(cache, nodeId, text, color) {
1912
1979
  }
1913
1980
  return entry;
1914
1981
  }
1915
- function updateLabels(state, nodes, positions, scales, camera, theme, showLabels, labelScale, labelThreshold, maxLabels, labelFormatter, highlightSet) {
1982
+ function updateLabels(state, nodes, positions, scales, camera, theme, showLabels, labelScale, labelThreshold, maxLabels, labelFormatter, highlightSet, hidden) {
1916
1983
  if (!positions || nodes.length === 0 || !showLabels) {
1917
1984
  for (const sp of state.sprites) sp.visible = false;
1918
1985
  return;
@@ -1926,6 +1993,7 @@ function updateLabels(state, nodes, positions, scales, camera, theme, showLabels
1926
1993
  const maxDistSq = maxDist * maxDist;
1927
1994
  const candidates = [];
1928
1995
  for (let i = 0; i < nc; i++) {
1996
+ if (hidden && hidden[i]) continue;
1929
1997
  if (highlightSet && !highlightSet.has(nodes[i].id)) continue;
1930
1998
  const dx = positions[i * 3] - camPos.x;
1931
1999
  const dy = positions[i * 3 + 1] - camPos.y;
@@ -1981,6 +2049,45 @@ const _right = new THREE__namespace.Vector3();
1981
2049
  const _q = new THREE__namespace.Quaternion();
1982
2050
  const _dir = new THREE__namespace.Vector3();
1983
2051
  const _worldUp = new THREE__namespace.Vector3(0, 1, 0);
2052
+ const PAN_SPEED = 0.02;
2053
+ const PAN_ZOOM_FACTOR = 0.02;
2054
+ function createPanUpdate(camera, controls, keys) {
2055
+ const _panRight = new THREE__namespace.Vector3();
2056
+ const _panUp = new THREE__namespace.Vector3();
2057
+ const _panOffset = new THREE__namespace.Vector3();
2058
+ return function update() {
2059
+ let dx = 0;
2060
+ let dy = 0;
2061
+ if (keys["ArrowLeft"] || keys["a"] || keys["A"]) dx -= 1;
2062
+ if (keys["ArrowRight"] || keys["d"] || keys["D"]) dx += 1;
2063
+ if (keys["ArrowUp"] || keys["w"] || keys["W"]) dy += 1;
2064
+ if (keys["ArrowDown"] || keys["s"] || keys["S"]) dy -= 1;
2065
+ const zoomIn = keys["z"] || keys["Z"] || keys["+"] || keys["="];
2066
+ const zoomOut = keys["x"] || keys["X"] || keys["-"] || keys["_"];
2067
+ if (!dx && !dy && !zoomIn && !zoomOut) return false;
2068
+ const target = controls.target;
2069
+ const dist = camera.position.distanceTo(target);
2070
+ if (dx || dy) {
2071
+ const step = Math.max(dist, 50) * PAN_SPEED;
2072
+ _panRight.setFromMatrixColumn(camera.matrix, 0);
2073
+ _panUp.setFromMatrixColumn(camera.matrix, 1);
2074
+ _panOffset.set(0, 0, 0).addScaledVector(_panRight, dx * step).addScaledVector(_panUp, dy * step);
2075
+ camera.position.add(_panOffset);
2076
+ target.add(_panOffset);
2077
+ }
2078
+ if (zoomIn || zoomOut) {
2079
+ const factor = zoomIn ? -PAN_ZOOM_FACTOR : PAN_ZOOM_FACTOR;
2080
+ _panOffset.copy(camera.position).sub(target);
2081
+ const newLen = Math.max(
2082
+ controls.minDistance,
2083
+ Math.min(controls.maxDistance, _panOffset.length() * (1 + factor))
2084
+ );
2085
+ _panOffset.setLength(newLen);
2086
+ camera.position.copy(target).add(_panOffset);
2087
+ }
2088
+ return true;
2089
+ };
2090
+ }
1984
2091
  function createOrbitUpdate(camera, controls, keys) {
1985
2092
  return function update() {
1986
2093
  let zoom = 0;
@@ -2079,7 +2186,14 @@ function setupKeyboardControls(camera, controls, container, mode = "fly", flySpe
2079
2186
  container.addEventListener("keydown", onKeyDown2);
2080
2187
  container.addEventListener("keyup", onKeyUp);
2081
2188
  container.addEventListener("blur", onBlur);
2082
- const updateFn = mode === "fly" ? createFlyUpdate(camera, controls, keys, state) : createOrbitUpdate(camera, controls, keys);
2189
+ let enabled = true;
2190
+ let currentMode = mode;
2191
+ const updaters = {
2192
+ fly: createFlyUpdate(camera, controls, keys, state),
2193
+ orbit: createOrbitUpdate(camera, controls, keys),
2194
+ pan: createPanUpdate(camera, controls, keys)
2195
+ };
2196
+ const updateFn = () => enabled ? updaters[currentMode]() : false;
2083
2197
  function cleanup() {
2084
2198
  container.removeEventListener("keydown", onKeyDown2);
2085
2199
  container.removeEventListener("keyup", onKeyUp);
@@ -2088,7 +2202,15 @@ function setupKeyboardControls(camera, controls, container, mode = "fly", flySpe
2088
2202
  function setFlySpeed(speed) {
2089
2203
  state.flySpeed = speed;
2090
2204
  }
2091
- return { update: updateFn, cleanup, setFlySpeed };
2205
+ function setEnabled(on) {
2206
+ enabled = on;
2207
+ if (!on) for (const k of Object.keys(keys)) keys[k] = false;
2208
+ }
2209
+ function setMode(m2) {
2210
+ currentMode = m2;
2211
+ for (const k of Object.keys(keys)) keys[k] = false;
2212
+ }
2213
+ return { update: updateFn, cleanup, setFlySpeed, setEnabled, setMode };
2092
2214
  }
2093
2215
  function createScene(container, backgroundColor, style, rendererConfig) {
2094
2216
  const scene = new THREE__namespace.Scene();
@@ -2128,8 +2250,13 @@ function createScene(container, backgroundColor, style, rendererConfig) {
2128
2250
  const cameraMode = (rendererConfig == null ? void 0 : rendererConfig.cameraMode) ?? "fly";
2129
2251
  const keyboard = setupKeyboardControls(camera, controls, container, cameraMode, style.flySpeed ?? 1);
2130
2252
  controls.enableZoom = false;
2253
+ const flags = {
2254
+ is2D: false,
2255
+ keyboardMode3D: cameraMode
2256
+ };
2131
2257
  const _wheelDir = new THREE__namespace.Vector3();
2132
2258
  const onWheel = (e) => {
2259
+ if (flags.is2D) return;
2133
2260
  e.preventDefault();
2134
2261
  let delta = -e.deltaY;
2135
2262
  if (e.deltaMode === 1) delta *= 40;
@@ -2153,9 +2280,41 @@ function createScene(container, backgroundColor, style, rendererConfig) {
2153
2280
  composer: null,
2154
2281
  bloomPass: null,
2155
2282
  keyboard,
2156
- scrollCleanup
2283
+ scrollCleanup,
2284
+ flags
2157
2285
  };
2158
2286
  }
2287
+ function applyCameraMode2D(state, is2D) {
2288
+ const { controls, camera, keyboard } = state;
2289
+ state.flags.is2D = is2D;
2290
+ controls.enableRotate = true;
2291
+ controls.enableZoom = is2D;
2292
+ controls.screenSpacePanning = is2D;
2293
+ keyboard.setEnabled(true);
2294
+ keyboard.setMode(is2D ? "pan" : state.flags.keyboardMode3D);
2295
+ if (is2D) {
2296
+ controls.mouseButtons = {
2297
+ LEFT: THREE__namespace.MOUSE.PAN,
2298
+ MIDDLE: THREE__namespace.MOUSE.DOLLY,
2299
+ RIGHT: THREE__namespace.MOUSE.ROTATE
2300
+ };
2301
+ controls.touches = { ONE: THREE__namespace.TOUCH.PAN, TWO: THREE__namespace.TOUCH.DOLLY_PAN };
2302
+ const t = controls.target;
2303
+ const dist = Math.max(camera.position.distanceTo(t), 50);
2304
+ t.z = 0;
2305
+ camera.up.set(0, 1, 0);
2306
+ camera.position.set(t.x, t.y, dist);
2307
+ camera.lookAt(t);
2308
+ } else {
2309
+ controls.mouseButtons = {
2310
+ LEFT: THREE__namespace.MOUSE.ROTATE,
2311
+ MIDDLE: THREE__namespace.MOUSE.DOLLY,
2312
+ RIGHT: THREE__namespace.MOUSE.PAN
2313
+ };
2314
+ controls.touches = { ONE: THREE__namespace.TOUCH.ROTATE, TWO: THREE__namespace.TOUCH.DOLLY_PAN };
2315
+ }
2316
+ controls.update();
2317
+ }
2159
2318
  function initBloom(state, nodeCount, style) {
2160
2319
  if (state.composer) return;
2161
2320
  try {
@@ -2352,14 +2511,14 @@ function createNodeMesh(nodes, scales, theme) {
2352
2511
  mesh.computeBoundingSphere();
2353
2512
  return { mesh, material, scales };
2354
2513
  }
2355
- function updateNodePositions(mesh, positions, scales, nodeCount) {
2514
+ function updateNodePositions(mesh, positions, scales, nodeCount, hidden) {
2356
2515
  const pos = new THREE__namespace.Vector3();
2357
2516
  const scale = new THREE__namespace.Vector3();
2358
2517
  const quat = new THREE__namespace.Quaternion();
2359
2518
  const mat = new THREE__namespace.Matrix4();
2360
2519
  for (let i = 0; i < nodeCount; i++) {
2361
2520
  pos.set(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]);
2362
- const sc = scales[i];
2521
+ const sc = hidden && hidden[i] ? 1e-4 : scales[i];
2363
2522
  scale.set(sc, sc, sc);
2364
2523
  mat.compose(pos, quat, scale);
2365
2524
  mesh.setMatrixAt(i, mat);
@@ -2416,7 +2575,7 @@ function createEdgeMesh(links, edgeNodeIndices, edgeLinkIndices, nodeCount, edge
2416
2575
  transparent: true,
2417
2576
  opacity: adaptiveOpacity,
2418
2577
  depthWrite: false,
2419
- blending: THREE__namespace.AdditiveBlending
2578
+ blending: theme.additiveEdges ? THREE__namespace.AdditiveBlending : THREE__namespace.NormalBlending
2420
2579
  });
2421
2580
  const mesh = new THREE__namespace.LineSegments(geometry, material);
2422
2581
  return {
@@ -2428,10 +2587,19 @@ function createEdgeMesh(links, edgeNodeIndices, edgeLinkIndices, nodeCount, edge
2428
2587
  edgeLinkIndices
2429
2588
  };
2430
2589
  }
2431
- function updateEdgePositions(positionArray, nodePositions, edgeNodeIndices, geometry) {
2590
+ function updateEdgePositions(positionArray, nodePositions, edgeNodeIndices, geometry, hiddenEdges) {
2432
2591
  const count = edgeNodeIndices.length;
2433
2592
  for (let i = 0; i < count; i++) {
2434
2593
  const [si, ti] = edgeNodeIndices[i];
2594
+ if (hiddenEdges && hiddenEdges[i]) {
2595
+ positionArray[i * 6 + 0] = nodePositions[si * 3];
2596
+ positionArray[i * 6 + 1] = nodePositions[si * 3 + 1];
2597
+ positionArray[i * 6 + 2] = nodePositions[si * 3 + 2];
2598
+ positionArray[i * 6 + 3] = nodePositions[si * 3];
2599
+ positionArray[i * 6 + 4] = nodePositions[si * 3 + 1];
2600
+ positionArray[i * 6 + 5] = nodePositions[si * 3 + 2];
2601
+ continue;
2602
+ }
2435
2603
  positionArray[i * 6 + 0] = nodePositions[si * 3];
2436
2604
  positionArray[i * 6 + 1] = nodePositions[si * 3 + 1];
2437
2605
  positionArray[i * 6 + 2] = nodePositions[si * 3 + 2];
@@ -2494,7 +2662,7 @@ function zoomToFitPositions(camera, controls, positions, duration, padding) {
2494
2662
  );
2495
2663
  }
2496
2664
  const EDGE_HIT_THRESHOLD = 5;
2497
- function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, callbacks, container, getEdgeData) {
2665
+ function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, callbacks, container, getEdgeData, options) {
2498
2666
  const raycaster = new THREE__namespace.Raycaster();
2499
2667
  const mouse = new THREE__namespace.Vector2();
2500
2668
  let mouseDownPos = null;
@@ -2506,11 +2674,12 @@ function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, call
2506
2674
  const dragPlane = new THREE__namespace.Plane();
2507
2675
  const dragIntersect = new THREE__namespace.Vector3();
2508
2676
  function onPointerDown2(e) {
2677
+ var _a;
2509
2678
  mouseDownPos = { x: e.clientX, y: e.clientY };
2510
2679
  if (container && document.activeElement !== container) {
2511
2680
  container.focus({ preventScroll: true });
2512
2681
  }
2513
- if (callbacks.onNodeDrag) {
2682
+ if (callbacks.onNodeDrag && (((_a = options == null ? void 0 : options.getNodeDragEnabled) == null ? void 0 : _a.call(options)) ?? true)) {
2514
2683
  const nodesMesh = getNodesMesh();
2515
2684
  if (nodesMesh) {
2516
2685
  const rect = canvas.getBoundingClientRect();
@@ -2652,20 +2821,34 @@ function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, call
2652
2821
  lastClickTime = now2;
2653
2822
  lastClickNodeId = node.id;
2654
2823
  singleClickTimer = setTimeout(() => {
2824
+ var _a2, _b;
2655
2825
  singleClickTimer = null;
2656
- const nx = node.x ?? 0;
2657
- const ny = node.y ?? 0;
2658
- const nz = node.z ?? 0;
2659
- const dist = Math.hypot(nx, ny, nz);
2660
- if (dist > 1) {
2661
- const ratio = 1 + 120 / dist;
2662
- animateCamera(
2663
- camera,
2664
- controls,
2665
- { x: nx * ratio, y: ny * ratio, z: nz * ratio },
2666
- { x: nx, y: ny, z: nz },
2667
- 1200
2668
- );
2826
+ const clickToFocus = ((_a2 = options == null ? void 0 : options.getClickToFocus) == null ? void 0 : _a2.call(options)) ?? true;
2827
+ if (clickToFocus) {
2828
+ const nx = node.x ?? 0;
2829
+ const ny = node.y ?? 0;
2830
+ const nz = node.z ?? 0;
2831
+ if ((_b = options == null ? void 0 : options.getIs2D) == null ? void 0 : _b.call(options)) {
2832
+ animateCamera(
2833
+ camera,
2834
+ controls,
2835
+ { x: nx, y: ny, z: camera.position.z },
2836
+ { x: nx, y: ny, z: 0 },
2837
+ 800
2838
+ );
2839
+ } else {
2840
+ const dist = Math.hypot(nx, ny, nz);
2841
+ if (dist > 1) {
2842
+ const ratio = 1 + 120 / dist;
2843
+ animateCamera(
2844
+ camera,
2845
+ controls,
2846
+ { x: nx * ratio, y: ny * ratio, z: nz * ratio },
2847
+ { x: nx, y: ny, z: nz },
2848
+ 1200
2849
+ );
2850
+ }
2851
+ }
2669
2852
  }
2670
2853
  callbacks.onNodeClick(node);
2671
2854
  }, 250);
@@ -2805,7 +2988,13 @@ function NetworkGraph3DInner(props, ref) {
2805
2988
  layout: layoutProp,
2806
2989
  renderer: rendererProp,
2807
2990
  labelFormatter,
2808
- nodeValueAccessor
2991
+ nodeValueAccessor,
2992
+ visibleNodeIds,
2993
+ linkVisibility,
2994
+ enableNodeDrag = true,
2995
+ clickToFocus = true,
2996
+ hoverHighlight = false,
2997
+ hoverHighlightHops = 1
2809
2998
  } = props;
2810
2999
  const containerRef = react.useRef(null);
2811
3000
  const resolvedStyle = react.useMemo(
@@ -2842,6 +3031,14 @@ function NetworkGraph3DInner(props, ref) {
2842
3031
  const selectedNodeIdRef = react.useRef(selectedNodeId);
2843
3032
  const labelFormatterRef = react.useRef(labelFormatter);
2844
3033
  const highlightSetRef = react.useRef(null);
3034
+ const clickToFocusRef = react.useRef(clickToFocus);
3035
+ const enableNodeDragRef = react.useRef(enableNodeDrag);
3036
+ const hoverHighlightRef = react.useRef(hoverHighlight);
3037
+ const hoverHighlightHopsRef = react.useRef(hoverHighlightHops);
3038
+ const adjacencyMapRef = react.useRef(/* @__PURE__ */ new Map());
3039
+ const is2DRef = react.useRef(false);
3040
+ const hiddenNodesRef = react.useRef(null);
3041
+ const hiddenEdgesRef = react.useRef(null);
2845
3042
  onNodeClickRef.current = onNodeClick;
2846
3043
  onNodeDoubleClickRef.current = onNodeDoubleClick;
2847
3044
  onNodeHoverRef.current = onNodeHover;
@@ -2856,6 +3053,15 @@ function NetworkGraph3DInner(props, ref) {
2856
3053
  themeRef.current = resolvedTheme;
2857
3054
  selectedNodeIdRef.current = selectedNodeId;
2858
3055
  labelFormatterRef.current = labelFormatter;
3056
+ clickToFocusRef.current = clickToFocus;
3057
+ enableNodeDragRef.current = enableNodeDrag;
3058
+ hoverHighlightRef.current = hoverHighlight;
3059
+ hoverHighlightHopsRef.current = hoverHighlightHops;
3060
+ const is2D = (layoutProp == null ? void 0 : layoutProp.dimensions) === 2;
3061
+ is2DRef.current = is2D;
3062
+ const layoutKey = JSON.stringify(layoutProp ?? null);
3063
+ const layoutRef = react.useRef(layoutProp);
3064
+ layoutRef.current = layoutProp;
2859
3065
  const mergedData = react.useMemo(() => {
2860
3066
  if (!appendedData) return data;
2861
3067
  const existingIds = new Set(data.nodes.map((n) => n.id));
@@ -2882,6 +3088,11 @@ function NetworkGraph3DInner(props, ref) {
2882
3088
  () => buildAdjacencyMapFromLinks(mergedData.links),
2883
3089
  [mergedData.links]
2884
3090
  );
3091
+ adjacencyMapRef.current = adjacencyMap;
3092
+ const visibleSet = react.useMemo(() => {
3093
+ if (visibleNodeIds == null) return null;
3094
+ return visibleNodeIds instanceof Set ? visibleNodeIds : new Set(visibleNodeIds);
3095
+ }, [visibleNodeIds]);
2885
3096
  const highlightSet = react.useMemo(() => {
2886
3097
  if (!selectedNodeId) return null;
2887
3098
  return computeHighlightSet(selectedNodeId, adjacencyMap, highlightHops);
@@ -2895,6 +3106,32 @@ function NetworkGraph3DInner(props, ref) {
2895
3106
  }
2896
3107
  return { min: isFinite(min) ? min : 1, max: isFinite(max) ? max : 1 };
2897
3108
  }, [mergedData.nodes, nodeValueAccessor]);
3109
+ const applyHoverHighlight = (node) => {
3110
+ if (!hoverHighlightRef.current) return;
3111
+ if (selectedNodeIdRef.current) return;
3112
+ const gObj = graphObjRef.current;
3113
+ if (!gObj) return;
3114
+ const d = dataRef.current;
3115
+ const set2 = node ? computeHighlightSet(
3116
+ node.id,
3117
+ adjacencyMapRef.current,
3118
+ hoverHighlightHopsRef.current
3119
+ ) : null;
3120
+ highlightSetRef.current = set2;
3121
+ applyNodeHighlight(gObj.nodesMesh, d.nodes, (node == null ? void 0 : node.id) ?? null, set2, themeRef.current);
3122
+ applyEdgeHighlight(
3123
+ gObj.edgesMesh,
3124
+ d.links,
3125
+ d.edgeNodeIndices,
3126
+ d.edgeLinkIndices,
3127
+ set2,
3128
+ styleRef.current.edgeOpacity,
3129
+ d.nodes.length,
3130
+ themeRef.current
3131
+ );
3132
+ };
3133
+ const applyHoverHighlightRef = react.useRef(applyHoverHighlight);
3134
+ applyHoverHighlightRef.current = applyHoverHighlight;
2898
3135
  react.useEffect(() => {
2899
3136
  const container = containerRef.current;
2900
3137
  if (!container) return;
@@ -2918,7 +3155,8 @@ function NetworkGraph3DInner(props, ref) {
2918
3155
  styleRef.current.labelThreshold,
2919
3156
  styleRef.current.maxLabels,
2920
3157
  labelFormatterRef.current,
2921
- highlightSetRef.current
3158
+ highlightSetRef.current,
3159
+ hiddenNodesRef.current
2922
3160
  );
2923
3161
  });
2924
3162
  const resizeObserver = setupResize(container, state);
@@ -2942,7 +3180,8 @@ function NetworkGraph3DInner(props, ref) {
2942
3180
  },
2943
3181
  onNodeHover: (node) => {
2944
3182
  var _a;
2945
- return (_a = onNodeHoverRef.current) == null ? void 0 : _a.call(onNodeHoverRef, node);
3183
+ (_a = onNodeHoverRef.current) == null ? void 0 : _a.call(onNodeHoverRef, node);
3184
+ applyHoverHighlightRef.current(node);
2946
3185
  },
2947
3186
  onContextMenu: (node, pos) => {
2948
3187
  var _a;
@@ -2958,6 +3197,7 @@ function NetworkGraph3DInner(props, ref) {
2958
3197
  },
2959
3198
  onNodeDrag: (node, pos) => {
2960
3199
  var _a;
3200
+ if (is2DRef.current) pos = { ...pos, z: 0 };
2961
3201
  (_a = onNodeDragRef.current) == null ? void 0 : _a.call(onNodeDragRef, node, pos);
2962
3202
  const d = dataRef.current;
2963
3203
  const idx = d.nodeIdToIndex.get(node.id);
@@ -2970,7 +3210,13 @@ function NetworkGraph3DInner(props, ref) {
2970
3210
  node.z = pos.z;
2971
3211
  const gObj = graphObjRef.current;
2972
3212
  if (gObj && d.scales) {
2973
- updateNodePositions(gObj.nodesMesh, d.positions, d.scales, d.nodes.length);
3213
+ updateNodePositions(
3214
+ gObj.nodesMesh,
3215
+ d.positions,
3216
+ d.scales,
3217
+ d.nodes.length,
3218
+ hiddenNodesRef.current
3219
+ );
2974
3220
  }
2975
3221
  }
2976
3222
  },
@@ -2988,6 +3234,11 @@ function NetworkGraph3DInner(props, ref) {
2988
3234
  edgeLinkIndices: d.edgeLinkIndices,
2989
3235
  positions: d.positions
2990
3236
  };
3237
+ },
3238
+ {
3239
+ getClickToFocus: () => clickToFocusRef.current,
3240
+ getIs2D: () => is2DRef.current,
3241
+ getNodeDragEnabled: () => enableNodeDragRef.current
2991
3242
  }
2992
3243
  );
2993
3244
  return () => {
@@ -3134,17 +3385,26 @@ function NetworkGraph3DInner(props, ref) {
3134
3385
  if (msg.type === "positions") {
3135
3386
  const positions = new Float32Array(msg.positions);
3136
3387
  dataRef.current.positions = positions;
3137
- updateNodePositions(nodesMesh, positions, scales, nc);
3388
+ const hn = hiddenNodesRef.current;
3389
+ updateNodePositions(
3390
+ nodesMesh,
3391
+ positions,
3392
+ scales,
3393
+ nc,
3394
+ hn && hn.length === nc ? hn : null
3395
+ );
3138
3396
  for (let i = 0; i < nc; i++) {
3139
3397
  nodes[i].x = positions[i * 3];
3140
3398
  nodes[i].y = positions[i * 3 + 1];
3141
3399
  nodes[i].z = positions[i * 3 + 2];
3142
3400
  }
3401
+ const he = hiddenEdgesRef.current;
3143
3402
  updateEdgePositions(
3144
3403
  edgeResult.positionArray,
3145
3404
  positions,
3146
3405
  edgeNodeIndices,
3147
- edgeResult.geometry
3406
+ edgeResult.geometry,
3407
+ he && he.length === edgeNodeIndices.length ? he : null
3148
3408
  );
3149
3409
  const selId = selectedNodeIdRef.current;
3150
3410
  if (selId && sceneState.selectionRing.visible) {
@@ -3164,7 +3424,20 @@ function NetworkGraph3DInner(props, ref) {
3164
3424
  (_b = onLayoutSettledRef.current) == null ? void 0 : _b.call(onLayoutSettledRef);
3165
3425
  }
3166
3426
  };
3167
- const layoutParams = resolveLayoutParams(nc, layoutProp);
3427
+ const layoutConfig = layoutRef.current;
3428
+ const layoutParams = resolveLayoutParams(nc, layoutConfig);
3429
+ let groups;
3430
+ if (layoutConfig == null ? void 0 : layoutConfig.clusterBy) {
3431
+ const keyOf = (n) => layoutConfig.clusterBy === "type" ? n.type : n.group;
3432
+ const keyToIdx = /* @__PURE__ */ new Map();
3433
+ groups = nodes.map((n) => {
3434
+ const k = keyOf(n);
3435
+ if (k == null) return -1;
3436
+ const ks = String(k);
3437
+ if (!keyToIdx.has(ks)) keyToIdx.set(ks, keyToIdx.size);
3438
+ return keyToIdx.get(ks);
3439
+ });
3440
+ }
3168
3441
  worker.postMessage({
3169
3442
  type: "init",
3170
3443
  nodes: nodes.map((n) => ({ id: n.id })),
@@ -3173,7 +3446,8 @@ function NetworkGraph3DInner(props, ref) {
3173
3446
  target: typeof l.target === "object" ? l.target.id : l.target
3174
3447
  })),
3175
3448
  params: layoutParams,
3176
- initialPositions: preservedPositionsRef.current
3449
+ initialPositions: preservedPositionsRef.current,
3450
+ groups
3177
3451
  });
3178
3452
  return () => {
3179
3453
  const d = dataRef.current;
@@ -3198,7 +3472,56 @@ function NetworkGraph3DInner(props, ref) {
3198
3472
  disposeObject(edgeResult.mesh);
3199
3473
  graphObjRef.current = null;
3200
3474
  };
3201
- }, [mergedData, valRange, nodeValueAccessor, layoutProp]);
3475
+ }, [mergedData, valRange, nodeValueAccessor, layoutKey]);
3476
+ react.useEffect(() => {
3477
+ const d = dataRef.current;
3478
+ const gObj = graphObjRef.current;
3479
+ if (!visibleSet && !linkVisibility) {
3480
+ hiddenNodesRef.current = null;
3481
+ hiddenEdgesRef.current = null;
3482
+ } else {
3483
+ const nc = d.nodes.length;
3484
+ const hn = new Uint8Array(nc);
3485
+ if (visibleSet) {
3486
+ for (let i = 0; i < nc; i++) {
3487
+ if (!visibleSet.has(d.nodes[i].id)) hn[i] = 1;
3488
+ }
3489
+ }
3490
+ const ec = d.edgeNodeIndices.length;
3491
+ const he = new Uint8Array(ec);
3492
+ for (let i = 0; i < ec; i++) {
3493
+ const [si, ti] = d.edgeNodeIndices[i];
3494
+ if (hn[si] || hn[ti]) {
3495
+ he[i] = 1;
3496
+ } else if (linkVisibility) {
3497
+ const link = d.links[d.edgeLinkIndices[i]];
3498
+ if (link && !linkVisibility(link)) he[i] = 1;
3499
+ }
3500
+ }
3501
+ hiddenNodesRef.current = visibleSet ? hn : null;
3502
+ hiddenEdgesRef.current = he;
3503
+ }
3504
+ if (gObj && d.positions && d.scales) {
3505
+ updateNodePositions(
3506
+ gObj.nodesMesh,
3507
+ d.positions,
3508
+ d.scales,
3509
+ d.nodes.length,
3510
+ hiddenNodesRef.current
3511
+ );
3512
+ updateEdgePositions(
3513
+ gObj.edgePositionArray,
3514
+ d.positions,
3515
+ d.edgeNodeIndices,
3516
+ gObj.edgeGeometry,
3517
+ hiddenEdgesRef.current
3518
+ );
3519
+ }
3520
+ }, [visibleSet, linkVisibility, mergedData]);
3521
+ react.useEffect(() => {
3522
+ const s = sceneRef.current;
3523
+ if (s) applyCameraMode2D(s, is2D);
3524
+ }, [is2D]);
3202
3525
  react.useEffect(() => {
3203
3526
  const gObj = graphObjRef.current;
3204
3527
  const sceneState = sceneRef.current;
@@ -3266,7 +3589,7 @@ function NetworkGraph3DInner(props, ref) {
3266
3589
  resolvedStyle.nodeMaxSize
3267
3590
  );
3268
3591
  dataRef.current.scales = newScales;
3269
- updateNodePositions(gObj.nodesMesh, positions, newScales, nc);
3592
+ updateNodePositions(gObj.nodesMesh, positions, newScales, nc, hiddenNodesRef.current);
3270
3593
  }, [resolvedStyle.nodeMinSize, resolvedStyle.nodeMaxSize, valRange]);
3271
3594
  react.useEffect(() => {
3272
3595
  const gObj = graphObjRef.current;
@@ -3355,6 +3678,17 @@ function NetworkGraph3DInner(props, ref) {
3355
3678
  const nx = d.positions[idx * 3];
3356
3679
  const ny = d.positions[idx * 3 + 1];
3357
3680
  const nz = d.positions[idx * 3 + 2];
3681
+ if (is2DRef.current) {
3682
+ const z2 = Math.max(120, Math.min(Math.abs(s.camera.position.z), 500));
3683
+ animateCamera(
3684
+ s.camera,
3685
+ s.controls,
3686
+ { x: nx, y: ny, z: z2 },
3687
+ { x: nx, y: ny, z: 0 },
3688
+ duration
3689
+ );
3690
+ return;
3691
+ }
3358
3692
  const dist = Math.hypot(nx, ny, nz);
3359
3693
  if (dist < 1) return;
3360
3694
  const ratio = 1 + 120 / dist;
@@ -3366,6 +3700,34 @@ function NetworkGraph3DInner(props, ref) {
3366
3700
  duration
3367
3701
  );
3368
3702
  },
3703
+ panTo(x2, y2, duration = 600) {
3704
+ const s = sceneRef.current;
3705
+ if (!s) return;
3706
+ const t = s.controls.target;
3707
+ if (is2DRef.current) {
3708
+ animateCamera(
3709
+ s.camera,
3710
+ s.controls,
3711
+ { x: x2, y: y2, z: s.camera.position.z },
3712
+ { x: x2, y: y2, z: 0 },
3713
+ duration
3714
+ );
3715
+ } else {
3716
+ const dx = x2 - t.x;
3717
+ const dy = y2 - t.y;
3718
+ animateCamera(
3719
+ s.camera,
3720
+ s.controls,
3721
+ {
3722
+ x: s.camera.position.x + dx,
3723
+ y: s.camera.position.y + dy,
3724
+ z: s.camera.position.z
3725
+ },
3726
+ { x: x2, y: y2, z: t.z },
3727
+ duration
3728
+ );
3729
+ }
3730
+ },
3369
3731
  appendData(newNodes, newLinks) {
3370
3732
  if (newNodes.length === 0 && newLinks.length === 0) return 0;
3371
3733
  const existingIds = new Set(dataRef.current.nodes.map((n) => n.id));
@@ -3394,6 +3756,32 @@ function NetworkGraph3DInner(props, ref) {
3394
3756
  s.renderer.render(s.scene, s.camera);
3395
3757
  return s.renderer.domElement.toDataURL("image/png");
3396
3758
  },
3759
+ getGraphSnapshot() {
3760
+ var _a;
3761
+ const gObj = graphObjRef.current;
3762
+ const d = dataRef.current;
3763
+ if (!gObj || !d.positions) return null;
3764
+ return {
3765
+ positions: d.positions,
3766
+ count: d.nodes.length,
3767
+ colors: ((_a = gObj.nodesMesh.instanceColor) == null ? void 0 : _a.array) ?? null,
3768
+ hidden: hiddenNodesRef.current,
3769
+ selectedIndex: selectedNodeIdRef.current ? d.nodeIdToIndex.get(selectedNodeIdRef.current) ?? -1 : -1
3770
+ };
3771
+ },
3772
+ getViewportRect() {
3773
+ const s = sceneRef.current;
3774
+ if (!s) return null;
3775
+ const cam = s.camera;
3776
+ const dist = Math.abs(cam.position.z);
3777
+ const halfH = Math.tan(cam.fov * Math.PI / 360) * dist;
3778
+ return {
3779
+ cx: cam.position.x,
3780
+ cy: cam.position.y,
3781
+ halfW: halfH * cam.aspect,
3782
+ halfH
3783
+ };
3784
+ },
3397
3785
  reheatLayout() {
3398
3786
  const gObj = graphObjRef.current;
3399
3787
  if (gObj == null ? void 0 : gObj.worker) {
@@ -3415,6 +3803,150 @@ function NetworkGraph3DInner(props, ref) {
3415
3803
  );
3416
3804
  }
3417
3805
  const NetworkGraph3D = react.forwardRef(NetworkGraph3DInner);
3806
+ function GraphMinimap({
3807
+ graphRef,
3808
+ width = 200,
3809
+ height = 140,
3810
+ backgroundColor,
3811
+ viewportColor = "#94a3b8",
3812
+ dotRadius = 1.5,
3813
+ fps = 15,
3814
+ padding = 0.08,
3815
+ className,
3816
+ style
3817
+ }) {
3818
+ const canvasRef = react.useRef(null);
3819
+ const fitRef = react.useRef(null);
3820
+ const draggingRef = react.useRef(false);
3821
+ react.useEffect(() => {
3822
+ const canvas = canvasRef.current;
3823
+ if (!canvas) return;
3824
+ const ctx = canvas.getContext("2d");
3825
+ if (!ctx) return;
3826
+ const dpr = Math.min(window.devicePixelRatio || 1, 2);
3827
+ canvas.width = width * dpr;
3828
+ canvas.height = height * dpr;
3829
+ let raf = 0;
3830
+ let last = 0;
3831
+ const interval2 = 1e3 / fps;
3832
+ const draw = (now2) => {
3833
+ var _a, _b;
3834
+ raf = requestAnimationFrame(draw);
3835
+ if (now2 - last < interval2) return;
3836
+ last = now2;
3837
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
3838
+ ctx.clearRect(0, 0, width, height);
3839
+ if (backgroundColor) {
3840
+ ctx.fillStyle = backgroundColor;
3841
+ ctx.fillRect(0, 0, width, height);
3842
+ }
3843
+ const snap = (_a = graphRef.current) == null ? void 0 : _a.getGraphSnapshot();
3844
+ if (!snap || snap.count === 0) {
3845
+ fitRef.current = null;
3846
+ return;
3847
+ }
3848
+ const { positions, count, colors, hidden, selectedIndex } = snap;
3849
+ let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
3850
+ for (let i = 0; i < count; i++) {
3851
+ if (hidden && hidden[i]) continue;
3852
+ const x2 = positions[i * 3];
3853
+ const y2 = positions[i * 3 + 1];
3854
+ if (x2 < minX) minX = x2;
3855
+ if (x2 > maxX) maxX = x2;
3856
+ if (y2 < minY) minY = y2;
3857
+ if (y2 > maxY) maxY = y2;
3858
+ }
3859
+ if (!isFinite(minX)) {
3860
+ fitRef.current = null;
3861
+ return;
3862
+ }
3863
+ const spanX = Math.max(maxX - minX, 1);
3864
+ const spanY = Math.max(maxY - minY, 1);
3865
+ const pad = Math.min(width, height) * padding;
3866
+ const scale = Math.min(
3867
+ (width - pad * 2) / spanX,
3868
+ (height - pad * 2) / spanY
3869
+ );
3870
+ const offsetX = width / 2 - (minX + maxX) / 2 * scale;
3871
+ const offsetY = height / 2 + (minY + maxY) / 2 * scale;
3872
+ fitRef.current = { scale, offsetX, offsetY };
3873
+ const r = dotRadius;
3874
+ for (let i = 0; i < count; i++) {
3875
+ if (hidden && hidden[i]) continue;
3876
+ const cx = positions[i * 3] * scale + offsetX;
3877
+ const cy = -positions[i * 3 + 1] * scale + offsetY;
3878
+ if (colors) {
3879
+ const cr = Math.min(255, Math.round(colors[i * 3] * 255));
3880
+ const cg = Math.min(255, Math.round(colors[i * 3 + 1] * 255));
3881
+ const cb = Math.min(255, Math.round(colors[i * 3 + 2] * 255));
3882
+ ctx.fillStyle = `rgb(${cr},${cg},${cb})`;
3883
+ } else {
3884
+ ctx.fillStyle = viewportColor;
3885
+ }
3886
+ const rad = i === selectedIndex ? r * 2 : r;
3887
+ ctx.beginPath();
3888
+ ctx.arc(cx, cy, rad, 0, Math.PI * 2);
3889
+ ctx.fill();
3890
+ }
3891
+ const vp = (_b = graphRef.current) == null ? void 0 : _b.getViewportRect();
3892
+ if (vp) {
3893
+ const x2 = (vp.cx - vp.halfW) * scale + offsetX;
3894
+ const y2 = -(vp.cy + vp.halfH) * scale + offsetY;
3895
+ const w = vp.halfW * 2 * scale;
3896
+ const h = vp.halfH * 2 * scale;
3897
+ ctx.strokeStyle = viewportColor;
3898
+ ctx.lineWidth = 1;
3899
+ ctx.strokeRect(x2, y2, w, h);
3900
+ ctx.fillStyle = viewportColor + "1a";
3901
+ ctx.fillRect(x2, y2, w, h);
3902
+ }
3903
+ };
3904
+ raf = requestAnimationFrame(draw);
3905
+ return () => cancelAnimationFrame(raf);
3906
+ }, [graphRef, width, height, backgroundColor, viewportColor, dotRadius, fps, padding]);
3907
+ const panToPointer = (e) => {
3908
+ var _a;
3909
+ const fit = fitRef.current;
3910
+ const canvas = canvasRef.current;
3911
+ if (!fit || !canvas) return;
3912
+ const rect = canvas.getBoundingClientRect();
3913
+ const px = e.clientX - rect.left;
3914
+ const py = e.clientY - rect.top;
3915
+ const wx = (px - fit.offsetX) / fit.scale;
3916
+ const wy = -(py - fit.offsetY) / fit.scale;
3917
+ (_a = graphRef.current) == null ? void 0 : _a.panTo(wx, wy, draggingRef.current ? 0 : 300);
3918
+ };
3919
+ return /* @__PURE__ */ jsxRuntime.jsx(
3920
+ "canvas",
3921
+ {
3922
+ ref: canvasRef,
3923
+ className,
3924
+ style: {
3925
+ width,
3926
+ height,
3927
+ cursor: "pointer",
3928
+ touchAction: "none",
3929
+ display: "block",
3930
+ ...style
3931
+ },
3932
+ onPointerDown: (e) => {
3933
+ draggingRef.current = true;
3934
+ e.currentTarget.setPointerCapture(e.pointerId);
3935
+ panToPointer(e);
3936
+ },
3937
+ onPointerMove: (e) => {
3938
+ if (draggingRef.current) panToPointer(e);
3939
+ },
3940
+ onPointerUp: (e) => {
3941
+ draggingRef.current = false;
3942
+ e.currentTarget.releasePointerCapture(e.pointerId);
3943
+ },
3944
+ onPointerCancel: () => {
3945
+ draggingRef.current = false;
3946
+ }
3947
+ }
3948
+ );
3949
+ }
3418
3950
  function forceCenter(x2, y2, z2) {
3419
3951
  var nodes, strength = 1;
3420
3952
  if (x2 == null) x2 = 0;
@@ -5482,6 +6014,7 @@ function CtrlBtn({ children, title, onClick }) {
5482
6014
  }
5483
6015
  exports.DEFAULT_LAYOUT = DEFAULT_LAYOUT;
5484
6016
  exports.DEFAULT_STYLE = DEFAULT_STYLE;
6017
+ exports.GraphMinimap = GraphMinimap;
5485
6018
  exports.NetworkGraph3D = NetworkGraph3D;
5486
6019
  exports.NodeDetailPanel = NodeDetailPanel;
5487
6020
  exports.SubgraphView2D = SubgraphView2D;
@@ -5492,6 +6025,7 @@ exports.celestial = celestial;
5492
6025
  exports.computeHighlightSet = computeHighlightSet;
5493
6026
  exports.minimal = minimal;
5494
6027
  exports.neon = neon;
6028
+ exports.paper = paper;
5495
6029
  exports.resolveTheme = resolveTheme;
5496
6030
  exports.zoomToFitPositions = zoomToFitPositions;
5497
6031
  //# sourceMappingURL=index.cjs.map