@imenam/mcp-documentor 1.0.91 → 1.0.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +2 -2
  2. package/dist/src/gui-worker.js +52 -68
  3. package/dist/src/index.js +8 -1
  4. package/gui/dist/assets/{arc-VljQAUvA.js → arc-BbedxJ3W.js} +1 -1
  5. package/gui/dist/assets/{architectureDiagram-3BPJPVTR-lbkjtvmN.js → architectureDiagram-3BPJPVTR-DF3IYwLZ.js} +1 -1
  6. package/gui/dist/assets/{blockDiagram-GPEHLZMM-G4A-rV4c.js → blockDiagram-GPEHLZMM-CgILcS8Q.js} +1 -1
  7. package/gui/dist/assets/{c4Diagram-AAUBKEIU-Dq3aMw8v.js → c4Diagram-AAUBKEIU-ByGBdJcU.js} +1 -1
  8. package/gui/dist/assets/channel-CIJsZK_a.js +1 -0
  9. package/gui/dist/assets/{chunk-2J33WTMH-VSzyIJHo.js → chunk-2J33WTMH-DIk0ZeJ6.js} +1 -1
  10. package/gui/dist/assets/{chunk-4BX2VUAB-DER41q8w.js → chunk-4BX2VUAB-fF78mC-G.js} +1 -1
  11. package/gui/dist/assets/{chunk-55IACEB6-BlOGGRk4.js → chunk-55IACEB6-BzoqbAWn.js} +1 -1
  12. package/gui/dist/assets/{chunk-727SXJPM-Dv3Ay2KV.js → chunk-727SXJPM-B0BlALdx.js} +1 -1
  13. package/gui/dist/assets/{chunk-AQP2D5EJ-BycHHbwh.js → chunk-AQP2D5EJ-DlKhB6LK.js} +1 -1
  14. package/gui/dist/assets/{chunk-FMBD7UC4-DBoCiqpY.js → chunk-FMBD7UC4-DBTqXHP1.js} +1 -1
  15. package/gui/dist/assets/{chunk-ND2GUHAM-DGKypjhb.js → chunk-ND2GUHAM-BmMICe1L.js} +1 -1
  16. package/gui/dist/assets/{chunk-QZHKN3VN-B8Gn_mBo.js → chunk-QZHKN3VN-DyEBqCzf.js} +1 -1
  17. package/gui/dist/assets/classDiagram-4FO5ZUOK-LzEGnqT7.js +1 -0
  18. package/gui/dist/assets/classDiagram-v2-Q7XG4LA2-LzEGnqT7.js +1 -0
  19. package/gui/dist/assets/{cose-bilkent-S5V4N54A-DyamTuYj.js → cose-bilkent-S5V4N54A-DMkNiOVz.js} +1 -1
  20. package/gui/dist/assets/{dagre-BM42HDAG-BKC5D2WN.js → dagre-BM42HDAG-CEGX5APR.js} +1 -1
  21. package/gui/dist/assets/{diagram-2AECGRRQ-BV2lBpwH.js → diagram-2AECGRRQ-DHo40rfh.js} +1 -1
  22. package/gui/dist/assets/{diagram-5GNKFQAL-DGwbAj4W.js → diagram-5GNKFQAL-CPbyX-Jj.js} +1 -1
  23. package/gui/dist/assets/{diagram-KO2AKTUF-CZAde8Sg.js → diagram-KO2AKTUF-B-LnaXtr.js} +1 -1
  24. package/gui/dist/assets/{diagram-LMA3HP47-fQfo0z7i.js → diagram-LMA3HP47-gjnm6GxN.js} +1 -1
  25. package/gui/dist/assets/{diagram-OG6HWLK6-BlD3VAFM.js → diagram-OG6HWLK6-B_qc7WBs.js} +1 -1
  26. package/gui/dist/assets/{erDiagram-TEJ5UH35-DPUEmQfe.js → erDiagram-TEJ5UH35-B7jlXuub.js} +1 -1
  27. package/gui/dist/assets/{flowDiagram-I6XJVG4X-p2HfkBjW.js → flowDiagram-I6XJVG4X-BjWyZsCs.js} +1 -1
  28. package/gui/dist/assets/{ganttDiagram-6RSMTGT7-CWfFoy4g.js → ganttDiagram-6RSMTGT7-CGdvXL_7.js} +1 -1
  29. package/gui/dist/assets/{gitGraphDiagram-PVQCEYII-DkTKzmes.js → gitGraphDiagram-PVQCEYII-TxUcHrcr.js} +1 -1
  30. package/gui/dist/assets/{index-BJ4WCWig.css → index-ARDnpfWR.css} +1 -1
  31. package/gui/dist/assets/{index-C8LVeAsA.js → index-CrG0yj-K.js} +93 -96
  32. package/gui/dist/assets/{infoDiagram-5YYISTIA-CXHTqZoU.js → infoDiagram-5YYISTIA-BElIHd-R.js} +1 -1
  33. package/gui/dist/assets/{ishikawaDiagram-YF4QCWOH-DZ61Cc8a.js → ishikawaDiagram-YF4QCWOH-De4Ds8bG.js} +1 -1
  34. package/gui/dist/assets/{journeyDiagram-JHISSGLW-qYtEmFuB.js → journeyDiagram-JHISSGLW-Cjpgxilg.js} +1 -1
  35. package/gui/dist/assets/{kanban-definition-UN3LZRKU-Bs-W313s.js → kanban-definition-UN3LZRKU-D8Y_Af2d.js} +1 -1
  36. package/gui/dist/assets/{linear-CU6J91M5.js → linear-BB2LhUqA.js} +1 -1
  37. package/gui/dist/assets/{mindmap-definition-RKZ34NQL-CvBqAH4c.js → mindmap-definition-RKZ34NQL-Cq_fBarD.js} +1 -1
  38. package/gui/dist/assets/{pieDiagram-4H26LBE5-BD2UcQce.js → pieDiagram-4H26LBE5-LGkTEx-6.js} +1 -1
  39. package/gui/dist/assets/{quadrantDiagram-W4KKPZXB-DEuynlP9.js → quadrantDiagram-W4KKPZXB-mgy_9RRW.js} +1 -1
  40. package/gui/dist/assets/{requirementDiagram-4Y6WPE33-DPxfzOF3.js → requirementDiagram-4Y6WPE33-B_d8OEc3.js} +1 -1
  41. package/gui/dist/assets/{sankeyDiagram-5OEKKPKP-C70_cePR.js → sankeyDiagram-5OEKKPKP-BgBLM80u.js} +1 -1
  42. package/gui/dist/assets/{sequenceDiagram-3UESZ5HK-FDb_1B1W.js → sequenceDiagram-3UESZ5HK-B9GkqtWb.js} +1 -1
  43. package/gui/dist/assets/{stateDiagram-AJRCARHV-BH1bq2it.js → stateDiagram-AJRCARHV-UoRM2vqX.js} +1 -1
  44. package/gui/dist/assets/stateDiagram-v2-BHNVJYJU-B7m-qaHs.js +1 -0
  45. package/gui/dist/assets/{timeline-definition-PNZ67QCA-DNUx0JIp.js → timeline-definition-PNZ67QCA-Dyx58rRr.js} +1 -1
  46. package/gui/dist/assets/{vennDiagram-CIIHVFJN-DEAfzbjb.js → vennDiagram-CIIHVFJN-IypthVr7.js} +1 -1
  47. package/gui/dist/assets/{wardley-L42UT6IY-_REPWPb-.js → wardley-L42UT6IY-DkLzWKUw.js} +1 -1
  48. package/gui/dist/assets/{wardleyDiagram-YWT4CUSO-CZFLXFE3.js → wardleyDiagram-YWT4CUSO-98VafNiZ.js} +1 -1
  49. package/gui/dist/assets/{xychartDiagram-2RQKCTM6-P2Nhif6M.js → xychartDiagram-2RQKCTM6-dZj2dDaC.js} +1 -1
  50. package/gui/dist/index.html +2 -2
  51. package/package.json +1 -1
  52. package/gui/dist/assets/channel-DFvG2cZZ.js +0 -1
  53. package/gui/dist/assets/classDiagram-4FO5ZUOK-B8xEoAMI.js +0 -1
  54. package/gui/dist/assets/classDiagram-v2-Q7XG4LA2-B8xEoAMI.js +0 -1
  55. package/gui/dist/assets/stateDiagram-v2-BHNVJYJU-BfpDu1Qi.js +0 -1
package/README.md CHANGED
@@ -12,7 +12,7 @@ Connect it to Cursor, Claude Desktop, or any MCP-compatible agent to let your AI
12
12
  - **Track a branch, not a checkout** — point a project at a GitHub branch from its settings in the GUI and freshness is measured against *published* code: switching branches or editing without committing no longer makes docs look stale, and a server with no copy of the codebase (an MCP gateway) can still verify them
13
13
  - **Semantic search** — find relevant docs by meaning (requires an OpenAI API key)
14
14
  - **Multi-project support** — organize docs into separate projects; every MCP tool names the project it targets, and the GUI's project selector is a per-browser view preference
15
- - **GUI** — built-in web interface, either behind the proxy (`PROXY_URL`) or served directly on a local port (`APP_PORT`); with neither, the GUI worker is not started. Navigation runs from an icon rail on the left: the current project's badge (click to switch projects or create one), then Documentation, Search (`Ctrl/⌘ + K`, current or all projects), Outdated, Recent, Export bundles and Logs, with Sync and Settings at the bottom. Each destination fills the panel next to the rail; the panel's hide button, or a second click on the active icon, folds it away. Drag the panel's right edge to resize it (double-click resets the width); the browser remembers the width. The details panel on the right of a document (`Ctrl/⌘ + \`) is open by default from 1280 px wide; showing or hiding it by hand is remembered across reloads until the window crosses that width. Badges show the outdated docs, pending commits and the day's failed GitHub calls
15
+ - **GUI** — built-in web interface, either behind the proxy (`PROXY_URL`) or served directly on a local port (`APP_PORT`); with neither, the GUI worker is not started. Navigation runs from an icon rail on the left: the current project's badge (click to switch projects or create one), then Documentation, Search (`Ctrl/⌘ + K`, current or all projects), Outdated, Recent, Export bundles and Logs, with Sync and Settings at the bottom. Each destination fills the panel next to the rail; the panel's hide button, or a second click on the active icon, folds it away. Drag the panel's right edge to resize it (double-click resets the width); the browser remembers the width. The details panel on the right of a document (`Ctrl/⌘ + \`) is open by default from 1280 px wide; showing or hiding it by hand is remembered across reloads until the window crosses that width. Badges show the outdated docs, pending commits and the day's failed GitHub calls. Each open tab polls `GET /api/changes` every 3 seconds and every request is answered immediately: no connection stays open, so many tabs can share the proxy's origin, and changes made by the agent show up within 3 seconds. After a GUI worker restart, or when it has fallen more than 200 changes behind, the tab reloads the server state (`GET /api/initial-state`) and the list of the project it shows
16
16
  - **Proxy-aware** — integrates with the [proxy-setup](https://github.com/Imena/proxy-setup) for GUI exposure
17
17
  - **Links & structure** — `check_links`, `get_doc_tree`, `move_doc`, and `git_diff_doc` for maintenance workflows
18
18
  - **Image support** — upload images to a project's assets via `upload_image` (local file path) or directly from the GUI editor; images are stored per-project and rendered inline in the viewer and in PDF exports
@@ -320,7 +320,7 @@ Everything else is content-addressed: a commit's tree is cached by its sha for t
320
320
 
321
321
  By default, data lives under **`.docs-data`** next to the resolved package root (the folder that contains `package.json` for the running install). Set **`MCP_DATA_DIR`** to use another directory. Contents include projects, SQLite/embeddings, and logs under `.docs-data/logs`. This tree is **not** part of the npm package; it is created at runtime.
322
322
 
323
- There is no server-side "active project": every MCP tool call names its project, and the GUI's selector only changes what that browser displays (kept in the URL and in `localStorage`). A legacy `currentProject` left in `config.json` is dropped on first read. GitHub sync settings live in environment variables, not on disk.
323
+ There is no server-side "active project": every MCP tool call names its project, and the GUI's selector only changes what that browser displays (kept in the URL and in `localStorage`). The open and closed folders of each project's navigation tree are also kept in `localStorage`, so a reload restores them. A legacy `currentProject` left in `config.json` is dropped on first read. GitHub sync settings live in environment variables, not on disk.
324
324
 
325
325
  ## License
326
326
 
@@ -1,7 +1,6 @@
1
1
  import { serve } from "@hono/node-server";
2
2
  import { serveStatic } from "@hono/node-server/serve-static";
3
3
  import { Hono } from "hono";
4
- import { streamSSE } from "hono/streaming";
5
4
  import { GUI_LISTEN_HOST, ProxyClient, honoGuiGuard } from "@imenam/mcp-gui-interface";
6
5
  import { IPCMessageSchema } from "../shared/schemas/doc.schema.js";
7
6
  import { isReadOnly } from "../shared/read-only.js";
@@ -9,6 +8,7 @@ import path from "path";
9
8
  import fs from "fs";
10
9
  import { execFile, spawn } from "child_process";
11
10
  import { Readable } from "stream";
11
+ import { randomUUID } from "crypto";
12
12
  import { promisify } from "util";
13
13
  const execFileAsync = promisify(execFile);
14
14
  import { fileURLToPath } from "url";
@@ -129,7 +129,6 @@ let guiPublicUrl = '';
129
129
  const app = new Hono();
130
130
  app.use("*", honoGuiGuard());
131
131
  let proxyClient = null;
132
- const sseControllers = new Set();
133
132
  const pendingRequests = new Map();
134
133
  function safeSend(message) {
135
134
  if (process.send && process.connected) {
@@ -171,6 +170,27 @@ function ipcRequest(type, data, timeout = 5000) {
171
170
  }
172
171
  });
173
172
  }
173
+ /** Message types the master pushes to every GUI, journaled for `/api/changes`. */
174
+ const BROADCAST_TYPES = [
175
+ "INITIAL_STATE",
176
+ "CONFIG_UPDATED",
177
+ "BUNDLES_UPDATED",
178
+ "PROJECTS_CHANGED",
179
+ "DOCS_CHANGED",
180
+ "CODE_SOURCES_CHANGED",
181
+ ];
182
+ /** Number of pushed messages kept for clients catching up. */
183
+ const CHANGE_JOURNAL_SIZE = 200;
184
+ /** Identifies this worker run: a client holding another epoch has missed everything since. */
185
+ const workerEpoch = randomUUID();
186
+ let changeSeq = 0;
187
+ const changeJournal = [];
188
+ function recordChange(message) {
189
+ changeSeq += 1;
190
+ changeJournal.push({ seq: changeSeq, message });
191
+ if (changeJournal.length > CHANGE_JOURNAL_SIZE)
192
+ changeJournal.shift();
193
+ }
174
194
  function setupIpcErrorHandlers() {
175
195
  process.on("error", (err) => {
176
196
  if (err.code === "ERR_IPC_CHANNEL_CLOSED")
@@ -179,7 +199,7 @@ function setupIpcErrorHandlers() {
179
199
  });
180
200
  process.on("disconnect", () => {
181
201
  logger.warn("IPC disconnected from MCP master (parent closed the channel or process exited). " +
182
- "GUI worker will exit; EventSource clients will show Disconnected.");
202
+ "GUI worker will exit.");
183
203
  process.exit(0);
184
204
  });
185
205
  process.on("message", (msg) => {
@@ -199,24 +219,8 @@ function setupIpcErrorHandlers() {
199
219
  });
200
220
  return;
201
221
  }
202
- const BROADCAST_TYPES = [
203
- "INITIAL_STATE",
204
- "CONFIG_UPDATED",
205
- "BUNDLES_UPDATED",
206
- "PROJECTS_CHANGED",
207
- "DOCS_CHANGED",
208
- "CODE_SOURCES_CHANGED",
209
- ];
210
- if (msg && BROADCAST_TYPES.includes(msg.type)) {
211
- for (const controller of sseControllers) {
212
- try {
213
- controller.writeSSE({ data: JSON.stringify(msg), event: "message" });
214
- }
215
- catch {
216
- sseControllers.delete(controller);
217
- }
218
- }
219
- }
222
+ if (msg && BROADCAST_TYPES.includes(msg.type))
223
+ recordChange(msg);
220
224
  });
221
225
  }
222
226
  // --- HTTP Routes ---
@@ -251,54 +255,34 @@ app.get("/proxy/health", (c) => {
251
255
  timestamp: new Date().toISOString(),
252
256
  });
253
257
  });
254
- app.get("/api/events", (c) => {
255
- return streamSSE(c, async (stream) => {
256
- const clientId = Math.random().toString(36).slice(2, 11);
257
- const openedAt = Date.now();
258
- sseControllers.add(stream);
259
- logger.info(`SSE /api/events: client connected (id=${clientId})`);
260
- stream.onAbort(() => {
261
- sseControllers.delete(stream);
262
- logger.warn(`SSE /api/events: stream aborted (id=${clientId}, durationMs=${Date.now() - openedAt}). ` +
263
- "Typical causes: user navigated away, proxy closed idle connection, or network drop. " +
264
- "Browser will retry EventSource and may log client-diagnostics with readyState.");
265
- });
266
- const initialSent = safeSend({ type: "GET_INITIAL_STATE", timestamp: new Date().toISOString() });
267
- if (!initialSent) {
268
- logger.warn(`SSE /api/events: GET_INITIAL_STATE not sent to master (id=${clientId}). ` +
269
- `IPC unavailable: process.connected=${process.connected}, process.send=${typeof process.send}. ` +
270
- "Dashboard will stay Disconnected until IPC to the MCP process works.");
271
- }
272
- try {
273
- await stream.writeSSE({ data: "connected", event: "ping" });
274
- }
275
- catch (err) {
276
- logger.warn(`SSE /api/events: initial writeSSE failed (id=${clientId}): ${err?.message ?? err}`);
277
- sseControllers.delete(stream);
278
- return;
279
- }
280
- while (true) {
281
- await stream.sleep(30000);
282
- try {
283
- await stream.writeSSE({ data: "ping", event: "ping" });
284
- }
285
- catch (err) {
286
- logger.warn(`SSE /api/events: keepalive ping failed (id=${clientId}): ${err?.message ?? err}`);
287
- sseControllers.delete(stream);
288
- break;
289
- }
290
- }
258
+ // Answers immediately with the pushed messages after `since`, or `reset: true` when the
259
+ // client must reload the whole state: no cursor, another worker run, or messages dropped.
260
+ app.get("/api/changes", (c) => {
261
+ const since = c.req.query("since");
262
+ const epoch = c.req.query("epoch");
263
+ if (since !== undefined && !/^\d+$/.test(since)) {
264
+ return c.json({ error: `since must be a non-negative integer, got "${since}"` }, 400);
265
+ }
266
+ const reset = { epoch: workerEpoch, seq: changeSeq, reset: true };
267
+ if (since === undefined || epoch !== workerEpoch)
268
+ return c.json(reset);
269
+ const from = Number(since);
270
+ const oldestKept = changeJournal.length > 0 ? changeJournal[0].seq : changeSeq + 1;
271
+ if (from > changeSeq || from < oldestKept - 1)
272
+ return c.json(reset);
273
+ return c.json({
274
+ epoch: workerEpoch,
275
+ seq: changeSeq,
276
+ reset: false,
277
+ events: changeJournal.filter((entry) => entry.seq > from).map((entry) => entry.message),
291
278
  });
292
279
  });
293
- app.post("/api/client-diagnostics", async (c) => {
294
- try {
295
- const body = await c.req.json();
296
- logger.warn(`Client diagnostics (SSE/EventSource): ${JSON.stringify(body)}`);
297
- }
298
- catch (e) {
299
- logger.warn(`Client diagnostics: invalid JSON body (${e?.message ?? e})`);
300
- }
301
- return c.json({ ok: true });
280
+ // Server-side state a client loads on start and after each reset.
281
+ app.get("/api/initial-state", async (c) => {
282
+ const result = await ipcRequest("GET_INITIAL_STATE");
283
+ if (result.error)
284
+ return c.json({ error: result.error }, 500);
285
+ return c.json(result.data);
302
286
  });
303
287
  app.get("/api/configurations", async (c) => {
304
288
  const configRes = await ipcRequest("GET_CONFIG");
@@ -700,7 +684,7 @@ app.get("/api/export-zip/:id", async (c) => {
700
684
  docId = ref;
701
685
  }
702
686
  else {
703
- zip.file(`${ref}.md`, `# [Unqualified doc reference: ${ref} — no project given]
687
+ zip.file(`${ref}.md`, `# [Unqualified doc reference: ${ref} — no project given]
704
688
  `);
705
689
  continue;
706
690
  }
package/dist/src/index.js CHANGED
@@ -120,7 +120,6 @@ let guiLauncher;
120
120
  let guiStatus = "disabled";
121
121
  let guiUrl = null;
122
122
  let guiStartWaiter = null;
123
- const sseControllers = new Set();
124
123
  function broadcastToGUI(message) {
125
124
  const child = guiLauncher.getProcess();
126
125
  if (child?.connected) {
@@ -359,6 +358,14 @@ async function handleGetInitialState(msg) {
359
358
  }
360
359
  catch (err) {
361
360
  logger.error(`Failed to get initial state: ${err.message}`);
361
+ if (msg.correlationId) {
362
+ broadcastToGUI({
363
+ type: "INITIAL_STATE",
364
+ correlationId: msg.correlationId,
365
+ error: err.message,
366
+ timestamp: new Date().toISOString(),
367
+ });
368
+ }
362
369
  }
363
370
  }
364
371
  async function handleGetConfig(msg) {
@@ -1 +1 @@
1
- import{a0 as ln,a1 as an,a2 as y,a3 as tn,a4 as H,a5 as q,a6 as _,a7 as un,a8 as rn,a9 as L,aa as o,ab as B,ac as sn,ad as on,ae as fn}from"./index-C8LVeAsA.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,C,a){var O=I-l,i=D-h,n=C-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function W(l,h,I,D,v,A,C){var a=l-I,O=h-D,i=(C?A:-A)/L(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,F=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*L(fn(0,T*T*R-P*P)),j=(P*g-m*S)/R,z=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=j-F,e=z-t,r=w-F,G=p-t;return x*x+e*e>r*r+G*G&&(j=w,z=p),{cx:j,cy:z,x01:-n,y01:-d,x11:j*(v/T-1),y11:z*(v/T-1)}}function hn(){var l=cn,h=yn,I=B(0),D=null,v=gn,A=dn,C=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-an,c=A.apply(this,arguments)-an,F=un(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(F>tn-y)a.moveTo(s*H(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*H(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=F,S=F,j=C.apply(this,arguments)/2,z=j>y&&(D?+D.apply(this,arguments):L(u*u+s*s)),w=_(un(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if(z>y){var G=sn(z/u*q(j)),M=sn(z/s*q(j));(P-=G*2)>y?(G*=t?1:-1,R+=G,T-=G):(P=0,R=T=(f+c)/2),(S-=M*2)>y?(M*=t?1:-1,m+=M,g-=M):(S=0,m=g=(f+c)/2)}var J=s*H(m),K=s*q(m),N=u*H(T),Q=u*q(T);if(w>y){var U=s*H(g),V=s*q(g),X=u*H(R),Y=u*q(R),E;if(F<rn)if(E=pn(J,K,X,Y,U,V,N,Q)){var Z=J-E[0],$=K-E[1],b=U-E[0],k=V-E[1],nn=1/q(on((Z*b+$*k)/(L(Z*Z+$*$)*L(b*b+k*k)))/2),en=L(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=W(X,Y,J,K,s,x,t),r=W(U,V,N,Q,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(J,K),a.arc(0,0,s,m,g,!t)):a.moveTo(J,K),!(u>y)||!(P>y)?a.lineTo(N,Q):p>y?(e=W(N,Q,U,V,u,-p,t),r=W(J,K,X,Y,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-rn/2;return[H(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:B(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:B(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:B(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:B(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:B(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:B(+n),i):A},i.padAngle=function(n){return arguments.length?(C=typeof n=="function"?n:B(+n),i):C},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
1
+ import{a0 as ln,a1 as an,a2 as y,a3 as tn,a4 as H,a5 as q,a6 as _,a7 as un,a8 as rn,a9 as L,aa as o,ab as B,ac as sn,ad as on,ae as fn}from"./index-CrG0yj-K.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,C,a){var O=I-l,i=D-h,n=C-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function W(l,h,I,D,v,A,C){var a=l-I,O=h-D,i=(C?A:-A)/L(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,F=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*L(fn(0,T*T*R-P*P)),j=(P*g-m*S)/R,z=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=j-F,e=z-t,r=w-F,G=p-t;return x*x+e*e>r*r+G*G&&(j=w,z=p),{cx:j,cy:z,x01:-n,y01:-d,x11:j*(v/T-1),y11:z*(v/T-1)}}function hn(){var l=cn,h=yn,I=B(0),D=null,v=gn,A=dn,C=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-an,c=A.apply(this,arguments)-an,F=un(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(F>tn-y)a.moveTo(s*H(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*H(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=F,S=F,j=C.apply(this,arguments)/2,z=j>y&&(D?+D.apply(this,arguments):L(u*u+s*s)),w=_(un(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if(z>y){var G=sn(z/u*q(j)),M=sn(z/s*q(j));(P-=G*2)>y?(G*=t?1:-1,R+=G,T-=G):(P=0,R=T=(f+c)/2),(S-=M*2)>y?(M*=t?1:-1,m+=M,g-=M):(S=0,m=g=(f+c)/2)}var J=s*H(m),K=s*q(m),N=u*H(T),Q=u*q(T);if(w>y){var U=s*H(g),V=s*q(g),X=u*H(R),Y=u*q(R),E;if(F<rn)if(E=pn(J,K,X,Y,U,V,N,Q)){var Z=J-E[0],$=K-E[1],b=U-E[0],k=V-E[1],nn=1/q(on((Z*b+$*k)/(L(Z*Z+$*$)*L(b*b+k*k)))/2),en=L(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=W(X,Y,J,K,s,x,t),r=W(U,V,N,Q,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(J,K),a.arc(0,0,s,m,g,!t)):a.moveTo(J,K),!(u>y)||!(P>y)?a.lineTo(N,Q):p>y?(e=W(N,Q,U,V,u,-p,t),r=W(J,K,X,Y,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-rn/2;return[H(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:B(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:B(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:B(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:B(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:B(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:B(+n),i):A},i.padAngle=function(n){return arguments.length?(C=typeof n=="function"?n:B(+n),i):C},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};