@nanonets/graft 0.23.0 → 0.24.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/README.md +4 -4
- package/dist/ai/crux.d.ts +31 -3
- package/dist/ai/crux.d.ts.map +1 -1
- package/dist/ai/crux.js +88 -10
- package/dist/ai/crux.js.map +1 -1
- package/dist/ai/llm/openai.d.ts +101 -0
- package/dist/ai/llm/openai.d.ts.map +1 -1
- package/dist/ai/llm/openai.js +396 -6
- package/dist/ai/llm/openai.js.map +1 -1
- package/dist/ai/llm/recover-tool.d.ts +2 -0
- package/dist/ai/llm/recover-tool.d.ts.map +1 -1
- package/dist/ai/llm/recover-tool.js +1 -1
- package/dist/ai/llm/recover-tool.js.map +1 -1
- package/dist/ai/synthesize.d.ts.map +1 -1
- package/dist/ai/synthesize.js +100 -1
- package/dist/ai/synthesize.js.map +1 -1
- package/dist/claude/format.d.ts +21 -0
- package/dist/claude/format.d.ts.map +1 -1
- package/dist/claude/format.js +46 -1
- package/dist/claude/format.js.map +1 -1
- package/dist/claude/hooks.d.ts +5 -9
- package/dist/claude/hooks.d.ts.map +1 -1
- package/dist/claude/hooks.js +71 -58
- package/dist/claude/hooks.js.map +1 -1
- package/dist/claude/init.js +3 -3
- package/dist/claude/init.js.map +1 -1
- package/dist/claude/note-signals.d.ts +28 -0
- package/dist/claude/note-signals.d.ts.map +1 -0
- package/dist/claude/note-signals.js +325 -0
- package/dist/claude/note-signals.js.map +1 -0
- package/dist/claude/shim-template.d.ts.map +1 -1
- package/dist/claude/shim-template.js +17 -6
- package/dist/claude/shim-template.js.map +1 -1
- package/dist/claude/skill-template.d.ts.map +1 -1
- package/dist/claude/skill-template.js +49 -18
- package/dist/claude/skill-template.js.map +1 -1
- package/dist/claude/state.d.ts +4 -3
- package/dist/claude/state.d.ts.map +1 -1
- package/dist/claude/state.js.map +1 -1
- package/dist/claude/sync-run.js +1 -1
- package/dist/claude/sync-run.js.map +1 -1
- package/dist/cli-picker.d.ts +12 -5
- package/dist/cli-picker.d.ts.map +1 -1
- package/dist/cli-picker.js +24 -8
- package/dist/cli-picker.js.map +1 -1
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +149 -43
- package/dist/cli.js.map +1 -1
- package/dist/context/batches.d.ts +29 -0
- package/dist/context/batches.d.ts.map +1 -0
- package/dist/context/batches.js +130 -0
- package/dist/context/batches.js.map +1 -0
- package/dist/context/build.d.ts +7 -2
- package/dist/context/build.d.ts.map +1 -1
- package/dist/context/build.js +84 -50
- package/dist/context/build.js.map +1 -1
- package/dist/context/node-file.d.ts.map +1 -1
- package/dist/context/node-file.js +41 -4
- package/dist/context/node-file.js.map +1 -1
- package/dist/engine.d.ts +2 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +1 -0
- package/dist/engine.js.map +1 -1
- package/dist/graph/cards.d.ts.map +1 -1
- package/dist/graph/cards.js +9 -4
- package/dist/graph/cards.js.map +1 -1
- package/dist/graph/enrich.d.ts.map +1 -1
- package/dist/graph/enrich.js +8 -3
- package/dist/graph/enrich.js.map +1 -1
- package/dist/graph/generic.d.ts.map +1 -1
- package/dist/graph/generic.js +207 -6
- package/dist/graph/generic.js.map +1 -1
- package/dist/graph/lsp/client.d.ts +18 -0
- package/dist/graph/lsp/client.d.ts.map +1 -1
- package/dist/graph/lsp/client.js +40 -2
- package/dist/graph/lsp/client.js.map +1 -1
- package/dist/graph/lsp/enrich.d.ts.map +1 -1
- package/dist/graph/lsp/enrich.js +9 -1
- package/dist/graph/lsp/enrich.js.map +1 -1
- package/dist/graph/lsp/registry.d.ts +7 -0
- package/dist/graph/lsp/registry.d.ts.map +1 -1
- package/dist/graph/lsp/registry.js +27 -2
- package/dist/graph/lsp/registry.js.map +1 -1
- package/dist/graph/queries/gleam.scm +51 -0
- package/dist/graph/resolve.d.ts.map +1 -1
- package/dist/graph/resolve.js +65 -3
- package/dist/graph/resolve.js.map +1 -1
- package/dist/graph/workspace-cli.d.ts +2 -0
- package/dist/graph/workspace-cli.d.ts.map +1 -1
- package/dist/graph/workspace-cli.js +1 -1
- package/dist/graph/workspace-cli.js.map +1 -1
- package/dist/init-guard.d.ts +11 -0
- package/dist/init-guard.d.ts.map +1 -0
- package/dist/init-guard.js +21 -0
- package/dist/init-guard.js.map +1 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +2 -1
- package/dist/mcp/tools.js.map +1 -1
- package/dist/notes/branches.d.ts +7 -1
- package/dist/notes/branches.d.ts.map +1 -1
- package/dist/notes/branches.js +31 -3
- package/dist/notes/branches.js.map +1 -1
- package/dist/notes/cold-start.d.ts +12 -2
- package/dist/notes/cold-start.d.ts.map +1 -1
- package/dist/notes/cold-start.js +46 -5
- package/dist/notes/cold-start.js.map +1 -1
- package/dist/notes/credit.d.ts +37 -0
- package/dist/notes/credit.d.ts.map +1 -0
- package/dist/notes/credit.js +78 -0
- package/dist/notes/credit.js.map +1 -0
- package/dist/notes/find-notes.d.ts +17 -0
- package/dist/notes/find-notes.d.ts.map +1 -0
- package/dist/notes/find-notes.js +48 -0
- package/dist/notes/find-notes.js.map +1 -0
- package/dist/notes/flatten.d.ts +31 -0
- package/dist/notes/flatten.d.ts.map +1 -0
- package/dist/notes/flatten.js +73 -0
- package/dist/notes/flatten.js.map +1 -0
- package/dist/notes/git-facts.d.ts +7 -1
- package/dist/notes/git-facts.d.ts.map +1 -1
- package/dist/notes/git-facts.js +12 -2
- package/dist/notes/git-facts.js.map +1 -1
- package/dist/notes/home.d.ts +24 -6
- package/dist/notes/home.d.ts.map +1 -1
- package/dist/notes/home.js +82 -15
- package/dist/notes/home.js.map +1 -1
- package/dist/notes/learning-fields.d.ts +102 -0
- package/dist/notes/learning-fields.d.ts.map +1 -0
- package/dist/notes/learning-fields.js +214 -0
- package/dist/notes/learning-fields.js.map +1 -0
- package/dist/notes/memory-notes.d.ts +71 -0
- package/dist/notes/memory-notes.d.ts.map +1 -0
- package/dist/notes/memory-notes.js +239 -0
- package/dist/notes/memory-notes.js.map +1 -0
- package/dist/notes/note-gate.d.ts +42 -0
- package/dist/notes/note-gate.d.ts.map +1 -0
- package/dist/notes/note-gate.js +181 -0
- package/dist/notes/note-gate.js.map +1 -0
- package/dist/notes/notes.d.ts +29 -77
- package/dist/notes/notes.d.ts.map +1 -1
- package/dist/notes/notes.js +69 -228
- package/dist/notes/notes.js.map +1 -1
- package/dist/notes/pr-reviews.d.ts +35 -7
- package/dist/notes/pr-reviews.d.ts.map +1 -1
- package/dist/notes/pr-reviews.js +156 -46
- package/dist/notes/pr-reviews.js.map +1 -1
- package/dist/notes/secrets.d.ts +28 -0
- package/dist/notes/secrets.d.ts.map +1 -0
- package/dist/notes/secrets.js +362 -0
- package/dist/notes/secrets.js.map +1 -0
- package/dist/notes/session-cost.d.ts +2 -0
- package/dist/notes/session-cost.d.ts.map +1 -1
- package/dist/notes/session-cost.js +8 -3
- package/dist/notes/session-cost.js.map +1 -1
- package/dist/notes/targets.d.ts +37 -0
- package/dist/notes/targets.d.ts.map +1 -0
- package/dist/notes/targets.js +108 -0
- package/dist/notes/targets.js.map +1 -0
- package/dist/notes/team-check.d.ts +22 -0
- package/dist/notes/team-check.d.ts.map +1 -0
- package/dist/notes/team-check.js +130 -0
- package/dist/notes/team-check.js.map +1 -0
- package/dist/notes/trail-home.d.ts +3 -0
- package/dist/notes/trail-home.d.ts.map +1 -0
- package/dist/notes/trail-home.js +12 -0
- package/dist/notes/trail-home.js.map +1 -0
- package/dist/search/grep-cli.d.ts +5 -2
- package/dist/search/grep-cli.d.ts.map +1 -1
- package/dist/search/grep-cli.js +11 -4
- package/dist/search/grep-cli.js.map +1 -1
- package/dist/search/ignored-code.d.ts +9 -0
- package/dist/search/ignored-code.d.ts.map +1 -0
- package/dist/search/ignored-code.js +73 -0
- package/dist/search/ignored-code.js.map +1 -0
- package/dist/skills/answers-prompt.d.ts +13 -0
- package/dist/skills/answers-prompt.d.ts.map +1 -0
- package/dist/skills/answers-prompt.js +83 -0
- package/dist/skills/answers-prompt.js.map +1 -0
- package/dist/skills/never-save.d.ts +5 -0
- package/dist/skills/never-save.d.ts.map +1 -0
- package/dist/skills/never-save.js +158 -0
- package/dist/skills/never-save.js.map +1 -0
- package/dist/skills/params.d.ts +39 -0
- package/dist/skills/params.d.ts.map +1 -0
- package/dist/skills/params.js +275 -0
- package/dist/skills/params.js.map +1 -0
- package/dist/skills/ran-less.d.ts +5 -0
- package/dist/skills/ran-less.d.ts.map +1 -0
- package/dist/skills/ran-less.js +51 -0
- package/dist/skills/ran-less.js.map +1 -0
- package/dist/skills/risk-delta.d.ts +32 -0
- package/dist/skills/risk-delta.d.ts.map +1 -0
- package/dist/skills/risk-delta.js +56 -0
- package/dist/skills/risk-delta.js.map +1 -0
- package/dist/skills/risk.d.ts +73 -0
- package/dist/skills/risk.d.ts.map +1 -0
- package/dist/skills/risk.js +396 -0
- package/dist/skills/risk.js.map +1 -0
- package/dist/skills/types.d.ts +422 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +2 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/telemetry/contract.d.ts.map +1 -1
- package/dist/telemetry/contract.js +8 -6
- package/dist/telemetry/contract.js.map +1 -1
- package/dist/telemetry/notice.d.ts.map +1 -1
- package/dist/telemetry/notice.js +3 -1
- package/dist/telemetry/notice.js.map +1 -1
- package/dist/trace/check-reads.d.ts +36 -0
- package/dist/trace/check-reads.d.ts.map +1 -0
- package/dist/trace/check-reads.js +57 -0
- package/dist/trace/check-reads.js.map +1 -0
- package/dist/trace/host.d.ts +40 -0
- package/dist/trace/host.d.ts.map +1 -0
- package/dist/trace/host.js +84 -0
- package/dist/trace/host.js.map +1 -0
- package/dist/trace/redact.d.ts +8 -0
- package/dist/trace/redact.d.ts.map +1 -0
- package/dist/trace/redact.js +63 -0
- package/dist/trace/redact.js.map +1 -0
- package/dist/trace/seen-cache.d.ts +9 -0
- package/dist/trace/seen-cache.d.ts.map +1 -0
- package/dist/trace/seen-cache.js +46 -0
- package/dist/trace/seen-cache.js.map +1 -0
- package/dist/trace/shell-scan.d.ts +52 -0
- package/dist/trace/shell-scan.d.ts.map +1 -0
- package/dist/trace/shell-scan.js +318 -0
- package/dist/trace/shell-scan.js.map +1 -0
- package/dist/trace/shell-words.d.ts +91 -0
- package/dist/trace/shell-words.d.ts.map +1 -0
- package/dist/trace/shell-words.js +558 -0
- package/dist/trace/shell-words.js.map +1 -0
- package/dist/trace/shell.d.ts +91 -0
- package/dist/trace/shell.d.ts.map +1 -0
- package/dist/trace/shell.js +435 -0
- package/dist/trace/shell.js.map +1 -0
- package/dist/trace/state.d.ts +27 -0
- package/dist/trace/state.d.ts.map +1 -0
- package/dist/trace/state.js +98 -0
- package/dist/trace/state.js.map +1 -0
- package/dist/trace/tamper-code.d.ts +9 -0
- package/dist/trace/tamper-code.d.ts.map +1 -0
- package/dist/trace/tamper-code.js +174 -0
- package/dist/trace/tamper-code.js.map +1 -0
- package/dist/trace/tamper-git.d.ts +12 -0
- package/dist/trace/tamper-git.d.ts.map +1 -0
- package/dist/trace/tamper-git.js +77 -0
- package/dist/trace/tamper-git.js.map +1 -0
- package/dist/trace/types.d.ts +477 -0
- package/dist/trace/types.d.ts.map +1 -0
- package/dist/trace/types.js +12 -0
- package/dist/trace/types.js.map +1 -0
- package/dist/trace/walls-glob.d.ts +11 -0
- package/dist/trace/walls-glob.d.ts.map +1 -0
- package/dist/trace/walls-glob.js +264 -0
- package/dist/trace/walls-glob.js.map +1 -0
- package/dist/trace/walls-quoted.d.ts +25 -0
- package/dist/trace/walls-quoted.d.ts.map +1 -0
- package/dist/trace/walls-quoted.js +81 -0
- package/dist/trace/walls-quoted.js.map +1 -0
- package/dist/upkeep.d.ts +1 -1
- package/dist/upkeep.d.ts.map +1 -1
- package/dist/upkeep.js +4 -1
- package/dist/upkeep.js.map +1 -1
- package/dist/util/actions-folder.d.ts +2 -0
- package/dist/util/actions-folder.d.ts.map +1 -0
- package/dist/util/actions-folder.js +9 -0
- package/dist/util/actions-folder.js.map +1 -0
- package/dist/util/front-matter.d.ts +31 -4
- package/dist/util/front-matter.d.ts.map +1 -1
- package/dist/util/front-matter.js +95 -3
- package/dist/util/front-matter.js.map +1 -1
- package/dist/util/private-file.d.ts +14 -0
- package/dist/util/private-file.d.ts.map +1 -0
- package/dist/util/private-file.js +82 -0
- package/dist/util/private-file.js.map +1 -0
- package/dist/util/private-fs.d.ts +25 -0
- package/dist/util/private-fs.d.ts.map +1 -0
- package/dist/util/private-fs.js +253 -0
- package/dist/util/private-fs.js.map +1 -0
- package/dist/util/state.d.ts.map +1 -1
- package/dist/util/state.js +3 -0
- package/dist/util/state.js.map +1 -1
- package/dist/viewer/app.js +2 -2
- package/package.json +5 -5
- package/scripts/run-tests.mjs +14 -2
package/dist/viewer/app.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var mt={part_of:"structure",contains:"structure",uses:"dependency",depends_on:"dependency",calls:"dependency",imports:"dependency",produces:"dependency",configures:"dependency",validates:"dependency",extends:"contract",implements:"contract",references:"association"};function Y(e){return mt[e]??"association"}var $e={structure:85,dependency:145,contract:150,association:185};function ee(e){return Y(e)==="structure"?"part of":e==="calls"||e==="uses"||e==="depends_on"||e==="imports"?"uses":e.replace(/_/g," ")}var Le={"part of":"where does this live? (contains, part of)",uses:"what breaks if the target changes? (calls, uses, depends on, imports)",produces:"where does this output come from?",configures:"what changes its behavior without a code change?",validates:"what checks or judges this? (tests, drift checks, scoring)",extends:"what contract must this honor? (inheritance)",implements:"what contract must this honor? (interface)",references:"mentioned but never called \u2014 possible dead coupling"},gt={system:"--sys",concept:"--con",file:"--fil",api:"--api",changed:"--fil",affected:"--sys"},vt={file:"--k-file",class:"--k-class",function:"--k-fn",method:"--k-method",interface:"--k-iface",type:"--k-type",enum:"--k-enum"};function R(e,t){return(e==="code"?vt:gt)[t]??"--edge"}function k(e){return getComputedStyle(document.documentElement).getPropertyValue(e).trim()}var F=globalThis.__GRAFT_DATA__;async function Te(){return F?.contextGraph?F.contextGraph:await(await fetch("/api/context-graph")).json()}async function Ae(){let e;if(F){if(!F.codeGraph)return null;e=F.codeGraph}else{let r=await fetch("/api/code-graph");if(!r.ok)return null;e=await r.json()}let t=e.nodes.map(r=>({id:r.id,name:r.name,type:r.kind,summary:r.summary??r.signature??"",sources:[`${r.path} \xB7 ${r.span}`]})),n=new Set(t.map(r=>r.id)),i=e.edges.filter(r=>n.has(r.source)&&n.has(r.target)).map(r=>({source:r.source,target:r.target,relation:r.relation,confidence:r.confidence}));return{meta:{nodeCount:t.length,edgeCount:i.length},nodes:t,edges:i}}function Se(e){if(F)return;let t=new EventSource("/events");t.onmessage=n=>{n.data==="change"&&e()}}function ce(e,t){var n,i=1;e==null&&(e=0),t==null&&(t=0);function r(){var o,a=n.length,h,d=0,s=0;for(o=0;o<a;++o)h=n[o],d+=h.x,s+=h.y;for(d=(d/a-e)*i,s=(s/a-t)*i,o=0;o<a;++o)h=n[o],h.x-=d,h.y-=s}return r.initialize=function(o){n=o},r.x=function(o){return arguments.length?(e=+o,r):e},r.y=function(o){return arguments.length?(t=+o,r):t},r.strength=function(o){return arguments.length?(i=+o,r):i},r}function Ge(e){let t=+this._x.call(null,e),n=+this._y.call(null,e);return Ve(this.cover(t,n),t,n,e)}function Ve(e,t,n,i){if(isNaN(t)||isNaN(n))return e;var r,o=e._root,a={data:i},h=e._x0,d=e._y0,s=e._x1,l=e._y1,g,c,f,v,p,u,m,y;if(!o)return e._root=a,e;for(;o.length;)if((p=t>=(g=(h+s)/2))?h=g:s=g,(u=n>=(c=(d+l)/2))?d=c:l=c,r=o,!(o=o[m=u<<1|p]))return r[m]=a,e;if(f=+e._x.call(null,o.data),v=+e._y.call(null,o.data),t===f&&n===v)return a.next=o,r?r[m]=a:e._root=a,e;do r=r?r[m]=new Array(4):e._root=new Array(4),(p=t>=(g=(h+s)/2))?h=g:s=g,(u=n>=(c=(d+l)/2))?d=c:l=c;while((m=u<<1|p)===(y=(v>=c)<<1|f>=g));return r[y]=o,r[m]=a,e}function ze(e){var t,n,i=e.length,r,o,a=new Array(i),h=new Array(i),d=1/0,s=1/0,l=-1/0,g=-1/0;for(n=0;n<i;++n)isNaN(r=+this._x.call(null,t=e[n]))||isNaN(o=+this._y.call(null,t))||(a[n]=r,h[n]=o,r<d&&(d=r),r>l&&(l=r),o<s&&(s=o),o>g&&(g=o));if(d>l||s>g)return this;for(this.cover(d,s).cover(l,g),n=0;n<i;++n)Ve(this,a[n],h[n],e[n]);return this}function De(e,t){if(isNaN(e=+e)||isNaN(t=+t))return this;var n=this._x0,i=this._y0,r=this._x1,o=this._y1;if(isNaN(n))r=(n=Math.floor(e))+1,o=(i=Math.floor(t))+1;else{for(var a=r-n||1,h=this._root,d,s;n>e||e>=r||i>t||t>=o;)switch(s=(t<i)<<1|e<n,d=new Array(4),d[s]=h,h=d,a*=2,s){case 0:r=n+a,o=i+a;break;case 1:n=r-a,o=i+a;break;case 2:r=n+a,i=o-a;break;case 3:n=r-a,i=o-a;break}this._root&&this._root.length&&(this._root=h)}return this._x0=n,this._y0=i,this._x1=r,this._y1=o,this}function He(){var e=[];return this.visit(function(t){if(!t.length)do e.push(t.data);while(t=t.next)}),e}function Ie(e){return arguments.length?this.cover(+e[0][0],+e[0][1]).cover(+e[1][0],+e[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]}function L(e,t,n,i,r){this.node=e,this.x0=t,this.y0=n,this.x1=i,this.y1=r}function Oe(e,t,n){var i,r=this._x0,o=this._y0,a,h,d,s,l=this._x1,g=this._y1,c=[],f=this._root,v,p;for(f&&c.push(new L(f,r,o,l,g)),n==null?n=1/0:(r=e-n,o=t-n,l=e+n,g=t+n,n*=n);v=c.pop();)if(!(!(f=v.node)||(a=v.x0)>l||(h=v.y0)>g||(d=v.x1)<r||(s=v.y1)<o))if(f.length){var u=(a+d)/2,m=(h+s)/2;c.push(new L(f[3],u,m,d,s),new L(f[2],a,m,u,s),new L(f[1],u,h,d,m),new L(f[0],a,h,u,m)),(p=(t>=m)<<1|e>=u)&&(v=c[c.length-1],c[c.length-1]=c[c.length-1-p],c[c.length-1-p]=v)}else{var y=e-+this._x.call(null,f.data),b=t-+this._y.call(null,f.data),x=y*y+b*b;if(x<n){var M=Math.sqrt(n=x);r=e-M,o=t-M,l=e+M,g=t+M,i=f.data}}return i}function Re(e){if(isNaN(l=+this._x.call(null,e))||isNaN(g=+this._y.call(null,e)))return this;var t,n=this._root,i,r,o,a=this._x0,h=this._y0,d=this._x1,s=this._y1,l,g,c,f,v,p,u,m;if(!n)return this;if(n.length)for(;;){if((v=l>=(c=(a+d)/2))?a=c:d=c,(p=g>=(f=(h+s)/2))?h=f:s=f,t=n,!(n=n[u=p<<1|v]))return this;if(!n.length)break;(t[u+1&3]||t[u+2&3]||t[u+3&3])&&(i=t,m=u)}for(;n.data!==e;)if(r=n,!(n=n.next))return this;return(o=n.next)&&delete n.next,r?(o?r.next=o:delete r.next,this):t?(o?t[u]=o:delete t[u],(n=t[0]||t[1]||t[2]||t[3])&&n===(t[3]||t[2]||t[1]||t[0])&&!n.length&&(i?i[m]=n:this._root=n),this):(this._root=o,this)}function Be(e){for(var t=0,n=e.length;t<n;++t)this.remove(e[t]);return this}function je(){return this._root}function Pe(){var e=0;return this.visit(function(t){if(!t.length)do++e;while(t=t.next)}),e}function We(e){var t=[],n,i=this._root,r,o,a,h,d;for(i&&t.push(new L(i,this._x0,this._y0,this._x1,this._y1));n=t.pop();)if(!e(i=n.node,o=n.x0,a=n.y0,h=n.x1,d=n.y1)&&i.length){var s=(o+h)/2,l=(a+d)/2;(r=i[3])&&t.push(new L(r,s,l,h,d)),(r=i[2])&&t.push(new L(r,o,l,s,d)),(r=i[1])&&t.push(new L(r,s,a,h,l)),(r=i[0])&&t.push(new L(r,o,a,s,l))}return this}function Fe(e){var t=[],n=[],i;for(this._root&&t.push(new L(this._root,this._x0,this._y0,this._x1,this._y1));i=t.pop();){var r=i.node;if(r.length){var o,a=i.x0,h=i.y0,d=i.x1,s=i.y1,l=(a+d)/2,g=(h+s)/2;(o=r[0])&&t.push(new L(o,a,h,l,g)),(o=r[1])&&t.push(new L(o,l,h,d,g)),(o=r[2])&&t.push(new L(o,a,g,l,s)),(o=r[3])&&t.push(new L(o,l,g,d,s))}n.push(i)}for(;i=n.pop();)e(i.node,i.x0,i.y0,i.x1,i.y1);return this}function Ye(e){return e[0]}function Xe(e){return arguments.length?(this._x=e,this):this._x}function qe(e){return e[1]}function Ke(e){return arguments.length?(this._y=e,this):this._y}function B(e,t,n){var i=new de(t??Ye,n??qe,NaN,NaN,NaN,NaN);return e==null?i:i.addAll(e)}function de(e,t,n,i,r,o){this._x=e,this._y=t,this._x0=n,this._y0=i,this._x1=r,this._y1=o,this._root=void 0}function Qe(e){for(var t={data:e.data},n=t;e=e.next;)n=n.next={data:e.data};return t}var S=B.prototype=de.prototype;S.copy=function(){var e=new de(this._x,this._y,this._x0,this._y0,this._x1,this._y1),t=this._root,n,i;if(!t)return e;if(!t.length)return e._root=Qe(t),e;for(n=[{source:t,target:e._root=new Array(4)}];t=n.pop();)for(var r=0;r<4;++r)(i=t.source[r])&&(i.length?n.push({source:i,target:t.target[r]=new Array(4)}):t.target[r]=Qe(i));return e};S.add=Ge;S.addAll=ze;S.cover=De;S.data=He;S.extent=Ie;S.find=Oe;S.remove=Re;S.removeAll=Be;S.root=je;S.size=Pe;S.visit=We;S.visitAfter=Fe;S.x=Xe;S.y=Ke;function D(e){return function(){return e}}function z(e){return(e()-.5)*1e-6}function yt(e){return e.x+e.vx}function xt(e){return e.y+e.vy}function ue(e){var t,n,i,r=1,o=1;typeof e!="function"&&(e=D(e==null?1:+e));function a(){for(var s,l=t.length,g,c,f,v,p,u,m=0;m<o;++m)for(g=B(t,yt,xt).visitAfter(h),s=0;s<l;++s)c=t[s],p=n[c.index],u=p*p,f=c.x+c.vx,v=c.y+c.vy,g.visit(y);function y(b,x,M,A,G){var C=b.data,V=b.r,$=p+V;if(C){if(C.index>c.index){var I=f-C.x-C.vx,O=v-C.y-C.vy,H=I*I+O*O;H<$*$&&(I===0&&(I=z(i),H+=I*I),O===0&&(O=z(i),H+=O*O),H=($-(H=Math.sqrt(H)))/H*r,c.vx+=(I*=H)*($=(V*=V)/(u+V)),c.vy+=(O*=H)*$,C.vx-=I*($=1-$),C.vy-=O*$)}return}return x>f+$||A<f-$||M>v+$||G<v-$}}function h(s){if(s.data)return s.r=n[s.data.index];for(var l=s.r=0;l<4;++l)s[l]&&s[l].r>s.r&&(s.r=s[l].r)}function d(){if(t){var s,l=t.length,g;for(n=new Array(l),s=0;s<l;++s)g=t[s],n[g.index]=+e(g,s,t)}}return a.initialize=function(s,l){t=s,i=l,d()},a.iterations=function(s){return arguments.length?(o=+s,a):o},a.strength=function(s){return arguments.length?(r=+s,a):r},a.radius=function(s){return arguments.length?(e=typeof s=="function"?s:D(+s),d(),a):e},a}function wt(e){return e.index}function Ze(e,t){var n=e.get(t);if(!n)throw new Error("node not found: "+t);return n}function fe(e){var t=wt,n=g,i,r=D(30),o,a,h,d,s,l=1;e==null&&(e=[]);function g(u){return 1/Math.min(h[u.source.index],h[u.target.index])}function c(u){for(var m=0,y=e.length;m<l;++m)for(var b=0,x,M,A,G,C,V,$;b<y;++b)x=e[b],M=x.source,A=x.target,G=A.x+A.vx-M.x-M.vx||z(s),C=A.y+A.vy-M.y-M.vy||z(s),V=Math.sqrt(G*G+C*C),V=(V-o[b])/V*u*i[b],G*=V,C*=V,A.vx-=G*($=d[b]),A.vy-=C*$,M.vx+=G*($=1-$),M.vy+=C*$}function f(){if(a){var u,m=a.length,y=e.length,b=new Map(a.map((M,A)=>[t(M,A,a),M])),x;for(u=0,h=new Array(m);u<y;++u)x=e[u],x.index=u,typeof x.source!="object"&&(x.source=Ze(b,x.source)),typeof x.target!="object"&&(x.target=Ze(b,x.target)),h[x.source.index]=(h[x.source.index]||0)+1,h[x.target.index]=(h[x.target.index]||0)+1;for(u=0,d=new Array(y);u<y;++u)x=e[u],d[u]=h[x.source.index]/(h[x.source.index]+h[x.target.index]);i=new Array(y),v(),o=new Array(y),p()}}function v(){if(a)for(var u=0,m=e.length;u<m;++u)i[u]=+n(e[u],u,e)}function p(){if(a)for(var u=0,m=e.length;u<m;++u)o[u]=+r(e[u],u,e)}return c.initialize=function(u,m){a=u,s=m,f()},c.links=function(u){return arguments.length?(e=u,f(),c):e},c.id=function(u){return arguments.length?(t=u,c):t},c.iterations=function(u){return arguments.length?(l=+u,c):l},c.strength=function(u){return arguments.length?(n=typeof u=="function"?u:D(+u),v(),c):n},c.distance=function(u){return arguments.length?(r=typeof u=="function"?u:D(+u),p(),c):r},c}var bt={value:()=>{}};function Je(){for(var e=0,t=arguments.length,n={},i;e<t;++e){if(!(i=arguments[e]+"")||i in n||/[\s.]/.test(i))throw new Error("illegal type: "+i);n[i]=[]}return new te(n)}function te(e){this._=e}function kt(e,t){return e.trim().split(/^|\s+/).map(function(n){var i="",r=n.indexOf(".");if(r>=0&&(i=n.slice(r+1),n=n.slice(0,r)),n&&!t.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:i}})}te.prototype=Je.prototype={constructor:te,on:function(e,t){var n=this._,i=kt(e+"",n),r,o=-1,a=i.length;if(arguments.length<2){for(;++o<a;)if((r=(e=i[o]).type)&&(r=_t(n[r],e.name)))return r;return}if(t!=null&&typeof t!="function")throw new Error("invalid callback: "+t);for(;++o<a;)if(r=(e=i[o]).type)n[r]=Ue(n[r],e.name,t);else if(t==null)for(r in n)n[r]=Ue(n[r],e.name,null);return this},copy:function(){var e={},t=this._;for(var n in t)e[n]=t[n].slice();return new te(e)},call:function(e,t){if((r=arguments.length-2)>0)for(var n=new Array(r),i=0,r,o;i<r;++i)n[i]=arguments[i+2];if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(o=this._[e],i=0,r=o.length;i<r;++i)o[i].value.apply(t,n)},apply:function(e,t,n){if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(var i=this._[e],r=0,o=i.length;r<o;++r)i[r].value.apply(t,n)}};function _t(e,t){for(var n=0,i=e.length,r;n<i;++n)if((r=e[n]).name===t)return r.value}function Ue(e,t,n){for(var i=0,r=e.length;i<r;++i)if(e[i].name===t){e[i]=bt,e=e.slice(0,i).concat(e.slice(i+1));break}return n!=null&&e.push({name:t,value:n}),e}var he=Je;var X=0,Q=0,K=0,tt=1e3,ne,Z,re=0,j=0,ie=0,U=typeof performance=="object"&&performance.now?performance:Date,nt=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(e){setTimeout(e,17)};function ge(){return j||(nt(Et),j=U.now()+ie)}function Et(){j=0}function pe(){this._call=this._time=this._next=null}pe.prototype=oe.prototype={constructor:pe,restart:function(e,t,n){if(typeof e!="function")throw new TypeError("callback is not a function");n=(n==null?ge():+n)+(t==null?0:+t),!this._next&&Z!==this&&(Z?Z._next=this:ne=this,Z=this),this._call=e,this._time=n,me()},stop:function(){this._call&&(this._call=null,this._time=1/0,me())}};function oe(e,t,n){var i=new pe;return i.restart(e,t,n),i}function rt(){ge(),++X;for(var e=ne,t;e;)(t=j-e._time)>=0&&e._call.call(void 0,t),e=e._next;--X}function et(){j=(re=U.now())+ie,X=Q=0;try{rt()}finally{X=0,Nt(),j=0}}function Mt(){var e=U.now(),t=e-re;t>tt&&(ie-=t,re=e)}function Nt(){for(var e,t=ne,n,i=1/0;t;)t._call?(i>t._time&&(i=t._time),e=t,t=t._next):(n=t._next,t._next=null,t=e?e._next=n:ne=n);Z=e,me(i)}function me(e){if(!X){Q&&(Q=clearTimeout(Q));var t=e-j;t>24?(e<1/0&&(Q=setTimeout(et,e-U.now()-ie)),K&&(K=clearInterval(K))):(K||(re=U.now(),K=setInterval(Mt,tt)),X=1,nt(et))}}function it(){let e=1;return()=>(e=(1664525*e+1013904223)%4294967296)/4294967296}function ot(e){return e.x}function st(e){return e.y}var Ct=10,$t=Math.PI*(3-Math.sqrt(5));function ve(e){var t,n=1,i=.001,r=1-Math.pow(i,1/300),o=0,a=.6,h=new Map,d=oe(g),s=he("tick","end"),l=it();e==null&&(e=[]);function g(){c(),s.call("tick",t),n<i&&(d.stop(),s.call("end",t))}function c(p){var u,m=e.length,y;p===void 0&&(p=1);for(var b=0;b<p;++b)for(n+=(o-n)*r,h.forEach(function(x){x(n)}),u=0;u<m;++u)y=e[u],y.fx==null?y.x+=y.vx*=a:(y.x=y.fx,y.vx=0),y.fy==null?y.y+=y.vy*=a:(y.y=y.fy,y.vy=0);return t}function f(){for(var p=0,u=e.length,m;p<u;++p){if(m=e[p],m.index=p,m.fx!=null&&(m.x=m.fx),m.fy!=null&&(m.y=m.fy),isNaN(m.x)||isNaN(m.y)){var y=Ct*Math.sqrt(.5+p),b=p*$t;m.x=y*Math.cos(b),m.y=y*Math.sin(b)}(isNaN(m.vx)||isNaN(m.vy))&&(m.vx=m.vy=0)}}function v(p){return p.initialize&&p.initialize(e,l),p}return f(),t={tick:c,restart:function(){return d.restart(g),t},stop:function(){return d.stop(),t},nodes:function(p){return arguments.length?(e=p,f(),h.forEach(v),t):e},alpha:function(p){return arguments.length?(n=+p,t):n},alphaMin:function(p){return arguments.length?(i=+p,t):i},alphaDecay:function(p){return arguments.length?(r=+p,t):+r},alphaTarget:function(p){return arguments.length?(o=+p,t):o},velocityDecay:function(p){return arguments.length?(a=1-p,t):1-a},randomSource:function(p){return arguments.length?(l=p,h.forEach(v),t):l},force:function(p,u){return arguments.length>1?(u==null?h.delete(p):h.set(p,v(u)),t):h.get(p)},find:function(p,u,m){var y=0,b=e.length,x,M,A,G,C;for(m==null?m=1/0:m*=m,y=0;y<b;++y)G=e[y],x=p-G.x,M=u-G.y,A=x*x+M*M,A<m&&(C=G,m=A);return C},on:function(p,u){return arguments.length>1?(s.on(p,u),t):s.on(p)}}}function ye(){var e,t,n,i,r=D(-30),o,a=1,h=1/0,d=.81;function s(f){var v,p=e.length,u=B(e,ot,st).visitAfter(g);for(i=f,v=0;v<p;++v)t=e[v],u.visit(c)}function l(){if(e){var f,v=e.length,p;for(o=new Array(v),f=0;f<v;++f)p=e[f],o[p.index]=+r(p,f,e)}}function g(f){var v=0,p,u,m=0,y,b,x;if(f.length){for(y=b=x=0;x<4;++x)(p=f[x])&&(u=Math.abs(p.value))&&(v+=p.value,m+=u,y+=u*p.x,b+=u*p.y);f.x=y/m,f.y=b/m}else{p=f,p.x=p.data.x,p.y=p.data.y;do v+=o[p.data.index];while(p=p.next)}f.value=v}function c(f,v,p,u){if(!f.value)return!0;var m=f.x-t.x,y=f.y-t.y,b=u-v,x=m*m+y*y;if(b*b/d<x)return x<h&&(m===0&&(m=z(n),x+=m*m),y===0&&(y=z(n),x+=y*y),x<a&&(x=Math.sqrt(a*x)),t.vx+=m*f.value*i/x,t.vy+=y*f.value*i/x),!0;if(f.length||x>=h)return;(f.data!==t||f.next)&&(m===0&&(m=z(n),x+=m*m),y===0&&(y=z(n),x+=y*y),x<a&&(x=Math.sqrt(a*x)));do f.data!==t&&(b=o[f.data.index]*i/x,t.vx+=m*b,t.vy+=y*b);while(f=f.next)}return s.initialize=function(f,v){e=f,n=v,l()},s.strength=function(f){return arguments.length?(r=typeof f=="function"?f:D(+f),l(),s):r},s.distanceMin=function(f){return arguments.length?(a=f*f,s):Math.sqrt(a)},s.distanceMax=function(f){return arguments.length?(h=f*f,s):Math.sqrt(h)},s.theta=function(f){return arguments.length?(d=f*f,s):Math.sqrt(d)},s}function T(e){return e.replace(/&/g,"&").replace(/</g,"<")}function Lt(e){let t=e.lines.map(n=>`<div class="ev-l ${n.sign==="+"?"add":n.sign==="-"?"del":"ctx"}"><span class="ev-n">${n.n??""}</span><span class="ev-s">${n.sign===" "?"":n.sign}</span><span class="ev-t">${T(n.text)}</span></div>`).join("");return`<div class="ev"><div class="ev-h mono">${T(e.label)}${e.note?` <span class="ev-note">${T(e.note)}</span>`:""}</div><div class="ev-b mono">${t}</div>`+(e.more?`<div class="ev-more">+ ${e.more} more lines</div>`:"")+"</div>"}function xe(e){let t=e.split(/[\s._-]+/).filter(Boolean);return(t.length>=2?t[0][0]+t[1][0]:(t[0]??"?").slice(0,2)).toUpperCase()}function Tt(e,t=Date.now()){let n=Date.parse(`${e}T00:00:00Z`);if(!Number.isFinite(n))return e;let i=Math.max(0,Math.round((t-n)/864e5));if(i<1)return"today";if(i===1)return"yesterday";if(i<31)return`${i}d ago`;let r=Math.round(i/30);return r<24?`${r}mo ago`:`${Math.round(i/365)}y ago`}function At(e){let t=e.map(r=>{let o=r.handle?`@${T(r.handle)}`:T(r.name),a=r.handle?"own-name mono":"own-name";return`<div class="own"><span class="av">${T(xe(r.handle??r.name))}</span><span class="own-txt"><span class="${a}">${o}</span><span class="own-why">${r.commits} commit${r.commits===1?"":"s"} here \xB7 last ${T(Tt(r.last))}</span></span></div>`}).join(""),n=e.filter(r=>!r.handle),i=n.length?`<div class="own-note">\u26A0 ${T(n.map(r=>r.name).join(", "))} ${n.length===1?"has":"have"} no GitHub handle in their commit email.</div>`:"";return`<div class="owners">${t}${i}</div>`}function at(e,t,n,i,r){if(!i||!t){e.innerHTML='<div class="empty">Select a node to view details</div>';return}let o=t.nodes.find(c=>c.id===i);if(!o){e.innerHTML='<div class="empty">Select a node to view details</div>';return}let a=k(R(n,o.type)),h=c=>t.nodes.find(f=>f.id===c)?.name??c,d=t.edges.filter(c=>c.source===i),s=t.edges.filter(c=>c.target===i),l=`<span class="d-type"><span class="sw" style="background:${a}"></span>${T(o.type)}</span>`;if(l+=`<h3>${T(o.name)}</h3>`,o.summary&&(l+=`<p class="summary">${T(o.summary)}</p>`),o.owners?.length&&(l+=`<div class="d-label"><span class="dot" style="background:var(--con)"></span>Who knows this \xB7 ${o.owners.length}</div>`,l+=At(o.owners)),o.evidence?.length){l+=`<div class="d-label">Code \xB7 ${o.evidence.length}</div>`;for(let f of o.evidence)l+=Lt(f);let c=o.sources.length-o.evidence.length;c>0&&(l+=`<div class="src mono">+ ${c} more, not shown</div>`)}else if(o.sources.length){l+=`<div class="d-label">Sources \xB7 ${o.sources.length}</div>`;for(let c of o.sources)l+=`<div class="src mono">${T(c)}</div>`}let g=(c,f,v,p)=>{if(c.length){l+=`<div class="d-label"><span class="dot" style="background:${f}"></span>${v} \xB7 ${c.length}</div>`;for(let u of c)l+=`<button class="lnk" data-go="${T(p(u))}"><span class="rel">${T(u.relation.replace(/_/g," "))}</span> <span class="to">${T(h(p(u)))}</span>`+(u.description?`<div class="desc">${T(u.description)}</div>`:"")+"</button>"}};g(d,k("--fil"),"Depends on",c=>c.target),g(s,k("--accent"),"Depended on by",c=>c.source),e.innerHTML=l,e.querySelectorAll("[data-go]").forEach(c=>{c.addEventListener("click",()=>r(c.dataset.go))})}var St="http://www.w3.org/2000/svg",Gt=2;function N(e,t){let n=document.createElementNS(St,e);for(let[i,r]of Object.entries(t))n.setAttribute(i,String(r));return n}function Vt(e){let t=e.owners??[];if(t.length===0)return null;let n=t.slice(0,Gt),i=t.length-n.length,r=[...n.map(a=>xe(a.handle??a.name)),...i>0?[`+${i}`]:[]],o=N("g",{"pointer-events":"none"});return r.forEach((a,h)=>{let d=e.r*.72+h*13,s=-e.r*.72+h*8;o.appendChild(N("circle",{cx:d,cy:s,r:8,fill:k("--panel"),stroke:k("--con"),"stroke-width":1.2}));let l=N("text",{x:d,y:s+3,"text-anchor":"middle","font-size":7.5,"font-weight":700,fill:k("--con")});l.textContent=a;let g=N("title",{});g.textContent=t.map(c=>`${c.handle?`@${c.handle}`:c.name} \u2014 ${c.commits} commits`).join(`
|
|
2
|
-
`),o.append(l,g)}),o}var se=class{svg;defs;viewport;sim=null;nodes=[];edges=[];edgeEls=[];nodeEls=[];view={x:0,y:0,k:1};tab="context";selected=null;query="";hiddenRels={};hiddenTypes={};showOwners=!0;onSelect=()=>{};constructor(t){this.svg=t,this.buildChrome(),this.bindPanZoom()}buildChrome(){this.svg.textContent="",this.defs=N("defs",{}),this.svg.appendChild(this.defs),this.viewport=N("g",{}),this.svg.appendChild(this.viewport),this.svg.addEventListener("click",()=>this.select(null))}ensureMarkers(){this.defs.textContent="";let t=N("marker",{id:"arr",viewBox:"0 0 10 10",refX:8,refY:5,markerWidth:4.5,markerHeight:4.5,orient:"auto-start-reverse"});t.appendChild(N("path",{d:"M2,1.5L8.5,5L2,8.5",fill:"none",stroke:k("--edge"),"stroke-width":1.8,"stroke-linecap":"round","stroke-linejoin":"round",opacity:.75}));let n=N("marker",{id:"arrH",viewBox:"0 0 12 12",refX:10,refY:6,markerWidth:6.5,markerHeight:6.5,orient:"auto-start-reverse"});n.appendChild(N("path",{d:"M1.5,1.5L10.5,6L1.5,10.5z",fill:k("--canvas"),stroke:k("--edge"),"stroke-width":1.4}));let i=N("marker",{id:"arrOut",viewBox:"0 0 10 10",refX:8,refY:5,markerWidth:5,markerHeight:5,orient:"auto-start-reverse"});i.appendChild(N("path",{d:"M1,1L9,5L1,9z",fill:k("--fil")}));let r=N("marker",{id:"arrIn",viewBox:"0 0 10 10",refX:8,refY:5,markerWidth:5,markerHeight:5,orient:"auto-start-reverse"});r.appendChild(N("path",{d:"M1,1L9,5L1,9z",fill:k("--accent")}));for(let o of[t,n,i,r])this.defs.appendChild(o)}setData(t,n){this.tab=n;let i=new Map(this.nodes.map(d=>[d.id,d])),r={};for(let d of t.edges)r[d.source]=(r[d.source]??0)+1,r[d.target]=(r[d.target]??0)+1;let o=this.svg.clientWidth||800,a=this.svg.clientHeight||600;this.nodes=t.nodes.map((d,s)=>{let l=i.get(d.id),g=s/Math.max(1,t.nodes.length)*Math.PI*2,c=r[d.id]??0;return{id:d.id,name:d.name,type:d.type,owners:d.owners,deg:c,r:11+Math.min(13,c*2.6),x:l?.x??o/2+Math.cos(g)*Math.min(o,a)/4,y:l?.y??a/2+Math.sin(g)*Math.min(o,a)/4,vx:l?.vx??0,vy:l?.vy??0}});let h=new Map(this.nodes.map(d=>[d.id,d]));this.edges=t.edges.map(d=>({source:h.get(d.source),target:h.get(d.target),relation:d.relation,description:d.description,confidence:d.confidence})).filter(d=>d.source&&d.target),this.sim?.stop(),this.sim=ve(this.nodes).force("charge",ye().strength(-220)).force("link",fe(this.edges).distance(d=>$e[Y(d.relation)]).strength(.5)).force("center",ce(o/2,a/2)).force("collide",ue().radius(d=>d.r+6)).on("tick",()=>this.tick()),this.buildElements(),this.restyle()}buildElements(){this.ensureMarkers(),this.viewport.textContent="",this.edgeEls=this.edges.map(t=>{let n=N("path",{fill:"none","stroke-linecap":"round"}),i=N("title",{});i.textContent=t.relation.replace(/_/g," ")+(t.description?` \u2014 ${t.description}`:""),n.appendChild(i);let r=N("text",{"text-anchor":"middle","font-size":9.5,"font-weight":700,"stroke-width":3,"paint-order":"stroke",display:"none"});return r.textContent=t.relation.replace(/_/g," "),this.viewport.appendChild(n),this.viewport.appendChild(r),{path:n,label:r,edge:t}}),this.nodeEls=this.nodes.map(t=>{let n=N("g",{cursor:"pointer"}),i=N("circle",{fill:"none","stroke-width":1.6,opacity:0,r:t.r+5}),r=N("circle",{r:t.r,opacity:.92}),o=N("text",{y:t.r+15,"text-anchor":"middle","font-size":11.5,"font-weight":600});o.textContent=t.name;let a=Vt(t);return n.append(i,r,o),a&&n.appendChild(a),n.addEventListener("click",h=>{h.stopPropagation(),this.select(t.id)}),this.bindDrag(n,t),this.viewport.appendChild(n),{group:n,circle:r,ring:i,label:o,badges:a,node:t}})}tick(){for(let{path:t,label:n,edge:i}of this.edgeEls){let r=i.source,o=i.target,a=(o.x??0)-(r.x??0),h=(o.y??0)-(r.y??0),d=Math.sqrt(a*a+h*h)||1,s=a/d,l=h/d,g=(r.x??0)+s*(r.r+2),c=(r.y??0)+l*(r.r+2),f=(o.x??0)-s*(o.r+6),v=(o.y??0)-l*(o.r+6),p=(g+f)/2-l*10,u=(c+v)/2+s*10;t.setAttribute("d",`M${g},${c} Q${p},${u} ${f},${v}`),n.setAttribute("x",String((g+f)/2-l*14)),n.setAttribute("y",String((c+v)/2+s*14))}for(let{group:t,node:n}of this.nodeEls)t.setAttribute("transform",`translate(${n.x??0},${n.y??0})`)}restyle(){this.ensureMarkers();let t=new Set;if(this.selected)for(let r of this.edges)r.source.id===this.selected&&t.add(r.target.id),r.target.id===this.selected&&t.add(r.source.id);let n=this.query.toLowerCase(),i=r=>!this.hiddenTypes[r.type];for(let{path:r,label:o,edge:a}of this.edgeEls){let h=i(a.source)&&i(a.target)&&!this.hiddenRels[ee(a.relation)];if(r.style.display=h?"":"none",o.setAttribute("display","none"),!h)continue;let d=Y(a.relation),s=k("--edge"),l=1.3,g="none",c=.5,f="url(#arr)";d==="structure"?(l=2.4,c=.32,f="none"):d==="dependency"?(l=1.5,c=.55):d==="contract"?(c=.55,f="url(#arrH)"):(g="2 5",l=1.2,c=.28,f="none"),a.confidence==="inferred"&&(g="5 4"),n&&(c=.12);let v=this.selected?a.source.id===this.selected?"out":a.target.id===this.selected?"in":"far":"none";v==="out"?(s=k("--fil"),c=.95,l+=.7,f="url(#arrOut)"):v==="in"?(s=k("--accent"),c=.95,l+=.7,f="url(#arrIn)"):v==="far"&&(c=.06),r.setAttribute("stroke",s),r.setAttribute("stroke-width",String(l)),r.setAttribute("stroke-dasharray",g),r.setAttribute("opacity",String(c)),f==="none"?r.removeAttribute("marker-end"):r.setAttribute("marker-end",f),(v==="out"||v==="in")&&(o.removeAttribute("display"),o.setAttribute("fill",s),o.setAttribute("stroke",k("--canvas")))}for(let{group:r,circle:o,ring:a,label:h,badges:d,node:s}of this.nodeEls){let l=i(s);if(r.style.display=l?"":"none",!l)continue;let c=!n||s.name.toLowerCase().includes(n)?1:.22;this.selected&&s.id!==this.selected&&!t.has(s.id)&&(c=Math.min(c,.2)),r.setAttribute("opacity",String(c));let f=k(R(this.tab,s.type));o.setAttribute("fill",f),a.setAttribute("stroke",f),a.setAttribute("opacity",s.id===this.selected?"0.55":"0"),h.setAttribute("fill",k("--ink")),d&&(d.style.display=this.showOwners?"":"none")}}select(t){this.selected=t,this.restyle(),this.onSelect(t)}focus(t){let n=this.nodes.find(o=>o.id===t);if(!n)return;let i=this.svg.clientWidth,r=this.svg.clientHeight;this.view.k=Math.max(this.view.k,1.4),this.view.x=i/2-(n.x??0)*this.view.k,this.view.y=r/2-(n.y??0)*this.view.k,this.applyView(),this.select(t)}firstMatch(){let t=this.query.toLowerCase();return this.nodes.find(n=>!this.hiddenTypes[n.type]&&n.name.toLowerCase().includes(t))}applyView(){this.viewport.setAttribute("transform",`translate(${this.view.x},${this.view.y}) scale(${this.view.k})`)}zoomBy(t){let n=this.svg.clientWidth/2,i=this.svg.clientHeight/2,r=Math.max(.35,Math.min(3,this.view.k*t));this.view.x=n-(n-this.view.x)*(r/this.view.k),this.view.y=i-(i-this.view.y)*(r/this.view.k),this.view.k=r,this.applyView()}resetView(){this.view={x:0,y:0,k:1},this.applyView()}reheat(){this.sim?.alpha(.6).restart()}bindDrag(t,n){t.addEventListener("pointerdown",i=>{i.stopPropagation(),t.setPointerCapture(i.pointerId);let r=a=>{let h=this.svg.getBoundingClientRect();n.fx=(a.clientX-h.left-this.view.x)/this.view.k,n.fy=(a.clientY-h.top-this.view.y)/this.view.k,this.sim?.alphaTarget(.25).restart()},o=()=>{n.fx=null,n.fy=null,this.sim?.alphaTarget(0),t.removeEventListener("pointermove",r),t.removeEventListener("pointerup",o)};t.addEventListener("pointermove",r),t.addEventListener("pointerup",o)})}bindPanZoom(){let t=null;this.svg.addEventListener("pointerdown",n=>{t={x:n.clientX-this.view.x,y:n.clientY-this.view.y}}),this.svg.addEventListener("pointermove",n=>{t&&(this.view.x=n.clientX-t.x,this.view.y=n.clientY-t.y,this.applyView())}),window.addEventListener("pointerup",()=>{t=null}),this.svg.addEventListener("wheel",n=>{n.preventDefault();let i=this.svg.getBoundingClientRect(),r=n.clientX-i.left,o=n.clientY-i.top,a=Math.max(.35,Math.min(3,this.view.k*Math.exp(-n.deltaY*.0016)));this.view.x=r-(r-this.view.x)*(a/this.view.k),this.view.y=o-(o-this.view.y)*(a/this.view.k),this.view.k=a,this.applyView()},{passive:!1})}};function we(e){return e.replace(/&/g,"&").replace(/</g,"<")}function q(e,t,n,i,r){let o=s=>t.edges.filter(l=>l.relation==="contains"&&l.source===s).map(l=>t.nodes.find(g=>g.id===l.target)).filter(l=>!!l),a=s=>{let l=o(s);return l.length+l.reduce((g,c)=>g+a(c.id),0)},h=t.nodes.filter(s=>s.type==="file"),d=s=>{let l=o(s.id),g=i[s.id]!==!1,c=`<button class="tree-row${g?" open":""}${n===s.id?" sel":""}" data-id="${we(s.id)}" data-haskids="${l.length?1:0}"><span class="chev">${l.length?"\u25B6":""}</span><span class="k" style="background:${k(R("code",s.type))}"></span><span class="t${s.type==="file"?" mono":""}">${we(s.name)}</span><span class="badge">${l.length?a(s.id)+" sym":we(s.type)}</span></button>`;return l.length&&g&&(c+=`<div class="tree-kids">${l.map(d).join("")}</div>`),c};e.innerHTML='<div class="tree-tools"><button data-tool="expand">Expand all</button><button data-tool="collapse">Collapse all</button></div>'+h.map(d).join(""),e.querySelectorAll(".tree-row").forEach(s=>{s.addEventListener("click",()=>{let l=s.dataset.id;s.dataset.haskids==="1"&&(i[l]=i[l]===!1,q(e,t,l,i,r)),r(l)})}),e.querySelector('[data-tool="expand"]')?.addEventListener("click",()=>{for(let s of Object.keys(i))delete i[s];q(e,t,n,i,r)}),e.querySelector('[data-tool="collapse"]')?.addEventListener("click",()=>{for(let s of t.nodes)i[s.id]=!1;q(e,t,n,i,r)})}var _=e=>document.getElementById(e),E={tab:"context",context:null,code:null,outlineOpen:{}},w=new se(_("graphSvg"));function J(){return E.tab==="context"?E.context:E.code}function Ee(){return E.tab==="code"||E.tab==="outline"?"code":"context"}function Me(){let e=_("edgeChips");e.innerHTML='<span class="cap">Edges</span>';let t=J();if(!t)return;let n=new Map;for(let r of t.edges){let o=ee(r.relation);n.set(o,(n.get(o)??0)+1)}let i=[...n.keys()].sort((r,o)=>{let a=h=>h==="part of"?0:h==="uses"?1:2;return a(r)-a(o)||r.localeCompare(o)});for(let r of i){let o=document.createElement("button");o.type="button",o.className="echip"+(w.hiddenRels[r]?"":" on"),o.innerHTML=`${zt(r)} ${r} <span style="opacity:.55">${n.get(r)}</span>`,o.title=(Le[r]??`"${r}" edges`)+" \u2014 click to "+(w.hiddenRels[r]?"show":"hide"),o.addEventListener("click",()=>{w.hiddenRels[r]=!w.hiddenRels[r],Me(),w.restyle(),Ne()}),e.appendChild(o)}}function zt(e){let t=e==="part of"?"structure":e==="uses"?"dependency":Y(e.replace(/ /g,"_"));return{structure:'<svg width="20" height="8" aria-hidden="true"><line x1="1" y1="4" x2="19" y2="4" stroke="currentColor" stroke-width="3" opacity=".5"/></svg>',dependency:'<svg width="20" height="8" aria-hidden="true"><line x1="1" y1="4" x2="14" y2="4" stroke="currentColor" stroke-width="1.6"/><path d="M14,1 L19,4 L14,7 z" fill="currentColor"/></svg>',contract:'<svg width="20" height="8" aria-hidden="true"><line x1="1" y1="4" x2="13" y2="4" stroke="currentColor" stroke-width="1.4"/><path d="M13,1 L19,4 L13,7 z" fill="none" stroke="currentColor" stroke-width="1.2"/></svg>',association:'<svg width="20" height="8" aria-hidden="true"><line x1="1" y1="4" x2="19" y2="4" stroke="currentColor" stroke-width="1.4" stroke-dasharray="2 4" opacity=".7"/></svg>'}[t]}function ae(){let e=_("legend");e.innerHTML="";let t=J();if(!t)return;let n=new Map;for(let r of t.nodes)n.set(r.type,(n.get(r.type)??0)+1);for(let[r,o]of n){let a=document.createElement("button");a.type="button",a.className="lchip"+(w.hiddenTypes[r]?" off":""),a.innerHTML=`<span class="sw" style="background:${k(R(Ee(),r))}"></span>${r} <span style="color:var(--muted);font-weight:500">${o}</span>`,a.addEventListener("click",()=>{w.hiddenTypes[r]=!w.hiddenTypes[r],ae(),w.restyle(),Ne()}),e.appendChild(a)}if(t.nodes.some(r=>r.owners?.length)){let r=document.createElement("button");r.type="button",r.className="lchip lchip-people"+(w.showOwners?"":" off"),r.innerHTML=`<span class="sw" style="background:${k("--con")}"></span>people`,r.title="Show who has worked on each area",r.addEventListener("click",()=>{w.showOwners=!w.showOwners,ae(),w.restyle()}),e.appendChild(r)}}function Ne(){let e=J();if(!e){_("lcount").textContent="";return}let t=e.nodes.filter(n=>!w.hiddenTypes[n.type]).length;_("lcount").textContent=`${t} / ${e.nodes.length} nodes shown`}function Dt(){let e=_("counts");if(E.tab==="outline"&&E.code){let t=E.code.nodes.filter(n=>n.type==="file").length;e.textContent=`${t} files \xB7 ${E.code.nodes.length} symbols`}else{let t=J();e.textContent=t?`${t.meta.nodeCount} nodes \xB7 ${t.meta.edgeCount} links`:""}}function P(e){at(_("detail"),E.tab==="context"?E.context:E.code,Ee(),e,t=>{E.tab==="outline"?(P(t),q(_("tree"),E.code,t,E.outlineOpen,P)):w.focus(t)})}w.onSelect=e=>P(e);function dt(e){E.tab=e,document.querySelectorAll(".tab").forEach(i=>{i.setAttribute("aria-selected",i.dataset.tab===e?"true":"false")});let t=e==="outline";_("canvasWrap").hidden=t,_("outlineView").hidden=!t,w.hiddenRels={},w.hiddenTypes={},w.selected=null,P(null);let n=_("graphEmpty");if(e==="outline")E.code?q(_("tree"),E.code,null,E.outlineOpen,P):(_("outlineView").hidden=!0,_("canvasWrap").hidden=!1,lt('No code graph yet \u2014 run <code>graft graph</code> to generate <span class="mono">graph.json</span>.'));else{let i=J();!i||i.nodes.length===0?lt(i?.meta.emptyNote?Ht(i.meta.emptyNote):e==="code"?'No code graph yet \u2014 run <code>graft graph</code> to generate <span class="mono">graph.json</span>.':"No context graph \u2014 run <code>graft init</code> first."):(n.hidden=!0,w.resetView(),w.setData(i,Ee()),w.reheat())}Me(),ae(),Ne(),Dt()}function Ht(e){return e.replace(/&/g,"&").replace(/</g,"<")}function lt(e){let t=_("graphEmpty");t.innerHTML=e,t.hidden=!1}document.querySelectorAll(".tab").forEach(e=>{e.addEventListener("click",()=>dt(e.dataset.tab))});var ke=_("search");ke.addEventListener("input",()=>{w.query=ke.value.trim(),w.restyle()});ke.addEventListener("keydown",e=>{if(e.key==="Enter"&&w.query){let t=w.firstMatch();t&&w.focus(t.id)}});_("zin").addEventListener("click",()=>w.zoomBy(1.25));_("zout").addEventListener("click",()=>w.zoomBy(1/1.25));_("zreset").addEventListener("click",()=>w.resetView());var ut="graft-viz-theme",ct=localStorage.getItem(ut);ct&&document.documentElement.setAttribute("data-theme",ct);_("themeBtn").addEventListener("click",()=>{let e=document.documentElement,t=e.getAttribute("data-theme"),n=window.matchMedia("(prefers-color-scheme: dark)").matches,r=(t?t==="dark":n)?"light":"dark";e.setAttribute("data-theme",r),localStorage.setItem(ut,r),w.restyle(),Me(),ae(),P(w.selected)});var ft="graft-viz-detail-w",_e=220,It=document.documentElement,Ot=e=>Math.min(Math.max(_e,Math.round(window.innerWidth*.6)),Math.max(_e,Math.round(e)));function Ce(e,t=!0){let n=Ot(e);It.style.setProperty("--detail-w",`${n}px`),t&&localStorage.setItem(ft,String(n))}var be=Number(localStorage.getItem(ft));Number.isFinite(be)&&be>=_e&&Ce(be,!1);var W=_("detailResizer"),le=!1;W.addEventListener("pointerdown",e=>{let t=e;le=!0,W.setPointerCapture(t.pointerId),document.body.style.cursor="col-resize",e.preventDefault()});W.addEventListener("pointermove",e=>{le&&Ce(window.innerWidth-e.clientX)});var ht=e=>{if(le){le=!1,document.body.style.cursor="";try{W.releasePointerCapture(e.pointerId)}catch{}w.reheat()}};W.addEventListener("pointerup",ht);W.addEventListener("pointercancel",ht);W.addEventListener("keydown",e=>{let t=e;if(t.key!=="ArrowLeft"&&t.key!=="ArrowRight")return;let n=t.shiftKey?40:16,i=_("detail").getBoundingClientRect().width;Ce(i+(t.key==="ArrowLeft"?n:-n)),w.reheat(),e.preventDefault()});async function pt(){let[e,t]=await Promise.all([Te(),Ae()]);E.context=e,E.code=t;let n=[e.meta.repoName,e.meta.subtitle].filter(Boolean).join(" \xB7 ");_("repoName").textContent=n,document.title=`graft viz \u2014 ${n}`;let i=e.meta.tabs;i&&document.querySelectorAll(".tab").forEach(o=>{o.hidden=!i.includes(o.dataset.tab)});let r=e.meta.defaultTab;dt(r&&r!==E.tab?r:E.tab)}Se(()=>{let e=w.selected;pt().then(()=>{e&&(w.selected=e,w.restyle(),P(e))})});pt();
|
|
1
|
+
var mt={part_of:"structure",contains:"structure",uses:"dependency",depends_on:"dependency",calls:"dependency",imports:"dependency",produces:"dependency",configures:"dependency",validates:"dependency",extends:"contract",implements:"contract",references:"association"};function F(e){return mt[e]??"association"}var $e={structure:85,dependency:145,contract:150,association:185};function ee(e){return F(e)==="structure"?"part of":e==="calls"||e==="uses"||e==="depends_on"||e==="imports"?"uses":e.replace(/_/g," ")}var Le={"part of":"where does this live? (contains, part of)",uses:"what breaks if the target changes? (calls, uses, depends on, imports)",produces:"where does this output come from?",configures:"what changes its behavior without a code change?",validates:"what checks or judges this? (tests, drift checks, scoring)",extends:"what contract must this honor? (inheritance)",implements:"what contract must this honor? (interface)",references:"mentioned but never called \u2014 possible dead coupling"},gt={system:"--sys",concept:"--con",file:"--fil",api:"--api",changed:"--fil",affected:"--sys"},vt={file:"--k-file",class:"--k-class",function:"--k-fn",method:"--k-method",interface:"--k-iface",type:"--k-type",enum:"--k-enum"};function R(e,t){return(e==="code"?vt:gt)[t]??"--edge"}function k(e){return getComputedStyle(document.documentElement).getPropertyValue(e).trim()}var X=globalThis.__GRAFT_DATA__;async function Ae(){return X?.contextGraph?X.contextGraph:await(await fetch("/api/context-graph")).json()}async function Te(){let e;if(X){if(!X.codeGraph)return null;e=X.codeGraph}else{let r=await fetch("/api/code-graph");if(!r.ok)return null;e=await r.json()}let t=e.nodes.map(r=>({id:r.id,name:r.name,type:r.kind,summary:r.summary??r.signature??"",sources:[`${r.path} \xB7 ${r.span}`]})),n=new Set(t.map(r=>r.id)),i=e.edges.filter(r=>n.has(r.source)&&n.has(r.target)).map(r=>({source:r.source,target:r.target,relation:r.relation,confidence:r.confidence}));return{meta:{nodeCount:t.length,edgeCount:i.length},nodes:t,edges:i}}function Se(e){if(X)return;let t=new EventSource("/events");t.onmessage=n=>{n.data==="change"&&e()}}function ce(e,t){var n,i=1;e==null&&(e=0),t==null&&(t=0);function r(){var o,a=n.length,h,d=0,s=0;for(o=0;o<a;++o)h=n[o],d+=h.x,s+=h.y;for(d=(d/a-e)*i,s=(s/a-t)*i,o=0;o<a;++o)h=n[o],h.x-=d,h.y-=s}return r.initialize=function(o){n=o},r.x=function(o){return arguments.length?(e=+o,r):e},r.y=function(o){return arguments.length?(t=+o,r):t},r.strength=function(o){return arguments.length?(i=+o,r):i},r}function Ge(e){let t=+this._x.call(null,e),n=+this._y.call(null,e);return Ve(this.cover(t,n),t,n,e)}function Ve(e,t,n,i){if(isNaN(t)||isNaN(n))return e;var r,o=e._root,a={data:i},h=e._x0,d=e._y0,s=e._x1,l=e._y1,g,c,f,v,p,u,m,y;if(!o)return e._root=a,e;for(;o.length;)if((p=t>=(g=(h+s)/2))?h=g:s=g,(u=n>=(c=(d+l)/2))?d=c:l=c,r=o,!(o=o[m=u<<1|p]))return r[m]=a,e;if(f=+e._x.call(null,o.data),v=+e._y.call(null,o.data),t===f&&n===v)return a.next=o,r?r[m]=a:e._root=a,e;do r=r?r[m]=new Array(4):e._root=new Array(4),(p=t>=(g=(h+s)/2))?h=g:s=g,(u=n>=(c=(d+l)/2))?d=c:l=c;while((m=u<<1|p)===(y=(v>=c)<<1|f>=g));return r[y]=o,r[m]=a,e}function ze(e){var t,n,i=e.length,r,o,a=new Array(i),h=new Array(i),d=1/0,s=1/0,l=-1/0,g=-1/0;for(n=0;n<i;++n)isNaN(r=+this._x.call(null,t=e[n]))||isNaN(o=+this._y.call(null,t))||(a[n]=r,h[n]=o,r<d&&(d=r),r>l&&(l=r),o<s&&(s=o),o>g&&(g=o));if(d>l||s>g)return this;for(this.cover(d,s).cover(l,g),n=0;n<i;++n)Ve(this,a[n],h[n],e[n]);return this}function De(e,t){if(isNaN(e=+e)||isNaN(t=+t))return this;var n=this._x0,i=this._y0,r=this._x1,o=this._y1;if(isNaN(n))r=(n=Math.floor(e))+1,o=(i=Math.floor(t))+1;else{for(var a=r-n||1,h=this._root,d,s;n>e||e>=r||i>t||t>=o;)switch(s=(t<i)<<1|e<n,d=new Array(4),d[s]=h,h=d,a*=2,s){case 0:r=n+a,o=i+a;break;case 1:n=r-a,o=i+a;break;case 2:r=n+a,i=o-a;break;case 3:n=r-a,i=o-a;break}this._root&&this._root.length&&(this._root=h)}return this._x0=n,this._y0=i,this._x1=r,this._y1=o,this}function He(){var e=[];return this.visit(function(t){if(!t.length)do e.push(t.data);while(t=t.next)}),e}function Oe(e){return arguments.length?this.cover(+e[0][0],+e[0][1]).cover(+e[1][0],+e[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]}function L(e,t,n,i,r){this.node=e,this.x0=t,this.y0=n,this.x1=i,this.y1=r}function Ie(e,t,n){var i,r=this._x0,o=this._y0,a,h,d,s,l=this._x1,g=this._y1,c=[],f=this._root,v,p;for(f&&c.push(new L(f,r,o,l,g)),n==null?n=1/0:(r=e-n,o=t-n,l=e+n,g=t+n,n*=n);v=c.pop();)if(!(!(f=v.node)||(a=v.x0)>l||(h=v.y0)>g||(d=v.x1)<r||(s=v.y1)<o))if(f.length){var u=(a+d)/2,m=(h+s)/2;c.push(new L(f[3],u,m,d,s),new L(f[2],a,m,u,s),new L(f[1],u,h,d,m),new L(f[0],a,h,u,m)),(p=(t>=m)<<1|e>=u)&&(v=c[c.length-1],c[c.length-1]=c[c.length-1-p],c[c.length-1-p]=v)}else{var y=e-+this._x.call(null,f.data),b=t-+this._y.call(null,f.data),x=y*y+b*b;if(x<n){var M=Math.sqrt(n=x);r=e-M,o=t-M,l=e+M,g=t+M,i=f.data}}return i}function Re(e){if(isNaN(l=+this._x.call(null,e))||isNaN(g=+this._y.call(null,e)))return this;var t,n=this._root,i,r,o,a=this._x0,h=this._y0,d=this._x1,s=this._y1,l,g,c,f,v,p,u,m;if(!n)return this;if(n.length)for(;;){if((v=l>=(c=(a+d)/2))?a=c:d=c,(p=g>=(f=(h+s)/2))?h=f:s=f,t=n,!(n=n[u=p<<1|v]))return this;if(!n.length)break;(t[u+1&3]||t[u+2&3]||t[u+3&3])&&(i=t,m=u)}for(;n.data!==e;)if(r=n,!(n=n.next))return this;return(o=n.next)&&delete n.next,r?(o?r.next=o:delete r.next,this):t?(o?t[u]=o:delete t[u],(n=t[0]||t[1]||t[2]||t[3])&&n===(t[3]||t[2]||t[1]||t[0])&&!n.length&&(i?i[m]=n:this._root=n),this):(this._root=o,this)}function Be(e){for(var t=0,n=e.length;t<n;++t)this.remove(e[t]);return this}function Pe(){return this._root}function je(){var e=0;return this.visit(function(t){if(!t.length)do++e;while(t=t.next)}),e}function We(e){var t=[],n,i=this._root,r,o,a,h,d;for(i&&t.push(new L(i,this._x0,this._y0,this._x1,this._y1));n=t.pop();)if(!e(i=n.node,o=n.x0,a=n.y0,h=n.x1,d=n.y1)&&i.length){var s=(o+h)/2,l=(a+d)/2;(r=i[3])&&t.push(new L(r,s,l,h,d)),(r=i[2])&&t.push(new L(r,o,l,s,d)),(r=i[1])&&t.push(new L(r,s,a,h,l)),(r=i[0])&&t.push(new L(r,o,a,s,l))}return this}function Xe(e){var t=[],n=[],i;for(this._root&&t.push(new L(this._root,this._x0,this._y0,this._x1,this._y1));i=t.pop();){var r=i.node;if(r.length){var o,a=i.x0,h=i.y0,d=i.x1,s=i.y1,l=(a+d)/2,g=(h+s)/2;(o=r[0])&&t.push(new L(o,a,h,l,g)),(o=r[1])&&t.push(new L(o,l,h,d,g)),(o=r[2])&&t.push(new L(o,a,g,l,s)),(o=r[3])&&t.push(new L(o,l,g,d,s))}n.push(i)}for(;i=n.pop();)e(i.node,i.x0,i.y0,i.x1,i.y1);return this}function Fe(e){return e[0]}function Ye(e){return arguments.length?(this._x=e,this):this._x}function qe(e){return e[1]}function Ke(e){return arguments.length?(this._y=e,this):this._y}function B(e,t,n){var i=new de(t??Fe,n??qe,NaN,NaN,NaN,NaN);return e==null?i:i.addAll(e)}function de(e,t,n,i,r,o){this._x=e,this._y=t,this._x0=n,this._y0=i,this._x1=r,this._y1=o,this._root=void 0}function Qe(e){for(var t={data:e.data},n=t;e=e.next;)n=n.next={data:e.data};return t}var S=B.prototype=de.prototype;S.copy=function(){var e=new de(this._x,this._y,this._x0,this._y0,this._x1,this._y1),t=this._root,n,i;if(!t)return e;if(!t.length)return e._root=Qe(t),e;for(n=[{source:t,target:e._root=new Array(4)}];t=n.pop();)for(var r=0;r<4;++r)(i=t.source[r])&&(i.length?n.push({source:i,target:t.target[r]=new Array(4)}):t.target[r]=Qe(i));return e};S.add=Ge;S.addAll=ze;S.cover=De;S.data=He;S.extent=Oe;S.find=Ie;S.remove=Re;S.removeAll=Be;S.root=Pe;S.size=je;S.visit=We;S.visitAfter=Xe;S.x=Ye;S.y=Ke;function D(e){return function(){return e}}function z(e){return(e()-.5)*1e-6}function yt(e){return e.x+e.vx}function xt(e){return e.y+e.vy}function ue(e){var t,n,i,r=1,o=1;typeof e!="function"&&(e=D(e==null?1:+e));function a(){for(var s,l=t.length,g,c,f,v,p,u,m=0;m<o;++m)for(g=B(t,yt,xt).visitAfter(h),s=0;s<l;++s)c=t[s],p=n[c.index],u=p*p,f=c.x+c.vx,v=c.y+c.vy,g.visit(y);function y(b,x,M,T,G){var C=b.data,V=b.r,$=p+V;if(C){if(C.index>c.index){var O=f-C.x-C.vx,I=v-C.y-C.vy,H=O*O+I*I;H<$*$&&(O===0&&(O=z(i),H+=O*O),I===0&&(I=z(i),H+=I*I),H=($-(H=Math.sqrt(H)))/H*r,c.vx+=(O*=H)*($=(V*=V)/(u+V)),c.vy+=(I*=H)*$,C.vx-=O*($=1-$),C.vy-=I*$)}return}return x>f+$||T<f-$||M>v+$||G<v-$}}function h(s){if(s.data)return s.r=n[s.data.index];for(var l=s.r=0;l<4;++l)s[l]&&s[l].r>s.r&&(s.r=s[l].r)}function d(){if(t){var s,l=t.length,g;for(n=new Array(l),s=0;s<l;++s)g=t[s],n[g.index]=+e(g,s,t)}}return a.initialize=function(s,l){t=s,i=l,d()},a.iterations=function(s){return arguments.length?(o=+s,a):o},a.strength=function(s){return arguments.length?(r=+s,a):r},a.radius=function(s){return arguments.length?(e=typeof s=="function"?s:D(+s),d(),a):e},a}function wt(e){return e.index}function Ze(e,t){var n=e.get(t);if(!n)throw new Error("node not found: "+t);return n}function fe(e){var t=wt,n=g,i,r=D(30),o,a,h,d,s,l=1;e==null&&(e=[]);function g(u){return 1/Math.min(h[u.source.index],h[u.target.index])}function c(u){for(var m=0,y=e.length;m<l;++m)for(var b=0,x,M,T,G,C,V,$;b<y;++b)x=e[b],M=x.source,T=x.target,G=T.x+T.vx-M.x-M.vx||z(s),C=T.y+T.vy-M.y-M.vy||z(s),V=Math.sqrt(G*G+C*C),V=(V-o[b])/V*u*i[b],G*=V,C*=V,T.vx-=G*($=d[b]),T.vy-=C*$,M.vx+=G*($=1-$),M.vy+=C*$}function f(){if(a){var u,m=a.length,y=e.length,b=new Map(a.map((M,T)=>[t(M,T,a),M])),x;for(u=0,h=new Array(m);u<y;++u)x=e[u],x.index=u,typeof x.source!="object"&&(x.source=Ze(b,x.source)),typeof x.target!="object"&&(x.target=Ze(b,x.target)),h[x.source.index]=(h[x.source.index]||0)+1,h[x.target.index]=(h[x.target.index]||0)+1;for(u=0,d=new Array(y);u<y;++u)x=e[u],d[u]=h[x.source.index]/(h[x.source.index]+h[x.target.index]);i=new Array(y),v(),o=new Array(y),p()}}function v(){if(a)for(var u=0,m=e.length;u<m;++u)i[u]=+n(e[u],u,e)}function p(){if(a)for(var u=0,m=e.length;u<m;++u)o[u]=+r(e[u],u,e)}return c.initialize=function(u,m){a=u,s=m,f()},c.links=function(u){return arguments.length?(e=u,f(),c):e},c.id=function(u){return arguments.length?(t=u,c):t},c.iterations=function(u){return arguments.length?(l=+u,c):l},c.strength=function(u){return arguments.length?(n=typeof u=="function"?u:D(+u),v(),c):n},c.distance=function(u){return arguments.length?(r=typeof u=="function"?u:D(+u),p(),c):r},c}var bt={value:()=>{}};function Je(){for(var e=0,t=arguments.length,n={},i;e<t;++e){if(!(i=arguments[e]+"")||i in n||/[\s.]/.test(i))throw new Error("illegal type: "+i);n[i]=[]}return new te(n)}function te(e){this._=e}function kt(e,t){return e.trim().split(/^|\s+/).map(function(n){var i="",r=n.indexOf(".");if(r>=0&&(i=n.slice(r+1),n=n.slice(0,r)),n&&!t.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:i}})}te.prototype=Je.prototype={constructor:te,on:function(e,t){var n=this._,i=kt(e+"",n),r,o=-1,a=i.length;if(arguments.length<2){for(;++o<a;)if((r=(e=i[o]).type)&&(r=_t(n[r],e.name)))return r;return}if(t!=null&&typeof t!="function")throw new Error("invalid callback: "+t);for(;++o<a;)if(r=(e=i[o]).type)n[r]=Ue(n[r],e.name,t);else if(t==null)for(r in n)n[r]=Ue(n[r],e.name,null);return this},copy:function(){var e={},t=this._;for(var n in t)e[n]=t[n].slice();return new te(e)},call:function(e,t){if((r=arguments.length-2)>0)for(var n=new Array(r),i=0,r,o;i<r;++i)n[i]=arguments[i+2];if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(o=this._[e],i=0,r=o.length;i<r;++i)o[i].value.apply(t,n)},apply:function(e,t,n){if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(var i=this._[e],r=0,o=i.length;r<o;++r)i[r].value.apply(t,n)}};function _t(e,t){for(var n=0,i=e.length,r;n<i;++n)if((r=e[n]).name===t)return r.value}function Ue(e,t,n){for(var i=0,r=e.length;i<r;++i)if(e[i].name===t){e[i]=bt,e=e.slice(0,i).concat(e.slice(i+1));break}return n!=null&&e.push({name:t,value:n}),e}var he=Je;var Y=0,Q=0,K=0,tt=1e3,ne,Z,re=0,P=0,ie=0,U=typeof performance=="object"&&performance.now?performance:Date,nt=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(e){setTimeout(e,17)};function ge(){return P||(nt(Et),P=U.now()+ie)}function Et(){P=0}function pe(){this._call=this._time=this._next=null}pe.prototype=oe.prototype={constructor:pe,restart:function(e,t,n){if(typeof e!="function")throw new TypeError("callback is not a function");n=(n==null?ge():+n)+(t==null?0:+t),!this._next&&Z!==this&&(Z?Z._next=this:ne=this,Z=this),this._call=e,this._time=n,me()},stop:function(){this._call&&(this._call=null,this._time=1/0,me())}};function oe(e,t,n){var i=new pe;return i.restart(e,t,n),i}function rt(){ge(),++Y;for(var e=ne,t;e;)(t=P-e._time)>=0&&e._call.call(void 0,t),e=e._next;--Y}function et(){P=(re=U.now())+ie,Y=Q=0;try{rt()}finally{Y=0,Nt(),P=0}}function Mt(){var e=U.now(),t=e-re;t>tt&&(ie-=t,re=e)}function Nt(){for(var e,t=ne,n,i=1/0;t;)t._call?(i>t._time&&(i=t._time),e=t,t=t._next):(n=t._next,t._next=null,t=e?e._next=n:ne=n);Z=e,me(i)}function me(e){if(!Y){Q&&(Q=clearTimeout(Q));var t=e-P;t>24?(e<1/0&&(Q=setTimeout(et,e-U.now()-ie)),K&&(K=clearInterval(K))):(K||(re=U.now(),K=setInterval(Mt,tt)),Y=1,nt(et))}}function it(){let e=1;return()=>(e=(1664525*e+1013904223)%4294967296)/4294967296}function ot(e){return e.x}function st(e){return e.y}var Ct=10,$t=Math.PI*(3-Math.sqrt(5));function ve(e){var t,n=1,i=.001,r=1-Math.pow(i,1/300),o=0,a=.6,h=new Map,d=oe(g),s=he("tick","end"),l=it();e==null&&(e=[]);function g(){c(),s.call("tick",t),n<i&&(d.stop(),s.call("end",t))}function c(p){var u,m=e.length,y;p===void 0&&(p=1);for(var b=0;b<p;++b)for(n+=(o-n)*r,h.forEach(function(x){x(n)}),u=0;u<m;++u)y=e[u],y.fx==null?y.x+=y.vx*=a:(y.x=y.fx,y.vx=0),y.fy==null?y.y+=y.vy*=a:(y.y=y.fy,y.vy=0);return t}function f(){for(var p=0,u=e.length,m;p<u;++p){if(m=e[p],m.index=p,m.fx!=null&&(m.x=m.fx),m.fy!=null&&(m.y=m.fy),isNaN(m.x)||isNaN(m.y)){var y=Ct*Math.sqrt(.5+p),b=p*$t;m.x=y*Math.cos(b),m.y=y*Math.sin(b)}(isNaN(m.vx)||isNaN(m.vy))&&(m.vx=m.vy=0)}}function v(p){return p.initialize&&p.initialize(e,l),p}return f(),t={tick:c,restart:function(){return d.restart(g),t},stop:function(){return d.stop(),t},nodes:function(p){return arguments.length?(e=p,f(),h.forEach(v),t):e},alpha:function(p){return arguments.length?(n=+p,t):n},alphaMin:function(p){return arguments.length?(i=+p,t):i},alphaDecay:function(p){return arguments.length?(r=+p,t):+r},alphaTarget:function(p){return arguments.length?(o=+p,t):o},velocityDecay:function(p){return arguments.length?(a=1-p,t):1-a},randomSource:function(p){return arguments.length?(l=p,h.forEach(v),t):l},force:function(p,u){return arguments.length>1?(u==null?h.delete(p):h.set(p,v(u)),t):h.get(p)},find:function(p,u,m){var y=0,b=e.length,x,M,T,G,C;for(m==null?m=1/0:m*=m,y=0;y<b;++y)G=e[y],x=p-G.x,M=u-G.y,T=x*x+M*M,T<m&&(C=G,m=T);return C},on:function(p,u){return arguments.length>1?(s.on(p,u),t):s.on(p)}}}function ye(){var e,t,n,i,r=D(-30),o,a=1,h=1/0,d=.81;function s(f){var v,p=e.length,u=B(e,ot,st).visitAfter(g);for(i=f,v=0;v<p;++v)t=e[v],u.visit(c)}function l(){if(e){var f,v=e.length,p;for(o=new Array(v),f=0;f<v;++f)p=e[f],o[p.index]=+r(p,f,e)}}function g(f){var v=0,p,u,m=0,y,b,x;if(f.length){for(y=b=x=0;x<4;++x)(p=f[x])&&(u=Math.abs(p.value))&&(v+=p.value,m+=u,y+=u*p.x,b+=u*p.y);f.x=y/m,f.y=b/m}else{p=f,p.x=p.data.x,p.y=p.data.y;do v+=o[p.data.index];while(p=p.next)}f.value=v}function c(f,v,p,u){if(!f.value)return!0;var m=f.x-t.x,y=f.y-t.y,b=u-v,x=m*m+y*y;if(b*b/d<x)return x<h&&(m===0&&(m=z(n),x+=m*m),y===0&&(y=z(n),x+=y*y),x<a&&(x=Math.sqrt(a*x)),t.vx+=m*f.value*i/x,t.vy+=y*f.value*i/x),!0;if(f.length||x>=h)return;(f.data!==t||f.next)&&(m===0&&(m=z(n),x+=m*m),y===0&&(y=z(n),x+=y*y),x<a&&(x=Math.sqrt(a*x)));do f.data!==t&&(b=o[f.data.index]*i/x,t.vx+=m*b,t.vy+=y*b);while(f=f.next)}return s.initialize=function(f,v){e=f,n=v,l()},s.strength=function(f){return arguments.length?(r=typeof f=="function"?f:D(+f),l(),s):r},s.distanceMin=function(f){return arguments.length?(a=f*f,s):Math.sqrt(a)},s.distanceMax=function(f){return arguments.length?(h=f*f,s):Math.sqrt(h)},s.theta=function(f){return arguments.length?(d=f*f,s):Math.sqrt(d)},s}function A(e){return e.replace(/&/g,"&").replace(/</g,"<")}function Lt(e){let t=e.lines.map(n=>`<div class="ev-l ${n.sign==="+"?"add":n.sign==="-"?"del":"ctx"}"><span class="ev-n">${n.n??""}</span><span class="ev-s">${n.sign===" "?"":n.sign}</span><span class="ev-t">${A(n.text)}</span></div>`).join("");return`<div class="ev"><div class="ev-h mono">${A(e.label)}${e.note?` <span class="ev-note">${A(e.note)}</span>`:""}</div><div class="ev-b mono">${t}</div>`+(e.more?`<div class="ev-more">+ ${e.more} more lines</div>`:"")+"</div>"}function xe(e){let t=e.split(/[\s._-]+/).filter(Boolean);return(t.length>=2?t[0][0]+t[1][0]:(t[0]??"?").slice(0,2)).toUpperCase()}function At(e,t=Date.now()){let n=Date.parse(`${e}T00:00:00Z`);if(!Number.isFinite(n))return e;let i=Math.max(0,Math.round((t-n)/864e5));if(i<1)return"today";if(i===1)return"yesterday";if(i<31)return`${i}d ago`;let r=Math.round(i/30);return r<24?`${r}mo ago`:`${Math.round(i/365)}y ago`}function Tt(e){let t=e.map(r=>{let o=r.handle?`@${A(r.handle)}`:A(r.name),a=r.handle?"own-name mono":"own-name";return`<div class="own"><span class="av">${A(xe(r.handle??r.name))}</span><span class="own-txt"><span class="${a}">${o}</span><span class="own-why">${r.commits} commit${r.commits===1?"":"s"} here \xB7 last ${A(At(r.last))}</span></span></div>`}).join(""),n=e.filter(r=>!r.handle),i=n.length?`<div class="own-note">\u26A0 ${A(n.map(r=>r.name).join(", "))} ${n.length===1?"has":"have"} no GitHub handle in their commit email.</div>`:"";return`<div class="owners">${t}${i}</div>`}function at(e,t,n,i,r){if(!i||!t){e.innerHTML='<div class="empty">Select a node to view details</div>';return}let o=t.nodes.find(c=>c.id===i);if(!o){e.innerHTML='<div class="empty">Select a node to view details</div>';return}let a=k(R(n,o.type)),h=c=>t.nodes.find(f=>f.id===c)?.name??c,d=t.edges.filter(c=>c.source===i),s=t.edges.filter(c=>c.target===i),l=`<span class="d-type"><span class="sw" style="background:${a}"></span>${A(o.type)}</span>`;if(l+=`<h3>${A(o.name)}</h3>`,o.summary&&(l+=`<p class="summary">${A(o.summary)}</p>`),o.owners?.length&&(l+=`<div class="d-label"><span class="dot" style="background:var(--con)"></span>Who knows this \xB7 ${o.owners.length}</div>`,l+=Tt(o.owners)),o.evidence?.length){l+=`<div class="d-label">Code \xB7 ${o.evidence.length}</div>`;for(let f of o.evidence)l+=Lt(f);let c=o.sources.length-o.evidence.length;c>0&&(l+=`<div class="src mono">+ ${c} more, not shown</div>`)}else if(o.sources.length){l+=`<div class="d-label">Sources \xB7 ${o.sources.length}</div>`;for(let c of o.sources)l+=`<div class="src mono">${A(c)}</div>`}let g=(c,f,v,p)=>{if(c.length){l+=`<div class="d-label"><span class="dot" style="background:${f}"></span>${v} \xB7 ${c.length}</div>`;for(let u of c)l+=`<button class="lnk" data-go="${A(p(u))}"><span class="rel">${A(u.relation.replace(/_/g," "))}</span> <span class="to">${A(h(p(u)))}</span>`+(u.description?`<div class="desc">${A(u.description)}</div>`:"")+"</button>"}};g(d,k("--fil"),"Depends on",c=>c.target),g(s,k("--accent"),"Depended on by",c=>c.source),e.innerHTML=l,e.querySelectorAll("[data-go]").forEach(c=>{c.addEventListener("click",()=>r(c.dataset.go))})}var St="http://www.w3.org/2000/svg",Gt=2;function N(e,t){let n=document.createElementNS(St,e);for(let[i,r]of Object.entries(t))n.setAttribute(i,String(r));return n}function Vt(e){let t=e.owners??[];if(t.length===0)return null;let n=t.slice(0,Gt),i=t.length-n.length,r=[...n.map(a=>xe(a.handle??a.name)),...i>0?[`+${i}`]:[]],o=N("g",{"pointer-events":"none"});return r.forEach((a,h)=>{let d=e.r*.72+h*13,s=-e.r*.72+h*8;o.appendChild(N("circle",{cx:d,cy:s,r:8,fill:k("--panel"),stroke:k("--con"),"stroke-width":1.2}));let l=N("text",{x:d,y:s+3,"text-anchor":"middle","font-size":7.5,"font-weight":700,fill:k("--con")});l.textContent=a;let g=N("title",{});g.textContent=t.map(c=>`${c.handle?`@${c.handle}`:c.name} \u2014 ${c.commits} commits`).join(`
|
|
2
|
+
`),o.append(l,g)}),o}var se=class{svg;defs;viewport;sim=null;nodes=[];edges=[];edgeEls=[];nodeEls=[];view={x:0,y:0,k:1};panMoved=!1;tab="context";selected=null;query="";hiddenRels={};hiddenTypes={};showOwners=!0;onSelect=()=>{};constructor(t){this.svg=t,this.buildChrome(),this.bindPanZoom()}buildChrome(){this.svg.textContent="",this.defs=N("defs",{}),this.svg.appendChild(this.defs),this.viewport=N("g",{}),this.svg.appendChild(this.viewport),this.svg.addEventListener("click",()=>{if(this.panMoved){this.panMoved=!1;return}this.select(null)})}ensureMarkers(){this.defs.textContent="";let t=N("marker",{id:"arr",viewBox:"0 0 10 10",refX:8,refY:5,markerWidth:4.5,markerHeight:4.5,orient:"auto-start-reverse"});t.appendChild(N("path",{d:"M2,1.5L8.5,5L2,8.5",fill:"none",stroke:k("--edge"),"stroke-width":1.8,"stroke-linecap":"round","stroke-linejoin":"round",opacity:.75}));let n=N("marker",{id:"arrH",viewBox:"0 0 12 12",refX:10,refY:6,markerWidth:6.5,markerHeight:6.5,orient:"auto-start-reverse"});n.appendChild(N("path",{d:"M1.5,1.5L10.5,6L1.5,10.5z",fill:k("--canvas"),stroke:k("--edge"),"stroke-width":1.4}));let i=N("marker",{id:"arrOut",viewBox:"0 0 10 10",refX:8,refY:5,markerWidth:5,markerHeight:5,orient:"auto-start-reverse"});i.appendChild(N("path",{d:"M1,1L9,5L1,9z",fill:k("--fil")}));let r=N("marker",{id:"arrIn",viewBox:"0 0 10 10",refX:8,refY:5,markerWidth:5,markerHeight:5,orient:"auto-start-reverse"});r.appendChild(N("path",{d:"M1,1L9,5L1,9z",fill:k("--accent")}));for(let o of[t,n,i,r])this.defs.appendChild(o)}setData(t,n){this.tab=n;let i=new Map(this.nodes.map(d=>[d.id,d])),r={};for(let d of t.edges)r[d.source]=(r[d.source]??0)+1,r[d.target]=(r[d.target]??0)+1;let o=this.svg.clientWidth||800,a=this.svg.clientHeight||600;this.nodes=t.nodes.map((d,s)=>{let l=i.get(d.id),g=s/Math.max(1,t.nodes.length)*Math.PI*2,c=r[d.id]??0;return{id:d.id,name:d.name,type:d.type,owners:d.owners,deg:c,r:11+Math.min(13,c*2.6),x:l?.x??o/2+Math.cos(g)*Math.min(o,a)/4,y:l?.y??a/2+Math.sin(g)*Math.min(o,a)/4,vx:l?.vx??0,vy:l?.vy??0}});let h=new Map(this.nodes.map(d=>[d.id,d]));this.edges=t.edges.map(d=>({source:h.get(d.source),target:h.get(d.target),relation:d.relation,description:d.description,confidence:d.confidence})).filter(d=>d.source&&d.target),this.sim?.stop(),this.sim=ve(this.nodes).force("charge",ye().strength(-220)).force("link",fe(this.edges).distance(d=>$e[F(d.relation)]).strength(.5)).force("center",ce(o/2,a/2)).force("collide",ue().radius(d=>d.r+6)).on("tick",()=>this.tick()),this.buildElements(),this.restyle()}buildElements(){this.ensureMarkers(),this.viewport.textContent="",this.edgeEls=this.edges.map(t=>{let n=N("path",{fill:"none","stroke-linecap":"round"}),i=N("title",{});i.textContent=t.relation.replace(/_/g," ")+(t.description?` \u2014 ${t.description}`:""),n.appendChild(i);let r=N("text",{"text-anchor":"middle","font-size":9.5,"font-weight":700,"stroke-width":3,"paint-order":"stroke",display:"none"});return r.textContent=t.relation.replace(/_/g," "),this.viewport.appendChild(n),this.viewport.appendChild(r),{path:n,label:r,edge:t}}),this.nodeEls=this.nodes.map(t=>{let n=N("g",{cursor:"pointer"}),i=N("circle",{fill:"none","stroke-width":1.6,opacity:0,r:t.r+5}),r=N("circle",{r:t.r,opacity:.92}),o=N("text",{y:t.r+15,"text-anchor":"middle","font-size":11.5,"font-weight":600});o.textContent=t.name;let a=Vt(t);return n.append(i,r,o),a&&n.appendChild(a),n.addEventListener("click",h=>{h.stopPropagation(),this.select(t.id)}),this.bindDrag(n,t),this.viewport.appendChild(n),{group:n,circle:r,ring:i,label:o,badges:a,node:t}})}tick(){for(let{path:t,label:n,edge:i}of this.edgeEls){let r=i.source,o=i.target,a=(o.x??0)-(r.x??0),h=(o.y??0)-(r.y??0),d=Math.sqrt(a*a+h*h)||1,s=a/d,l=h/d,g=(r.x??0)+s*(r.r+2),c=(r.y??0)+l*(r.r+2),f=(o.x??0)-s*(o.r+6),v=(o.y??0)-l*(o.r+6),p=(g+f)/2-l*10,u=(c+v)/2+s*10;t.setAttribute("d",`M${g},${c} Q${p},${u} ${f},${v}`),n.setAttribute("x",String((g+f)/2-l*14)),n.setAttribute("y",String((c+v)/2+s*14))}for(let{group:t,node:n}of this.nodeEls)t.setAttribute("transform",`translate(${n.x??0},${n.y??0})`)}restyle(){this.ensureMarkers();let t=new Set;if(this.selected)for(let r of this.edges)r.source.id===this.selected&&t.add(r.target.id),r.target.id===this.selected&&t.add(r.source.id);let n=this.query.toLowerCase(),i=r=>!this.hiddenTypes[r.type];for(let{path:r,label:o,edge:a}of this.edgeEls){let h=i(a.source)&&i(a.target)&&!this.hiddenRels[ee(a.relation)];if(r.style.display=h?"":"none",o.setAttribute("display","none"),!h)continue;let d=F(a.relation),s=k("--edge"),l=1.3,g="none",c=.5,f="url(#arr)";d==="structure"?(l=2.4,c=.32,f="none"):d==="dependency"?(l=1.5,c=.55):d==="contract"?(c=.55,f="url(#arrH)"):(g="2 5",l=1.2,c=.28,f="none"),a.confidence==="inferred"&&(g="5 4"),n&&(c=.12);let v=this.selected?a.source.id===this.selected?"out":a.target.id===this.selected?"in":"far":"none";v==="out"?(s=k("--fil"),c=.95,l+=.7,f="url(#arrOut)"):v==="in"?(s=k("--accent"),c=.95,l+=.7,f="url(#arrIn)"):v==="far"&&(c=.06),r.setAttribute("stroke",s),r.setAttribute("stroke-width",String(l)),r.setAttribute("stroke-dasharray",g),r.setAttribute("opacity",String(c)),f==="none"?r.removeAttribute("marker-end"):r.setAttribute("marker-end",f),(v==="out"||v==="in")&&(o.removeAttribute("display"),o.setAttribute("fill",s),o.setAttribute("stroke",k("--canvas")))}for(let{group:r,circle:o,ring:a,label:h,badges:d,node:s}of this.nodeEls){let l=i(s);if(r.style.display=l?"":"none",!l)continue;let c=!n||s.name.toLowerCase().includes(n)?1:.22;this.selected&&s.id!==this.selected&&!t.has(s.id)&&(c=Math.min(c,.2)),r.setAttribute("opacity",String(c));let f=k(R(this.tab,s.type));o.setAttribute("fill",f),a.setAttribute("stroke",f),a.setAttribute("opacity",s.id===this.selected?"0.55":"0"),h.setAttribute("fill",k("--ink")),d&&(d.style.display=this.showOwners?"":"none")}}select(t){this.selected=t,this.restyle(),this.onSelect(t)}focus(t){let n=this.nodes.find(o=>o.id===t);if(!n)return;let i=this.svg.clientWidth,r=this.svg.clientHeight;this.view.k=Math.max(this.view.k,1.4),this.view.x=i/2-(n.x??0)*this.view.k,this.view.y=r/2-(n.y??0)*this.view.k,this.applyView(),this.select(t)}firstMatch(){let t=this.query.toLowerCase();return this.nodes.find(n=>!this.hiddenTypes[n.type]&&n.name.toLowerCase().includes(t))}applyView(){this.viewport.setAttribute("transform",`translate(${this.view.x},${this.view.y}) scale(${this.view.k})`)}zoomBy(t){let n=this.svg.clientWidth/2,i=this.svg.clientHeight/2,r=Math.max(.35,Math.min(3,this.view.k*t));this.view.x=n-(n-this.view.x)*(r/this.view.k),this.view.y=i-(i-this.view.y)*(r/this.view.k),this.view.k=r,this.applyView()}resetView(){this.view={x:0,y:0,k:1},this.applyView()}reheat(){this.sim?.alpha(.6).restart()}bindDrag(t,n){t.addEventListener("pointerdown",i=>{i.stopPropagation(),t.setPointerCapture(i.pointerId);let r=a=>{let h=this.svg.getBoundingClientRect();n.fx=(a.clientX-h.left-this.view.x)/this.view.k,n.fy=(a.clientY-h.top-this.view.y)/this.view.k,this.sim?.alphaTarget(.25).restart()},o=()=>{n.fx=null,n.fy=null,this.sim?.alphaTarget(0),t.removeEventListener("pointermove",r),t.removeEventListener("pointerup",o)};t.addEventListener("pointermove",r),t.addEventListener("pointerup",o)})}bindPanZoom(){let n=null,i={x:0,y:0};this.svg.addEventListener("pointerdown",r=>{n={x:r.clientX-this.view.x,y:r.clientY-this.view.y},i={x:r.clientX,y:r.clientY},this.panMoved=!1}),this.svg.addEventListener("pointermove",r=>{n&&(!this.panMoved&&Math.hypot(r.clientX-i.x,r.clientY-i.y)>4&&(this.panMoved=!0),this.view.x=r.clientX-n.x,this.view.y=r.clientY-n.y,this.applyView())}),window.addEventListener("pointerup",()=>{n=null}),this.svg.addEventListener("wheel",r=>{r.preventDefault();let o=this.svg.getBoundingClientRect(),a=r.clientX-o.left,h=r.clientY-o.top,d=Math.max(.35,Math.min(3,this.view.k*Math.exp(-r.deltaY*.0016)));this.view.x=a-(a-this.view.x)*(d/this.view.k),this.view.y=h-(h-this.view.y)*(d/this.view.k),this.view.k=d,this.applyView()},{passive:!1})}};function we(e){return e.replace(/&/g,"&").replace(/</g,"<")}function q(e,t,n,i,r){let o=s=>t.edges.filter(l=>l.relation==="contains"&&l.source===s).map(l=>t.nodes.find(g=>g.id===l.target)).filter(l=>!!l),a=s=>{let l=o(s);return l.length+l.reduce((g,c)=>g+a(c.id),0)},h=t.nodes.filter(s=>s.type==="file"),d=s=>{let l=o(s.id),g=i[s.id]!==!1,c=`<button class="tree-row${g?" open":""}${n===s.id?" sel":""}" data-id="${we(s.id)}" data-haskids="${l.length?1:0}"><span class="chev">${l.length?"\u25B6":""}</span><span class="k" style="background:${k(R("code",s.type))}"></span><span class="t${s.type==="file"?" mono":""}">${we(s.name)}</span><span class="badge">${l.length?a(s.id)+" sym":we(s.type)}</span></button>`;return l.length&&g&&(c+=`<div class="tree-kids">${l.map(d).join("")}</div>`),c};e.innerHTML='<div class="tree-tools"><button data-tool="expand">Expand all</button><button data-tool="collapse">Collapse all</button></div>'+h.map(d).join(""),e.querySelectorAll(".tree-row").forEach(s=>{s.addEventListener("click",()=>{let l=s.dataset.id;s.dataset.haskids==="1"&&(i[l]=i[l]===!1,q(e,t,l,i,r)),r(l)})}),e.querySelector('[data-tool="expand"]')?.addEventListener("click",()=>{for(let s of Object.keys(i))delete i[s];q(e,t,n,i,r)}),e.querySelector('[data-tool="collapse"]')?.addEventListener("click",()=>{for(let s of t.nodes)i[s.id]=!1;q(e,t,n,i,r)})}var _=e=>document.getElementById(e),E={tab:"context",context:null,code:null,outlineOpen:{}},w=new se(_("graphSvg"));function J(){return E.tab==="context"?E.context:E.code}function Ee(){return E.tab==="code"||E.tab==="outline"?"code":"context"}function Me(){let e=_("edgeChips");e.innerHTML='<span class="cap">Edges</span>';let t=J();if(!t)return;let n=new Map;for(let r of t.edges){let o=ee(r.relation);n.set(o,(n.get(o)??0)+1)}let i=[...n.keys()].sort((r,o)=>{let a=h=>h==="part of"?0:h==="uses"?1:2;return a(r)-a(o)||r.localeCompare(o)});for(let r of i){let o=document.createElement("button");o.type="button",o.className="echip"+(w.hiddenRels[r]?"":" on"),o.innerHTML=`${zt(r)} ${r} <span style="opacity:.55">${n.get(r)}</span>`,o.title=(Le[r]??`"${r}" edges`)+" \u2014 click to "+(w.hiddenRels[r]?"show":"hide"),o.addEventListener("click",()=>{w.hiddenRels[r]=!w.hiddenRels[r],Me(),w.restyle(),Ne()}),e.appendChild(o)}}function zt(e){let t=e==="part of"?"structure":e==="uses"?"dependency":F(e.replace(/ /g,"_"));return{structure:'<svg width="20" height="8" aria-hidden="true"><line x1="1" y1="4" x2="19" y2="4" stroke="currentColor" stroke-width="3" opacity=".5"/></svg>',dependency:'<svg width="20" height="8" aria-hidden="true"><line x1="1" y1="4" x2="14" y2="4" stroke="currentColor" stroke-width="1.6"/><path d="M14,1 L19,4 L14,7 z" fill="currentColor"/></svg>',contract:'<svg width="20" height="8" aria-hidden="true"><line x1="1" y1="4" x2="13" y2="4" stroke="currentColor" stroke-width="1.4"/><path d="M13,1 L19,4 L13,7 z" fill="none" stroke="currentColor" stroke-width="1.2"/></svg>',association:'<svg width="20" height="8" aria-hidden="true"><line x1="1" y1="4" x2="19" y2="4" stroke="currentColor" stroke-width="1.4" stroke-dasharray="2 4" opacity=".7"/></svg>'}[t]}function ae(){let e=_("legend");e.innerHTML="";let t=J();if(!t)return;let n=new Map;for(let r of t.nodes)n.set(r.type,(n.get(r.type)??0)+1);for(let[r,o]of n){let a=document.createElement("button");a.type="button",a.className="lchip"+(w.hiddenTypes[r]?" off":""),a.innerHTML=`<span class="sw" style="background:${k(R(Ee(),r))}"></span>${r} <span style="color:var(--muted);font-weight:500">${o}</span>`,a.addEventListener("click",()=>{w.hiddenTypes[r]=!w.hiddenTypes[r],ae(),w.restyle(),Ne()}),e.appendChild(a)}if(t.nodes.some(r=>r.owners?.length)){let r=document.createElement("button");r.type="button",r.className="lchip lchip-people"+(w.showOwners?"":" off"),r.innerHTML=`<span class="sw" style="background:${k("--con")}"></span>people`,r.title="Show who has worked on each area",r.addEventListener("click",()=>{w.showOwners=!w.showOwners,ae(),w.restyle()}),e.appendChild(r)}}function Ne(){let e=J();if(!e){_("lcount").textContent="";return}let t=e.nodes.filter(n=>!w.hiddenTypes[n.type]).length;_("lcount").textContent=`${t} / ${e.nodes.length} nodes shown`}function Dt(){let e=_("counts");if(E.tab==="outline"&&E.code){let t=E.code.nodes.filter(n=>n.type==="file").length;e.textContent=`${t} files \xB7 ${E.code.nodes.length} symbols`}else{let t=J();e.textContent=t?`${t.meta.nodeCount} nodes \xB7 ${t.meta.edgeCount} links`:""}}function j(e){at(_("detail"),E.tab==="context"?E.context:E.code,Ee(),e,t=>{E.tab==="outline"?(j(t),q(_("tree"),E.code,t,E.outlineOpen,j)):w.focus(t)})}w.onSelect=e=>j(e);function dt(e){E.tab=e,document.querySelectorAll(".tab").forEach(i=>{i.setAttribute("aria-selected",i.dataset.tab===e?"true":"false")});let t=e==="outline";_("canvasWrap").hidden=t,_("outlineView").hidden=!t,w.hiddenRels={},w.hiddenTypes={},w.selected=null,j(null);let n=_("graphEmpty");if(e==="outline")E.code?q(_("tree"),E.code,null,E.outlineOpen,j):(_("outlineView").hidden=!0,_("canvasWrap").hidden=!1,lt('No code graph yet \u2014 run <code>graft graph</code> to generate <span class="mono">graph.json</span>.'));else{let i=J();!i||i.nodes.length===0?lt(i?.meta.emptyNote?Ht(i.meta.emptyNote):e==="code"?'No code graph yet \u2014 run <code>graft graph</code> to generate <span class="mono">graph.json</span>.':"No context graph \u2014 run <code>graft init</code> first."):(n.hidden=!0,w.resetView(),w.setData(i,Ee()),w.reheat())}Me(),ae(),Ne(),Dt()}function Ht(e){return e.replace(/&/g,"&").replace(/</g,"<")}function lt(e){let t=_("graphEmpty");t.innerHTML=e,t.hidden=!1}document.querySelectorAll(".tab").forEach(e=>{e.addEventListener("click",()=>dt(e.dataset.tab))});var ke=_("search");ke.addEventListener("input",()=>{w.query=ke.value.trim(),w.restyle()});ke.addEventListener("keydown",e=>{if(e.key==="Enter"&&w.query){let t=w.firstMatch();t&&w.focus(t.id)}});_("zin").addEventListener("click",()=>w.zoomBy(1.25));_("zout").addEventListener("click",()=>w.zoomBy(1/1.25));_("zreset").addEventListener("click",()=>w.resetView());var ut="graft-viz-theme",ct=localStorage.getItem(ut);ct&&document.documentElement.setAttribute("data-theme",ct);_("themeBtn").addEventListener("click",()=>{let e=document.documentElement,t=e.getAttribute("data-theme"),n=window.matchMedia("(prefers-color-scheme: dark)").matches,r=(t?t==="dark":n)?"light":"dark";e.setAttribute("data-theme",r),localStorage.setItem(ut,r),w.restyle(),Me(),ae(),j(w.selected)});var ft="graft-viz-detail-w",_e=220,Ot=document.documentElement,It=e=>Math.min(Math.max(_e,Math.round(window.innerWidth*.6)),Math.max(_e,Math.round(e)));function Ce(e,t=!0){let n=It(e);Ot.style.setProperty("--detail-w",`${n}px`),t&&localStorage.setItem(ft,String(n))}var be=Number(localStorage.getItem(ft));Number.isFinite(be)&&be>=_e&&Ce(be,!1);var W=_("detailResizer"),le=!1;W.addEventListener("pointerdown",e=>{let t=e;le=!0,W.setPointerCapture(t.pointerId),document.body.style.cursor="col-resize",e.preventDefault()});W.addEventListener("pointermove",e=>{le&&Ce(window.innerWidth-e.clientX)});var ht=e=>{if(le){le=!1,document.body.style.cursor="";try{W.releasePointerCapture(e.pointerId)}catch{}w.reheat()}};W.addEventListener("pointerup",ht);W.addEventListener("pointercancel",ht);W.addEventListener("keydown",e=>{let t=e;if(t.key!=="ArrowLeft"&&t.key!=="ArrowRight")return;let n=t.shiftKey?40:16,i=_("detail").getBoundingClientRect().width;Ce(i+(t.key==="ArrowLeft"?n:-n)),w.reheat(),e.preventDefault()});async function pt(){let[e,t]=await Promise.all([Ae(),Te()]);E.context=e,E.code=t;let n=[e.meta.repoName,e.meta.subtitle].filter(Boolean).join(" \xB7 ");_("repoName").textContent=n,document.title=`graft viz \u2014 ${n}`;let i=e.meta.tabs;i&&document.querySelectorAll(".tab").forEach(o=>{o.hidden=!i.includes(o.dataset.tab)});let r=e.meta.defaultTab;dt(r&&r!==E.tab?r:E.tab)}Se(()=>{let e=w.selected;pt().then(()=>{e&&(w.selected=e,w.restyle(),j(e))})});pt();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nanonets/graft",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Build a repo's context graph as a folder of linked markdown files: a local, regenerable cache that every query keeps in sync with your code.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -55,9 +55,9 @@
|
|
|
55
55
|
"node": ">=20"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@anthropic-ai/sdk": "^0.
|
|
58
|
+
"@anthropic-ai/sdk": "^0.133.0",
|
|
59
59
|
"commander": "^15.0.0",
|
|
60
|
-
"dotenv": "^
|
|
60
|
+
"dotenv": "^18.0.7",
|
|
61
61
|
"gray-matter": "^4.0.3",
|
|
62
62
|
"openai": "^7.8.0",
|
|
63
63
|
"tree-sitter": "^0.21.1",
|
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
"tree-sitter-r": "npm:@davisvaughan/tree-sitter-r@^1.3.0",
|
|
70
70
|
"tree-sitter-swift": "^0.7.1",
|
|
71
71
|
"tree-sitter-typescript": "^0.23.2",
|
|
72
|
-
"tree-sitter-wasm": "^
|
|
72
|
+
"tree-sitter-wasm": "^2.0.4",
|
|
73
73
|
"vscode-jsonrpc": "^8.2.1",
|
|
74
74
|
"vscode-languageserver-protocol": "^3.18.2",
|
|
75
|
-
"web-tree-sitter": "^0.
|
|
75
|
+
"web-tree-sitter": "^0.27.1"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"@types/d3-force": "^3.0.10",
|
package/scripts/run-tests.mjs
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* Enumerating the files here instead means `npm test` behaves identically in
|
|
12
12
|
* cmd.exe, PowerShell, bash and CI, on any supported Node.
|
|
13
13
|
*/
|
|
14
|
-
import { readdirSync } from "node:fs";
|
|
14
|
+
import { mkdtempSync, readdirSync, rmSync } from "node:fs";
|
|
15
|
+
import { tmpdir } from "node:os";
|
|
15
16
|
import { spawnSync } from "node:child_process";
|
|
16
17
|
import { dirname, join, resolve } from "node:path";
|
|
17
18
|
import { fileURLToPath } from "node:url";
|
|
@@ -43,14 +44,25 @@ const gitEnv = {
|
|
|
43
44
|
GIT_CONFIG_KEY_1: "tag.gpgsign", GIT_CONFIG_VALUE_1: "false",
|
|
44
45
|
};
|
|
45
46
|
|
|
47
|
+
// Tests make thousands of scratch repos and homes under the temp folder and
|
|
48
|
+
// don't all remove them: a day of runs left over 50,000 folders (6 GB). Give the
|
|
49
|
+
// run its own temp folder and remove it at the end, whatever the outcome.
|
|
50
|
+
const runTmp = mkdtempSync(join(tmpdir(), "trail-test-run-"));
|
|
51
|
+
const tmpEnv = { TMPDIR: runTmp, TEMP: runTmp, TMP: runTmp };
|
|
52
|
+
|
|
46
53
|
// A graft repo moves to trail when a session opens on a machine with the trail
|
|
47
54
|
// command, so a contributor who has trail installed would see test repos move.
|
|
48
55
|
// Off for the run; the tests of the move turn it back on.
|
|
49
56
|
const result = spawnSync(process.execPath, ["--import", "tsx", "--test", ...files], {
|
|
50
57
|
cwd: repoRoot,
|
|
51
58
|
stdio: "inherit",
|
|
52
|
-
env: { ...process.env, ...gitEnv, GRAFT_NO_TRAIL_SWITCH: "1" },
|
|
59
|
+
env: { ...process.env, ...gitEnv, ...tmpEnv, GRAFT_NO_TRAIL_SWITCH: "1" },
|
|
53
60
|
});
|
|
61
|
+
try {
|
|
62
|
+
rmSync(runTmp, { recursive: true, force: true });
|
|
63
|
+
} catch {
|
|
64
|
+
/* best effort: a locked file on Windows must not fail the run */
|
|
65
|
+
}
|
|
54
66
|
|
|
55
67
|
if (result.error) {
|
|
56
68
|
console.error(`✗ could not start the test runner: ${result.error.message}`);
|