@cocorof/graphier 1.3.3 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -26,7 +26,10 @@ const DEFAULT_LAYOUT = {
26
26
  alphaDecay: "auto",
27
27
  velocityDecay: 0.4,
28
28
  settledThreshold: 5e-3,
29
- spreadFactor: "auto"
29
+ spreadFactor: "auto",
30
+ dimensions: 3,
31
+ clusterBy: null,
32
+ clusterStrength: 0.05
30
33
  };
31
34
  function hexToRgb(hex) {
32
35
  const c2 = hex.replace("#", "");
@@ -38,6 +41,14 @@ function rgbToHex(r, g, b) {
38
41
  const hex = clamp(r) << 16 | clamp(g) << 8 | clamp(b);
39
42
  return "#" + hex.toString(16).padStart(6, "0");
40
43
  }
44
+ function luminance(hex) {
45
+ const [r, g, b] = hexToRgb(hex);
46
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
47
+ }
48
+ function darken(hex, factor) {
49
+ const [r, g, b] = hexToRgb(hex);
50
+ return rgbToHex(r * factor, g * factor, b * factor);
51
+ }
41
52
  function brighten(hex, factor) {
42
53
  const [r, g, b] = hexToRgb(hex);
43
54
  const t = 1 - 1 / factor;
@@ -119,10 +130,40 @@ const minimal = {
119
130
  defaultLinkColor: "#444444",
120
131
  backgroundColor: "#1a1a2e"
121
132
  };
133
+ const paper = {
134
+ nodeColors: {},
135
+ // Bright (label / highlight) colors are auto-derived: on a light
136
+ // background resolveTheme darkens instead of whitening.
137
+ nodeColorsBright: {},
138
+ linkColors: {},
139
+ defaultNodeColor: "#64748b",
140
+ defaultLinkColor: "#b3bdcc",
141
+ backgroundColor: "#f6f7f9",
142
+ blending: "normal",
143
+ palette: [
144
+ "#2563eb",
145
+ // blue
146
+ "#d97706",
147
+ // amber
148
+ "#7c3aed",
149
+ // violet
150
+ "#db2777",
151
+ // pink
152
+ "#0891b2",
153
+ // cyan
154
+ "#16a34a",
155
+ // green
156
+ "#dc2626",
157
+ // red
158
+ "#475569"
159
+ // slate
160
+ ]
161
+ };
122
162
  const PRESETS = {
123
163
  celestial,
124
164
  neon,
125
- minimal
165
+ minimal,
166
+ paper
126
167
  };
127
168
  const DEFAULT_THEME = {
128
169
  nodeColors: celestial.nodeColors ?? {},
@@ -150,6 +191,8 @@ function resolveTheme(theme) {
150
191
  const defaultLinkColor = config.defaultLinkColor ?? DEFAULT_THEME.defaultLinkColor;
151
192
  const backgroundColor = config.backgroundColor ?? DEFAULT_THEME.backgroundColor;
152
193
  const palette = config.palette ?? DEFAULT_THEME.palette;
194
+ const isLight = luminance(backgroundColor) > 0.5;
195
+ const additiveEdges = config.blending ? config.blending === "additive" : !isLight;
153
196
  const autoAssigned = /* @__PURE__ */ new Map();
154
197
  let nextPaletteIdx = 0;
155
198
  function nodeColor(type) {
@@ -161,16 +204,24 @@ function resolveTheme(theme) {
161
204
  }
162
205
  return palette[autoAssigned.get(type)];
163
206
  }
207
+ const emphasize = (c2) => isLight ? darken(c2, 0.72) : brighten(c2, 1.5);
164
208
  function nodeColorBright(type) {
165
- if (!type) return brighten(defaultNodeColor, 1.5);
209
+ if (!type) return emphasize(defaultNodeColor);
166
210
  if (nodeColorsBright[type]) return nodeColorsBright[type];
167
- return brighten(nodeColor(type), 1.5);
211
+ return emphasize(nodeColor(type));
168
212
  }
169
213
  function linkColor(type) {
170
214
  if (!type) return defaultLinkColor;
171
215
  return linkColors[type] ?? defaultLinkColor;
172
216
  }
173
- return { nodeColor, nodeColorBright, linkColor, backgroundColor };
217
+ return {
218
+ nodeColor,
219
+ nodeColorBright,
220
+ linkColor,
221
+ backgroundColor,
222
+ isLight,
223
+ additiveEdges
224
+ };
174
225
  }
175
226
  function autoSpreadFactor(n) {
176
227
  if (n <= 500) return 1;
@@ -193,6 +244,8 @@ function resolveLayoutParams(nodeCount, config) {
193
244
  const postEvery = n > 5e4 ? 5 : n > 1e4 ? 3 : 2;
194
245
  const initialRadius2 = (500 + Math.min(n, 1e4) * 0.1) * spread;
195
246
  return {
247
+ dimensions: (config == null ? void 0 : config.dimensions) === 2 ? 2 : 3,
248
+ clusterStrength: (config == null ? void 0 : config.clusterStrength) ?? 0.05,
196
249
  charge,
197
250
  distanceMax,
198
251
  theta,
@@ -204,7 +257,7 @@ function resolveLayoutParams(nodeCount, config) {
204
257
  initialRadius: initialRadius2
205
258
  };
206
259
  }
207
- 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';
260
+ 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';
208
261
  function createLayoutWorker() {
209
262
  const blob = new Blob([WORKER_SOURCE], { type: "application/javascript" });
210
263
  const url = URL.createObjectURL(blob);
@@ -1705,6 +1758,7 @@ function applyNodeHighlight(nodesMesh, nodes, selectedNodeId, highlightSet, them
1705
1758
  const nc = nodes.length;
1706
1759
  const tmpColor = new THREE.Color();
1707
1760
  const brightTmp = new THREE.Color();
1761
+ const bgColor = new THREE.Color(theme.backgroundColor);
1708
1762
  for (let i = 0; i < nc; i++) {
1709
1763
  const node = nodes[i];
1710
1764
  const baseColor = theme.nodeColor(node.type);
@@ -1712,13 +1766,17 @@ function applyNodeHighlight(nodesMesh, nodes, selectedNodeId, highlightSet, them
1712
1766
  if (!highlightSet) {
1713
1767
  tmpColor.set(baseColor);
1714
1768
  } else if (node.id === selectedNodeId) {
1715
- tmpColor.set(brightColor);
1716
- brightTmp.setRGB(1, 1, 1);
1717
- tmpColor.lerp(brightTmp, 0.65);
1718
- tmpColor.multiplyScalar(1.4);
1719
- tmpColor.r = Math.min(tmpColor.r, 2);
1720
- tmpColor.g = Math.min(tmpColor.g, 2);
1721
- tmpColor.b = Math.min(tmpColor.b, 2);
1769
+ if (theme.isLight) {
1770
+ tmpColor.set(brightColor);
1771
+ } else {
1772
+ tmpColor.set(brightColor);
1773
+ brightTmp.setRGB(1, 1, 1);
1774
+ tmpColor.lerp(brightTmp, 0.65);
1775
+ tmpColor.multiplyScalar(1.4);
1776
+ tmpColor.r = Math.min(tmpColor.r, 2);
1777
+ tmpColor.g = Math.min(tmpColor.g, 2);
1778
+ tmpColor.b = Math.min(tmpColor.b, 2);
1779
+ }
1722
1780
  } else if (highlightSet.has(node.id)) {
1723
1781
  const hop = highlightSet.get(node.id);
1724
1782
  if (hop === 1) {
@@ -1730,6 +1788,8 @@ function applyNodeHighlight(nodesMesh, nodes, selectedNodeId, highlightSet, them
1730
1788
  } else {
1731
1789
  tmpColor.set(baseColor).multiplyScalar(0.6);
1732
1790
  }
1791
+ } else if (theme.isLight) {
1792
+ tmpColor.set(baseColor).lerp(bgColor, 0.88);
1733
1793
  } else {
1734
1794
  tmpColor.set(baseColor).multiplyScalar(0.04);
1735
1795
  }
@@ -1747,6 +1807,7 @@ function applyEdgeHighlight(edgesMesh, links, edgeNodeIndices, edgeLinkIndices,
1747
1807
  const colorArr = colorAttr.array;
1748
1808
  const validCount = edgeNodeIndices.length;
1749
1809
  const tmpColor = new THREE.Color();
1810
+ const bgColor = new THREE.Color(theme.backgroundColor);
1750
1811
  for (let i = 0; i < validCount; i++) {
1751
1812
  const origIdx = edgeLinkIndices[i];
1752
1813
  const link = links[origIdx];
@@ -1758,13 +1819,19 @@ function applyEdgeHighlight(edgesMesh, links, edgeNodeIndices, edgeLinkIndices,
1758
1819
  const maxHopVal = Math.max(highlightSet.get(sId), highlightSet.get(tId));
1759
1820
  tmpColor.set(theme.linkColor(link == null ? void 0 : link.type));
1760
1821
  if (maxHopVal <= 1) {
1761
- tmpColor.multiplyScalar(1.8);
1762
- tmpColor.r = Math.min(tmpColor.r, 1);
1763
- tmpColor.g = Math.min(tmpColor.g, 1);
1764
- tmpColor.b = Math.min(tmpColor.b, 1);
1822
+ if (theme.isLight) {
1823
+ tmpColor.multiplyScalar(0.55);
1824
+ } else {
1825
+ tmpColor.multiplyScalar(1.8);
1826
+ tmpColor.r = Math.min(tmpColor.r, 1);
1827
+ tmpColor.g = Math.min(tmpColor.g, 1);
1828
+ tmpColor.b = Math.min(tmpColor.b, 1);
1829
+ }
1765
1830
  } else if (maxHopVal === 2) {
1766
- tmpColor.multiplyScalar(1.2);
1831
+ tmpColor.multiplyScalar(theme.isLight ? 0.8 : 1.2);
1767
1832
  }
1833
+ } else if (theme.isLight) {
1834
+ tmpColor.set(theme.linkColor(link == null ? void 0 : link.type)).lerp(bgColor, 0.85);
1768
1835
  } else {
1769
1836
  tmpColor.setRGB(0.01, 0.01, 0.02);
1770
1837
  }
@@ -1894,7 +1961,7 @@ function getOrCreateTexture(cache, nodeId, text, color) {
1894
1961
  }
1895
1962
  return entry;
1896
1963
  }
1897
- function updateLabels(state, nodes, positions, scales, camera, theme, showLabels, labelScale, labelThreshold, maxLabels, labelFormatter, highlightSet) {
1964
+ function updateLabels(state, nodes, positions, scales, camera, theme, showLabels, labelScale, labelThreshold, maxLabels, labelFormatter, highlightSet, hidden) {
1898
1965
  if (!positions || nodes.length === 0 || !showLabels) {
1899
1966
  for (const sp of state.sprites) sp.visible = false;
1900
1967
  return;
@@ -1908,6 +1975,7 @@ function updateLabels(state, nodes, positions, scales, camera, theme, showLabels
1908
1975
  const maxDistSq = maxDist * maxDist;
1909
1976
  const candidates = [];
1910
1977
  for (let i = 0; i < nc; i++) {
1978
+ if (hidden && hidden[i]) continue;
1911
1979
  if (highlightSet && !highlightSet.has(nodes[i].id)) continue;
1912
1980
  const dx = positions[i * 3] - camPos.x;
1913
1981
  const dy = positions[i * 3 + 1] - camPos.y;
@@ -2061,7 +2129,9 @@ function setupKeyboardControls(camera, controls, container, mode = "fly", flySpe
2061
2129
  container.addEventListener("keydown", onKeyDown2);
2062
2130
  container.addEventListener("keyup", onKeyUp);
2063
2131
  container.addEventListener("blur", onBlur);
2064
- const updateFn = mode === "fly" ? createFlyUpdate(camera, controls, keys, state) : createOrbitUpdate(camera, controls, keys);
2132
+ let enabled = true;
2133
+ const innerUpdate = mode === "fly" ? createFlyUpdate(camera, controls, keys, state) : createOrbitUpdate(camera, controls, keys);
2134
+ const updateFn = () => enabled ? innerUpdate() : false;
2065
2135
  function cleanup() {
2066
2136
  container.removeEventListener("keydown", onKeyDown2);
2067
2137
  container.removeEventListener("keyup", onKeyUp);
@@ -2070,7 +2140,11 @@ function setupKeyboardControls(camera, controls, container, mode = "fly", flySpe
2070
2140
  function setFlySpeed(speed) {
2071
2141
  state.flySpeed = speed;
2072
2142
  }
2073
- return { update: updateFn, cleanup, setFlySpeed };
2143
+ function setEnabled(on) {
2144
+ enabled = on;
2145
+ if (!on) for (const k of Object.keys(keys)) keys[k] = false;
2146
+ }
2147
+ return { update: updateFn, cleanup, setFlySpeed, setEnabled };
2074
2148
  }
2075
2149
  function createScene(container, backgroundColor, style, rendererConfig) {
2076
2150
  const scene = new THREE.Scene();
@@ -2110,8 +2184,10 @@ function createScene(container, backgroundColor, style, rendererConfig) {
2110
2184
  const cameraMode = (rendererConfig == null ? void 0 : rendererConfig.cameraMode) ?? "fly";
2111
2185
  const keyboard = setupKeyboardControls(camera, controls, container, cameraMode, style.flySpeed ?? 1);
2112
2186
  controls.enableZoom = false;
2187
+ const flags = { is2D: false };
2113
2188
  const _wheelDir = new THREE.Vector3();
2114
2189
  const onWheel = (e) => {
2190
+ if (flags.is2D) return;
2115
2191
  e.preventDefault();
2116
2192
  let delta = -e.deltaY;
2117
2193
  if (e.deltaMode === 1) delta *= 40;
@@ -2135,9 +2211,40 @@ function createScene(container, backgroundColor, style, rendererConfig) {
2135
2211
  composer: null,
2136
2212
  bloomPass: null,
2137
2213
  keyboard,
2138
- scrollCleanup
2214
+ scrollCleanup,
2215
+ flags
2139
2216
  };
2140
2217
  }
2218
+ function applyCameraMode2D(state, is2D) {
2219
+ const { controls, camera, keyboard } = state;
2220
+ state.flags.is2D = is2D;
2221
+ controls.enableRotate = !is2D;
2222
+ controls.enableZoom = is2D;
2223
+ controls.screenSpacePanning = is2D;
2224
+ keyboard.setEnabled(!is2D);
2225
+ if (is2D) {
2226
+ controls.mouseButtons = {
2227
+ LEFT: THREE.MOUSE.PAN,
2228
+ MIDDLE: THREE.MOUSE.DOLLY,
2229
+ RIGHT: THREE.MOUSE.PAN
2230
+ };
2231
+ controls.touches = { ONE: THREE.TOUCH.PAN, TWO: THREE.TOUCH.DOLLY_PAN };
2232
+ const t = controls.target;
2233
+ const dist = Math.max(camera.position.distanceTo(t), 50);
2234
+ t.z = 0;
2235
+ camera.up.set(0, 1, 0);
2236
+ camera.position.set(t.x, t.y, dist);
2237
+ camera.lookAt(t);
2238
+ } else {
2239
+ controls.mouseButtons = {
2240
+ LEFT: THREE.MOUSE.ROTATE,
2241
+ MIDDLE: THREE.MOUSE.DOLLY,
2242
+ RIGHT: THREE.MOUSE.PAN
2243
+ };
2244
+ controls.touches = { ONE: THREE.TOUCH.ROTATE, TWO: THREE.TOUCH.DOLLY_PAN };
2245
+ }
2246
+ controls.update();
2247
+ }
2141
2248
  function initBloom(state, nodeCount, style) {
2142
2249
  if (state.composer) return;
2143
2250
  try {
@@ -2334,14 +2441,14 @@ function createNodeMesh(nodes, scales, theme) {
2334
2441
  mesh.computeBoundingSphere();
2335
2442
  return { mesh, material, scales };
2336
2443
  }
2337
- function updateNodePositions(mesh, positions, scales, nodeCount) {
2444
+ function updateNodePositions(mesh, positions, scales, nodeCount, hidden) {
2338
2445
  const pos = new THREE.Vector3();
2339
2446
  const scale = new THREE.Vector3();
2340
2447
  const quat = new THREE.Quaternion();
2341
2448
  const mat = new THREE.Matrix4();
2342
2449
  for (let i = 0; i < nodeCount; i++) {
2343
2450
  pos.set(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]);
2344
- const sc = scales[i];
2451
+ const sc = hidden && hidden[i] ? 1e-4 : scales[i];
2345
2452
  scale.set(sc, sc, sc);
2346
2453
  mat.compose(pos, quat, scale);
2347
2454
  mesh.setMatrixAt(i, mat);
@@ -2398,7 +2505,7 @@ function createEdgeMesh(links, edgeNodeIndices, edgeLinkIndices, nodeCount, edge
2398
2505
  transparent: true,
2399
2506
  opacity: adaptiveOpacity,
2400
2507
  depthWrite: false,
2401
- blending: THREE.AdditiveBlending
2508
+ blending: theme.additiveEdges ? THREE.AdditiveBlending : THREE.NormalBlending
2402
2509
  });
2403
2510
  const mesh = new THREE.LineSegments(geometry, material);
2404
2511
  return {
@@ -2410,10 +2517,19 @@ function createEdgeMesh(links, edgeNodeIndices, edgeLinkIndices, nodeCount, edge
2410
2517
  edgeLinkIndices
2411
2518
  };
2412
2519
  }
2413
- function updateEdgePositions(positionArray, nodePositions, edgeNodeIndices, geometry) {
2520
+ function updateEdgePositions(positionArray, nodePositions, edgeNodeIndices, geometry, hiddenEdges) {
2414
2521
  const count = edgeNodeIndices.length;
2415
2522
  for (let i = 0; i < count; i++) {
2416
2523
  const [si, ti] = edgeNodeIndices[i];
2524
+ if (hiddenEdges && hiddenEdges[i]) {
2525
+ positionArray[i * 6 + 0] = nodePositions[si * 3];
2526
+ positionArray[i * 6 + 1] = nodePositions[si * 3 + 1];
2527
+ positionArray[i * 6 + 2] = nodePositions[si * 3 + 2];
2528
+ positionArray[i * 6 + 3] = nodePositions[si * 3];
2529
+ positionArray[i * 6 + 4] = nodePositions[si * 3 + 1];
2530
+ positionArray[i * 6 + 5] = nodePositions[si * 3 + 2];
2531
+ continue;
2532
+ }
2417
2533
  positionArray[i * 6 + 0] = nodePositions[si * 3];
2418
2534
  positionArray[i * 6 + 1] = nodePositions[si * 3 + 1];
2419
2535
  positionArray[i * 6 + 2] = nodePositions[si * 3 + 2];
@@ -2476,7 +2592,7 @@ function zoomToFitPositions(camera, controls, positions, duration, padding) {
2476
2592
  );
2477
2593
  }
2478
2594
  const EDGE_HIT_THRESHOLD = 5;
2479
- function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, callbacks, container, getEdgeData) {
2595
+ function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, callbacks, container, getEdgeData, options) {
2480
2596
  const raycaster = new THREE.Raycaster();
2481
2597
  const mouse = new THREE.Vector2();
2482
2598
  let mouseDownPos = null;
@@ -2634,20 +2750,34 @@ function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, call
2634
2750
  lastClickTime = now2;
2635
2751
  lastClickNodeId = node.id;
2636
2752
  singleClickTimer = setTimeout(() => {
2753
+ var _a2, _b;
2637
2754
  singleClickTimer = null;
2638
- const nx = node.x ?? 0;
2639
- const ny = node.y ?? 0;
2640
- const nz = node.z ?? 0;
2641
- const dist = Math.hypot(nx, ny, nz);
2642
- if (dist > 1) {
2643
- const ratio = 1 + 120 / dist;
2644
- animateCamera(
2645
- camera,
2646
- controls,
2647
- { x: nx * ratio, y: ny * ratio, z: nz * ratio },
2648
- { x: nx, y: ny, z: nz },
2649
- 1200
2650
- );
2755
+ const clickToFocus = ((_a2 = options == null ? void 0 : options.getClickToFocus) == null ? void 0 : _a2.call(options)) ?? true;
2756
+ if (clickToFocus) {
2757
+ const nx = node.x ?? 0;
2758
+ const ny = node.y ?? 0;
2759
+ const nz = node.z ?? 0;
2760
+ if ((_b = options == null ? void 0 : options.getIs2D) == null ? void 0 : _b.call(options)) {
2761
+ animateCamera(
2762
+ camera,
2763
+ controls,
2764
+ { x: nx, y: ny, z: camera.position.z },
2765
+ { x: nx, y: ny, z: 0 },
2766
+ 800
2767
+ );
2768
+ } else {
2769
+ const dist = Math.hypot(nx, ny, nz);
2770
+ if (dist > 1) {
2771
+ const ratio = 1 + 120 / dist;
2772
+ animateCamera(
2773
+ camera,
2774
+ controls,
2775
+ { x: nx * ratio, y: ny * ratio, z: nz * ratio },
2776
+ { x: nx, y: ny, z: nz },
2777
+ 1200
2778
+ );
2779
+ }
2780
+ }
2651
2781
  }
2652
2782
  callbacks.onNodeClick(node);
2653
2783
  }, 250);
@@ -2787,7 +2917,12 @@ function NetworkGraph3DInner(props, ref) {
2787
2917
  layout: layoutProp,
2788
2918
  renderer: rendererProp,
2789
2919
  labelFormatter,
2790
- nodeValueAccessor
2920
+ nodeValueAccessor,
2921
+ visibleNodeIds,
2922
+ linkVisibility,
2923
+ clickToFocus = true,
2924
+ hoverHighlight = false,
2925
+ hoverHighlightHops = 1
2791
2926
  } = props;
2792
2927
  const containerRef = useRef(null);
2793
2928
  const resolvedStyle = useMemo(
@@ -2824,6 +2959,13 @@ function NetworkGraph3DInner(props, ref) {
2824
2959
  const selectedNodeIdRef = useRef(selectedNodeId);
2825
2960
  const labelFormatterRef = useRef(labelFormatter);
2826
2961
  const highlightSetRef = useRef(null);
2962
+ const clickToFocusRef = useRef(clickToFocus);
2963
+ const hoverHighlightRef = useRef(hoverHighlight);
2964
+ const hoverHighlightHopsRef = useRef(hoverHighlightHops);
2965
+ const adjacencyMapRef = useRef(/* @__PURE__ */ new Map());
2966
+ const is2DRef = useRef(false);
2967
+ const hiddenNodesRef = useRef(null);
2968
+ const hiddenEdgesRef = useRef(null);
2827
2969
  onNodeClickRef.current = onNodeClick;
2828
2970
  onNodeDoubleClickRef.current = onNodeDoubleClick;
2829
2971
  onNodeHoverRef.current = onNodeHover;
@@ -2838,6 +2980,14 @@ function NetworkGraph3DInner(props, ref) {
2838
2980
  themeRef.current = resolvedTheme;
2839
2981
  selectedNodeIdRef.current = selectedNodeId;
2840
2982
  labelFormatterRef.current = labelFormatter;
2983
+ clickToFocusRef.current = clickToFocus;
2984
+ hoverHighlightRef.current = hoverHighlight;
2985
+ hoverHighlightHopsRef.current = hoverHighlightHops;
2986
+ const is2D = (layoutProp == null ? void 0 : layoutProp.dimensions) === 2;
2987
+ is2DRef.current = is2D;
2988
+ const layoutKey = JSON.stringify(layoutProp ?? null);
2989
+ const layoutRef = useRef(layoutProp);
2990
+ layoutRef.current = layoutProp;
2841
2991
  const mergedData = useMemo(() => {
2842
2992
  if (!appendedData) return data;
2843
2993
  const existingIds = new Set(data.nodes.map((n) => n.id));
@@ -2864,6 +3014,11 @@ function NetworkGraph3DInner(props, ref) {
2864
3014
  () => buildAdjacencyMapFromLinks(mergedData.links),
2865
3015
  [mergedData.links]
2866
3016
  );
3017
+ adjacencyMapRef.current = adjacencyMap;
3018
+ const visibleSet = useMemo(() => {
3019
+ if (visibleNodeIds == null) return null;
3020
+ return visibleNodeIds instanceof Set ? visibleNodeIds : new Set(visibleNodeIds);
3021
+ }, [visibleNodeIds]);
2867
3022
  const highlightSet = useMemo(() => {
2868
3023
  if (!selectedNodeId) return null;
2869
3024
  return computeHighlightSet(selectedNodeId, adjacencyMap, highlightHops);
@@ -2877,6 +3032,32 @@ function NetworkGraph3DInner(props, ref) {
2877
3032
  }
2878
3033
  return { min: isFinite(min) ? min : 1, max: isFinite(max) ? max : 1 };
2879
3034
  }, [mergedData.nodes, nodeValueAccessor]);
3035
+ const applyHoverHighlight = (node) => {
3036
+ if (!hoverHighlightRef.current) return;
3037
+ if (selectedNodeIdRef.current) return;
3038
+ const gObj = graphObjRef.current;
3039
+ if (!gObj) return;
3040
+ const d = dataRef.current;
3041
+ const set2 = node ? computeHighlightSet(
3042
+ node.id,
3043
+ adjacencyMapRef.current,
3044
+ hoverHighlightHopsRef.current
3045
+ ) : null;
3046
+ highlightSetRef.current = set2;
3047
+ applyNodeHighlight(gObj.nodesMesh, d.nodes, (node == null ? void 0 : node.id) ?? null, set2, themeRef.current);
3048
+ applyEdgeHighlight(
3049
+ gObj.edgesMesh,
3050
+ d.links,
3051
+ d.edgeNodeIndices,
3052
+ d.edgeLinkIndices,
3053
+ set2,
3054
+ styleRef.current.edgeOpacity,
3055
+ d.nodes.length,
3056
+ themeRef.current
3057
+ );
3058
+ };
3059
+ const applyHoverHighlightRef = useRef(applyHoverHighlight);
3060
+ applyHoverHighlightRef.current = applyHoverHighlight;
2880
3061
  useEffect(() => {
2881
3062
  const container = containerRef.current;
2882
3063
  if (!container) return;
@@ -2900,7 +3081,8 @@ function NetworkGraph3DInner(props, ref) {
2900
3081
  styleRef.current.labelThreshold,
2901
3082
  styleRef.current.maxLabels,
2902
3083
  labelFormatterRef.current,
2903
- highlightSetRef.current
3084
+ highlightSetRef.current,
3085
+ hiddenNodesRef.current
2904
3086
  );
2905
3087
  });
2906
3088
  const resizeObserver = setupResize(container, state);
@@ -2924,7 +3106,8 @@ function NetworkGraph3DInner(props, ref) {
2924
3106
  },
2925
3107
  onNodeHover: (node) => {
2926
3108
  var _a;
2927
- return (_a = onNodeHoverRef.current) == null ? void 0 : _a.call(onNodeHoverRef, node);
3109
+ (_a = onNodeHoverRef.current) == null ? void 0 : _a.call(onNodeHoverRef, node);
3110
+ applyHoverHighlightRef.current(node);
2928
3111
  },
2929
3112
  onContextMenu: (node, pos) => {
2930
3113
  var _a;
@@ -2940,6 +3123,7 @@ function NetworkGraph3DInner(props, ref) {
2940
3123
  },
2941
3124
  onNodeDrag: (node, pos) => {
2942
3125
  var _a;
3126
+ if (is2DRef.current) pos = { ...pos, z: 0 };
2943
3127
  (_a = onNodeDragRef.current) == null ? void 0 : _a.call(onNodeDragRef, node, pos);
2944
3128
  const d = dataRef.current;
2945
3129
  const idx = d.nodeIdToIndex.get(node.id);
@@ -2952,7 +3136,13 @@ function NetworkGraph3DInner(props, ref) {
2952
3136
  node.z = pos.z;
2953
3137
  const gObj = graphObjRef.current;
2954
3138
  if (gObj && d.scales) {
2955
- updateNodePositions(gObj.nodesMesh, d.positions, d.scales, d.nodes.length);
3139
+ updateNodePositions(
3140
+ gObj.nodesMesh,
3141
+ d.positions,
3142
+ d.scales,
3143
+ d.nodes.length,
3144
+ hiddenNodesRef.current
3145
+ );
2956
3146
  }
2957
3147
  }
2958
3148
  },
@@ -2970,6 +3160,10 @@ function NetworkGraph3DInner(props, ref) {
2970
3160
  edgeLinkIndices: d.edgeLinkIndices,
2971
3161
  positions: d.positions
2972
3162
  };
3163
+ },
3164
+ {
3165
+ getClickToFocus: () => clickToFocusRef.current,
3166
+ getIs2D: () => is2DRef.current
2973
3167
  }
2974
3168
  );
2975
3169
  return () => {
@@ -3116,17 +3310,26 @@ function NetworkGraph3DInner(props, ref) {
3116
3310
  if (msg.type === "positions") {
3117
3311
  const positions = new Float32Array(msg.positions);
3118
3312
  dataRef.current.positions = positions;
3119
- updateNodePositions(nodesMesh, positions, scales, nc);
3313
+ const hn = hiddenNodesRef.current;
3314
+ updateNodePositions(
3315
+ nodesMesh,
3316
+ positions,
3317
+ scales,
3318
+ nc,
3319
+ hn && hn.length === nc ? hn : null
3320
+ );
3120
3321
  for (let i = 0; i < nc; i++) {
3121
3322
  nodes[i].x = positions[i * 3];
3122
3323
  nodes[i].y = positions[i * 3 + 1];
3123
3324
  nodes[i].z = positions[i * 3 + 2];
3124
3325
  }
3326
+ const he = hiddenEdgesRef.current;
3125
3327
  updateEdgePositions(
3126
3328
  edgeResult.positionArray,
3127
3329
  positions,
3128
3330
  edgeNodeIndices,
3129
- edgeResult.geometry
3331
+ edgeResult.geometry,
3332
+ he && he.length === edgeNodeIndices.length ? he : null
3130
3333
  );
3131
3334
  const selId = selectedNodeIdRef.current;
3132
3335
  if (selId && sceneState.selectionRing.visible) {
@@ -3146,7 +3349,20 @@ function NetworkGraph3DInner(props, ref) {
3146
3349
  (_b = onLayoutSettledRef.current) == null ? void 0 : _b.call(onLayoutSettledRef);
3147
3350
  }
3148
3351
  };
3149
- const layoutParams = resolveLayoutParams(nc, layoutProp);
3352
+ const layoutConfig = layoutRef.current;
3353
+ const layoutParams = resolveLayoutParams(nc, layoutConfig);
3354
+ let groups;
3355
+ if (layoutConfig == null ? void 0 : layoutConfig.clusterBy) {
3356
+ const keyOf = (n) => layoutConfig.clusterBy === "type" ? n.type : n.group;
3357
+ const keyToIdx = /* @__PURE__ */ new Map();
3358
+ groups = nodes.map((n) => {
3359
+ const k = keyOf(n);
3360
+ if (k == null) return -1;
3361
+ const ks = String(k);
3362
+ if (!keyToIdx.has(ks)) keyToIdx.set(ks, keyToIdx.size);
3363
+ return keyToIdx.get(ks);
3364
+ });
3365
+ }
3150
3366
  worker.postMessage({
3151
3367
  type: "init",
3152
3368
  nodes: nodes.map((n) => ({ id: n.id })),
@@ -3155,7 +3371,8 @@ function NetworkGraph3DInner(props, ref) {
3155
3371
  target: typeof l.target === "object" ? l.target.id : l.target
3156
3372
  })),
3157
3373
  params: layoutParams,
3158
- initialPositions: preservedPositionsRef.current
3374
+ initialPositions: preservedPositionsRef.current,
3375
+ groups
3159
3376
  });
3160
3377
  return () => {
3161
3378
  const d = dataRef.current;
@@ -3180,7 +3397,56 @@ function NetworkGraph3DInner(props, ref) {
3180
3397
  disposeObject(edgeResult.mesh);
3181
3398
  graphObjRef.current = null;
3182
3399
  };
3183
- }, [mergedData, valRange, nodeValueAccessor, layoutProp]);
3400
+ }, [mergedData, valRange, nodeValueAccessor, layoutKey]);
3401
+ useEffect(() => {
3402
+ const d = dataRef.current;
3403
+ const gObj = graphObjRef.current;
3404
+ if (!visibleSet && !linkVisibility) {
3405
+ hiddenNodesRef.current = null;
3406
+ hiddenEdgesRef.current = null;
3407
+ } else {
3408
+ const nc = d.nodes.length;
3409
+ const hn = new Uint8Array(nc);
3410
+ if (visibleSet) {
3411
+ for (let i = 0; i < nc; i++) {
3412
+ if (!visibleSet.has(d.nodes[i].id)) hn[i] = 1;
3413
+ }
3414
+ }
3415
+ const ec = d.edgeNodeIndices.length;
3416
+ const he = new Uint8Array(ec);
3417
+ for (let i = 0; i < ec; i++) {
3418
+ const [si, ti] = d.edgeNodeIndices[i];
3419
+ if (hn[si] || hn[ti]) {
3420
+ he[i] = 1;
3421
+ } else if (linkVisibility) {
3422
+ const link = d.links[d.edgeLinkIndices[i]];
3423
+ if (link && !linkVisibility(link)) he[i] = 1;
3424
+ }
3425
+ }
3426
+ hiddenNodesRef.current = visibleSet ? hn : null;
3427
+ hiddenEdgesRef.current = he;
3428
+ }
3429
+ if (gObj && d.positions && d.scales) {
3430
+ updateNodePositions(
3431
+ gObj.nodesMesh,
3432
+ d.positions,
3433
+ d.scales,
3434
+ d.nodes.length,
3435
+ hiddenNodesRef.current
3436
+ );
3437
+ updateEdgePositions(
3438
+ gObj.edgePositionArray,
3439
+ d.positions,
3440
+ d.edgeNodeIndices,
3441
+ gObj.edgeGeometry,
3442
+ hiddenEdgesRef.current
3443
+ );
3444
+ }
3445
+ }, [visibleSet, linkVisibility, mergedData]);
3446
+ useEffect(() => {
3447
+ const s = sceneRef.current;
3448
+ if (s) applyCameraMode2D(s, is2D);
3449
+ }, [is2D]);
3184
3450
  useEffect(() => {
3185
3451
  const gObj = graphObjRef.current;
3186
3452
  const sceneState = sceneRef.current;
@@ -3248,7 +3514,7 @@ function NetworkGraph3DInner(props, ref) {
3248
3514
  resolvedStyle.nodeMaxSize
3249
3515
  );
3250
3516
  dataRef.current.scales = newScales;
3251
- updateNodePositions(gObj.nodesMesh, positions, newScales, nc);
3517
+ updateNodePositions(gObj.nodesMesh, positions, newScales, nc, hiddenNodesRef.current);
3252
3518
  }, [resolvedStyle.nodeMinSize, resolvedStyle.nodeMaxSize, valRange]);
3253
3519
  useEffect(() => {
3254
3520
  const gObj = graphObjRef.current;
@@ -3337,6 +3603,17 @@ function NetworkGraph3DInner(props, ref) {
3337
3603
  const nx = d.positions[idx * 3];
3338
3604
  const ny = d.positions[idx * 3 + 1];
3339
3605
  const nz = d.positions[idx * 3 + 2];
3606
+ if (is2DRef.current) {
3607
+ const z2 = Math.max(120, Math.min(Math.abs(s.camera.position.z), 500));
3608
+ animateCamera(
3609
+ s.camera,
3610
+ s.controls,
3611
+ { x: nx, y: ny, z: z2 },
3612
+ { x: nx, y: ny, z: 0 },
3613
+ duration
3614
+ );
3615
+ return;
3616
+ }
3340
3617
  const dist = Math.hypot(nx, ny, nz);
3341
3618
  if (dist < 1) return;
3342
3619
  const ratio = 1 + 120 / dist;
@@ -3348,6 +3625,34 @@ function NetworkGraph3DInner(props, ref) {
3348
3625
  duration
3349
3626
  );
3350
3627
  },
3628
+ panTo(x2, y2, duration = 600) {
3629
+ const s = sceneRef.current;
3630
+ if (!s) return;
3631
+ const t = s.controls.target;
3632
+ if (is2DRef.current) {
3633
+ animateCamera(
3634
+ s.camera,
3635
+ s.controls,
3636
+ { x: x2, y: y2, z: s.camera.position.z },
3637
+ { x: x2, y: y2, z: 0 },
3638
+ duration
3639
+ );
3640
+ } else {
3641
+ const dx = x2 - t.x;
3642
+ const dy = y2 - t.y;
3643
+ animateCamera(
3644
+ s.camera,
3645
+ s.controls,
3646
+ {
3647
+ x: s.camera.position.x + dx,
3648
+ y: s.camera.position.y + dy,
3649
+ z: s.camera.position.z
3650
+ },
3651
+ { x: x2, y: y2, z: t.z },
3652
+ duration
3653
+ );
3654
+ }
3655
+ },
3351
3656
  appendData(newNodes, newLinks) {
3352
3657
  if (newNodes.length === 0 && newLinks.length === 0) return 0;
3353
3658
  const existingIds = new Set(dataRef.current.nodes.map((n) => n.id));
@@ -3376,6 +3681,32 @@ function NetworkGraph3DInner(props, ref) {
3376
3681
  s.renderer.render(s.scene, s.camera);
3377
3682
  return s.renderer.domElement.toDataURL("image/png");
3378
3683
  },
3684
+ getGraphSnapshot() {
3685
+ var _a;
3686
+ const gObj = graphObjRef.current;
3687
+ const d = dataRef.current;
3688
+ if (!gObj || !d.positions) return null;
3689
+ return {
3690
+ positions: d.positions,
3691
+ count: d.nodes.length,
3692
+ colors: ((_a = gObj.nodesMesh.instanceColor) == null ? void 0 : _a.array) ?? null,
3693
+ hidden: hiddenNodesRef.current,
3694
+ selectedIndex: selectedNodeIdRef.current ? d.nodeIdToIndex.get(selectedNodeIdRef.current) ?? -1 : -1
3695
+ };
3696
+ },
3697
+ getViewportRect() {
3698
+ const s = sceneRef.current;
3699
+ if (!s) return null;
3700
+ const cam = s.camera;
3701
+ const dist = Math.abs(cam.position.z);
3702
+ const halfH = Math.tan(cam.fov * Math.PI / 360) * dist;
3703
+ return {
3704
+ cx: cam.position.x,
3705
+ cy: cam.position.y,
3706
+ halfW: halfH * cam.aspect,
3707
+ halfH
3708
+ };
3709
+ },
3379
3710
  reheatLayout() {
3380
3711
  const gObj = graphObjRef.current;
3381
3712
  if (gObj == null ? void 0 : gObj.worker) {
@@ -3397,6 +3728,150 @@ function NetworkGraph3DInner(props, ref) {
3397
3728
  );
3398
3729
  }
3399
3730
  const NetworkGraph3D = forwardRef(NetworkGraph3DInner);
3731
+ function GraphMinimap({
3732
+ graphRef,
3733
+ width = 200,
3734
+ height = 140,
3735
+ backgroundColor,
3736
+ viewportColor = "#94a3b8",
3737
+ dotRadius = 1.5,
3738
+ fps = 15,
3739
+ padding = 0.08,
3740
+ className,
3741
+ style
3742
+ }) {
3743
+ const canvasRef = useRef(null);
3744
+ const fitRef = useRef(null);
3745
+ const draggingRef = useRef(false);
3746
+ useEffect(() => {
3747
+ const canvas = canvasRef.current;
3748
+ if (!canvas) return;
3749
+ const ctx = canvas.getContext("2d");
3750
+ if (!ctx) return;
3751
+ const dpr = Math.min(window.devicePixelRatio || 1, 2);
3752
+ canvas.width = width * dpr;
3753
+ canvas.height = height * dpr;
3754
+ let raf = 0;
3755
+ let last = 0;
3756
+ const interval2 = 1e3 / fps;
3757
+ const draw = (now2) => {
3758
+ var _a, _b;
3759
+ raf = requestAnimationFrame(draw);
3760
+ if (now2 - last < interval2) return;
3761
+ last = now2;
3762
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
3763
+ ctx.clearRect(0, 0, width, height);
3764
+ if (backgroundColor) {
3765
+ ctx.fillStyle = backgroundColor;
3766
+ ctx.fillRect(0, 0, width, height);
3767
+ }
3768
+ const snap = (_a = graphRef.current) == null ? void 0 : _a.getGraphSnapshot();
3769
+ if (!snap || snap.count === 0) {
3770
+ fitRef.current = null;
3771
+ return;
3772
+ }
3773
+ const { positions, count, colors, hidden, selectedIndex } = snap;
3774
+ let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
3775
+ for (let i = 0; i < count; i++) {
3776
+ if (hidden && hidden[i]) continue;
3777
+ const x2 = positions[i * 3];
3778
+ const y2 = positions[i * 3 + 1];
3779
+ if (x2 < minX) minX = x2;
3780
+ if (x2 > maxX) maxX = x2;
3781
+ if (y2 < minY) minY = y2;
3782
+ if (y2 > maxY) maxY = y2;
3783
+ }
3784
+ if (!isFinite(minX)) {
3785
+ fitRef.current = null;
3786
+ return;
3787
+ }
3788
+ const spanX = Math.max(maxX - minX, 1);
3789
+ const spanY = Math.max(maxY - minY, 1);
3790
+ const pad = Math.min(width, height) * padding;
3791
+ const scale = Math.min(
3792
+ (width - pad * 2) / spanX,
3793
+ (height - pad * 2) / spanY
3794
+ );
3795
+ const offsetX = width / 2 - (minX + maxX) / 2 * scale;
3796
+ const offsetY = height / 2 + (minY + maxY) / 2 * scale;
3797
+ fitRef.current = { scale, offsetX, offsetY };
3798
+ const r = dotRadius;
3799
+ for (let i = 0; i < count; i++) {
3800
+ if (hidden && hidden[i]) continue;
3801
+ const cx = positions[i * 3] * scale + offsetX;
3802
+ const cy = -positions[i * 3 + 1] * scale + offsetY;
3803
+ if (colors) {
3804
+ const cr = Math.min(255, Math.round(colors[i * 3] * 255));
3805
+ const cg = Math.min(255, Math.round(colors[i * 3 + 1] * 255));
3806
+ const cb = Math.min(255, Math.round(colors[i * 3 + 2] * 255));
3807
+ ctx.fillStyle = `rgb(${cr},${cg},${cb})`;
3808
+ } else {
3809
+ ctx.fillStyle = viewportColor;
3810
+ }
3811
+ const rad = i === selectedIndex ? r * 2 : r;
3812
+ ctx.beginPath();
3813
+ ctx.arc(cx, cy, rad, 0, Math.PI * 2);
3814
+ ctx.fill();
3815
+ }
3816
+ const vp = (_b = graphRef.current) == null ? void 0 : _b.getViewportRect();
3817
+ if (vp) {
3818
+ const x2 = (vp.cx - vp.halfW) * scale + offsetX;
3819
+ const y2 = -(vp.cy + vp.halfH) * scale + offsetY;
3820
+ const w = vp.halfW * 2 * scale;
3821
+ const h = vp.halfH * 2 * scale;
3822
+ ctx.strokeStyle = viewportColor;
3823
+ ctx.lineWidth = 1;
3824
+ ctx.strokeRect(x2, y2, w, h);
3825
+ ctx.fillStyle = viewportColor + "1a";
3826
+ ctx.fillRect(x2, y2, w, h);
3827
+ }
3828
+ };
3829
+ raf = requestAnimationFrame(draw);
3830
+ return () => cancelAnimationFrame(raf);
3831
+ }, [graphRef, width, height, backgroundColor, viewportColor, dotRadius, fps, padding]);
3832
+ const panToPointer = (e) => {
3833
+ var _a;
3834
+ const fit = fitRef.current;
3835
+ const canvas = canvasRef.current;
3836
+ if (!fit || !canvas) return;
3837
+ const rect = canvas.getBoundingClientRect();
3838
+ const px = e.clientX - rect.left;
3839
+ const py = e.clientY - rect.top;
3840
+ const wx = (px - fit.offsetX) / fit.scale;
3841
+ const wy = -(py - fit.offsetY) / fit.scale;
3842
+ (_a = graphRef.current) == null ? void 0 : _a.panTo(wx, wy, draggingRef.current ? 0 : 300);
3843
+ };
3844
+ return /* @__PURE__ */ jsx(
3845
+ "canvas",
3846
+ {
3847
+ ref: canvasRef,
3848
+ className,
3849
+ style: {
3850
+ width,
3851
+ height,
3852
+ cursor: "pointer",
3853
+ touchAction: "none",
3854
+ display: "block",
3855
+ ...style
3856
+ },
3857
+ onPointerDown: (e) => {
3858
+ draggingRef.current = true;
3859
+ e.currentTarget.setPointerCapture(e.pointerId);
3860
+ panToPointer(e);
3861
+ },
3862
+ onPointerMove: (e) => {
3863
+ if (draggingRef.current) panToPointer(e);
3864
+ },
3865
+ onPointerUp: (e) => {
3866
+ draggingRef.current = false;
3867
+ e.currentTarget.releasePointerCapture(e.pointerId);
3868
+ },
3869
+ onPointerCancel: () => {
3870
+ draggingRef.current = false;
3871
+ }
3872
+ }
3873
+ );
3874
+ }
3400
3875
  function forceCenter(x2, y2, z2) {
3401
3876
  var nodes, strength = 1;
3402
3877
  if (x2 == null) x2 = 0;
@@ -5465,6 +5940,7 @@ function CtrlBtn({ children, title, onClick }) {
5465
5940
  export {
5466
5941
  DEFAULT_LAYOUT,
5467
5942
  DEFAULT_STYLE,
5943
+ GraphMinimap,
5468
5944
  NetworkGraph3D,
5469
5945
  NodeDetailPanel,
5470
5946
  SubgraphView2D,
@@ -5475,6 +5951,7 @@ export {
5475
5951
  computeHighlightSet,
5476
5952
  minimal,
5477
5953
  neon,
5954
+ paper,
5478
5955
  resolveTheme,
5479
5956
  zoomToFitPositions
5480
5957
  };