@vectojs/markdown 0.4.0 → 0.6.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/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
@@ -23,26 +33,442 @@ __export(index_exports, {
23
33
  CodeBlock: () => CodeBlock,
24
34
  Markdown: () => Markdown,
25
35
  codeAtlas: () => codeAtlas,
26
- codeAtlasStats: () => codeAtlasStats
36
+ codeAtlasStats: () => codeAtlasStats,
37
+ isMathJaxReady: () => isMathJaxReady,
38
+ preloadMathJax: () => preloadMathJax
27
39
  });
28
40
  module.exports = __toCommonJS(index_exports);
29
41
 
30
42
  // src/Markdown.ts
31
43
  var import_core = require("@vectojs/core");
32
44
  var import_marked = require("marked");
33
- var import_mathjax = require("mathjax-full/js/mathjax.js");
34
- var import_tex = require("mathjax-full/js/input/tex.js");
35
- var import_svg = require("mathjax-full/js/output/svg.js");
36
- var import_liteAdaptor = require("mathjax-full/js/adaptors/liteAdaptor.js");
37
- var import_html = require("mathjax-full/js/handlers/html.js");
38
- var import_AllPackages = require("mathjax-full/js/input/tex/AllPackages.js");
45
+
46
+ // src/StreamController.ts
47
+ var DEFAULT_MAX_BUFFERED_CHARS = 64 * 1024;
48
+ var MAX_FRAME_DELTA_MS = 100;
49
+ var MIN_SCAN_CODE_UNITS = 64;
50
+ function positiveFinite(value, label) {
51
+ if (!Number.isFinite(value) || value <= 0) {
52
+ throw new RangeError(`${label} must be a positive finite number`);
53
+ }
54
+ return value;
55
+ }
56
+ function abortError() {
57
+ const error = new Error("Stream aborted");
58
+ error.name = "AbortError";
59
+ return error;
60
+ }
61
+ var StreamControllerImpl = class {
62
+ constructor(host, options) {
63
+ this.host = host;
64
+ this.maxBufferedChars = positiveFinite(
65
+ options.maxBufferedChars ?? DEFAULT_MAX_BUFFERED_CHARS,
66
+ "maxBufferedChars"
67
+ );
68
+ this.graphemesPerSecond = options.pacing ? positiveFinite(options.pacing.graphemesPerSecond, "pacing.graphemesPerSecond") : null;
69
+ this.segmenter = this.graphemesPerSecond === null ? null : new Intl.Segmenter(void 0, { granularity: "grapheme" });
70
+ this.signal = options.signal;
71
+ this.onSignalAbort = () => this.abort(this.signal?.reason);
72
+ if (this.signal?.aborted) this.abort(this.signal.reason);
73
+ else
74
+ this.signal?.addEventListener("abort", this.onSignalAbort, {
75
+ once: true
76
+ });
77
+ }
78
+ host;
79
+ maxBufferedChars;
80
+ graphemesPerSecond;
81
+ segmenter;
82
+ signal;
83
+ onSignalAbort;
84
+ chunks = [];
85
+ headIndex = 0;
86
+ headOffset = 0;
87
+ acceptedChars = 0;
88
+ blocked = null;
89
+ currentState = "open";
90
+ terminalReason = null;
91
+ rafId = null;
92
+ lastFrameAt = null;
93
+ graphemeCredit = 0;
94
+ released = false;
95
+ closePromise = null;
96
+ resolveClose = null;
97
+ rejectClose = null;
98
+ get state() {
99
+ return this.currentState;
100
+ }
101
+ get bufferedChars() {
102
+ return this.acceptedChars + (this.blocked?.chunk.length ?? 0);
103
+ }
104
+ write(chunk) {
105
+ if (this.currentState !== "open" || this.closePromise) {
106
+ return Promise.reject(this.reasonForWrite());
107
+ }
108
+ if (chunk.length === 0) return Promise.resolve();
109
+ if (this.blocked) {
110
+ return Promise.reject(new Error("StreamController already has a blocked write"));
111
+ }
112
+ if (this.canAdmit(chunk)) {
113
+ this.admit(chunk);
114
+ try {
115
+ this.schedule();
116
+ return Promise.resolve();
117
+ } catch (error) {
118
+ return Promise.reject(error);
119
+ }
120
+ }
121
+ return new Promise((resolve, reject) => {
122
+ const blocked = { chunk, resolve, reject };
123
+ this.blocked = blocked;
124
+ try {
125
+ this.schedule();
126
+ } catch (error) {
127
+ if (this.blocked === blocked) this.blocked = null;
128
+ reject(error);
129
+ }
130
+ });
131
+ }
132
+ flush() {
133
+ if (this.currentState === "closed") return;
134
+ if (this.currentState === "aborted") throw this.terminalReason;
135
+ this.cancelFrame();
136
+ this.commitAllSubmitted();
137
+ this.resetPacingIfIdle();
138
+ }
139
+ close() {
140
+ if (this.currentState === "closed") return Promise.resolve();
141
+ if (this.currentState === "aborted") return Promise.reject(this.terminalReason);
142
+ if (this.closePromise) return this.closePromise;
143
+ let resolveClose;
144
+ let rejectClose;
145
+ const closePromise = new Promise((resolve, reject) => {
146
+ resolveClose = resolve;
147
+ rejectClose = reject;
148
+ });
149
+ this.closePromise = closePromise;
150
+ this.resolveClose = resolveClose;
151
+ this.rejectClose = rejectClose;
152
+ this.cancelFrame();
153
+ try {
154
+ this.commitAllSubmitted();
155
+ } catch (error) {
156
+ this.rejectPendingClose(error);
157
+ return closePromise;
158
+ }
159
+ if (this.currentState !== "open") {
160
+ this.rejectPendingClose(this.terminalReason);
161
+ return closePromise;
162
+ }
163
+ this.currentState = "closed";
164
+ let settled;
165
+ try {
166
+ settled = this.host.onClose?.();
167
+ } catch (error) {
168
+ this.cleanup();
169
+ this.rejectPendingClose(error);
170
+ return closePromise;
171
+ }
172
+ if (settled === void 0) {
173
+ this.cleanup();
174
+ this.resolveClose?.();
175
+ this.resolveClose = null;
176
+ this.rejectClose = null;
177
+ return closePromise;
178
+ }
179
+ void Promise.resolve(settled).then(
180
+ () => {
181
+ this.cleanup();
182
+ this.resolveClose?.();
183
+ this.resolveClose = null;
184
+ this.rejectClose = null;
185
+ },
186
+ (error) => {
187
+ this.cleanup();
188
+ this.rejectPendingClose(error);
189
+ }
190
+ );
191
+ return closePromise;
192
+ }
193
+ abort(reason) {
194
+ if (this.currentState !== "open") return;
195
+ this.fail(reason === void 0 ? abortError() : reason);
196
+ }
197
+ destroy() {
198
+ this.abort();
199
+ }
200
+ onFrame = (timestamp) => {
201
+ this.rafId = null;
202
+ if (this.currentState !== "open") return;
203
+ let keepScheduling = true;
204
+ try {
205
+ if (this.graphemesPerSecond === null) this.commitAccepted();
206
+ else keepScheduling = this.commitPaced(timestamp);
207
+ } catch {
208
+ return;
209
+ }
210
+ if (this.currentState !== "open") return;
211
+ this.admitBlockedIfPossible();
212
+ this.resetPacingIfIdle();
213
+ if (!keepScheduling) return;
214
+ try {
215
+ this.schedule();
216
+ } catch {
217
+ }
218
+ };
219
+ reasonForWrite() {
220
+ if (this.currentState === "aborted") return this.terminalReason;
221
+ if (this.currentState === "closed") return new Error("StreamController is closed");
222
+ return new Error("StreamController is closing");
223
+ }
224
+ canAdmit(chunk) {
225
+ return this.acceptedChars + chunk.length <= this.maxBufferedChars || this.acceptedChars === 0 && chunk.length > this.maxBufferedChars;
226
+ }
227
+ admit(chunk) {
228
+ this.chunks.push(chunk);
229
+ this.acceptedChars += chunk.length;
230
+ }
231
+ admitBlockedIfPossible() {
232
+ const blocked = this.blocked;
233
+ if (!blocked || !this.canAdmit(blocked.chunk)) return;
234
+ this.blocked = null;
235
+ this.admit(blocked.chunk);
236
+ blocked.resolve();
237
+ }
238
+ schedule() {
239
+ if (this.currentState !== "open" || this.acceptedChars === 0 || this.rafId !== null) return;
240
+ if (typeof requestAnimationFrame !== "function") {
241
+ this.flush();
242
+ return;
243
+ }
244
+ this.rafId = requestAnimationFrame(this.onFrame);
245
+ }
246
+ cancelFrame() {
247
+ if (this.rafId === null) return;
248
+ if (typeof cancelAnimationFrame === "function") cancelAnimationFrame(this.rafId);
249
+ this.rafId = null;
250
+ }
251
+ commitAccepted() {
252
+ if (this.acceptedChars === 0) return;
253
+ const text = this.takeAcceptedText();
254
+ try {
255
+ this.host.append(text);
256
+ } catch (error) {
257
+ this.fail(error);
258
+ throw error;
259
+ }
260
+ }
261
+ /** Return true while another frame can make progress without more producer input. */
262
+ commitPaced(timestamp) {
263
+ if (this.lastFrameAt === null) {
264
+ this.lastFrameAt = timestamp;
265
+ return true;
266
+ }
267
+ const delta = Math.min(MAX_FRAME_DELTA_MS, Math.max(0, timestamp - this.lastFrameAt));
268
+ this.lastFrameAt = timestamp;
269
+ this.graphemeCredit += delta * this.graphemesPerSecond / 1e3;
270
+ const available = Math.floor(this.graphemeCredit);
271
+ if (available < 1) return true;
272
+ const selected = this.selectGraphemePrefix(available);
273
+ if (selected.count === 0) {
274
+ this.lastFrameAt = null;
275
+ this.graphemeCredit = 0;
276
+ return false;
277
+ }
278
+ const completedBlocked = this.consumeSubmittedChars(selected.codeUnits);
279
+ try {
280
+ this.host.append(selected.text);
281
+ completedBlocked?.resolve();
282
+ } catch (error) {
283
+ completedBlocked?.reject(error);
284
+ this.fail(error);
285
+ throw error;
286
+ }
287
+ this.graphemeCredit -= selected.count;
288
+ return true;
289
+ }
290
+ selectGraphemePrefix(maxCount) {
291
+ const submittedChars = this.acceptedChars + (this.blocked?.chunk.length ?? 0);
292
+ let scanLength = Math.min(submittedChars, Math.max(MIN_SCAN_CODE_UNITS, maxCount * 2));
293
+ while (scanLength > 0) {
294
+ let sample = this.peekSubmittedChars(scanLength);
295
+ if (scanLength < submittedChars && /[\uD800-\uDBFF]$/.test(sample)) {
296
+ scanLength++;
297
+ sample = this.peekSubmittedChars(scanLength);
298
+ }
299
+ const segments = [...this.segmenter.segment(sample)];
300
+ const hasUnscannedText = scanLength < submittedChars;
301
+ if (hasUnscannedText && segments.length <= maxCount) {
302
+ scanLength = Math.min(submittedChars, scanLength * 2);
303
+ continue;
304
+ }
305
+ const count = hasUnscannedText ? maxCount : Math.min(maxCount, Math.max(0, segments.length - 1));
306
+ if (count > 0) {
307
+ const last = segments[count - 1];
308
+ const codeUnits = last.index + last.segment.length;
309
+ return { text: sample.slice(0, codeUnits), count, codeUnits };
310
+ }
311
+ if (this.blocked || this.acceptedChars > this.maxBufferedChars) {
312
+ return this.forceCodePointPrefix(sample);
313
+ }
314
+ return { text: "", count: 0, codeUnits: 0 };
315
+ }
316
+ return { text: "", count: 0, codeUnits: 0 };
317
+ }
318
+ forceCodePointPrefix(sample) {
319
+ const first = sample.charCodeAt(0);
320
+ const second = sample.charCodeAt(1);
321
+ const codeUnits = first >= 55296 && first <= 56319 && second >= 56320 && second <= 57343 ? 2 : 1;
322
+ return { text: sample.slice(0, codeUnits), count: 1, codeUnits };
323
+ }
324
+ peekSubmittedChars(limit) {
325
+ const parts = this.peekAcceptedParts(Math.min(limit, this.acceptedChars));
326
+ const acceptedLength = Math.min(limit, this.acceptedChars);
327
+ const blockedLength = limit - acceptedLength;
328
+ if (blockedLength > 0 && this.blocked) {
329
+ parts.push(this.blocked.chunk.slice(0, blockedLength));
330
+ }
331
+ return parts.length === 1 ? parts[0] : parts.join("");
332
+ }
333
+ peekAcceptedParts(limit) {
334
+ if (limit <= 0) return [];
335
+ const parts = [];
336
+ let remaining = limit;
337
+ for (let index = this.headIndex; index < this.chunks.length && remaining > 0; index++) {
338
+ const chunk = this.chunks[index];
339
+ const start = index === this.headIndex ? this.headOffset : 0;
340
+ const available = chunk.length - start;
341
+ if (available <= remaining) {
342
+ parts.push(start === 0 ? chunk : chunk.slice(start));
343
+ remaining -= available;
344
+ } else {
345
+ parts.push(chunk.slice(start, start + remaining));
346
+ remaining = 0;
347
+ }
348
+ }
349
+ return parts;
350
+ }
351
+ consumeSubmittedChars(count) {
352
+ const acceptedCount = Math.min(count, this.acceptedChars);
353
+ this.consumeAcceptedChars(acceptedCount);
354
+ const blockedCount = count - acceptedCount;
355
+ if (blockedCount === 0) return null;
356
+ const blocked = this.blocked;
357
+ if (!blocked) throw new Error("StreamController queue accounting diverged");
358
+ if (blockedCount >= blocked.chunk.length) {
359
+ this.blocked = null;
360
+ return blocked;
361
+ }
362
+ blocked.chunk = blocked.chunk.slice(blockedCount);
363
+ return null;
364
+ }
365
+ consumeAcceptedChars(count) {
366
+ if (count < 0 || count > this.acceptedChars) {
367
+ throw new Error("StreamController queue accounting diverged");
368
+ }
369
+ this.acceptedChars -= count;
370
+ let remaining = count;
371
+ while (remaining > 0) {
372
+ const chunk = this.chunks[this.headIndex];
373
+ const available = chunk.length - this.headOffset;
374
+ if (remaining < available) {
375
+ this.headOffset += remaining;
376
+ remaining = 0;
377
+ } else {
378
+ remaining -= available;
379
+ this.headIndex++;
380
+ this.headOffset = 0;
381
+ }
382
+ }
383
+ if (this.acceptedChars === 0) {
384
+ this.chunks = [];
385
+ this.headIndex = 0;
386
+ this.headOffset = 0;
387
+ } else if (this.headIndex >= 64 && this.headIndex * 2 >= this.chunks.length) {
388
+ this.chunks.splice(0, this.headIndex);
389
+ this.headIndex = 0;
390
+ }
391
+ }
392
+ takeAcceptedText() {
393
+ const parts = this.takeAcceptedParts();
394
+ return parts.length === 1 ? parts[0] : parts.join("");
395
+ }
396
+ takeAcceptedParts() {
397
+ const parts = this.peekAcceptedParts(this.acceptedChars);
398
+ this.chunks = [];
399
+ this.headIndex = 0;
400
+ this.headOffset = 0;
401
+ this.acceptedChars = 0;
402
+ return parts;
403
+ }
404
+ commitAllSubmitted() {
405
+ const blocked = this.blocked;
406
+ this.blocked = null;
407
+ const parts = this.takeAcceptedParts();
408
+ if (blocked) parts.push(blocked.chunk);
409
+ if (parts.length === 0) return;
410
+ try {
411
+ this.host.append(parts.length === 1 ? parts[0] : parts.join(""));
412
+ blocked?.resolve();
413
+ } catch (error) {
414
+ blocked?.reject(error);
415
+ this.fail(error);
416
+ throw error;
417
+ }
418
+ }
419
+ rejectPendingClose(reason) {
420
+ this.rejectClose?.(reason);
421
+ this.resolveClose = null;
422
+ this.rejectClose = null;
423
+ }
424
+ fail(reason) {
425
+ if (this.currentState !== "open") return;
426
+ this.currentState = "aborted";
427
+ this.terminalReason = reason;
428
+ this.cancelFrame();
429
+ this.chunks = [];
430
+ this.headIndex = 0;
431
+ this.headOffset = 0;
432
+ this.acceptedChars = 0;
433
+ const blocked = this.blocked;
434
+ this.blocked = null;
435
+ blocked?.reject(reason);
436
+ this.rejectPendingClose(reason);
437
+ this.cleanup();
438
+ }
439
+ cleanup() {
440
+ this.signal?.removeEventListener("abort", this.onSignalAbort);
441
+ if (this.released) return;
442
+ this.released = true;
443
+ this.host.release(this);
444
+ }
445
+ resetPacingIfIdle() {
446
+ if (this.acceptedChars !== 0 || this.blocked) return;
447
+ this.lastFrameAt = null;
448
+ this.graphemeCredit = 0;
449
+ }
450
+ };
451
+ function createStreamController(host, options = {}) {
452
+ return new StreamControllerImpl(host, options);
453
+ }
454
+
455
+ // src/Markdown.ts
39
456
  var import_ui = require("@vectojs/ui");
40
457
 
41
458
  // src/MarkdownWorkerSource.ts
42
- var WORKER_SOURCE_STRING = '"use strict";(()=>{function N(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var T=N();function oe(r){T=r}var R={exec:()=>null};function A(r){let e=[];return t=>{let s=Math.max(0,Math.min(3,t-1)),n=e[s];return n||(n=r(s),e[s]=n),n}}function k(r,e=""){let t=typeof r=="string"?r:r.source,s={replace:(n,i)=>{let a=typeof i=="string"?i:i.source;return a=a.replace(b.caret,"$1"),t=t.replace(n,a),s},getRegex:()=>new RegExp(t,e)};return s}var me=((r="")=>{try{return!!new RegExp("(?<=1)(?<!1)"+r)}catch{return!1}})(),b={codeRemoveIndent:/^(?: {1,4}| {0,3}\\t)/gm,outputLinkReplace:/\\\\([\\[\\]])/g,indentCodeCompensation:/^(\\s+)(?:```)/,beginningSpace:/^\\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\\n/g,tabCharGlobal:/\\t/g,multipleSpaceGlobal:/\\s+/g,blankLine:/^[ \\t]*$/,doubleBlankLine:/\\n[ \\t]*\\n[ \\t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\\n {0,3}((?:=+|-+) *)(?=\\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \\t]?/gm,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\\[[ xX]\\] +\\S/,listReplaceTask:/^\\[[ xX]\\] +/,listTaskCheckbox:/\\[[ xX]\\]/,anyLine:/\\n.*\\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\\||\\| *$/g,tableRowBlankLine:/\\n[ \\t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\\s|>)/i,endPreScriptTag:/^<\\/(pre|code|kbd|script)(\\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^\'"]*[^\\s])\\s+([\'"])(.*)\\2/,unicodeAlphaNumeric:/[\\p{L}\\p{N}]/u,escapeTest:/[&<>"\']/,escapeReplace:/[&<>"\']/g,escapeTestNoEncode:/[<>"\']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/,escapeReplaceNoEncode:/[<>"\']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/g,caret:/(^|[^\\[])\\^/g,percentDecode:/%25/g,findPipe:/\\|/g,splitPipe:/ \\|/,slashPipe:/\\\\\\|/g,carriageReturn:/\\r\\n|\\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\\S*/,endingNewline:/\\n$/,listItemRegex:r=>new RegExp(`^( {0,3}${r})((?:[ ][^\\\\n]*)?(?:\\\\n|$))`),nextBulletRegex:A(r=>new RegExp(`^ {0,${r}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ ][^\\\\n]*)?(?:\\\\n|$))`)),hrRegex:A(r=>new RegExp(`^ {0,${r}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`)),fencesBeginRegex:A(r=>new RegExp(`^ {0,${r}}(?:\\`\\`\\`|~~~)`)),headingBeginRegex:A(r=>new RegExp(`^ {0,${r}}#`)),htmlBeginRegex:A(r=>new RegExp(`^ {0,${r}}<(?:[a-z].*>|!--)`,"i")),blockquoteBeginRegex:A(r=>new RegExp(`^ {0,${r}}>`))},ye=/^(?:[ \\t]*(?:\\n|$))+/,$e=/^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/,Re=/^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/,E=/^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/,Se=/^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/,G=/ {0,3}(?:[*+-]|\\d{1,9}[.)])/,ce=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,he=k(ce).replace(/bull/g,G).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}(?:\\s|$)/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/\\|table/g,"").getRegex(),Te=k(ce).replace(/bull/g,G).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}(?:\\s|$)/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/table/g,/ {0,3}\\|?(?:[:\\- ]*\\|)+[\\:\\- ]*\\n/).getRegex(),X=/^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \\t]+\\n)[^\\n]+)*)/,ze=/^[^\\n]+/,W=/(?!\\s*\\])(?:\\\\[\\s\\S]|[^\\[\\]\\\\])+/,Ae=k(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/).replace("label",W).replace("title",/(?:"(?:\\\\"?|[^"\\\\])*"|\'[^\'\\n]*(?:\\n[^\'\\n]+)*\\n?\'|\\([^()]*\\))/).getRegex(),Le=k(/^(bull)([ \\t][^\\n]*?)?(?:\\n|$)/).replace(/bull/g,G).getRegex(),Z="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",F=/<!--(?:-?>|[\\s\\S]*?(?:-->|$))/,_e=k("^ {0,3}(?:<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:</\\\\1>[^\\\\n]*\\\\n*|$)|comment[^\\\\n]*(\\\\n+|$)|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>[^\\\\n]*\\\\n*|$)|<![A-Z][\\\\s\\\\S]*?(?:>[^\\\\n]*\\\\n*|$)|<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?(?:\\\\]\\\\]>[^\\\\n]*\\\\n*|$)|</?(tag)(?: +|\\\\n|/?>)[\\\\s\\\\S]*?(?:(?:\\\\n[ ]*)+\\\\n|$)|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ ]*)+\\\\n|$)|</(?!script|pre|style|textarea)[a-z][\\\\w-]*\\\\s*>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ ]*)+\\\\n|$))","i").replace("comment",F).replace("tag",Z).replace("attribute",/ +[a-zA-Z:_][\\w.:-]*(?: *= *"[^"\\n]*"| *= *\'[^\'\\n]*\'| *= *[^\\s"\'=<>`]+)?/).getRegex(),pe=r=>k(X).replace("hr",E).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n").replace("list",r).replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",Z).getRegex(),Pe=pe(/ {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]/),ve=pe(/ {0,3}(?:[*+-]|\\d{1,9}[.)])(?:[ \\t]|\\n|$)/),Ie=k(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/).replace("paragraph",ve).getRegex(),U={blockquote:Ie,code:$e,def:Ae,fences:Re,heading:Se,hr:E,html:_e,lheading:he,list:Le,newline:ye,paragraph:Pe,table:R,text:ze},te=k("^ *([^\\\\n ].*)\\\\n {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)").replace("hr",E).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3} )[^\\\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\\\t]").replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",Z).getRegex(),Ee={...U,lheading:Te,table:te,paragraph:k(X).replace("hr",E).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("|lheading","").replace("table",te).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\\\t]+[^ \\\\t\\\\n]").replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",Z).getRegex()},Ce={...U,html:k(`^ *(?:comment *(?:\\\\n|\\\\s*$)|<(tag)[\\\\s\\\\S]+?</\\\\1> *(?:\\\\n{2,}|\\\\s*$)|<tag(?:"[^"]*"|\'[^\']*\'|\\\\s[^\'"/>\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))`).replace("comment",F).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b").getRegex(),def:/^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +(["(][^\\n]+[")]))? *(?:\\n+|$)/,heading:/^(#{1,6})(.*)(?:\\n+|$)/,fences:R,lheading:/^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,paragraph:k(X).replace("hr",E).replace("heading",` *#{1,6} *[^\n]`).replace("lheading",he).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},Be=/^\\\\([!"#$%&\'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/,qe=/^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/,ue=/^( {2,}|\\\\)\\n(?!\\s*$)/,Me=/^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/,L=/[\\p{P}\\p{S}]/u,D=/[\\s\\p{P}\\p{S}]/u,V=/[^\\s\\p{P}\\p{S}]/u,Ze=k(/^((?![*_])punctSpace)/,"u").replace(/punctSpace/g,D).getRegex(),ge=/(?!~)[\\p{P}\\p{S}]/u,De=/(?!~)[\\s\\p{P}\\p{S}]/u,Qe=/(?:[^\\s\\p{P}\\p{S}]|~)/u,je=k(/link|precode-code|html/,"g").replace("link",/\\[(?:[^\\[\\]`]|(?<a>`+)[^`]+\\k<a>(?!`))*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)/).replace("precode-",me?"(?<!`)()":"(^^|[^`])").replace("code",/(?<b>`+)[^`]+\\k<b>(?!`)/).replace("html",/<(?! )[^<>]*?>/).getRegex(),ke=/^(?:\\*+(?:((?!\\*)punct)|([^\\s*]))?)|^_+(?:((?!_)punct)|([^\\s_]))?/,He=k(ke,"u").replace(/punct/g,L).getRegex(),Oe=k(ke,"u").replace(/punct/g,ge).getRegex(),de="^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)|(?!\\\\*)punctSpace(\\\\*+)(?=notPunctSpace)|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)|notPunctSpace(\\\\*+)(?=notPunctSpace)",Ne=k(de,"gu").replace(/notPunctSpace/g,V).replace(/punctSpace/g,D).replace(/punct/g,L).getRegex(),Ge=k(de,"gu").replace(/notPunctSpace/g,Qe).replace(/punctSpace/g,De).replace(/punct/g,ge).getRegex(),Xe=k("^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,V).replace(/punctSpace/g,D).replace(/punct/g,L).getRegex(),We=k(/^~~?(?:((?!~)punct)|[^\\s~])/,"u").replace(/punct/g,L).getRegex(),Fe="^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)",Ue=k(Fe,"gu").replace(/notPunctSpace/g,V).replace(/punctSpace/g,D).replace(/punct/g,L).getRegex(),Ve=k(/\\\\(punct)/,"gu").replace(/punct/g,L).getRegex(),Je=k(/^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&\'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),Ke=k(F).replace("(?:-->|$)","-->").getRegex(),Ye=k("^comment|^</[a-zA-Z][\\\\w:-]*\\\\s*>|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>|^<\\\\?[\\\\s\\\\S]*?\\\\?>|^<![a-zA-Z]+\\\\s[\\\\s\\\\S]*?>|^<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>").replace("comment",Ke).replace("attribute",/\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*"[^"]*"|\\s*=\\s*\'[^\']*\'|\\s*=\\s*[^\\s"\'=<>`]+)?/).getRegex(),B=/(?:\\[(?:\\\\[\\s\\S]|[^\\[\\]\\\\])*\\]|\\\\[\\s\\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\\])|[^\\[\\]\\\\`])*?/,et=k(/^!?\\[(label)\\]\\(\\s*(href)(?:(?:[ \\t]+(?:\\n[ \\t]*)?|\\n[ \\t]*)(title))?\\s*\\)/).replace("label",B).replace("href",/<(?:\\\\.|[^\\n<>\\\\])+>|[^ \\t\\n\\x00-\\x1f]+|(?=\\))/).replace("title",/"(?:\\\\"?|[^"\\\\])*"|\'(?:\\\\\'?|[^\'\\\\])*\'|\\((?:\\\\\\)?|[^)\\\\])*\\)/).getRegex(),fe=k(/^!?\\[(label)\\]\\[(ref)\\]/).replace("label",B).replace("ref",W).getRegex(),xe=k(/^!?\\[(ref)\\](?:\\[\\])?/).replace("ref",W).getRegex(),tt=k("reflink|nolink(?!\\\\()","g").replace("reflink",fe).replace("nolink",xe).getRegex(),re=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,J={_backpedal:R,anyPunctuation:Ve,autolink:Je,blockSkip:je,br:ue,code:qe,del:R,delLDelim:R,delRDelim:R,emStrongLDelim:He,emStrongRDelimAst:Ne,emStrongRDelimUnd:Xe,escape:Be,link:et,nolink:xe,punctuation:Ze,reflink:fe,reflinkSearch:tt,tag:Ye,text:Me,url:R},rt={...J,link:k(/^!?\\[(label)\\]\\((.*?)\\)/).replace("label",B).getRegex(),reflink:k(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/).replace("label",B).getRegex()},j={...J,emStrongRDelimAst:Ge,emStrongLDelim:Oe,delLDelim:We,delRDelim:Ue,url:k(/^((?:protocol):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/).replace("protocol",re).replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_\'"~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_\'"~)]+(?!$))+/,del:/^(~~?)(?=[^\\s~])((?:\\\\[\\s\\S]|[^\\\\])*?(?:\\\\[\\s\\S]|[^\\s~\\\\]))\\1(?=[^~]|$)/,text:k(/^(`+|~+|[^`~])(?:(?=[`~])|(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&\'*+\\/=?_`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*~_]|\\b_|protocol:\\/\\/|www\\.|$)|[^ ](?= {2,}\\n)|[^a-zA-Z0-9.!#$%&\'*+\\/=?_`{\\|}~-](?=[a-zA-Z0-9.!#$%&\'*+\\/=?_`{\\|}~-]+@)))/).replace("protocol",re).getRegex()},nt={...j,br:k(ue).replace("{2,}","*").getRegex(),text:k(j.text).replace("\\\\b_","\\\\b_| {2,}\\\\n").replace(/\\{2,\\}/g,"*").getRegex()},C={normal:U,gfm:Ee,pedantic:Ce},v={normal:J,gfm:j,breaks:nt,pedantic:rt},st={"&":"&amp;","<":"&lt;",">":"&gt;",\'"\':"&quot;","\'":"&#39;"},ne=r=>st[r];function y(r,e){if(e){if(b.escapeTest.test(r))return r.replace(b.escapeReplace,ne)}else if(b.escapeTestNoEncode.test(r))return r.replace(b.escapeReplaceNoEncode,ne);return r}function se(r){try{r=encodeURI(r).replace(b.percentDecode,"%")}catch{return null}return r}function ie(r,e){let t=r.replace(b.findPipe,(i,a,l)=>{let o=!1,c=a;for(;--c>=0&&l[c]==="\\\\";)o=!o;return o?"|":" |"}),s=t.split(b.splitPipe),n=0;if(s[0].trim()||s.shift(),s.length>0&&!s.at(-1)?.trim()&&s.pop(),e)if(s.length>e)s.splice(e);else for(;s.length<e;)s.push("");for(;n<s.length;n++)s[n]=s[n].trim().replace(b.slashPipe,"|");return s}function $(r,e,t){let s=r.length;if(s===0)return"";let n=0;for(;n<s;){let i=r.charAt(s-n-1);if(i===e&&!t)n++;else if(i!==e&&t)n++;else break}return r.slice(0,s-n)}function le(r){let e=r.split(`\n`),t=e.length-1;for(;t>=0&&b.blankLine.test(e[t]);)t--;return e.length-t<=2?r:e.slice(0,t+1).join(`\n`)}function it(r,e){if(r.indexOf(e[1])===-1)return-1;let t=0;for(let s=0;s<r.length;s++)if(r[s]==="\\\\")s++;else if(r[s]===e[0])t++;else if(r[s]===e[1]&&(t--,t<0))return s;return t>0?-2:-1}function lt(r,e=0){let t=e,s="";for(let n of r)if(n===" "){let i=4-t%4;s+=" ".repeat(i),t+=i}else s+=n,t++;return s}function ae(r,e,t,s,n){let i=e.href,a=e.title||null,l=r[1].replace(n.other.outputLinkReplace,"$1");s.state.inLink=!0;let o={type:r[0].charAt(0)==="!"?"image":"link",raw:t,href:i,title:a,text:l,tokens:s.inlineTokens(l)};return s.state.inLink=!1,o}function at(r,e,t){let s=r.match(t.other.indentCodeCompensation);if(s===null)return e;let n=s[1];return e.split(`\n`).map(i=>{let a=i.match(t.other.beginningSpace);if(a===null)return i;let[l]=a;return l.length>=n.length?i.slice(n.length):i}).join(`\n`)}var q=class{options;rules;lexer;constructor(r){this.options=r||T}space(r){let e=this.rules.block.newline.exec(r);if(e&&e[0].length>0)return{type:"space",raw:e[0]}}code(r){let e=this.rules.block.code.exec(r);if(e){let t=this.options.pedantic?e[0]:le(e[0]),s=t.replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:t,codeBlockStyle:"indented",text:s}}}fences(r){let e=this.rules.block.fences.exec(r);if(e){let t=e[0],s=at(t,e[3]||"",this.rules);return{type:"code",raw:t,lang:e[2]?e[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):e[2],text:s}}}heading(r){let e=this.rules.block.heading.exec(r);if(e){let t=e[2].trim();if(this.rules.other.endingHash.test(t)){let s=$(t,"#");(this.options.pedantic||!s||this.rules.other.endingSpaceChar.test(s))&&(t=s.trim())}return{type:"heading",raw:$(e[0],`\n`),depth:e[1].length,text:t,tokens:this.lexer.inline(t)}}}hr(r){let e=this.rules.block.hr.exec(r);if(e)return{type:"hr",raw:$(e[0],`\n`)}}blockquote(r){let e=this.rules.block.blockquote.exec(r);if(e){let t=$(e[0],`\n`).split(`\n`),s="",n="",i=[];for(;t.length>0;){let a=!1,l=[],o;for(o=0;o<t.length;o++)if(this.rules.other.blockquoteStart.test(t[o]))l.push(t[o]),a=!0;else if(!a)l.push(t[o]);else break;t=t.slice(o);let c=l.join(`\n`),p=c.replace(this.rules.other.blockquoteSetextReplace,`\n $1`).replace(this.rules.other.blockquoteSetextReplace2,"");s=s?`${s}\n${c}`:c,n=n?`${n}\n${p}`:p;let h=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(p,i,!0),this.lexer.state.top=h,t.length===0)break;let u=i.at(-1);if(u?.type==="code")break;if(u?.type==="blockquote"){let f=u,g=f.raw+`\n`+t.join(`\n`),x=this.blockquote(g);i[i.length-1]=x,s=s.substring(0,s.length-f.raw.length)+x.raw,n=n.substring(0,n.length-f.text.length)+x.text;break}else if(u?.type==="list"){let f=u,g=f.raw+`\n`+t.join(`\n`),x=this.list(g);i[i.length-1]=x,s=s.substring(0,s.length-u.raw.length)+x.raw,n=n.substring(0,n.length-f.raw.length)+x.raw,t=g.substring(i.at(-1).raw.length).split(`\n`);continue}}return{type:"blockquote",raw:s,tokens:i,text:n}}}list(r){let e=this.rules.block.list.exec(r);if(e){let t=e[1].trim(),s=t.length>1,n={type:"list",raw:"",ordered:s,start:s?+t.slice(0,-1):"",loose:!1,items:[]};t=s?`\\\\d{1,9}\\\\${t.slice(-1)}`:`\\\\${t}`,this.options.pedantic&&(t=s?t:"[*+-]");let i=this.rules.other.listItemRegex(t),a=!1;for(;r;){let o=!1,c="",p="";if(!(e=i.exec(r))||this.rules.block.hr.test(r))break;c=e[0],r=r.substring(c.length);let h=lt(e[2].split(`\n`,1)[0],e[1].length),u=r.split(`\n`,1)[0],f=!h.trim(),g=0;if(this.options.pedantic?(g=2,p=h.trimStart()):f?g=e[1].length+1:(g=h.search(this.rules.other.nonSpaceChar),g=g>4?1:g,p=h.slice(g),g+=e[1].length),f&&this.rules.other.blankLine.test(u)&&(c+=u+`\n`,r=r.substring(u.length+1),o=!0),!o){let x=this.rules.other.nextBulletRegex(g),z=this.rules.other.hrRegex(g),Y=this.rules.other.fencesBeginRegex(g),ee=this.rules.other.headingBeginRegex(g),be=this.rules.other.htmlBeginRegex(g),we=this.rules.other.blockquoteBeginRegex(g);for(;r;){let Q=r.split(`\n`,1)[0],P;if(u=Q,this.options.pedantic?(u=u.replace(this.rules.other.listReplaceNesting," "),P=u):P=u.replace(this.rules.other.tabCharGlobal," "),Y.test(u)||ee.test(u)||be.test(u)||we.test(u)||x.test(u)||z.test(u))break;if(P.search(this.rules.other.nonSpaceChar)>=g||!u.trim())p+=`\n`+P.slice(g);else{if(f||h.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||Y.test(h)||ee.test(h)||z.test(h))break;p+=`\n`+u}f=!u.trim(),c+=Q+`\n`,r=r.substring(Q.length+1),h=P.slice(g)}}n.loose||(a?n.loose=!0:this.rules.other.doubleBlankLine.test(c)&&(a=!0)),n.items.push({type:"list_item",raw:c,task:!!this.options.gfm&&this.rules.other.listIsTask.test(p),loose:!1,text:p,tokens:[]}),n.raw+=c}let l=n.items.at(-1);if(l)l.raw=l.raw.trimEnd(),l.text=l.text.trimEnd();else return;n.raw=n.raw.trimEnd();for(let o of n.items){this.lexer.state.top=!1,o.tokens=this.lexer.blockTokens(o.text,[]);let c=o.tokens[0];if(o.task&&(c?.type==="text"||c?.type==="paragraph")){o.text=o.text.replace(this.rules.other.listReplaceTask,""),c.raw=c.raw.replace(this.rules.other.listReplaceTask,""),c.text=c.text.replace(this.rules.other.listReplaceTask,"");for(let h=this.lexer.inlineQueue.length-1;h>=0;h--)if(this.rules.other.listIsTask.test(this.lexer.inlineQueue[h].src)){this.lexer.inlineQueue[h].src=this.lexer.inlineQueue[h].src.replace(this.rules.other.listReplaceTask,"");break}let p=this.rules.other.listTaskCheckbox.exec(o.raw);if(p){let h={type:"checkbox",raw:p[0]+" ",checked:p[0]!=="[ ]"};o.checked=h.checked,n.loose?o.tokens[0]&&["paragraph","text"].includes(o.tokens[0].type)&&"tokens"in o.tokens[0]&&o.tokens[0].tokens?(o.tokens[0].raw=h.raw+o.tokens[0].raw,o.tokens[0].text=h.raw+o.tokens[0].text,o.tokens[0].tokens.unshift(h)):o.tokens.unshift({type:"paragraph",raw:h.raw,text:h.raw,tokens:[h]}):o.tokens.unshift(h)}}else o.task&&(o.task=!1);if(!n.loose){let p=o.tokens.filter(u=>u.type==="space"),h=p.length>0&&p.some(u=>this.rules.other.anyLine.test(u.raw));n.loose=h}}if(n.loose)for(let o of n.items){o.loose=!0;for(let c of o.tokens)c.type==="text"&&(c.type="paragraph")}return n}}html(r){let e=this.rules.block.html.exec(r);if(e){let t=le(e[0]);return{type:"html",block:!0,raw:t,pre:e[1]==="pre"||e[1]==="script"||e[1]==="style",text:t}}}def(r){let e=this.rules.block.def.exec(r);if(e){let t=e[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal," "),s=e[2]?e[2].replace(this.rules.other.hrefBrackets,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",n=e[3]?e[3].substring(1,e[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):e[3];return{type:"def",tag:t,raw:$(e[0],`\n`),href:s,title:n}}}table(r){let e=this.rules.block.table.exec(r);if(!e||!this.rules.other.tableDelimiter.test(e[2]))return;let t=ie(e[1]),s=e[2].replace(this.rules.other.tableAlignChars,"").split("|"),n=e[3]?.trim()?e[3].replace(this.rules.other.tableRowBlankLine,"").split(`\n`):[],i={type:"table",raw:$(e[0],`\n`),header:[],align:[],rows:[]};if(t.length===s.length){for(let a of s)this.rules.other.tableAlignRight.test(a)?i.align.push("right"):this.rules.other.tableAlignCenter.test(a)?i.align.push("center"):this.rules.other.tableAlignLeft.test(a)?i.align.push("left"):i.align.push(null);for(let a=0;a<t.length;a++)i.header.push({text:t[a],tokens:this.lexer.inline(t[a]),header:!0,align:i.align[a]});for(let a of n)i.rows.push(ie(a,i.header.length).map((l,o)=>({text:l,tokens:this.lexer.inline(l),header:!1,align:i.align[o]})));return i}}lheading(r){let e=this.rules.block.lheading.exec(r);if(e){let t=e[1].trim();return{type:"heading",raw:$(e[0],`\n`),depth:e[2].charAt(0)==="="?1:2,text:t,tokens:this.lexer.inline(t)}}}paragraph(r){let e=this.rules.block.paragraph.exec(r);if(e){let t=e[1].charAt(e[1].length-1)===`\n`?e[1].slice(0,-1):e[1];return{type:"paragraph",raw:e[0],text:t,tokens:this.lexer.inline(t)}}}text(r){let e=this.rules.block.text.exec(r);if(e)return{type:"text",raw:e[0],text:e[0],tokens:this.lexer.inline(e[0])}}escape(r){let e=this.rules.inline.escape.exec(r);if(e)return{type:"escape",raw:e[0],text:e[1]}}tag(r){let e=this.rules.inline.tag.exec(r);if(e)return!this.lexer.state.inLink&&this.rules.other.startATag.test(e[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:e[0]}}link(r){let e=this.rules.inline.link.exec(r);if(e){let t=e[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(t)){if(!this.rules.other.endAngleBracket.test(t))return;let i=$(t.slice(0,-1),"\\\\");if((t.length-i.length)%2===0)return}else{let i=it(e[2],"()");if(i===-2)return;if(i>-1){let a=(e[0].indexOf("!")===0?5:4)+e[1].length+i;e[2]=e[2].substring(0,i),e[0]=e[0].substring(0,a).trim(),e[3]=""}}let s=e[2],n="";if(this.options.pedantic){let i=this.rules.other.pedanticHrefTitle.exec(s);i&&(s=i[1],n=i[3])}else n=e[3]?e[3].slice(1,-1):"";return s=s.trim(),this.rules.other.startAngleBracket.test(s)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(t)?s=s.slice(1):s=s.slice(1,-1)),ae(e,{href:s&&s.replace(this.rules.inline.anyPunctuation,"$1"),title:n&&n.replace(this.rules.inline.anyPunctuation,"$1")},e[0],this.lexer,this.rules)}}reflink(r,e){let t;if((t=this.rules.inline.reflink.exec(r))||(t=this.rules.inline.nolink.exec(r))){let s=(t[2]||t[1]).replace(this.rules.other.multipleSpaceGlobal," "),n=e[s.toLowerCase()];if(!n){let i=t[0].charAt(0);return{type:"text",raw:i,text:i}}return ae(t,n,t[0],this.lexer,this.rules)}}emStrong(r,e,t=""){let s=this.rules.inline.emStrongLDelim.exec(r);if(!(!s||!s[1]&&!s[2]&&!s[3]&&!s[4]||s[4]&&t.match(this.rules.other.unicodeAlphaNumeric))&&(!(s[1]||s[3])||!t||this.rules.inline.punctuation.exec(t))){let n=[...s[0]].length-1,i,a,l=n,o=0,c=s[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(c.lastIndex=0,e=e.slice(-1*r.length+n);(s=c.exec(e))!==null;){if(i=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!i)continue;if(a=[...i].length,s[3]||s[4]){l+=a;continue}else if((s[5]||s[6])&&n%3&&!((n+a)%3)){o+=a;continue}if(l-=a,l>0)continue;a=Math.min(a,a+l+o);let p=[...s[0]][0].length,h=r.slice(0,n+s.index+p+a);if(Math.min(n,a)%2){let f=h.slice(1,-1);return{type:"em",raw:h,text:f,tokens:this.lexer.inlineTokens(f)}}let u=h.slice(2,-2);return{type:"strong",raw:h,text:u,tokens:this.lexer.inlineTokens(u)}}}}codespan(r){let e=this.rules.inline.code.exec(r);if(e){let t=e[2].replace(this.rules.other.newLineCharGlobal," "),s=this.rules.other.nonSpaceChar.test(t),n=this.rules.other.startingSpaceChar.test(t)&&this.rules.other.endingSpaceChar.test(t);return s&&n&&(t=t.substring(1,t.length-1)),{type:"codespan",raw:e[0],text:t}}}br(r){let e=this.rules.inline.br.exec(r);if(e)return{type:"br",raw:e[0]}}del(r,e,t=""){let s=this.rules.inline.delLDelim.exec(r);if(s&&(!s[1]||!t||this.rules.inline.punctuation.exec(t))){let n=[...s[0]].length-1,i,a,l=n,o=this.rules.inline.delRDelim;for(o.lastIndex=0,e=e.slice(-1*r.length+n);(s=o.exec(e))!==null;){if(i=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!i||(a=[...i].length,a!==n))continue;if(s[3]||s[4]){l+=a;continue}if(l-=a,l>0)continue;a=Math.min(a,a+l);let c=[...s[0]][0].length,p=r.slice(0,n+s.index+c+a),h=p.slice(n,-n);return{type:"del",raw:p,text:h,tokens:this.lexer.inlineTokens(h)}}}}autolink(r){let e=this.rules.inline.autolink.exec(r);if(e){let t,s;return e[2]==="@"?(t=e[1],s="mailto:"+t):(t=e[1],s=t),{type:"link",raw:e[0],text:t,href:s,tokens:[{type:"text",raw:t,text:t}]}}}url(r){let e;if(e=this.rules.inline.url.exec(r)){let t,s;if(e[2]==="@")t=e[0],s="mailto:"+t;else{let n;do n=e[0],e[0]=this.rules.inline._backpedal.exec(e[0])?.[0]??"";while(n!==e[0]);t=e[0],e[1]==="www."?s="http://"+e[0]:s=e[0]}return{type:"link",raw:e[0],text:t,href:s,tokens:[{type:"text",raw:t,text:t}]}}}inlineText(r){let e=this.rules.inline.text.exec(r);if(e){let t=this.lexer.state.inRawBlock;return{type:"text",raw:e[0],text:e[0],escaped:t}}}},w=class H{tokens;options;state;inlineQueue;tokenizer;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||T,this.options.tokenizer=this.options.tokenizer||new q,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let t={other:b,block:C.normal,inline:v.normal};this.options.pedantic?(t.block=C.pedantic,t.inline=v.pedantic):this.options.gfm&&(t.block=C.gfm,this.options.breaks?t.inline=v.breaks:t.inline=v.gfm),this.tokenizer.rules=t}static get rules(){return{block:C,inline:v}}static lex(e,t){return new H(t).lex(e)}static lexInline(e,t){return new H(t).inlineTokens(e)}lex(e){e=e.replace(b.carriageReturn,`\n`),this.blockTokens(e,this.tokens);for(let t=0;t<this.inlineQueue.length;t++){let s=this.inlineQueue[t];this.inlineTokens(s.src,s.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,t=[],s=!1){this.tokenizer.lexer=this,this.options.pedantic&&(e=e.replace(b.tabCharGlobal," ").replace(b.spaceLine,""));let n=1/0;for(;e;){if(e.length<n)n=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}let i;if(this.options.extensions?.block?.some(l=>(i=l.call({lexer:this},e,t))?(e=e.substring(i.raw.length),t.push(i),!0):!1))continue;if(i=this.tokenizer.space(e)){e=e.substring(i.raw.length);let l=t.at(-1);i.raw.length===1&&l!==void 0?l.raw+=`\n`:t.push(i);continue}if(i=this.tokenizer.code(e)){e=e.substring(i.raw.length);let l=t.at(-1);l?.type==="paragraph"||l?.type==="text"?(l.raw+=(l.raw.endsWith(`\n`)?"":`\n`)+i.raw,l.text+=`\n`+i.text,this.inlineQueue.at(-1).src=l.text):t.push(i);continue}if(i=this.tokenizer.fences(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.heading(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.hr(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.blockquote(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.list(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.html(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.def(e)){e=e.substring(i.raw.length);let l=t.at(-1);l?.type==="paragraph"||l?.type==="text"?(l.raw+=(l.raw.endsWith(`\n`)?"":`\n`)+i.raw,l.text+=`\n`+i.raw,this.inlineQueue.at(-1).src=l.text):this.tokens.links[i.tag]||(this.tokens.links[i.tag]={href:i.href,title:i.title},t.push(i));continue}if(i=this.tokenizer.table(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.lheading(e)){e=e.substring(i.raw.length),t.push(i);continue}let a=e;if(this.options.extensions?.startBlock){let l=1/0,o=e.slice(1),c;this.options.extensions.startBlock.forEach(p=>{c=p.call({lexer:this},o),typeof c=="number"&&c>=0&&(l=Math.min(l,c))}),l<1/0&&l>=0&&(a=e.substring(0,l+1))}if(this.state.top&&(i=this.tokenizer.paragraph(a))){let l=t.at(-1);s&&l?.type==="paragraph"?(l.raw+=(l.raw.endsWith(`\n`)?"":`\n`)+i.raw,l.text+=`\n`+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=l.text):t.push(i),s=a.length!==e.length,e=e.substring(i.raw.length);continue}if(i=this.tokenizer.text(e)){e=e.substring(i.raw.length);let l=t.at(-1);l?.type==="text"?(l.raw+=(l.raw.endsWith(`\n`)?"":`\n`)+i.raw,l.text+=`\n`+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=l.text):t.push(i);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){this.tokenizer.lexer=this;let s=e;if(this.tokens.links){let l=Object.keys(this.tokens.links);l.length>0&&(s=s.replace(this.tokenizer.rules.inline.reflinkSearch,o=>l.includes(o.slice(o.lastIndexOf("[")+1,-1))?"["+"a".repeat(o.length-2)+"]":o))}s=s.replace(this.tokenizer.rules.inline.anyPunctuation,"++"),s=s.replace(this.tokenizer.rules.inline.blockSkip,(l,o,c)=>{let p=c?c.length:0;return l.slice(0,p)+"["+"a".repeat(l.length-p-2)+"]"}),s=this.options.hooks?.emStrongMask?.call({lexer:this},s)??s;let n=!1,i="",a=1/0;for(;e;){if(e.length<a)a=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}n||(i=""),n=!1;let l;if(this.options.extensions?.inline?.some(c=>(l=c.call({lexer:this},e,t))?(e=e.substring(l.raw.length),t.push(l),!0):!1))continue;if(l=this.tokenizer.escape(e)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.tag(e)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.link(e)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(l.raw.length);let c=t.at(-1);l.type==="text"&&c?.type==="text"?(c.raw+=l.raw,c.text+=l.text):t.push(l);continue}if(l=this.tokenizer.emStrong(e,s,i)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.codespan(e)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.br(e)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.del(e,s,i)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.autolink(e)){e=e.substring(l.raw.length),t.push(l);continue}if(!this.state.inLink&&(l=this.tokenizer.url(e))){e=e.substring(l.raw.length),t.push(l);continue}let o=e;if(this.options.extensions?.startInline){let c=1/0,p=e.slice(1),h;this.options.extensions.startInline.forEach(u=>{h=u.call({lexer:this},p),typeof h=="number"&&h>=0&&(c=Math.min(c,h))}),c<1/0&&c>=0&&(o=e.substring(0,c+1))}if(l=this.tokenizer.inlineText(o)){e=e.substring(l.raw.length),l.raw.slice(-1)!=="_"&&(i=l.raw.slice(-1)),n=!0;let c=t.at(-1);c?.type==="text"?(c.raw+=l.raw,c.text+=l.text):t.push(l);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return t}infiniteLoopError(e){let t="Infinite loop on byte: "+e;if(this.options.silent)console.error(t);else throw new Error(t)}},M=class{options;parser;constructor(r){this.options=r||T}space(r){return""}code({text:r,lang:e,escaped:t}){let s=(e||"").match(b.notSpaceStart)?.[0],n=r.replace(b.endingNewline,"")+`\n`;return s?\'<pre><code class="language-\'+y(s)+\'">\'+(t?n:y(n,!0))+`</code></pre>\n`:"<pre><code>"+(t?n:y(n,!0))+`</code></pre>\n`}blockquote({tokens:r}){return`<blockquote>\n${this.parser.parse(r)}</blockquote>\n`}html({text:r}){return r}def(r){return""}heading({tokens:r,depth:e}){return`<h${e}>${this.parser.parseInline(r)}</h${e}>\n`}hr(r){return`<hr>\n`}list(r){let e=r.ordered,t=r.start,s="";for(let a=0;a<r.items.length;a++){let l=r.items[a];s+=this.listitem(l)}let n=e?"ol":"ul",i=e&&t!==1?\' start="\'+t+\'"\':"";return"<"+n+i+`>\n`+s+"</"+n+`>\n`}listitem(r){return`<li>${this.parser.parse(r.tokens)}</li>\n`}checkbox({checked:r}){return"<input "+(r?\'checked="" \':"")+\'disabled="" type="checkbox"> \'}paragraph({tokens:r}){return`<p>${this.parser.parseInline(r)}</p>\n`}table(r){let e="",t="";for(let n=0;n<r.header.length;n++)t+=this.tablecell(r.header[n]);e+=this.tablerow({text:t});let s="";for(let n=0;n<r.rows.length;n++){let i=r.rows[n];t="";for(let a=0;a<i.length;a++)t+=this.tablecell(i[a]);s+=this.tablerow({text:t})}return s&&(s=`<tbody>${s}</tbody>`),`<table>\n<thead>\n`+e+`</thead>\n`+s+`</table>\n`}tablerow({text:r}){return`<tr>\n${r}</tr>\n`}tablecell(r){let e=this.parser.parseInline(r.tokens),t=r.header?"th":"td";return(r.align?`<${t} align="${r.align}">`:`<${t}>`)+e+`</${t}>\n`}strong({tokens:r}){return`<strong>${this.parser.parseInline(r)}</strong>`}em({tokens:r}){return`<em>${this.parser.parseInline(r)}</em>`}codespan({text:r}){return`<code>${y(r,!0)}</code>`}br(r){return"<br>"}del({tokens:r}){return`<del>${this.parser.parseInline(r)}</del>`}link({href:r,title:e,tokens:t}){let s=this.parser.parseInline(t),n=se(r);if(n===null)return s;r=n;let i=\'<a href="\'+r+\'"\';return e&&(i+=\' title="\'+y(e)+\'"\'),i+=">"+s+"</a>",i}image({href:r,title:e,text:t,tokens:s}){s&&(t=this.parser.parseInline(s,this.parser.textRenderer));let n=se(r);if(n===null)return y(t);r=n;let i=`<img src="${r}" alt="${y(t)}"`;return e&&(i+=` title="${y(e)}"`),i+=">",i}text(r){return"tokens"in r&&r.tokens?this.parser.parseInline(r.tokens):"escaped"in r&&r.escaped?r.text:y(r.text)}},K=class{strong({text:r}){return r}em({text:r}){return r}codespan({text:r}){return r}del({text:r}){return r}html({text:r}){return r}text({text:r}){return r}link({text:r}){return""+r}image({text:r}){return""+r}br(){return""}checkbox({raw:r}){return r}},m=class O{options;renderer;textRenderer;constructor(e){this.options=e||T,this.options.renderer=this.options.renderer||new M,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new K}static parse(e,t){return new O(t).parse(e)}static parseInline(e,t){return new O(t).parseInline(e)}parse(e){this.renderer.parser=this;let t="";for(let s=0;s<e.length;s++){let n=e[s];if(this.options.extensions?.renderers?.[n.type]){let a=n,l=this.options.extensions.renderers[a.type].call({parser:this},a);if(l!==!1||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(a.type)){t+=l||"";continue}}let i=n;switch(i.type){case"space":{t+=this.renderer.space(i);break}case"hr":{t+=this.renderer.hr(i);break}case"heading":{t+=this.renderer.heading(i);break}case"code":{t+=this.renderer.code(i);break}case"table":{t+=this.renderer.table(i);break}case"blockquote":{t+=this.renderer.blockquote(i);break}case"list":{t+=this.renderer.list(i);break}case"checkbox":{t+=this.renderer.checkbox(i);break}case"html":{t+=this.renderer.html(i);break}case"def":{t+=this.renderer.def(i);break}case"paragraph":{t+=this.renderer.paragraph(i);break}case"text":{t+=this.renderer.text(i);break}default:{let a=\'Token with "\'+i.type+\'" type was not found.\';if(this.options.silent)return console.error(a),"";throw new Error(a)}}}return t}parseInline(e,t=this.renderer){this.renderer.parser=this;let s="";for(let n=0;n<e.length;n++){let i=e[n];if(this.options.extensions?.renderers?.[i.type]){let l=this.options.extensions.renderers[i.type].call({parser:this},i);if(l!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(i.type)){s+=l||"";continue}}let a=i;switch(a.type){case"escape":{s+=t.text(a);break}case"html":{s+=t.html(a);break}case"link":{s+=t.link(a);break}case"image":{s+=t.image(a);break}case"checkbox":{s+=t.checkbox(a);break}case"strong":{s+=t.strong(a);break}case"em":{s+=t.em(a);break}case"codespan":{s+=t.codespan(a);break}case"br":{s+=t.br(a);break}case"del":{s+=t.del(a);break}case"text":{s+=t.text(a);break}default:{let l=\'Token with "\'+a.type+\'" type was not found.\';if(this.options.silent)return console.error(l),"";throw new Error(l)}}}return s}},I=class{options;block;constructor(r){this.options=r||T}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(r){return r}postprocess(r){return r}processAllTokens(r){return r}emStrongMask(r){return r}provideLexer(r=this.block){return r?w.lex:w.lexInline}provideParser(r=this.block){return r?m.parse:m.parseInline}},ot=class{defaults=N();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=m;Renderer=M;TextRenderer=K;Lexer=w;Tokenizer=q;Hooks=I;constructor(...r){this.use(...r)}walkTokens(r,e){let t=[];for(let s of r)switch(t=t.concat(e.call(this,s)),s.type){case"table":{let n=s;for(let i of n.header)t=t.concat(this.walkTokens(i.tokens,e));for(let i of n.rows)for(let a of i)t=t.concat(this.walkTokens(a.tokens,e));break}case"list":{let n=s;t=t.concat(this.walkTokens(n.items,e));break}default:{let n=s;this.defaults.extensions?.childTokens?.[n.type]?this.defaults.extensions.childTokens[n.type].forEach(i=>{let a=n[i].flat(1/0);t=t.concat(this.walkTokens(a,e))}):n.tokens&&(t=t.concat(this.walkTokens(n.tokens,e)))}}return t}use(...r){let e=this.defaults.extensions||{renderers:{},childTokens:{}};return r.forEach(t=>{let s={...t};if(s.async=this.defaults.async||s.async||!1,t.extensions&&(t.extensions.forEach(n=>{if(!n.name)throw new Error("extension name required");if("renderer"in n){let i=e.renderers[n.name];i?e.renderers[n.name]=function(...a){let l=n.renderer.apply(this,a);return l===!1&&(l=i.apply(this,a)),l}:e.renderers[n.name]=n.renderer}if("tokenizer"in n){if(!n.level||n.level!=="block"&&n.level!=="inline")throw new Error("extension level must be \'block\' or \'inline\'");let i=e[n.level];i?i.unshift(n.tokenizer):e[n.level]=[n.tokenizer],n.start&&(n.level==="block"?e.startBlock?e.startBlock.push(n.start):e.startBlock=[n.start]:n.level==="inline"&&(e.startInline?e.startInline.push(n.start):e.startInline=[n.start]))}"childTokens"in n&&n.childTokens&&(e.childTokens[n.name]=n.childTokens)}),s.extensions=e),t.renderer){let n=this.defaults.renderer||new M(this.defaults);for(let i in t.renderer){if(!(i in n))throw new Error(`renderer \'${i}\' does not exist`);if(["options","parser"].includes(i))continue;let a=i,l=t.renderer[a],o=n[a];n[a]=(...c)=>{let p=l.apply(n,c);return p===!1&&(p=o.apply(n,c)),p||""}}s.renderer=n}if(t.tokenizer){let n=this.defaults.tokenizer||new q(this.defaults);for(let i in t.tokenizer){if(!(i in n))throw new Error(`tokenizer \'${i}\' does not exist`);if(["options","rules","lexer"].includes(i))continue;let a=i,l=t.tokenizer[a],o=n[a];n[a]=(...c)=>{let p=l.apply(n,c);return p===!1&&(p=o.apply(n,c)),p}}s.tokenizer=n}if(t.hooks){let n=this.defaults.hooks||new I;for(let i in t.hooks){if(!(i in n))throw new Error(`hook \'${i}\' does not exist`);if(["options","block"].includes(i))continue;let a=i,l=t.hooks[a],o=n[a];I.passThroughHooks.has(i)?n[a]=c=>{if(this.defaults.async&&I.passThroughHooksRespectAsync.has(i))return(async()=>{let h=await l.call(n,c);return o.call(n,h)})();let p=l.call(n,c);return o.call(n,p)}:n[a]=(...c)=>{if(this.defaults.async)return(async()=>{let h=await l.apply(n,c);return h===!1&&(h=await o.apply(n,c)),h})();let p=l.apply(n,c);return p===!1&&(p=o.apply(n,c)),p}}s.hooks=n}if(t.walkTokens){let n=this.defaults.walkTokens,i=t.walkTokens;s.walkTokens=function(a){let l=[];return l.push(i.call(this,a)),n&&(l=l.concat(n.call(this,a))),l}}this.defaults={...this.defaults,...s}}),this}setOptions(r){return this.defaults={...this.defaults,...r},this}lexer(r,e){return w.lex(r,e??this.defaults)}parser(r,e){return m.parse(r,e??this.defaults)}parseMarkdown(r){return(e,t)=>{let s={...t},n={...this.defaults,...s},i=this.onError(!!n.silent,!!n.async);if(this.defaults.async===!0&&s.async===!1)return i(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof e>"u"||e===null)return i(new Error("marked(): input parameter is undefined or null"));if(typeof e!="string")return i(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected"));if(n.hooks&&(n.hooks.options=n,n.hooks.block=r),n.async)return(async()=>{let a=n.hooks?await n.hooks.preprocess(e):e,l=await(n.hooks?await n.hooks.provideLexer(r):r?w.lex:w.lexInline)(a,n),o=n.hooks?await n.hooks.processAllTokens(l):l;n.walkTokens&&await Promise.all(this.walkTokens(o,n.walkTokens));let c=await(n.hooks?await n.hooks.provideParser(r):r?m.parse:m.parseInline)(o,n);return n.hooks?await n.hooks.postprocess(c):c})().catch(i);try{n.hooks&&(e=n.hooks.preprocess(e));let a=(n.hooks?n.hooks.provideLexer(r):r?w.lex:w.lexInline)(e,n);n.hooks&&(a=n.hooks.processAllTokens(a)),n.walkTokens&&this.walkTokens(a,n.walkTokens);let l=(n.hooks?n.hooks.provideParser(r):r?m.parse:m.parseInline)(a,n);return n.hooks&&(l=n.hooks.postprocess(l)),l}catch(a){return i(a)}}}onError(r,e){return t=>{if(t.message+=`\nPlease report this to https://github.com/markedjs/marked.`,r){let s="<p>An error occurred:</p><pre>"+y(t.message+"",!0)+"</pre>";return e?Promise.resolve(s):s}if(e)return Promise.reject(t);throw t}}},S=new ot;function d(r,e){return S.parse(r,e)}d.options=d.setOptions=function(r){return S.setOptions(r),d.defaults=S.defaults,oe(d.defaults),d};d.getDefaults=N;d.defaults=T;d.use=function(...r){return S.use(...r),d.defaults=S.defaults,oe(d.defaults),d};d.walkTokens=function(r,e){return S.walkTokens(r,e)};d.parseInline=S.parseInline;d.Parser=m;d.parser=m.parse;d.Renderer=M;d.TextRenderer=K;d.Lexer=w;d.lexer=w.lex;d.Tokenizer=q;d.Hooks=I;d.parse=d;var ct=d.options,ht=d.setOptions,pt=d.use,ut=d.walkTokens,gt=d.parseInline;var kt=m.parse,dt=w.lex;d.use({extensions:[{name:"inlineMath",level:"inline",start(r){return r.match(/(?<![\\\\$])\\$(?![$\\s])/)?.index},tokenizer(r){let e=/^\\$(?![$\\s\\d])((?:\\\\\\$|[^$\\n])*?)(?<!\\s)\\$(?!\\d)/.exec(r);if(e)return{type:"inlineMath",raw:e[0],text:e[1].trim()}},renderer(r){return r.raw}}]});var _=new Map;self.onmessage=r=>{let e=r.data;if(typeof e!="object"||e===null)return;let{id:t,text:s,append:n,expectedLength:i,oldRaws:a,instance:l,baseVersion:o,dispose:c}=e;if(c===!0){typeof l=="string"&&_.delete(l);return}let p=typeof l=="string"?l:null,h=typeof o=="number"?o:null,u,f=null;if(typeof n=="string"){if(p===null||h===null){self.postMessage({id:t,needResync:!0});return}let g=_.get(p);if(!g||g.version!==h){self.postMessage({id:t,needResync:!0});return}if(u=g.source+n,typeof i=="number"&&u.length!==i){_.delete(p),self.postMessage({id:t,needResync:!0});return}f=g.raws}else if(typeof s=="string"){if(u=s,Array.isArray(a))f=a;else if(p!==null&&h!==null){let g=_.get(p);if(g&&g.version===h)f=g.raws;else{self.postMessage({id:t,needResync:!0});return}}}else return;try{let g=d.lexer(u),x=0;if(f){let z=Math.min(f.length,g.length);for(;x<z&&f[x]===g[x].raw;x++);}p!==null&&h!==null&&_.set(p,{version:h+1,raws:g.map(z=>z.raw),source:u}),self.postMessage({id:t,matchLen:x,tail:g.slice(x)})}catch(g){p!==null&&_.delete(p),self.postMessage({id:t,error:String(g)})}};})();\n';
459
+ var WORKER_SOURCE_STRING = '"use strict";(()=>{function U(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var A=U();function he(r){A=r}var T={exec:()=>null};function L(r){let e=[];return t=>{let s=Math.max(0,Math.min(3,t-1)),n=e[s];return n||(n=r(s),e[s]=n),n}}function g(r,e=""){let t=typeof r=="string"?r:r.source,s={replace:(n,i)=>{let a=typeof i=="string"?i:i.source;return a=a.replace(b.caret,"$1"),t=t.replace(n,a),s},getRegex:()=>new RegExp(t,e)};return s}var me=((r="")=>{try{return!!new RegExp("(?<=1)(?<!1)"+r)}catch{return!1}})(),b={codeRemoveIndent:/^(?: {1,4}| {0,3}\\t)/gm,outputLinkReplace:/\\\\([\\[\\]])/g,indentCodeCompensation:/^(\\s+)(?:```)/,beginningSpace:/^\\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\\n/g,tabCharGlobal:/\\t/g,multipleSpaceGlobal:/\\s+/g,blankLine:/^[ \\t]*$/,doubleBlankLine:/\\n[ \\t]*\\n[ \\t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\\n {0,3}((?:=+|-+) *)(?=\\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \\t]?/gm,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\\[[ xX]\\] +\\S/,listReplaceTask:/^\\[[ xX]\\] +/,listTaskCheckbox:/\\[[ xX]\\]/,anyLine:/\\n.*\\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\\||\\| *$/g,tableRowBlankLine:/\\n[ \\t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\\s|>)/i,endPreScriptTag:/^<\\/(pre|code|kbd|script)(\\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^\'"]*[^\\s])\\s+([\'"])(.*)\\2/,unicodeAlphaNumeric:/[\\p{L}\\p{N}]/u,escapeTest:/[&<>"\']/,escapeReplace:/[&<>"\']/g,escapeTestNoEncode:/[<>"\']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/,escapeReplaceNoEncode:/[<>"\']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/g,caret:/(^|[^\\[])\\^/g,percentDecode:/%25/g,findPipe:/\\|/g,splitPipe:/ \\|/,slashPipe:/\\\\\\|/g,carriageReturn:/\\r\\n|\\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\\S*/,endingNewline:/\\n$/,listItemRegex:r=>new RegExp(`^( {0,3}${r})((?:[ ][^\\\\n]*)?(?:\\\\n|$))`),nextBulletRegex:L(r=>new RegExp(`^ {0,${r}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ ][^\\\\n]*)?(?:\\\\n|$))`)),hrRegex:L(r=>new RegExp(`^ {0,${r}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`)),fencesBeginRegex:L(r=>new RegExp(`^ {0,${r}}(?:\\`\\`\\`|~~~)`)),headingBeginRegex:L(r=>new RegExp(`^ {0,${r}}#`)),htmlBeginRegex:L(r=>new RegExp(`^ {0,${r}}<(?:[a-z].*>|!--)`,"i")),blockquoteBeginRegex:L(r=>new RegExp(`^ {0,${r}}>`))},ye=/^(?:[ \\t]*(?:\\n|$))+/,$e=/^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/,Re=/^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/,M=/^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/,Se=/^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/,F=/ {0,3}(?:[*+-]|\\d{1,9}[.)])/,pe=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,ue=g(pe).replace(/bull/g,F).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}(?:\\s|$)/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/\\|table/g,"").getRegex(),Te=g(pe).replace(/bull/g,F).replace(/blockCode/g,/(?: {4}| {0,3}\\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}(?:\\s|$)/).replace(/html/g,/ {0,3}<[^\\n>]+>\\n/).replace(/table/g,/ {0,3}\\|?(?:[:\\- ]*\\|)+[\\:\\- ]*\\n/).getRegex(),V=/^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \\t]+\\n)[^\\n]+)*)/,ze=/^[^\\n]+/,J=/(?!\\s*\\])(?:\\\\[\\s\\S]|[^\\[\\]\\\\])+/,Ae=g(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/).replace("label",J).replace("title",/(?:"(?:\\\\"?|[^"\\\\])*"|\'[^\'\\n]*(?:\\n[^\'\\n]+)*\\n?\'|\\([^()]*\\))/).getRegex(),Le=g(/^(bull)([ \\t][^\\n]*?)?(?:\\n|$)/).replace(/bull/g,F).getRegex(),j="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",K=/<!--(?:-?>|[\\s\\S]*?(?:-->|$))/,_e=g("^ {0,3}(?:<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:</\\\\1>[^\\\\n]*\\\\n*|$)|comment[^\\\\n]*(\\\\n+|$)|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>[^\\\\n]*\\\\n*|$)|<![A-Z][\\\\s\\\\S]*?(?:>[^\\\\n]*\\\\n*|$)|<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?(?:\\\\]\\\\]>[^\\\\n]*\\\\n*|$)|</?(tag)(?: +|\\\\n|/?>)[\\\\s\\\\S]*?(?:(?:\\\\n[ ]*)+\\\\n|$)|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ ]*)+\\\\n|$)|</(?!script|pre|style|textarea)[a-z][\\\\w-]*\\\\s*>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ ]*)+\\\\n|$))","i").replace("comment",K).replace("tag",j).replace("attribute",/ +[a-zA-Z:_][\\w.:-]*(?: *= *"[^"\\n]*"| *= *\'[^\'\\n]*\'| *= *[^\\s"\'=<>`]+)?/).getRegex(),ge=r=>g(V).replace("hr",M).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n").replace("list",r).replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",j).getRegex(),Pe=ge(/ {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]/),ve=ge(/ {0,3}(?:[*+-]|\\d{1,9}[.)])(?:[ \\t]|\\n|$)/),Ie=g(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/).replace("paragraph",ve).getRegex(),Y={blockquote:Ie,code:$e,def:Ae,fences:Re,heading:Se,hr:M,html:_e,lheading:ue,list:Le,newline:ye,paragraph:Pe,table:T,text:ze},ne=g("^ *([^\\\\n ].*)\\\\n {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)").replace("hr",M).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3} )[^\\\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\\\t]").replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",j).getRegex(),Ce={...Y,lheading:Te,table:ne,paragraph:g(V).replace("hr",M).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("|lheading","").replace("table",ne).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~~~)[^\\\\n]*\\\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\\\t]+[^ \\\\t\\\\n]").replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",j).getRegex()},Ee={...Y,html:g(`^ *(?:comment *(?:\\\\n|\\\\s*$)|<(tag)[\\\\s\\\\S]+?</\\\\1> *(?:\\\\n{2,}|\\\\s*$)|<tag(?:"[^"]*"|\'[^\']*\'|\\\\s[^\'"/>\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))`).replace("comment",K).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b").getRegex(),def:/^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +(["(][^\\n]+[")]))? *(?:\\n+|$)/,heading:/^(#{1,6})(.*)(?:\\n+|$)/,fences:T,lheading:/^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,paragraph:g(V).replace("hr",M).replace("heading",` *#{1,6} *[^\n]`).replace("lheading",ue).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},Me=/^\\\\([!"#$%&\'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/,Be=/^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/,ke=/^( {2,}|\\\\)\\n(?!\\s*$)/,qe=/^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/,_=/[\\p{P}\\p{S}]/u,H=/[\\s\\p{P}\\p{S}]/u,ee=/[^\\s\\p{P}\\p{S}]/u,Ze=g(/^((?![*_])punctSpace)/,"u").replace(/punctSpace/g,H).getRegex(),fe=/(?!~)[\\p{P}\\p{S}]/u,De=/(?!~)[\\s\\p{P}\\p{S}]/u,Qe=/(?:[^\\s\\p{P}\\p{S}]|~)/u,Ne=g(/link|precode-code|html/,"g").replace("link",/\\[(?:[^\\[\\]`]|(?<a>`+)[^`]+\\k<a>(?!`))*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)/).replace("precode-",me?"(?<!`)()":"(^^|[^`])").replace("code",/(?<b>`+)[^`]+\\k<b>(?!`)/).replace("html",/<(?! )[^<>]*?>/).getRegex(),de=/^(?:\\*+(?:((?!\\*)punct)|([^\\s*]))?)|^_+(?:((?!_)punct)|([^\\s_]))?/,je=g(de,"u").replace(/punct/g,_).getRegex(),He=g(de,"u").replace(/punct/g,fe).getRegex(),xe="^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)|(?!\\\\*)punctSpace(\\\\*+)(?=notPunctSpace)|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)|notPunctSpace(\\\\*+)(?=notPunctSpace)",Oe=g(xe,"gu").replace(/notPunctSpace/g,ee).replace(/punctSpace/g,H).replace(/punct/g,_).getRegex(),Ge=g(xe,"gu").replace(/notPunctSpace/g,Qe).replace(/punctSpace/g,De).replace(/punct/g,fe).getRegex(),We=g("^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,ee).replace(/punctSpace/g,H).replace(/punct/g,_).getRegex(),Xe=g(/^~~?(?:((?!~)punct)|[^\\s~])/,"u").replace(/punct/g,_).getRegex(),Ue="^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)",Fe=g(Ue,"gu").replace(/notPunctSpace/g,ee).replace(/punctSpace/g,H).replace(/punct/g,_).getRegex(),Ve=g(/\\\\(punct)/,"gu").replace(/punct/g,_).getRegex(),Je=g(/^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&\'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),Ke=g(K).replace("(?:-->|$)","-->").getRegex(),Ye=g("^comment|^</[a-zA-Z][\\\\w:-]*\\\\s*>|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>|^<\\\\?[\\\\s\\\\S]*?\\\\?>|^<![a-zA-Z]+\\\\s[\\\\s\\\\S]*?>|^<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>").replace("comment",Ke).replace("attribute",/\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*"[^"]*"|\\s*=\\s*\'[^\']*\'|\\s*=\\s*[^\\s"\'=<>`]+)?/).getRegex(),D=/(?:\\[(?:\\\\[\\s\\S]|[^\\[\\]\\\\])*\\]|\\\\[\\s\\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\\])|[^\\[\\]\\\\`])*?/,et=g(/^!?\\[(label)\\]\\(\\s*(href)(?:(?:[ \\t]+(?:\\n[ \\t]*)?|\\n[ \\t]*)(title))?\\s*\\)/).replace("label",D).replace("href",/<(?:\\\\.|[^\\n<>\\\\])+>|[^ \\t\\n\\x00-\\x1f]+|(?=\\))/).replace("title",/"(?:\\\\"?|[^"\\\\])*"|\'(?:\\\\\'?|[^\'\\\\])*\'|\\((?:\\\\\\)?|[^)\\\\])*\\)/).getRegex(),be=g(/^!?\\[(label)\\]\\[(ref)\\]/).replace("label",D).replace("ref",J).getRegex(),we=g(/^!?\\[(ref)\\](?:\\[\\])?/).replace("ref",J).getRegex(),tt=g("reflink|nolink(?!\\\\()","g").replace("reflink",be).replace("nolink",we).getRegex(),se=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,te={_backpedal:T,anyPunctuation:Ve,autolink:Je,blockSkip:Ne,br:ke,code:Be,del:T,delLDelim:T,delRDelim:T,emStrongLDelim:je,emStrongRDelimAst:Oe,emStrongRDelimUnd:We,escape:Me,link:et,nolink:we,punctuation:Ze,reflink:be,reflinkSearch:tt,tag:Ye,text:qe,url:T},rt={...te,link:g(/^!?\\[(label)\\]\\((.*?)\\)/).replace("label",D).getRegex(),reflink:g(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/).replace("label",D).getRegex()},G={...te,emStrongRDelimAst:Ge,emStrongLDelim:He,delLDelim:Xe,delRDelim:Fe,url:g(/^((?:protocol):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/).replace("protocol",se).replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_\'"~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_\'"~)]+(?!$))+/,del:/^(~~?)(?=[^\\s~])((?:\\\\[\\s\\S]|[^\\\\])*?(?:\\\\[\\s\\S]|[^\\s~\\\\]))\\1(?=[^~]|$)/,text:g(/^(`+|~+|[^`~])(?:(?=[`~])|(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&\'*+\\/=?_`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*~_]|\\b_|protocol:\\/\\/|www\\.|$)|[^ ](?= {2,}\\n)|[^a-zA-Z0-9.!#$%&\'*+\\/=?_`{\\|}~-](?=[a-zA-Z0-9.!#$%&\'*+\\/=?_`{\\|}~-]+@)))/).replace("protocol",se).getRegex()},nt={...G,br:g(ke).replace("{2,}","*").getRegex(),text:g(G.text).replace("\\\\b_","\\\\b_| {2,}\\\\n").replace(/\\{2,\\}/g,"*").getRegex()},Z={normal:Y,gfm:Ce,pedantic:Ee},C={normal:te,gfm:G,breaks:nt,pedantic:rt},st={"&":"&amp;","<":"&lt;",">":"&gt;",\'"\':"&quot;","\'":"&#39;"},ie=r=>st[r];function y(r,e){if(e){if(b.escapeTest.test(r))return r.replace(b.escapeReplace,ie)}else if(b.escapeTestNoEncode.test(r))return r.replace(b.escapeReplaceNoEncode,ie);return r}function le(r){try{r=encodeURI(r).replace(b.percentDecode,"%")}catch{return null}return r}function ae(r,e){let t=r.replace(b.findPipe,(i,a,l)=>{let o=!1,c=a;for(;--c>=0&&l[c]==="\\\\";)o=!o;return o?"|":" |"}),s=t.split(b.splitPipe),n=0;if(s[0].trim()||s.shift(),s.length>0&&!s.at(-1)?.trim()&&s.pop(),e)if(s.length>e)s.splice(e);else for(;s.length<e;)s.push("");for(;n<s.length;n++)s[n]=s[n].trim().replace(b.slashPipe,"|");return s}function S(r,e,t){let s=r.length;if(s===0)return"";let n=0;for(;n<s;){let i=r.charAt(s-n-1);if(i===e&&!t)n++;else if(i!==e&&t)n++;else break}return r.slice(0,s-n)}function oe(r){let e=r.split(`\n`),t=e.length-1;for(;t>=0&&b.blankLine.test(e[t]);)t--;return e.length-t<=2?r:e.slice(0,t+1).join(`\n`)}function it(r,e){if(r.indexOf(e[1])===-1)return-1;let t=0;for(let s=0;s<r.length;s++)if(r[s]==="\\\\")s++;else if(r[s]===e[0])t++;else if(r[s]===e[1]&&(t--,t<0))return s;return t>0?-2:-1}function lt(r,e=0){let t=e,s="";for(let n of r)if(n===" "){let i=4-t%4;s+=" ".repeat(i),t+=i}else s+=n,t++;return s}function ce(r,e,t,s,n){let i=e.href,a=e.title||null,l=r[1].replace(n.other.outputLinkReplace,"$1");s.state.inLink=!0;let o={type:r[0].charAt(0)==="!"?"image":"link",raw:t,href:i,title:a,text:l,tokens:s.inlineTokens(l)};return s.state.inLink=!1,o}function at(r,e,t){let s=r.match(t.other.indentCodeCompensation);if(s===null)return e;let n=s[1];return e.split(`\n`).map(i=>{let a=i.match(t.other.beginningSpace);if(a===null)return i;let[l]=a;return l.length>=n.length?i.slice(n.length):i}).join(`\n`)}var Q=class{options;rules;lexer;constructor(r){this.options=r||A}space(r){let e=this.rules.block.newline.exec(r);if(e&&e[0].length>0)return{type:"space",raw:e[0]}}code(r){let e=this.rules.block.code.exec(r);if(e){let t=this.options.pedantic?e[0]:oe(e[0]),s=t.replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:t,codeBlockStyle:"indented",text:s}}}fences(r){let e=this.rules.block.fences.exec(r);if(e){let t=e[0],s=at(t,e[3]||"",this.rules);return{type:"code",raw:t,lang:e[2]?e[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):e[2],text:s}}}heading(r){let e=this.rules.block.heading.exec(r);if(e){let t=e[2].trim();if(this.rules.other.endingHash.test(t)){let s=S(t,"#");(this.options.pedantic||!s||this.rules.other.endingSpaceChar.test(s))&&(t=s.trim())}return{type:"heading",raw:S(e[0],`\n`),depth:e[1].length,text:t,tokens:this.lexer.inline(t)}}}hr(r){let e=this.rules.block.hr.exec(r);if(e)return{type:"hr",raw:S(e[0],`\n`)}}blockquote(r){let e=this.rules.block.blockquote.exec(r);if(e){let t=S(e[0],`\n`).split(`\n`),s="",n="",i=[];for(;t.length>0;){let a=!1,l=[],o;for(o=0;o<t.length;o++)if(this.rules.other.blockquoteStart.test(t[o]))l.push(t[o]),a=!0;else if(!a)l.push(t[o]);else break;t=t.slice(o);let c=l.join(`\n`),p=c.replace(this.rules.other.blockquoteSetextReplace,`\n $1`).replace(this.rules.other.blockquoteSetextReplace2,"");s=s?`${s}\n${c}`:c,n=n?`${n}\n${p}`:p;let h=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(p,i,!0),this.lexer.state.top=h,t.length===0)break;let u=i.at(-1);if(u?.type==="code")break;if(u?.type==="blockquote"){let x=u,f=x.raw+`\n`+t.join(`\n`),d=this.blockquote(f);i[i.length-1]=d,s=s.substring(0,s.length-x.raw.length)+d.raw,n=n.substring(0,n.length-x.text.length)+d.text;break}else if(u?.type==="list"){let x=u,f=x.raw+`\n`+t.join(`\n`),d=this.list(f);i[i.length-1]=d,s=s.substring(0,s.length-u.raw.length)+d.raw,n=n.substring(0,n.length-x.raw.length)+d.raw,t=f.substring(i.at(-1).raw.length).split(`\n`);continue}}return{type:"blockquote",raw:s,tokens:i,text:n}}}list(r){let e=this.rules.block.list.exec(r);if(e){let t=e[1].trim(),s=t.length>1,n={type:"list",raw:"",ordered:s,start:s?+t.slice(0,-1):"",loose:!1,items:[]};t=s?`\\\\d{1,9}\\\\${t.slice(-1)}`:`\\\\${t}`,this.options.pedantic&&(t=s?t:"[*+-]");let i=this.rules.other.listItemRegex(t),a=!1;for(;r;){let o=!1,c="",p="";if(!(e=i.exec(r))||this.rules.block.hr.test(r))break;c=e[0],r=r.substring(c.length);let h=lt(e[2].split(`\n`,1)[0],e[1].length),u=r.split(`\n`,1)[0],x=!h.trim(),f=0;if(this.options.pedantic?(f=2,p=h.trimStart()):x?f=e[1].length+1:(f=h.search(this.rules.other.nonSpaceChar),f=f>4?1:f,p=h.slice(f),f+=e[1].length),x&&this.rules.other.blankLine.test(u)&&(c+=u+`\n`,r=r.substring(u.length+1),o=!0),!o){let d=this.rules.other.nextBulletRegex(f),B=this.rules.other.hrRegex(f),$=this.rules.other.fencesBeginRegex(f),q=this.rules.other.headingBeginRegex(f),R=this.rules.other.htmlBeginRegex(f),v=this.rules.other.blockquoteBeginRegex(f);for(;r;){let O=r.split(`\n`,1)[0],I;if(u=O,this.options.pedantic?(u=u.replace(this.rules.other.listReplaceNesting," "),I=u):I=u.replace(this.rules.other.tabCharGlobal," "),$.test(u)||q.test(u)||R.test(u)||v.test(u)||d.test(u)||B.test(u))break;if(I.search(this.rules.other.nonSpaceChar)>=f||!u.trim())p+=`\n`+I.slice(f);else{if(x||h.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||$.test(h)||q.test(h)||B.test(h))break;p+=`\n`+u}x=!u.trim(),c+=O+`\n`,r=r.substring(O.length+1),h=I.slice(f)}}n.loose||(a?n.loose=!0:this.rules.other.doubleBlankLine.test(c)&&(a=!0)),n.items.push({type:"list_item",raw:c,task:!!this.options.gfm&&this.rules.other.listIsTask.test(p),loose:!1,text:p,tokens:[]}),n.raw+=c}let l=n.items.at(-1);if(l)l.raw=l.raw.trimEnd(),l.text=l.text.trimEnd();else return;n.raw=n.raw.trimEnd();for(let o of n.items){this.lexer.state.top=!1,o.tokens=this.lexer.blockTokens(o.text,[]);let c=o.tokens[0];if(o.task&&(c?.type==="text"||c?.type==="paragraph")){o.text=o.text.replace(this.rules.other.listReplaceTask,""),c.raw=c.raw.replace(this.rules.other.listReplaceTask,""),c.text=c.text.replace(this.rules.other.listReplaceTask,"");for(let h=this.lexer.inlineQueue.length-1;h>=0;h--)if(this.rules.other.listIsTask.test(this.lexer.inlineQueue[h].src)){this.lexer.inlineQueue[h].src=this.lexer.inlineQueue[h].src.replace(this.rules.other.listReplaceTask,"");break}let p=this.rules.other.listTaskCheckbox.exec(o.raw);if(p){let h={type:"checkbox",raw:p[0]+" ",checked:p[0]!=="[ ]"};o.checked=h.checked,n.loose?o.tokens[0]&&["paragraph","text"].includes(o.tokens[0].type)&&"tokens"in o.tokens[0]&&o.tokens[0].tokens?(o.tokens[0].raw=h.raw+o.tokens[0].raw,o.tokens[0].text=h.raw+o.tokens[0].text,o.tokens[0].tokens.unshift(h)):o.tokens.unshift({type:"paragraph",raw:h.raw,text:h.raw,tokens:[h]}):o.tokens.unshift(h)}}else o.task&&(o.task=!1);if(!n.loose){let p=o.tokens.filter(u=>u.type==="space"),h=p.length>0&&p.some(u=>this.rules.other.anyLine.test(u.raw));n.loose=h}}if(n.loose)for(let o of n.items){o.loose=!0;for(let c of o.tokens)c.type==="text"&&(c.type="paragraph")}return n}}html(r){let e=this.rules.block.html.exec(r);if(e){let t=oe(e[0]);return{type:"html",block:!0,raw:t,pre:e[1]==="pre"||e[1]==="script"||e[1]==="style",text:t}}}def(r){let e=this.rules.block.def.exec(r);if(e){let t=e[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal," "),s=e[2]?e[2].replace(this.rules.other.hrefBrackets,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",n=e[3]?e[3].substring(1,e[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):e[3];return{type:"def",tag:t,raw:S(e[0],`\n`),href:s,title:n}}}table(r){let e=this.rules.block.table.exec(r);if(!e||!this.rules.other.tableDelimiter.test(e[2]))return;let t=ae(e[1]),s=e[2].replace(this.rules.other.tableAlignChars,"").split("|"),n=e[3]?.trim()?e[3].replace(this.rules.other.tableRowBlankLine,"").split(`\n`):[],i={type:"table",raw:S(e[0],`\n`),header:[],align:[],rows:[]};if(t.length===s.length){for(let a of s)this.rules.other.tableAlignRight.test(a)?i.align.push("right"):this.rules.other.tableAlignCenter.test(a)?i.align.push("center"):this.rules.other.tableAlignLeft.test(a)?i.align.push("left"):i.align.push(null);for(let a=0;a<t.length;a++)i.header.push({text:t[a],tokens:this.lexer.inline(t[a]),header:!0,align:i.align[a]});for(let a of n)i.rows.push(ae(a,i.header.length).map((l,o)=>({text:l,tokens:this.lexer.inline(l),header:!1,align:i.align[o]})));return i}}lheading(r){let e=this.rules.block.lheading.exec(r);if(e){let t=e[1].trim();return{type:"heading",raw:S(e[0],`\n`),depth:e[2].charAt(0)==="="?1:2,text:t,tokens:this.lexer.inline(t)}}}paragraph(r){let e=this.rules.block.paragraph.exec(r);if(e){let t=e[1].charAt(e[1].length-1)===`\n`?e[1].slice(0,-1):e[1];return{type:"paragraph",raw:e[0],text:t,tokens:this.lexer.inline(t)}}}text(r){let e=this.rules.block.text.exec(r);if(e)return{type:"text",raw:e[0],text:e[0],tokens:this.lexer.inline(e[0])}}escape(r){let e=this.rules.inline.escape.exec(r);if(e)return{type:"escape",raw:e[0],text:e[1]}}tag(r){let e=this.rules.inline.tag.exec(r);if(e)return!this.lexer.state.inLink&&this.rules.other.startATag.test(e[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:e[0]}}link(r){let e=this.rules.inline.link.exec(r);if(e){let t=e[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(t)){if(!this.rules.other.endAngleBracket.test(t))return;let i=S(t.slice(0,-1),"\\\\");if((t.length-i.length)%2===0)return}else{let i=it(e[2],"()");if(i===-2)return;if(i>-1){let a=(e[0].indexOf("!")===0?5:4)+e[1].length+i;e[2]=e[2].substring(0,i),e[0]=e[0].substring(0,a).trim(),e[3]=""}}let s=e[2],n="";if(this.options.pedantic){let i=this.rules.other.pedanticHrefTitle.exec(s);i&&(s=i[1],n=i[3])}else n=e[3]?e[3].slice(1,-1):"";return s=s.trim(),this.rules.other.startAngleBracket.test(s)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(t)?s=s.slice(1):s=s.slice(1,-1)),ce(e,{href:s&&s.replace(this.rules.inline.anyPunctuation,"$1"),title:n&&n.replace(this.rules.inline.anyPunctuation,"$1")},e[0],this.lexer,this.rules)}}reflink(r,e){let t;if((t=this.rules.inline.reflink.exec(r))||(t=this.rules.inline.nolink.exec(r))){let s=(t[2]||t[1]).replace(this.rules.other.multipleSpaceGlobal," "),n=e[s.toLowerCase()];if(!n){let i=t[0].charAt(0);return{type:"text",raw:i,text:i}}return ce(t,n,t[0],this.lexer,this.rules)}}emStrong(r,e,t=""){let s=this.rules.inline.emStrongLDelim.exec(r);if(!(!s||!s[1]&&!s[2]&&!s[3]&&!s[4]||s[4]&&t.match(this.rules.other.unicodeAlphaNumeric))&&(!(s[1]||s[3])||!t||this.rules.inline.punctuation.exec(t))){let n=[...s[0]].length-1,i,a,l=n,o=0,c=s[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(c.lastIndex=0,e=e.slice(-1*r.length+n);(s=c.exec(e))!==null;){if(i=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!i)continue;if(a=[...i].length,s[3]||s[4]){l+=a;continue}else if((s[5]||s[6])&&n%3&&!((n+a)%3)){o+=a;continue}if(l-=a,l>0)continue;a=Math.min(a,a+l+o);let p=[...s[0]][0].length,h=r.slice(0,n+s.index+p+a);if(Math.min(n,a)%2){let x=h.slice(1,-1);return{type:"em",raw:h,text:x,tokens:this.lexer.inlineTokens(x)}}let u=h.slice(2,-2);return{type:"strong",raw:h,text:u,tokens:this.lexer.inlineTokens(u)}}}}codespan(r){let e=this.rules.inline.code.exec(r);if(e){let t=e[2].replace(this.rules.other.newLineCharGlobal," "),s=this.rules.other.nonSpaceChar.test(t),n=this.rules.other.startingSpaceChar.test(t)&&this.rules.other.endingSpaceChar.test(t);return s&&n&&(t=t.substring(1,t.length-1)),{type:"codespan",raw:e[0],text:t}}}br(r){let e=this.rules.inline.br.exec(r);if(e)return{type:"br",raw:e[0]}}del(r,e,t=""){let s=this.rules.inline.delLDelim.exec(r);if(s&&(!s[1]||!t||this.rules.inline.punctuation.exec(t))){let n=[...s[0]].length-1,i,a,l=n,o=this.rules.inline.delRDelim;for(o.lastIndex=0,e=e.slice(-1*r.length+n);(s=o.exec(e))!==null;){if(i=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!i||(a=[...i].length,a!==n))continue;if(s[3]||s[4]){l+=a;continue}if(l-=a,l>0)continue;a=Math.min(a,a+l);let c=[...s[0]][0].length,p=r.slice(0,n+s.index+c+a),h=p.slice(n,-n);return{type:"del",raw:p,text:h,tokens:this.lexer.inlineTokens(h)}}}}autolink(r){let e=this.rules.inline.autolink.exec(r);if(e){let t,s;return e[2]==="@"?(t=e[1],s="mailto:"+t):(t=e[1],s=t),{type:"link",raw:e[0],text:t,href:s,tokens:[{type:"text",raw:t,text:t}]}}}url(r){let e;if(e=this.rules.inline.url.exec(r)){let t,s;if(e[2]==="@")t=e[0],s="mailto:"+t;else{let n;do n=e[0],e[0]=this.rules.inline._backpedal.exec(e[0])?.[0]??"";while(n!==e[0]);t=e[0],e[1]==="www."?s="http://"+e[0]:s=e[0]}return{type:"link",raw:e[0],text:t,href:s,tokens:[{type:"text",raw:t,text:t}]}}}inlineText(r){let e=this.rules.inline.text.exec(r);if(e){let t=this.lexer.state.inRawBlock;return{type:"text",raw:e[0],text:e[0],escaped:t}}}},w=class W{tokens;options;state;inlineQueue;tokenizer;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||A,this.options.tokenizer=this.options.tokenizer||new Q,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let t={other:b,block:Z.normal,inline:C.normal};this.options.pedantic?(t.block=Z.pedantic,t.inline=C.pedantic):this.options.gfm&&(t.block=Z.gfm,this.options.breaks?t.inline=C.breaks:t.inline=C.gfm),this.tokenizer.rules=t}static get rules(){return{block:Z,inline:C}}static lex(e,t){return new W(t).lex(e)}static lexInline(e,t){return new W(t).inlineTokens(e)}lex(e){e=e.replace(b.carriageReturn,`\n`),this.blockTokens(e,this.tokens);for(let t=0;t<this.inlineQueue.length;t++){let s=this.inlineQueue[t];this.inlineTokens(s.src,s.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,t=[],s=!1){this.tokenizer.lexer=this,this.options.pedantic&&(e=e.replace(b.tabCharGlobal," ").replace(b.spaceLine,""));let n=1/0;for(;e;){if(e.length<n)n=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}let i;if(this.options.extensions?.block?.some(l=>(i=l.call({lexer:this},e,t))?(e=e.substring(i.raw.length),t.push(i),!0):!1))continue;if(i=this.tokenizer.space(e)){e=e.substring(i.raw.length);let l=t.at(-1);i.raw.length===1&&l!==void 0?l.raw+=`\n`:t.push(i);continue}if(i=this.tokenizer.code(e)){e=e.substring(i.raw.length);let l=t.at(-1);l?.type==="paragraph"||l?.type==="text"?(l.raw+=(l.raw.endsWith(`\n`)?"":`\n`)+i.raw,l.text+=`\n`+i.text,this.inlineQueue.at(-1).src=l.text):t.push(i);continue}if(i=this.tokenizer.fences(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.heading(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.hr(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.blockquote(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.list(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.html(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.def(e)){e=e.substring(i.raw.length);let l=t.at(-1);l?.type==="paragraph"||l?.type==="text"?(l.raw+=(l.raw.endsWith(`\n`)?"":`\n`)+i.raw,l.text+=`\n`+i.raw,this.inlineQueue.at(-1).src=l.text):this.tokens.links[i.tag]||(this.tokens.links[i.tag]={href:i.href,title:i.title},t.push(i));continue}if(i=this.tokenizer.table(e)){e=e.substring(i.raw.length),t.push(i);continue}if(i=this.tokenizer.lheading(e)){e=e.substring(i.raw.length),t.push(i);continue}let a=e;if(this.options.extensions?.startBlock){let l=1/0,o=e.slice(1),c;this.options.extensions.startBlock.forEach(p=>{c=p.call({lexer:this},o),typeof c=="number"&&c>=0&&(l=Math.min(l,c))}),l<1/0&&l>=0&&(a=e.substring(0,l+1))}if(this.state.top&&(i=this.tokenizer.paragraph(a))){let l=t.at(-1);s&&l?.type==="paragraph"?(l.raw+=(l.raw.endsWith(`\n`)?"":`\n`)+i.raw,l.text+=`\n`+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=l.text):t.push(i),s=a.length!==e.length,e=e.substring(i.raw.length);continue}if(i=this.tokenizer.text(e)){e=e.substring(i.raw.length);let l=t.at(-1);l?.type==="text"?(l.raw+=(l.raw.endsWith(`\n`)?"":`\n`)+i.raw,l.text+=`\n`+i.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=l.text):t.push(i);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){this.tokenizer.lexer=this;let s=e;if(this.tokens.links){let l=Object.keys(this.tokens.links);l.length>0&&(s=s.replace(this.tokenizer.rules.inline.reflinkSearch,o=>l.includes(o.slice(o.lastIndexOf("[")+1,-1))?"["+"a".repeat(o.length-2)+"]":o))}s=s.replace(this.tokenizer.rules.inline.anyPunctuation,"++"),s=s.replace(this.tokenizer.rules.inline.blockSkip,(l,o,c)=>{let p=c?c.length:0;return l.slice(0,p)+"["+"a".repeat(l.length-p-2)+"]"}),s=this.options.hooks?.emStrongMask?.call({lexer:this},s)??s;let n=!1,i="",a=1/0;for(;e;){if(e.length<a)a=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}n||(i=""),n=!1;let l;if(this.options.extensions?.inline?.some(c=>(l=c.call({lexer:this},e,t))?(e=e.substring(l.raw.length),t.push(l),!0):!1))continue;if(l=this.tokenizer.escape(e)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.tag(e)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.link(e)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(l.raw.length);let c=t.at(-1);l.type==="text"&&c?.type==="text"?(c.raw+=l.raw,c.text+=l.text):t.push(l);continue}if(l=this.tokenizer.emStrong(e,s,i)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.codespan(e)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.br(e)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.del(e,s,i)){e=e.substring(l.raw.length),t.push(l);continue}if(l=this.tokenizer.autolink(e)){e=e.substring(l.raw.length),t.push(l);continue}if(!this.state.inLink&&(l=this.tokenizer.url(e))){e=e.substring(l.raw.length),t.push(l);continue}let o=e;if(this.options.extensions?.startInline){let c=1/0,p=e.slice(1),h;this.options.extensions.startInline.forEach(u=>{h=u.call({lexer:this},p),typeof h=="number"&&h>=0&&(c=Math.min(c,h))}),c<1/0&&c>=0&&(o=e.substring(0,c+1))}if(l=this.tokenizer.inlineText(o)){e=e.substring(l.raw.length),l.raw.slice(-1)!=="_"&&(i=l.raw.slice(-1)),n=!0;let c=t.at(-1);c?.type==="text"?(c.raw+=l.raw,c.text+=l.text):t.push(l);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return t}infiniteLoopError(e){let t="Infinite loop on byte: "+e;if(this.options.silent)console.error(t);else throw new Error(t)}},N=class{options;parser;constructor(r){this.options=r||A}space(r){return""}code({text:r,lang:e,escaped:t}){let s=(e||"").match(b.notSpaceStart)?.[0],n=r.replace(b.endingNewline,"")+`\n`;return s?\'<pre><code class="language-\'+y(s)+\'">\'+(t?n:y(n,!0))+`</code></pre>\n`:"<pre><code>"+(t?n:y(n,!0))+`</code></pre>\n`}blockquote({tokens:r}){return`<blockquote>\n${this.parser.parse(r)}</blockquote>\n`}html({text:r}){return r}def(r){return""}heading({tokens:r,depth:e}){return`<h${e}>${this.parser.parseInline(r)}</h${e}>\n`}hr(r){return`<hr>\n`}list(r){let e=r.ordered,t=r.start,s="";for(let a=0;a<r.items.length;a++){let l=r.items[a];s+=this.listitem(l)}let n=e?"ol":"ul",i=e&&t!==1?\' start="\'+t+\'"\':"";return"<"+n+i+`>\n`+s+"</"+n+`>\n`}listitem(r){return`<li>${this.parser.parse(r.tokens)}</li>\n`}checkbox({checked:r}){return"<input "+(r?\'checked="" \':"")+\'disabled="" type="checkbox"> \'}paragraph({tokens:r}){return`<p>${this.parser.parseInline(r)}</p>\n`}table(r){let e="",t="";for(let n=0;n<r.header.length;n++)t+=this.tablecell(r.header[n]);e+=this.tablerow({text:t});let s="";for(let n=0;n<r.rows.length;n++){let i=r.rows[n];t="";for(let a=0;a<i.length;a++)t+=this.tablecell(i[a]);s+=this.tablerow({text:t})}return s&&(s=`<tbody>${s}</tbody>`),`<table>\n<thead>\n`+e+`</thead>\n`+s+`</table>\n`}tablerow({text:r}){return`<tr>\n${r}</tr>\n`}tablecell(r){let e=this.parser.parseInline(r.tokens),t=r.header?"th":"td";return(r.align?`<${t} align="${r.align}">`:`<${t}>`)+e+`</${t}>\n`}strong({tokens:r}){return`<strong>${this.parser.parseInline(r)}</strong>`}em({tokens:r}){return`<em>${this.parser.parseInline(r)}</em>`}codespan({text:r}){return`<code>${y(r,!0)}</code>`}br(r){return"<br>"}del({tokens:r}){return`<del>${this.parser.parseInline(r)}</del>`}link({href:r,title:e,tokens:t}){let s=this.parser.parseInline(t),n=le(r);if(n===null)return s;r=n;let i=\'<a href="\'+r+\'"\';return e&&(i+=\' title="\'+y(e)+\'"\'),i+=">"+s+"</a>",i}image({href:r,title:e,text:t,tokens:s}){s&&(t=this.parser.parseInline(s,this.parser.textRenderer));let n=le(r);if(n===null)return y(t);r=n;let i=`<img src="${r}" alt="${y(t)}"`;return e&&(i+=` title="${y(e)}"`),i+=">",i}text(r){return"tokens"in r&&r.tokens?this.parser.parseInline(r.tokens):"escaped"in r&&r.escaped?r.text:y(r.text)}},re=class{strong({text:r}){return r}em({text:r}){return r}codespan({text:r}){return r}del({text:r}){return r}html({text:r}){return r}text({text:r}){return r}link({text:r}){return""+r}image({text:r}){return""+r}br(){return""}checkbox({raw:r}){return r}},m=class X{options;renderer;textRenderer;constructor(e){this.options=e||A,this.options.renderer=this.options.renderer||new N,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new re}static parse(e,t){return new X(t).parse(e)}static parseInline(e,t){return new X(t).parseInline(e)}parse(e){this.renderer.parser=this;let t="";for(let s=0;s<e.length;s++){let n=e[s];if(this.options.extensions?.renderers?.[n.type]){let a=n,l=this.options.extensions.renderers[a.type].call({parser:this},a);if(l!==!1||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(a.type)){t+=l||"";continue}}let i=n;switch(i.type){case"space":{t+=this.renderer.space(i);break}case"hr":{t+=this.renderer.hr(i);break}case"heading":{t+=this.renderer.heading(i);break}case"code":{t+=this.renderer.code(i);break}case"table":{t+=this.renderer.table(i);break}case"blockquote":{t+=this.renderer.blockquote(i);break}case"list":{t+=this.renderer.list(i);break}case"checkbox":{t+=this.renderer.checkbox(i);break}case"html":{t+=this.renderer.html(i);break}case"def":{t+=this.renderer.def(i);break}case"paragraph":{t+=this.renderer.paragraph(i);break}case"text":{t+=this.renderer.text(i);break}default:{let a=\'Token with "\'+i.type+\'" type was not found.\';if(this.options.silent)return console.error(a),"";throw new Error(a)}}}return t}parseInline(e,t=this.renderer){this.renderer.parser=this;let s="";for(let n=0;n<e.length;n++){let i=e[n];if(this.options.extensions?.renderers?.[i.type]){let l=this.options.extensions.renderers[i.type].call({parser:this},i);if(l!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(i.type)){s+=l||"";continue}}let a=i;switch(a.type){case"escape":{s+=t.text(a);break}case"html":{s+=t.html(a);break}case"link":{s+=t.link(a);break}case"image":{s+=t.image(a);break}case"checkbox":{s+=t.checkbox(a);break}case"strong":{s+=t.strong(a);break}case"em":{s+=t.em(a);break}case"codespan":{s+=t.codespan(a);break}case"br":{s+=t.br(a);break}case"del":{s+=t.del(a);break}case"text":{s+=t.text(a);break}default:{let l=\'Token with "\'+a.type+\'" type was not found.\';if(this.options.silent)return console.error(l),"";throw new Error(l)}}}return s}},E=class{options;block;constructor(r){this.options=r||A}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(r){return r}postprocess(r){return r}processAllTokens(r){return r}emStrongMask(r){return r}provideLexer(r=this.block){return r?w.lex:w.lexInline}provideParser(r=this.block){return r?m.parse:m.parseInline}},ot=class{defaults=U();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=m;Renderer=N;TextRenderer=re;Lexer=w;Tokenizer=Q;Hooks=E;constructor(...r){this.use(...r)}walkTokens(r,e){let t=[];for(let s of r)switch(t=t.concat(e.call(this,s)),s.type){case"table":{let n=s;for(let i of n.header)t=t.concat(this.walkTokens(i.tokens,e));for(let i of n.rows)for(let a of i)t=t.concat(this.walkTokens(a.tokens,e));break}case"list":{let n=s;t=t.concat(this.walkTokens(n.items,e));break}default:{let n=s;this.defaults.extensions?.childTokens?.[n.type]?this.defaults.extensions.childTokens[n.type].forEach(i=>{let a=n[i].flat(1/0);t=t.concat(this.walkTokens(a,e))}):n.tokens&&(t=t.concat(this.walkTokens(n.tokens,e)))}}return t}use(...r){let e=this.defaults.extensions||{renderers:{},childTokens:{}};return r.forEach(t=>{let s={...t};if(s.async=this.defaults.async||s.async||!1,t.extensions&&(t.extensions.forEach(n=>{if(!n.name)throw new Error("extension name required");if("renderer"in n){let i=e.renderers[n.name];i?e.renderers[n.name]=function(...a){let l=n.renderer.apply(this,a);return l===!1&&(l=i.apply(this,a)),l}:e.renderers[n.name]=n.renderer}if("tokenizer"in n){if(!n.level||n.level!=="block"&&n.level!=="inline")throw new Error("extension level must be \'block\' or \'inline\'");let i=e[n.level];i?i.unshift(n.tokenizer):e[n.level]=[n.tokenizer],n.start&&(n.level==="block"?e.startBlock?e.startBlock.push(n.start):e.startBlock=[n.start]:n.level==="inline"&&(e.startInline?e.startInline.push(n.start):e.startInline=[n.start]))}"childTokens"in n&&n.childTokens&&(e.childTokens[n.name]=n.childTokens)}),s.extensions=e),t.renderer){let n=this.defaults.renderer||new N(this.defaults);for(let i in t.renderer){if(!(i in n))throw new Error(`renderer \'${i}\' does not exist`);if(["options","parser"].includes(i))continue;let a=i,l=t.renderer[a],o=n[a];n[a]=(...c)=>{let p=l.apply(n,c);return p===!1&&(p=o.apply(n,c)),p||""}}s.renderer=n}if(t.tokenizer){let n=this.defaults.tokenizer||new Q(this.defaults);for(let i in t.tokenizer){if(!(i in n))throw new Error(`tokenizer \'${i}\' does not exist`);if(["options","rules","lexer"].includes(i))continue;let a=i,l=t.tokenizer[a],o=n[a];n[a]=(...c)=>{let p=l.apply(n,c);return p===!1&&(p=o.apply(n,c)),p}}s.tokenizer=n}if(t.hooks){let n=this.defaults.hooks||new E;for(let i in t.hooks){if(!(i in n))throw new Error(`hook \'${i}\' does not exist`);if(["options","block"].includes(i))continue;let a=i,l=t.hooks[a],o=n[a];E.passThroughHooks.has(i)?n[a]=c=>{if(this.defaults.async&&E.passThroughHooksRespectAsync.has(i))return(async()=>{let h=await l.call(n,c);return o.call(n,h)})();let p=l.call(n,c);return o.call(n,p)}:n[a]=(...c)=>{if(this.defaults.async)return(async()=>{let h=await l.apply(n,c);return h===!1&&(h=await o.apply(n,c)),h})();let p=l.apply(n,c);return p===!1&&(p=o.apply(n,c)),p}}s.hooks=n}if(t.walkTokens){let n=this.defaults.walkTokens,i=t.walkTokens;s.walkTokens=function(a){let l=[];return l.push(i.call(this,a)),n&&(l=l.concat(n.call(this,a))),l}}this.defaults={...this.defaults,...s}}),this}setOptions(r){return this.defaults={...this.defaults,...r},this}lexer(r,e){return w.lex(r,e??this.defaults)}parser(r,e){return m.parse(r,e??this.defaults)}parseMarkdown(r){return(e,t)=>{let s={...t},n={...this.defaults,...s},i=this.onError(!!n.silent,!!n.async);if(this.defaults.async===!0&&s.async===!1)return i(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof e>"u"||e===null)return i(new Error("marked(): input parameter is undefined or null"));if(typeof e!="string")return i(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected"));if(n.hooks&&(n.hooks.options=n,n.hooks.block=r),n.async)return(async()=>{let a=n.hooks?await n.hooks.preprocess(e):e,l=await(n.hooks?await n.hooks.provideLexer(r):r?w.lex:w.lexInline)(a,n),o=n.hooks?await n.hooks.processAllTokens(l):l;n.walkTokens&&await Promise.all(this.walkTokens(o,n.walkTokens));let c=await(n.hooks?await n.hooks.provideParser(r):r?m.parse:m.parseInline)(o,n);return n.hooks?await n.hooks.postprocess(c):c})().catch(i);try{n.hooks&&(e=n.hooks.preprocess(e));let a=(n.hooks?n.hooks.provideLexer(r):r?w.lex:w.lexInline)(e,n);n.hooks&&(a=n.hooks.processAllTokens(a)),n.walkTokens&&this.walkTokens(a,n.walkTokens);let l=(n.hooks?n.hooks.provideParser(r):r?m.parse:m.parseInline)(a,n);return n.hooks&&(l=n.hooks.postprocess(l)),l}catch(a){return i(a)}}}onError(r,e){return t=>{if(t.message+=`\nPlease report this to https://github.com/markedjs/marked.`,r){let s="<p>An error occurred:</p><pre>"+y(t.message+"",!0)+"</pre>";return e?Promise.resolve(s):s}if(e)return Promise.reject(t);throw t}}},z=new ot;function k(r,e){return z.parse(r,e)}k.options=k.setOptions=function(r){return z.setOptions(r),k.defaults=z.defaults,he(k.defaults),k};k.getDefaults=U;k.defaults=A;k.use=function(...r){return z.use(...r),k.defaults=z.defaults,he(k.defaults),k};k.walkTokens=function(r,e){return z.walkTokens(r,e)};k.parseInline=z.parseInline;k.Parser=m;k.parser=m.parse;k.Renderer=N;k.TextRenderer=re;k.Lexer=w;k.lexer=w.lex;k.Tokenizer=Q;k.Hooks=E;k.parse=k;var ut=k.options,gt=k.setOptions,kt=k.use,ft=k.walkTokens,dt=k.parseInline;var xt=m.parse,bt=w.lex;var ct=0;function ht(r){if(typeof r!="string"||typeof performance.mark!="function"||typeof performance.measure!="function")return null;let e=ct++,t={name:r,startMark:`${r}:start:${e}`,endMark:`${r}:end:${e}`};try{return performance.mark(t.startMark),t}catch{return null}}function pt(r){if(r)try{performance.mark(r.endMark),performance.measure(r.name,r.startMark,r.endMark)}catch{}finally{try{performance.clearMarks?.(r.startMark),performance.clearMarks?.(r.endMark)}catch{}}}k.use({extensions:[{name:"inlineMath",level:"inline",start(r){return r.match(/(?<![\\\\$])\\$(?![$\\s])/)?.index},tokenizer(r){let e=/^\\$(?![$\\s\\d])((?:\\\\\\$|[^$\\n])*?)(?<!\\s)\\$(?!\\d)/.exec(r);if(e)return{type:"inlineMath",raw:e[0],text:e[1].trim()}},renderer(r){return r.raw}}]});var P=new Map;self.onmessage=r=>{let e=r.data;if(typeof e!="object"||e===null)return;let{id:t,text:s,append:n,expectedLength:i,oldRaws:a,instance:l,baseVersion:o,dispose:c,userTimingName:p}=e;if(c===!0){typeof l=="string"&&P.delete(l);return}let h=typeof l=="string"?l:null,u=typeof o=="number"?o:null,x,f=null;if(typeof n=="string"){if(h===null||u===null){self.postMessage({id:t,needResync:!0});return}let d=P.get(h);if(!d||d.version!==u){self.postMessage({id:t,needResync:!0});return}if(x=d.source+n,typeof i=="number"&&x.length!==i){P.delete(h),self.postMessage({id:t,needResync:!0});return}f=d.raws}else if(typeof s=="string"){if(x=s,Array.isArray(a))f=a;else if(h!==null&&u!==null){let d=P.get(h);if(d&&d.version===u)f=d.raws;else{self.postMessage({id:t,needResync:!0});return}}}else return;try{let d=typeof p=="string"?ht(p):null,B=performance.now(),$;try{$=k.lexer(x)}finally{d&&pt(d)}let q=performance.now()-B,R=0;if(f){let v=Math.min(f.length,$.length);for(;R<v&&f[R]===$[R].raw;R++);}h!==null&&u!==null&&P.set(h,{version:u+1,raws:$.map(v=>v.raw),source:x}),self.postMessage({id:t,matchLen:R,tail:$.slice(R),lexerMs:q,sourceCharsLexed:x.length})}catch(d){h!==null&&P.delete(h),self.postMessage({id:t,error:String(d)})}};})();\n';
43
460
 
44
461
  // src/Markdown.ts
45
462
  var now = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
463
+ function lexMarkdown(text, userTiming) {
464
+ if (!userTiming) return import_marked.marked.lexer(text);
465
+ const timing = (0, import_core.beginVectoUserTiming)(import_core.VECTO_USER_TIMING.markdown.parse);
466
+ try {
467
+ return import_marked.marked.lexer(text);
468
+ } finally {
469
+ if (timing) (0, import_core.endVectoUserTiming)(timing);
470
+ }
471
+ }
46
472
  import_marked.marked.use({
47
473
  extensions: [
48
474
  {
@@ -68,23 +494,183 @@ import_marked.marked.use({
68
494
  }
69
495
  ]
70
496
  });
71
- var adaptor = (0, import_liteAdaptor.liteAdaptor)();
72
- (0, import_html.RegisterHTMLHandler)(adaptor);
73
- var tex = new import_tex.TeX({ packages: import_AllPackages.AllPackages });
74
- var svg = new import_svg.SVG({ fontCache: "local" });
75
- var htmlMathJax = import_mathjax.mathjax.document("", { InputJax: tex, OutputJax: svg });
497
+ var mathConverter = null;
498
+ var mathLoad = null;
499
+ function interop(mod, key) {
500
+ const ns = mod;
501
+ if (typeof ns?.[key] !== "undefined") return ns;
502
+ const fallback = ns?.default;
503
+ if (fallback && typeof fallback[key] !== "undefined") return fallback;
504
+ throw new Error(`mathjax-full module is missing export "${key}"`);
505
+ }
506
+ function preloadMathJax() {
507
+ if (mathLoad) return mathLoad;
508
+ mathLoad = (async () => {
509
+ const [mathjaxMod, texMod, svgMod, adaptorMod, handlerMod, packagesMod] = await Promise.all([
510
+ import("mathjax-full/js/mathjax.js"),
511
+ import("mathjax-full/js/input/tex.js"),
512
+ import("mathjax-full/js/output/svg.js"),
513
+ import("mathjax-full/js/adaptors/liteAdaptor.js"),
514
+ import("mathjax-full/js/handlers/html.js"),
515
+ import("mathjax-full/js/input/tex/AllPackages.js")
516
+ ]);
517
+ const { mathjax } = interop(mathjaxMod, "mathjax");
518
+ const { TeX } = interop(texMod, "TeX");
519
+ const { SVG } = interop(svgMod, "SVG");
520
+ const { liteAdaptor } = interop(adaptorMod, "liteAdaptor");
521
+ const { RegisterHTMLHandler } = interop(handlerMod, "RegisterHTMLHandler");
522
+ const { AllPackages } = interop(packagesMod, "AllPackages");
523
+ const adaptor = liteAdaptor();
524
+ RegisterHTMLHandler(adaptor);
525
+ const tex = new TeX({ packages: AllPackages });
526
+ const svg = new SVG({ fontCache: "local" });
527
+ const htmlMathJax = mathjax.document("", { InputJax: tex, OutputJax: svg });
528
+ mathConverter = (formula, displayMode) => convertMathToSVGDataURI(
529
+ formula,
530
+ displayMode,
531
+ (f, d) => adaptor.innerHTML(htmlMathJax.convert(f, { display: d }))
532
+ );
533
+ })().catch((e) => {
534
+ console.error("MathJax failed to load; formulas will render as TeX source", e);
535
+ });
536
+ return mathLoad;
537
+ }
538
+ function isMathJaxReady() {
539
+ return mathConverter !== null;
540
+ }
541
+ var EX_PER_EM = 0.4421;
542
+ function exToPx(ex, fontSize) {
543
+ return ex * fontSize * EX_PER_EM;
544
+ }
545
+ function fontSizeFromFont(font) {
546
+ const pxIndex = font.indexOf("px");
547
+ if (pxIndex <= 0) return void 0;
548
+ let start = pxIndex;
549
+ while (start > 0) {
550
+ const ch = font[start - 1];
551
+ if (ch >= "0" && ch <= "9" || ch === ".") start--;
552
+ else break;
553
+ }
554
+ if (start === pxIndex) return void 0;
555
+ const size = parseFloat(font.slice(start, pxIndex));
556
+ return Number.isFinite(size) ? size : void 0;
557
+ }
558
+ var mathCache = /* @__PURE__ */ new Map();
559
+ var MATH_CACHE_LIMIT = 256;
560
+ var inlineMathRasters = /* @__PURE__ */ new Map();
561
+ var inlineMathRasterWaiters = /* @__PURE__ */ new Set();
562
+ function ensureInlineMathRaster(uri) {
563
+ const existing = inlineMathRasters.get(uri);
564
+ if (existing) return existing;
565
+ const entry = { decoded: false };
566
+ inlineMathRasters.set(uri, entry);
567
+ if (typeof globalThis.Image !== "undefined") {
568
+ const bitmap = new globalThis.Image();
569
+ bitmap.onload = () => {
570
+ entry.decoded = true;
571
+ for (const notify of inlineMathRasterWaiters) notify();
572
+ };
573
+ bitmap.src = uri;
574
+ entry.bitmap = bitmap;
575
+ }
576
+ return entry;
577
+ }
578
+ function paintInlineMath(uri, surface, box) {
579
+ const raster = ensureInlineMathRaster(uri);
580
+ if (!raster.decoded || !raster.bitmap) return;
581
+ surface.drawImage(raster.bitmap, box.x, box.y, box.width, box.height);
582
+ }
583
+ var MATH_LANGS = /* @__PURE__ */ new Set(["math", "latex", "tex"]);
584
+ function containsInlineMath(token) {
585
+ if (token.type === "inlineMath") return true;
586
+ const anyToken = token;
587
+ if (Array.isArray(anyToken.tokens) && anyToken.tokens.some(containsInlineMath)) {
588
+ return true;
589
+ }
590
+ if (Array.isArray(anyToken.items) && anyToken.items.some(containsInlineMath)) {
591
+ return true;
592
+ }
593
+ if (Array.isArray(anyToken.header) && anyToken.header.some(containsInlineMath)) {
594
+ return true;
595
+ }
596
+ if (Array.isArray(anyToken.rows)) {
597
+ for (const row of anyToken.rows) {
598
+ if (Array.isArray(row) && row.some(containsInlineMath)) return true;
599
+ }
600
+ }
601
+ return false;
602
+ }
603
+ var FENCE_OPEN_RE = /^ {0,3}(`{3,}|~{3,})/;
604
+ var FENCE_CLOSE_RE = /^ {0,3}(`+|~+)[ \t]*$/;
605
+ function isFenceClosed(raw) {
606
+ const lines = raw.split("\n");
607
+ const open = FENCE_OPEN_RE.exec(lines[0]);
608
+ if (!open) return false;
609
+ const marker = open[1][0];
610
+ const minLen = open[1].length;
611
+ for (let i = 1; i < lines.length; i++) {
612
+ const close = FENCE_CLOSE_RE.exec(lines[i]);
613
+ if (close && close[1][0] === marker && close[1].length >= minLen) return true;
614
+ }
615
+ return false;
616
+ }
617
+ function paragraphHasImage(token) {
618
+ return token.tokens?.some((child) => child.type === "image") === true;
619
+ }
620
+ function lastIndexOfImage(tokens) {
621
+ for (let i = tokens.length - 1; i >= 0; i--) {
622
+ if (tokens[i].type === "image") return i;
623
+ }
624
+ return -1;
625
+ }
626
+ function expectedImageParagraphChildren(tokens) {
627
+ let children = 0;
628
+ let inTextRun = false;
629
+ for (const token of tokens) {
630
+ if (token.type === "image") {
631
+ children++;
632
+ inTextRun = false;
633
+ } else if (!inTextRun) {
634
+ children++;
635
+ inTextRun = true;
636
+ }
637
+ }
638
+ return children;
639
+ }
640
+ function rendersAsMath(token) {
641
+ return MATH_LANGS.has((token.lang ?? "").toLowerCase()) && token.text.trim() !== "" && isFenceClosed(token.raw);
642
+ }
76
643
  function renderMathToSVGDataURI(formula, displayMode) {
644
+ const key = `${displayMode ? 1 : 0}\0${formula}`;
645
+ const hit = mathCache.get(key);
646
+ if (hit) return hit;
647
+ if (!mathConverter) return null;
648
+ const converted = mathConverter(formula, displayMode);
649
+ if (converted) {
650
+ if (mathCache.size >= MATH_CACHE_LIMIT) {
651
+ const oldest = mathCache.keys().next().value;
652
+ if (oldest !== void 0) mathCache.delete(oldest);
653
+ }
654
+ mathCache.set(key, converted);
655
+ }
656
+ return converted;
657
+ }
658
+ function convertMathToSVGDataURI(formula, displayMode, typeset) {
77
659
  try {
78
- const node = htmlMathJax.convert(formula, { display: displayMode });
79
- const svgString = adaptor.innerHTML(node);
660
+ const svgString = typeset(formula, displayMode);
80
661
  const wMatch = svgString.match(/width="([^"]+)ex"/);
81
662
  const hMatch = svgString.match(/height="([^"]+)ex"/);
82
663
  const wEx = wMatch ? parseFloat(wMatch[1]) : 10;
83
664
  const hEx = hMatch ? parseFloat(hMatch[1]) : 2;
84
- const width = wEx * 8;
85
- const height = hEx * 8;
665
+ const vMatch = svgString.match(/vertical-align:\s*(-?[\d.]+)ex/);
666
+ const depthEx = vMatch ? Math.max(0, -parseFloat(vMatch[1])) : 0;
86
667
  const base64 = btoa(unescape(encodeURIComponent(svgString)));
87
- return { uri: `data:image/svg+xml;base64,${base64}`, width, height };
668
+ return {
669
+ uri: `data:image/svg+xml;base64,${base64}`,
670
+ widthEx: wEx,
671
+ heightEx: hEx,
672
+ depthEx
673
+ };
88
674
  } catch (e) {
89
675
  console.error("MathJax error", e);
90
676
  return null;
@@ -96,9 +682,10 @@ var workerInstanceCounter = 0;
96
682
  var workerCallbacks = /* @__PURE__ */ new Map();
97
683
  function runSyncFallback(entry) {
98
684
  try {
99
- entry.cb(0, import_marked.marked.lexer(entry.text), true);
685
+ entry.cb(0, lexMarkdown(entry.text, entry.userTiming), true);
100
686
  } catch (err) {
101
687
  console.warn("Markdown sync fallback parse failed", err);
688
+ entry.onDropped?.();
102
689
  }
103
690
  }
104
691
  if (typeof Worker !== "undefined") {
@@ -108,7 +695,7 @@ if (typeof Worker !== "undefined") {
108
695
  });
109
696
  markdownWorker = new Worker(URL.createObjectURL(blob));
110
697
  markdownWorker.onmessage = (e) => {
111
- const { id, matchLen, tail, error, needResync } = e.data;
698
+ const { id, matchLen, tail, error, needResync, lexerMs, sourceCharsLexed } = e.data;
112
699
  const entry = workerCallbacks.get(id);
113
700
  if (entry) {
114
701
  workerCallbacks.delete(id);
@@ -117,7 +704,10 @@ if (typeof Worker !== "undefined") {
117
704
  } else if (needResync) {
118
705
  runSyncFallback(entry);
119
706
  } else if (!error) {
120
- entry.cb(matchLen, tail);
707
+ entry.cb(matchLen, tail, false, {
708
+ lexerMs: typeof lexerMs === "number" ? lexerMs : 0,
709
+ sourceCharsLexed: typeof sourceCharsLexed === "number" ? sourceCharsLexed : 0
710
+ });
121
711
  } else {
122
712
  runSyncFallback(entry);
123
713
  }
@@ -621,13 +1211,13 @@ function codeAtlas() {
621
1211
  function decodeEntities(text) {
622
1212
  return text.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&amp;/g, "&");
623
1213
  }
624
- function collectSpans(tokens, inherited, theme, out) {
1214
+ function collectSpans(tokens, inherited, theme, out, blockFontSize) {
625
1215
  for (const token of tokens) {
626
1216
  switch (token.type) {
627
1217
  case "strong": {
628
1218
  const t = token;
629
1219
  if (t.tokens) {
630
- collectSpans(t.tokens, { ...inherited, bold: true }, theme, out);
1220
+ collectSpans(t.tokens, { ...inherited, bold: true }, theme, out, blockFontSize);
631
1221
  } else {
632
1222
  out.push({
633
1223
  text: decodeEntities(t.text),
@@ -639,7 +1229,7 @@ function collectSpans(tokens, inherited, theme, out) {
639
1229
  case "em": {
640
1230
  const t = token;
641
1231
  if (t.tokens) {
642
- collectSpans(t.tokens, { ...inherited, italic: true }, theme, out);
1232
+ collectSpans(t.tokens, { ...inherited, italic: true }, theme, out, blockFontSize);
643
1233
  } else {
644
1234
  out.push({
645
1235
  text: decodeEntities(t.text),
@@ -675,10 +1265,31 @@ function collectSpans(tokens, inherited, theme, out) {
675
1265
  }
676
1266
  case "inlineMath": {
677
1267
  const t = token;
678
- out.push({
679
- text: decodeEntities(t.raw),
680
- style: { ...inherited, color: "#fcd34d" }
681
- });
1268
+ const runSize = inherited.fontSize ?? blockFontSize ?? theme.fontSize;
1269
+ const rendered = renderMathToSVGDataURI(t.text, false);
1270
+ if (rendered) {
1271
+ const uri = rendered.uri;
1272
+ out.push({
1273
+ text: import_core.OBJECT_REPLACEMENT,
1274
+ style: inherited,
1275
+ object: {
1276
+ width: exToPx(rendered.widthEx, runSize),
1277
+ height: exToPx(rendered.heightEx, runSize),
1278
+ depth: exToPx(rendered.depthEx, runSize),
1279
+ // The TeX source is the accessible name: without it a screen reader
1280
+ // receives only the invisible U+FFFC sentinel.
1281
+ alt: t.text,
1282
+ // Without this the box is reserved and stays empty. The engine does
1283
+ // not draw objects, and nothing else in the tree holds the raster.
1284
+ paint: (surface, box) => paintInlineMath(uri, surface, box)
1285
+ }
1286
+ });
1287
+ } else {
1288
+ out.push({
1289
+ text: decodeEntities(t.raw),
1290
+ style: { ...inherited, color: "#fcd34d" }
1291
+ });
1292
+ }
682
1293
  break;
683
1294
  }
684
1295
  case "link": {
@@ -689,7 +1300,7 @@ function collectSpans(tokens, inherited, theme, out) {
689
1300
  color: "#38bdf8"
690
1301
  };
691
1302
  if (t.tokens && t.tokens.length > 0) {
692
- collectSpans(t.tokens, linkStyle, theme, out);
1303
+ collectSpans(t.tokens, linkStyle, theme, out, blockFontSize);
693
1304
  } else {
694
1305
  out.push({ text: decodeEntities(t.text), style: linkStyle });
695
1306
  }
@@ -698,7 +1309,7 @@ function collectSpans(tokens, inherited, theme, out) {
698
1309
  case "text": {
699
1310
  const t = token;
700
1311
  if ("tokens" in t && t.tokens?.length) {
701
- collectSpans(t.tokens, inherited, theme, out);
1312
+ collectSpans(t.tokens, inherited, theme, out, blockFontSize);
702
1313
  } else {
703
1314
  const decoded = decodeEntities(t.text);
704
1315
  if (decoded) {
@@ -721,10 +1332,37 @@ function collectSpans(tokens, inherited, theme, out) {
721
1332
  }
722
1333
  }
723
1334
  }
1335
+ function findUnclosedInline(text) {
1336
+ let best = null;
1337
+ const tick = text.lastIndexOf("`");
1338
+ if (tick !== -1 && tick < text.length - 1) {
1339
+ return { kind: "codespan", at: tick, contentAt: tick + 1 };
1340
+ }
1341
+ if (tick !== -1) return null;
1342
+ const emphasis = /(\*{1,2}(?!\*)|_{1,2}(?!_))(?=[^\s])/g;
1343
+ for (let match = emphasis.exec(text); match !== null; match = emphasis.exec(text)) {
1344
+ const marker = match[1];
1345
+ const at = match.index;
1346
+ if (marker[0] === "_" && at > 0 && /[\w]/.test(text[at - 1])) continue;
1347
+ best = {
1348
+ kind: marker.length === 2 ? "strong" : "em",
1349
+ at,
1350
+ contentAt: at + marker.length
1351
+ };
1352
+ }
1353
+ const bracket = text.lastIndexOf("[");
1354
+ if (bracket !== -1 && bracket < text.length - 1 && (best === null || bracket > best.at)) {
1355
+ const closed = /\]\([^)]*\)/.test(text.slice(bracket));
1356
+ if (!closed) {
1357
+ best = { kind: "link", at: bracket, contentAt: bracket + 1 };
1358
+ }
1359
+ }
1360
+ return best;
1361
+ }
724
1362
  function renderInlineToRichText(tokens, fallbackText, font, color, maxWidth, theme, selectable, onLinkClick) {
725
1363
  const spans = [];
726
1364
  if (tokens && tokens.length > 0) {
727
- collectSpans(tokens, {}, theme, spans);
1365
+ collectSpans(tokens, {}, theme, spans, fontSizeFromFont(font));
728
1366
  }
729
1367
  if (spans.length === 0) {
730
1368
  spans.push({ text: decodeEntities(fallbackText) });
@@ -744,8 +1382,64 @@ var Markdown = class extends import_ui.UIComponent {
744
1382
  theme;
745
1383
  onLinkClick;
746
1384
  selectable;
1385
+ activeBlockMetrics = null;
1386
+ /**
1387
+ * Called after a streamed append has re-laid-out the document.
1388
+ *
1389
+ * Not required for a `VirtualList` to track a streaming row's height: the list
1390
+ * re-reads `height` on every mounted row each frame, so it sees this entity grow
1391
+ * without being told. Prefer that over wiring this up — it fires from the append
1392
+ * path only, **not** from `setContent()`, so it is not a complete size signal.
1393
+ */
747
1394
  onLayoutUpdated;
748
1395
  rawMarkdown;
1396
+ streamController = null;
1397
+ /**
1398
+ * Trailing-unclosed-syntax policy of the active stream, or `'literal'` when no
1399
+ * stream is open.
1400
+ *
1401
+ * Held here rather than read back off the controller because it is a rendering
1402
+ * concern: `StreamController` owns buffering and pacing and has no view of the
1403
+ * entity tree, while the guess is a transform applied where spans are built.
1404
+ */
1405
+ streamIncompleteMode = "literal";
1406
+ /** End-of-stream callback of the active stream, if it supplied one. */
1407
+ streamOnStable = null;
1408
+ /**
1409
+ * The trailing paragraph entity currently showing an optimistic guess, plus the
1410
+ * token it was rendered from.
1411
+ *
1412
+ * Both halves are needed. The entity is what must be re-rendered to drop the
1413
+ * guess; the token is what it must be re-rendered FROM, and it is the only
1414
+ * copy — `this.tokens` has already moved on by the time an unwind is decided.
1415
+ * `null` means no guess is live, which is the state every `'literal'` stream
1416
+ * and every closed stream stays in.
1417
+ */
1418
+ optimisticTail = null;
1419
+ /** Resolvers waiting for every in-flight worker append to have been applied. */
1420
+ appendSettledWaiters = [];
1421
+ /** True only inside an `onStable` callback, to reject reentrant mutation. */
1422
+ inStableCallback = false;
1423
+ /** Set by {@link destroy} so late settlement work skips a torn-down tree. */
1424
+ isDestroyed = false;
1425
+ /**
1426
+ * This instance's entry in {@link inlineMathRasterWaiters}, or `undefined` if it
1427
+ * has never rendered inline math.
1428
+ *
1429
+ * Subscribed lazily so a document without formulas costs nothing, and held as a
1430
+ * field only so {@link destroy} can remove the exact closure it added.
1431
+ */
1432
+ inlineMathRepaint;
1433
+ /**
1434
+ * True while this document is waiting on the lazy MathJax load.
1435
+ *
1436
+ * Tracked per instance rather than read off the module state because it also
1437
+ * gates settlement: `await close()` and `onStable` must not resolve while a
1438
+ * formula is still showing TeX source, or a caller doing expensive one-time
1439
+ * work on a "final" document would measure and export placeholder boxes.
1440
+ */
1441
+ mathLoadPending = false;
1442
+ _userTiming;
749
1443
  tokens = [];
750
1444
  // At most one worker lex request in flight at a time. Required for the
751
1445
  // delta-transfer protocol below to be safe: the request captures a
@@ -760,19 +1454,38 @@ var Markdown = class extends import_ui.UIComponent {
760
1454
  /**
761
1455
  * Streaming counters for the DevTools inspector.
762
1456
  *
763
- * Cheap enough to keep always-on (four integer increments per append) and the
764
- * only way to see, from outside, whether incremental reuse is actually working:
765
- * a stable-prefix ratio near 1 means the worker is matching almost everything
766
- * and only the tail is re-lexed, while a ratio near 0 means every chunk is
767
- * re-parsing the whole document.
1457
+ * Cheap enough to keep always-on (a handful of integer increments per append).
1458
+ *
1459
+ * These describe the **token diff and the transfer**, not the parser. `marked`
1460
+ * has no incremental lexing API, so the worker calls `marked.lexer()` on the
1461
+ * whole accumulated source for every chunk and the lexer's cost is O(document)
1462
+ * per append no matter how well the diff goes. That is what `lexerMs` and
1463
+ * `sourceCharsLexed` are for; an earlier version of these counters was named as
1464
+ * though a high prefix match meant less lexing, which sent readers to optimise
1465
+ * the already-solved transfer path.
768
1466
  */
769
1467
  streamStats = {
770
1468
  appends: 0,
771
1469
  workerResponses: 0,
772
- /** Sum of `matchLen` across responses, i.e. tokens reused rather than re-lexed. */
773
- tokensReused: 0,
774
- /** Sum of returned tail lengths, i.e. tokens the worker had to re-lex. */
775
- tokensRelexed: 0,
1470
+ /**
1471
+ * Sum of `matchLen`: leading tokens whose `raw` was unchanged, so the main
1472
+ * thread kept its existing token objects and child entities. A prefix match,
1473
+ * not a lexer saving — the worker still lexed them.
1474
+ */
1475
+ tokensPrefixMatched: 0,
1476
+ /**
1477
+ * Sum of returned tail lengths: tokens the worker sent back because their
1478
+ * `raw` differed. This is the structured-clone payload size in tokens, which
1479
+ * is what the delta protocol exists to keep small.
1480
+ */
1481
+ tokensReturned: 0,
1482
+ /** Total ms spent inside `marked.lexer()` across worker responses. */
1483
+ lexerMs: 0,
1484
+ /**
1485
+ * Characters handed to the lexer, summed across responses. Grows ~O(n^2) over
1486
+ * a stream of n chunks, because every chunk re-lexes the whole document.
1487
+ */
1488
+ sourceCharsLexed: 0,
776
1489
  /** Total round-trip ms across worker lex requests, dispatch to callback. */
777
1490
  workerMs: 0,
778
1491
  /** Longest single worker round trip, which is what a dropped frame feels. */
@@ -782,7 +1495,7 @@ var Markdown = class extends import_ui.UIComponent {
782
1495
  * worker matched and did not re-read.
783
1496
  */
784
1497
  stablePrefixChars: 0,
785
- /** Source length of the tail that had to be re-lexed on the most recent append. */
1498
+ /** Source length of the tail whose tokens changed on the most recent append. */
786
1499
  changedTailChars: 0,
787
1500
  /** Child entities kept across reconciles, either untouched or updated in place. */
788
1501
  entitiesReused: 0,
@@ -855,6 +1568,7 @@ var Markdown = class extends import_ui.UIComponent {
855
1568
  this.theme = { ...DEFAULT_THEME, ...opts.theme };
856
1569
  this.onLinkClick = opts.onLinkClick;
857
1570
  this.selectable = opts.selectable ?? true;
1571
+ this._userTiming = opts.userTiming ?? false;
858
1572
  this.content = new import_ui.Stack({ direction: "vertical", gap: 16 });
859
1573
  this.add(this.content);
860
1574
  this.rawMarkdown = markdownText;
@@ -862,7 +1576,7 @@ var Markdown = class extends import_ui.UIComponent {
862
1576
  this.renderMarkdown(markdownText);
863
1577
  }
864
1578
  renderMarkdown(text) {
865
- const tokens = import_marked.marked.lexer(text);
1579
+ const tokens = lexMarkdown(text, this._userTiming);
866
1580
  this.setTokens(tokens);
867
1581
  for (const token of tokens) {
868
1582
  const el = this.renderToken(token);
@@ -873,12 +1587,53 @@ var Markdown = class extends import_ui.UIComponent {
873
1587
  this.width = this.content.width;
874
1588
  this.height = this.content.height;
875
1589
  }
1590
+ /** Create a frame-coalesced stream bound to this Markdown instance. */
1591
+ createStream(options = {}) {
1592
+ if (this.streamController) {
1593
+ throw new Error("Markdown already has an active StreamController");
1594
+ }
1595
+ const controller = createStreamController(
1596
+ {
1597
+ append: (chunk) => this.appendMarkdownCore(chunk),
1598
+ release: (released) => {
1599
+ if (this.streamController !== released) return;
1600
+ this.streamController = null;
1601
+ this.streamIncompleteMode = "literal";
1602
+ this.streamOnStable = null;
1603
+ this.unwindOptimisticTail();
1604
+ },
1605
+ onClose: async () => {
1606
+ await this.waitForAppendSettled();
1607
+ if (this.isDestroyed) return;
1608
+ this.unwindOptimisticTail();
1609
+ const onStable = this.streamOnStable;
1610
+ if (!onStable) return;
1611
+ this.inStableCallback = true;
1612
+ try {
1613
+ onStable(Array.from(this.content.children));
1614
+ } finally {
1615
+ this.inStableCallback = false;
1616
+ }
1617
+ }
1618
+ },
1619
+ options
1620
+ );
1621
+ if (controller.state === "open") {
1622
+ this.streamController = controller;
1623
+ this.streamIncompleteMode = options.incompleteMode ?? "literal";
1624
+ this.streamOnStable = options.onStable ?? null;
1625
+ }
1626
+ return controller;
1627
+ }
876
1628
  /** Replace all markdown content (full rebuild). */
877
1629
  setContent(markdown) {
1630
+ this.assertNotInStableCallback("setContent");
1631
+ this.streamController?.abort(new Error("Markdown content was replaced"));
878
1632
  for (const id of this.pendingWorkerIds) workerCallbacks.delete(id);
879
1633
  this.pendingWorkerIds.clear();
880
1634
  this.appendInFlight = false;
881
1635
  this.appendPending = false;
1636
+ this.flushAppendSettledWaiters();
882
1637
  this.rawMarkdown = markdown;
883
1638
  this.workerSourceLen = 0;
884
1639
  while (this.content.children.length > 0) {
@@ -894,11 +1649,35 @@ var Markdown = class extends import_ui.UIComponent {
894
1649
  * the whole subtree alive until the worker replied), then recurse into the
895
1650
  * content subtree via `super.destroy()` so every block's resources are freed.
896
1651
  */
1652
+ /**
1653
+ * Repaint this document when an inline formula's raster finishes decoding.
1654
+ *
1655
+ * Idempotent — called on every render of a math-bearing token, and the set holds
1656
+ * one closure per instance.
1657
+ */
1658
+ subscribeInlineMathRepaint() {
1659
+ if (this.inlineMathRepaint || this.isDestroyed) return;
1660
+ const repaint = () => {
1661
+ if (this.isDestroyed) return;
1662
+ this.scene?.markDirty();
1663
+ };
1664
+ this.inlineMathRepaint = repaint;
1665
+ inlineMathRasterWaiters.add(repaint);
1666
+ }
897
1667
  destroy() {
1668
+ this.isDestroyed = true;
1669
+ this.optimisticTail = null;
1670
+ this.streamController?.destroy();
898
1671
  for (const id of this.pendingWorkerIds) workerCallbacks.delete(id);
899
1672
  this.pendingWorkerIds.clear();
900
1673
  this.appendInFlight = false;
901
1674
  this.appendPending = false;
1675
+ this.mathLoadPending = false;
1676
+ this.flushAppendSettledWaiters();
1677
+ if (this.inlineMathRepaint) {
1678
+ inlineMathRasterWaiters.delete(this.inlineMathRepaint);
1679
+ this.inlineMathRepaint = void 0;
1680
+ }
902
1681
  markdownWorker?.postMessage({
903
1682
  instance: this.workerInstanceId,
904
1683
  dispose: true
@@ -909,15 +1688,17 @@ var Markdown = class extends import_ui.UIComponent {
909
1688
  * Streaming and parse state — the markdown streaming inspector.
910
1689
  *
911
1690
  * Source length, chunk count, worker in-flight state, and the stable-prefix
912
- * versus re-lexed-tail split. That last ratio is the one worth watching: it is
1691
+ * versus changed-tail split. That last ratio is the one worth watching: it is
913
1692
  * how you tell incremental reuse is working from outside, and nothing else
914
1693
  * surfaces it. A ratio near 1 means the worker matched almost the whole prefix
915
- * and only re-lexed the tail; near 0 means every chunk re-parses the document.
1694
+ * and rebuilt only the tail's entities; near 0 means almost nothing was reused.
1695
+ * Neither says anything about lexer CPU, which is O(document) per append — that
1696
+ * is what the Parser cost group reports.
916
1697
  */
917
1698
  getDevtoolsDescriptor() {
918
1699
  const s = this.streamStats;
919
- const lexed = s.tokensReused + s.tokensRelexed;
920
- const reuseRatio = lexed > 0 ? s.tokensReused / lexed : 0;
1700
+ const diffedTokens = s.tokensPrefixMatched + s.tokensReturned;
1701
+ const tokenPrefixReuseRatio = diffedTokens > 0 ? s.tokensPrefixMatched / diffedTokens : 0;
921
1702
  return {
922
1703
  kind: "Markdown",
923
1704
  groups: [
@@ -989,7 +1770,7 @@ var Markdown = class extends import_ui.UIComponent {
989
1770
  {
990
1771
  label: "changedTailChars",
991
1772
  value: s.changedTailChars,
992
- hint: "Source characters re-lexed on the last append. Growing with the document means O(document) per chunk",
1773
+ hint: "Source characters whose tokens changed on the last append. Growing with the document means the delta is not a delta",
993
1774
  readOnly: true
994
1775
  },
995
1776
  {
@@ -1016,21 +1797,38 @@ var Markdown = class extends import_ui.UIComponent {
1016
1797
  label: "Incremental reuse",
1017
1798
  fields: [
1018
1799
  {
1019
- label: "tokensReused",
1020
- value: s.tokensReused,
1021
- hint: "Sum of matchLen: prefix tokens the worker matched and did not re-lex",
1800
+ label: "tokensPrefixMatched",
1801
+ value: s.tokensPrefixMatched,
1802
+ hint: "Sum of matchLen: leading tokens whose raw was unchanged, so their entities were kept",
1022
1803
  readOnly: true
1023
1804
  },
1024
1805
  {
1025
- label: "tokensRelexed",
1026
- value: s.tokensRelexed,
1027
- hint: "Sum of returned tail lengths: tokens the worker had to re-lex",
1806
+ label: "tokensReturned",
1807
+ value: s.tokensReturned,
1808
+ hint: "Sum of returned tail lengths: the changed suffix the worker cloned back",
1028
1809
  readOnly: true
1029
1810
  },
1030
1811
  {
1031
- label: "reuseRatio",
1032
- value: Math.round(reuseRatio * 1e3) / 1e3,
1033
- hint: "reused / (reused + relexed). Near 1 is healthy; near 0 means no reuse",
1812
+ label: "tokenPrefixReuseRatio",
1813
+ value: Math.round(tokenPrefixReuseRatio * 1e3) / 1e3,
1814
+ hint: "matched / (matched + returned). Near 1 means small transfers and high entity reuse \u2014 NOT less lexing",
1815
+ readOnly: true
1816
+ }
1817
+ ]
1818
+ },
1819
+ {
1820
+ label: "Parser cost",
1821
+ fields: [
1822
+ {
1823
+ label: "lexerMs",
1824
+ value: Math.round(s.lexerMs * 10) / 10,
1825
+ hint: "Total ms inside marked.lexer() \u2014 the whole source, every append",
1826
+ readOnly: true
1827
+ },
1828
+ {
1829
+ label: "sourceCharsLexed",
1830
+ value: s.sourceCharsLexed,
1831
+ hint: "Characters lexed, summed over appends. Grows ~O(n^2) across a stream",
1034
1832
  readOnly: true
1035
1833
  }
1036
1834
  ]
@@ -1038,13 +1836,22 @@ var Markdown = class extends import_ui.UIComponent {
1038
1836
  ],
1039
1837
  notes: s.workerResponses === 0 && s.appends > 0 ? [
1040
1838
  "No worker responses yet: either the worker is unavailable and parsing ran synchronously on the main thread, or the first request is still in flight."
1041
- ] : reuseRatio > 0 && reuseRatio < 0.5 ? [
1042
- `Only ${Math.round(reuseRatio * 100)}% of lexed tokens were reused, so most of the document is being re-lexed per chunk. Expect O(document) work per append.`
1839
+ ] : tokenPrefixReuseRatio > 0 && tokenPrefixReuseRatio < 0.5 ? [
1840
+ `Only ${Math.round(tokenPrefixReuseRatio * 100)}% of tokens matched the prior prefix, so most of the token array is being returned and its entities rebuilt every chunk. Note the LEXER is O(document) per append regardless \u2014 see lexerMs.`
1043
1841
  ] : s.changedTailChars > 0 && this.rawMarkdown.length > 0 && s.changedTailChars / this.rawMarkdown.length > 0.5 ? [
1044
- `The last append re-lexed ${s.changedTailChars} of ${this.rawMarkdown.length} characters. A tail that grows with the document is the O(document)-per-chunk shape, even when the token reuse ratio looks healthy.`
1842
+ `The last append changed ${s.changedTailChars} of ${this.rawMarkdown.length} characters. A changed tail that grows with the document means the delta is not a delta, so almost every entity is rebuilt per chunk.`
1045
1843
  ] : void 0
1046
1844
  };
1047
1845
  }
1846
+ /** Enable or disable User Timing for subsequent parses. */
1847
+ setUserTiming(enabled) {
1848
+ this._userTiming = enabled;
1849
+ return this;
1850
+ }
1851
+ /** Whether Markdown parse User Timing is enabled. */
1852
+ get userTiming() {
1853
+ return this._userTiming;
1854
+ }
1048
1855
  /** Enable or disable native selection for existing and future Markdown text. */
1049
1856
  setSelectable(selectable) {
1050
1857
  this.selectable = selectable;
@@ -1059,11 +1866,16 @@ var Markdown = class extends import_ui.UIComponent {
1059
1866
  }
1060
1867
  /** Append a markdown chunk incrementally. Reuses unchanged prefix entities. */
1061
1868
  appendMarkdown(chunk) {
1869
+ this.assertNotInStableCallback("appendMarkdown");
1870
+ this.streamController?.flush();
1871
+ return this.appendMarkdownCore(chunk);
1872
+ }
1873
+ appendMarkdownCore(chunk) {
1062
1874
  this.rawMarkdown += chunk;
1063
1875
  this.streamStats.appends++;
1064
1876
  if (!markdownWorker) {
1065
1877
  this.workerSourceLen = 0;
1066
- const newTokens = import_marked.marked.lexer(this.rawMarkdown);
1878
+ const newTokens = lexMarkdown(this.rawMarkdown, this._userTiming);
1067
1879
  this.updateTokens(newTokens);
1068
1880
  return this;
1069
1881
  }
@@ -1099,11 +1911,15 @@ var Markdown = class extends import_ui.UIComponent {
1099
1911
  const canSendDelta = !resync && this.workerSourceLen > 0 && this.workerSourceLen <= sentLength;
1100
1912
  this.pendingWorkerIds.add(id);
1101
1913
  workerCallbacks.set(id, {
1102
- cb: (matchLen, tail, local = false) => {
1914
+ cb: (matchLen, tail, local = false, lex) => {
1103
1915
  this.pendingWorkerIds.delete(id);
1104
1916
  this.streamStats.workerResponses++;
1105
- this.streamStats.tokensReused += matchLen;
1106
- this.streamStats.tokensRelexed += tail.length;
1917
+ this.streamStats.tokensPrefixMatched += matchLen;
1918
+ this.streamStats.tokensReturned += tail.length;
1919
+ if (lex) {
1920
+ this.streamStats.lexerMs += lex.lexerMs;
1921
+ this.streamStats.sourceCharsLexed += lex.sourceCharsLexed;
1922
+ }
1107
1923
  const elapsed = now() - dispatchedAt;
1108
1924
  this.streamStats.workerMs += elapsed;
1109
1925
  if (elapsed > this.streamStats.workerMsMax) this.streamStats.workerMsMax = elapsed;
@@ -1119,6 +1935,7 @@ var Markdown = class extends import_ui.UIComponent {
1119
1935
  this.appendPending = false;
1120
1936
  this.dispatchAppend();
1121
1937
  }
1938
+ this.flushAppendSettledWaiters();
1122
1939
  },
1123
1940
  // The worker can't trust what it holds for this request; retry it once with
1124
1941
  // the full text and raws attached. `this.tokens` is untouched (no
@@ -1129,12 +1946,28 @@ var Markdown = class extends import_ui.UIComponent {
1129
1946
  this.workerSourceLen = 0;
1130
1947
  this.dispatchAppend(true);
1131
1948
  },
1132
- text: this.rawMarkdown
1949
+ // Neither the worker nor the fallback lexer could produce tokens for this
1950
+ // request, so `this.tokens` stays as it was. Only the in-flight bookkeeping
1951
+ // needs unwinding — including any coalesced chunk waiting behind it, which
1952
+ // still has to be attempted.
1953
+ onDropped: () => {
1954
+ this.pendingWorkerIds.delete(id);
1955
+ this.appendInFlight = false;
1956
+ this.workerSourceLen = 0;
1957
+ if (this.appendPending) {
1958
+ this.appendPending = false;
1959
+ this.dispatchAppend(true);
1960
+ }
1961
+ this.flushAppendSettledWaiters();
1962
+ },
1963
+ text: this.rawMarkdown,
1964
+ userTiming: this._userTiming
1133
1965
  });
1134
1966
  markdownWorker.postMessage({
1135
1967
  id,
1136
1968
  instance: this.workerInstanceId,
1137
1969
  baseVersion,
1970
+ userTimingName: this._userTiming ? import_core.VECTO_USER_TIMING.markdown.parse : void 0,
1138
1971
  ...canSendDelta ? {
1139
1972
  append: this.rawMarkdown.slice(this.workerSourceLen),
1140
1973
  // What the worker's source must total once it applies this append. It
@@ -1148,6 +1981,647 @@ var Markdown = class extends import_ui.UIComponent {
1148
1981
  }
1149
1982
  });
1150
1983
  }
1984
+ /**
1985
+ * Spans for one paragraph token exactly as `marked` produced it.
1986
+ *
1987
+ * The literal baseline: what every release renders, and what an optimistic
1988
+ * guess is unwound back to.
1989
+ */
1990
+ literalParagraphSpans(token) {
1991
+ const spans = [];
1992
+ if (token.tokens && token.tokens.length > 0) {
1993
+ collectSpans(token.tokens, {}, this.theme, spans);
1994
+ }
1995
+ if (spans.length === 0) spans.push({ text: token.text });
1996
+ return spans;
1997
+ }
1998
+ /**
1999
+ * Update a reused blockquote's tail child in place, or report that it cannot be.
2000
+ *
2001
+ * The render arm builds `container[border, innerStack]` where every inner block
2002
+ * sits in its own single-child `wrapper`, so the tail entity is
2003
+ * `innerStack.children.at(-1).children[0]`. Only the LAST inner block may be
2004
+ * updated: the inner token list is prefix-stable exactly like the top level (a
2005
+ * growing quote keeps its earlier blocks byte-identical), so anything before the
2006
+ * tail is untouched and anything more complicated than a changed tail falls back
2007
+ * to the caller's rebuild.
2008
+ *
2009
+ * Returns `false` without mutating anything when the shape is not the simple
2010
+ * grow-the-tail case, which is the signal for the caller to rebuild. Every early
2011
+ * return has to leave the entity untouched, or a rejected reuse would leave a
2012
+ * half-updated quote on screen.
2013
+ */
2014
+ /**
2015
+ * Build one list item's spans: inline content plus its marker.
2016
+ *
2017
+ * Shared by the `list` render arm and the streamed-reuse path below, because
2018
+ * the two must produce byte-identical spans — a reused list that disagreed with
2019
+ * a rebuilt one about its marker or its entity decoding would make a streamed
2020
+ * document differ from the same source pasted at once.
2021
+ */
2022
+ /**
2023
+ * Inline spans for one table cell.
2024
+ *
2025
+ * Always returns at least one span. A cell whose markup collapses to nothing —
2026
+ * an empty cell, but also a bare `<span>`, an image, or an HTML comment, none
2027
+ * of which `collectSpans` emits for — falls back to its decoded source text,
2028
+ * which is what the previous string-returning path rendered. That guarantee is
2029
+ * what lets every cell be a `RichText`: an empty cell would otherwise become a
2030
+ * `Text`, and since `Text` has `setText` while `RichText` has `setSpans` and
2031
+ * nothing converts between them, a cell that starts empty and later gains
2032
+ * content could not be updated in place. A streamed table needs exactly that,
2033
+ * because `marked` materializes a partial row as a full row of empty cells and
2034
+ * then fills them one at a time.
2035
+ */
2036
+ tableCellSpans(cell, t) {
2037
+ const spans = [];
2038
+ collectSpans(cell.tokens, {}, t, spans);
2039
+ if (spans.length === 0) spans.push({ text: decodeEntities(cell.text) });
2040
+ return spans;
2041
+ }
2042
+ /**
2043
+ * Spans for one run of consecutive non-image inline tokens.
2044
+ *
2045
+ * A paragraph holding an image renders as a `Stack` of alternating text runs
2046
+ * and images, and this is one text run. Shared by the render arm and
2047
+ * {@link updateImageParagraph} so a reused run cannot drift from a rebuilt one.
2048
+ *
2049
+ * The empty fallback mirrors `renderInlineToRichText('', …)`, which the render
2050
+ * arm passed for these runs: a run is only created when it has at least one
2051
+ * token, so the fallback is for tokens that emit no spans at all rather than
2052
+ * for an empty run.
2053
+ */
2054
+ inlineRunSpans(tokens, t) {
2055
+ const spans = [];
2056
+ if (tokens.length > 0) collectSpans(tokens, {}, t, spans);
2057
+ if (spans.length === 0) spans.push({ text: "" });
2058
+ return spans;
2059
+ }
2060
+ /** One text run of an image-bearing paragraph, as both paths build it. */
2061
+ inlineRunRichText(tokens, availableWidth, t) {
2062
+ return new import_ui.RichText(this.inlineRunSpans(tokens, t), {
2063
+ font: `${t.fontSize}px ${t.bodyFont}`,
2064
+ color: t.textColor,
2065
+ maxWidth: availableWidth,
2066
+ linkColor: "#38bdf8",
2067
+ selectable: this.selectable,
2068
+ onLinkClick: this.onLinkClick
2069
+ });
2070
+ }
2071
+ /**
2072
+ * One image inside a paragraph, sized by a guess until its bitmap decodes.
2073
+ *
2074
+ * Width and height start at a 16:10 guess because the intrinsic size is not
2075
+ * known until the browser has the bitmap; `onLoad` corrects both from
2076
+ * `naturalWidth`/`naturalHeight`. Extracted from the render arm so the streamed
2077
+ * path reuses this exact entity rather than constructing a second variant.
2078
+ *
2079
+ * `markDirty()` is unconditional, matching the display-math sibling. It used
2080
+ * to sit inside the `naturalWidth && naturalHeight` check, which meant a
2081
+ * source that loads successfully while reporting a zero dimension left the
2082
+ * scene un-notified. `Image` sets `loaded` before invoking this callback, so
2083
+ * its `render()` starts drawing the bitmap either way — the cost was not a
2084
+ * stale placeholder but a box frozen at the guess: measured on Chromium and
2085
+ * Firefox, an `<svg width="0" height="0">` paragraph image kept 800x480 of
2086
+ * reserved layout forever while a normal raster corrected to 80x60. An
2087
+ * `onDemand` scene repaints only when marked, so nothing reclaimed it.
2088
+ *
2089
+ * The box is deliberately left at the guess when the bitmap reports zero.
2090
+ * Collapsing it to 0x0 would make the paragraph reflow correctly but would
2091
+ * also silently delete a reserved region on the strength of one browser
2092
+ * quirk, and `Image.render()` still blits whatever the bitmap holds. Sizing
2093
+ * policy for a zero-dimension source is a separate decision from notifying
2094
+ * the scene, which is the actual defect here.
2095
+ */
2096
+ paragraphImage(imgToken, availableWidth) {
2097
+ const initialWidth = Math.min(800, availableWidth);
2098
+ const initialHeight = Math.round(initialWidth * 0.6);
2099
+ const img = new import_ui.Image(imgToken.href, {
2100
+ width: initialWidth,
2101
+ height: initialHeight,
2102
+ alt: imgToken.text,
2103
+ radius: 8,
2104
+ onLoad: () => {
2105
+ const bmp = img.bitmap;
2106
+ if (bmp && bmp.naturalWidth && bmp.naturalHeight) {
2107
+ const aspect = bmp.naturalHeight / bmp.naturalWidth;
2108
+ img.width = Math.min(bmp.naturalWidth, availableWidth);
2109
+ img.height = Math.round(img.width * aspect);
2110
+ }
2111
+ this.scene?.markDirty();
2112
+ }
2113
+ });
2114
+ return img;
2115
+ }
2116
+ /** One table cell entity, shared by the render arm and the streamed-table path. */
2117
+ tableCellRichText(cell, header, t) {
2118
+ return new import_ui.RichText(this.tableCellSpans(cell, t), {
2119
+ font: `${t.fontSize - 2}px ${t.bodyFont}`,
2120
+ color: header ? t.headingColor : t.textColor,
2121
+ baseStyle: header ? { bold: true } : void 0,
2122
+ linkColor: "#38bdf8",
2123
+ selectable: this.selectable,
2124
+ onLinkClick: this.onLinkClick
2125
+ });
2126
+ }
2127
+ listItemSpans(token, index) {
2128
+ const item = token.items[index];
2129
+ const num = Number(token.start ?? 1) + index;
2130
+ const contentSpans = [];
2131
+ if (item.tokens && item.tokens.length > 0) {
2132
+ for (const inner of item.tokens) {
2133
+ if (inner.type === "text" && "tokens" in inner && inner.tokens?.length) {
2134
+ collectSpans(
2135
+ inner.tokens,
2136
+ {},
2137
+ this.theme,
2138
+ contentSpans
2139
+ );
2140
+ } else if ("tokens" in inner && inner.tokens?.length) {
2141
+ collectSpans(
2142
+ inner.tokens,
2143
+ {},
2144
+ this.theme,
2145
+ contentSpans
2146
+ );
2147
+ } else if ("text" in inner) {
2148
+ contentSpans.push({ text: decodeEntities(inner.text) });
2149
+ }
2150
+ }
2151
+ } else {
2152
+ contentSpans.push({ text: decodeEntities(item.text) });
2153
+ }
2154
+ const itemIsRtl = import_core.BidiResolver.getBaseLevel(contentSpans.map((s) => s.text).join("")) % 2 === 1;
2155
+ return itemIsRtl ? [...contentSpans, { text: token.ordered ? ` .${num}` : " \u2022" }] : [{ text: token.ordered ? `${num}. ` : "\u2022 " }, ...contentSpans];
2156
+ }
2157
+ /** Construct the `RichText` for one list item. */
2158
+ listItemRichText(token, index, availableWidth, t) {
2159
+ return new import_ui.RichText(this.listItemSpans(token, index), {
2160
+ font: `${t.fontSize}px ${t.bodyFont}`,
2161
+ color: t.textColor,
2162
+ maxWidth: availableWidth,
2163
+ linkColor: "#38bdf8",
2164
+ selectable: this.selectable,
2165
+ onLinkClick: this.onLinkClick
2166
+ });
2167
+ }
2168
+ /**
2169
+ * Reuse a streamed list's `Stack` instead of rebuilding every item.
2170
+ *
2171
+ * Returns `false` to mean "rebuild instead", exactly like
2172
+ * {@link updateBlockquoteTail}, and every rejection path leaves the entity
2173
+ * untouched so a refused reuse cannot leave a half-updated list on screen.
2174
+ *
2175
+ * This is the shape a stream actually produces: items are APPENDED, and only
2176
+ * the last one grows. That matters for the ordinal marker, which is
2177
+ * position-derived (`start + index`) — under append an already-rendered item's
2178
+ * index never changes, so its marker stays correct. A mid-list insertion would
2179
+ * shift every later ordinal, but no stream produces one.
2180
+ *
2181
+ * Two traps this guards, both found by probing marked 18.0.7 rather than by
2182
+ * reading:
2183
+ *
2184
+ * - **A retained item's `raw` is NOT stable.** `items[1].raw` goes `"- two"` ->
2185
+ * `"- two\\n"` when item 3 arrives, so a byte-equality guard on `raw` fails on
2186
+ * every chunk and the fast path would never fire. `text` is stable; compare
2187
+ * that.
2188
+ * - **A tight list can become loose.** Adding a blank line flips
2189
+ * `token.loose`, which re-lexes every item's children from `text` to
2190
+ * `paragraph`. Item 0's own `text` is unchanged, so a naive guard would reuse
2191
+ * and keep stale spans. Bail when `loose` flips.
2192
+ */
2193
+ updateStreamedList(stack, oldToken, newToken) {
2194
+ if (!(stack instanceof import_ui.Stack)) return false;
2195
+ if (newToken.items.length < oldToken.items.length || oldToken.items.length === 0) return false;
2196
+ if (oldToken.ordered !== newToken.ordered) return false;
2197
+ if ((oldToken.start ?? 1) !== (newToken.start ?? 1)) return false;
2198
+ if (oldToken.loose !== newToken.loose) return false;
2199
+ if (stack.children.length !== oldToken.items.length) return false;
2200
+ const lastRetained = oldToken.items.length - 1;
2201
+ for (let i = 0; i < lastRetained; i++) {
2202
+ if (oldToken.items[i].text !== newToken.items[i].text) return false;
2203
+ }
2204
+ const availableWidth = this.activeBlockMetrics?.availableWidth ?? this.maxWidth;
2205
+ const t = this.theme;
2206
+ const tailEntity = stack.children[lastRetained];
2207
+ if (oldToken.items[lastRetained].text !== newToken.items[lastRetained].text) {
2208
+ if (!("setSpans" in tailEntity)) return false;
2209
+ tailEntity.setSpans(
2210
+ this.listItemSpans(newToken, lastRetained)
2211
+ );
2212
+ }
2213
+ for (let i = oldToken.items.length; i < newToken.items.length; i++) {
2214
+ stack.add(this.listItemRichText(newToken, i, availableWidth, t));
2215
+ }
2216
+ const last = stack.children.at(-1);
2217
+ if (last) stack.resizeLastChild(last);
2218
+ return true;
2219
+ }
2220
+ /**
2221
+ * Reuse a streamed image-bearing paragraph's `Stack` instead of rebuilding it.
2222
+ *
2223
+ * Returns `false` to mean "rebuild instead", and every rejection happens before
2224
+ * any mutation, so a refused reuse leaves the entity exactly as it was.
2225
+ *
2226
+ * This was the last silent fallthrough in the in-place reuse path. A paragraph
2227
+ * holding an image renders as a `Stack` of alternating text runs and images
2228
+ * rather than one `RichText`, so it has no `setSpans` and failed the ordinary
2229
+ * paragraph gate — with no `else`, which is what made the miss invisible:
2230
+ * `inPlaceUpdates` stayed flat while `entitiesRebuilt` climbed. Measured on a
2231
+ * six-chunk stream, `inPlaceUpdates` 0 / `entitiesRebuilt` 4 with an image
2232
+ * against 4 / 0 for the identical shape without one. Every rebuild also
2233
+ * re-created the `Image`, discarding its decoded bitmap and its corrected
2234
+ * intrinsic size.
2235
+ *
2236
+ * It is *only* a performance path. The obvious worry — that a fresh `Image`
2237
+ * starts at `loaded = false` and so repaints its placeholder slab — was
2238
+ * measured and does not happen: sampling the real canvas pixel at the image
2239
+ * centre in both Chromium and Firefox gives zero placeholder frames after the
2240
+ * first paint, at 60ms and at 0ms between chunks, because a cached bitmap
2241
+ * decodes before the next frame.
2242
+ *
2243
+ * The reuse is deliberately narrow: **only a growing trailing text run**. Probed
2244
+ * against `marked@18.0.7`, that is the shape a stream actually produces once an
2245
+ * image has closed — the image token's `raw` and its index are then stable while
2246
+ * trailing prose grows, and the token list settles at
2247
+ * `[…, image, text]` and stops changing length. Anything else (a new image
2248
+ * arriving, an image token changing, a run appearing before the last image)
2249
+ * falls through to the rebuild, which is correct and rare.
2250
+ *
2251
+ * Note the child list is not one entity per token: consecutive non-image tokens
2252
+ * are merged into one `RichText` by the render arm's `flushText`, so
2253
+ * `[text, text, image]` is two children, not three. The guards therefore compare
2254
+ * *token runs* split at the last image, never token index against child index.
2255
+ */
2256
+ updateImageParagraph(entity, oldToken, newToken) {
2257
+ if (!(entity instanceof import_ui.Stack)) return false;
2258
+ const oldTokens = oldToken.tokens;
2259
+ const newTokens = newToken.tokens;
2260
+ if (!oldTokens || !newTokens) return false;
2261
+ const oldLastImage = lastIndexOfImage(oldTokens);
2262
+ const newLastImage = lastIndexOfImage(newTokens);
2263
+ if (oldLastImage < 0 || newLastImage < 0) return false;
2264
+ if (oldLastImage !== newLastImage) return false;
2265
+ for (let i = 0; i <= newLastImage; i++) {
2266
+ if (oldTokens[i].raw !== newTokens[i].raw) return false;
2267
+ }
2268
+ const oldTail = oldTokens.slice(oldLastImage + 1);
2269
+ const newTail = newTokens.slice(newLastImage + 1);
2270
+ if (newTail.length === 0) return false;
2271
+ const oldTailRaw = oldTail.map((t2) => t2.raw).join("");
2272
+ const newTailRaw = newTail.map((t2) => t2.raw).join("");
2273
+ if (!newTailRaw.startsWith(oldTailRaw)) return false;
2274
+ const expectedOldChildren = expectedImageParagraphChildren(oldTokens);
2275
+ if (entity.children.length !== expectedOldChildren) return false;
2276
+ const t = this.theme;
2277
+ const availableWidth = this.activeBlockMetrics?.availableWidth ?? this.maxWidth;
2278
+ if (oldTail.length === 0) {
2279
+ entity.add(this.inlineRunRichText(newTail, availableWidth, t));
2280
+ } else {
2281
+ const tailEntity = entity.children[entity.children.length - 1];
2282
+ if (!(tailEntity instanceof import_ui.RichText)) return false;
2283
+ tailEntity.setSpans(this.inlineRunSpans(newTail, t));
2284
+ }
2285
+ const last = entity.children[entity.children.length - 1];
2286
+ if (last) entity.resizeLastChild(last);
2287
+ return true;
2288
+ }
2289
+ /**
2290
+ * Reuse a streamed table's `Table` entity instead of rebuilding every cell.
2291
+ *
2292
+ * Returns `false` to mean "rebuild instead", and every rejection happens before
2293
+ * any mutation, so a refused reuse leaves the entity exactly as it was.
2294
+ *
2295
+ * A `table` token carries every row, so the rebuild path costs Θ(C·N²)
2296
+ * `RichText` constructions across a stream — and a further 2×, because
2297
+ * `Table.layout()` re-runs `fitCell` on every cell. This was the last block
2298
+ * type without an in-place path.
2299
+ *
2300
+ * Two shapes have to be handled, because of how `marked` lexes a growing table
2301
+ * (probed against 18.0.7): a partial row is materialized immediately as a FULL
2302
+ * row padded with empty cells, and its cells are then filled one at a time. A
2303
+ * 2×2 table passes through eleven distinct row states, of which only two are
2304
+ * clean row appends. So handling appends alone would reject most chunks and
2305
+ * leave the quadratic cost essentially in place:
2306
+ *
2307
+ * 1. the last row's cells are rewritten in place via `setSpans`, and
2308
+ * 2. genuinely new rows go through `Table.appendRows`.
2309
+ *
2310
+ * Cells are compared by `text`, never `raw` — a table cell has no `raw` at all
2311
+ * (its keys are `text`/`tokens`/`header`/`align`).
2312
+ */
2313
+ updateStreamedTable(entity, oldToken, newToken) {
2314
+ if (!(entity instanceof import_ui.Table)) return false;
2315
+ if (oldToken.header.length !== newToken.header.length) return false;
2316
+ for (let c = 0; c < oldToken.header.length; c++) {
2317
+ if (oldToken.header[c].text !== newToken.header[c].text) return false;
2318
+ }
2319
+ if (newToken.rows.length < oldToken.rows.length) return false;
2320
+ if (entity.rows.length !== oldToken.rows.length) return false;
2321
+ const lastRetained = oldToken.rows.length - 1;
2322
+ for (let r = 0; r < lastRetained; r++) {
2323
+ const oldRow = oldToken.rows[r];
2324
+ const newRow = newToken.rows[r];
2325
+ for (let c = 0; c < oldToken.header.length; c++) {
2326
+ if (oldRow[c]?.text !== newRow[c]?.text) return false;
2327
+ }
2328
+ }
2329
+ if (lastRetained >= 0) {
2330
+ for (let c = 0; c < oldToken.header.length; c++) {
2331
+ const cell = entity.rows[lastRetained]?.[c];
2332
+ if (!(cell instanceof import_ui.RichText)) return false;
2333
+ }
2334
+ }
2335
+ const t = this.theme;
2336
+ let changed = false;
2337
+ if (lastRetained >= 0) {
2338
+ const oldRow = oldToken.rows[lastRetained];
2339
+ const newRow = newToken.rows[lastRetained];
2340
+ for (let c = 0; c < oldToken.header.length; c++) {
2341
+ if (oldRow[c]?.text === newRow[c]?.text) continue;
2342
+ const cell = entity.rows[lastRetained][c];
2343
+ cell.setSpans(this.tableCellSpans(newRow[c], t));
2344
+ changed = true;
2345
+ }
2346
+ }
2347
+ if (newToken.rows.length > oldToken.rows.length) {
2348
+ const added = newToken.rows.slice(oldToken.rows.length).map((row) => row.map((cell) => this.tableCellRichText(cell, false, t)));
2349
+ entity.appendRows(added);
2350
+ } else if (changed) {
2351
+ entity.layout();
2352
+ }
2353
+ return true;
2354
+ }
2355
+ updateBlockquoteTail(container, oldInner, newInner) {
2356
+ if (oldInner.length !== newInner.length || newInner.length === 0) return false;
2357
+ const tail = newInner.length - 1;
2358
+ for (let i = 0; i < tail; i++) {
2359
+ if (oldInner[i].raw !== newInner[i].raw) return false;
2360
+ }
2361
+ const oldTail = oldInner[tail];
2362
+ const newTail = newInner[tail];
2363
+ if (oldTail.type !== newTail.type) return false;
2364
+ const innerStack = container.children[1];
2365
+ if (!(innerStack instanceof import_ui.Stack)) return false;
2366
+ const wrapper = innerStack.children.at(-1);
2367
+ if (!wrapper || wrapper.children.length !== 1) return false;
2368
+ const entity = wrapper.children[0];
2369
+ if (!this.producesEntity(newTail)) return false;
2370
+ if (newTail.type === "paragraph" && "setSpans" in entity) {
2371
+ entity.setSpans(
2372
+ this.literalParagraphSpans(newTail)
2373
+ );
2374
+ } else if (newTail.type === "heading" && "setSpans" in entity) {
2375
+ if (oldTail.depth !== newTail.depth) {
2376
+ return false;
2377
+ }
2378
+ entity.setSpans(
2379
+ this.headingSpans(newTail)
2380
+ );
2381
+ } else if (newTail.type === "code" && entity instanceof CodeBlock && !rendersAsMath(newTail)) {
2382
+ const codeToken = newTail;
2383
+ entity.setCode(codeToken.text, codeToken.lang ?? void 0);
2384
+ } else {
2385
+ return false;
2386
+ }
2387
+ wrapper.width = entity.x + entity.width;
2388
+ wrapper.height = entity.height;
2389
+ innerStack.resizeLastChild(wrapper);
2390
+ const border = container.children[0];
2391
+ if (border instanceof QuoteBorder) border.height = innerStack.height || 20;
2392
+ container.height = Math.max(border?.height ?? 0, innerStack.height);
2393
+ return true;
2394
+ }
2395
+ /**
2396
+ * Spans for a heading being updated in place.
2397
+ *
2398
+ * Kept in lockstep with the `heading` arm of {@link renderToken}, which builds
2399
+ * its `RichText` through `renderInlineToRichText`: same `collectSpans` call and
2400
+ * the same `decodeEntities` fallback when a heading has no inline tokens (`##`
2401
+ * with no text yet, which a stream produces before its first word arrives). A
2402
+ * plain `token.text` fallback here would leave an entity-bearing heading
2403
+ * undecoded on the in-place path but decoded on a fresh render.
2404
+ */
2405
+ headingSpans(token) {
2406
+ const spans = [];
2407
+ if (token.tokens && token.tokens.length > 0) {
2408
+ collectSpans(token.tokens, {}, this.theme, spans);
2409
+ }
2410
+ if (spans.length === 0) spans.push({ text: decodeEntities(token.text) });
2411
+ return spans;
2412
+ }
2413
+ /**
2414
+ * Spans for the trailing paragraph with its last unclosed inline construct
2415
+ * rendered as though it had closed, or `null` when there is nothing to guess.
2416
+ *
2417
+ * `null` is the answer for every `'literal'` stream, every closed or absent
2418
+ * stream, and any trailing paragraph whose syntax is all balanced — so the
2419
+ * caller falls back to {@link literalParagraphSpans} and pays nothing.
2420
+ *
2421
+ * Only the paragraph's LAST inline token is scanned. An unclosed construct can
2422
+ * only be there: anything that closed is already its own `strong`/`em`/
2423
+ * `codespan`/`link` token, so a syntax character surviving into a trailing
2424
+ * plain-text run is one `marked` could not pair. Scanning the whole raw string
2425
+ * instead would re-find the markers of already-closed constructs.
2426
+ */
2427
+ optimisticParagraphSpans(token) {
2428
+ if (this.streamIncompleteMode !== "optimistic") return null;
2429
+ if (this.streamController?.state !== "open") return null;
2430
+ const inline = token.tokens;
2431
+ if (!inline || inline.length === 0) return null;
2432
+ let runLength = 1;
2433
+ let runText;
2434
+ const last = inline[inline.length - 1];
2435
+ const prev = inline.length > 1 ? inline[inline.length - 2] : null;
2436
+ const isFlatText = (token2) => token2.type === "text" && !token2.tokens?.length;
2437
+ if (last.type === "link" && last.raw === last.text && prev !== null && isFlatText(prev) && prev.text.endsWith("](")) {
2438
+ runLength = 2;
2439
+ runText = prev.text + last.raw;
2440
+ } else if (isFlatText(last)) {
2441
+ runText = last.text;
2442
+ } else {
2443
+ return null;
2444
+ }
2445
+ const found = findUnclosedInline(runText);
2446
+ if (!found) return null;
2447
+ const spans = [];
2448
+ if (inline.length > runLength) {
2449
+ collectSpans(inline.slice(0, -runLength), {}, this.theme, spans);
2450
+ }
2451
+ const head = runText.slice(0, found.at);
2452
+ if (head) spans.push({ text: decodeEntities(head) });
2453
+ let content = runText.slice(found.contentAt);
2454
+ if (found.kind === "link") {
2455
+ const close = content.indexOf("](");
2456
+ if (close !== -1) content = content.slice(0, close);
2457
+ }
2458
+ if (!content) return null;
2459
+ const style = this.optimisticStyle(found.kind);
2460
+ spans.push({ text: decodeEntities(content), style });
2461
+ return spans;
2462
+ }
2463
+ /** Display style for a guessed-closed construct. */
2464
+ optimisticStyle(kind) {
2465
+ switch (kind) {
2466
+ case "strong":
2467
+ return { bold: true };
2468
+ case "em":
2469
+ return { italic: true };
2470
+ case "codespan":
2471
+ return { color: this.theme.codeColor, fontFamily: this.theme.codeFont };
2472
+ // A link with no closing paren has no href, so it renders as plain text —
2473
+ // no link color and no click affordance for a destination nobody has yet.
2474
+ case "link":
2475
+ return void 0;
2476
+ }
2477
+ }
2478
+ /**
2479
+ * Re-render the paragraph currently showing a guess from its own tokens, with
2480
+ * no overlay, and forget it.
2481
+ *
2482
+ * Idempotent and free when no guess is live, which is what lets `close()`,
2483
+ * `abort()`, and a mid-stream staleness check all call it unconditionally.
2484
+ */
2485
+ /**
2486
+ * Start the MathJax load, and re-typeset this document once it resolves.
2487
+ *
2488
+ * Called from two places, for two different reasons:
2489
+ *
2490
+ * - When an OPEN math fence is rendered. This is a prefetch, and it is what
2491
+ * makes the lazy load invisible while streaming: the module starts loading
2492
+ * the moment a formula begins arriving, several chunks before its closing
2493
+ * fence, so by the time the fence closes the converter is usually already
2494
+ * installed and the formula typesets synchronously on the normal path.
2495
+ * - When a CLOSED fence could not be typeset because the module is not ready.
2496
+ * That is the case a rebuild actually exists for: a document constructed with
2497
+ * math already complete, or a stream that closed a fence faster than the
2498
+ * module loaded.
2499
+ *
2500
+ * Idempotent per instance. Concurrent callers coalesce onto the one cached
2501
+ * module promise, and `mathLoadPending` keeps a second rebuild from being
2502
+ * queued while the first is outstanding.
2503
+ */
2504
+ ensureMathJax() {
2505
+ if (mathConverter || this.mathLoadPending || this.isDestroyed) return;
2506
+ this.mathLoadPending = true;
2507
+ void preloadMathJax().then(() => {
2508
+ this.mathLoadPending = false;
2509
+ if (this.isDestroyed) return;
2510
+ if (mathConverter) this.retypesetFromTokens();
2511
+ this.flushAppendSettledWaiters();
2512
+ });
2513
+ }
2514
+ /**
2515
+ * Rebuild every block from the tokens already lexed, without re-lexing.
2516
+ *
2517
+ * Used only when MathJax arrives after a formula has already been rendered as
2518
+ * source. Rebuilding wholesale rather than surgically replacing the math blocks
2519
+ * is the deliberate choice: `tokenChildPrefix` maps token indices to child
2520
+ * slots positionally, so swapping one child in place would have to keep that
2521
+ * mapping, the `Stack`'s cached box, and every following sibling's position in
2522
+ * agreement by hand. Re-rendering the same token list in the same order leaves
2523
+ * the mapping trivially correct, and this runs at most once per document — the
2524
+ * same cost as the `setContent` rebuild that already exists.
2525
+ *
2526
+ * The optimistic tail is dropped first. Its `entity` is about to be destroyed,
2527
+ * so the pointer would dangle; unwinding restores literal spans, and if the
2528
+ * stream is still open the next chunk re-applies a guess.
2529
+ */
2530
+ retypesetFromTokens() {
2531
+ this.unwindOptimisticTail();
2532
+ const tokens = this.tokens;
2533
+ while (this.content.children.length > 0) {
2534
+ this.content.children[this.content.children.length - 1].destroy();
2535
+ }
2536
+ for (const token of tokens) {
2537
+ const el = this.renderToken(token);
2538
+ if (el) this.content.add(el);
2539
+ }
2540
+ this.width = this.content.width;
2541
+ this.height = this.content.height;
2542
+ this.scene?.markDirty();
2543
+ }
2544
+ unwindOptimisticTail() {
2545
+ const tail = this.optimisticTail;
2546
+ this.optimisticTail = null;
2547
+ if (!tail || this.isDestroyed) return;
2548
+ const entity = tail.entity;
2549
+ if (!entity.setSpans || entity.parent !== this.content) return;
2550
+ entity.setSpans(this.literalParagraphSpans(tail.token));
2551
+ if (this.content.children.at(-1) === entity) {
2552
+ this.content.resizeLastChild(entity);
2553
+ } else {
2554
+ this.content.layout();
2555
+ }
2556
+ this.width = this.content.width;
2557
+ this.height = this.content.height;
2558
+ this.scene?.markDirty();
2559
+ }
2560
+ /**
2561
+ * Drop a guess that is no longer on the document's trailing paragraph.
2562
+ *
2563
+ * A coalesced append can add a block after the paragraph that owns the guess,
2564
+ * at which point the guess is frozen — the construct can never close, because
2565
+ * no further text lands in that paragraph. Without this the stale styling would
2566
+ * survive until `close()`.
2567
+ *
2568
+ * `writtenThisPass` is the entity whose spans this reconcile already rewrote,
2569
+ * if any: for that one, literal spans are on screen already and re-rendering it
2570
+ * would be wasted layout, so only the bookkeeping is cleared.
2571
+ */
2572
+ dropStaleOptimisticTail(trailing, writtenThisPass) {
2573
+ const tail = this.optimisticTail;
2574
+ if (!tail || tail.entity === trailing) return;
2575
+ if (tail.entity === writtenThisPass) {
2576
+ this.optimisticTail = null;
2577
+ return;
2578
+ }
2579
+ this.unwindOptimisticTail();
2580
+ }
2581
+ /**
2582
+ * Resolve once every in-flight worker append has actually been applied.
2583
+ *
2584
+ * Committing text is not the same as the document reflecting it: `append()`
2585
+ * reaches `dispatchAppend()`, which `postMessage()`s and returns, and the reply
2586
+ * that runs `updateTokens()` lands later. Without waiting here, `close()` could
2587
+ * resolve — and `onStable` fire — against a document missing its last chunk.
2588
+ *
2589
+ * An outstanding lazy MathJax load counts as unsettled for the same reason. A
2590
+ * document whose formulas are still TeX source is not final in any sense a
2591
+ * caller of `onStable` cares about: the boxes are the wrong size, so measuring
2592
+ * or exporting there would capture placeholders.
2593
+ */
2594
+ waitForAppendSettled() {
2595
+ if (!this.appendInFlight && !this.mathLoadPending) return Promise.resolve();
2596
+ return new Promise((resolve) => {
2597
+ this.appendSettledWaiters.push(resolve);
2598
+ });
2599
+ }
2600
+ /**
2601
+ * Release settlement waiters, but only once nothing is outstanding.
2602
+ *
2603
+ * Called at the very END of the worker callback, after its coalesced-re-dispatch
2604
+ * check, rather than wherever `appendInFlight` goes false. Within that callback
2605
+ * `appendInFlight` is cleared and then, if another chunk arrived while the
2606
+ * request was in flight, set straight back to `true` by the re-dispatch — both
2607
+ * synchronously, before anything watching the flag could observe the gap. Only
2608
+ * checking here, after that, waits through the re-dispatch instead of resolving
2609
+ * one chunk early.
2610
+ */
2611
+ flushAppendSettledWaiters() {
2612
+ if (this.appendInFlight || this.mathLoadPending || this.appendSettledWaiters.length === 0) {
2613
+ return;
2614
+ }
2615
+ const waiters = this.appendSettledWaiters;
2616
+ this.appendSettledWaiters = [];
2617
+ for (const resolve of waiters) resolve();
2618
+ }
2619
+ /** Throw if a public mutation is attempted from inside an `onStable` callback. */
2620
+ assertNotInStableCallback(method) {
2621
+ if (this.inStableCallback) {
2622
+ throw new Error(`Markdown.${method}() cannot be called from an onStable callback`);
2623
+ }
2624
+ }
1151
2625
  updateTokens(newTokens, knownMatchLen) {
1152
2626
  const oldTokens = this.tokens;
1153
2627
  const oldChildren = [...this.content.children];
@@ -1167,11 +2641,18 @@ var Markdown = class extends import_ui.UIComponent {
1167
2641
  }
1168
2642
  const oldTokenToChild = this.tokenChildPrefix;
1169
2643
  const rawMatchLen = matchLen;
2644
+ let pendingTail = null;
2645
+ let spansWrittenTo = null;
1170
2646
  const lastTokenSameType = matchLen === oldTokens.length - 1 && matchLen < newTokens.length && oldTokens[matchLen]?.type === newTokens[matchLen]?.type;
1171
2647
  if (lastTokenSameType && newTokens[matchLen]?.type === "code") {
1172
2648
  const existingEntity = oldChildren[oldTokenToChild[matchLen]];
1173
2649
  const codeToken = newTokens[matchLen];
1174
- if (existingEntity instanceof CodeBlock) {
2650
+ const oldCodeToken = oldTokens[matchLen];
2651
+ const isMath = rendersAsMath(codeToken);
2652
+ if (isMath && rendersAsMath(oldCodeToken) && oldCodeToken.text === codeToken.text) {
2653
+ this.streamStats.inPlaceUpdates++;
2654
+ matchLen++;
2655
+ } else if (existingEntity instanceof CodeBlock && !isMath) {
1175
2656
  existingEntity.setCode(codeToken.text, codeToken.lang ?? void 0);
1176
2657
  this.streamStats.inPlaceUpdates++;
1177
2658
  matchLen++;
@@ -1180,17 +2661,63 @@ var Markdown = class extends import_ui.UIComponent {
1180
2661
  } else if (lastTokenSameType && newTokens[matchLen]?.type === "paragraph") {
1181
2662
  const entityIdx = oldTokenToChild[matchLen];
1182
2663
  const existingEntity = oldChildren[entityIdx];
1183
- if (existingEntity && "setSpans" in existingEntity) {
2664
+ if (existingEntity && "setSpans" in existingEntity && !paragraphHasImage(newTokens[matchLen])) {
1184
2665
  const pToken = newTokens[matchLen];
1185
- const t = this.theme;
1186
- const spans = [];
1187
- if (pToken.tokens && pToken.tokens.length > 0) {
1188
- collectSpans(pToken.tokens, {}, t, spans);
1189
- }
1190
- if (spans.length === 0) {
1191
- spans.push({ text: pToken.text });
1192
- }
1193
- existingEntity.setSpans(spans);
2666
+ const isTrailing = matchLen === newTokens.length - 1;
2667
+ const optimistic = isTrailing ? this.optimisticParagraphSpans(pToken) : null;
2668
+ existingEntity.setSpans(optimistic ?? this.literalParagraphSpans(pToken));
2669
+ spansWrittenTo = existingEntity;
2670
+ if (optimistic) pendingTail = { entity: existingEntity, token: pToken };
2671
+ this.streamStats.inPlaceUpdates++;
2672
+ matchLen++;
2673
+ this.content.resizeLastChild(existingEntity);
2674
+ } else if (existingEntity && this.updateImageParagraph(
2675
+ existingEntity,
2676
+ oldTokens[matchLen],
2677
+ newTokens[matchLen]
2678
+ )) {
2679
+ this.streamStats.inPlaceUpdates++;
2680
+ matchLen++;
2681
+ this.content.resizeLastChild(existingEntity);
2682
+ }
2683
+ } else if (lastTokenSameType && newTokens[matchLen]?.type === "heading") {
2684
+ const existingEntity = oldChildren[oldTokenToChild[matchLen]];
2685
+ const hToken = newTokens[matchLen];
2686
+ const oldToken = oldTokens[matchLen];
2687
+ if (existingEntity && "setSpans" in existingEntity && oldToken?.depth === hToken.depth) {
2688
+ existingEntity.setSpans(this.headingSpans(hToken));
2689
+ spansWrittenTo = existingEntity;
2690
+ this.streamStats.inPlaceUpdates++;
2691
+ matchLen++;
2692
+ this.content.resizeLastChild(existingEntity);
2693
+ }
2694
+ } else if (lastTokenSameType && newTokens[matchLen]?.type === "blockquote") {
2695
+ const existingEntity = oldChildren[oldTokenToChild[matchLen]];
2696
+ const newInner = newTokens[matchLen].tokens;
2697
+ const oldInner = oldTokens[matchLen].tokens;
2698
+ if (existingEntity instanceof MarkdownContainer && newInner && oldInner && this.updateBlockquoteTail(existingEntity, oldInner, newInner)) {
2699
+ this.streamStats.inPlaceUpdates++;
2700
+ matchLen++;
2701
+ this.content.resizeLastChild(existingEntity);
2702
+ }
2703
+ } else if (lastTokenSameType && newTokens[matchLen]?.type === "list") {
2704
+ const existingEntity = oldChildren[oldTokenToChild[matchLen]];
2705
+ if (existingEntity && this.updateStreamedList(
2706
+ existingEntity,
2707
+ oldTokens[matchLen],
2708
+ newTokens[matchLen]
2709
+ )) {
2710
+ this.streamStats.inPlaceUpdates++;
2711
+ matchLen++;
2712
+ this.content.resizeLastChild(existingEntity);
2713
+ }
2714
+ } else if (lastTokenSameType && newTokens[matchLen]?.type === "table") {
2715
+ const existingEntity = oldChildren[oldTokenToChild[matchLen]];
2716
+ if (existingEntity && this.updateStreamedTable(
2717
+ existingEntity,
2718
+ oldTokens[matchLen],
2719
+ newTokens[matchLen]
2720
+ )) {
1194
2721
  this.streamStats.inPlaceUpdates++;
1195
2722
  matchLen++;
1196
2723
  this.content.resizeLastChild(existingEntity);
@@ -1208,10 +2735,24 @@ var Markdown = class extends import_ui.UIComponent {
1208
2735
  }
1209
2736
  }
1210
2737
  }
2738
+ const lastIndex = newTokens.length - 1;
1211
2739
  for (let i = matchLen; i < newTokens.length; i++) {
1212
2740
  const el = this.renderToken(newTokens[i]);
1213
- if (el) this.content.add(el);
2741
+ if (!el) continue;
2742
+ this.content.add(el);
2743
+ if (i === lastIndex && newTokens[i].type === "paragraph" && "setSpans" in el) {
2744
+ const pToken = newTokens[i];
2745
+ const optimistic = this.optimisticParagraphSpans(pToken);
2746
+ if (optimistic) {
2747
+ el.setSpans(optimistic);
2748
+ this.content.resizeLastChild(el);
2749
+ pendingTail = { entity: el, token: pToken };
2750
+ spansWrittenTo = el;
2751
+ }
2752
+ }
1214
2753
  }
2754
+ this.dropStaleOptimisticTail(pendingTail?.entity ?? null, spansWrittenTo);
2755
+ if (pendingTail) this.optimisticTail = pendingTail;
1215
2756
  this.setTokens(newTokens, rawMatchLen);
1216
2757
  this.width = this.content.width;
1217
2758
  this.height = this.content.height;
@@ -1220,6 +2761,19 @@ var Markdown = class extends import_ui.UIComponent {
1220
2761
  this.onLayoutUpdated();
1221
2762
  }
1222
2763
  }
2764
+ /**
2765
+ * Render one nested block with a temporary width/margin context while
2766
+ * preserving `renderToken` as the subclass override seam.
2767
+ */
2768
+ renderTokenWithMetrics(token, metrics) {
2769
+ const previous = this.activeBlockMetrics;
2770
+ this.activeBlockMetrics = metrics;
2771
+ try {
2772
+ return this.renderToken(token);
2773
+ } finally {
2774
+ this.activeBlockMetrics = previous;
2775
+ }
2776
+ }
1223
2777
  /**
1224
2778
  * Whether {@link renderToken} produces a child entity for this token (vs
1225
2779
  * `null`). `updateTokens` maps token indices to child-entity indices, and the
@@ -1254,6 +2808,17 @@ var Markdown = class extends import_ui.UIComponent {
1254
2808
  renderToken(token) {
1255
2809
  const t = this.theme;
1256
2810
  const bodyFont = `${t.fontSize}px ${t.bodyFont}`;
2811
+ const metrics = this.activeBlockMetrics ?? {
2812
+ marginBefore: 0,
2813
+ marginAfter: 0,
2814
+ indentStart: 0,
2815
+ availableWidth: this.maxWidth
2816
+ };
2817
+ const availableWidth = metrics.availableWidth;
2818
+ if (containsInlineMath(token)) {
2819
+ if (!mathConverter) this.ensureMathJax();
2820
+ this.subscribeInlineMathRepaint();
2821
+ }
1257
2822
  switch (token.type) {
1258
2823
  // ── Headings ─────────────────────────────────────────────────────
1259
2824
  case "heading": {
@@ -1266,7 +2831,7 @@ var Markdown = class extends import_ui.UIComponent {
1266
2831
  hToken.text,
1267
2832
  headingFont,
1268
2833
  t.headingColor,
1269
- this.maxWidth,
2834
+ availableWidth,
1270
2835
  t,
1271
2836
  this.selectable,
1272
2837
  this.onLinkClick
@@ -1275,13 +2840,13 @@ var Markdown = class extends import_ui.UIComponent {
1275
2840
  // ── Paragraphs ───────────────────────────────────────────────────
1276
2841
  case "paragraph": {
1277
2842
  const pToken = token;
1278
- if (!pToken.tokens || !pToken.tokens.some((t2) => t2.type === "image")) {
2843
+ if (!paragraphHasImage(pToken)) {
1279
2844
  return renderInlineToRichText(
1280
2845
  pToken.tokens,
1281
2846
  pToken.text,
1282
2847
  bodyFont,
1283
2848
  t.textColor,
1284
- this.maxWidth,
2849
+ availableWidth,
1285
2850
  t,
1286
2851
  this.selectable,
1287
2852
  this.onLinkClick
@@ -1290,48 +2855,19 @@ var Markdown = class extends import_ui.UIComponent {
1290
2855
  const stack = new import_ui.Stack({
1291
2856
  direction: "vertical",
1292
2857
  gap: 16,
1293
- maxWidth: this.maxWidth
2858
+ maxWidth: availableWidth
1294
2859
  });
1295
2860
  let currentTokens = [];
1296
2861
  const flushText = () => {
1297
2862
  if (currentTokens.length > 0) {
1298
- stack.add(
1299
- renderInlineToRichText(
1300
- currentTokens,
1301
- "",
1302
- bodyFont,
1303
- t.textColor,
1304
- this.maxWidth,
1305
- t,
1306
- this.selectable,
1307
- this.onLinkClick
1308
- )
1309
- );
2863
+ stack.add(this.inlineRunRichText(currentTokens, availableWidth, t));
1310
2864
  currentTokens = [];
1311
2865
  }
1312
2866
  };
1313
2867
  for (const child of pToken.tokens) {
1314
2868
  if (child.type === "image") {
1315
2869
  flushText();
1316
- const imgToken = child;
1317
- const initialWidth = Math.min(800, this.maxWidth);
1318
- const initialHeight = Math.round(initialWidth * 0.6);
1319
- const img = new import_ui.Image(imgToken.href, {
1320
- width: initialWidth,
1321
- height: initialHeight,
1322
- alt: imgToken.text,
1323
- radius: 8,
1324
- onLoad: () => {
1325
- const bmp = img.bitmap;
1326
- if (bmp && bmp.naturalWidth && bmp.naturalHeight) {
1327
- const aspect = bmp.naturalHeight / bmp.naturalWidth;
1328
- img.width = Math.min(bmp.naturalWidth, this.maxWidth);
1329
- img.height = Math.round(img.width * aspect);
1330
- if (this.scene) this.scene.markDirty();
1331
- }
1332
- }
1333
- });
1334
- stack.add(img);
2870
+ stack.add(this.paragraphImage(child, availableWidth));
1335
2871
  } else {
1336
2872
  currentTokens.push(child);
1337
2873
  }
@@ -1343,13 +2879,22 @@ var Markdown = class extends import_ui.UIComponent {
1343
2879
  case "code": {
1344
2880
  const codeToken = token;
1345
2881
  const lang = (codeToken.lang ?? "").toLowerCase();
1346
- if (lang === "math" || lang === "latex" || lang === "tex") {
2882
+ if (MATH_LANGS.has(lang)) this.ensureMathJax();
2883
+ if (rendersAsMath(codeToken)) {
1347
2884
  const mathData = renderMathToSVGDataURI(codeToken.text, true);
1348
2885
  if (mathData) {
2886
+ const intrinsicW = exToPx(mathData.widthEx, t.fontSize);
2887
+ const intrinsicH = exToPx(mathData.heightEx, t.fontSize);
1349
2888
  const mathImg = new import_ui.Image(mathData.uri, {
1350
- width: Math.min(this.maxWidth, mathData.width),
1351
- height: mathData.height * Math.min(1, this.maxWidth / mathData.width),
1352
- alt: codeToken.text
2889
+ width: Math.min(availableWidth, intrinsicW),
2890
+ height: intrinsicH * Math.min(1, availableWidth / intrinsicW),
2891
+ alt: codeToken.text,
2892
+ // The SVG decodes asynchronously and Image paints a placeholder
2893
+ // until it lands. Without this an `onDemand` scene, which repaints
2894
+ // only when marked dirty, leaves the formula a blank slab forever.
2895
+ onLoad: () => {
2896
+ this.scene?.markDirty();
2897
+ }
1353
2898
  });
1354
2899
  const wrapper = new MarkdownContainer();
1355
2900
  mathImg.x = 16;
@@ -1360,20 +2905,27 @@ var Markdown = class extends import_ui.UIComponent {
1360
2905
  return wrapper;
1361
2906
  }
1362
2907
  }
1363
- return new CodeBlock(codeToken.text, lang, this.maxWidth, t, this.selectable);
2908
+ return new CodeBlock(codeToken.text, lang, availableWidth, t, this.selectable);
1364
2909
  }
1365
2910
  // ── Blockquotes ──────────────────────────────────────────────────
1366
2911
  case "blockquote": {
1367
2912
  const bqToken = token;
1368
2913
  const innerStack = new import_ui.Stack({ direction: "vertical", gap: 8 });
2914
+ const indentStart = Math.min(16, availableWidth);
2915
+ const childMetrics = {
2916
+ marginBefore: 0,
2917
+ marginAfter: 0,
2918
+ indentStart,
2919
+ availableWidth: Math.max(0, availableWidth - indentStart)
2920
+ };
1369
2921
  if (bqToken.tokens) {
1370
2922
  for (const inner of bqToken.tokens) {
1371
- const el = this.renderToken(inner);
2923
+ const el = this.renderTokenWithMetrics(inner, childMetrics);
1372
2924
  if (el) {
1373
2925
  const wrapper = new MarkdownContainer();
1374
- el.x = 16;
2926
+ el.x = childMetrics.indentStart;
1375
2927
  wrapper.add(el);
1376
- wrapper.width = el.width + 16;
2928
+ wrapper.width = el.width + childMetrics.indentStart;
1377
2929
  wrapper.height = el.height;
1378
2930
  innerStack.add(wrapper);
1379
2931
  }
@@ -1387,70 +2939,30 @@ var Markdown = class extends import_ui.UIComponent {
1387
2939
  innerStack.y = 0;
1388
2940
  innerStack.x = 0;
1389
2941
  container.add(innerStack);
1390
- container.width = this.maxWidth;
2942
+ container.width = availableWidth;
1391
2943
  container.height = Math.max(border.height, innerStack.height);
1392
2944
  return container;
1393
2945
  }
1394
- // ── Lists ────────────────────────────────────────────────────────
2946
+ // ── Lists ────────────────────────────────────────────────
1395
2947
  case "list": {
1396
2948
  const listToken = token;
1397
2949
  const listStack = new import_ui.Stack({ direction: "vertical", gap: 6 });
1398
2950
  for (let i = 0; i < listToken.items.length; i++) {
1399
- const item = listToken.items[i];
1400
- const num = Number(listToken.start ?? 1) + i;
1401
- const contentSpans = [];
1402
- if (item.tokens && item.tokens.length > 0) {
1403
- for (const inner of item.tokens) {
1404
- if (inner.type === "text" && "tokens" in inner && inner.tokens?.length) {
1405
- collectSpans(inner.tokens, {}, t, contentSpans);
1406
- } else if ("tokens" in inner && inner.tokens?.length) {
1407
- collectSpans(inner.tokens, {}, t, contentSpans);
1408
- } else if ("text" in inner) {
1409
- contentSpans.push({
1410
- text: decodeEntities(inner.text)
1411
- });
1412
- }
1413
- }
1414
- } else {
1415
- contentSpans.push({ text: decodeEntities(item.text) });
1416
- }
1417
- const itemIsRtl = import_core.BidiResolver.getBaseLevel(contentSpans.map((s) => s.text).join("")) % 2 === 1;
1418
- const itemSpans = itemIsRtl ? [...contentSpans, { text: listToken.ordered ? ` .${num}` : " \u2022" }] : [{ text: listToken.ordered ? `${num}. ` : "\u2022 " }, ...contentSpans];
1419
- const itemRt = new import_ui.RichText(itemSpans, {
1420
- font: bodyFont,
1421
- color: t.textColor,
1422
- maxWidth: this.maxWidth - 24,
1423
- linkColor: "#38bdf8",
1424
- selectable: this.selectable,
1425
- onLinkClick: this.onLinkClick
1426
- });
1427
- itemRt.x = 12;
1428
- listStack.add(itemRt);
2951
+ listStack.add(this.listItemRichText(listToken, i, availableWidth, t));
1429
2952
  }
1430
2953
  return listStack;
1431
2954
  }
1432
2955
  // ── Table ────────────────────────────────────────────────────────
1433
2956
  case "table": {
1434
2957
  const tblToken = token;
1435
- const buildCell = (cell, header) => {
1436
- const spans = [];
1437
- collectSpans(cell.tokens, {}, t, spans);
1438
- if (spans.length === 0) return decodeEntities(cell.text);
1439
- return new import_ui.RichText(spans, {
1440
- font: `${t.fontSize - 2}px ${t.bodyFont}`,
1441
- color: header ? t.headingColor : t.textColor,
1442
- baseStyle: header ? { bold: true } : void 0,
1443
- linkColor: "#38bdf8",
1444
- selectable: this.selectable,
1445
- onLinkClick: this.onLinkClick
1446
- });
1447
- };
1448
- const headers = tblToken.header.map((cell) => buildCell(cell, true));
1449
- const rows = tblToken.rows.map((row) => row.map((cell) => buildCell(cell, false)));
2958
+ const headers = tblToken.header.map((cell) => this.tableCellRichText(cell, true, t));
2959
+ const rows = tblToken.rows.map(
2960
+ (row) => row.map((cell) => this.tableCellRichText(cell, false, t))
2961
+ );
1450
2962
  return new import_ui.Table({
1451
2963
  headers,
1452
2964
  rows,
1453
- width: this.maxWidth,
2965
+ width: availableWidth,
1454
2966
  textColor: t.textColor,
1455
2967
  headerTextColor: t.headingColor,
1456
2968
  font: `${t.fontSize - 2}px ${t.bodyFont}`,
@@ -1462,7 +2974,7 @@ var Markdown = class extends import_ui.UIComponent {
1462
2974
  }
1463
2975
  // ── Horizontal rule ──────────────────────────────────────────────
1464
2976
  case "hr":
1465
- return new HorizontalRule(this.maxWidth, t.hrColor);
2977
+ return new HorizontalRule(availableWidth, t.hrColor);
1466
2978
  // ── Whitespace ───────────────────────────────────────────────────
1467
2979
  case "space":
1468
2980
  return null;
@@ -1480,7 +2992,7 @@ var Markdown = class extends import_ui.UIComponent {
1480
2992
  return new import_ui.Text(token.text, {
1481
2993
  font: bodyFont,
1482
2994
  color: t.textColor,
1483
- maxWidth: this.maxWidth,
2995
+ maxWidth: availableWidth,
1484
2996
  lineHeight: 24,
1485
2997
  selectable: this.selectable
1486
2998
  });
@@ -1497,5 +3009,7 @@ var Markdown = class extends import_ui.UIComponent {
1497
3009
  CodeBlock,
1498
3010
  Markdown,
1499
3011
  codeAtlas,
1500
- codeAtlasStats
3012
+ codeAtlasStats,
3013
+ isMathJaxReady,
3014
+ preloadMathJax
1501
3015
  });