@io.github.hj1003862396/draw-flow-mcp-server 1.0.1

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.
@@ -0,0 +1,562 @@
1
+ /**
2
+ * Embedded HTTP Server for MCP
3
+ * Serves draw.io embed with state sync and history UI
4
+ */
5
+ import http from "node:http";
6
+ import { addHistory, clearHistory, getHistory, getHistoryEntry, updateLastHistorySvg, } from "./history.js";
7
+ import { log } from "./logger.js";
8
+ // Configurable draw.io embed URL for private deployments
9
+ const DRAWIO_BASE_URL = process.env.DRAWIO_BASE_URL || "https://embed.diagrams.net";
10
+ // Extract origin (scheme + host + port) from URL for postMessage security check
11
+ function getOrigin(url) {
12
+ try {
13
+ const parsed = new URL(url);
14
+ return `${parsed.protocol}//${parsed.host}`;
15
+ }
16
+ catch {
17
+ return url; // Fallback if parsing fails
18
+ }
19
+ }
20
+ const DRAWIO_ORIGIN = getOrigin(DRAWIO_BASE_URL);
21
+ // Minimal blank diagram used to bootstrap new sessions.
22
+ // This avoids the draw.io embed spinner (spin=1) getting stuck when no `load(xml)` is ever sent.
23
+ const DEFAULT_DIAGRAM_XML = `<mxfile host="app.diagrams.net"><diagram id="blank" name="Page-1"><mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/></root></mxGraphModel></diagram></mxfile>`;
24
+ // Normalize URL for iframe src - ensure no double slashes
25
+ function normalizeUrl(url) {
26
+ // Remove trailing slash to avoid double slashes
27
+ return url.replace(/\/$/, "");
28
+ }
29
+ function isLikelyMcpSessionId(sessionId) {
30
+ // Keep this cheap and conservative to avoid creating state for arbitrary IDs.
31
+ return sessionId.startsWith("mcp-") && sessionId.length <= 128;
32
+ }
33
+ function ensureSessionStateInitialized(sessionId) {
34
+ if (!sessionId)
35
+ return;
36
+ if (!isLikelyMcpSessionId(sessionId))
37
+ return;
38
+ if (stateStore.has(sessionId))
39
+ return;
40
+ setState(sessionId, DEFAULT_DIAGRAM_XML);
41
+ }
42
+ export const stateStore = new Map();
43
+ let server = null;
44
+ let serverPort = 6002;
45
+ const MAX_PORT = 6020;
46
+ const SESSION_TTL = 60 * 60 * 1000;
47
+ export function getState(sessionId) {
48
+ return stateStore.get(sessionId);
49
+ }
50
+ export function setState(sessionId, xml, svg) {
51
+ const existing = stateStore.get(sessionId);
52
+ const newVersion = (existing?.version || 0) + 1;
53
+ stateStore.set(sessionId, {
54
+ xml,
55
+ version: newVersion,
56
+ lastUpdated: new Date(),
57
+ svg: svg || existing?.svg, // Preserve cached SVG if not provided
58
+ syncRequested: undefined, // Clear sync request when browser pushes state
59
+ });
60
+ log.debug(`State updated: session=${sessionId}, version=${newVersion}`);
61
+ return newVersion;
62
+ }
63
+ export function requestSync(sessionId) {
64
+ const state = stateStore.get(sessionId);
65
+ if (state) {
66
+ state.syncRequested = Date.now();
67
+ log.debug(`Sync requested for session=${sessionId}`);
68
+ return true;
69
+ }
70
+ log.debug(`Sync requested for non-existent session=${sessionId}`);
71
+ return false;
72
+ }
73
+ export async function waitForSync(sessionId, timeoutMs = 3000) {
74
+ const start = Date.now();
75
+ while (Date.now() - start < timeoutMs) {
76
+ const state = stateStore.get(sessionId);
77
+ if (!state?.syncRequested)
78
+ return true; // Sync completed
79
+ await new Promise((r) => setTimeout(r, 100));
80
+ }
81
+ log.warn(`Sync timeout for session=${sessionId}`);
82
+ return false; // Timeout
83
+ }
84
+ export function startHttpServer(port = 6002) {
85
+ return new Promise((resolve, reject) => {
86
+ if (server) {
87
+ resolve(serverPort);
88
+ return;
89
+ }
90
+ serverPort = port;
91
+ server = http.createServer(handleRequest);
92
+ server.on("error", (err) => {
93
+ if (err.code === "EADDRINUSE") {
94
+ if (port >= MAX_PORT) {
95
+ reject(new Error(`No available ports in range 6002-${MAX_PORT}`));
96
+ return;
97
+ }
98
+ log.info(`Port ${port} in use, trying ${port + 1}`);
99
+ server = null;
100
+ startHttpServer(port + 1)
101
+ .then(resolve)
102
+ .catch(reject);
103
+ }
104
+ else {
105
+ reject(err);
106
+ }
107
+ });
108
+ server.listen(port, () => {
109
+ serverPort = port;
110
+ log.info(`HTTP server running on http://localhost:${port}`);
111
+ resolve(port);
112
+ });
113
+ });
114
+ }
115
+ export function stopHttpServer() {
116
+ if (server) {
117
+ server.close();
118
+ server = null;
119
+ }
120
+ }
121
+ function cleanupExpiredSessions() {
122
+ const now = Date.now();
123
+ for (const [sessionId, state] of stateStore) {
124
+ if (now - state.lastUpdated.getTime() > SESSION_TTL) {
125
+ stateStore.delete(sessionId);
126
+ clearHistory(sessionId);
127
+ log.info(`Cleaned up expired session: ${sessionId}`);
128
+ }
129
+ }
130
+ }
131
+ const cleanupIntervalId = setInterval(cleanupExpiredSessions, 5 * 60 * 1000);
132
+ export function shutdown() {
133
+ clearInterval(cleanupIntervalId);
134
+ stopHttpServer();
135
+ }
136
+ export function getServerPort() {
137
+ return serverPort;
138
+ }
139
+ function handleRequest(req, res) {
140
+ const url = new URL(req.url || "/", `http://localhost:${serverPort}`);
141
+ res.setHeader("Access-Control-Allow-Origin", "*");
142
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
143
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type");
144
+ if (req.method === "OPTIONS") {
145
+ res.writeHead(204);
146
+ res.end();
147
+ return;
148
+ }
149
+ if (url.pathname === "/" || url.pathname === "/index.html") {
150
+ const sessionId = url.searchParams.get("mcp") || "";
151
+ ensureSessionStateInitialized(sessionId);
152
+ res.writeHead(200, { "Content-Type": "text/html" });
153
+ res.end(getHtmlPage(sessionId));
154
+ }
155
+ else if (url.pathname === "/api/state") {
156
+ handleStateApi(req, res, url);
157
+ }
158
+ else if (url.pathname === "/api/history") {
159
+ handleHistoryApi(req, res, url);
160
+ }
161
+ else if (url.pathname === "/api/restore") {
162
+ handleRestoreApi(req, res);
163
+ }
164
+ else if (url.pathname === "/api/history-svg") {
165
+ handleHistorySvgApi(req, res);
166
+ }
167
+ else {
168
+ res.writeHead(404);
169
+ res.end("Not Found");
170
+ }
171
+ }
172
+ function handleStateApi(req, res, url) {
173
+ if (req.method === "GET") {
174
+ const sessionId = url.searchParams.get("sessionId");
175
+ if (!sessionId) {
176
+ res.writeHead(400, { "Content-Type": "application/json" });
177
+ res.end(JSON.stringify({ error: "sessionId required" }));
178
+ return;
179
+ }
180
+ ensureSessionStateInitialized(sessionId);
181
+ const state = stateStore.get(sessionId);
182
+ res.writeHead(200, { "Content-Type": "application/json" });
183
+ res.end(JSON.stringify({
184
+ xml: state?.xml || null,
185
+ version: state?.version || 0,
186
+ syncRequested: !!state?.syncRequested,
187
+ }));
188
+ }
189
+ else if (req.method === "POST") {
190
+ let body = "";
191
+ req.on("data", (chunk) => {
192
+ body += chunk;
193
+ });
194
+ req.on("end", () => {
195
+ try {
196
+ const { sessionId, xml, svg } = JSON.parse(body);
197
+ if (!sessionId) {
198
+ res.writeHead(400, { "Content-Type": "application/json" });
199
+ res.end(JSON.stringify({ error: "sessionId required" }));
200
+ return;
201
+ }
202
+ const version = setState(sessionId, xml, svg);
203
+ res.writeHead(200, { "Content-Type": "application/json" });
204
+ res.end(JSON.stringify({ success: true, version }));
205
+ }
206
+ catch {
207
+ res.writeHead(400, { "Content-Type": "application/json" });
208
+ res.end(JSON.stringify({ error: "Invalid JSON" }));
209
+ }
210
+ });
211
+ }
212
+ else {
213
+ res.writeHead(405);
214
+ res.end("Method Not Allowed");
215
+ }
216
+ }
217
+ function handleHistoryApi(req, res, url) {
218
+ if (req.method !== "GET") {
219
+ res.writeHead(405);
220
+ res.end("Method Not Allowed");
221
+ return;
222
+ }
223
+ const sessionId = url.searchParams.get("sessionId");
224
+ if (!sessionId) {
225
+ res.writeHead(400, { "Content-Type": "application/json" });
226
+ res.end(JSON.stringify({ error: "sessionId required" }));
227
+ return;
228
+ }
229
+ const history = getHistory(sessionId);
230
+ res.writeHead(200, { "Content-Type": "application/json" });
231
+ res.end(JSON.stringify({
232
+ entries: history.map((entry, i) => ({ index: i, svg: entry.svg })),
233
+ count: history.length,
234
+ }));
235
+ }
236
+ function handleRestoreApi(req, res) {
237
+ if (req.method !== "POST") {
238
+ res.writeHead(405);
239
+ res.end("Method Not Allowed");
240
+ return;
241
+ }
242
+ let body = "";
243
+ req.on("data", (chunk) => {
244
+ body += chunk;
245
+ });
246
+ req.on("end", () => {
247
+ try {
248
+ const { sessionId, index } = JSON.parse(body);
249
+ if (!sessionId || index === undefined) {
250
+ res.writeHead(400, { "Content-Type": "application/json" });
251
+ res.end(JSON.stringify({ error: "sessionId and index required" }));
252
+ return;
253
+ }
254
+ const entry = getHistoryEntry(sessionId, index);
255
+ if (!entry) {
256
+ res.writeHead(404, { "Content-Type": "application/json" });
257
+ res.end(JSON.stringify({ error: "Entry not found" }));
258
+ return;
259
+ }
260
+ const newVersion = setState(sessionId, entry.xml);
261
+ addHistory(sessionId, entry.xml, entry.svg);
262
+ log.info(`Restored session ${sessionId} to index ${index}`);
263
+ res.writeHead(200, { "Content-Type": "application/json" });
264
+ res.end(JSON.stringify({ success: true, newVersion }));
265
+ }
266
+ catch {
267
+ res.writeHead(400, { "Content-Type": "application/json" });
268
+ res.end(JSON.stringify({ error: "Invalid JSON" }));
269
+ }
270
+ });
271
+ }
272
+ function handleHistorySvgApi(req, res) {
273
+ if (req.method !== "POST") {
274
+ res.writeHead(405);
275
+ res.end("Method Not Allowed");
276
+ return;
277
+ }
278
+ let body = "";
279
+ req.on("data", (chunk) => {
280
+ body += chunk;
281
+ });
282
+ req.on("end", () => {
283
+ try {
284
+ const { sessionId, svg } = JSON.parse(body);
285
+ if (!sessionId || !svg) {
286
+ res.writeHead(400, { "Content-Type": "application/json" });
287
+ res.end(JSON.stringify({ error: "sessionId and svg required" }));
288
+ return;
289
+ }
290
+ updateLastHistorySvg(sessionId, svg);
291
+ res.writeHead(200, { "Content-Type": "application/json" });
292
+ res.end(JSON.stringify({ success: true }));
293
+ }
294
+ catch {
295
+ res.writeHead(400, { "Content-Type": "application/json" });
296
+ res.end(JSON.stringify({ error: "Invalid JSON" }));
297
+ }
298
+ });
299
+ }
300
+ function getHtmlPage(sessionId) {
301
+ return `<!DOCTYPE html>
302
+ <html lang="en">
303
+ <head>
304
+ <meta charset="UTF-8">
305
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
306
+ <title>Draw.io MCP</title>
307
+ <style>
308
+ * { margin: 0; padding: 0; box-sizing: border-box; }
309
+ html, body { width: 100%; height: 100%; overflow: hidden; }
310
+ #container { width: 100%; height: 100%; display: flex; flex-direction: column; }
311
+ #header {
312
+ padding: 8px 16px; background: #1a1a2e; color: #eee;
313
+ font-family: system-ui, sans-serif; font-size: 14px;
314
+ display: flex; justify-content: space-between; align-items: center;
315
+ }
316
+ #header .session { color: #888; font-size: 12px; }
317
+ #header .status { font-size: 12px; }
318
+ #header .status.connected { color: #4ade80; }
319
+ #header .status.disconnected { color: #f87171; }
320
+ #drawio { flex: 1; border: none; }
321
+ #history-btn {
322
+ position: fixed; bottom: 24px; right: 24px;
323
+ width: 48px; height: 48px; border-radius: 50%;
324
+ background: #3b82f6; color: white; border: none; cursor: pointer;
325
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
326
+ display: flex; align-items: center; justify-content: center;
327
+ z-index: 1000;
328
+ }
329
+ #history-btn:hover { background: #2563eb; }
330
+ #history-btn:disabled { background: #6b7280; cursor: not-allowed; }
331
+ #history-btn svg { width: 24px; height: 24px; }
332
+ #history-modal {
333
+ display: none; position: fixed; inset: 0;
334
+ background: rgba(0,0,0,0.5); z-index: 2000;
335
+ align-items: center; justify-content: center;
336
+ }
337
+ #history-modal.open { display: flex; }
338
+ .modal-content {
339
+ background: white; border-radius: 12px;
340
+ width: 90%; max-width: 500px; max-height: 70vh;
341
+ display: flex; flex-direction: column;
342
+ }
343
+ .modal-header { padding: 16px; border-bottom: 1px solid #e5e7eb; }
344
+ .modal-header h2 { font-size: 18px; margin: 0; }
345
+ .modal-body { flex: 1; overflow-y: auto; padding: 16px; }
346
+ .modal-footer { padding: 12px 16px; border-top: 1px solid #e5e7eb; display: flex; gap: 8px; justify-content: flex-end; }
347
+ .history-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
348
+ .history-item {
349
+ border: 2px solid #e5e7eb; border-radius: 8px; padding: 8px;
350
+ cursor: pointer; text-align: center;
351
+ }
352
+ .history-item:hover { border-color: #3b82f6; }
353
+ .history-item.selected { border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59,130,246,0.3); }
354
+ .history-item .thumb {
355
+ aspect-ratio: 4/3; background: #f3f4f6; border-radius: 4px;
356
+ display: flex; align-items: center; justify-content: center;
357
+ margin-bottom: 4px; overflow: hidden;
358
+ }
359
+ .history-item .thumb img { max-width: 100%; max-height: 100%; object-fit: contain; }
360
+ .history-item .label { font-size: 12px; color: #666; }
361
+ .btn { padding: 8px 16px; border-radius: 6px; font-size: 14px; cursor: pointer; border: none; }
362
+ .btn-primary { background: #3b82f6; color: white; }
363
+ .btn-primary:disabled { background: #93c5fd; cursor: not-allowed; }
364
+ .btn-secondary { background: #f3f4f6; color: #374151; }
365
+ .empty { text-align: center; padding: 40px; color: #666; }
366
+ </style>
367
+ </head>
368
+ <body>
369
+ <div id="container">
370
+ <div id="header">
371
+ <div>
372
+ <strong>Draw.io MCP</strong>
373
+ <span class="session">${sessionId ? `Session: ${sessionId}` : "No session"}</span>
374
+ </div>
375
+ <div id="status" class="status disconnected">Connecting...</div>
376
+ </div>
377
+ <iframe id="drawio" src="${normalizeUrl(DRAWIO_BASE_URL)}/?embed=1&proto=json&spin=1&libraries=1"></iframe>
378
+ </div>
379
+ <button id="history-btn" title="History" ${sessionId ? "" : "disabled"}>
380
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
381
+ <circle cx="12" cy="12" r="10"></circle>
382
+ <polyline points="12 6 12 12 16 14"></polyline>
383
+ </svg>
384
+ </button>
385
+ <div id="history-modal">
386
+ <div class="modal-content">
387
+ <div class="modal-header"><h2>History</h2></div>
388
+ <div class="modal-body">
389
+ <div id="history-grid" class="history-grid"></div>
390
+ <div id="history-empty" class="empty" style="display:none;">No history yet</div>
391
+ </div>
392
+ <div class="modal-footer">
393
+ <button class="btn btn-secondary" id="cancel-btn">Cancel</button>
394
+ <button class="btn btn-primary" id="restore-btn" disabled>Restore</button>
395
+ </div>
396
+ </div>
397
+ </div>
398
+ <script>
399
+ const sessionId = "${sessionId}";
400
+ const iframe = document.getElementById('drawio');
401
+ const statusEl = document.getElementById('status');
402
+ let currentVersion = 0, isReady = false, pendingXml = null, lastXml = null;
403
+ let pendingSvgExport = null;
404
+ let pendingAiSvg = false;
405
+
406
+ window.addEventListener('message', (e) => {
407
+ if (e.origin !== '${DRAWIO_ORIGIN}') return;
408
+ try {
409
+ const msg = JSON.parse(e.data);
410
+ if (msg.event === 'init') {
411
+ isReady = true;
412
+ statusEl.textContent = 'Ready';
413
+ statusEl.className = 'status connected';
414
+ if (pendingXml) { loadDiagram(pendingXml); pendingXml = null; }
415
+ } else if ((msg.event === 'save' || msg.event === 'autosave') && msg.xml && msg.xml !== lastXml) {
416
+ // Request SVG export, then push state with SVG
417
+ pendingSvgExport = msg.xml;
418
+ iframe.contentWindow.postMessage(JSON.stringify({ action: 'export', format: 'svg' }), '*');
419
+ // Fallback if export doesn't respond
420
+ setTimeout(() => { if (pendingSvgExport === msg.xml) { pushState(msg.xml, ''); pendingSvgExport = null; } }, 2000);
421
+ } else if (msg.event === 'export' && msg.data) {
422
+ // Handle sync export (XML format) - server requested fresh state
423
+ if (pendingSyncExport && !msg.data.startsWith('data:') && !msg.data.startsWith('<svg')) {
424
+ pendingSyncExport = false;
425
+ pushState(msg.data, '');
426
+ return;
427
+ }
428
+ // Handle SVG export
429
+ let svg = msg.data;
430
+ if (!svg.startsWith('data:')) svg = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svg)));
431
+ if (pendingSvgExport) {
432
+ const xml = pendingSvgExport;
433
+ pendingSvgExport = null;
434
+ pushState(xml, svg);
435
+ } else if (pendingAiSvg) {
436
+ pendingAiSvg = false;
437
+ fetch('/api/history-svg', {
438
+ method: 'POST',
439
+ headers: { 'Content-Type': 'application/json' },
440
+ body: JSON.stringify({ sessionId, svg })
441
+ }).catch(() => {});
442
+ }
443
+ }
444
+ } catch {}
445
+ });
446
+
447
+ function loadDiagram(xml, capturePreview = false) {
448
+ if (!isReady) { pendingXml = xml; return; }
449
+ lastXml = xml;
450
+ iframe.contentWindow.postMessage(JSON.stringify({ action: 'load', xml, autosave: 1 }), '*');
451
+ if (capturePreview) {
452
+ setTimeout(() => {
453
+ pendingAiSvg = true;
454
+ iframe.contentWindow.postMessage(JSON.stringify({ action: 'export', format: 'svg' }), '*');
455
+ }, 500);
456
+ }
457
+ }
458
+
459
+ async function pushState(xml, svg = '') {
460
+ if (!sessionId) return;
461
+ try {
462
+ const r = await fetch('/api/state', {
463
+ method: 'POST',
464
+ headers: { 'Content-Type': 'application/json' },
465
+ body: JSON.stringify({ sessionId, xml, svg })
466
+ });
467
+ if (r.ok) { const d = await r.json(); currentVersion = d.version; lastXml = xml; }
468
+ } catch (e) { console.error('Push failed:', e); }
469
+ }
470
+
471
+ let pendingSyncExport = false;
472
+
473
+ async function poll() {
474
+ if (!sessionId) return;
475
+ try {
476
+ const r = await fetch('/api/state?sessionId=' + encodeURIComponent(sessionId));
477
+ if (!r.ok) return;
478
+ const s = await r.json();
479
+ // Handle sync request - server needs fresh state
480
+ if (s.syncRequested && !pendingSyncExport) {
481
+ pendingSyncExport = true;
482
+ iframe.contentWindow.postMessage(JSON.stringify({ action: 'export', format: 'xml' }), '*');
483
+ }
484
+ // Load new diagram from server
485
+ if (s.version > currentVersion && s.xml) {
486
+ currentVersion = s.version;
487
+ loadDiagram(s.xml, true);
488
+ }
489
+ } catch {}
490
+ }
491
+
492
+ if (sessionId) { poll(); setInterval(poll, 2000); }
493
+
494
+ // History UI
495
+ const historyBtn = document.getElementById('history-btn');
496
+ const historyModal = document.getElementById('history-modal');
497
+ const historyGrid = document.getElementById('history-grid');
498
+ const historyEmpty = document.getElementById('history-empty');
499
+ const restoreBtn = document.getElementById('restore-btn');
500
+ const cancelBtn = document.getElementById('cancel-btn');
501
+ let historyData = [], selectedIdx = null;
502
+
503
+ historyBtn.onclick = async () => {
504
+ if (!sessionId) return;
505
+ try {
506
+ const r = await fetch('/api/history?sessionId=' + encodeURIComponent(sessionId));
507
+ if (r.ok) {
508
+ const d = await r.json();
509
+ historyData = d.entries || [];
510
+ renderHistory();
511
+ }
512
+ } catch {}
513
+ historyModal.classList.add('open');
514
+ };
515
+
516
+ cancelBtn.onclick = () => { historyModal.classList.remove('open'); selectedIdx = null; restoreBtn.disabled = true; };
517
+ historyModal.onclick = (e) => { if (e.target === historyModal) cancelBtn.onclick(); };
518
+
519
+ function renderHistory() {
520
+ if (historyData.length === 0) {
521
+ historyGrid.style.display = 'none';
522
+ historyEmpty.style.display = 'block';
523
+ return;
524
+ }
525
+ historyGrid.style.display = 'grid';
526
+ historyEmpty.style.display = 'none';
527
+ historyGrid.innerHTML = historyData.map((e, i) => \`
528
+ <div class="history-item" data-idx="\${e.index}">
529
+ <div class="thumb">\${e.svg ? \`<img src="\${e.svg}">\` : '#' + e.index}</div>
530
+ <div class="label">#\${e.index}</div>
531
+ </div>
532
+ \`).join('');
533
+ historyGrid.querySelectorAll('.history-item').forEach(item => {
534
+ item.onclick = () => {
535
+ const idx = parseInt(item.dataset.idx);
536
+ if (selectedIdx === idx) { selectedIdx = null; restoreBtn.disabled = true; }
537
+ else { selectedIdx = idx; restoreBtn.disabled = false; }
538
+ historyGrid.querySelectorAll('.history-item').forEach(el => el.classList.toggle('selected', parseInt(el.dataset.idx) === selectedIdx));
539
+ };
540
+ });
541
+ }
542
+
543
+ restoreBtn.onclick = async () => {
544
+ if (selectedIdx === null) return;
545
+ restoreBtn.disabled = true;
546
+ restoreBtn.textContent = 'Restoring...';
547
+ try {
548
+ const r = await fetch('/api/restore', {
549
+ method: 'POST',
550
+ headers: { 'Content-Type': 'application/json' },
551
+ body: JSON.stringify({ sessionId, index: selectedIdx })
552
+ });
553
+ if (r.ok) { cancelBtn.onclick(); await poll(); }
554
+ else { alert('Restore failed'); }
555
+ } catch { alert('Restore failed'); }
556
+ restoreBtn.textContent = 'Restore';
557
+ };
558
+ </script>
559
+ </body>
560
+ </html>`;
561
+ }
562
+ //# sourceMappingURL=http-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-server.js","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EACH,UAAU,EACV,YAAY,EACZ,UAAU,EACV,eAAe,EACf,oBAAoB,GACvB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAEjC,yDAAyD;AACzD,MAAM,eAAe,GACjB,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,4BAA4B,CAAA;AAE/D,gFAAgF;AAChF,SAAS,SAAS,CAAC,GAAW;IAC1B,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QAC3B,OAAO,GAAG,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,IAAI,EAAE,CAAA;IAC/C,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,GAAG,CAAA,CAAC,4BAA4B;IAC3C,CAAC;AACL,CAAC;AAED,MAAM,aAAa,GAAG,SAAS,CAAC,eAAe,CAAC,CAAA;AAEhD,wDAAwD;AACxD,iGAAiG;AACjG,MAAM,mBAAmB,GAAG,4KAA4K,CAAA;AAExM,0DAA0D;AAC1D,SAAS,YAAY,CAAC,GAAW;IAC7B,gDAAgD;IAChD,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;AACjC,CAAC;AAED,SAAS,oBAAoB,CAAC,SAAiB;IAC3C,8EAA8E;IAC9E,OAAO,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,MAAM,IAAI,GAAG,CAAA;AAClE,CAAC;AAED,SAAS,6BAA6B,CAAC,SAAiB;IACpD,IAAI,CAAC,SAAS;QAAE,OAAM;IACtB,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC;QAAE,OAAM;IAC5C,IAAI,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAM;IAErC,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAA;AAC5C,CAAC;AAUD,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAwB,CAAA;AAEzD,IAAI,MAAM,GAAuB,IAAI,CAAA;AACrC,IAAI,UAAU,GAAG,IAAI,CAAA;AACrB,MAAM,QAAQ,GAAG,IAAI,CAAA;AACrB,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAElC,MAAM,UAAU,QAAQ,CAAC,SAAiB;IACtC,OAAO,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,SAAiB,EAAE,GAAW,EAAE,GAAY;IACjE,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAC1C,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;IAC/C,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE;QACtB,GAAG;QACH,OAAO,EAAE,UAAU;QACnB,WAAW,EAAE,IAAI,IAAI,EAAE;QACvB,GAAG,EAAE,GAAG,IAAI,QAAQ,EAAE,GAAG,EAAE,sCAAsC;QACjE,aAAa,EAAE,SAAS,EAAE,+CAA+C;KAC5E,CAAC,CAAA;IACF,GAAG,CAAC,KAAK,CAAC,0BAA0B,SAAS,aAAa,UAAU,EAAE,CAAC,CAAA;IACvE,OAAO,UAAU,CAAA;AACrB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,SAAiB;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IACvC,IAAI,KAAK,EAAE,CAAC;QACR,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAChC,GAAG,CAAC,KAAK,CAAC,8BAA8B,SAAS,EAAE,CAAC,CAAA;QACpD,OAAO,IAAI,CAAA;IACf,CAAC;IACD,GAAG,CAAC,KAAK,CAAC,2CAA2C,SAAS,EAAE,CAAC,CAAA;IACjE,OAAO,KAAK,CAAA;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC7B,SAAiB,EACjB,SAAS,GAAG,IAAI;IAEhB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxB,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QACvC,IAAI,CAAC,KAAK,EAAE,aAAa;YAAE,OAAO,IAAI,CAAA,CAAC,iBAAiB;QACxD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;IAChD,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,4BAA4B,SAAS,EAAE,CAAC,CAAA;IACjD,OAAO,KAAK,CAAA,CAAC,UAAU;AAC3B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAI,GAAG,IAAI;IACvC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,IAAI,MAAM,EAAE,CAAC;YACT,OAAO,CAAC,UAAU,CAAC,CAAA;YACnB,OAAM;QACV,CAAC;QAED,UAAU,GAAG,IAAI,CAAA;QACjB,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAA;QAEzC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;YAC9C,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC5B,IAAI,IAAI,IAAI,QAAQ,EAAE,CAAC;oBACnB,MAAM,CACF,IAAI,KAAK,CACL,oCAAoC,QAAQ,EAAE,CACjD,CACJ,CAAA;oBACD,OAAM;gBACV,CAAC;gBACD,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,mBAAmB,IAAI,GAAG,CAAC,EAAE,CAAC,CAAA;gBACnD,MAAM,GAAG,IAAI,CAAA;gBACb,eAAe,CAAC,IAAI,GAAG,CAAC,CAAC;qBACpB,IAAI,CAAC,OAAO,CAAC;qBACb,KAAK,CAAC,MAAM,CAAC,CAAA;YACtB,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,GAAG,CAAC,CAAA;YACf,CAAC;QACL,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YACrB,UAAU,GAAG,IAAI,CAAA;YACjB,GAAG,CAAC,IAAI,CAAC,2CAA2C,IAAI,EAAE,CAAC,CAAA;YAC3D,OAAO,CAAC,IAAI,CAAC,CAAA;QACjB,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;AACN,CAAC;AAED,MAAM,UAAU,cAAc;IAC1B,IAAI,MAAM,EAAE,CAAC;QACT,MAAM,CAAC,KAAK,EAAE,CAAA;QACd,MAAM,GAAG,IAAI,CAAA;IACjB,CAAC;AACL,CAAC;AAED,SAAS,sBAAsB;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACtB,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,UAAU,EAAE,CAAC;QAC1C,IAAI,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,WAAW,EAAE,CAAC;YAClD,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;YAC5B,YAAY,CAAC,SAAS,CAAC,CAAA;YACvB,GAAG,CAAC,IAAI,CAAC,+BAA+B,SAAS,EAAE,CAAC,CAAA;QACxD,CAAC;IACL,CAAC;AACL,CAAC;AAED,MAAM,iBAAiB,GAAG,WAAW,CAAC,sBAAsB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;AAE5E,MAAM,UAAU,QAAQ;IACpB,aAAa,CAAC,iBAAiB,CAAC,CAAA;IAChC,cAAc,EAAE,CAAA;AACpB,CAAC;AAED,MAAM,UAAU,aAAa;IACzB,OAAO,UAAU,CAAA;AACrB,CAAC;AAED,SAAS,aAAa,CAClB,GAAyB,EACzB,GAAwB;IAExB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,oBAAoB,UAAU,EAAE,CAAC,CAAA;IAErE,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAA;IACjD,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,oBAAoB,CAAC,CAAA;IACnE,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,cAAc,CAAC,CAAA;IAE7D,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC3B,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAClB,GAAG,CAAC,GAAG,EAAE,CAAA;QACT,OAAM;IACV,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;QACzD,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;QACnD,6BAA6B,CAAC,SAAS,CAAC,CAAA;QAExC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAA;QACnD,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAA;IACnC,CAAC;SAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;QACvC,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IACjC,CAAC;SAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,cAAc,EAAE,CAAC;QACzC,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IACnC,CAAC;SAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,cAAc,EAAE,CAAC;QACzC,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAC9B,CAAC;SAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,kBAAkB,EAAE,CAAC;QAC7C,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACjC,CAAC;SAAM,CAAC;QACJ,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAClB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IACxB,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CACnB,GAAyB,EACzB,GAAwB,EACxB,GAAQ;IAER,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QACnD,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;YAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAA;YACxD,OAAM;QACV,CAAC;QACD,6BAA6B,CAAC,SAAS,CAAC,CAAA;QACxC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QACvC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;QAC1D,GAAG,CAAC,GAAG,CACH,IAAI,CAAC,SAAS,CAAC;YACX,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,IAAI;YACvB,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,CAAC;YAC5B,aAAa,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa;SACxC,CAAC,CACL,CAAA;IACL,CAAC;SAAM,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC/B,IAAI,IAAI,GAAG,EAAE,CAAA;QACb,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YACrB,IAAI,IAAI,KAAK,CAAA;QACjB,CAAC,CAAC,CAAA;QACF,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACf,IAAI,CAAC;gBACD,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBAChD,IAAI,CAAC,SAAS,EAAE,CAAC;oBACb,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;oBAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAA;oBACxD,OAAM;gBACV,CAAC;gBACD,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;gBAC7C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;gBAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;YACvD,CAAC;YAAC,MAAM,CAAC;gBACL,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;gBAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAA;YACtD,CAAC;QACL,CAAC,CAAC,CAAA;IACN,CAAC;SAAM,CAAC;QACJ,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAClB,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;IACjC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CACrB,GAAyB,EACzB,GAAwB,EACxB,GAAQ;IAER,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QACvB,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAClB,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;QAC7B,OAAM;IACV,CAAC;IAED,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IACnD,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;QAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAA;QACxD,OAAM;IACV,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,CAAA;IACrC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;IAC1D,GAAG,CAAC,GAAG,CACH,IAAI,CAAC,SAAS,CAAC;QACX,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAClE,KAAK,EAAE,OAAO,CAAC,MAAM;KACxB,CAAC,CACL,CAAA;AACL,CAAC;AAED,SAAS,gBAAgB,CACrB,GAAyB,EACzB,GAAwB;IAExB,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QACxB,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAClB,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;QAC7B,OAAM;IACV,CAAC;IAED,IAAI,IAAI,GAAG,EAAE,CAAA;IACb,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QACrB,IAAI,IAAI,KAAK,CAAA;IACjB,CAAC,CAAC,CAAA;IACF,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;QACf,IAAI,CAAC;YACD,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YAC7C,IAAI,CAAC,SAAS,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACpC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;gBAC1D,GAAG,CAAC,GAAG,CACH,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC,CAC5D,CAAA;gBACD,OAAM;YACV,CAAC;YAED,MAAM,KAAK,GAAG,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;YAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;gBAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAA;gBACrD,OAAM;YACV,CAAC;YAED,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;YACjD,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;YAE3C,GAAG,CAAC,IAAI,CAAC,oBAAoB,SAAS,aAAa,KAAK,EAAE,CAAC,CAAA;YAE3D,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;YAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAA;QAC1D,CAAC;QAAC,MAAM,CAAC;YACL,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;YAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAA;QACtD,CAAC;IACL,CAAC,CAAC,CAAA;AACN,CAAC;AAED,SAAS,mBAAmB,CACxB,GAAyB,EACzB,GAAwB;IAExB,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QACxB,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAClB,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;QAC7B,OAAM;IACV,CAAC;IAED,IAAI,IAAI,GAAG,EAAE,CAAA;IACb,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QACrB,IAAI,IAAI,KAAK,CAAA;IACjB,CAAC,CAAC,CAAA;IACF,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;QACf,IAAI,CAAC;YACD,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YAC3C,IAAI,CAAC,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC;gBACrB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;gBAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC,CAAC,CAAA;gBAChE,OAAM;YACV,CAAC;YAED,oBAAoB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;YACpC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;YAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAC9C,CAAC;QAAC,MAAM,CAAC;YACL,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;YAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAA;QACtD,CAAC;IACL,CAAC,CAAC,CAAA;AACN,CAAC;AAED,SAAS,WAAW,CAAC,SAAiB;IAClC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wCAwE6B,SAAS,CAAC,CAAC,CAAC,YAAY,SAAS,EAAE,CAAC,CAAC,CAAC,YAAY;;;;mCAIvD,YAAY,CAAC,eAAe,CAAC;;+CAEjB,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU;;;;;;;;;;;;;;;;;;;;6BAoB7C,SAAS;;;;;;;;gCAQN,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyJrC,CAAA;AACR,CAAC"}
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Server for Next AI Draw.io
4
+ *
5
+ * Enables AI agents (Claude Desktop, Cursor, etc.) to generate and edit
6
+ * draw.io diagrams with real-time browser preview.
7
+ *
8
+ * Uses an embedded HTTP server - no external dependencies required.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG"}