@ai-markdown/core 3.3.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/dist/components/index.cjs +786 -167
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +388 -53
- package/dist/components/index.d.ts +388 -53
- package/dist/components/index.js +775 -163
- package/dist/components/index.js.map +1 -1
- package/package.json +3 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
let _ai_markdown_code_language_detector = require("@ai-markdown/code-language-detector");
|
|
3
4
|
function extractCode(node) {
|
|
4
5
|
if (node?.tagName !== "pre" || node.children.length !== 1 || Object.keys(node.properties).length) return null;
|
|
5
6
|
const child = node.children[0];
|
|
@@ -45,19 +46,26 @@ function text(node) {
|
|
|
45
46
|
if (node.tagName === "img" || node.tagName === "cross-chunk-image") return String(node.properties.alt ?? "");
|
|
46
47
|
return node.children.map(text).join("");
|
|
47
48
|
}
|
|
49
|
+
var ExportRefused = class extends Error {
|
|
50
|
+
reason;
|
|
51
|
+
constructor(reason) {
|
|
52
|
+
super(reason);
|
|
53
|
+
this.reason = reason;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
48
56
|
function projectTable(node) {
|
|
49
57
|
try {
|
|
50
|
-
if (node?.tagName !== "table") throw new
|
|
58
|
+
if (node?.tagName !== "table") throw new ExportRefused("unavailable");
|
|
51
59
|
const rows = [];
|
|
52
60
|
const walk = (parent) => {
|
|
53
61
|
for (const child of parent.children) {
|
|
54
62
|
if (child.type === "text" && !child.value.trim()) continue;
|
|
55
|
-
if (child.type !== "element") throw new
|
|
63
|
+
if (child.type !== "element") throw new ExportRefused("unsupportedContent");
|
|
56
64
|
if (child.tagName === "tr") {
|
|
57
65
|
const cells = [];
|
|
58
66
|
for (const cell of child.children) {
|
|
59
67
|
if (cell.type === "text" && !cell.value.trim()) continue;
|
|
60
|
-
if (cell.type !== "element" || !["th", "td"].includes(cell.tagName) || Number(cell.properties.colSpan ?? 1) !== 1 || Number(cell.properties.rowSpan ?? 1) !== 1) throw new
|
|
68
|
+
if (cell.type !== "element" || !["th", "td"].includes(cell.tagName) || Number(cell.properties.colSpan ?? 1) !== 1 || Number(cell.properties.rowSpan ?? 1) !== 1) throw new ExportRefused("mergedCells");
|
|
61
69
|
cells.push(text(cell));
|
|
62
70
|
}
|
|
63
71
|
rows.push(cells);
|
|
@@ -66,14 +74,14 @@ function projectTable(node) {
|
|
|
66
74
|
"tbody",
|
|
67
75
|
"tfoot"
|
|
68
76
|
].includes(child.tagName) && parent === node) walk(child);
|
|
69
|
-
else throw new
|
|
77
|
+
else throw new ExportRefused("unsupportedStructure");
|
|
70
78
|
}
|
|
71
79
|
};
|
|
72
80
|
walk(node);
|
|
73
|
-
if (!rows.length || !rows[0].length || rows.some((r) => r.length !== rows[0].length)) throw new
|
|
81
|
+
if (!rows.length || !rows[0].length || rows.some((r) => r.length !== rows[0].length)) throw new ExportRefused("notRectangular");
|
|
74
82
|
return { rows };
|
|
75
83
|
} catch (error) {
|
|
76
|
-
return { reason: error instanceof
|
|
84
|
+
return { reason: error instanceof ExportRefused ? error.reason : "unavailable" };
|
|
77
85
|
}
|
|
78
86
|
}
|
|
79
87
|
const formulaPrefix = /^[\s\u0000-\u001f]*[=+@-]/;
|
|
@@ -83,6 +91,57 @@ function serializeTable(rows, delimiter = ",") {
|
|
|
83
91
|
return /["\r\n\t,]/.test(value) ? `"${value.replaceAll("\"", "\"\"")}"` : value;
|
|
84
92
|
}).join(delimiter)).join("\r\n");
|
|
85
93
|
}
|
|
94
|
+
function codeBody(code) {
|
|
95
|
+
return code.endsWith("\n") ? code.slice(0, -1) : code;
|
|
96
|
+
}
|
|
97
|
+
function startsWithText(text, prefix) {
|
|
98
|
+
return text.length >= prefix.length && text.slice(0, prefix.length) === prefix;
|
|
99
|
+
}
|
|
100
|
+
function extendsCode(next, previous) {
|
|
101
|
+
return startsWithText(next, codeBody(previous));
|
|
102
|
+
}
|
|
103
|
+
function createCodeLanguageTracker(onSettle) {
|
|
104
|
+
const detector = new _ai_markdown_code_language_detector.StreamingLanguageDetector();
|
|
105
|
+
let followed;
|
|
106
|
+
let settled = null;
|
|
107
|
+
let timer;
|
|
108
|
+
const cancel = () => {
|
|
109
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
110
|
+
timer = void 0;
|
|
111
|
+
};
|
|
112
|
+
const judge = (from, text, streaming) => (streaming && settled !== text ? from.update(text) : from.finalize(text)).language;
|
|
113
|
+
return {
|
|
114
|
+
read(code, streaming) {
|
|
115
|
+
if (followed !== void 0 && extendsCode(code, followed)) return detector.current.language;
|
|
116
|
+
return judge(new _ai_markdown_code_language_detector.StreamingLanguageDetector(), codeBody(code), streaming);
|
|
117
|
+
},
|
|
118
|
+
observe(code, streaming) {
|
|
119
|
+
cancel();
|
|
120
|
+
const text = codeBody(code);
|
|
121
|
+
const starting = followed === void 0 || !extendsCode(code, followed);
|
|
122
|
+
if (starting) detector.reset();
|
|
123
|
+
const before = detector.current.language;
|
|
124
|
+
followed = code;
|
|
125
|
+
const after = judge(detector, text, streaming);
|
|
126
|
+
if (streaming && settled !== text) timer = setTimeout(() => {
|
|
127
|
+
timer = void 0;
|
|
128
|
+
settled = text;
|
|
129
|
+
detector.finalize(text);
|
|
130
|
+
onSettle();
|
|
131
|
+
}, 300);
|
|
132
|
+
return !starting && before !== after;
|
|
133
|
+
},
|
|
134
|
+
dispose: cancel
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function nextCodeFrame(previous, code, language) {
|
|
138
|
+
if (previous?.code === code && previous.language === language) return previous;
|
|
139
|
+
return {
|
|
140
|
+
code,
|
|
141
|
+
language,
|
|
142
|
+
generation: previous && language === previous.language && extendsCode(code, previous.code) ? previous.generation : {}
|
|
143
|
+
};
|
|
144
|
+
}
|
|
86
145
|
function createCodeFrame(initial, publish) {
|
|
87
146
|
let shown = initial;
|
|
88
147
|
let latest = initial;
|
|
@@ -100,7 +159,7 @@ function createCodeFrame(initial, publish) {
|
|
|
100
159
|
};
|
|
101
160
|
return {
|
|
102
161
|
update(next, streaming, interval) {
|
|
103
|
-
const replaced = next.
|
|
162
|
+
const replaced = next.generation !== latest.generation;
|
|
104
163
|
latest = next;
|
|
105
164
|
if (delay !== interval) cancel();
|
|
106
165
|
delay = interval;
|
|
@@ -162,16 +221,17 @@ function createJsonCompletenessScanner() {
|
|
|
162
221
|
let invalid = false;
|
|
163
222
|
let last = "";
|
|
164
223
|
return (text) => {
|
|
224
|
+
const body = codeBody(text);
|
|
165
225
|
let from = previous.length;
|
|
166
|
-
if (!
|
|
226
|
+
if (!startsWithText(body, previous)) {
|
|
167
227
|
from = 0;
|
|
168
228
|
depth = 0;
|
|
169
229
|
quoted = escaped = invalid = false;
|
|
170
230
|
last = "";
|
|
171
231
|
}
|
|
172
|
-
previous =
|
|
173
|
-
for (let i = from; i <
|
|
174
|
-
const c =
|
|
232
|
+
previous = body;
|
|
233
|
+
for (let i = from; i < body.length; i++) {
|
|
234
|
+
const c = body[i];
|
|
175
235
|
if (!/\s/.test(c)) last = c;
|
|
176
236
|
if (quoted) {
|
|
177
237
|
if (escaped) escaped = false;
|
|
@@ -190,6 +250,89 @@ function createJsonCompletenessScanner() {
|
|
|
190
250
|
function jsonLooksComplete(text) {
|
|
191
251
|
return createJsonCompletenessScanner()(text);
|
|
192
252
|
}
|
|
253
|
+
function createCodeBlockSession(onChange) {
|
|
254
|
+
let committed;
|
|
255
|
+
let shown;
|
|
256
|
+
let frames;
|
|
257
|
+
let token;
|
|
258
|
+
let committing = false;
|
|
259
|
+
const tracker = createCodeLanguageTracker(() => onChange());
|
|
260
|
+
const scanJson = createJsonCompletenessScanner();
|
|
261
|
+
let formatted;
|
|
262
|
+
const generationOf = (input) => {
|
|
263
|
+
if (!committed) return 0;
|
|
264
|
+
return input.identity === committed.identity && input.language === committed.language && extendsCode(input.code, committed.code) ? committed.generation : committed.generation + 1;
|
|
265
|
+
};
|
|
266
|
+
const languageOf = (input) => input.language || (input.autoDetect ? tracker.read(input.code, input.streaming) ?? "" : "");
|
|
267
|
+
const pretty = (source, nested) => {
|
|
268
|
+
if (formatted?.source !== source || formatted.nested !== nested) formatted = {
|
|
269
|
+
source,
|
|
270
|
+
nested,
|
|
271
|
+
text: prettyPrintJson(source, nested)
|
|
272
|
+
};
|
|
273
|
+
return formatted.text;
|
|
274
|
+
};
|
|
275
|
+
return {
|
|
276
|
+
read(input) {
|
|
277
|
+
const generation = generationOf(input);
|
|
278
|
+
const language = languageOf(input);
|
|
279
|
+
const displayed = !shown || !input.streaming || input.highlightIntervalMs === 0 || shown.generation !== generation || shown.language !== language ? input.code : shown.code;
|
|
280
|
+
return {
|
|
281
|
+
text: input.formatJson && displayed && language === "json" && (!input.streaming || scanJson(displayed)) ? pretty(displayed, input.expandNestedJson) : displayed,
|
|
282
|
+
language,
|
|
283
|
+
generation
|
|
284
|
+
};
|
|
285
|
+
},
|
|
286
|
+
commit(input) {
|
|
287
|
+
const generation = generationOf(input);
|
|
288
|
+
const moved = input.autoDetect && !input.language ? tracker.observe(input.code, input.streaming) : (tracker.dispose(), false);
|
|
289
|
+
const language = languageOf(input);
|
|
290
|
+
committed = {
|
|
291
|
+
code: input.code,
|
|
292
|
+
language: input.language,
|
|
293
|
+
identity: input.identity,
|
|
294
|
+
generation
|
|
295
|
+
};
|
|
296
|
+
const key = `${generation}:${language}`;
|
|
297
|
+
if (token?.key !== key) token = {
|
|
298
|
+
key,
|
|
299
|
+
value: {}
|
|
300
|
+
};
|
|
301
|
+
const frame = {
|
|
302
|
+
code: input.code,
|
|
303
|
+
language,
|
|
304
|
+
generation: token.value
|
|
305
|
+
};
|
|
306
|
+
committing = true;
|
|
307
|
+
try {
|
|
308
|
+
if (!frames) {
|
|
309
|
+
shown = {
|
|
310
|
+
code: input.code,
|
|
311
|
+
language,
|
|
312
|
+
generation
|
|
313
|
+
};
|
|
314
|
+
frames = createCodeFrame(frame, (next) => {
|
|
315
|
+
shown = {
|
|
316
|
+
code: next.code,
|
|
317
|
+
language: next.language,
|
|
318
|
+
generation: committed.generation
|
|
319
|
+
};
|
|
320
|
+
if (!committing) onChange();
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
frames.update(frame, input.streaming, input.highlightIntervalMs);
|
|
324
|
+
if (shown.code === input.code && shown.language === language) shown.generation = generation;
|
|
325
|
+
} finally {
|
|
326
|
+
committing = false;
|
|
327
|
+
}
|
|
328
|
+
if (moved) onChange();
|
|
329
|
+
},
|
|
330
|
+
dispose() {
|
|
331
|
+
frames?.dispose();
|
|
332
|
+
tracker.dispose();
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
}
|
|
193
336
|
function createRenderQueue() {
|
|
194
337
|
const pending = /* @__PURE__ */ new Map();
|
|
195
338
|
let running = false;
|
|
@@ -231,9 +374,6 @@ function createRenderQueue() {
|
|
|
231
374
|
const mermaidRenderQueue = createRenderQueue();
|
|
232
375
|
const SAFE_SECURITY_LEVELS = /* @__PURE__ */ new Set(["strict", "sandbox"]);
|
|
233
376
|
let ownedThemes = /* @__PURE__ */ new WeakMap();
|
|
234
|
-
const resetMermaidInitializationForTests = () => {
|
|
235
|
-
ownedThemes = /* @__PURE__ */ new WeakMap();
|
|
236
|
-
};
|
|
237
377
|
const readSiteConfig = (mermaid) => {
|
|
238
378
|
const api = mermaid.mermaidAPI;
|
|
239
379
|
return api?.getSiteConfig?.() ?? api?.getConfig?.() ?? {};
|
|
@@ -271,94 +411,265 @@ const ensureMermaidInitialized = (mermaid, isDark) => {
|
|
|
271
411
|
}
|
|
272
412
|
mermaid.initialize(next);
|
|
273
413
|
};
|
|
274
|
-
|
|
414
|
+
function diagramErrorText(error, labels) {
|
|
415
|
+
if (error.reason === "tooLarge") return labels.tooLarge(error.length, error.limit);
|
|
416
|
+
return error.message || labels.renderFailed;
|
|
417
|
+
}
|
|
418
|
+
const ERROR_MESSAGE_MAX_CHARS = 500;
|
|
419
|
+
const LOAD_RETRIES = 3;
|
|
420
|
+
const LOAD_RETRY_MS = 1500;
|
|
421
|
+
function engineMessage(error) {
|
|
422
|
+
const text = (error instanceof Error ? error.message : typeof error === "string" ? error : "").replace(/\r\n?/g, "\n").trim();
|
|
423
|
+
return text.length > ERROR_MESSAGE_MAX_CHARS ? `${text.slice(0, ERROR_MESSAGE_MAX_CHARS)}…` : text;
|
|
424
|
+
}
|
|
425
|
+
var DiagramFailure = class {
|
|
426
|
+
view;
|
|
427
|
+
constructor(view) {
|
|
428
|
+
this.view = view;
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
const diagramId = () => `mermaid-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
275
432
|
function createDiagramController(load, publish) {
|
|
276
433
|
const owner = {};
|
|
434
|
+
let request;
|
|
435
|
+
let current;
|
|
436
|
+
let shown;
|
|
437
|
+
let frames;
|
|
438
|
+
let updating = false;
|
|
439
|
+
let view = { kind: "source" };
|
|
440
|
+
let loadFailed = false;
|
|
441
|
+
let previousStreaming = false;
|
|
442
|
+
let needsCorrective = false;
|
|
443
|
+
let lastSuccess;
|
|
444
|
+
let loadFailures = 0;
|
|
445
|
+
let nonce = 0;
|
|
446
|
+
let ran;
|
|
277
447
|
let epoch = 0;
|
|
278
|
-
let
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
448
|
+
let retryTimer;
|
|
449
|
+
const sameError = (a, b) => a.reason === "tooLarge" ? b.reason === "tooLarge" && a.length === b.length && a.limit === b.limit : b.reason === a.reason && a.message === b.message;
|
|
450
|
+
const emit = () => publish({
|
|
451
|
+
view,
|
|
452
|
+
loadFailed
|
|
453
|
+
});
|
|
454
|
+
const show = (next) => {
|
|
455
|
+
if (next.kind === "source" && view.kind === "source") return;
|
|
456
|
+
if (next.kind === "error" && view.kind === "error" && sameError(next, view)) return;
|
|
457
|
+
view = next;
|
|
458
|
+
emit();
|
|
459
|
+
};
|
|
282
460
|
const cancel = () => {
|
|
283
461
|
epoch++;
|
|
284
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
285
|
-
timer = void 0;
|
|
286
462
|
mermaidRenderQueue.cancel(owner);
|
|
463
|
+
if (retryTimer !== void 0) clearTimeout(retryTimer);
|
|
464
|
+
retryTimer = void 0;
|
|
287
465
|
};
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
if (
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
466
|
+
const attempt = async (code, dark, streaming, generation) => {
|
|
467
|
+
const stale = () => generation !== epoch;
|
|
468
|
+
let engine;
|
|
469
|
+
try {
|
|
470
|
+
engine = await load();
|
|
471
|
+
} catch {
|
|
472
|
+
if (stale()) return;
|
|
473
|
+
if (loadFailures < LOAD_RETRIES) {
|
|
474
|
+
loadFailures += 1;
|
|
475
|
+
retryTimer = setTimeout(() => {
|
|
476
|
+
retryTimer = void 0;
|
|
477
|
+
nonce++;
|
|
478
|
+
run();
|
|
479
|
+
}, LOAD_RETRY_MS);
|
|
480
|
+
} else if (!loadFailed) {
|
|
481
|
+
loadFailed = true;
|
|
482
|
+
emit();
|
|
304
483
|
}
|
|
305
|
-
|
|
306
|
-
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
loadFailures = 0;
|
|
487
|
+
let reason = "render";
|
|
488
|
+
try {
|
|
489
|
+
if (stale()) return;
|
|
490
|
+
ensureMermaidInitialized(engine, dark);
|
|
491
|
+
const maxTextSize = getMermaidMaxTextSize(engine);
|
|
492
|
+
if (code.length > maxTextSize) throw new DiagramFailure({
|
|
493
|
+
kind: "error",
|
|
494
|
+
reason: "tooLarge",
|
|
495
|
+
length: code.length,
|
|
496
|
+
limit: maxTextSize
|
|
497
|
+
});
|
|
498
|
+
reason = "parse";
|
|
499
|
+
if (!await engine.parse(code)) throw new DiagramFailure({
|
|
500
|
+
kind: "error",
|
|
501
|
+
reason: "parse",
|
|
502
|
+
message: ""
|
|
503
|
+
});
|
|
504
|
+
reason = "render";
|
|
505
|
+
if (stale()) return;
|
|
506
|
+
const { svg, bindFunctions, diagramType } = await engine.render(diagramId(), code);
|
|
507
|
+
if (stale()) return;
|
|
508
|
+
needsCorrective = false;
|
|
509
|
+
lastSuccess = {
|
|
510
|
+
code,
|
|
511
|
+
dark
|
|
512
|
+
};
|
|
513
|
+
loadFailed = false;
|
|
514
|
+
show({
|
|
515
|
+
kind: "diagram",
|
|
307
516
|
svg,
|
|
308
|
-
|
|
517
|
+
chartType: diagramType ?? "",
|
|
518
|
+
bind: bindFunctions
|
|
309
519
|
});
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
phase = "render";
|
|
318
|
-
if (!valid()) return;
|
|
319
|
-
return mermaidRenderQueue.enqueue(owner, async () => {
|
|
320
|
-
if (!valid()) return;
|
|
321
|
-
ensureMermaidInitialized(engine, current.dark);
|
|
322
|
-
if (current.code.length > getMermaidMaxTextSize(engine)) throw new Error("Diagram exceeds Mermaid’s maximum text size");
|
|
323
|
-
const parsed = await engine.parse(current.code, { suppressErrors: true });
|
|
324
|
-
if (!valid()) return;
|
|
325
|
-
if (parsed === false) throw new Error("Diagram syntax is incomplete or invalid");
|
|
326
|
-
const result = await engine.render(`aimd-diagram-${++nextId}`, current.code);
|
|
327
|
-
if (!valid()) return;
|
|
328
|
-
svg = result.svg;
|
|
329
|
-
bind = result.bindFunctions;
|
|
330
|
-
publish({
|
|
331
|
-
status: "ready",
|
|
332
|
-
svg,
|
|
333
|
-
bind
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
}).catch((error) => {
|
|
337
|
-
if (valid()) publish({
|
|
338
|
-
status: current.streaming && phase === "render" ? "loading" : "error",
|
|
339
|
-
svg,
|
|
340
|
-
bind,
|
|
341
|
-
error: (phase === "load" ? "Diagram engine could not load: " : "") + (error instanceof Error ? error.message : String(error)).slice(0, 500)
|
|
342
|
-
});
|
|
343
|
-
});
|
|
520
|
+
} catch (error) {
|
|
521
|
+
if (stale()) return;
|
|
522
|
+
if (streaming) return;
|
|
523
|
+
const failure = error instanceof DiagramFailure ? error.view : {
|
|
524
|
+
kind: "error",
|
|
525
|
+
reason,
|
|
526
|
+
message: engineMessage(error)
|
|
344
527
|
};
|
|
345
|
-
if (
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
528
|
+
if (needsCorrective) {
|
|
529
|
+
needsCorrective = false;
|
|
530
|
+
show(failure);
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
if (view.kind === "diagram") return;
|
|
534
|
+
show(failure);
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
function run() {
|
|
538
|
+
if (!request || !current || !shown) return;
|
|
539
|
+
const { dark, active, streaming, interval } = request;
|
|
540
|
+
const code = !streaming || interval === 0 || current.generation !== shown.generation ? request.code : shown.code;
|
|
541
|
+
if (ran && ran.code === code && ran.dark === dark && ran.active === active && ran.streaming === streaming && ran.nonce === nonce) return;
|
|
542
|
+
ran = {
|
|
543
|
+
code,
|
|
544
|
+
dark,
|
|
545
|
+
active,
|
|
546
|
+
streaming,
|
|
547
|
+
nonce
|
|
548
|
+
};
|
|
549
|
+
cancel();
|
|
550
|
+
if (streaming && !previousStreaming) {
|
|
551
|
+
needsCorrective = false;
|
|
552
|
+
lastSuccess = void 0;
|
|
553
|
+
loadFailures = 0;
|
|
554
|
+
if (view.kind !== "source" || loadFailed) {
|
|
555
|
+
loadFailed = false;
|
|
556
|
+
view = { kind: "source" };
|
|
557
|
+
emit();
|
|
558
|
+
}
|
|
559
|
+
} else if (!streaming && previousStreaming) needsCorrective = true;
|
|
560
|
+
previousStreaming = streaming;
|
|
561
|
+
if (!code || !active) return;
|
|
562
|
+
if (lastSuccess?.code === code && lastSuccess.dark === dark) {
|
|
563
|
+
needsCorrective = false;
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
const generation = epoch;
|
|
567
|
+
mermaidRenderQueue.enqueue(owner, () => attempt(code, dark, streaming, generation));
|
|
568
|
+
}
|
|
569
|
+
return {
|
|
570
|
+
update(next) {
|
|
571
|
+
request = next;
|
|
572
|
+
updating = true;
|
|
573
|
+
try {
|
|
574
|
+
if (!frames || !current) {
|
|
575
|
+
current = shown = nextCodeFrame(void 0, next.code, "");
|
|
576
|
+
frames = createCodeFrame(current, (frame) => {
|
|
577
|
+
shown = frame;
|
|
578
|
+
if (!updating) run();
|
|
579
|
+
});
|
|
580
|
+
} else current = nextCodeFrame(current, next.code, "");
|
|
581
|
+
frames.update(current, next.streaming, next.interval);
|
|
582
|
+
} finally {
|
|
583
|
+
updating = false;
|
|
584
|
+
}
|
|
585
|
+
run();
|
|
349
586
|
},
|
|
350
|
-
|
|
587
|
+
retry() {
|
|
588
|
+
loadFailures = 0;
|
|
589
|
+
if (loadFailed) {
|
|
590
|
+
loadFailed = false;
|
|
591
|
+
emit();
|
|
592
|
+
}
|
|
593
|
+
nonce++;
|
|
594
|
+
run();
|
|
595
|
+
},
|
|
596
|
+
dispose() {
|
|
597
|
+
cancel();
|
|
598
|
+
frames?.dispose();
|
|
599
|
+
ran = void 0;
|
|
600
|
+
}
|
|
351
601
|
};
|
|
352
602
|
}
|
|
603
|
+
function resolveLabels(defaults, option) {
|
|
604
|
+
const overrides = typeof option === "function" ? option() : option;
|
|
605
|
+
if (!overrides) return defaults;
|
|
606
|
+
const labels = { ...defaults };
|
|
607
|
+
for (const key of Object.keys(overrides)) {
|
|
608
|
+
const value = overrides[key];
|
|
609
|
+
if (value !== void 0) labels[key] = value;
|
|
610
|
+
}
|
|
611
|
+
return labels;
|
|
612
|
+
}
|
|
613
|
+
const defaultCodeBlockLabels = Object.freeze({
|
|
614
|
+
actions: "Code block actions",
|
|
615
|
+
plainText: "text",
|
|
616
|
+
copy: "Copy code",
|
|
617
|
+
copied: "Copied",
|
|
618
|
+
copyFailed: "Copy failed",
|
|
619
|
+
showSource: "Show source",
|
|
620
|
+
showPreview: "Show preview",
|
|
621
|
+
expand: "Expand",
|
|
622
|
+
collapse: "Collapse",
|
|
623
|
+
previewFailed: "Preview failed. Source is available below."
|
|
624
|
+
});
|
|
625
|
+
const defaultDiagramLabels = Object.freeze({
|
|
626
|
+
waiting: "Waiting for diagram…",
|
|
627
|
+
rendering: "Rendering diagram…",
|
|
628
|
+
loadFailed: "Diagram engine could not load.",
|
|
629
|
+
retry: "Retry diagram",
|
|
630
|
+
renderFailed: "Mermaid could not render this diagram.",
|
|
631
|
+
tooLarge: (length, limit) => `Diagram source is ${length} characters, above mermaid's maxTextSize of ${limit}.`
|
|
632
|
+
});
|
|
633
|
+
const defaultImageLabels = Object.freeze({
|
|
634
|
+
close: "Close preview",
|
|
635
|
+
prev: "Previous image",
|
|
636
|
+
next: "Next image",
|
|
637
|
+
rotateLeft: "Rotate left",
|
|
638
|
+
rotateRight: "Rotate right",
|
|
639
|
+
zoomIn: "Zoom in",
|
|
640
|
+
zoomOut: "Zoom out",
|
|
641
|
+
flipX: "Flip horizontally",
|
|
642
|
+
flipY: "Flip vertically",
|
|
643
|
+
loading: "Loading image…",
|
|
644
|
+
loadFailed: "Image could not be loaded.",
|
|
645
|
+
open: (alt) => `Preview image${alt ? `: ${alt}` : ""}`,
|
|
646
|
+
preview: "Image preview",
|
|
647
|
+
actions: "Image preview actions"
|
|
648
|
+
});
|
|
649
|
+
const defaultTableLabels = Object.freeze({
|
|
650
|
+
actions: "Table actions",
|
|
651
|
+
copy: "Copy table",
|
|
652
|
+
download: "Download CSV",
|
|
653
|
+
copied: "Table copied",
|
|
654
|
+
copyFailed: "Copy failed",
|
|
655
|
+
scrollRegion: "Scrollable table",
|
|
656
|
+
mergedCells: "Only tables without merged cells can be exported",
|
|
657
|
+
notRectangular: "Only rectangular tables can be exported",
|
|
658
|
+
unsupportedStructure: "Unsupported table structure",
|
|
659
|
+
unsupportedContent: "Unsupported table content",
|
|
660
|
+
unavailable: "Table source is unavailable"
|
|
661
|
+
});
|
|
353
662
|
const locks = /* @__PURE__ */ new WeakMap();
|
|
354
|
-
function lockImagePreviewScroll(target) {
|
|
663
|
+
function lockImagePreviewScroll(target, scrollbarWidth = 0) {
|
|
355
664
|
let lock = locks.get(target);
|
|
356
665
|
if (!lock) {
|
|
357
666
|
lock = {
|
|
358
667
|
count: 0,
|
|
359
|
-
overflow: target.style.overflow
|
|
668
|
+
overflow: target.style.overflow,
|
|
669
|
+
paddingRight: target.style.paddingRight
|
|
360
670
|
};
|
|
361
671
|
locks.set(target, lock);
|
|
672
|
+
if (scrollbarWidth > 0) target.style.paddingRight = lock.paddingRight ? `calc(${lock.paddingRight} + ${scrollbarWidth}px)` : `${scrollbarWidth}px`;
|
|
362
673
|
}
|
|
363
674
|
lock.count++;
|
|
364
675
|
target.style.overflow = "hidden";
|
|
@@ -368,10 +679,374 @@ function lockImagePreviewScroll(target) {
|
|
|
368
679
|
released = true;
|
|
369
680
|
if (--lock.count === 0) {
|
|
370
681
|
if (target.style.overflow === "hidden") target.style.overflow = lock.overflow;
|
|
682
|
+
target.style.paddingRight = lock.paddingRight;
|
|
371
683
|
locks.delete(target);
|
|
372
684
|
}
|
|
373
685
|
};
|
|
374
686
|
}
|
|
687
|
+
const initialImageTransform = () => ({
|
|
688
|
+
x: 0,
|
|
689
|
+
y: 0,
|
|
690
|
+
rotate: 0,
|
|
691
|
+
scale: 1,
|
|
692
|
+
flipX: false,
|
|
693
|
+
flipY: false
|
|
694
|
+
});
|
|
695
|
+
function imageTransformStyle(transform) {
|
|
696
|
+
const { x, y, scale, rotate, flipX, flipY } = transform;
|
|
697
|
+
return `translate3d(${x}px, ${y}px, 0) scale3d(${flipX ? "-" : ""}${scale}, ${flipY ? "-" : ""}${scale}, 1) rotate(${rotate}deg)`;
|
|
698
|
+
}
|
|
699
|
+
function zoomImage(transform, ratio, geometry, centerX = geometry.viewportWidth / 2, centerY = geometry.viewportHeight / 2, touch = false) {
|
|
700
|
+
if (!Number.isFinite(ratio) || ratio <= 0) return transform;
|
|
701
|
+
const scale = Math.min(50, touch ? Math.max(.01, transform.scale * ratio) : Math.max(1, transform.scale * ratio));
|
|
702
|
+
const difference = scale / transform.scale - 1;
|
|
703
|
+
let x = transform.x - difference * (centerX - transform.x - geometry.left - geometry.width / 2);
|
|
704
|
+
let y = transform.y - difference * (centerY - transform.y - geometry.top - geometry.height / 2);
|
|
705
|
+
if (ratio < 1 && scale === 1 && geometry.width <= geometry.viewportWidth && geometry.height <= geometry.viewportHeight) x = y = 0;
|
|
706
|
+
return {
|
|
707
|
+
...transform,
|
|
708
|
+
x,
|
|
709
|
+
y,
|
|
710
|
+
scale
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
function imageWheelRatio(delta, mode = 0, pinch = false) {
|
|
714
|
+
if (!Number.isFinite(delta) || delta === 0) return 1;
|
|
715
|
+
if (pinch) return Math.min(1.5, Math.max(1 / 1.5, Math.exp(-delta / 100)));
|
|
716
|
+
const pixels = mode === 1 ? delta * 100 / 3 : mode === 2 ? delta * 100 : delta;
|
|
717
|
+
const ratio = 1 + Math.min(Math.abs(pixels / 100), 1) * .5;
|
|
718
|
+
return pixels > 0 ? 1 / ratio : ratio;
|
|
719
|
+
}
|
|
720
|
+
function reboundImage(transform, geometry, bounds) {
|
|
721
|
+
if (transform.scale < 1) return {
|
|
722
|
+
...transform,
|
|
723
|
+
x: 0,
|
|
724
|
+
y: 0,
|
|
725
|
+
scale: 1
|
|
726
|
+
};
|
|
727
|
+
const rotated = transform.rotate % 180 !== 0;
|
|
728
|
+
const width = (rotated ? geometry.height : geometry.width) * transform.scale;
|
|
729
|
+
const height = (rotated ? geometry.width : geometry.height) * transform.scale;
|
|
730
|
+
if (width <= geometry.viewportWidth && height <= geometry.viewportHeight) return {
|
|
731
|
+
...transform,
|
|
732
|
+
x: 0,
|
|
733
|
+
y: 0
|
|
734
|
+
};
|
|
735
|
+
const fix = (position, start, size, viewport) => {
|
|
736
|
+
const offset = (size - viewport) / 2;
|
|
737
|
+
if (size > viewport) {
|
|
738
|
+
if (start > 0) return offset;
|
|
739
|
+
if (start < 0 && start + size < viewport) return -offset;
|
|
740
|
+
} else if (start < 0 || start + size > viewport) return start < 0 ? offset : -offset;
|
|
741
|
+
return position;
|
|
742
|
+
};
|
|
743
|
+
return {
|
|
744
|
+
...transform,
|
|
745
|
+
x: fix(transform.x, bounds.left, width, geometry.viewportWidth),
|
|
746
|
+
y: fix(transform.y, bounds.top, height, geometry.viewportHeight)
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
function imagePinchCenter(oldA, oldB, a, b) {
|
|
750
|
+
const distanceA = Math.hypot(a.x - oldA.x, a.y - oldA.y), distanceB = Math.hypot(b.x - oldB.x, b.y - oldB.y);
|
|
751
|
+
const ratio = distanceA + distanceB ? distanceA / (distanceA + distanceB) : 0;
|
|
752
|
+
return {
|
|
753
|
+
x: oldA.x + ratio * (oldB.x - oldA.x),
|
|
754
|
+
y: oldA.y + ratio * (oldB.y - oldA.y)
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
const ZOOM_STEP = 1.5;
|
|
758
|
+
const MAX_SCALE = 50;
|
|
759
|
+
const CLOSE_MS = 300;
|
|
760
|
+
const closedState = Object.freeze({
|
|
761
|
+
phase: "closed",
|
|
762
|
+
items: Object.freeze([]),
|
|
763
|
+
current: -1,
|
|
764
|
+
item: void 0,
|
|
765
|
+
transform: initialImageTransform(),
|
|
766
|
+
status: "loading",
|
|
767
|
+
moving: false,
|
|
768
|
+
canPrevious: false,
|
|
769
|
+
canNext: false,
|
|
770
|
+
canZoomIn: false,
|
|
771
|
+
canZoomOut: false
|
|
772
|
+
});
|
|
773
|
+
function createImagePreviewController(host, publish, options = {}) {
|
|
774
|
+
let phase = "closed";
|
|
775
|
+
let items = [];
|
|
776
|
+
let selected;
|
|
777
|
+
let current = -1;
|
|
778
|
+
let transform = initialImageTransform();
|
|
779
|
+
let status = "loading";
|
|
780
|
+
let moving = false;
|
|
781
|
+
let unsubscribe;
|
|
782
|
+
let cancelPublish;
|
|
783
|
+
let cancelOpening;
|
|
784
|
+
let closeTimer;
|
|
785
|
+
const pointers = /* @__PURE__ */ new Map();
|
|
786
|
+
let grip;
|
|
787
|
+
let displaced = false;
|
|
788
|
+
const snapshot = () => {
|
|
789
|
+
if (phase === "closed") return closedState;
|
|
790
|
+
const ready = status === "ready";
|
|
791
|
+
return {
|
|
792
|
+
phase,
|
|
793
|
+
items,
|
|
794
|
+
current,
|
|
795
|
+
item: items[current],
|
|
796
|
+
transform,
|
|
797
|
+
status,
|
|
798
|
+
moving,
|
|
799
|
+
canPrevious: current > 0,
|
|
800
|
+
canNext: current < items.length - 1,
|
|
801
|
+
canZoomIn: ready && transform.scale < MAX_SCALE,
|
|
802
|
+
canZoomOut: ready && transform.scale > 1
|
|
803
|
+
};
|
|
804
|
+
};
|
|
805
|
+
const emit = () => {
|
|
806
|
+
cancelPublish?.();
|
|
807
|
+
cancelPublish = void 0;
|
|
808
|
+
publish(snapshot());
|
|
809
|
+
};
|
|
810
|
+
const emitNextFrame = () => {
|
|
811
|
+
cancelPublish ??= host.frame(() => {
|
|
812
|
+
cancelPublish = void 0;
|
|
813
|
+
publish(snapshot());
|
|
814
|
+
});
|
|
815
|
+
};
|
|
816
|
+
const endGesture = () => {
|
|
817
|
+
pointers.clear();
|
|
818
|
+
grip = void 0;
|
|
819
|
+
displaced = false;
|
|
820
|
+
moving = false;
|
|
821
|
+
};
|
|
822
|
+
const startImage = () => {
|
|
823
|
+
transform = initialImageTransform();
|
|
824
|
+
status = "loading";
|
|
825
|
+
endGesture();
|
|
826
|
+
};
|
|
827
|
+
const zoom = (ratio, x, y, touch = false) => {
|
|
828
|
+
const box = host.geometry();
|
|
829
|
+
if (box && status === "ready") transform = zoomImage(transform, ratio, box, x, y, touch);
|
|
830
|
+
};
|
|
831
|
+
const rebound = () => {
|
|
832
|
+
if (transform.scale < 1) {
|
|
833
|
+
transform = {
|
|
834
|
+
...transform,
|
|
835
|
+
x: 0,
|
|
836
|
+
y: 0,
|
|
837
|
+
scale: 1
|
|
838
|
+
};
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
const box = host.geometry();
|
|
842
|
+
if (!box) return;
|
|
843
|
+
const turned = transform.rotate % 180 !== 0;
|
|
844
|
+
const width = (turned ? box.height : box.width) * transform.scale;
|
|
845
|
+
const height = (turned ? box.width : box.height) * transform.scale;
|
|
846
|
+
transform = reboundImage(transform, box, {
|
|
847
|
+
left: box.left + box.width / 2 + transform.x - width / 2,
|
|
848
|
+
top: box.top + box.height / 2 + transform.y - height / 2
|
|
849
|
+
});
|
|
850
|
+
};
|
|
851
|
+
const finishClosing = () => {
|
|
852
|
+
closeTimer = void 0;
|
|
853
|
+
phase = "closed";
|
|
854
|
+
items = [];
|
|
855
|
+
selected = void 0;
|
|
856
|
+
current = -1;
|
|
857
|
+
emit();
|
|
858
|
+
};
|
|
859
|
+
const close = () => {
|
|
860
|
+
if (phase === "closed" || phase === "closing") return;
|
|
861
|
+
cancelOpening?.();
|
|
862
|
+
cancelOpening = void 0;
|
|
863
|
+
unsubscribe?.();
|
|
864
|
+
unsubscribe = void 0;
|
|
865
|
+
endGesture();
|
|
866
|
+
phase = "closing";
|
|
867
|
+
const duration = typeof options.closeDuration === "function" ? options.closeDuration() : options.closeDuration ?? CLOSE_MS;
|
|
868
|
+
if (duration > 0) {
|
|
869
|
+
emit();
|
|
870
|
+
closeTimer = setTimeout(finishClosing, duration);
|
|
871
|
+
} else finishClosing();
|
|
872
|
+
};
|
|
873
|
+
const go = (delta) => {
|
|
874
|
+
const target = current + delta;
|
|
875
|
+
if (phase === "closed" || phase === "closing" || target < 0 || target >= items.length || target === current) return;
|
|
876
|
+
current = target;
|
|
877
|
+
selected = items[target].id;
|
|
878
|
+
startImage();
|
|
879
|
+
emit();
|
|
880
|
+
};
|
|
881
|
+
const follow = (gallery) => {
|
|
882
|
+
const next = gallery.items();
|
|
883
|
+
const index = next.findIndex((item) => item.id === selected);
|
|
884
|
+
if (index < 0) return close();
|
|
885
|
+
if (next[index].src !== items[current]?.src) startImage();
|
|
886
|
+
items = next;
|
|
887
|
+
current = index;
|
|
888
|
+
emit();
|
|
889
|
+
};
|
|
890
|
+
return {
|
|
891
|
+
state: snapshot,
|
|
892
|
+
open(gallery, id) {
|
|
893
|
+
const list = gallery.items();
|
|
894
|
+
const index = list.findIndex((item) => item.id === id);
|
|
895
|
+
if (index < 0) return false;
|
|
896
|
+
if (closeTimer !== void 0) clearTimeout(closeTimer);
|
|
897
|
+
closeTimer = void 0;
|
|
898
|
+
unsubscribe?.();
|
|
899
|
+
cancelOpening?.();
|
|
900
|
+
items = list;
|
|
901
|
+
current = index;
|
|
902
|
+
selected = id;
|
|
903
|
+
startImage();
|
|
904
|
+
unsubscribe = gallery.subscribe(() => follow(gallery));
|
|
905
|
+
if (phase === "open") {
|
|
906
|
+
emit();
|
|
907
|
+
return true;
|
|
908
|
+
}
|
|
909
|
+
cancelOpening = void 0;
|
|
910
|
+
phase = "opening";
|
|
911
|
+
emit();
|
|
912
|
+
cancelOpening = host.frame(() => {
|
|
913
|
+
cancelOpening = host.frame(() => {
|
|
914
|
+
cancelOpening = void 0;
|
|
915
|
+
phase = "open";
|
|
916
|
+
emit();
|
|
917
|
+
});
|
|
918
|
+
});
|
|
919
|
+
return true;
|
|
920
|
+
},
|
|
921
|
+
close,
|
|
922
|
+
go,
|
|
923
|
+
action(name) {
|
|
924
|
+
if (phase === "closed" || phase === "closing") return;
|
|
925
|
+
if (name === "close") return close();
|
|
926
|
+
if (name === "prev") return go(-1);
|
|
927
|
+
if (name === "next") return go(1);
|
|
928
|
+
if (status !== "ready") return;
|
|
929
|
+
if (name === "zoomIn") zoom(ZOOM_STEP);
|
|
930
|
+
else if (name === "zoomOut") zoom(1 / ZOOM_STEP);
|
|
931
|
+
else if (name === "rotateLeft") transform = {
|
|
932
|
+
...transform,
|
|
933
|
+
rotate: transform.rotate - 90
|
|
934
|
+
};
|
|
935
|
+
else if (name === "rotateRight") transform = {
|
|
936
|
+
...transform,
|
|
937
|
+
rotate: transform.rotate + 90
|
|
938
|
+
};
|
|
939
|
+
else if (name === "flipX") transform = {
|
|
940
|
+
...transform,
|
|
941
|
+
flipX: !transform.flipX
|
|
942
|
+
};
|
|
943
|
+
else if (name === "flipY") transform = {
|
|
944
|
+
...transform,
|
|
945
|
+
flipY: !transform.flipY
|
|
946
|
+
};
|
|
947
|
+
emit();
|
|
948
|
+
},
|
|
949
|
+
loaded() {
|
|
950
|
+
if (phase === "closed" || status === "ready") return;
|
|
951
|
+
status = "ready";
|
|
952
|
+
emit();
|
|
953
|
+
},
|
|
954
|
+
failed() {
|
|
955
|
+
if (phase === "closed" || status === "error") return;
|
|
956
|
+
status = "error";
|
|
957
|
+
endGesture();
|
|
958
|
+
emit();
|
|
959
|
+
},
|
|
960
|
+
pointerDown(pointer) {
|
|
961
|
+
if (phase !== "open" && phase !== "opening" || status !== "ready") return false;
|
|
962
|
+
if (pointer.button !== void 0 && pointer.button !== 0) return false;
|
|
963
|
+
if (pointers.size >= 2 && !pointers.has(pointer.id)) return false;
|
|
964
|
+
pointers.set(pointer.id, {
|
|
965
|
+
x: pointer.x,
|
|
966
|
+
y: pointer.y
|
|
967
|
+
});
|
|
968
|
+
grip = pointers.size === 1 ? {
|
|
969
|
+
x: pointer.x - transform.x,
|
|
970
|
+
y: pointer.y - transform.y
|
|
971
|
+
} : void 0;
|
|
972
|
+
moving = true;
|
|
973
|
+
emit();
|
|
974
|
+
return true;
|
|
975
|
+
},
|
|
976
|
+
pointerMove(pointer) {
|
|
977
|
+
const previous = pointers.get(pointer.id);
|
|
978
|
+
if (!previous || previous.x === pointer.x && previous.y === pointer.y) return;
|
|
979
|
+
const before = [...pointers.values()];
|
|
980
|
+
pointers.set(pointer.id, {
|
|
981
|
+
x: pointer.x,
|
|
982
|
+
y: pointer.y
|
|
983
|
+
});
|
|
984
|
+
if (pointers.size === 2) {
|
|
985
|
+
const [a, b] = [...pointers.values()];
|
|
986
|
+
const span = Math.hypot(before[0].x - before[1].x, before[0].y - before[1].y);
|
|
987
|
+
const center = imagePinchCenter(before[0], before[1], a, b);
|
|
988
|
+
if (span > 0) zoom(Math.hypot(a.x - b.x, a.y - b.y) / span, center.x, center.y, true);
|
|
989
|
+
} else if (grip) transform = {
|
|
990
|
+
...transform,
|
|
991
|
+
x: pointer.x - grip.x,
|
|
992
|
+
y: pointer.y - grip.y
|
|
993
|
+
};
|
|
994
|
+
displaced = true;
|
|
995
|
+
emitNextFrame();
|
|
996
|
+
},
|
|
997
|
+
pointerUp(id) {
|
|
998
|
+
if (!pointers.delete(id)) return;
|
|
999
|
+
const [remaining] = pointers.values();
|
|
1000
|
+
if (remaining) {
|
|
1001
|
+
grip = {
|
|
1002
|
+
x: remaining.x - transform.x,
|
|
1003
|
+
y: remaining.y - transform.y
|
|
1004
|
+
};
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
const settle = displaced;
|
|
1008
|
+
endGesture();
|
|
1009
|
+
if (settle) rebound();
|
|
1010
|
+
emit();
|
|
1011
|
+
},
|
|
1012
|
+
wheel(input) {
|
|
1013
|
+
if (phase !== "open" || status !== "ready" || !input.deltaY) return false;
|
|
1014
|
+
zoom(imageWheelRatio(input.deltaY, input.mode, input.pinch), input.x, input.y);
|
|
1015
|
+
emitNextFrame();
|
|
1016
|
+
return true;
|
|
1017
|
+
},
|
|
1018
|
+
doubleClick(x, y) {
|
|
1019
|
+
if (phase !== "open" || status !== "ready") return;
|
|
1020
|
+
if (transform.scale !== 1) transform = {
|
|
1021
|
+
...transform,
|
|
1022
|
+
x: 0,
|
|
1023
|
+
y: 0,
|
|
1024
|
+
scale: 1
|
|
1025
|
+
};
|
|
1026
|
+
else zoom(ZOOM_STEP, x, y);
|
|
1027
|
+
emit();
|
|
1028
|
+
},
|
|
1029
|
+
key(key) {
|
|
1030
|
+
if (phase !== "open" && phase !== "opening" || items.length < 2) return false;
|
|
1031
|
+
if (key !== "ArrowLeft" && key !== "ArrowRight") return false;
|
|
1032
|
+
go(key === "ArrowLeft" ? -1 : 1);
|
|
1033
|
+
return true;
|
|
1034
|
+
},
|
|
1035
|
+
dispose() {
|
|
1036
|
+
if (closeTimer !== void 0) clearTimeout(closeTimer);
|
|
1037
|
+
closeTimer = void 0;
|
|
1038
|
+
cancelPublish?.();
|
|
1039
|
+
cancelOpening?.();
|
|
1040
|
+
unsubscribe?.();
|
|
1041
|
+
cancelPublish = cancelOpening = unsubscribe = void 0;
|
|
1042
|
+
endGesture();
|
|
1043
|
+
phase = "closed";
|
|
1044
|
+
items = [];
|
|
1045
|
+
selected = void 0;
|
|
1046
|
+
current = -1;
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
375
1050
|
const imageIconPaths = {
|
|
376
1051
|
rotateLeft: ["M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8", "M3 3v5h5"],
|
|
377
1052
|
rotateRight: ["M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8", "M21 3v5h-5"],
|
|
@@ -418,16 +1093,20 @@ const imageIconPaths = {
|
|
|
418
1093
|
"M11 9a2 2 0 1 1-4 0 2 2 0 0 1 4 0"
|
|
419
1094
|
]
|
|
420
1095
|
};
|
|
421
|
-
const imageGroupSelector = "[data-aimd-image-scope], .aim-typography-root, .aimd-vue, .mantine-Typography-root";
|
|
422
1096
|
const galleries = /* @__PURE__ */ new WeakMap();
|
|
423
1097
|
function getImageGallery(scope) {
|
|
424
1098
|
const existing = galleries.get(scope);
|
|
425
1099
|
if (existing) return existing;
|
|
426
1100
|
const entries = /* @__PURE__ */ new Map();
|
|
427
1101
|
const listeners = /* @__PURE__ */ new Set();
|
|
428
|
-
|
|
1102
|
+
let sorted;
|
|
1103
|
+
const notify = () => {
|
|
1104
|
+
sorted = void 0;
|
|
1105
|
+
listeners.forEach((listener) => listener());
|
|
1106
|
+
};
|
|
429
1107
|
const gallery = {
|
|
430
|
-
items: () => [...entries.values()].sort((a, b) => a.precedes(b.id) ? -1 : b.precedes(a.id) ? 1 : 0),
|
|
1108
|
+
items: () => sorted ??= [...entries.values()].sort((a, b) => a.precedes(b.id) ? -1 : b.precedes(a.id) ? 1 : 0),
|
|
1109
|
+
size: () => entries.size,
|
|
431
1110
|
subscribe(listener) {
|
|
432
1111
|
listeners.add(listener);
|
|
433
1112
|
return () => {
|
|
@@ -447,95 +1126,34 @@ function getImageGallery(scope) {
|
|
|
447
1126
|
galleries.set(scope, gallery);
|
|
448
1127
|
return gallery;
|
|
449
1128
|
}
|
|
450
|
-
const
|
|
451
|
-
close
|
|
452
|
-
prev
|
|
453
|
-
next
|
|
454
|
-
rotateLeft
|
|
455
|
-
rotateRight
|
|
456
|
-
zoomIn
|
|
457
|
-
zoomOut
|
|
458
|
-
flipX
|
|
459
|
-
flipY
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
x: 0,
|
|
463
|
-
y: 0,
|
|
464
|
-
rotate: 0,
|
|
465
|
-
scale: 1,
|
|
466
|
-
flipX: false,
|
|
467
|
-
flipY: false
|
|
468
|
-
});
|
|
469
|
-
function imageTransformStyle(transform) {
|
|
470
|
-
const { x, y, scale, rotate, flipX, flipY } = transform;
|
|
471
|
-
return `translate3d(${x}px, ${y}px, 0) scale3d(${flipX ? "-" : ""}${scale}, ${flipY ? "-" : ""}${scale}, 1) rotate(${rotate}deg)`;
|
|
472
|
-
}
|
|
473
|
-
function zoomImage(transform, ratio, geometry, centerX = geometry.viewportWidth / 2, centerY = geometry.viewportHeight / 2, touch = false) {
|
|
474
|
-
if (!Number.isFinite(ratio) || ratio <= 0) return transform;
|
|
475
|
-
const scale = Math.min(50, touch ? Math.max(.01, transform.scale * ratio) : Math.max(1, transform.scale * ratio));
|
|
476
|
-
const difference = scale / transform.scale - 1;
|
|
477
|
-
let x = transform.x - difference * (centerX - transform.x - geometry.left - geometry.width / 2);
|
|
478
|
-
let y = transform.y - difference * (centerY - transform.y - geometry.top - geometry.height / 2);
|
|
479
|
-
if (ratio < 1 && scale === 1 && geometry.width <= geometry.viewportWidth && geometry.height <= geometry.viewportHeight) x = y = 0;
|
|
480
|
-
return {
|
|
481
|
-
...transform,
|
|
482
|
-
x,
|
|
483
|
-
y,
|
|
484
|
-
scale
|
|
485
|
-
};
|
|
486
|
-
}
|
|
487
|
-
function imageWheelRatio(delta) {
|
|
488
|
-
const ratio = 1 + Math.min(Math.abs(delta / 100), 1) * .5;
|
|
489
|
-
return delta > 0 ? 1 / ratio : ratio;
|
|
490
|
-
}
|
|
491
|
-
function reboundImage(transform, geometry, bounds) {
|
|
492
|
-
if (transform.scale < 1) return {
|
|
493
|
-
...transform,
|
|
494
|
-
x: 0,
|
|
495
|
-
y: 0,
|
|
496
|
-
scale: 1
|
|
497
|
-
};
|
|
498
|
-
const rotated = transform.rotate % 180 !== 0;
|
|
499
|
-
const width = (rotated ? geometry.height : geometry.width) * transform.scale;
|
|
500
|
-
const height = (rotated ? geometry.width : geometry.height) * transform.scale;
|
|
501
|
-
if (width <= geometry.viewportWidth && height <= geometry.viewportHeight) return {
|
|
502
|
-
...transform,
|
|
503
|
-
x: 0,
|
|
504
|
-
y: 0
|
|
505
|
-
};
|
|
506
|
-
const fix = (position, start, size, viewport) => {
|
|
507
|
-
const offset = (size - viewport) / 2;
|
|
508
|
-
if (size > viewport) {
|
|
509
|
-
if (start > 0) return offset;
|
|
510
|
-
if (start < 0 && start + size < viewport) return -offset;
|
|
511
|
-
} else if (start < 0 || start + size > viewport) return start < 0 ? offset : -offset;
|
|
512
|
-
return position;
|
|
513
|
-
};
|
|
514
|
-
return {
|
|
515
|
-
...transform,
|
|
516
|
-
x: fix(transform.x, bounds.left, width, geometry.viewportWidth),
|
|
517
|
-
y: fix(transform.y, bounds.top, height, geometry.viewportHeight)
|
|
518
|
-
};
|
|
519
|
-
}
|
|
520
|
-
function imagePinchCenter(oldA, oldB, a, b) {
|
|
521
|
-
const distanceA = Math.hypot(a.x - oldA.x, a.y - oldA.y), distanceB = Math.hypot(b.x - oldB.x, b.y - oldB.y);
|
|
522
|
-
const ratio = distanceA + distanceB ? distanceA / (distanceA + distanceB) : 0;
|
|
523
|
-
return {
|
|
524
|
-
x: oldA.x + ratio * (oldB.x - oldA.x),
|
|
525
|
-
y: oldA.y + ratio * (oldB.y - oldA.y)
|
|
526
|
-
};
|
|
527
|
-
}
|
|
528
|
-
exports.MERMAID_DEFAULT_MAX_TEXT_SIZE = MERMAID_DEFAULT_MAX_TEXT_SIZE;
|
|
1129
|
+
const imageActionNames = Object.freeze([
|
|
1130
|
+
"close",
|
|
1131
|
+
"prev",
|
|
1132
|
+
"next",
|
|
1133
|
+
"rotateLeft",
|
|
1134
|
+
"rotateRight",
|
|
1135
|
+
"zoomIn",
|
|
1136
|
+
"zoomOut",
|
|
1137
|
+
"flipX",
|
|
1138
|
+
"flipY"
|
|
1139
|
+
]);
|
|
1140
|
+
exports.createCodeBlockSession = createCodeBlockSession;
|
|
529
1141
|
exports.createCodeFrame = createCodeFrame;
|
|
1142
|
+
exports.createCodeLanguageTracker = createCodeLanguageTracker;
|
|
530
1143
|
exports.createDiagramController = createDiagramController;
|
|
1144
|
+
exports.createImagePreviewController = createImagePreviewController;
|
|
531
1145
|
exports.createJsonCompletenessScanner = createJsonCompletenessScanner;
|
|
532
|
-
exports.
|
|
1146
|
+
exports.defaultCodeBlockLabels = defaultCodeBlockLabels;
|
|
1147
|
+
exports.defaultDiagramLabels = defaultDiagramLabels;
|
|
1148
|
+
exports.defaultImageLabels = defaultImageLabels;
|
|
1149
|
+
exports.defaultTableLabels = defaultTableLabels;
|
|
1150
|
+
exports.diagramErrorText = diagramErrorText;
|
|
533
1151
|
exports.ensureMermaidInitialized = ensureMermaidInitialized;
|
|
1152
|
+
exports.extendsCode = extendsCode;
|
|
534
1153
|
exports.extractCode = extractCode;
|
|
535
1154
|
exports.getImageGallery = getImageGallery;
|
|
536
1155
|
exports.getMermaidMaxTextSize = getMermaidMaxTextSize;
|
|
537
|
-
exports.
|
|
538
|
-
exports.imageGroupSelector = imageGroupSelector;
|
|
1156
|
+
exports.imageActionNames = imageActionNames;
|
|
539
1157
|
exports.imageIconPaths = imageIconPaths;
|
|
540
1158
|
exports.imagePinchCenter = imagePinchCenter;
|
|
541
1159
|
exports.imageTransformStyle = imageTransformStyle;
|
|
@@ -544,11 +1162,12 @@ exports.initialImageTransform = initialImageTransform;
|
|
|
544
1162
|
exports.jsonLooksComplete = jsonLooksComplete;
|
|
545
1163
|
exports.lockImagePreviewScroll = lockImagePreviewScroll;
|
|
546
1164
|
exports.mermaidRenderQueue = mermaidRenderQueue;
|
|
1165
|
+
exports.nextCodeFrame = nextCodeFrame;
|
|
547
1166
|
exports.normalizeRenderers = normalizeRenderers;
|
|
548
1167
|
exports.prettyPrintJson = prettyPrintJson;
|
|
549
1168
|
exports.projectTable = projectTable;
|
|
550
1169
|
exports.reboundImage = reboundImage;
|
|
551
|
-
exports.
|
|
1170
|
+
exports.resolveLabels = resolveLabels;
|
|
552
1171
|
exports.serializeTable = serializeTable;
|
|
553
1172
|
exports.zoomImage = zoomImage;
|
|
554
1173
|
|