@a9n-shoji/rvw 0.4.2 → 0.5.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.
@@ -5,14 +5,14 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <meta name="color-scheme" content="light dark" />
7
7
  <title>rvw</title>
8
- <script type="module" crossorigin src="/assets/index-DUZmOKYW.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-D0LsMDeu.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-hePW80VL.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/FileIcon-wDKKQgGv.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-Czpn1I53.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/MermaidSurface-CKiZv7R8.js">
13
13
  <link rel="modulepreload" crossorigin href="/assets/ccount-DFmD81E1.js">
14
14
  <link rel="modulepreload" crossorigin href="/assets/WalkthroughPanel-D2KqSIf9.js">
15
- <link rel="stylesheet" crossorigin href="/assets/index-B0xRoLW2.css">
15
+ <link rel="stylesheet" crossorigin href="/assets/index-CUAdTtdU.css">
16
16
  </head>
17
17
  <body>
18
18
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a9n-shoji/rvw",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "Human-centered repository viewer for understanding and refining GitHub pull request changes",
5
5
  "keywords": [
6
6
  "code-review",
@@ -27,8 +27,9 @@ select a node, or claim that publication changed rvw navigation.
27
27
  ## Preflight
28
28
 
29
29
  1. Run `rvw protocol --json` and parse stdout as JSON.
30
- 2. Require `protocolVersion` 4, `agent.transport`, `structure.read`, `structure.list`, and every one of
31
- `structure.publish`, `structure.update`, or `structure.delete` needed for the task.
30
+ 2. Require `protocolVersion` 4, `agent.transport`, `structure.read`, `structure.list`,
31
+ `structure.preview`, and every one of `structure.publish`, `structure.update`, or
32
+ `structure.delete` needed for the task.
32
33
  3. Run `rvw agent status --json`. If `selectedTransport` is `unavailable`, stop and report its
33
34
  diagnostic. Otherwise use the reported transport without overriding it.
34
35
  4. Require local access to the saved repository and an exact committed source OID containing every
@@ -68,6 +69,27 @@ when relation direction is ignored. The complete Structure contains no more than
68
69
  Every `--stdin` command reads until EOF. Supply the entire object and close stdin in the same
69
70
  non-interactive invocation; do not start an interactive PTY and send only JSON plus a newline.
70
71
 
72
+ ## Preview before publishing or updating
73
+
74
+ Immediately before `publish` or `update`, preview the exact Structure content that will be sent. Omit
75
+ only command metadata: `pullRequest` and `idempotencyKey` for publication, or `expectedUpdatedAt` for
76
+ an update. Keep `sourceOid`, `title`, `scope`, `originNodeId`, `nodes`, and `edges` identical:
77
+
78
+ ```bash
79
+ rvw structure preview --stdin --json
80
+ ```
81
+
82
+ Parse the canonical `layout` diagnostics and `warnings`. Treat `maxRows >= 8`,
83
+ `nonForwardDirectionalLinkRatio >= 0.25`, or `originOutgoingDirectionalLinkCount === 0` as authoring
84
+ smells. Reconsider whether the origin is the factual behavior entrypoint, nodes are too granular,
85
+ claims or anchors overlap or nest, multiple behaviors are mixed, the subject boundary is too broad,
86
+ or nodes merely reproduce adjacent source lines.
87
+
88
+ These are not validation failures. If the factual graph does not improve after reconsideration,
89
+ publish or update it and explain why the warning remains when useful. Never change factual edge
90
+ direction, the factual origin, predicate wording, or a node responsibility claim merely to improve a
91
+ layout score. Do not implement or invoke a separate Skill-side layout preview.
92
+
71
93
  ## Publish
72
94
 
73
95
  ```bash
@@ -116,6 +138,9 @@ the result is known. After a timeout or connection loss, retry only the identica
116
138
  same key; the retry returns the original Structure. Never reuse the key for changed content.
117
139
  Publication is passive.
118
140
 
141
+ Parse any returned `warnings` as response-derived authoring feedback. They do not mean publication
142
+ failed and are not persisted graph content.
143
+
119
144
  ## Replace the current value
120
145
 
121
146
  Use an in-place update only when the requested subject identity remains the same. Preserve IDs for
@@ -54,6 +54,12 @@ can verify in committed code.
54
54
  `plain` card.
55
55
  - Prefer the smallest meaningful multi-line anchor that verifies the node claim. Use a file anchor only
56
56
  for genuinely file-wide responsibility and a single-line range only for a line-local declaration.
57
+ - Within one file, merge overlapping or nested Node anchors unless each Node expresses a distinct,
58
+ independently explainable code-centered responsibility. Do not represent both an entire method and
59
+ each of its branches as overlapping Nodes; when branches are the claims, normally omit the parent
60
+ method Node. Anchor each Node to the smallest meaningful, preferably non-overlapping range. A
61
+ file-wide anchor will overlap most other Nodes in that file, so use it deliberately. Overlap is not
62
+ an error, but retained overlap must support distinct responsibility claims.
57
63
 
58
64
  Do not create giant graphs, file inventories, one node per function, inferred runtime call graphs,
59
65
  dependency graphs obtained only from import syntax, or concept-only diagrams detached from code.
@@ -66,8 +72,13 @@ expanding merely because more static responsibilities are connected.
66
72
  Each edge is a producer claim about how two nodes relate in this subject.
67
73
 
68
74
  - Use a short verb or verb phrase: `calls`, `constructs`, `validates`, `persists`, `loads`, `implements`,
69
- `emits`, `renders`, or another fact supported by the source. Avoid vague labels such as `related to`,
70
- `part of`, `connects`, or unlabeled arrows.
75
+ `emits`, `renders`, or another fact supported by the source. As a practical authoring target, keep a
76
+ Japanese predicate around 20 full-width characters or fewer and an English predicate readable in
77
+ one or two lines at normal zoom. State only the primary predicate; do not pack conditions, reasons,
78
+ or result explanations into the Edge label. For example, prefer `キャッシュから読む` over
79
+ `設定値が存在するときのみキャッシュから読み込む`. Put necessary detail in a Node description,
80
+ Edge anchor, and the source evidence the reviewer can open. This is guidance, not a length limit.
81
+ Avoid vague labels such as `related to`, `part of`, `connects`, or unlabeled arrows.
71
82
  - Write the predicate so the claim reads naturally from the `from` Node as its actor or source to the
72
83
  `to` Node as its target. Choose the factual relationship that best explains the declared behavior,
73
84
  not an inverse or passive restatement chosen to move either endpoint on the canvas.
@@ -103,7 +114,16 @@ IDs identify claims across whole-value replacements; labels are presentation.
103
114
  starts verifying the declared behavior: for example an HTTP route, public API, command handler,
104
115
  worker trigger, event subscriber, composition call, or migration execution point. It is not required
105
116
  to be an HTTP/runtime boundary, but it must be an existing Node with its own exact source anchor. It
106
- is not persisted viewer state or a claim of architectural importance.
117
+ is not persisted viewer state or a claim of architectural importance. Do not choose a central data
118
+ structure, important-looking class, or highly connected hub merely because it seems central. When a
119
+ request starts from a file, symbol, class, or data structure, identify the concrete behavior first
120
+ and find where a reviewer factually starts verifying that behavior in source; do not mechanically
121
+ reuse the requested source as origin. A data structure or contract may still be the map's central hub,
122
+ but connectivity alone does not make it the origin.
123
+ - An origin with no outgoing unambiguous directed relation is an authoring smell: reconsider whether it
124
+ is really the factual entrypoint. A terminal or intermediate origin is still valid when the source
125
+ establishes it. Never increase origin out-degree by reversing an Edge, changing predicate wording,
126
+ or otherwise distorting relation semantics for layout quality.
107
127
  - Ensure every Node is reachable from the origin when direction, parallel multiplicity, and self-loops
108
128
  are ignored. A disconnected component is a different subject or an unsupported inventory, not a
109
129
  second island in the same Structure.
@@ -131,11 +151,20 @@ Use this checklist internally; do not reproduce it as the Structure description.
131
151
  - [ ] Each node's main claim is quickly understandable at normal zoom without relying on scrolling.
132
152
  - [ ] Concept-only nodes are necessary and do not invent semantics.
133
153
  - [ ] Every edge label states a precise relationship and direction is factual.
154
+ - [ ] Every edge label is a short verb or verb phrase readable at normal zoom and does not contain a
155
+ packed condition or explanation.
134
156
  - [ ] IDs are unique, semantic, and stable across updates; removed IDs are not recycled.
135
- - [ ] `originNodeId` names the existing source-established Node where review of this behavior starts.
157
+ - [ ] `originNodeId` names the existing source-established factual code entrypoint where review of this
158
+ behavior starts, not merely the subject's central object.
159
+ - [ ] If the origin has no outgoing unambiguous directed relation, its selection was rechecked against
160
+ the factual behavior entrypoint.
161
+ - [ ] If layout preview reports `maxRows >= 8` or a non-forward directional link ratio of at least 25%,
162
+ origin, granularity, behavior mix, and subject boundary were reconsidered.
136
163
  - [ ] The origin Node has an exact source anchor and every Node is connected to it by declared relations.
137
164
  - [ ] Every edge endpoint exists and parallel relationships have distinct IDs.
138
165
  - [ ] Every path and range is exact at the single committed `sourceOid`.
166
+ - [ ] There are no unintended overlapping or nested Node anchors in one file; any retained overlap is
167
+ justified by distinct responsibility claims.
139
168
  - [ ] The graph contains at least one source anchor and no more than 400 across all nodes and edges.
140
169
  - [ ] The map contains no hidden review conclusion, presentation layout, inferred confidence, or
141
170
  exhaustive-completeness claim.
@@ -1,5 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-hePW80VL.js";import{c as t,i as n,l as r,t as i}from"./FileIcon-wDKKQgGv.js";import{a,c as o,d as s,f as c,i as l,l as u,m as d,n as f,o as p,p as m,r as h,s as g,t as _,u as v}from"./index-DUZmOKYW.js";var y=e(r(),1),b=210,x=64,S=11,C=2;function w(e,t){return e.localeCompare(t,`en`)}function T(e){let t=[...new Set(e)],n=new Map(t.map(e=>[e,e.split(`/`)]));return new Map(t.map(e=>{let r=n.get(e);for(let i=1;i<=r.length;i+=1){let a=r.slice(-i).join(`/`);if(t.every(t=>t===e||n.get(t).slice(-i).join(`/`)!==a))return[e,a]}return[e,e]}))}function E(e,t){let n=e.anchors.flatMap(e=>{let n=t.get(e.path);return n?[n]:[]}),r=[...new Set(n)].sort(w);return{anchorCount:e.anchors.length,changeKind:r.length>1?`mixed`:r.length===1?r[0]:null}}function D(e,t,n=0,r=!1){let i=t[e.from],a=t[e.to];if(!i||!a)return null;let o=i.x+114,s=i.y+56,c=a.x+114,l=a.y+56;if(e.from===e.to){let e=i.x+228,t=i.y,r=n*.3,a=88+Math.abs(n)*.35;return{path:`M ${e+8} ${t+34+r} C ${e+a} ${t-84+r}, ${e+a} ${t+112+84+r}, ${e+8} ${t+112-34+r}`,startX:e+8,startY:t+34+r,control1X:e+a,control1Y:t-84+r,control2X:e+a,control2Y:t+112+84+r,endX:e+8,endY:t+112-34+r,bounds:{left:e+8,top:t-84+r,right:e+a,bottom:t+112+84+r}}}let u=c-o,d=l-s,f=Math.max(1,Math.hypot(u,d)),p=u/f,m=d/f,h=-m,g=p,_=Math.min(114/Math.max(1e-4,Math.abs(p)),56/Math.max(1e-4,Math.abs(m)))+8,v=o+p*_+h*n,y=s+m*_+g*n,b=c-p*_+h*n,x=l-m*_+g*n,S=Math.min(r?168:96,Math.max(r?132:n===0?28:52,f*(r?.18:.1)))+n*.35,C=v+(b-v)*.36+h*S,w=y+(x-y)*.36+g*S,T=v+(b-v)*.64+h*S,E=y+(x-y)*.64+g*S;return{path:`M ${v} ${y} C ${C} ${w}, ${T} ${E}, ${b} ${x}`,startX:v,startY:y,control1X:C,control1Y:w,control2X:T,control2Y:E,endX:b,endY:x,bounds:{left:Math.min(v,C,T,b),top:Math.min(y,w,E,x),right:Math.max(v,C,T,b),bottom:Math.max(y,w,E,x)}}}function O(e){let t=new Set(e.filter(e=>e.directed&&e.from!==e.to).map(e=>JSON.stringify([e.from,e.to])));return new Set(e.filter(e=>e.directed&&e.from!==e.to&&t.has(JSON.stringify([e.to,e.from]))).map(e=>e.id))}function k(e,t,n){let r=1-t,i=r**3*e.startX+3*r**2*t*e.control1X+3*r*t**2*e.control2X+t**3*e.endX,a=r**3*e.startY+3*r**2*t*e.control1Y+3*r*t**2*e.control2Y+t**3*e.endY,o=3*r**2*(e.control1X-e.startX)+6*r*t*(e.control2X-e.control1X)+3*t**2*(e.endX-e.control2X),s=3*r**2*(e.control1Y-e.startY)+6*r*t*(e.control2Y-e.control1Y)+3*t**2*(e.endY-e.control2Y),c=Math.max(1,Math.hypot(o,s));return{x:i+-s/c*n,y:a+o/c*n}}function A(e,t){return!(e.right<t.left||e.left>t.right||e.bottom<t.top||e.top>t.bottom)}function j(e,t,n,r,i=0){return{left:e-n/2-i,top:t-r/2-i,right:e+n/2+i,bottom:t+r/2+i}}function ee(e){return e.length===0?null:{left:Math.min(...e.map(e=>e.left)),top:Math.min(...e.map(e=>e.top)),right:Math.max(...e.map(e=>e.right)),bottom:Math.max(...e.map(e=>e.bottom))}}function M(e){return[...e].reduce((e,t)=>e+(/\p{Script=Han}|\p{Script=Hiragana}|\p{Script=Katakana}/u.test(t)?1:.56),0)}function N(e,t){return/\s/u.test(e)||/[./_-]/u.test(e)||e===`:`&&t===`:`}function P(e,t){let n=[...e.trimEnd()];for(;n.length>0&&M(n.join(``)+`…`)>t;)n.pop();return`${n.join(``).trimEnd()}…`}function te(e,t){let n=e.trim();if(!n)return[``];let r=[];for(;M(n)>t;){let e=[...n],i=0,a=0,o=0;for(let n=0;n<e.length;n+=1){let r=e[n],s=i+M(r);if(s>t&&a>0)break;if(i=s,a=n+1,N(r,e[n+1])){if(r===`:`&&e[n+1]===`:`){if(s+M(e[n+1])<=t)o=n+2;else if(n>0){o=n;break}}else o=n+1}if(i>t)break}let s=Math.min(e.length,o>0?o:Math.max(1,a));if(r.push(e.slice(0,s).join(``).trimEnd()),n=e.slice(s).join(``).trimStart(),!n)break}return n&&r.push(n),r}function F(e){let t=Math.max(.56,e.maxUnits),n=e.text.replaceAll(`\r
2
- `,`
3
- `).replaceAll(`\r`,`
4
- `).split(`
5
- `).flatMap(e=>te(e,t)),r=e.maxLines??1/0;if(n.length<=r)return n;let i=n.slice(0,Math.max(1,r));return e.ellipsize!==!1&&(i[i.length-1]=P(i[i.length-1],t)),i}function I(e,t,n){let r=Math.ceil(M(e.label)*11.5),i=Math.min(b,Math.max(x,r+S+C)),a=Math.max(1,i-S),o=F({text:e.label,maxUnits:a/11.5,ellipsize:!1}).length,s=Math.max(24,o*14+10),c=E(e,t),l=c.anchorCount>1?4:0,u=n===`source-actions`&&c.anchorCount>0?29+l:0,d=n===`source-actions`?Math.max(s,c.anchorCount>1?34:c.anchorCount===1?26:0):s;return{selectWidth:i,boxWidth:i+u,height:d,source:c}}function L(e,t,n,r,i,a,o){let s=t.flatMap(e=>{let t=n[e.id];return t?[{left:t.x,top:t.y,right:t.x+228,bottom:t.y+112}]:[]}),c=new Map,l=e=>{let t=[],n=Math.floor(e.left/128),r=Math.floor(e.right/128),i=Math.floor(e.top/128),a=Math.floor(e.bottom/128);for(let e=n;e<=r;e+=1)for(let n=i;n<=a;n+=1)t.push(`${e}:${n}`);return t},u=e=>{let t=new Set;for(let n of l(e)){let r=c.get(n);if(r){if(r.saturated)return!0;for(let n of r.boxes)if(!t.has(n)&&(t.add(n),A(e,n)))return!0}}return!1},d=e=>{for(let t of l(e)){let n=c.get(t)??{boxes:[],saturated:!1};n.saturated||(n.boxes.push(e),n.boxes.length>=48&&(n.boxes=[],n.saturated=!0)),c.set(t,n)}},f=[],p=Array.from({length:22},(e,t)=>.08+t*.04).sort((e,t)=>Math.abs(e-.5)-Math.abs(t-.5)),m=[0,12,-12,24,-24,36,-36,48,-48].flatMap(e=>p.map(t=>[t,e])),h=[...e].sort((e,t)=>w(e.id,t.id));for(let[e,t]of h.entries()){let c=D(t,n,i.get(t.id)??0,a.has(t.id));if(!c)continue;let l=I(t,r,o),p=m.map(([e,t])=>k(c,e,t)),h=p.filter(e=>{let t=j(e.x,e.y,l.boxWidth,l.height,4);return!s.some(e=>A(t,e))}),g=h.find(e=>{let t=j(e.x,e.y,l.boxWidth,l.height,5);return!u(t)}),_=h.length>0?h[e%h.length]:void 0,v=g??_??p[e%p.length];d(j(v.x,v.y,l.boxWidth,l.height,4)),f.push({edge:t,source:l.source,x:v.x,y:v.y,selectWidth:l.selectWidth,boxWidth:l.boxWidth,height:l.height,crowded:!g})}return f}function ne(e){let{structure:t,positions:n,sourceChangeKinds:r,selection:i,labelAccessory:a}=e,o=T([...t.nodes.flatMap(e=>e.anchor?[e.anchor.path]:[]),...t.edges.flatMap(e=>e.anchors.map(e=>e.path))]),s=t.nodes.flatMap(e=>{if(!i.nodeIds.has(e.id))return[];let t=n[e.id];return t?[{node:e,point:t,sourceLabel:e.anchor?o.get(e.anchor.path)??e.anchor.path:null,changeKind:e.anchor?r.get(e.anchor.path)??null:null}]:[]}),c=new Set(s.map(({node:e})=>e.id)),l=t.edges.filter(e=>i.edgeIds.has(e.id)&&c.has(e.from)&&c.has(e.to)),u=v(t.edges),d=O(t.edges),f=l.flatMap(e=>{let t=D(e,n,u.get(e.id)??0,d.has(e.id));return t?[{edge:e,geometry:t,source:E(e,r)}]:[]}),p=new Set(f.map(({edge:e})=>e.id)),m=L(l.filter(e=>p.has(e.id)&&i.labelEdgeIds.has(e.id)),s.map(({node:e})=>e),n,r,u,d,a),h=s.map(({point:e})=>({left:e.x,top:e.y,right:e.x+228,bottom:e.y+112}));return h.push(...f.map(({geometry:e})=>e.bounds)),h.push(...m.map(e=>j(e.x,e.y,e.boxWidth,e.height,4))),{nodes:s,edges:f,labels:m,bounds:ee(h)}}function re(e){let{structure:t}=e;return ne({...e,selection:{nodeIds:new Set(t.nodes.map(e=>e.id)),edgeIds:new Set(t.edges.map(e=>e.id)),labelEdgeIds:new Set(t.edges.map(e=>e.id))},labelAccessory:`none`})}var R=class extends Error{code;constructor(e){super(e),this.code=e,this.name=`StructureExportError`}},z=48,B=2,V=16384,ie=32e6,H=.5,U=`ui-monospace, SFMono-Regular, Consolas, Liberation Mono, monospace`,ae=`Arial, Helvetica Neue, sans-serif`,oe=[`default`,`added`,`modified`,`deleted`,`renamed`,`type-changed`,`mixed`],W={background:`--bg`,panel:`--panel`,text:`--text`,muted:`--muted`,line:`--line`,lineStrong:`--line-strong`,accent:`--accent`,success:`--success`,attention:`--attention`,danger:`--danger`,done:`--done`,info:`--info`};function se(e){let t=getComputedStyle(e);return Object.fromEntries(Object.entries(W).map(([e,n])=>{let r=t.getPropertyValue(n).trim();if(!r)throw new R(`INVALID_BOUNDS`);return[e,r]}))}function G(e){let t=``;for(let n of e){let e=n.codePointAt(0);(e===9||e===10||e===13||e>=32&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111)&&(t+=n)}return t}function K(e){return G(e).replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`).replaceAll(`'`,`&apos;`)}function q(e){if(!Number.isFinite(e))throw new R(`INVALID_BOUNDS`);return Number(e.toFixed(3)).toString()}function J(e,t,n){switch(e){case`added`:return t.success;case`modified`:case`mixed`:return t.attention;case`deleted`:return t.danger;case`renamed`:return t.done;case`type-changed`:return t.info;default:return n}}function Y(e){let t=e.anchor??`start`;return`<text x="${q(e.x)}" y="${q(e.firstY)}" fill="${K(e.fill)}" font-family="${K(e.fontFamily)}" font-size="${q(e.fontSize)}"${e.fontWeight?` font-weight="${e.fontWeight}"`:``} text-anchor="${t}">${e.lines.map((t,n)=>`<tspan x="${q(e.x)}" dy="${n===0?`0`:q(e.lineHeight)}">${K(t)}</tspan>`).join(``)}</text>`}function ce(e){let{node:t,point:n}=e;switch(t.notation){case`database`:return{x:n.x+10,y:n.y+21,width:208,height:84};case`component`:return{x:n.x+22,y:n.y+6,width:198,height:100};case`external`:return{x:n.x+18,y:n.y+6,width:192,height:100};case`concept`:return{x:n.x+24,y:n.y+12,width:180,height:94};default:return{x:n.x+8,y:n.y+6,width:212,height:100}}}function X(e,t,n){let{node:r,point:i}=e,a=i.x,o=i.y,s=`fill="${K(n.panel)}" stroke="${K(t)}" stroke-width="1.4"`;switch(r.notation){case`class`:case`interface`:return`<rect x="${q(a)}" y="${q(o)}" width="228" height="112" rx="2" ${s}${r.notation===`interface`?` stroke-dasharray="5 3"`:``}/>`;case`database`:{let e=a,n=a+228,r=o+10,i=o+112-10;return`<path d="M ${q(e)} ${q(r)} C ${q(e)} ${q(o-3)}, ${q(n)} ${q(o-3)}, ${q(n)} ${q(r)} L ${q(n)} ${q(i)} C ${q(n)} ${q(o+112+3)}, ${q(e)} ${q(o+112+3)}, ${q(e)} ${q(i)} Z" ${s}/><path d="M ${q(e)} ${q(r)} C ${q(e)} ${q(o+23)}, ${q(n)} ${q(o+23)}, ${q(n)} ${q(r)}" fill="none" stroke="${K(t)}" stroke-width="1.2"/>`}case`component`:return`<rect x="${q(a)}" y="${q(o)}" width="228" height="112" rx="3" ${s}/><rect x="${q(a+2)}" y="${q(o+36)}" width="13" height="8" ${s}/><rect x="${q(a+2)}" y="${q(o+52)}" width="13" height="8" ${s}/>`;case`external`:return`<polygon points="${q(a+20)},${q(o)} ${q(a+228-20)},${q(o)} ${q(a+228)},${q(o+56)} ${q(a+228-20)},${q(o+112)} ${q(a+20)},${q(o+112)} ${q(a)},${q(o+56)}" ${s}/>`;case`concept`:return`<rect x="${q(a)}" y="${q(o)}" width="228" height="112" rx="56" ${s}/>`;default:return`<rect x="${q(a)}" y="${q(o)}" width="228" height="112" rx="8" ${s}/>`}}function le(e,t,n){let{node:r,point:i}=e,a=J(e.changeKind,n,n.lineStrong),o=ce(e),s=e.sourceLabel?F({text:e.sourceLabel,maxUnits:o.width/10,maxLines:1,ellipsize:!0}):[],c=s.length>0?17:0,l=s.length>0?3:4,u=F({text:r.label,maxUnits:o.width/11,maxLines:l,ellipsize:!0}),d=14.5,f=Math.max(1,u.length)*d,p=o.y+c+f+3,m=12.6,h=Math.max(0,Math.floor((o.y+o.height-p)/m)),g=h>0?F({text:r.description??`Producerによる説明なし`,maxUnits:o.width/9,maxLines:h,ellipsize:!0}):[],_=r.notation===`class`||r.notation===`interface`?`<line x1="${q(o.x)}" y1="${q(p-2)}" x2="${q(o.x+o.width)}" y2="${q(p-2)}" stroke="${K(a)}" stroke-width="1"/>`:``,v=(()=>{switch(r.notation){case`external`:return{x:i.x+22,top:i.y+16,bottom:i.y+112-16};case`concept`:return{x:i.x+20,top:i.y+24,bottom:i.y+112-24};case`database`:return{x:i.x+5,top:i.y+18,bottom:i.y+112-18};case`component`:return{x:i.x+18,top:i.y+10,bottom:i.y+112-10};default:return{x:i.x+4,top:i.y+10,bottom:i.y+112-10}}})(),y=r.id===t.originNodeId?`<line data-node-origin-mark="true" x1="${q(v.x)}" y1="${q(v.top)}" x2="${q(v.x)}" y2="${q(v.bottom)}" stroke="${K(n.accent)}" stroke-width="4" stroke-linecap="round"/>`:``,b=s.length>0?Y({lines:s,x:o.x,firstY:o.y+10,lineHeight:12,fontSize:10,fontFamily:U,fill:n.muted,fontWeight:600}):``,x=o.y+c+10,S=Y({lines:u,x:o.x,firstY:x,lineHeight:d,fontSize:11,fontFamily:U,fill:n.text,fontWeight:700}),C=g.length>0?Y({lines:g,x:o.x,firstY:p+9,lineHeight:m,fontSize:9,fontFamily:ae,fill:n.muted}):``;return`<g data-node-id="${K(r.id)}" data-node-notation="${K(r.notation)}"${r.id===t.originNodeId?` data-origin-node="true"`:``}${e.changeKind?` data-source-change-kind="${K(e.changeKind)}"`:``}>${X(e,a,n)}${y}<g data-node-content="true">${b}${S}${_}${C}</g><title>${K(r.label)}</title><desc>${K(r.description??``)}</desc></g>`}function ue(e,t){let n=e.nodes.length===t.nodes.length&&e.edges.length===t.edges.length&&e.labels.length===t.edges.length&&e.bounds!==null,r=e.bounds?[e.bounds.left,e.bounds.top,e.bounds.right,e.bounds.bottom].every(Number.isFinite):!1;if(!n||!r)throw new R(`INCOMPLETE_LAYOUT`)}function de(e,t){let n=J(e.source.changeKind,t,t.accent),r=Math.max(1,(e.selectWidth-11)/11.5),i=F({text:e.edge.label,maxUnits:r,ellipsize:!1}),a=-((i.length-1)*14)/2+3.5;return`<g data-edge-label-id="${K(e.edge.id)}" transform="translate(${q(e.x)} ${q(e.y)})"${e.crowded?` data-crowded="true"`:``}><rect x="${q(-e.selectWidth/2)}" y="${q(-e.height/2)}" width="${q(e.selectWidth)}" height="${q(e.height)}" rx="${q(e.height/2)}" fill="${K(t.panel)}" stroke="${K(n)}" stroke-width="1"${e.crowded?` stroke-dasharray="4 3"`:``}/>${Y({lines:i,x:0,firstY:a,lineHeight:14,fontSize:10,fontFamily:ae,fill:n,anchor:`middle`})}<title>${K(e.edge.label)}</title></g>`}function fe(e){return e??`default`}function Z(e){return`rvw-structure-arrow-${e}`}function pe(e,t){return J(e==="default"?null:e,t,t.muted)}function me(e){return oe.map(t=>{let n=pe(t,e);return`<marker id="${Z(t)}" data-edge-marker-kind="${t}" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto" markerUnits="strokeWidth"><path d="M 0 0 L 10 5 L 0 10 z" fill="${K(n)}"/></marker>`}).join(``)}function he(e){let{structure:t,model:n,palette:r}=e;ue(n,t);let i=n.bounds,a=Math.floor(i.left-z),o=Math.floor(i.top-z),s=Math.ceil(i.right+z),c=Math.ceil(i.bottom+z),l=s-a,u=c-o;if(![a,o,l,u].every(Number.isFinite)||l<=0||u<=0)throw new R(`INVALID_BOUNDS`);let d=n.edges.map(({edge:e,geometry:t,source:n})=>{let i=fe(n.changeKind),a=pe(i,r);return`<path data-edge-id="${K(e.id)}" d="${K(t.path)}" fill="none" stroke="${K(a)}" stroke-width="1.4" opacity="${n.changeKind?`0.76`:`0.58`}"${e.directed?` marker-end="url(#${Z(i)})"`:``}/>`}).join(``),f=n.labels.map(e=>de(e,r)).join(``),p=n.nodes.map(e=>le(e,t,r)).join(``);return{source:`<?xml version="1.0" encoding="UTF-8"?>\n<svg xmlns="http://www.w3.org/2000/svg" width="${l}" height="${u}" viewBox="${a} ${o} ${l} ${u}" role="img" aria-labelledby="rvw-structure-title rvw-structure-description" data-rvw-structure-id="${K(t.id)}" data-rvw-source-oid="${K(t.sourceOid)}"><title id="rvw-structure-title">${K(t.title)}</title><desc id="rvw-structure-description">${K(t.scope)}</desc><defs>${me(r)}</defs><rect x="${a}" y="${o}" width="${l}" height="${u}" fill="${K(r.background)}"/><g data-layer="edges">${d}</g><g data-layer="edge-labels">${f}</g><g data-layer="nodes">${p}</g></svg>`,width:l,height:u,viewBox:{x:a,y:o,width:l,height:u}}}function ge(e,t){if(!Number.isFinite(e)||!Number.isFinite(t)||e<=0||t<=0)throw new R(`INVALID_BOUNDS`);let n=Math.min(B,V/e,V/t,Math.sqrt(ie/(e*t)));if(!Number.isFinite(n)||n<H)throw new R(`PNG_TOO_LARGE`);return{scale:n,pixelWidth:Math.max(1,Math.floor(e*n)),pixelHeight:Math.max(1,Math.floor(t*n)),downscaled:n<B}}function _e(e,t){return e.source.replace(/(<svg\b[^>]*\bwidth=")[^"]*(")/u,`$1${t.pixelWidth}$2`).replace(/(<svg\b[^>]*\bheight=")[^"]*(")/u,`$1${t.pixelHeight}$2`)}async function ve(e,t){let n=new Blob([_e(e,t)],{type:`image/svg+xml;charset=utf-8`}),r=URL.createObjectURL(n);try{let e=new Image;e.decoding=`async`,await new Promise((t,n)=>{e.onload=()=>t(),e.onerror=()=>n(new R(`PNG_DECODE_FAILED`)),e.src=r});let n=window.document.createElement(`canvas`);n.width=t.pixelWidth,n.height=t.pixelHeight;let i=n.getContext(`2d`);if(!i)throw new R(`PNG_ENCODE_FAILED`);return i.drawImage(e,0,0,t.pixelWidth,t.pixelHeight),await new Promise((e,t)=>{n.toBlob(n=>n?e(n):t(new R(`PNG_ENCODE_FAILED`)),`image/png`)})}finally{URL.revokeObjectURL(r)}}function ye(e,t){return`rvw-structure-${[...G(e.title).replace(/[<>:"\\|?*]+|\//gu,`-`).replace(/\s+/gu,`-`).replace(/-+/gu,`-`).replace(/^[.\s-]+|[.\s-]+$/gu,``)].slice(0,80).join(``)||`structure`}-${e.sourceOid.slice(0,8)}.${t}`}function be(e,t){let n=URL.createObjectURL(e),r=window.document.createElement(`a`);r.href=n,r.download=t,r.style.display=`none`,window.document.body.append(r),r.click(),r.remove(),window.setTimeout(()=>URL.revokeObjectURL(n),0)}function xe(e){if(e instanceof R)switch(e.code){case`INCOMPLETE_LAYOUT`:return`Structure全体の配置を構築できませんでした。レイアウトを戻して再実行してください。`;case`PNG_TOO_LARGE`:return`図がPNGの安全なサイズを超えています。SVGを使用するか、Node配置を近づけてから再実行してください。`;case`PNG_DECODE_FAILED`:return`Structure SVGをPNGへ変換できませんでした。SVG形式で再実行してください。`;case`PNG_ENCODE_FAILED`:return`PNGファイルを生成できませんでした。SVG形式で再実行してください。`;case`INVALID_BOUNDS`:return`Structureの出力範囲を計算できませんでした。`}return e instanceof Error?e.message:`Structureをエクスポートできませんでした。`}var Q=t();function Se({disabled:e,exporting:t,onExport:n}){let r=(0,y.useRef)(null),i=e=>{r.current?.removeAttribute(`open`),n(e)};return(0,Q.jsxs)(`details`,{className:`structure-export-menu`,ref:r,children:[(0,Q.jsxs)(`summary`,{className:`structure-header-action`,"aria-label":`Structureをエクスポート`,"aria-disabled":e,onClick:t=>{e&&t.preventDefault()},children:[t?`${t.toUpperCase()}…`:`Export`,(0,Q.jsx)(`span`,{"aria-hidden":`true`,children:`▾`})]}),(0,Q.jsxs)(`div`,{className:`structure-export-popover`,children:[(0,Q.jsxs)(`button`,{type:`button`,disabled:e,onClick:()=>i(`svg`),children:[(0,Q.jsx)(`strong`,{children:`SVG`}),(0,Q.jsx)(`span`,{children:`全体・ベクター`})]}),(0,Q.jsxs)(`button`,{type:`button`,disabled:e,onClick:()=>i(`png`),children:[(0,Q.jsx)(`strong`,{children:`PNG`}),(0,Q.jsx)(`span`,{children:`全体・2×`})]}),(0,Q.jsx)(`p`,{children:`現在の配置で、全Node・全Relation・全Edge labelを書き出します。`})]})]})}var Ce=2,we=.005,Te=.002;function $(e){return e.startLine===null?e.path:`${e.path}:${e.startLine}${e.endLine===e.startLine?``:`-${e.endLine}`}`}function Ee({anchor:e,compact:t=!1,onOpen:n}){let r=`${$(e)}を開く`;return(0,Q.jsxs)(`button`,{type:`button`,className:`structure-source${t?` compact`:``}`,title:r,"aria-label":r,onPointerDown:e=>e.stopPropagation(),onClick:e=>{e.stopPropagation(),n(e.metaKey||e.ctrlKey)},children:[(0,Q.jsx)(`span`,{"aria-hidden":`true`,children:`</>`}),!t&&(0,Q.jsx)(`span`,{children:$(e)})]})}function De({edge:e,onOpen:t}){return e.anchors.length===0?null:e.anchors.length===1?(0,Q.jsx)(Ee,{compact:!0,anchor:e.anchors[0],onOpen:n=>t({kind:`edge`,edgeId:e.id,anchorIndex:0},e.anchors[0],n)}):(0,Q.jsxs)(`details`,{className:`structure-edge-sources`,children:[(0,Q.jsxs)(`summary`,{className:`structure-source compact`,"aria-label":`${e.label}のsource evidence ${e.anchors.length}件を表示`,title:`source evidence ${e.anchors.length}件`,children:[(0,Q.jsx)(`span`,{"aria-hidden":`true`,children:`</>`}),(0,Q.jsx)(`span`,{className:`structure-edge-source-count`,"aria-hidden":`true`,children:e.anchors.length})]}),(0,Q.jsx)(`div`,{className:`structure-edge-source-menu`,children:e.anchors.map((n,r)=>(0,Q.jsx)(Ee,{anchor:n,onOpen:i=>t({kind:`edge`,edgeId:e.id,anchorIndex:r},n,i)},`${e.id}:${r}`))})]})}function Oe({anchor:e,changeKind:t,sourceLabel:n}){return(0,Q.jsxs)(`span`,{className:`structure-source-identity`,"data-source-path":e.path,"data-source-change-kind":t??void 0,title:e.path,children:[(0,Q.jsx)(i,{path:e.path,kind:`file`}),t&&(0,Q.jsx)(m,{kind:t}),(0,Q.jsx)(`span`,{className:`structure-source-name`,children:n})]})}function ke({label:e}){let t=e.split(/(::|[./_-])/u);return(0,Q.jsx)(Q.Fragment,{children:t.map((e,t)=>(0,Q.jsxs)(y.Fragment,{children:[e,(e===`::`||/^[./_-]$/u.test(e))&&(0,Q.jsx)(`wbr`,{})]},`${t}-${e}`))})}function Ae({structure:e,positions:t,focusedNodeId:n,viewport:r,viewportElement:i}){let a=s(e.nodes.map(e=>e.id),t);if(!a)return null;let o=Math.max(1,a.maxX-a.minX),c=Math.max(1,a.maxY-a.minY),l=Math.min(164/o,98/c),u=i?{x:-r.x/r.scale,y:-r.y/r.scale,width:i.clientWidth/r.scale,height:i.clientHeight/r.scale}:null,d=e=>(e-a.minX)*l,f=e=>(e-a.minY)*l;return(0,Q.jsxs)(`svg`,{className:`structure-minimap`,viewBox:`0 0 164 98`,"aria-label":`Structure minimap`,children:[e.nodes.map(e=>{let r=t[e.id];return r?(0,Q.jsx)(`circle`,{cx:d(r.x+114),cy:f(r.y+56),r:e.id===n?3.2:1.7,className:e.id===n?`focused`:``},e.id):null}),u&&(0,Q.jsx)(`rect`,{className:`structure-minimap-viewport`,x:d(u.x),y:f(u.y),width:Math.max(2,u.width*l),height:Math.max(2,u.height*l)})]})}function je({paneId:e,pullRequestId:t,structure:r,changedFiles:i,navigationTarget:s=null,onNavigationApplied:m,onNavigationFailed:v,onOpenSource:b,onDeleted:x}){let S=`structure-${e}-${r.id}`,C=l(e,r.id),w=C??f(r),[T,E]=(0,y.useState)(w.focusId),[D,O]=(0,y.useState)(w.selectedEdgeId),[k,A]=(0,y.useState)(w.depth),[j,ee]=(0,y.useState)(w.positions),[M,N]=(0,y.useState)(w.viewport),[P,te]=(0,y.useState)({width:0,height:0}),[F,I]=(0,y.useState)(null),[L,R]=(0,y.useState)(null),[z,B]=(0,y.useState)(!1),V=(0,y.useRef)(null),ie=(0,y.useRef)(w.surfaceSize),H=(0,y.useRef)(T),U=(0,y.useRef)(j),ae=(0,y.useRef)({sourceOid:r.sourceOid,updatedAt:r.updatedAt}),oe=(0,y.useRef)(C?null:`initial`),W=(0,y.useRef)(null),G=(0,y.useRef)(null),K=(0,y.useRef)(null);H.current=T,U.current=j,(0,y.useLayoutEffect)(()=>{let e=V.current;if(!e)return;let t=()=>{let t={width:e.clientWidth,height:e.clientHeight};if(t.width===0||t.height===0)return;let n=ie.current;ie.current=t,te(t),n.width!==0&&n.height!==0&&N(e=>{let r={...e,x:e.x+(t.width-n.width)/2,y:e.y+(t.height-n.height)/2},i=H.current?U.current[H.current]:void 0;if(!i)return r;let a=228*r.scale,o=112*r.scale,s=r.x+i.x*r.scale,c=r.y+i.y*r.scale;return a>t.width-24?r.x=t.width/2-(i.x+114)*r.scale:s<12?r.x+=12-s:s+a>t.width-12&&(r.x-=s+a-(t.width-12)),o>t.height-24?r.y=t.height/2-(i.y+56)*r.scale:c<12?r.y+=12-c:c+o>t.height-12&&(r.y-=c+o-(t.height-12)),r})};t();let n=new ResizeObserver(t);return n.observe(e),()=>n.disconnect()},[]),(0,y.useEffect)(()=>{let e=V.current;if(!e)return;let t=t=>{let n=t.ctrlKey||t.metaKey;if(t.target instanceof Element){let e=t.target.closest(`.structure-node-focus`),r=Math.abs(t.deltaY)>=Math.abs(t.deltaX),i=e?t.deltaY<0?e.scrollTop>0:t.deltaY>0&&e.scrollTop+e.clientHeight<e.scrollHeight-1:!1;if(!n&&r&&i)return}t.preventDefault(),t.stopPropagation();let r=t.deltaMode===WheelEvent.DOM_DELTA_LINE?16:t.deltaMode===WheelEvent.DOM_DELTA_PAGE?Math.max(1,e.clientHeight):1;if(!n){N(e=>({...e,x:e.x-t.deltaX*r*Ce,y:e.y-t.deltaY*r*Ce}));return}let i=e.getBoundingClientRect(),o=t.clientX-i.left,s=t.clientY-i.top;N(e=>{let n=t.ctrlKey&&!t.metaKey?we:Te,i=a(e.scale,Math.exp(-t.deltaY*r*n)),c=(o-e.x)/e.scale,l=(s-e.y)/e.scale;return{scale:i,x:o-c*i,y:s-l*i}})};return e.addEventListener(`wheel`,t,{passive:!1}),()=>e.removeEventListener(`wheel`,t)},[]),(0,y.useEffect)(()=>{if(l(e,r.id)?.updatedAt===r.updatedAt)return;let t=ae.current;t.updatedAt!==r.updatedAt&&I(t.sourceOid===r.sourceOid?`Structureが更新されました。閲覧状態を保ったまま最新のclaimへ反映しています。`:`Structureが更新されました。exact source ${t.sourceOid.slice(0,8)} → ${r.sourceOid.slice(0,8)}`),ae.current={sourceOid:r.sourceOid,updatedAt:r.updatedAt},ee(e=>u(r,e));let n=H.current&&r.nodes.some(e=>e.id===H.current)?H.current:null;E(n),n===null&&A(`all`),O(e=>e&&r.edges.some(t=>t.id===e)?e:null)},[e,r,r.updatedAt]),(0,y.useEffect)(()=>{p(e,r.id,{focusId:T,selectedEdgeId:D,depth:k,positions:j,viewport:M,surfaceSize:ie.current,updatedAt:r.updatedAt})},[k,T,j,e,D,r.updatedAt,M]);let q=(0,y.useMemo)(()=>c(r,T,k),[k,T,r]),J=(0,y.useMemo)(()=>new Map(r.nodes.map(e=>[e.id,e])),[r.nodes]),Y=T?J.get(T)??null:null,ce=J.get(r.originNodeId),X=D?r.edges.find(e=>e.id===D)??null:null,le=(0,y.useMemo)(()=>new Set(X?[X.from,X.to]:[]),[X]),ue=(0,y.useMemo)(()=>T?g(r,T):[],[T,r]),de=(0,y.useMemo)(()=>{let e=new Map;for(let t of i){let n=d(t);n&&e.set(n,t.kind),t.oldPath&&e.set(t.oldPath,t.kind),t.newPath&&e.set(t.newPath,t.kind)}return e},[i]),fe=(0,y.useMemo)(()=>new Set(r.edges.filter(e=>q.edgeIds.has(e.id)&&(!T||e.from===T||e.to===T||e.id===D)).map(e=>e.id)),[T,D,r.edges,q.edgeIds]),Z=(0,y.useMemo)(()=>ne({structure:r,positions:j,sourceChangeKinds:de,selection:{nodeIds:q.nodeIds,edgeIds:q.edgeIds,labelEdgeIds:fe},labelAccessory:`source-actions`}),[fe,j,de,r,q.edgeIds,q.nodeIds]),pe=Z.edges.map(({edge:e})=>e),me=Z.nodes.map(({node:e})=>e),_e=Z.labels,$=Z.bounds,je=Math.max(1200,($?.right??1e3)+180),Me=Math.max(800,($?.bottom??600)+180),Ne=()=>{if(!$||P.width===0||P.height===0)return null;let e=Math.min(1.25,Math.max(_,Math.min((P.width-72)/Math.max(1,$.right-$.left),(P.height-72)/Math.max(1,$.bottom-$.top)))),t=($.right-$.left)*e,n=($.bottom-$.top)*e;return{scale:e,x:(P.width-t)/2-$.left*e,y:(P.height-n)/2-$.top*e}},Pe=()=>{let e=Ne();e&&N(e)};(0,y.useLayoutEffect)(()=>{if(!oe.current||!$||P.width===0||P.height===0)return;let e=j[r.originNodeId],t=e?e.x+114:($.left+$.right)/2,n=e?e.y+56:($.top+$.bottom)/2;oe.current=null,N({scale:1,x:P.width*.25-t,y:P.height/2-n})},[$,j,r.originNodeId,P.height,P.width]);let Fe=(0,y.useCallback)((e,t)=>{let n=j[e];n&&N(e=>({scale:t??e.scale,x:P.width/2-(n.x+114)*(t??e.scale),y:P.height/2-(n.y+56)*(t??e.scale)}))},[j,P.height,P.width]);(0,y.useLayoutEffect)(()=>{if(!s||s.structureId!==r.id||s.pane!==e||W.current===s.requestId||r.updatedAt<s.structureUpdatedAt)return;if(r.updatedAt>s.structureUpdatedAt){W.current=s.requestId,I(`Structureが更新されたため、ファイル参照を更新しました。もう一度選択してください。`),v(s.requestId);return}let t=r.nodes.find(e=>e.id===s.nodeId);if(!t){W.current=s.requestId,I(`移動先のNodeはStructureの更新により削除されています。ファイル参照を更新しました。`),v(s.requestId);return}!j[t.id]||P.width===0||P.height===0||(oe.current=null,I(null),O(null),E(t.id),Fe(t.id),W.current=s.requestId,m(s.requestId))},[Fe,s,m,v,e,j,r.id,r.nodes,P.height,P.width]);let Ie=()=>{T&&Fe(T)},Le=()=>{ee(o(r))},Re=(e,t=!1)=>{O(null),E(e),t&&Fe(e)},ze=()=>{O(null),E(null),A(`all`)},Be=e=>{e!==k&&A(e)},Ve=async()=>{try{await navigator.clipboard.writeText(r.ref),I(`Structure参照をコピーしました。`)}catch{I(`Structure参照をコピーできませんでした。`)}},He=async e=>{if(!L){R(e),I(null);try{let t=he({structure:r,model:re({structure:r,positions:j,sourceChangeKinds:de}),palette:se(document.documentElement)});if(e===`svg`){be(new Blob([t.source],{type:`image/svg+xml;charset=utf-8`}),ye(r,`svg`));return}let n=ge(t.width,t.height);be(await ve(t,n),ye(r,`png`)),n.downscaled&&I(`PNGを${Math.round(n.scale*100)}%で出力しました。より高い解像度にはSVGを使用してください。`)}catch(e){I(xe(e))}finally{R(null)}}},Ue=e=>{N(t=>{let n=a(t.scale,e),r=P.width/2,i=P.height/2,o=(r-t.x)/t.scale,s=(i-t.y)/t.scale;return{scale:n,x:r-o*n,y:i-s*n}})},We=async(e,t,n)=>{I(null);try{let t=await b(e,n);I(t)}catch(e){I(e instanceof Error?e.message:`参照先を開けません · ${t.path}`)}},Ge=async()=>{if(z)return;let e=r.nodes.filter(e=>e.anchor!==null).length+r.edges.reduce((e,t)=>e+t.anchors.length,0);if(window.confirm(`Structure「${r.title}」を削除します。\n\nNode ${r.nodes.length}\nEdge ${r.edges.length}\nSource anchor ${e}\n\nこの操作は元に戻せません。`)){B(!0),I(null);try{await n(`/api/pull-requests/${t}/structures/${r.id}`,{method:`DELETE`,headers:{"content-type":`application/json`},body:JSON.stringify({expectedUpdatedAt:r.updatedAt})}),h(r.id),x()}catch(e){I(e instanceof Error?e.message:`Structureを削除できませんでした。`)}finally{B(!1)}}},Ke=e=>{let t=K.current;if(t?.pointerId===e.pointerId){let n=(e.clientX-t.x)/M.scale,r=(e.clientY-t.y)/M.scale;K.current={...t,x:e.clientX,y:e.clientY,distance:t.distance+Math.hypot(e.clientX-t.x,e.clientY-t.y)},ee(e=>{let i=e[t.nodeId];return i?{...e,[t.nodeId]:{x:i.x+n,y:i.y+r}}:e});return}let n=G.current;if(n?.pointerId!==e.pointerId)return;let r=e.clientX-n.x,i=e.clientY-n.y;G.current={...n,x:e.clientX,y:e.clientY},N(e=>({...e,x:e.x+r,y:e.y+i}))},qe=e=>{if(G.current?.pointerId===e.pointerId&&(G.current=null),K.current?.pointerId===e.pointerId){let e=K.current;K.current=null,e.distance<4&&Re(e.nodeId)}e.currentTarget.hasPointerCapture(e.pointerId)&&e.currentTarget.releasePointerCapture(e.pointerId)};return(0,Q.jsxs)(`article`,{className:`structure-viewer`,"data-structure-id":r.id,"data-visible-node-count":q.nodeIds.size,"data-total-node-count":r.nodes.length,"data-visible-edge-count":q.edgeIds.size,"data-total-edge-count":r.edges.length,"data-rendered-node-count":me.length,"data-rendered-edge-count":pe.length,"data-viewport-scale":M.scale.toFixed(3),"data-selected-edge-id":D??void 0,children:[(0,Q.jsxs)(`header`,{className:`structure-header`,children:[(0,Q.jsxs)(`div`,{className:`structure-header-main`,children:[(0,Q.jsx)(`span`,{className:`structure-kicker`,children:`Structure`}),(0,Q.jsx)(`h2`,{title:r.title,children:r.title}),(0,Q.jsx)(`span`,{className:`structure-source-oid`,title:`exact source ${r.sourceOid}`,children:r.sourceOid.slice(0,8)}),(0,Q.jsxs)(`details`,{className:`structure-scope-details`,children:[(0,Q.jsx)(`summary`,{"aria-label":`scopeを表示`,children:`scope`}),(0,Q.jsx)(`p`,{children:r.scope})]})]}),(0,Q.jsxs)(`div`,{className:`structure-header-side`,children:[(0,Q.jsx)(`button`,{type:`button`,className:`structure-header-action`,"aria-label":`参照をコピー`,title:`Structure参照をコピー`,onClick:()=>void Ve(),children:`参照`}),(0,Q.jsx)(Se,{disabled:z||L!==null,exporting:L,onExport:e=>void He(e)}),(0,Q.jsx)(`button`,{type:`button`,className:`danger structure-delete`,disabled:z,onClick:()=>void Ge(),children:z?`削除中…`:`削除`})]})]}),(0,Q.jsxs)(`div`,{className:`structure-body`,children:[(0,Q.jsxs)(`div`,{className:`structure-toolbar`,"aria-label":`Structure表示操作`,children:[(0,Q.jsx)(`div`,{className:`structure-toolbar-group`,role:`group`,"aria-label":`近傍の深さ`,children:[1,2,`all`].map(e=>(0,Q.jsx)(`button`,{type:`button`,className:k===e?`active`:``,"aria-pressed":k===e,disabled:!T&&e!==`all`,onClick:()=>Be(e),children:e===`all`?`全体`:`${e}-hop`},e))}),(0,Q.jsxs)(`div`,{className:`structure-toolbar-group`,children:[(0,Q.jsx)(`button`,{type:`button`,onClick:()=>Ue(1/1.2),"aria-label":`縮小`,children:`−`}),(0,Q.jsxs)(`span`,{children:[Math.round(M.scale*100),`%`]}),(0,Q.jsx)(`button`,{type:`button`,onClick:()=>Ue(1.2),"aria-label":`拡大`,children:`+`}),(0,Q.jsx)(`button`,{type:`button`,"aria-label":`表示中を収める`,title:`表示中を収める`,onClick:Pe,children:`Fit`}),(0,Q.jsx)(`button`,{type:`button`,"aria-label":`focusを中央へ`,title:`focusを中央へ`,disabled:!T,onClick:Ie,children:`中央`}),(0,Q.jsx)(`button`,{type:`button`,"aria-label":`focusを解除`,title:`focusを解除`,disabled:!T,onClick:ze,children:`解除`}),(0,Q.jsx)(`button`,{type:`button`,"aria-label":`レイアウトを戻す`,title:`レイアウトを戻す`,onClick:Le,children:`Reset`})]})]}),F&&(0,Q.jsx)(`div`,{className:`structure-status`,role:`status`,"aria-live":`polite`,children:F}),(0,Q.jsx)(`section`,{className:`structure-canvas-shell`,"aria-label":`${r.title} graph`,children:(0,Q.jsxs)(`div`,{ref:V,className:`structure-canvas`,tabIndex:0,onKeyDown:e=>{e.key!==`Escape`||!D&&!T||(e.preventDefault(),D?O(null):ze())},onPointerDown:e=>{e.button!==0||e.target instanceof Element&&e.target.closest(`.structure-node, .structure-edge-label, button`)||(G.current={pointerId:e.pointerId,x:e.clientX,y:e.clientY},e.currentTarget.setPointerCapture(e.pointerId))},onPointerMove:Ke,onPointerUp:qe,onPointerCancel:qe,onDoubleClick:e=>{e.target===e.currentTarget&&Pe()},children:[(0,Q.jsxs)(`div`,{className:`structure-world`,style:{width:je,height:Me,transform:`translate(${M.x}px, ${M.y}px) scale(${M.scale})`},children:[(0,Q.jsxs)(`svg`,{className:`structure-edges`,width:je,height:Me,"aria-hidden":`true`,children:[(0,Q.jsx)(`defs`,{children:(0,Q.jsx)(`marker`,{id:`${S}-arrow`,viewBox:`0 0 10 10`,refX:`9`,refY:`5`,markerWidth:`7`,markerHeight:`7`,orient:`auto`,children:(0,Q.jsx)(`path`,{d:`M 0 0 L 10 5 L 0 10 z`})})}),Z.edges.map(({edge:e,geometry:t,source:n})=>{let r=e.from===T||e.to===T,i=e.id===D,a=D!==null&&!i,o=n.changeKind;return(0,Q.jsx)(`path`,{className:`structure-edge${r?` focused`:``}${i?` selected`:``}${a?` muted`:``}`,"data-edge-id":e.id,"data-source-change-kind":o??void 0,"data-start-x":t.startX,"data-start-y":t.startY,"data-end-x":t.endX,"data-end-y":t.endY,d:t.path,markerEnd:e.directed?`url(#${S}-arrow)`:void 0},e.id)})]}),_e.map(({edge:e,source:t,x:n,y:r,selectWidth:i,height:a,crowded:o})=>{let s=t.changeKind,c=J.get(e.from),l=J.get(e.to),u=e.directed?`${c?.label??e.from} から ${l?.label??e.to} へ: ${e.label}`:`${c?.label??e.from} と ${l?.label??e.to} の関係: ${e.label}`,d=e.id===D;return(0,Q.jsxs)(`div`,{className:`structure-edge-label${o?` crowded`:``}${D!==null&&!d?` muted`:``}`,"data-edge-id":e.id,"data-source-anchor-count":t.anchorCount,"data-source-change-kind":s??void 0,style:{left:n,top:r,minHeight:a},children:[(0,Q.jsx)(`button`,{type:`button`,className:`structure-edge-select${d?` selected`:``}`,title:e.label,"aria-label":u,"aria-pressed":d,style:{maxWidth:i},onClick:()=>O(t=>t===e.id?null:e.id),children:(0,Q.jsx)(`span`,{className:`structure-edge-label-text`,children:e.label})}),(0,Q.jsx)(De,{edge:e,onOpen:(e,t,n)=>void We(e,t,n)})]},`label:${e.id}`)}),Z.nodes.map(({node:e,point:t,changeKind:n,sourceLabel:i})=>{let a=e.id===T,o=ue.some(t=>t.from===e.id||t.to===e.id);return(0,Q.jsxs)(`div`,{className:`structure-node notation-${e.notation}${e.id===r.originNodeId?` origin`:``}${a?` focused`:``}${o?` neighboring`:``}${le.has(e.id)?` edge-endpoint`:``}`,"data-node-id":e.id,"data-node-notation":e.notation,"data-origin-node":e.id===r.originNodeId?`true`:void 0,"data-source-change-kind":n??void 0,style:{left:t.x,top:t.y},onPointerDown:t=>{t.button===0&&(t.stopPropagation(),K.current={pointerId:t.pointerId,nodeId:e.id,x:t.clientX,y:t.clientY,distance:0},V.current?.setPointerCapture(t.pointerId))},children:[(0,Q.jsxs)(`button`,{type:`button`,className:`structure-node-focus`,"aria-pressed":a,onClick:t=>{t.detail===0&&Re(e.id)},children:[e.anchor&&(0,Q.jsx)(Oe,{anchor:e.anchor,changeKind:n,sourceLabel:i??e.anchor.path}),(0,Q.jsx)(`strong`,{className:`structure-node-title`,children:(0,Q.jsx)(`span`,{className:`structure-node-title-text`,title:e.label,children:(0,Q.jsx)(ke,{label:e.label})})}),(0,Q.jsx)(`span`,{className:`structure-node-description`,children:e.description??`Producerによる説明なし`})]}),e.anchor&&(0,Q.jsx)(Ee,{compact:!0,anchor:e.anchor,onOpen:t=>void We({kind:`node`,nodeId:e.id},e.anchor,t)})]},e.id)})]}),(0,Q.jsxs)(`div`,{className:`structure-canvas-status`,children:[(0,Q.jsx)(`strong`,{children:Y?.label??`focusなし`}),(0,Q.jsxs)(`span`,{children:[`origin · `,ce.label]}),(0,Q.jsxs)(`span`,{children:[q.nodeIds.size,`/`,r.nodes.length,` Node · `,q.edgeIds.size,`/`,r.edges.length,` Relation`]})]}),(0,Q.jsx)(Ae,{structure:r,positions:j,focusedNodeId:T,viewport:M,viewportElement:V.current})]})})]})]})}export{je as StructureViewer};