@cocorof/graphier 1.3.2 → 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.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;
@@ -2002,7 +2070,9 @@ function createOrbitUpdate(camera, controls, keys) {
2002
2070
  radius = Math.max(controls.minDistance, Math.min(controls.maxDistance, radius));
2003
2071
  }
2004
2072
  if (azimuth !== 0) {
2005
- _q.setFromAxisAngle(camera.up, -azimuth);
2073
+ const upDot = camera.up.dot(_worldUp);
2074
+ const azSign = upDot < 0 ? -1 : 1;
2075
+ _q.setFromAxisAngle(camera.up, -azimuth * azSign);
2006
2076
  _offset.applyQuaternion(_q);
2007
2077
  }
2008
2078
  if (polar !== 0) {
@@ -2077,7 +2147,9 @@ function setupKeyboardControls(camera, controls, container, mode = "fly", flySpe
2077
2147
  container.addEventListener("keydown", onKeyDown2);
2078
2148
  container.addEventListener("keyup", onKeyUp);
2079
2149
  container.addEventListener("blur", onBlur);
2080
- const updateFn = mode === "fly" ? createFlyUpdate(camera, controls, keys, state) : createOrbitUpdate(camera, controls, keys);
2150
+ let enabled = true;
2151
+ const innerUpdate = mode === "fly" ? createFlyUpdate(camera, controls, keys, state) : createOrbitUpdate(camera, controls, keys);
2152
+ const updateFn = () => enabled ? innerUpdate() : false;
2081
2153
  function cleanup() {
2082
2154
  container.removeEventListener("keydown", onKeyDown2);
2083
2155
  container.removeEventListener("keyup", onKeyUp);
@@ -2086,7 +2158,11 @@ function setupKeyboardControls(camera, controls, container, mode = "fly", flySpe
2086
2158
  function setFlySpeed(speed) {
2087
2159
  state.flySpeed = speed;
2088
2160
  }
2089
- return { update: updateFn, cleanup, setFlySpeed };
2161
+ function setEnabled(on) {
2162
+ enabled = on;
2163
+ if (!on) for (const k of Object.keys(keys)) keys[k] = false;
2164
+ }
2165
+ return { update: updateFn, cleanup, setFlySpeed, setEnabled };
2090
2166
  }
2091
2167
  function createScene(container, backgroundColor, style, rendererConfig) {
2092
2168
  const scene = new THREE__namespace.Scene();
@@ -2126,8 +2202,10 @@ function createScene(container, backgroundColor, style, rendererConfig) {
2126
2202
  const cameraMode = (rendererConfig == null ? void 0 : rendererConfig.cameraMode) ?? "fly";
2127
2203
  const keyboard = setupKeyboardControls(camera, controls, container, cameraMode, style.flySpeed ?? 1);
2128
2204
  controls.enableZoom = false;
2205
+ const flags = { is2D: false };
2129
2206
  const _wheelDir = new THREE__namespace.Vector3();
2130
2207
  const onWheel = (e) => {
2208
+ if (flags.is2D) return;
2131
2209
  e.preventDefault();
2132
2210
  let delta = -e.deltaY;
2133
2211
  if (e.deltaMode === 1) delta *= 40;
@@ -2151,9 +2229,40 @@ function createScene(container, backgroundColor, style, rendererConfig) {
2151
2229
  composer: null,
2152
2230
  bloomPass: null,
2153
2231
  keyboard,
2154
- scrollCleanup
2232
+ scrollCleanup,
2233
+ flags
2155
2234
  };
2156
2235
  }
2236
+ function applyCameraMode2D(state, is2D) {
2237
+ const { controls, camera, keyboard } = state;
2238
+ state.flags.is2D = is2D;
2239
+ controls.enableRotate = !is2D;
2240
+ controls.enableZoom = is2D;
2241
+ controls.screenSpacePanning = is2D;
2242
+ keyboard.setEnabled(!is2D);
2243
+ if (is2D) {
2244
+ controls.mouseButtons = {
2245
+ LEFT: THREE__namespace.MOUSE.PAN,
2246
+ MIDDLE: THREE__namespace.MOUSE.DOLLY,
2247
+ RIGHT: THREE__namespace.MOUSE.PAN
2248
+ };
2249
+ controls.touches = { ONE: THREE__namespace.TOUCH.PAN, TWO: THREE__namespace.TOUCH.DOLLY_PAN };
2250
+ const t = controls.target;
2251
+ const dist = Math.max(camera.position.distanceTo(t), 50);
2252
+ t.z = 0;
2253
+ camera.up.set(0, 1, 0);
2254
+ camera.position.set(t.x, t.y, dist);
2255
+ camera.lookAt(t);
2256
+ } else {
2257
+ controls.mouseButtons = {
2258
+ LEFT: THREE__namespace.MOUSE.ROTATE,
2259
+ MIDDLE: THREE__namespace.MOUSE.DOLLY,
2260
+ RIGHT: THREE__namespace.MOUSE.PAN
2261
+ };
2262
+ controls.touches = { ONE: THREE__namespace.TOUCH.ROTATE, TWO: THREE__namespace.TOUCH.DOLLY_PAN };
2263
+ }
2264
+ controls.update();
2265
+ }
2157
2266
  function initBloom(state, nodeCount, style) {
2158
2267
  if (state.composer) return;
2159
2268
  try {
@@ -2350,14 +2459,14 @@ function createNodeMesh(nodes, scales, theme) {
2350
2459
  mesh.computeBoundingSphere();
2351
2460
  return { mesh, material, scales };
2352
2461
  }
2353
- function updateNodePositions(mesh, positions, scales, nodeCount) {
2462
+ function updateNodePositions(mesh, positions, scales, nodeCount, hidden) {
2354
2463
  const pos = new THREE__namespace.Vector3();
2355
2464
  const scale = new THREE__namespace.Vector3();
2356
2465
  const quat = new THREE__namespace.Quaternion();
2357
2466
  const mat = new THREE__namespace.Matrix4();
2358
2467
  for (let i = 0; i < nodeCount; i++) {
2359
2468
  pos.set(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]);
2360
- const sc = scales[i];
2469
+ const sc = hidden && hidden[i] ? 1e-4 : scales[i];
2361
2470
  scale.set(sc, sc, sc);
2362
2471
  mat.compose(pos, quat, scale);
2363
2472
  mesh.setMatrixAt(i, mat);
@@ -2414,7 +2523,7 @@ function createEdgeMesh(links, edgeNodeIndices, edgeLinkIndices, nodeCount, edge
2414
2523
  transparent: true,
2415
2524
  opacity: adaptiveOpacity,
2416
2525
  depthWrite: false,
2417
- blending: THREE__namespace.AdditiveBlending
2526
+ blending: theme.additiveEdges ? THREE__namespace.AdditiveBlending : THREE__namespace.NormalBlending
2418
2527
  });
2419
2528
  const mesh = new THREE__namespace.LineSegments(geometry, material);
2420
2529
  return {
@@ -2426,10 +2535,19 @@ function createEdgeMesh(links, edgeNodeIndices, edgeLinkIndices, nodeCount, edge
2426
2535
  edgeLinkIndices
2427
2536
  };
2428
2537
  }
2429
- function updateEdgePositions(positionArray, nodePositions, edgeNodeIndices, geometry) {
2538
+ function updateEdgePositions(positionArray, nodePositions, edgeNodeIndices, geometry, hiddenEdges) {
2430
2539
  const count = edgeNodeIndices.length;
2431
2540
  for (let i = 0; i < count; i++) {
2432
2541
  const [si, ti] = edgeNodeIndices[i];
2542
+ if (hiddenEdges && hiddenEdges[i]) {
2543
+ positionArray[i * 6 + 0] = nodePositions[si * 3];
2544
+ positionArray[i * 6 + 1] = nodePositions[si * 3 + 1];
2545
+ positionArray[i * 6 + 2] = nodePositions[si * 3 + 2];
2546
+ positionArray[i * 6 + 3] = nodePositions[si * 3];
2547
+ positionArray[i * 6 + 4] = nodePositions[si * 3 + 1];
2548
+ positionArray[i * 6 + 5] = nodePositions[si * 3 + 2];
2549
+ continue;
2550
+ }
2433
2551
  positionArray[i * 6 + 0] = nodePositions[si * 3];
2434
2552
  positionArray[i * 6 + 1] = nodePositions[si * 3 + 1];
2435
2553
  positionArray[i * 6 + 2] = nodePositions[si * 3 + 2];
@@ -2492,7 +2610,7 @@ function zoomToFitPositions(camera, controls, positions, duration, padding) {
2492
2610
  );
2493
2611
  }
2494
2612
  const EDGE_HIT_THRESHOLD = 5;
2495
- function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, callbacks, container, getEdgeData) {
2613
+ function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, callbacks, container, getEdgeData, options) {
2496
2614
  const raycaster = new THREE__namespace.Raycaster();
2497
2615
  const mouse = new THREE__namespace.Vector2();
2498
2616
  let mouseDownPos = null;
@@ -2650,20 +2768,34 @@ function setupInteraction(canvas, camera, controls, getNodesMesh, getNodes, call
2650
2768
  lastClickTime = now2;
2651
2769
  lastClickNodeId = node.id;
2652
2770
  singleClickTimer = setTimeout(() => {
2771
+ var _a2, _b;
2653
2772
  singleClickTimer = null;
2654
- const nx = node.x ?? 0;
2655
- const ny = node.y ?? 0;
2656
- const nz = node.z ?? 0;
2657
- const dist = Math.hypot(nx, ny, nz);
2658
- if (dist > 1) {
2659
- const ratio = 1 + 120 / dist;
2660
- animateCamera(
2661
- camera,
2662
- controls,
2663
- { x: nx * ratio, y: ny * ratio, z: nz * ratio },
2664
- { x: nx, y: ny, z: nz },
2665
- 1200
2666
- );
2773
+ const clickToFocus = ((_a2 = options == null ? void 0 : options.getClickToFocus) == null ? void 0 : _a2.call(options)) ?? true;
2774
+ if (clickToFocus) {
2775
+ const nx = node.x ?? 0;
2776
+ const ny = node.y ?? 0;
2777
+ const nz = node.z ?? 0;
2778
+ if ((_b = options == null ? void 0 : options.getIs2D) == null ? void 0 : _b.call(options)) {
2779
+ animateCamera(
2780
+ camera,
2781
+ controls,
2782
+ { x: nx, y: ny, z: camera.position.z },
2783
+ { x: nx, y: ny, z: 0 },
2784
+ 800
2785
+ );
2786
+ } else {
2787
+ const dist = Math.hypot(nx, ny, nz);
2788
+ if (dist > 1) {
2789
+ const ratio = 1 + 120 / dist;
2790
+ animateCamera(
2791
+ camera,
2792
+ controls,
2793
+ { x: nx * ratio, y: ny * ratio, z: nz * ratio },
2794
+ { x: nx, y: ny, z: nz },
2795
+ 1200
2796
+ );
2797
+ }
2798
+ }
2667
2799
  }
2668
2800
  callbacks.onNodeClick(node);
2669
2801
  }, 250);
@@ -2803,7 +2935,12 @@ function NetworkGraph3DInner(props, ref) {
2803
2935
  layout: layoutProp,
2804
2936
  renderer: rendererProp,
2805
2937
  labelFormatter,
2806
- nodeValueAccessor
2938
+ nodeValueAccessor,
2939
+ visibleNodeIds,
2940
+ linkVisibility,
2941
+ clickToFocus = true,
2942
+ hoverHighlight = false,
2943
+ hoverHighlightHops = 1
2807
2944
  } = props;
2808
2945
  const containerRef = react.useRef(null);
2809
2946
  const resolvedStyle = react.useMemo(
@@ -2840,6 +2977,13 @@ function NetworkGraph3DInner(props, ref) {
2840
2977
  const selectedNodeIdRef = react.useRef(selectedNodeId);
2841
2978
  const labelFormatterRef = react.useRef(labelFormatter);
2842
2979
  const highlightSetRef = react.useRef(null);
2980
+ const clickToFocusRef = react.useRef(clickToFocus);
2981
+ const hoverHighlightRef = react.useRef(hoverHighlight);
2982
+ const hoverHighlightHopsRef = react.useRef(hoverHighlightHops);
2983
+ const adjacencyMapRef = react.useRef(/* @__PURE__ */ new Map());
2984
+ const is2DRef = react.useRef(false);
2985
+ const hiddenNodesRef = react.useRef(null);
2986
+ const hiddenEdgesRef = react.useRef(null);
2843
2987
  onNodeClickRef.current = onNodeClick;
2844
2988
  onNodeDoubleClickRef.current = onNodeDoubleClick;
2845
2989
  onNodeHoverRef.current = onNodeHover;
@@ -2854,6 +2998,14 @@ function NetworkGraph3DInner(props, ref) {
2854
2998
  themeRef.current = resolvedTheme;
2855
2999
  selectedNodeIdRef.current = selectedNodeId;
2856
3000
  labelFormatterRef.current = labelFormatter;
3001
+ clickToFocusRef.current = clickToFocus;
3002
+ hoverHighlightRef.current = hoverHighlight;
3003
+ hoverHighlightHopsRef.current = hoverHighlightHops;
3004
+ const is2D = (layoutProp == null ? void 0 : layoutProp.dimensions) === 2;
3005
+ is2DRef.current = is2D;
3006
+ const layoutKey = JSON.stringify(layoutProp ?? null);
3007
+ const layoutRef = react.useRef(layoutProp);
3008
+ layoutRef.current = layoutProp;
2857
3009
  const mergedData = react.useMemo(() => {
2858
3010
  if (!appendedData) return data;
2859
3011
  const existingIds = new Set(data.nodes.map((n) => n.id));
@@ -2880,6 +3032,11 @@ function NetworkGraph3DInner(props, ref) {
2880
3032
  () => buildAdjacencyMapFromLinks(mergedData.links),
2881
3033
  [mergedData.links]
2882
3034
  );
3035
+ adjacencyMapRef.current = adjacencyMap;
3036
+ const visibleSet = react.useMemo(() => {
3037
+ if (visibleNodeIds == null) return null;
3038
+ return visibleNodeIds instanceof Set ? visibleNodeIds : new Set(visibleNodeIds);
3039
+ }, [visibleNodeIds]);
2883
3040
  const highlightSet = react.useMemo(() => {
2884
3041
  if (!selectedNodeId) return null;
2885
3042
  return computeHighlightSet(selectedNodeId, adjacencyMap, highlightHops);
@@ -2893,6 +3050,32 @@ function NetworkGraph3DInner(props, ref) {
2893
3050
  }
2894
3051
  return { min: isFinite(min) ? min : 1, max: isFinite(max) ? max : 1 };
2895
3052
  }, [mergedData.nodes, nodeValueAccessor]);
3053
+ const applyHoverHighlight = (node) => {
3054
+ if (!hoverHighlightRef.current) return;
3055
+ if (selectedNodeIdRef.current) return;
3056
+ const gObj = graphObjRef.current;
3057
+ if (!gObj) return;
3058
+ const d = dataRef.current;
3059
+ const set2 = node ? computeHighlightSet(
3060
+ node.id,
3061
+ adjacencyMapRef.current,
3062
+ hoverHighlightHopsRef.current
3063
+ ) : null;
3064
+ highlightSetRef.current = set2;
3065
+ applyNodeHighlight(gObj.nodesMesh, d.nodes, (node == null ? void 0 : node.id) ?? null, set2, themeRef.current);
3066
+ applyEdgeHighlight(
3067
+ gObj.edgesMesh,
3068
+ d.links,
3069
+ d.edgeNodeIndices,
3070
+ d.edgeLinkIndices,
3071
+ set2,
3072
+ styleRef.current.edgeOpacity,
3073
+ d.nodes.length,
3074
+ themeRef.current
3075
+ );
3076
+ };
3077
+ const applyHoverHighlightRef = react.useRef(applyHoverHighlight);
3078
+ applyHoverHighlightRef.current = applyHoverHighlight;
2896
3079
  react.useEffect(() => {
2897
3080
  const container = containerRef.current;
2898
3081
  if (!container) return;
@@ -2916,7 +3099,8 @@ function NetworkGraph3DInner(props, ref) {
2916
3099
  styleRef.current.labelThreshold,
2917
3100
  styleRef.current.maxLabels,
2918
3101
  labelFormatterRef.current,
2919
- highlightSetRef.current
3102
+ highlightSetRef.current,
3103
+ hiddenNodesRef.current
2920
3104
  );
2921
3105
  });
2922
3106
  const resizeObserver = setupResize(container, state);
@@ -2940,7 +3124,8 @@ function NetworkGraph3DInner(props, ref) {
2940
3124
  },
2941
3125
  onNodeHover: (node) => {
2942
3126
  var _a;
2943
- return (_a = onNodeHoverRef.current) == null ? void 0 : _a.call(onNodeHoverRef, node);
3127
+ (_a = onNodeHoverRef.current) == null ? void 0 : _a.call(onNodeHoverRef, node);
3128
+ applyHoverHighlightRef.current(node);
2944
3129
  },
2945
3130
  onContextMenu: (node, pos) => {
2946
3131
  var _a;
@@ -2956,6 +3141,7 @@ function NetworkGraph3DInner(props, ref) {
2956
3141
  },
2957
3142
  onNodeDrag: (node, pos) => {
2958
3143
  var _a;
3144
+ if (is2DRef.current) pos = { ...pos, z: 0 };
2959
3145
  (_a = onNodeDragRef.current) == null ? void 0 : _a.call(onNodeDragRef, node, pos);
2960
3146
  const d = dataRef.current;
2961
3147
  const idx = d.nodeIdToIndex.get(node.id);
@@ -2968,7 +3154,13 @@ function NetworkGraph3DInner(props, ref) {
2968
3154
  node.z = pos.z;
2969
3155
  const gObj = graphObjRef.current;
2970
3156
  if (gObj && d.scales) {
2971
- updateNodePositions(gObj.nodesMesh, d.positions, d.scales, d.nodes.length);
3157
+ updateNodePositions(
3158
+ gObj.nodesMesh,
3159
+ d.positions,
3160
+ d.scales,
3161
+ d.nodes.length,
3162
+ hiddenNodesRef.current
3163
+ );
2972
3164
  }
2973
3165
  }
2974
3166
  },
@@ -2986,6 +3178,10 @@ function NetworkGraph3DInner(props, ref) {
2986
3178
  edgeLinkIndices: d.edgeLinkIndices,
2987
3179
  positions: d.positions
2988
3180
  };
3181
+ },
3182
+ {
3183
+ getClickToFocus: () => clickToFocusRef.current,
3184
+ getIs2D: () => is2DRef.current
2989
3185
  }
2990
3186
  );
2991
3187
  return () => {
@@ -3132,17 +3328,26 @@ function NetworkGraph3DInner(props, ref) {
3132
3328
  if (msg.type === "positions") {
3133
3329
  const positions = new Float32Array(msg.positions);
3134
3330
  dataRef.current.positions = positions;
3135
- updateNodePositions(nodesMesh, positions, scales, nc);
3331
+ const hn = hiddenNodesRef.current;
3332
+ updateNodePositions(
3333
+ nodesMesh,
3334
+ positions,
3335
+ scales,
3336
+ nc,
3337
+ hn && hn.length === nc ? hn : null
3338
+ );
3136
3339
  for (let i = 0; i < nc; i++) {
3137
3340
  nodes[i].x = positions[i * 3];
3138
3341
  nodes[i].y = positions[i * 3 + 1];
3139
3342
  nodes[i].z = positions[i * 3 + 2];
3140
3343
  }
3344
+ const he = hiddenEdgesRef.current;
3141
3345
  updateEdgePositions(
3142
3346
  edgeResult.positionArray,
3143
3347
  positions,
3144
3348
  edgeNodeIndices,
3145
- edgeResult.geometry
3349
+ edgeResult.geometry,
3350
+ he && he.length === edgeNodeIndices.length ? he : null
3146
3351
  );
3147
3352
  const selId = selectedNodeIdRef.current;
3148
3353
  if (selId && sceneState.selectionRing.visible) {
@@ -3162,7 +3367,20 @@ function NetworkGraph3DInner(props, ref) {
3162
3367
  (_b = onLayoutSettledRef.current) == null ? void 0 : _b.call(onLayoutSettledRef);
3163
3368
  }
3164
3369
  };
3165
- const layoutParams = resolveLayoutParams(nc, layoutProp);
3370
+ const layoutConfig = layoutRef.current;
3371
+ const layoutParams = resolveLayoutParams(nc, layoutConfig);
3372
+ let groups;
3373
+ if (layoutConfig == null ? void 0 : layoutConfig.clusterBy) {
3374
+ const keyOf = (n) => layoutConfig.clusterBy === "type" ? n.type : n.group;
3375
+ const keyToIdx = /* @__PURE__ */ new Map();
3376
+ groups = nodes.map((n) => {
3377
+ const k = keyOf(n);
3378
+ if (k == null) return -1;
3379
+ const ks = String(k);
3380
+ if (!keyToIdx.has(ks)) keyToIdx.set(ks, keyToIdx.size);
3381
+ return keyToIdx.get(ks);
3382
+ });
3383
+ }
3166
3384
  worker.postMessage({
3167
3385
  type: "init",
3168
3386
  nodes: nodes.map((n) => ({ id: n.id })),
@@ -3171,7 +3389,8 @@ function NetworkGraph3DInner(props, ref) {
3171
3389
  target: typeof l.target === "object" ? l.target.id : l.target
3172
3390
  })),
3173
3391
  params: layoutParams,
3174
- initialPositions: preservedPositionsRef.current
3392
+ initialPositions: preservedPositionsRef.current,
3393
+ groups
3175
3394
  });
3176
3395
  return () => {
3177
3396
  const d = dataRef.current;
@@ -3196,7 +3415,56 @@ function NetworkGraph3DInner(props, ref) {
3196
3415
  disposeObject(edgeResult.mesh);
3197
3416
  graphObjRef.current = null;
3198
3417
  };
3199
- }, [mergedData, valRange, nodeValueAccessor, layoutProp]);
3418
+ }, [mergedData, valRange, nodeValueAccessor, layoutKey]);
3419
+ react.useEffect(() => {
3420
+ const d = dataRef.current;
3421
+ const gObj = graphObjRef.current;
3422
+ if (!visibleSet && !linkVisibility) {
3423
+ hiddenNodesRef.current = null;
3424
+ hiddenEdgesRef.current = null;
3425
+ } else {
3426
+ const nc = d.nodes.length;
3427
+ const hn = new Uint8Array(nc);
3428
+ if (visibleSet) {
3429
+ for (let i = 0; i < nc; i++) {
3430
+ if (!visibleSet.has(d.nodes[i].id)) hn[i] = 1;
3431
+ }
3432
+ }
3433
+ const ec = d.edgeNodeIndices.length;
3434
+ const he = new Uint8Array(ec);
3435
+ for (let i = 0; i < ec; i++) {
3436
+ const [si, ti] = d.edgeNodeIndices[i];
3437
+ if (hn[si] || hn[ti]) {
3438
+ he[i] = 1;
3439
+ } else if (linkVisibility) {
3440
+ const link = d.links[d.edgeLinkIndices[i]];
3441
+ if (link && !linkVisibility(link)) he[i] = 1;
3442
+ }
3443
+ }
3444
+ hiddenNodesRef.current = visibleSet ? hn : null;
3445
+ hiddenEdgesRef.current = he;
3446
+ }
3447
+ if (gObj && d.positions && d.scales) {
3448
+ updateNodePositions(
3449
+ gObj.nodesMesh,
3450
+ d.positions,
3451
+ d.scales,
3452
+ d.nodes.length,
3453
+ hiddenNodesRef.current
3454
+ );
3455
+ updateEdgePositions(
3456
+ gObj.edgePositionArray,
3457
+ d.positions,
3458
+ d.edgeNodeIndices,
3459
+ gObj.edgeGeometry,
3460
+ hiddenEdgesRef.current
3461
+ );
3462
+ }
3463
+ }, [visibleSet, linkVisibility, mergedData]);
3464
+ react.useEffect(() => {
3465
+ const s = sceneRef.current;
3466
+ if (s) applyCameraMode2D(s, is2D);
3467
+ }, [is2D]);
3200
3468
  react.useEffect(() => {
3201
3469
  const gObj = graphObjRef.current;
3202
3470
  const sceneState = sceneRef.current;
@@ -3264,7 +3532,7 @@ function NetworkGraph3DInner(props, ref) {
3264
3532
  resolvedStyle.nodeMaxSize
3265
3533
  );
3266
3534
  dataRef.current.scales = newScales;
3267
- updateNodePositions(gObj.nodesMesh, positions, newScales, nc);
3535
+ updateNodePositions(gObj.nodesMesh, positions, newScales, nc, hiddenNodesRef.current);
3268
3536
  }, [resolvedStyle.nodeMinSize, resolvedStyle.nodeMaxSize, valRange]);
3269
3537
  react.useEffect(() => {
3270
3538
  const gObj = graphObjRef.current;
@@ -3353,6 +3621,17 @@ function NetworkGraph3DInner(props, ref) {
3353
3621
  const nx = d.positions[idx * 3];
3354
3622
  const ny = d.positions[idx * 3 + 1];
3355
3623
  const nz = d.positions[idx * 3 + 2];
3624
+ if (is2DRef.current) {
3625
+ const z2 = Math.max(120, Math.min(Math.abs(s.camera.position.z), 500));
3626
+ animateCamera(
3627
+ s.camera,
3628
+ s.controls,
3629
+ { x: nx, y: ny, z: z2 },
3630
+ { x: nx, y: ny, z: 0 },
3631
+ duration
3632
+ );
3633
+ return;
3634
+ }
3356
3635
  const dist = Math.hypot(nx, ny, nz);
3357
3636
  if (dist < 1) return;
3358
3637
  const ratio = 1 + 120 / dist;
@@ -3364,6 +3643,34 @@ function NetworkGraph3DInner(props, ref) {
3364
3643
  duration
3365
3644
  );
3366
3645
  },
3646
+ panTo(x2, y2, duration = 600) {
3647
+ const s = sceneRef.current;
3648
+ if (!s) return;
3649
+ const t = s.controls.target;
3650
+ if (is2DRef.current) {
3651
+ animateCamera(
3652
+ s.camera,
3653
+ s.controls,
3654
+ { x: x2, y: y2, z: s.camera.position.z },
3655
+ { x: x2, y: y2, z: 0 },
3656
+ duration
3657
+ );
3658
+ } else {
3659
+ const dx = x2 - t.x;
3660
+ const dy = y2 - t.y;
3661
+ animateCamera(
3662
+ s.camera,
3663
+ s.controls,
3664
+ {
3665
+ x: s.camera.position.x + dx,
3666
+ y: s.camera.position.y + dy,
3667
+ z: s.camera.position.z
3668
+ },
3669
+ { x: x2, y: y2, z: t.z },
3670
+ duration
3671
+ );
3672
+ }
3673
+ },
3367
3674
  appendData(newNodes, newLinks) {
3368
3675
  if (newNodes.length === 0 && newLinks.length === 0) return 0;
3369
3676
  const existingIds = new Set(dataRef.current.nodes.map((n) => n.id));
@@ -3392,6 +3699,32 @@ function NetworkGraph3DInner(props, ref) {
3392
3699
  s.renderer.render(s.scene, s.camera);
3393
3700
  return s.renderer.domElement.toDataURL("image/png");
3394
3701
  },
3702
+ getGraphSnapshot() {
3703
+ var _a;
3704
+ const gObj = graphObjRef.current;
3705
+ const d = dataRef.current;
3706
+ if (!gObj || !d.positions) return null;
3707
+ return {
3708
+ positions: d.positions,
3709
+ count: d.nodes.length,
3710
+ colors: ((_a = gObj.nodesMesh.instanceColor) == null ? void 0 : _a.array) ?? null,
3711
+ hidden: hiddenNodesRef.current,
3712
+ selectedIndex: selectedNodeIdRef.current ? d.nodeIdToIndex.get(selectedNodeIdRef.current) ?? -1 : -1
3713
+ };
3714
+ },
3715
+ getViewportRect() {
3716
+ const s = sceneRef.current;
3717
+ if (!s) return null;
3718
+ const cam = s.camera;
3719
+ const dist = Math.abs(cam.position.z);
3720
+ const halfH = Math.tan(cam.fov * Math.PI / 360) * dist;
3721
+ return {
3722
+ cx: cam.position.x,
3723
+ cy: cam.position.y,
3724
+ halfW: halfH * cam.aspect,
3725
+ halfH
3726
+ };
3727
+ },
3395
3728
  reheatLayout() {
3396
3729
  const gObj = graphObjRef.current;
3397
3730
  if (gObj == null ? void 0 : gObj.worker) {
@@ -3413,6 +3746,150 @@ function NetworkGraph3DInner(props, ref) {
3413
3746
  );
3414
3747
  }
3415
3748
  const NetworkGraph3D = react.forwardRef(NetworkGraph3DInner);
3749
+ function GraphMinimap({
3750
+ graphRef,
3751
+ width = 200,
3752
+ height = 140,
3753
+ backgroundColor,
3754
+ viewportColor = "#94a3b8",
3755
+ dotRadius = 1.5,
3756
+ fps = 15,
3757
+ padding = 0.08,
3758
+ className,
3759
+ style
3760
+ }) {
3761
+ const canvasRef = react.useRef(null);
3762
+ const fitRef = react.useRef(null);
3763
+ const draggingRef = react.useRef(false);
3764
+ react.useEffect(() => {
3765
+ const canvas = canvasRef.current;
3766
+ if (!canvas) return;
3767
+ const ctx = canvas.getContext("2d");
3768
+ if (!ctx) return;
3769
+ const dpr = Math.min(window.devicePixelRatio || 1, 2);
3770
+ canvas.width = width * dpr;
3771
+ canvas.height = height * dpr;
3772
+ let raf = 0;
3773
+ let last = 0;
3774
+ const interval2 = 1e3 / fps;
3775
+ const draw = (now2) => {
3776
+ var _a, _b;
3777
+ raf = requestAnimationFrame(draw);
3778
+ if (now2 - last < interval2) return;
3779
+ last = now2;
3780
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
3781
+ ctx.clearRect(0, 0, width, height);
3782
+ if (backgroundColor) {
3783
+ ctx.fillStyle = backgroundColor;
3784
+ ctx.fillRect(0, 0, width, height);
3785
+ }
3786
+ const snap = (_a = graphRef.current) == null ? void 0 : _a.getGraphSnapshot();
3787
+ if (!snap || snap.count === 0) {
3788
+ fitRef.current = null;
3789
+ return;
3790
+ }
3791
+ const { positions, count, colors, hidden, selectedIndex } = snap;
3792
+ let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
3793
+ for (let i = 0; i < count; i++) {
3794
+ if (hidden && hidden[i]) continue;
3795
+ const x2 = positions[i * 3];
3796
+ const y2 = positions[i * 3 + 1];
3797
+ if (x2 < minX) minX = x2;
3798
+ if (x2 > maxX) maxX = x2;
3799
+ if (y2 < minY) minY = y2;
3800
+ if (y2 > maxY) maxY = y2;
3801
+ }
3802
+ if (!isFinite(minX)) {
3803
+ fitRef.current = null;
3804
+ return;
3805
+ }
3806
+ const spanX = Math.max(maxX - minX, 1);
3807
+ const spanY = Math.max(maxY - minY, 1);
3808
+ const pad = Math.min(width, height) * padding;
3809
+ const scale = Math.min(
3810
+ (width - pad * 2) / spanX,
3811
+ (height - pad * 2) / spanY
3812
+ );
3813
+ const offsetX = width / 2 - (minX + maxX) / 2 * scale;
3814
+ const offsetY = height / 2 + (minY + maxY) / 2 * scale;
3815
+ fitRef.current = { scale, offsetX, offsetY };
3816
+ const r = dotRadius;
3817
+ for (let i = 0; i < count; i++) {
3818
+ if (hidden && hidden[i]) continue;
3819
+ const cx = positions[i * 3] * scale + offsetX;
3820
+ const cy = -positions[i * 3 + 1] * scale + offsetY;
3821
+ if (colors) {
3822
+ const cr = Math.min(255, Math.round(colors[i * 3] * 255));
3823
+ const cg = Math.min(255, Math.round(colors[i * 3 + 1] * 255));
3824
+ const cb = Math.min(255, Math.round(colors[i * 3 + 2] * 255));
3825
+ ctx.fillStyle = `rgb(${cr},${cg},${cb})`;
3826
+ } else {
3827
+ ctx.fillStyle = viewportColor;
3828
+ }
3829
+ const rad = i === selectedIndex ? r * 2 : r;
3830
+ ctx.beginPath();
3831
+ ctx.arc(cx, cy, rad, 0, Math.PI * 2);
3832
+ ctx.fill();
3833
+ }
3834
+ const vp = (_b = graphRef.current) == null ? void 0 : _b.getViewportRect();
3835
+ if (vp) {
3836
+ const x2 = (vp.cx - vp.halfW) * scale + offsetX;
3837
+ const y2 = -(vp.cy + vp.halfH) * scale + offsetY;
3838
+ const w = vp.halfW * 2 * scale;
3839
+ const h = vp.halfH * 2 * scale;
3840
+ ctx.strokeStyle = viewportColor;
3841
+ ctx.lineWidth = 1;
3842
+ ctx.strokeRect(x2, y2, w, h);
3843
+ ctx.fillStyle = viewportColor + "1a";
3844
+ ctx.fillRect(x2, y2, w, h);
3845
+ }
3846
+ };
3847
+ raf = requestAnimationFrame(draw);
3848
+ return () => cancelAnimationFrame(raf);
3849
+ }, [graphRef, width, height, backgroundColor, viewportColor, dotRadius, fps, padding]);
3850
+ const panToPointer = (e) => {
3851
+ var _a;
3852
+ const fit = fitRef.current;
3853
+ const canvas = canvasRef.current;
3854
+ if (!fit || !canvas) return;
3855
+ const rect = canvas.getBoundingClientRect();
3856
+ const px = e.clientX - rect.left;
3857
+ const py = e.clientY - rect.top;
3858
+ const wx = (px - fit.offsetX) / fit.scale;
3859
+ const wy = -(py - fit.offsetY) / fit.scale;
3860
+ (_a = graphRef.current) == null ? void 0 : _a.panTo(wx, wy, draggingRef.current ? 0 : 300);
3861
+ };
3862
+ return /* @__PURE__ */ jsxRuntime.jsx(
3863
+ "canvas",
3864
+ {
3865
+ ref: canvasRef,
3866
+ className,
3867
+ style: {
3868
+ width,
3869
+ height,
3870
+ cursor: "pointer",
3871
+ touchAction: "none",
3872
+ display: "block",
3873
+ ...style
3874
+ },
3875
+ onPointerDown: (e) => {
3876
+ draggingRef.current = true;
3877
+ e.currentTarget.setPointerCapture(e.pointerId);
3878
+ panToPointer(e);
3879
+ },
3880
+ onPointerMove: (e) => {
3881
+ if (draggingRef.current) panToPointer(e);
3882
+ },
3883
+ onPointerUp: (e) => {
3884
+ draggingRef.current = false;
3885
+ e.currentTarget.releasePointerCapture(e.pointerId);
3886
+ },
3887
+ onPointerCancel: () => {
3888
+ draggingRef.current = false;
3889
+ }
3890
+ }
3891
+ );
3892
+ }
3416
3893
  function forceCenter(x2, y2, z2) {
3417
3894
  var nodes, strength = 1;
3418
3895
  if (x2 == null) x2 = 0;
@@ -5480,6 +5957,7 @@ function CtrlBtn({ children, title, onClick }) {
5480
5957
  }
5481
5958
  exports.DEFAULT_LAYOUT = DEFAULT_LAYOUT;
5482
5959
  exports.DEFAULT_STYLE = DEFAULT_STYLE;
5960
+ exports.GraphMinimap = GraphMinimap;
5483
5961
  exports.NetworkGraph3D = NetworkGraph3D;
5484
5962
  exports.NodeDetailPanel = NodeDetailPanel;
5485
5963
  exports.SubgraphView2D = SubgraphView2D;
@@ -5490,6 +5968,7 @@ exports.celestial = celestial;
5490
5968
  exports.computeHighlightSet = computeHighlightSet;
5491
5969
  exports.minimal = minimal;
5492
5970
  exports.neon = neon;
5971
+ exports.paper = paper;
5493
5972
  exports.resolveTheme = resolveTheme;
5494
5973
  exports.zoomToFitPositions = zoomToFitPositions;
5495
5974
  //# sourceMappingURL=index.cjs.map