weflow-cli 1.9.0 → 1.11.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.
Files changed (134) hide show
  1. package/ARCHITECTURE.md +62 -26
  2. package/CHANGELOG.md +1051 -0
  3. package/OPERATIONS.md +99 -13
  4. package/README.en.md +14 -5
  5. package/README.md +23 -8
  6. package/bin/weflow-cli.ts +364 -40
  7. package/dist/bin/weflow-cli.js +381 -69
  8. package/dist/bin/weflow-cli.js.map +1 -1
  9. package/dist/mcp-server/index.d.ts.map +1 -1
  10. package/dist/mcp-server/index.js +19 -1
  11. package/dist/mcp-server/index.js.map +1 -1
  12. package/dist/src/core/dbPathService.d.ts +12 -0
  13. package/dist/src/core/dbPathService.d.ts.map +1 -1
  14. package/dist/src/core/dbPathService.js +20 -3
  15. package/dist/src/core/dbPathService.js.map +1 -1
  16. package/dist/src/panel/server.d.ts.map +1 -1
  17. package/dist/src/panel/server.js +35 -0
  18. package/dist/src/panel/server.js.map +1 -1
  19. package/dist/src/services/assistantService.d.ts +19 -0
  20. package/dist/src/services/assistantService.d.ts.map +1 -1
  21. package/dist/src/services/assistantService.js +20 -0
  22. package/dist/src/services/assistantService.js.map +1 -1
  23. package/dist/src/services/assistantTools.d.ts +27 -1
  24. package/dist/src/services/assistantTools.d.ts.map +1 -1
  25. package/dist/src/services/assistantTools.js +169 -35
  26. package/dist/src/services/assistantTools.js.map +1 -1
  27. package/dist/src/services/configService.d.ts +2 -0
  28. package/dist/src/services/configService.d.ts.map +1 -1
  29. package/dist/src/services/configService.js +3 -2
  30. package/dist/src/services/configService.js.map +1 -1
  31. package/dist/src/services/exportService.d.ts +43 -0
  32. package/dist/src/services/exportService.d.ts.map +1 -1
  33. package/dist/src/services/exportService.js +116 -11
  34. package/dist/src/services/exportService.js.map +1 -1
  35. package/dist/src/services/messageQuery.d.ts +18 -0
  36. package/dist/src/services/messageQuery.d.ts.map +1 -1
  37. package/dist/src/services/messageQuery.js +29 -0
  38. package/dist/src/services/messageQuery.js.map +1 -1
  39. package/dist/src/services/wechatClient.d.ts +125 -0
  40. package/dist/src/services/wechatClient.d.ts.map +1 -0
  41. package/dist/src/services/wechatClient.js +344 -0
  42. package/dist/src/services/wechatClient.js.map +1 -0
  43. package/dist/src/services/wechatMedia.d.ts +44 -0
  44. package/dist/src/services/wechatMedia.d.ts.map +1 -0
  45. package/dist/src/services/wechatMedia.js +155 -0
  46. package/dist/src/services/wechatMedia.js.map +1 -0
  47. package/dist/src/services/wechatMessageService.d.ts +11 -0
  48. package/dist/src/services/wechatMessageService.d.ts.map +1 -1
  49. package/dist/src/services/wechatMessageService.js +55 -11
  50. package/dist/src/services/wechatMessageService.js.map +1 -1
  51. package/dist/src/types.d.ts +4 -0
  52. package/dist/src/types.d.ts.map +1 -1
  53. package/docs/CONTACT_DB_SCHEMA.md +1085 -0
  54. package/docs/DECISIONS.md +1274 -0
  55. package/docs/EXTENDING.md +69 -7
  56. package/docs/FUNCTIONAL-IMPROVEMENT-SPEC.md +27 -0
  57. package/docs/HEALTH-CHECK.md +12 -7
  58. package/docs/JEV/345/272/224/347/224/250/346/226/275/345/267/245/346/226/207/346/241/243.md +2 -2
  59. package/docs/MCP.md +2 -2
  60. package/docs/PROJECT_STATE.md +64 -5
  61. package/docs/RELEASING.md +128 -1
  62. package/docs/images/weflow-architecture-gpt-image-2.png +0 -0
  63. package/logo.png +0 -0
  64. package/mcp-server/index.ts +18 -3
  65. package/package.json +5 -3
  66. package/resources/js/graph3d/NOTICE.txt +35 -0
  67. package/resources/js/graph3d/d3-binarytree.min.js +2 -0
  68. package/resources/js/graph3d/d3-dispatch.min.js +2 -0
  69. package/resources/js/graph3d/d3-force-3d.min.js +2 -0
  70. package/resources/js/graph3d/d3-octree.min.js +2 -0
  71. package/resources/js/graph3d/d3-quadtree.min.js +2 -0
  72. package/resources/js/graph3d/d3-timer.min.js +2 -0
  73. package/resources/js/graph3d/layout.mjs +63 -0
  74. package/resources/js/graph3d/three.min.js +6 -0
  75. package/resources/js/graph3d/viewer2d.js +448 -0
  76. package/resources/panel/index.html +12 -0
  77. package/resources/panel/mascot-blink-1.png +0 -0
  78. package/resources/panel/mascot-blink-2.png +0 -0
  79. package/resources/panel/mascot-lift-down-1.png +0 -0
  80. package/resources/panel/mascot-lift-down-2.png +0 -0
  81. package/resources/panel/mascot-lift-down-3.png +0 -0
  82. package/resources/panel/mascot-lift-down-4.png +0 -0
  83. package/resources/panel/mascot-lift-down-5.png +0 -0
  84. package/resources/panel/mascot-lift-down-6.png +0 -0
  85. package/resources/panel/mascot-lift-up-1.png +0 -0
  86. package/resources/panel/mascot-lift-up-2.png +0 -0
  87. package/resources/panel/mascot-lift-up-3.png +0 -0
  88. package/resources/panel/mascot-lift-up-4.png +0 -0
  89. package/resources/panel/mascot-lift-up-5.png +0 -0
  90. package/resources/panel/mascot-lift-up-6.png +0 -0
  91. package/resources/panel/mascot-tickle-1.png +0 -0
  92. package/resources/panel/mascot-tickle-2.png +0 -0
  93. package/resources/panel/mascot-tickle-3.png +0 -0
  94. package/resources/panel/mascot-tickle-4.png +0 -0
  95. package/resources/panel/panel.css +111 -0
  96. package/resources/panel/renderer.js +480 -8
  97. package/scripts/_utils.py +1203 -977
  98. package/scripts/biz_daily.py +25 -10
  99. package/scripts/chat_notes.py +15 -5
  100. package/scripts/check_readme_commands.py +426 -0
  101. package/scripts/compile_wiki.py +163 -57
  102. package/scripts/contact_schema.py +339 -0
  103. package/scripts/data/wechat_emoji.json +225 -0
  104. package/scripts/export_chat_html.py +346 -6
  105. package/scripts/fav_notes.py +4 -1
  106. package/scripts/graph_2d.py +151 -0
  107. package/scripts/graph_3d.py +646 -0
  108. package/scripts/health_check.py +163 -26
  109. package/scripts/nt_decrypt.py +3 -3
  110. package/scripts/panel_frames.py +683 -0
  111. package/scripts/pipeline.py +21 -10
  112. package/scripts/quality_eval.py +5 -0
  113. package/scripts/rag_chat.py +33 -16
  114. package/scripts/reply_debt.py +26 -6
  115. package/scripts/semantic_search.py +212 -58
  116. package/scripts/vault_rag.py +42 -16
  117. package/scripts/vault_search.py +44 -8
  118. package/scripts/wechat_emoticon.py +6 -0
  119. package/scripts/wiki_lint.py +94 -17
  120. package/src/core/dbPathService.ts +22 -4
  121. package/src/panel/server.ts +33 -0
  122. package/src/services/assistantService.ts +26 -0
  123. package/src/services/assistantTools.ts +2452 -2319
  124. package/src/services/configService.ts +5 -2
  125. package/src/services/exportService.ts +129 -12
  126. package/src/services/messageQuery.ts +29 -0
  127. package/src/services/wechatClient.ts +380 -0
  128. package/src/services/wechatMedia.ts +166 -0
  129. package/src/services/wechatMessageService.ts +62 -11
  130. package/src/types.ts +4 -0
  131. package/dist/src/utils/wechatEmoji.d.ts +0 -5
  132. package/dist/src/utils/wechatEmoji.d.ts.map +0 -1
  133. package/dist/src/utils/wechatEmoji.js +0 -35
  134. package/dist/src/utils/wechatEmoji.js.map +0 -1
@@ -0,0 +1,35 @@
1
+ 随包发出去的第三方 JS(3D 图谱页面用)
2
+ =====================================
3
+
4
+ 这些文件**不是本仓库写的**,是原样收进来的上游产物。放进仓库的原因只有一个:
5
+ `weflow-cli wiki graph` 要把页面做成**自包含**的(库内联进 HTML,`file://` 双击就能开、
6
+ 不联网、不依赖 CDN)。所以它们随 npm 包一起发,各自的许可证照旧约束各自的使用。
7
+
8
+ three.min.js three.js r147 MIT
9
+ Copyright 2010-2022 Three.js Authors(许可头在该文件里)
10
+ https://github.com/mrdoob/three.js
11
+ d3-dispatch.min.js d3-dispatch ISC
12
+ d3-quadtree.min.js d3-quadtree ISC
13
+ d3-timer.min.js d3-timer ISC
14
+ https://d3js.org(Mike Bostock 等)
15
+ d3-force-3d.min.js d3-force-3d v3.0.6 MIT
16
+ d3-octree.min.js d3-octree MIT
17
+ d3-binarytree.min.js d3-binarytree MIT
18
+ https://github.com/vasturiano(来源写在每个文件第一行)
19
+
20
+ d3-force-3d 的 UMD **不带依赖**:它从全局 `d3` 命名空间取 dispatch / timer / quadtree /
21
+ octree / binarytree,所以上面五个必须按这个顺序先引(`layout.mjs` 与 `graph_3d.py` 里
22
+ 都按这个顺序读)。少一个的报错是 "u.timer is not a function",看着像库坏了,其实只是缺件。
23
+
24
+ 本目录里另外两个文件是**本项目自己的**,不是第三方:`layout.mjs`(构建期算布局的 Node 助手)与
25
+ `viewer2d.js`(2D 版的 canvas 渲染器,会被 `graph_2d.py` 内联进页面)。它们与上面这些库放在一起,
26
+ 是因为布局助手 `new Function` 跑的就是这套 UMD —— 一个在包外、一个在包里最容易漏。2D 页面本身
27
+ **不需要任何库**(布局在构建期做完,渲染是裸 canvas),所以 `graph_2d.py` 只检查 d3 那几个 + 这两个文件。
28
+
29
+ 注意事项:
30
+ - **升级这些文件要一起改两处**:`scripts/graph_3d.py` 的 `LIB_D3` 与
31
+ `resources/js/graph3d/layout.mjs` 的 `LIBS`。两处都要有,因为页面与布局用的是同一套 UMD。
32
+ - `test/graph-3d-cli.test.ts` 会断言这些文件都在、且页面里**没有外部 http 引用** ——
33
+ 换库时别把 CDN 引回来。
34
+ - 3d-force-graph 曾经用过(第一版,2.2 fps),后来换成自己拼 three + d3-force-3d
35
+ (每帧 3~4 次 draw call)。那个 692KB 的捆绑包**没有**收进仓库。
@@ -0,0 +1,2 @@
1
+ // https://github.com/vasturiano/d3-binarytree v1.0.2
2
+ !function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{})}(this,(function(t){"use strict";function r(t,r,e){if(isNaN(r))return t;var n,i,o,s,h,a,u=t._root,f={data:e},l=t._x0,x=t._x1;if(!u)return t._root=f,t;for(;u.length;)if((s=r>=(i=(l+x)/2))?l=i:x=i,n=u,!(u=u[h=+s]))return n[h]=f,t;if(r===(o=+t._x.call(null,u.data)))return f.next=u,n?n[h]=f:t._root=f,t;do{n=n?n[h]=new Array(2):t._root=new Array(2),(s=r>=(i=(l+x)/2))?l=i:x=i}while((h=+s)==(a=+(o>=i)));return n[a]=u,n[h]=f,t}function e(t,r,e){this.node=t,this.x0=r,this.x1=e}function n(t){return t[0]}function i(t,r){var e=new o(null==r?n:r,NaN,NaN);return null==t?e:e.addAll(t)}function o(t,r,e){this._x=t,this._x0=r,this._x1=e,this._root=void 0}function s(t){for(var r={data:t.data},e=r;t=t.next;)e=e.next={data:t.data};return r}var h=i.prototype=o.prototype;h.copy=function(){var t,r,e=new o(this._x,this._x0,this._x1),n=this._root;if(!n)return e;if(!n.length)return e._root=s(n),e;for(t=[{source:n,target:e._root=new Array(2)}];n=t.pop();)for(var i=0;i<2;++i)(r=n.source[i])&&(r.length?t.push({source:r,target:n.target[i]=new Array(2)}):n.target[i]=s(r));return e},h.add=function(t){const e=+this._x.call(null,t);return r(this.cover(e),e,t)},h.addAll=function(t){Array.isArray(t)||(t=Array.from(t));const e=t.length,n=new Float64Array(e);let i=1/0,o=-1/0;for(let r,s=0;s<e;++s)isNaN(r=+this._x.call(null,t[s]))||(n[s]=r,r<i&&(i=r),r>o&&(o=r));if(i>o)return this;this.cover(i).cover(o);for(let i=0;i<e;++i)r(this,n[i],t[i]);return this},h.cover=function(t){if(isNaN(t=+t))return this;var r=this._x0,e=this._x1;if(isNaN(r))e=(r=Math.floor(t))+1;else{for(var n,i,o=e-r||1,s=this._root;r>t||t>=e;)switch(i=+(t<r),(n=new Array(2))[i]=s,s=n,o*=2,i){case 0:e=r+o;break;case 1:r=e-o}this._root&&this._root.length&&(this._root=s)}return this._x0=r,this._x1=e,this},h.data=function(){var t=[];return this.visit((function(r){if(!r.length)do{t.push(r.data)}while(r=r.next)})),t},h.extent=function(t){return arguments.length?this.cover(+t[0][0]).cover(+t[1][0]):isNaN(this._x0)?void 0:[[this._x0],[this._x1]]},h.find=function(t,r){var n,i,o,s,h,a=this._x0,u=this._x1,f=[],l=this._root;for(l&&f.push(new e(l,a,u)),null==r?r=1/0:(a=t-r,u=t+r);s=f.pop();)if(!(!(l=s.node)||(i=s.x0)>u||(o=s.x1)<a))if(l.length){var x=(i+o)/2;f.push(new e(l[1],x,o),new e(l[0],i,x)),(h=+(t>=x))&&(s=f[f.length-1],f[f.length-1]=f[f.length-1-h],f[f.length-1-h]=s)}else{var _=Math.abs(t-+this._x.call(null,l.data));_<r&&(r=_,a=t-_,u=t+_,n=l.data)}return n},h.remove=function(t){if(isNaN(o=+this._x.call(null,t)))return this;var r,e,n,i,o,s,h,a,u,f=this._root,l=this._x0,x=this._x1;if(!f)return this;if(f.length)for(;;){if((h=o>=(s=(l+x)/2))?l=s:x=s,r=f,!(f=f[a=+h]))return this;if(!f.length)break;r[a+1&1]&&(e=r,u=a)}for(;f.data!==t;)if(n=f,!(f=f.next))return this;return(i=f.next)&&delete f.next,n?(i?n.next=i:delete n.next,this):r?(i?r[a]=i:delete r[a],(f=r[0]||r[1])&&f===(r[1]||r[0])&&!f.length&&(e?e[u]=f:this._root=f),this):(this._root=i,this)},h.removeAll=function(t){for(var r=0,e=t.length;r<e;++r)this.remove(t[r]);return this},h.root=function(){return this._root},h.size=function(){var t=0;return this.visit((function(r){if(!r.length)do{++t}while(r=r.next)})),t},h.visit=function(t){var r,n,i,o,s=[],h=this._root;for(h&&s.push(new e(h,this._x0,this._x1));r=s.pop();)if(!t(h=r.node,i=r.x0,o=r.x1)&&h.length){var a=(i+o)/2;(n=h[1])&&s.push(new e(n,a,o)),(n=h[0])&&s.push(new e(n,i,a))}return this},h.visitAfter=function(t){var r,n=[],i=[];for(this._root&&n.push(new e(this._root,this._x0,this._x1));r=n.pop();){var o=r.node;if(o.length){var s,h=r.x0,a=r.x1,u=(h+a)/2;(s=o[0])&&n.push(new e(s,h,u)),(s=o[1])&&n.push(new e(s,u,a))}i.push(r)}for(;r=i.pop();)t(r.node,r.x0,r.x1);return this},h.x=function(t){return arguments.length?(this._x=t,this):this._x},t.binarytree=i}));
@@ -0,0 +1,2 @@
1
+ // https://d3js.org/d3-dispatch/ v3.0.1 Copyright 2010-2021 Mike Bostock
2
+ !function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((n="undefined"!=typeof globalThis?globalThis:n||self).d3=n.d3||{})}(this,(function(n){"use strict";var e={value:()=>{}};function t(){for(var n,e=0,t=arguments.length,o={};e<t;++e){if(!(n=arguments[e]+"")||n in o||/[\s.]/.test(n))throw new Error("illegal type: "+n);o[n]=[]}return new r(o)}function r(n){this._=n}function o(n,e){return n.trim().split(/^|\s+/).map((function(n){var t="",r=n.indexOf(".");if(r>=0&&(t=n.slice(r+1),n=n.slice(0,r)),n&&!e.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:t}}))}function i(n,e){for(var t,r=0,o=n.length;r<o;++r)if((t=n[r]).name===e)return t.value}function f(n,t,r){for(var o=0,i=n.length;o<i;++o)if(n[o].name===t){n[o]=e,n=n.slice(0,o).concat(n.slice(o+1));break}return null!=r&&n.push({name:t,value:r}),n}r.prototype=t.prototype={constructor:r,on:function(n,e){var t,r=this._,l=o(n+"",r),a=-1,u=l.length;if(!(arguments.length<2)){if(null!=e&&"function"!=typeof e)throw new Error("invalid callback: "+e);for(;++a<u;)if(t=(n=l[a]).type)r[t]=f(r[t],n.name,e);else if(null==e)for(t in r)r[t]=f(r[t],n.name,null);return this}for(;++a<u;)if((t=(n=l[a]).type)&&(t=i(r[t],n.name)))return t},copy:function(){var n={},e=this._;for(var t in e)n[t]=e[t].slice();return new r(n)},call:function(n,e){if((t=arguments.length-2)>0)for(var t,r,o=new Array(t),i=0;i<t;++i)o[i]=arguments[i+2];if(!this._.hasOwnProperty(n))throw new Error("unknown type: "+n);for(i=0,t=(r=this._[n]).length;i<t;++i)r[i].value.apply(e,o)},apply:function(n,e,t){if(!this._.hasOwnProperty(n))throw new Error("unknown type: "+n);for(var r=this._[n],o=0,i=r.length;o<i;++o)r[o].value.apply(e,t)}},n.dispatch=t,Object.defineProperty(n,"__esModule",{value:!0})}));
@@ -0,0 +1,2 @@
1
+ // https://github.com/vasturiano/d3-force-3d v3.0.6
2
+ !function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-binarytree"),require("d3-quadtree"),require("d3-octree"),require("d3-dispatch"),require("d3-timer")):"function"==typeof define&&define.amd?define(["exports","d3-binarytree","d3-quadtree","d3-octree","d3-dispatch","d3-timer"],t):t((n="undefined"!=typeof globalThis?globalThis:n||self).d3=n.d3||{},n.d3,n.d3,n.d3,n.d3,n.d3)}(this,(function(n,t,r,e,i,u){"use strict";function o(n){return function(){return n}}function f(n){return 1e-6*(n()-.5)}function a(n){return n.x+n.vx}function c(n){return n.y+n.vy}function l(n){return n.z+n.vz}function h(n){return n.index}function v(n,t){var r=n.get(t);if(!r)throw new Error("node not found: "+t);return r}const d=1664525,y=1013904223,s=4294967296;var g=3;function x(n){return n.x}function z(n){return n.y}function p(n){return n.z}var M=10,w=Math.PI*(3-Math.sqrt(5)),q=20*Math.PI/(9+Math.sqrt(221));n.forceCenter=function(n,t,r){var e,i=1;function u(){var u,o,f=e.length,a=0,c=0,l=0;for(u=0;u<f;++u)a+=(o=e[u]).x||0,c+=o.y||0,l+=o.z||0;for(a=(a/f-n)*i,c=(c/f-t)*i,l=(l/f-r)*i,u=0;u<f;++u)o=e[u],a&&(o.x-=a),c&&(o.y-=c),l&&(o.z-=l)}return null==n&&(n=0),null==t&&(t=0),null==r&&(r=0),u.initialize=function(n){e=n},u.x=function(t){return arguments.length?(n=+t,u):n},u.y=function(n){return arguments.length?(t=+n,u):t},u.z=function(n){return arguments.length?(r=+n,u):r},u.strength=function(n){return arguments.length?(i=+n,u):i},u},n.forceCollide=function(n){var i,u,h,v,d=1,y=1;function s(){for(var n,o,s,x,z,p,M,w,q=i.length,N=0;N<y;++N)for(o=(1===u?t.binarytree(i,a):2===u?r.quadtree(i,a,c):3===u?e.octree(i,a,c,l):null).visitAfter(g),n=0;n<q;++n)s=i[n],M=h[s.index],w=M*M,x=s.x+s.vx,u>1&&(z=s.y+s.vy),u>2&&(p=s.z+s.vz),o.visit(m);function m(n,t,r,e,i,o,a){var c=[t,r,e,i,o,a],l=c[0],h=c[1],y=c[2],g=c[u],q=c[u+1],N=c[u+2],m=n.data,A=n.r,b=M+A;if(!m)return l>x+b||g<x-b||u>1&&(h>z+b||q<z-b)||u>2&&(y>p+b||N<p-b);if(m.index>s.index){var k=x-m.x-m.vx,E=u>1?z-m.y-m.vy:0,j=u>2?p-m.z-m.vz:0,D=k*k+E*E+j*j;D<b*b&&(0===k&&(D+=(k=f(v))*k),u>1&&0===E&&(D+=(E=f(v))*E),u>2&&0===j&&(D+=(j=f(v))*j),D=(b-(D=Math.sqrt(D)))/D*d,s.vx+=(k*=D)*(b=(A*=A)/(w+A)),u>1&&(s.vy+=(E*=D)*b),u>2&&(s.vz+=(j*=D)*b),m.vx-=k*(b=1-b),u>1&&(m.vy-=E*b),u>2&&(m.vz-=j*b))}}}function g(n){if(n.data)return n.r=h[n.data.index];for(var t=n.r=0;t<Math.pow(2,u);++t)n[t]&&n[t].r>n.r&&(n.r=n[t].r)}function x(){if(i){var t,r,e=i.length;for(h=new Array(e),t=0;t<e;++t)r=i[t],h[r.index]=+n(r,t,i)}}return"function"!=typeof n&&(n=o(null==n?1:+n)),s.initialize=function(n,...t){i=n,v=t.find((n=>"function"==typeof n))||Math.random,u=t.find((n=>[1,2,3].includes(n)))||2,x()},s.iterations=function(n){return arguments.length?(y=+n,s):y},s.strength=function(n){return arguments.length?(d=+n,s):d},s.radius=function(t){return arguments.length?(n="function"==typeof t?t:o(+t),x(),s):n},s},n.forceLink=function(n){var t,r,e,i,u,a,c,l=h,d=function(n){return 1/Math.min(u[n.source.index],u[n.target.index])},y=o(30),s=1;function g(e){for(var u=0,o=n.length;u<s;++u)for(var l,h,v,d,y,g=0,x=0,z=0,p=0;g<o;++g)h=(l=n[g]).source,x=(v=l.target).x+v.vx-h.x-h.vx||f(c),i>1&&(z=v.y+v.vy-h.y-h.vy||f(c)),i>2&&(p=v.z+v.vz-h.z-h.vz||f(c)),x*=d=((d=Math.sqrt(x*x+z*z+p*p))-r[g])/d*e*t[g],z*=d,p*=d,v.vx-=x*(y=a[g]),i>1&&(v.vy-=z*y),i>2&&(v.vz-=p*y),h.vx+=x*(y=1-y),i>1&&(h.vy+=z*y),i>2&&(h.vz+=p*y)}function x(){if(e){var i,o,f=e.length,c=n.length,h=new Map(e.map(((n,t)=>[l(n,t,e),n])));for(i=0,u=new Array(f);i<c;++i)(o=n[i]).index=i,"object"!=typeof o.source&&(o.source=v(h,o.source)),"object"!=typeof o.target&&(o.target=v(h,o.target)),u[o.source.index]=(u[o.source.index]||0)+1,u[o.target.index]=(u[o.target.index]||0)+1;for(i=0,a=new Array(c);i<c;++i)o=n[i],a[i]=u[o.source.index]/(u[o.source.index]+u[o.target.index]);t=new Array(c),z(),r=new Array(c),p()}}function z(){if(e)for(var r=0,i=n.length;r<i;++r)t[r]=+d(n[r],r,n)}function p(){if(e)for(var t=0,i=n.length;t<i;++t)r[t]=+y(n[t],t,n)}return null==n&&(n=[]),g.initialize=function(n,...t){e=n,c=t.find((n=>"function"==typeof n))||Math.random,i=t.find((n=>[1,2,3].includes(n)))||2,x()},g.links=function(t){return arguments.length?(n=t,x(),g):n},g.id=function(n){return arguments.length?(l=n,g):l},g.iterations=function(n){return arguments.length?(s=+n,g):s},g.strength=function(n){return arguments.length?(d="function"==typeof n?n:o(+n),z(),g):d},g.distance=function(n){return arguments.length?(y="function"==typeof n?n:o(+n),p(),g):y},g},n.forceManyBody=function(){var n,i,u,a,c,l,h=o(-30),v=1,d=1/0,y=.81;function s(o){var f,a=n.length,l=(1===i?t.binarytree(n,x):2===i?r.quadtree(n,x,z):3===i?e.octree(n,x,z,p):null).visitAfter(M);for(c=o,f=0;f<a;++f)u=n[f],l.visit(w)}function g(){if(n){var t,r,e=n.length;for(l=new Array(e),t=0;t<e;++t)r=n[t],l[r.index]=+h(r,t,n)}}function M(n){var t,r,e,u,o,f,a=0,c=0,h=n.length;if(h){for(e=u=o=f=0;f<h;++f)(t=n[f])&&(r=Math.abs(t.value))&&(a+=t.value,c+=r,e+=r*(t.x||0),u+=r*(t.y||0),o+=r*(t.z||0));a*=Math.sqrt(4/h),n.x=e/c,i>1&&(n.y=u/c),i>2&&(n.z=o/c)}else{(t=n).x=t.data.x,i>1&&(t.y=t.data.y),i>2&&(t.z=t.data.z);do{a+=l[t.data.index]}while(t=t.next)}n.value=a}function w(n,t,r,e,o){if(!n.value)return!0;var h=[r,e,o][i-1],s=n.x-u.x,g=i>1?n.y-u.y:0,x=i>2?n.z-u.z:0,z=h-t,p=s*s+g*g+x*x;if(z*z/y<p)return p<d&&(0===s&&(p+=(s=f(a))*s),i>1&&0===g&&(p+=(g=f(a))*g),i>2&&0===x&&(p+=(x=f(a))*x),p<v&&(p=Math.sqrt(v*p)),u.vx+=s*n.value*c/p,i>1&&(u.vy+=g*n.value*c/p),i>2&&(u.vz+=x*n.value*c/p)),!0;if(!(n.length||p>=d)){(n.data!==u||n.next)&&(0===s&&(p+=(s=f(a))*s),i>1&&0===g&&(p+=(g=f(a))*g),i>2&&0===x&&(p+=(x=f(a))*x),p<v&&(p=Math.sqrt(v*p)));do{n.data!==u&&(z=l[n.data.index]*c/p,u.vx+=s*z,i>1&&(u.vy+=g*z),i>2&&(u.vz+=x*z))}while(n=n.next)}}return s.initialize=function(t,...r){n=t,a=r.find((n=>"function"==typeof n))||Math.random,i=r.find((n=>[1,2,3].includes(n)))||2,g()},s.strength=function(n){return arguments.length?(h="function"==typeof n?n:o(+n),g(),s):h},s.distanceMin=function(n){return arguments.length?(v=n*n,s):Math.sqrt(v)},s.distanceMax=function(n){return arguments.length?(d=n*n,s):Math.sqrt(d)},s.theta=function(n){return arguments.length?(y=n*n,s):Math.sqrt(y)},s},n.forceRadial=function(n,t,r,e){var i,u,f,a,c=o(.1);function l(n){for(var o=0,c=i.length;o<c;++o){var l=i[o],h=l.x-t||1e-6,v=(l.y||0)-r||1e-6,d=(l.z||0)-e||1e-6,y=Math.sqrt(h*h+v*v+d*d),s=(a[o]-y)*f[o]*n/y;l.vx+=h*s,u>1&&(l.vy+=v*s),u>2&&(l.vz+=d*s)}}function h(){if(i){var t,r=i.length;for(f=new Array(r),a=new Array(r),t=0;t<r;++t)a[t]=+n(i[t],t,i),f[t]=isNaN(a[t])?0:+c(i[t],t,i)}}return"function"!=typeof n&&(n=o(+n)),null==t&&(t=0),null==r&&(r=0),null==e&&(e=0),l.initialize=function(n,...t){i=n,u=t.find((n=>[1,2,3].includes(n)))||2,h()},l.strength=function(n){return arguments.length?(c="function"==typeof n?n:o(+n),h(),l):c},l.radius=function(t){return arguments.length?(n="function"==typeof t?t:o(+t),h(),l):n},l.x=function(n){return arguments.length?(t=+n,l):t},l.y=function(n){return arguments.length?(r=+n,l):r},l.z=function(n){return arguments.length?(e=+n,l):e},l},n.forceSimulation=function(n,t){t=t||2;var r,e=Math.min(g,Math.max(1,Math.round(t))),o=1,f=.001,a=1-Math.pow(f,1/300),c=0,l=.6,h=new Map,v=u.timer(p),x=i.dispatch("tick","end"),z=function(){let n=1;return()=>(n=(d*n+y)%s)/s}();function p(){N(),x.call("tick",r),o<f&&(v.stop(),x.call("end",r))}function N(t){var i,u,f=n.length;void 0===t&&(t=1);for(var v=0;v<t;++v)for(o+=(c-o)*a,h.forEach((function(n){n(o)})),i=0;i<f;++i)null==(u=n[i]).fx?u.x+=u.vx*=l:(u.x=u.fx,u.vx=0),e>1&&(null==u.fy?u.y+=u.vy*=l:(u.y=u.fy,u.vy=0)),e>2&&(null==u.fz?u.z+=u.vz*=l:(u.z=u.fz,u.vz=0));return r}function m(){for(var t,r=0,i=n.length;r<i;++r){if((t=n[r]).index=r,null!=t.fx&&(t.x=t.fx),null!=t.fy&&(t.y=t.fy),null!=t.fz&&(t.z=t.fz),isNaN(t.x)||e>1&&isNaN(t.y)||e>2&&isNaN(t.z)){var u=M*(e>2?Math.cbrt(.5+r):e>1?Math.sqrt(.5+r):r),o=r*w,f=r*q;1===e?t.x=u:2===e?(t.x=u*Math.cos(o),t.y=u*Math.sin(o)):(t.x=u*Math.sin(o)*Math.cos(f),t.y=u*Math.cos(o),t.z=u*Math.sin(o)*Math.sin(f))}(isNaN(t.vx)||e>1&&isNaN(t.vy)||e>2&&isNaN(t.vz))&&(t.vx=0,e>1&&(t.vy=0),e>2&&(t.vz=0))}}function A(t){return t.initialize&&t.initialize(n,z,e),t}return null==n&&(n=[]),m(),r={tick:N,restart:function(){return v.restart(p),r},stop:function(){return v.stop(),r},numDimensions:function(n){return arguments.length?(e=Math.min(g,Math.max(1,Math.round(n))),h.forEach(A),r):e},nodes:function(t){return arguments.length?(n=t,m(),h.forEach(A),r):n},alpha:function(n){return arguments.length?(o=+n,r):o},alphaMin:function(n){return arguments.length?(f=+n,r):f},alphaDecay:function(n){return arguments.length?(a=+n,r):+a},alphaTarget:function(n){return arguments.length?(c=+n,r):c},velocityDecay:function(n){return arguments.length?(l=1-n,r):1-l},randomSource:function(n){return arguments.length?(z=n,h.forEach(A),r):z},force:function(n,t){return arguments.length>1?(null==t?h.delete(n):h.set(n,A(t)),r):h.get(n)},find:function(){var t,r,i,u,o,f,a=Array.prototype.slice.call(arguments),c=a.shift()||0,l=(e>1?a.shift():null)||0,h=(e>2?a.shift():null)||0,v=a.shift()||1/0,d=0,y=n.length;for(v*=v,d=0;d<y;++d)(u=(t=c-(o=n[d]).x)*t+(r=l-(o.y||0))*r+(i=h-(o.z||0))*i)<v&&(f=o,v=u);return f},on:function(n,t){return arguments.length>1?(x.on(n,t),r):x.on(n)}}},n.forceX=function(n){var t,r,e,i=o(.1);function u(n){for(var i,u=0,o=t.length;u<o;++u)(i=t[u]).vx+=(e[u]-i.x)*r[u]*n}function f(){if(t){var u,o=t.length;for(r=new Array(o),e=new Array(o),u=0;u<o;++u)r[u]=isNaN(e[u]=+n(t[u],u,t))?0:+i(t[u],u,t)}}return"function"!=typeof n&&(n=o(null==n?0:+n)),u.initialize=function(n){t=n,f()},u.strength=function(n){return arguments.length?(i="function"==typeof n?n:o(+n),f(),u):i},u.x=function(t){return arguments.length?(n="function"==typeof t?t:o(+t),f(),u):n},u},n.forceY=function(n){var t,r,e,i=o(.1);function u(n){for(var i,u=0,o=t.length;u<o;++u)(i=t[u]).vy+=(e[u]-i.y)*r[u]*n}function f(){if(t){var u,o=t.length;for(r=new Array(o),e=new Array(o),u=0;u<o;++u)r[u]=isNaN(e[u]=+n(t[u],u,t))?0:+i(t[u],u,t)}}return"function"!=typeof n&&(n=o(null==n?0:+n)),u.initialize=function(n){t=n,f()},u.strength=function(n){return arguments.length?(i="function"==typeof n?n:o(+n),f(),u):i},u.y=function(t){return arguments.length?(n="function"==typeof t?t:o(+t),f(),u):n},u},n.forceZ=function(n){var t,r,e,i=o(.1);function u(n){for(var i,u=0,o=t.length;u<o;++u)(i=t[u]).vz+=(e[u]-i.z)*r[u]*n}function f(){if(t){var u,o=t.length;for(r=new Array(o),e=new Array(o),u=0;u<o;++u)r[u]=isNaN(e[u]=+n(t[u],u,t))?0:+i(t[u],u,t)}}return"function"!=typeof n&&(n=o(null==n?0:+n)),u.initialize=function(n){t=n,f()},u.strength=function(n){return arguments.length?(i="function"==typeof n?n:o(+n),f(),u):i},u.z=function(t){return arguments.length?(n="function"==typeof t?t:o(+t),f(),u):n},u}}));
@@ -0,0 +1,2 @@
1
+ // https://github.com/vasturiano/d3-octree v1.1.0
2
+ !function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{})}(this,(function(t){"use strict";function i(t,i,n,s,e){if(isNaN(i)||isNaN(n)||isNaN(s))return t;var h,r,o,a,l,u,_,f,c,y,x,d,p=t._root,w={data:e},z=t._x0,N=t._y0,v=t._z0,g=t._x1,A=t._y1,b=t._z1;if(!p)return t._root=w,t;for(;p.length;)if((f=i>=(r=(z+g)/2))?z=r:g=r,(c=n>=(o=(N+A)/2))?N=o:A=o,(y=s>=(a=(v+b)/2))?v=a:b=a,h=p,!(p=p[x=y<<2|c<<1|f]))return h[x]=w,t;if(l=+t._x.call(null,p.data),u=+t._y.call(null,p.data),_=+t._z.call(null,p.data),i===l&&n===u&&s===_)return w.next=p,h?h[x]=w:t._root=w,t;do{h=h?h[x]=new Array(8):t._root=new Array(8),(f=i>=(r=(z+g)/2))?z=r:g=r,(c=n>=(o=(N+A)/2))?N=o:A=o,(y=s>=(a=(v+b)/2))?v=a:b=a}while((x=y<<2|c<<1|f)==(d=(_>=a)<<2|(u>=o)<<1|l>=r));return h[d]=p,h[x]=w,t}function n(t,i,n,s,e,h,r){this.node=t,this.x0=i,this.y0=n,this.z0=s,this.x1=e,this.y1=h,this.z1=r}const s=(t,i,n,s,e,h)=>Math.sqrt((t-s)**2+(i-e)**2+(n-h)**2);function e(t){return t[0]}function h(t){return t[1]}function r(t){return t[2]}function o(t,i,n,s){var o=new a(null==i?e:i,null==n?h:n,null==s?r:s,NaN,NaN,NaN,NaN,NaN,NaN);return null==t?o:o.addAll(t)}function a(t,i,n,s,e,h,r,o,a){this._x=t,this._y=i,this._z=n,this._x0=s,this._y0=e,this._z0=h,this._x1=r,this._y1=o,this._z1=a,this._root=void 0}function l(t){for(var i={data:t.data},n=i;t=t.next;)n=n.next={data:t.data};return i}var u=o.prototype=a.prototype;u.copy=function(){var t,i,n=new a(this._x,this._y,this._z,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1),s=this._root;if(!s)return n;if(!s.length)return n._root=l(s),n;for(t=[{source:s,target:n._root=new Array(8)}];s=t.pop();)for(var e=0;e<8;++e)(i=s.source[e])&&(i.length?t.push({source:i,target:s.target[e]=new Array(8)}):s.target[e]=l(i));return n},u.add=function(t){const n=+this._x.call(null,t),s=+this._y.call(null,t),e=+this._z.call(null,t);return i(this.cover(n,s,e),n,s,e,t)},u.addAll=function(t){Array.isArray(t)||(t=Array.from(t));const n=t.length,s=new Float64Array(n),e=new Float64Array(n),h=new Float64Array(n);let r=1/0,o=1/0,a=1/0,l=-1/0,u=-1/0,_=-1/0;for(let i,f,c,y,x=0;x<n;++x)isNaN(f=+this._x.call(null,i=t[x]))||isNaN(c=+this._y.call(null,i))||isNaN(y=+this._z.call(null,i))||(s[x]=f,e[x]=c,h[x]=y,f<r&&(r=f),f>l&&(l=f),c<o&&(o=c),c>u&&(u=c),y<a&&(a=y),y>_&&(_=y));if(r>l||o>u||a>_)return this;this.cover(r,o,a).cover(l,u,_);for(let r=0;r<n;++r)i(this,s[r],e[r],h[r],t[r]);return this},u.cover=function(t,i,n){if(isNaN(t=+t)||isNaN(i=+i)||isNaN(n=+n))return this;var s=this._x0,e=this._y0,h=this._z0,r=this._x1,o=this._y1,a=this._z1;if(isNaN(s))r=(s=Math.floor(t))+1,o=(e=Math.floor(i))+1,a=(h=Math.floor(n))+1;else{for(var l,u,_=r-s||1,f=this._root;s>t||t>=r||e>i||i>=o||h>n||n>=a;)switch(u=(n<h)<<2|(i<e)<<1|t<s,(l=new Array(8))[u]=f,f=l,_*=2,u){case 0:r=s+_,o=e+_,a=h+_;break;case 1:s=r-_,o=e+_,a=h+_;break;case 2:r=s+_,e=o-_,a=h+_;break;case 3:s=r-_,e=o-_,a=h+_;break;case 4:r=s+_,o=e+_,h=a-_;break;case 5:s=r-_,o=e+_,h=a-_;break;case 6:r=s+_,e=o-_,h=a-_;break;case 7:s=r-_,e=o-_,h=a-_}this._root&&this._root.length&&(this._root=f)}return this._x0=s,this._y0=e,this._z0=h,this._x1=r,this._y1=o,this._z1=a,this},u.data=function(){var t=[];return this.visit((function(i){if(!i.length)do{t.push(i.data)}while(i=i.next)})),t},u.extent=function(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]]},u.find=function(t,i,s,e){var h,r,o,a,l,u,_,f,c,y=this._x0,x=this._y0,d=this._z0,p=this._x1,w=this._y1,z=this._z1,N=[],v=this._root;for(v&&N.push(new n(v,y,x,d,p,w,z)),null==e?e=1/0:(y=t-e,x=i-e,d=s-e,p=t+e,w=i+e,z=s+e,e*=e);f=N.pop();)if(!(!(v=f.node)||(r=f.x0)>p||(o=f.y0)>w||(a=f.z0)>z||(l=f.x1)<y||(u=f.y1)<x||(_=f.z1)<d))if(v.length){var g=(r+l)/2,A=(o+u)/2,b=(a+_)/2;N.push(new n(v[7],g,A,b,l,u,_),new n(v[6],r,A,b,g,u,_),new n(v[5],g,o,b,l,A,_),new n(v[4],r,o,b,g,A,_),new n(v[3],g,A,a,l,u,b),new n(v[2],r,A,a,g,u,b),new n(v[1],g,o,a,l,A,b),new n(v[0],r,o,a,g,A,b)),(c=(s>=b)<<2|(i>=A)<<1|t>=g)&&(f=N[N.length-1],N[N.length-1]=N[N.length-1-c],N[N.length-1-c]=f)}else{var k=t-+this._x.call(null,v.data),m=i-+this._y.call(null,v.data),M=s-+this._z.call(null,v.data),F=k*k+m*m+M*M;if(F<e){var q=Math.sqrt(e=F);y=t-q,x=i-q,d=s-q,p=t+q,w=i+q,z=s+q,h=v.data}}return h},u.findAllWithinRadius=function(t,i,n,e){const h=[],r=t-e,o=i-e,a=n-e,l=t+e,u=i+e,_=n+e;return this.visit(((f,c,y,x,d,p,w)=>{if(!f.length)do{const r=f.data;s(t,i,n,this._x(r),this._y(r),this._z(r))<=e&&h.push(r)}while(f=f.next);return c>l||y>u||x>_||d<r||p<o||w<a})),h},u.remove=function(t){if(isNaN(h=+this._x.call(null,t))||isNaN(r=+this._y.call(null,t))||isNaN(o=+this._z.call(null,t)))return this;var i,n,s,e,h,r,o,a,l,u,_,f,c,y,x,d=this._root,p=this._x0,w=this._y0,z=this._z0,N=this._x1,v=this._y1,g=this._z1;if(!d)return this;if(d.length)for(;;){if((_=h>=(a=(p+N)/2))?p=a:N=a,(f=r>=(l=(w+v)/2))?w=l:v=l,(c=o>=(u=(z+g)/2))?z=u:g=u,i=d,!(d=d[y=c<<2|f<<1|_]))return this;if(!d.length)break;(i[y+1&7]||i[y+2&7]||i[y+3&7]||i[y+4&7]||i[y+5&7]||i[y+6&7]||i[y+7&7])&&(n=i,x=y)}for(;d.data!==t;)if(s=d,!(d=d.next))return this;return(e=d.next)&&delete d.next,s?(e?s.next=e:delete s.next,this):i?(e?i[y]=e:delete i[y],(d=i[0]||i[1]||i[2]||i[3]||i[4]||i[5]||i[6]||i[7])&&d===(i[7]||i[6]||i[5]||i[4]||i[3]||i[2]||i[1]||i[0])&&!d.length&&(n?n[x]=d:this._root=d),this):(this._root=e,this)},u.removeAll=function(t){for(var i=0,n=t.length;i<n;++i)this.remove(t[i]);return this},u.root=function(){return this._root},u.size=function(){var t=0;return this.visit((function(i){if(!i.length)do{++t}while(i=i.next)})),t},u.visit=function(t){var i,s,e,h,r,o,a,l,u=[],_=this._root;for(_&&u.push(new n(_,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1));i=u.pop();)if(!t(_=i.node,e=i.x0,h=i.y0,r=i.z0,o=i.x1,a=i.y1,l=i.z1)&&_.length){var f=(e+o)/2,c=(h+a)/2,y=(r+l)/2;(s=_[7])&&u.push(new n(s,f,c,y,o,a,l)),(s=_[6])&&u.push(new n(s,e,c,y,f,a,l)),(s=_[5])&&u.push(new n(s,f,h,y,o,c,l)),(s=_[4])&&u.push(new n(s,e,h,y,f,c,l)),(s=_[3])&&u.push(new n(s,f,c,r,o,a,y)),(s=_[2])&&u.push(new n(s,e,c,r,f,a,y)),(s=_[1])&&u.push(new n(s,f,h,r,o,c,y)),(s=_[0])&&u.push(new n(s,e,h,r,f,c,y))}return this},u.visitAfter=function(t){var i,s=[],e=[];for(this._root&&s.push(new n(this._root,this._x0,this._y0,this._z0,this._x1,this._y1,this._z1));i=s.pop();){var h=i.node;if(h.length){var r,o=i.x0,a=i.y0,l=i.z0,u=i.x1,_=i.y1,f=i.z1,c=(o+u)/2,y=(a+_)/2,x=(l+f)/2;(r=h[0])&&s.push(new n(r,o,a,l,c,y,x)),(r=h[1])&&s.push(new n(r,c,a,l,u,y,x)),(r=h[2])&&s.push(new n(r,o,y,l,c,_,x)),(r=h[3])&&s.push(new n(r,c,y,l,u,_,x)),(r=h[4])&&s.push(new n(r,o,a,x,c,y,f)),(r=h[5])&&s.push(new n(r,c,a,x,u,y,f)),(r=h[6])&&s.push(new n(r,o,y,x,c,_,f)),(r=h[7])&&s.push(new n(r,c,y,x,u,_,f))}e.push(i)}for(;i=e.pop();)t(i.node,i.x0,i.y0,i.z0,i.x1,i.y1,i.z1);return this},u.x=function(t){return arguments.length?(this._x=t,this):this._x},u.y=function(t){return arguments.length?(this._y=t,this):this._y},u.z=function(t){return arguments.length?(this._z=t,this):this._z},t.octree=o}));
@@ -0,0 +1,2 @@
1
+ // https://d3js.org/d3-quadtree/ v3.0.1 Copyright 2010-2021 Mike Bostock
2
+ !function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{})}(this,(function(t){"use strict";function i(t,i,e,n){if(isNaN(i)||isNaN(e))return t;var r,s,h,o,a,u,l,_,f,c=t._root,x={data:n},y=t._x0,d=t._y0,p=t._x1,v=t._y1;if(!c)return t._root=x,t;for(;c.length;)if((u=i>=(s=(y+p)/2))?y=s:p=s,(l=e>=(h=(d+v)/2))?d=h:v=h,r=c,!(c=c[_=l<<1|u]))return r[_]=x,t;if(o=+t._x.call(null,c.data),a=+t._y.call(null,c.data),i===o&&e===a)return x.next=c,r?r[_]=x:t._root=x,t;do{r=r?r[_]=new Array(4):t._root=new Array(4),(u=i>=(s=(y+p)/2))?y=s:p=s,(l=e>=(h=(d+v)/2))?d=h:v=h}while((_=l<<1|u)==(f=(a>=h)<<1|o>=s));return r[f]=c,r[_]=x,t}function e(t,i,e,n,r){this.node=t,this.x0=i,this.y0=e,this.x1=n,this.y1=r}function n(t){return t[0]}function r(t){return t[1]}function s(t,i,e){var s=new h(null==i?n:i,null==e?r:e,NaN,NaN,NaN,NaN);return null==t?s:s.addAll(t)}function h(t,i,e,n,r,s){this._x=t,this._y=i,this._x0=e,this._y0=n,this._x1=r,this._y1=s,this._root=void 0}function o(t){for(var i={data:t.data},e=i;t=t.next;)e=e.next={data:t.data};return i}var a=s.prototype=h.prototype;a.copy=function(){var t,i,e=new h(this._x,this._y,this._x0,this._y0,this._x1,this._y1),n=this._root;if(!n)return e;if(!n.length)return e._root=o(n),e;for(t=[{source:n,target:e._root=new Array(4)}];n=t.pop();)for(var r=0;r<4;++r)(i=n.source[r])&&(i.length?t.push({source:i,target:n.target[r]=new Array(4)}):n.target[r]=o(i));return e},a.add=function(t){const e=+this._x.call(null,t),n=+this._y.call(null,t);return i(this.cover(e,n),e,n,t)},a.addAll=function(t){var e,n,r,s,h=t.length,o=new Array(h),a=new Array(h),u=1/0,l=1/0,_=-1/0,f=-1/0;for(n=0;n<h;++n)isNaN(r=+this._x.call(null,e=t[n]))||isNaN(s=+this._y.call(null,e))||(o[n]=r,a[n]=s,r<u&&(u=r),r>_&&(_=r),s<l&&(l=s),s>f&&(f=s));if(u>_||l>f)return this;for(this.cover(u,l).cover(_,f),n=0;n<h;++n)i(this,o[n],a[n],t[n]);return this},a.cover=function(t,i){if(isNaN(t=+t)||isNaN(i=+i))return this;var e=this._x0,n=this._y0,r=this._x1,s=this._y1;if(isNaN(e))r=(e=Math.floor(t))+1,s=(n=Math.floor(i))+1;else{for(var h,o,a=r-e||1,u=this._root;e>t||t>=r||n>i||i>=s;)switch(o=(i<n)<<1|t<e,(h=new Array(4))[o]=u,u=h,a*=2,o){case 0:r=e+a,s=n+a;break;case 1:e=r-a,s=n+a;break;case 2:r=e+a,n=s-a;break;case 3:e=r-a,n=s-a}this._root&&this._root.length&&(this._root=u)}return this._x0=e,this._y0=n,this._x1=r,this._y1=s,this},a.data=function(){var t=[];return this.visit((function(i){if(!i.length)do{t.push(i.data)}while(i=i.next)})),t},a.extent=function(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]]},a.find=function(t,i,n){var r,s,h,o,a,u,l,_=this._x0,f=this._y0,c=this._x1,x=this._y1,y=[],d=this._root;for(d&&y.push(new e(d,_,f,c,x)),null==n?n=1/0:(_=t-n,f=i-n,c=t+n,x=i+n,n*=n);u=y.pop();)if(!(!(d=u.node)||(s=u.x0)>c||(h=u.y0)>x||(o=u.x1)<_||(a=u.y1)<f))if(d.length){var p=(s+o)/2,v=(h+a)/2;y.push(new e(d[3],p,v,o,a),new e(d[2],s,v,p,a),new e(d[1],p,h,o,v),new e(d[0],s,h,p,v)),(l=(i>=v)<<1|t>=p)&&(u=y[y.length-1],y[y.length-1]=y[y.length-1-l],y[y.length-1-l]=u)}else{var w=t-+this._x.call(null,d.data),N=i-+this._y.call(null,d.data),g=w*w+N*N;if(g<n){var A=Math.sqrt(n=g);_=t-A,f=i-A,c=t+A,x=i+A,r=d.data}}return r},a.remove=function(t){if(isNaN(s=+this._x.call(null,t))||isNaN(h=+this._y.call(null,t)))return this;var i,e,n,r,s,h,o,a,u,l,_,f,c=this._root,x=this._x0,y=this._y0,d=this._x1,p=this._y1;if(!c)return this;if(c.length)for(;;){if((u=s>=(o=(x+d)/2))?x=o:d=o,(l=h>=(a=(y+p)/2))?y=a:p=a,i=c,!(c=c[_=l<<1|u]))return this;if(!c.length)break;(i[_+1&3]||i[_+2&3]||i[_+3&3])&&(e=i,f=_)}for(;c.data!==t;)if(n=c,!(c=c.next))return this;return(r=c.next)&&delete c.next,n?(r?n.next=r:delete n.next,this):i?(r?i[_]=r:delete i[_],(c=i[0]||i[1]||i[2]||i[3])&&c===(i[3]||i[2]||i[1]||i[0])&&!c.length&&(e?e[f]=c:this._root=c),this):(this._root=r,this)},a.removeAll=function(t){for(var i=0,e=t.length;i<e;++i)this.remove(t[i]);return this},a.root=function(){return this._root},a.size=function(){var t=0;return this.visit((function(i){if(!i.length)do{++t}while(i=i.next)})),t},a.visit=function(t){var i,n,r,s,h,o,a=[],u=this._root;for(u&&a.push(new e(u,this._x0,this._y0,this._x1,this._y1));i=a.pop();)if(!t(u=i.node,r=i.x0,s=i.y0,h=i.x1,o=i.y1)&&u.length){var l=(r+h)/2,_=(s+o)/2;(n=u[3])&&a.push(new e(n,l,_,h,o)),(n=u[2])&&a.push(new e(n,r,_,l,o)),(n=u[1])&&a.push(new e(n,l,s,h,_)),(n=u[0])&&a.push(new e(n,r,s,l,_))}return this},a.visitAfter=function(t){var i,n=[],r=[];for(this._root&&n.push(new e(this._root,this._x0,this._y0,this._x1,this._y1));i=n.pop();){var s=i.node;if(s.length){var h,o=i.x0,a=i.y0,u=i.x1,l=i.y1,_=(o+u)/2,f=(a+l)/2;(h=s[0])&&n.push(new e(h,o,a,_,f)),(h=s[1])&&n.push(new e(h,_,a,u,f)),(h=s[2])&&n.push(new e(h,o,f,_,l)),(h=s[3])&&n.push(new e(h,_,f,u,l))}r.push(i)}for(;i=r.pop();)t(i.node,i.x0,i.y0,i.x1,i.y1);return this},a.x=function(t){return arguments.length?(this._x=t,this):this._x},a.y=function(t){return arguments.length?(this._y=t,this):this._y},t.quadtree=s,Object.defineProperty(t,"__esModule",{value:!0})}));
@@ -0,0 +1,2 @@
1
+ // https://d3js.org/d3-timer/ v3.0.1 Copyright 2010-2021 Mike Bostock
2
+ !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{})}(this,(function(t){"use strict";var n,e,o=0,i=0,r=0,l=0,u=0,a=0,s="object"==typeof performance&&performance.now?performance:Date,c="object"==typeof window&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};function f(){return u||(c(_),u=s.now()+a)}function _(){u=0}function m(){this._call=this._time=this._next=null}function p(t,n,e){var o=new m;return o.restart(t,n,e),o}function w(){f(),++o;for(var t,e=n;e;)(t=u-e._time)>=0&&e._call.call(void 0,t),e=e._next;--o}function d(){u=(l=s.now())+a,o=i=0;try{w()}finally{o=0,function(){var t,o,i=n,r=1/0;for(;i;)i._call?(r>i._time&&(r=i._time),t=i,i=i._next):(o=i._next,i._next=null,i=t?t._next=o:n=o);e=t,y(r)}(),u=0}}function h(){var t=s.now(),n=t-l;n>1e3&&(a-=n,l=t)}function y(t){o||(i&&(i=clearTimeout(i)),t-u>24?(t<1/0&&(i=setTimeout(d,t-s.now()-a)),r&&(r=clearInterval(r))):(r||(l=s.now(),r=setInterval(h,1e3)),o=1,c(d)))}m.prototype=p.prototype={constructor:m,restart:function(t,o,i){if("function"!=typeof t)throw new TypeError("callback is not a function");i=(null==i?f():+i)+(null==o?0:+o),this._next||e===this||(e?e._next=this:n=this,e=this),this._call=t,this._time=i,y()},stop:function(){this._call&&(this._call=null,this._time=1/0,y())}},t.interval=function(t,n,e){var o=new m,i=n;return null==n?(o.restart(t,n,e),o):(o._restart=o.restart,o.restart=function(t,n,e){n=+n,e=null==e?f():+e,o._restart((function r(l){l+=i,o._restart(r,i+=n,e),t(l)}),n,e)},o.restart(t,n,e),o)},t.now=f,t.timeout=function(t,n,e){var o=new m;return n=null==n?0:+n,o.restart((e=>{o.stop(),t(e+n)}),n,e),o},t.timer=p,t.timerFlush=w,Object.defineProperty(t,"__esModule",{value:!0})}));
@@ -0,0 +1,63 @@
1
+ // 在 Node 里把 3D 布局算好,坐标交给 scripts/graph_3d.py 内联进页面。
2
+ //
3
+ // 为什么不在浏览器里算:25,431 个点跑 90 tick 实测要 **15.9 秒**,每次打开页面都要等一遍。
4
+ // 布局只跟图有关、跟窗口无关,所以算一次存下来最合适 —— 打开即用。
5
+ //
6
+ // 这里不装 npm 包:d3-force-3d 的 UMD 就是浏览器分支(挂 globalThis.d3),
7
+ // 用 new Function 跑一遍就得到同一个 d3,省掉 node_modules。
8
+ //
9
+ // 用法:node layout.mjs <缓存目录> <库目录> [tick] [digest] [dims]
10
+ //
11
+ // `dims=2` 走 2D 力导向(`forceCenter(0,0)`):**不是把 3D 的 x/y 拍扁** —— 那一维也承载结构,
12
+ // 拍扁会把两团本不相干的点叠在一起。2D 的解也更省(快的不是一个量级),所以同一张图重算得起。
13
+ //
14
+ // **路径一律走参数**:这个文件原来住在 output/_3d/ 里,并且写死了某台机器的绝对路径。
15
+ // 搬进仓库时一并改掉 —— 仓库里的代码不许出现用户的真实路径。
16
+ import { readFileSync, writeFileSync } from 'node:fs'
17
+
18
+ const [cacheDir, libDir, ticksArg, digest, dimsArg, paramsArg] = process.argv.slice(2)
19
+ if (!cacheDir || !libDir) {
20
+ console.error('用法:node layout.mjs <缓存目录> <库目录> [tick] [digest] [dims] [params-json]')
21
+ process.exit(2)
22
+ }
23
+ const DIMS = Number(dimsArg || 3) === 2 ? 2 : 3
24
+ // digest 是图内容的哈希(含维度):核心图与全量图、2D 与 3D 各存一份坐标
25
+ // (见 graph_3d.py / graph_2d.py 里那段注释)
26
+ const suffix = digest ? `-${digest}` : ''
27
+ const IN = `${cacheDir}/graph${suffix}.json`
28
+ const OUT = `${cacheDir}/positions${suffix}.json`
29
+ const TICKS = Number(ticksArg || 250)
30
+
31
+ const LIBS = ['d3-dispatch.min.js', 'd3-timer.min.js', 'd3-quadtree.min.js',
32
+ 'd3-binarytree.min.js', 'd3-octree.min.js', 'd3-force-3d.min.js']
33
+ const code = LIBS.map((f) => readFileSync(`${libDir}/${f}`, 'utf8')).join('\n')
34
+ new Function(code)()
35
+ const d3 = globalThis.d3
36
+ if (!d3?.forceSimulation) {
37
+ console.error('d3 没挂上 globalThis,检查 UMD 列表')
38
+ process.exit(1)
39
+ }
40
+
41
+ const { nodes, links } = JSON.parse(readFileSync(IN, 'utf8'))
42
+ const L = links.map(([source, target]) => ({ source, target }))
43
+ // 力参数**由调用方给**(graph_3d.py 的 LAYOUT_PARAMS),这里只照做:参数放两处迟早会分叉,
44
+ // 而它们还得计入缓存 key(改了参数却读到旧坐标,这个坑踩过一次)。
45
+ const P = paramsArg ? JSON.parse(paramsArg) : { charge: -22, chargeMax: 600, linkDist: 22, linkStrength: 0.6 }
46
+ const sim = d3.forceSimulation(nodes, DIMS)
47
+ .force('charge', d3.forceManyBody().strength(P.charge).distanceMax(P.chargeMax).theta(1.1))
48
+ .force('link', d3.forceLink(L).id((d) => d.id).distance(P.linkDist).strength(P.linkStrength))
49
+ .force('center', DIMS === 2 ? d3.forceCenter(0, 0) : d3.forceCenter(0, 0, 0))
50
+ .stop()
51
+
52
+ const t0 = Date.now()
53
+ for (let i = 0; i < TICKS; i += 1) sim.tick()
54
+ const ms = Date.now() - t0
55
+
56
+ // 整数就够:整团云上千单位宽,1 个单位的误差在屏幕上肉眼不可见,但能省一半体积
57
+ const coords = (n) => (DIMS === 2
58
+ ? `${Math.round(n.x)},${Math.round(n.y)}`
59
+ : `${Math.round(n.x)},${Math.round(n.y)},${Math.round(n.z)}`)
60
+ const flat = nodes.map(coords).join(',')
61
+ writeFileSync(OUT, flat)
62
+ console.log(`布局 ${nodes.length} 点 / ${L.length} 边,${TICKS} tick 用时 ${(ms / 1000).toFixed(1)} s`)
63
+ console.log(`${OUT} ${(flat.length / 1048576).toFixed(2)} MB`)