@vectojs/markdown 0.13.0 → 0.15.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
@@ -30,20 +30,29 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ BlockAffordanceButton: () => BlockAffordanceButton,
34
+ BlockWithAffordances: () => BlockWithAffordances,
33
35
  CodeBlock: () => CodeBlock,
34
36
  Markdown: () => Markdown,
35
37
  MathBlock: () => MathBlock,
36
38
  codeAtlas: () => codeAtlas,
37
39
  codeAtlasStats: () => codeAtlasStats,
40
+ escapeCsvField: () => escapeCsvField,
41
+ escapeMarkdownTableCell: () => escapeMarkdownTableCell,
42
+ extensionForLanguage: () => extensionForLanguage,
38
43
  isMathJaxReady: () => isMathJaxReady,
44
+ mimeForLanguage: () => mimeForLanguage,
39
45
  parseFrontMatterFields: () => parseFrontMatterFields,
40
46
  preloadMathJax: () => preloadMathJax,
41
- scanFrontMatter: () => scanFrontMatter
47
+ scanFrontMatter: () => scanFrontMatter,
48
+ tableContentOf: () => tableContentOf,
49
+ tableToCsv: () => tableToCsv,
50
+ tableToMarkdown: () => tableToMarkdown
42
51
  });
43
52
  module.exports = __toCommonJS(index_exports);
44
53
 
45
54
  // src/Markdown.ts
46
- var import_core = require("@vectojs/core");
55
+ var import_core4 = require("@vectojs/core");
47
56
  var import_marked = require("marked");
48
57
 
49
58
  // src/StreamController.ts
@@ -455,450 +464,109 @@ function createStreamController(host, options = {}) {
455
464
  return new StreamControllerImpl(host, options);
456
465
  }
457
466
 
458
- // src/Markdown.ts
459
- var import_ui = require("@vectojs/ui");
460
-
461
- // src/frontMatter.ts
462
- var OPEN_RE = /^---[ \t]*\r?\n/;
463
- var OPENER_PREFIX_RE = /^(?:-|--|---[ \t]*\r?)$/;
464
- var KEY_RE = /^[^\s:#][^:]*:(?:[ \t].*)?$/;
465
- var CLOSE_RE = /^(?:---|\.\.\.)[ \t]*$/;
466
- var MAX_PENDING_CHARS = 4096;
467
- var NONE = { kind: "none" };
468
- var PENDING = { kind: "pending" };
469
- function scanFrontMatter(text, complete) {
470
- if (text.length === 0) return PENDING;
471
- const open = OPEN_RE.exec(text);
472
- if (!open) {
473
- return !complete && OPENER_PREFIX_RE.test(text) ? PENDING : NONE;
474
- }
475
- const decide = complete || text.length > MAX_PENDING_CHARS;
476
- const contentStart = open[0].length;
477
- let cursor = contentStart;
478
- let keyChecked = false;
479
- while (cursor < text.length) {
480
- const nl = text.indexOf("\n", cursor);
481
- if (nl === -1 && !decide) return PENDING;
482
- const line = text.slice(cursor, nl === -1 ? text.length : nl).replace(/\r$/, "");
483
- if (!keyChecked) {
484
- if (!KEY_RE.test(line)) return NONE;
485
- keyChecked = true;
486
- } else if (CLOSE_RE.test(line)) {
487
- return {
488
- kind: "found",
489
- raw: text.slice(contentStart, cursor),
490
- // A closer with no trailing newline ends the document, so the body is
491
- // empty rather than starting one character past the end.
492
- bodyStart: nl === -1 ? text.length : nl + 1
493
- };
494
- }
495
- if (nl === -1) break;
496
- cursor = nl + 1;
497
- }
498
- return decide ? NONE : PENDING;
499
- }
500
- function parseFrontMatterFields(raw) {
501
- const out = {};
502
- for (const rawLine of raw.split("\n")) {
503
- const line = rawLine.replace(/\r$/, "");
504
- if (line.length === 0 || /^[\s#]/.test(line)) continue;
505
- const sep = line.indexOf(":");
506
- if (sep <= 0) continue;
507
- const value = line.slice(sep + 1);
508
- if (value.length > 0 && value[0] !== " " && value[0] !== " ") continue;
509
- out[line.slice(0, sep).trim()] = unquote(value.trim());
467
+ // src/markdown-entities.ts
468
+ var import_core = require("@vectojs/core");
469
+ var HorizontalRule = class extends import_core.Entity {
470
+ color;
471
+ constructor(w, color) {
472
+ super();
473
+ this.width = w;
474
+ this.height = 1;
475
+ this.color = color;
510
476
  }
511
- return out;
512
- }
513
- function unquote(value) {
514
- if (value.length < 2) return value;
515
- const first = value[0];
516
- if ((first === '"' || first === "'") && value.endsWith(first)) {
517
- return value.slice(1, -1);
477
+ isPointInside() {
478
+ return false;
518
479
  }
519
- return value;
520
- }
521
-
522
- // src/MarkdownWorkerSource.ts
523
- var WORKER_SOURCE_STRING = '"use strict";(()=>{function V(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var _=V();function ke(t){_=t}var C={exec:()=>null};function P(t){let e=[];return n=>{let s=Math.max(0,Math.min(3,n-1)),r=e[s];return r||(r=t(s),e[s]=r),r}}function k(t,e=""){let n=typeof t=="string"?t:t.source,s={replace:(r,l)=>{let a=typeof l=="string"?l:l.source;return a=a.replace(x.caret,"$1"),n=n.replace(r,a),s},getRegex:()=>new RegExp(n,e)};return s}var _e=((t="")=>{try{return!!new RegExp("(?<=1)(?<!1)"+t)}catch{return!1}})(),x={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:t=>new RegExp(`^( {0,3}${t})((?:[ ][^\\\\n]*)?(?:\\\\n|$))`),nextBulletRegex:P(t=>new RegExp(`^ {0,${t}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ ][^\\\\n]*)?(?:\\\\n|$))`)),hrRegex:P(t=>new RegExp(`^ {0,${t}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`)),fencesBeginRegex:P(t=>new RegExp(`^ {0,${t}}(?:\\`\\`\\`|~~~)`)),headingBeginRegex:P(t=>new RegExp(`^ {0,${t}}#`)),htmlBeginRegex:P(t=>new RegExp(`^ {0,${t}}<(?:[a-z].*>|!--)`,"i")),blockquoteBeginRegex:P(t=>new RegExp(`^ {0,${t}}>`))},Pe=/^(?:[ \\t]*(?:\\n|$))+/,Me=/^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/,Ee=/^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/,v=/^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/,Be=/^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/,K=/ {0,3}(?:[*+-]|\\d{1,9}[.)])/,fe=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,de=k(fe).replace(/bull/g,K).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(),qe=k(fe).replace(/bull/g,K).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(),J=/^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \\t]+\\n)[^\\n]+)*)/,ve=/^[^\\n]+/,Y=/(?!\\s*\\])(?:\\\\[\\s\\S]|[^\\[\\]\\\\])+/,De=k(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/).replace("label",Y).replace("title",/(?:"(?:\\\\"?|[^"\\\\])*"|\'[^\'\\n]*(?:\\n[^\'\\n]+)*\\n?\'|\\([^()]*\\))/).getRegex(),Ze=k(/^(bull)([ \\t][^\\n]*?)?(?:\\n|$)/).replace(/bull/g,K).getRegex(),N="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",ee=/<!--(?:-?>|[\\s\\S]*?(?:-->|$))/,Oe=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",ee).replace("tag",N).replace("attribute",/ +[a-zA-Z:_][\\w.:-]*(?: *= *"[^"\\n]*"| *= *\'[^\'\\n]*\'| *= *[^\\s"\'=<>`]+)?/).getRegex(),xe=t=>k(J).replace("hr",v).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",t).replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",N).getRegex(),Qe=xe(/ {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]/),Ne=xe(/ {0,3}(?:[*+-]|\\d{1,9}[.)])(?:[ \\t]|\\n|$)/),He=k(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/).replace("paragraph",Ne).getRegex(),te={blockquote:He,code:Me,def:De,fences:Ee,heading:Be,hr:v,html:Oe,lheading:de,list:Ze,newline:Pe,paragraph:Qe,table:C,text:ve},ae=k("^ *([^\\\\n ].*)\\\\n {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)").replace("hr",v).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",N).getRegex(),je={...te,lheading:qe,table:ae,paragraph:k(J).replace("hr",v).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("|lheading","").replace("table",ae).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",N).getRegex()},Ge={...te,html:k(`^ *(?:comment *(?:\\\\n|\\\\s*$)|<(tag)[\\\\s\\\\S]+?</\\\\1> *(?:\\\\n{2,}|\\\\s*$)|<tag(?:"[^"]*"|\'[^\']*\'|\\\\s[^\'"/>\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))`).replace("comment",ee).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:C,lheading:/^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,paragraph:k(J).replace("hr",v).replace("heading",` *#{1,6} *[^\n]`).replace("lheading",de).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},We=/^\\\\([!"#$%&\'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/,Fe=/^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/,be=/^( {2,}|\\\\)\\n(?!\\s*$)/,Xe=/^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/,M=/[\\p{P}\\p{S}]/u,H=/[\\s\\p{P}\\p{S}]/u,ne=/[^\\s\\p{P}\\p{S}]/u,Ue=k(/^((?![*_])punctSpace)/,"u").replace(/punctSpace/g,H).getRegex(),me=/(?!~)[\\p{P}\\p{S}]/u,Ve=/(?!~)[\\s\\p{P}\\p{S}]/u,Ke=/(?:[^\\s\\p{P}\\p{S}]|~)/u,Je=k(/link|precode-code|html/,"g").replace("link",/\\[(?:[^\\[\\]`]|(?<a>`+)[^`]+\\k<a>(?!`))*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)/).replace("precode-",_e?"(?<!`)()":"(^^|[^`])").replace("code",/(?<b>`+)[^`]+\\k<b>(?!`)/).replace("html",/<(?! )[^<>]*?>/).getRegex(),we=/^(?:\\*+(?:((?!\\*)punct)|([^\\s*]))?)|^_+(?:((?!_)punct)|([^\\s_]))?/,Ye=k(we,"u").replace(/punct/g,M).getRegex(),et=k(we,"u").replace(/punct/g,me).getRegex(),ye="^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)|(?!\\\\*)punctSpace(\\\\*+)(?=notPunctSpace)|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)|notPunctSpace(\\\\*+)(?=notPunctSpace)",tt=k(ye,"gu").replace(/notPunctSpace/g,ne).replace(/punctSpace/g,H).replace(/punct/g,M).getRegex(),nt=k(ye,"gu").replace(/notPunctSpace/g,Ke).replace(/punctSpace/g,Ve).replace(/punct/g,me).getRegex(),rt=k("^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,ne).replace(/punctSpace/g,H).replace(/punct/g,M).getRegex(),st=k(/^~~?(?:((?!~)punct)|[^\\s~])/,"u").replace(/punct/g,M).getRegex(),lt="^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)",it=k(lt,"gu").replace(/notPunctSpace/g,ne).replace(/punctSpace/g,H).replace(/punct/g,M).getRegex(),at=k(/\\\\(punct)/,"gu").replace(/punct/g,M).getRegex(),ot=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(),ct=k(ee).replace("(?:-->|$)","-->").getRegex(),ht=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",ct).replace("attribute",/\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*"[^"]*"|\\s*=\\s*\'[^\']*\'|\\s*=\\s*[^\\s"\'=<>`]+)?/).getRegex(),Z=/(?:\\[(?:\\\\[\\s\\S]|[^\\[\\]\\\\])*\\]|\\\\[\\s\\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\\])|[^\\[\\]\\\\`])*?/,ut=k(/^!?\\[(label)\\]\\(\\s*(href)(?:(?:[ \\t]+(?:\\n[ \\t]*)?|\\n[ \\t]*)(title))?\\s*\\)/).replace("label",Z).replace("href",/<(?:\\\\.|[^\\n<>\\\\])+>|[^ \\t\\n\\x00-\\x1f]+|(?=\\))/).replace("title",/"(?:\\\\"?|[^"\\\\])*"|\'(?:\\\\\'?|[^\'\\\\])*\'|\\((?:\\\\\\)?|[^)\\\\])*\\)/).getRegex(),Re=k(/^!?\\[(label)\\]\\[(ref)\\]/).replace("label",Z).replace("ref",Y).getRegex(),$e=k(/^!?\\[(ref)\\](?:\\[\\])?/).replace("ref",Y).getRegex(),pt=k("reflink|nolink(?!\\\\()","g").replace("reflink",Re).replace("nolink",$e).getRegex(),oe=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,re={_backpedal:C,anyPunctuation:at,autolink:ot,blockSkip:Je,br:be,code:Fe,del:C,delLDelim:C,delRDelim:C,emStrongLDelim:Ye,emStrongRDelimAst:tt,emStrongRDelimUnd:rt,escape:We,link:ut,nolink:$e,punctuation:Ue,reflink:Re,reflinkSearch:pt,tag:ht,text:Xe,url:C},gt={...re,link:k(/^!?\\[(label)\\]\\((.*?)\\)/).replace("label",Z).getRegex(),reflink:k(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/).replace("label",Z).getRegex()},F={...re,emStrongRDelimAst:nt,emStrongLDelim:et,delLDelim:st,delRDelim:it,url:k(/^((?:protocol):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/).replace("protocol",oe).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",oe).getRegex()},kt={...F,br:k(be).replace("{2,}","*").getRegex(),text:k(F.text).replace("\\\\b_","\\\\b_| {2,}\\\\n").replace(/\\{2,\\}/g,"*").getRegex()},D={normal:te,gfm:je,pedantic:Ge},B={normal:re,gfm:F,breaks:kt,pedantic:gt},ft={"&":"&amp;","<":"&lt;",">":"&gt;",\'"\':"&quot;","\'":"&#39;"},ce=t=>ft[t];function S(t,e){if(e){if(x.escapeTest.test(t))return t.replace(x.escapeReplace,ce)}else if(x.escapeTestNoEncode.test(t))return t.replace(x.escapeReplaceNoEncode,ce);return t}function he(t){try{t=encodeURI(t).replace(x.percentDecode,"%")}catch{return null}return t}function ue(t,e){let n=t.replace(x.findPipe,(l,a,i)=>{let o=!1,c=a;for(;--c>=0&&i[c]==="\\\\";)o=!o;return o?"|":" |"}),s=n.split(x.splitPipe),r=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(;r<s.length;r++)s[r]=s[r].trim().replace(x.slashPipe,"|");return s}function z(t,e,n){let s=t.length;if(s===0)return"";let r=0;for(;r<s;){let l=t.charAt(s-r-1);if(l===e&&!n)r++;else if(l!==e&&n)r++;else break}return t.slice(0,s-r)}function pe(t){let e=t.split(`\n`),n=e.length-1;for(;n>=0&&x.blankLine.test(e[n]);)n--;return e.length-n<=2?t:e.slice(0,n+1).join(`\n`)}function dt(t,e){if(t.indexOf(e[1])===-1)return-1;let n=0;for(let s=0;s<t.length;s++)if(t[s]==="\\\\")s++;else if(t[s]===e[0])n++;else if(t[s]===e[1]&&(n--,n<0))return s;return n>0?-2:-1}function xt(t,e=0){let n=e,s="";for(let r of t)if(r===" "){let l=4-n%4;s+=" ".repeat(l),n+=l}else s+=r,n++;return s}function ge(t,e,n,s,r){let l=e.href,a=e.title||null,i=t[1].replace(r.other.outputLinkReplace,"$1");s.state.inLink=!0;let o={type:t[0].charAt(0)==="!"?"image":"link",raw:n,href:l,title:a,text:i,tokens:s.inlineTokens(i)};return s.state.inLink=!1,o}function bt(t,e,n){let s=t.match(n.other.indentCodeCompensation);if(s===null)return e;let r=s[1];return e.split(`\n`).map(l=>{let a=l.match(n.other.beginningSpace);if(a===null)return l;let[i]=a;return i.length>=r.length?l.slice(r.length):l}).join(`\n`)}var O=class{options;rules;lexer;constructor(t){this.options=t||_}space(t){let e=this.rules.block.newline.exec(t);if(e&&e[0].length>0)return{type:"space",raw:e[0]}}code(t){let e=this.rules.block.code.exec(t);if(e){let n=this.options.pedantic?e[0]:pe(e[0]),s=n.replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:n,codeBlockStyle:"indented",text:s}}}fences(t){let e=this.rules.block.fences.exec(t);if(e){let n=e[0],s=bt(n,e[3]||"",this.rules);return{type:"code",raw:n,lang:e[2]?e[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):e[2],text:s}}}heading(t){let e=this.rules.block.heading.exec(t);if(e){let n=e[2].trim();if(this.rules.other.endingHash.test(n)){let s=z(n,"#");(this.options.pedantic||!s||this.rules.other.endingSpaceChar.test(s))&&(n=s.trim())}return{type:"heading",raw:z(e[0],`\n`),depth:e[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(t){let e=this.rules.block.hr.exec(t);if(e)return{type:"hr",raw:z(e[0],`\n`)}}blockquote(t){let e=this.rules.block.blockquote.exec(t);if(e){let n=z(e[0],`\n`).split(`\n`),s="",r="",l=[];for(;n.length>0;){let a=!1,i=[],o;for(o=0;o<n.length;o++)if(this.rules.other.blockquoteStart.test(n[o]))i.push(n[o]),a=!0;else if(!a)i.push(n[o]);else break;n=n.slice(o);let c=i.join(`\n`),u=c.replace(this.rules.other.blockquoteSetextReplace,`\n $1`).replace(this.rules.other.blockquoteSetextReplace2,"");s=s?`${s}\n${c}`:c,r=r?`${r}\n${u}`:u;let h=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(u,l,!0),this.lexer.state.top=h,n.length===0)break;let p=l.at(-1);if(p?.type==="code")break;if(p?.type==="blockquote"){let d=p,f=d.raw+`\n`+n.join(`\n`),m=this.blockquote(f);l[l.length-1]=m,s=s.substring(0,s.length-d.raw.length)+m.raw,r=r.substring(0,r.length-d.text.length)+m.text;break}else if(p?.type==="list"){let d=p,f=d.raw+`\n`+n.join(`\n`),m=this.list(f);l[l.length-1]=m,s=s.substring(0,s.length-p.raw.length)+m.raw,r=r.substring(0,r.length-d.raw.length)+m.raw,n=f.substring(l.at(-1).raw.length).split(`\n`);continue}}return{type:"blockquote",raw:s,tokens:l,text:r}}}list(t){let e=this.rules.block.list.exec(t);if(e){let n=e[1].trim(),s=n.length>1,r={type:"list",raw:"",ordered:s,start:s?+n.slice(0,-1):"",loose:!1,items:[]};n=s?`\\\\d{1,9}\\\\${n.slice(-1)}`:`\\\\${n}`,this.options.pedantic&&(n=s?n:"[*+-]");let l=this.rules.other.listItemRegex(n),a=!1;for(;t;){let o=!1,c="",u="";if(!(e=l.exec(t))||this.rules.block.hr.test(t))break;c=e[0],t=t.substring(c.length);let h=xt(e[2].split(`\n`,1)[0],e[1].length),p=t.split(`\n`,1)[0],d=!h.trim(),f=0;if(this.options.pedantic?(f=2,u=h.trimStart()):d?f=e[1].length+1:(f=h.search(this.rules.other.nonSpaceChar),f=f>4?1:f,u=h.slice(f),f+=e[1].length),d&&this.rules.other.blankLine.test(p)&&(c+=p+`\n`,t=t.substring(p.length+1),o=!0),!o){let m=this.rules.other.nextBulletRegex(f),w=this.rules.other.hrRegex(f),y=this.rules.other.fencesBeginRegex(f),L=this.rules.other.headingBeginRegex(f),W=this.rules.other.htmlBeginRegex(f),A=this.rules.other.blockquoteBeginRegex(f);for(;t;){let b=t.split(`\n`,1)[0],T;if(p=b,this.options.pedantic?(p=p.replace(this.rules.other.listReplaceNesting," "),T=p):T=p.replace(this.rules.other.tabCharGlobal," "),y.test(p)||L.test(p)||W.test(p)||A.test(p)||m.test(p)||w.test(p))break;if(T.search(this.rules.other.nonSpaceChar)>=f||!p.trim())u+=`\n`+T.slice(f);else{if(d||h.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||y.test(h)||L.test(h)||w.test(h))break;u+=`\n`+p}d=!p.trim(),c+=b+`\n`,t=t.substring(b.length+1),h=T.slice(f)}}r.loose||(a?r.loose=!0:this.rules.other.doubleBlankLine.test(c)&&(a=!0)),r.items.push({type:"list_item",raw:c,task:!!this.options.gfm&&this.rules.other.listIsTask.test(u),loose:!1,text:u,tokens:[]}),r.raw+=c}let i=r.items.at(-1);if(i)i.raw=i.raw.trimEnd(),i.text=i.text.trimEnd();else return;r.raw=r.raw.trimEnd();for(let o of r.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 u=this.rules.other.listTaskCheckbox.exec(o.raw);if(u){let h={type:"checkbox",raw:u[0]+" ",checked:u[0]!=="[ ]"};o.checked=h.checked,r.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(!r.loose){let u=o.tokens.filter(p=>p.type==="space"),h=u.length>0&&u.some(p=>this.rules.other.anyLine.test(p.raw));r.loose=h}}if(r.loose)for(let o of r.items){o.loose=!0;for(let c of o.tokens)c.type==="text"&&(c.type="paragraph")}return r}}html(t){let e=this.rules.block.html.exec(t);if(e){let n=pe(e[0]);return{type:"html",block:!0,raw:n,pre:e[1]==="pre"||e[1]==="script"||e[1]==="style",text:n}}}def(t){let e=this.rules.block.def.exec(t);if(e){let n=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"):"",r=e[3]?e[3].substring(1,e[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):e[3];return{type:"def",tag:n,raw:z(e[0],`\n`),href:s,title:r}}}table(t){let e=this.rules.block.table.exec(t);if(!e||!this.rules.other.tableDelimiter.test(e[2]))return;let n=ue(e[1]),s=e[2].replace(this.rules.other.tableAlignChars,"").split("|"),r=e[3]?.trim()?e[3].replace(this.rules.other.tableRowBlankLine,"").split(`\n`):[],l={type:"table",raw:z(e[0],`\n`),header:[],align:[],rows:[]};if(n.length===s.length){for(let a of s)this.rules.other.tableAlignRight.test(a)?l.align.push("right"):this.rules.other.tableAlignCenter.test(a)?l.align.push("center"):this.rules.other.tableAlignLeft.test(a)?l.align.push("left"):l.align.push(null);for(let a=0;a<n.length;a++)l.header.push({text:n[a],tokens:this.lexer.inline(n[a]),header:!0,align:l.align[a]});for(let a of r)l.rows.push(ue(a,l.header.length).map((i,o)=>({text:i,tokens:this.lexer.inline(i),header:!1,align:l.align[o]})));return l}}lheading(t){let e=this.rules.block.lheading.exec(t);if(e){let n=e[1].trim();return{type:"heading",raw:z(e[0],`\n`),depth:e[2].charAt(0)==="="?1:2,text:n,tokens:this.lexer.inline(n)}}}paragraph(t){let e=this.rules.block.paragraph.exec(t);if(e){let n=e[1].charAt(e[1].length-1)===`\n`?e[1].slice(0,-1):e[1];return{type:"paragraph",raw:e[0],text:n,tokens:this.lexer.inline(n)}}}text(t){let e=this.rules.block.text.exec(t);if(e)return{type:"text",raw:e[0],text:e[0],tokens:this.lexer.inline(e[0])}}escape(t){let e=this.rules.inline.escape.exec(t);if(e)return{type:"escape",raw:e[0],text:e[1]}}tag(t){let e=this.rules.inline.tag.exec(t);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(t){let e=this.rules.inline.link.exec(t);if(e){let n=e[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(n)){if(!this.rules.other.endAngleBracket.test(n))return;let l=z(n.slice(0,-1),"\\\\");if((n.length-l.length)%2===0)return}else{let l=dt(e[2],"()");if(l===-2)return;if(l>-1){let a=(e[0].indexOf("!")===0?5:4)+e[1].length+l;e[2]=e[2].substring(0,l),e[0]=e[0].substring(0,a).trim(),e[3]=""}}let s=e[2],r="";if(this.options.pedantic){let l=this.rules.other.pedanticHrefTitle.exec(s);l&&(s=l[1],r=l[3])}else r=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(n)?s=s.slice(1):s=s.slice(1,-1)),ge(e,{href:s&&s.replace(this.rules.inline.anyPunctuation,"$1"),title:r&&r.replace(this.rules.inline.anyPunctuation,"$1")},e[0],this.lexer,this.rules)}}reflink(t,e){let n;if((n=this.rules.inline.reflink.exec(t))||(n=this.rules.inline.nolink.exec(t))){let s=(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal," "),r=e[s.toLowerCase()];if(!r){let l=n[0].charAt(0);return{type:"text",raw:l,text:l}}return ge(n,r,n[0],this.lexer,this.rules)}}emStrong(t,e,n=""){let s=this.rules.inline.emStrongLDelim.exec(t);if(!(!s||!s[1]&&!s[2]&&!s[3]&&!s[4]||s[4]&&n.match(this.rules.other.unicodeAlphaNumeric))&&(!(s[1]||s[3])||!n||this.rules.inline.punctuation.exec(n))){let r=[...s[0]].length-1,l,a,i=r,o=0,c=s[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(c.lastIndex=0,e=e.slice(-1*t.length+r);(s=c.exec(e))!==null;){if(l=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!l)continue;if(a=[...l].length,s[3]||s[4]){i+=a;continue}else if((s[5]||s[6])&&r%3&&!((r+a)%3)){o+=a;continue}if(i-=a,i>0)continue;a=Math.min(a,a+i+o);let u=[...s[0]][0].length,h=t.slice(0,r+s.index+u+a);if(Math.min(r,a)%2){let d=h.slice(1,-1);return{type:"em",raw:h,text:d,tokens:this.lexer.inlineTokens(d)}}let p=h.slice(2,-2);return{type:"strong",raw:h,text:p,tokens:this.lexer.inlineTokens(p)}}}}codespan(t){let e=this.rules.inline.code.exec(t);if(e){let n=e[2].replace(this.rules.other.newLineCharGlobal," "),s=this.rules.other.nonSpaceChar.test(n),r=this.rules.other.startingSpaceChar.test(n)&&this.rules.other.endingSpaceChar.test(n);return s&&r&&(n=n.substring(1,n.length-1)),{type:"codespan",raw:e[0],text:n}}}br(t){let e=this.rules.inline.br.exec(t);if(e)return{type:"br",raw:e[0]}}del(t,e,n=""){let s=this.rules.inline.delLDelim.exec(t);if(s&&(!s[1]||!n||this.rules.inline.punctuation.exec(n))){let r=[...s[0]].length-1,l,a,i=r,o=this.rules.inline.delRDelim;for(o.lastIndex=0,e=e.slice(-1*t.length+r);(s=o.exec(e))!==null;){if(l=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!l||(a=[...l].length,a!==r))continue;if(s[3]||s[4]){i+=a;continue}if(i-=a,i>0)continue;a=Math.min(a,a+i);let c=[...s[0]][0].length,u=t.slice(0,r+s.index+c+a),h=u.slice(r,-r);return{type:"del",raw:u,text:h,tokens:this.lexer.inlineTokens(h)}}}}autolink(t){let e=this.rules.inline.autolink.exec(t);if(e){let n,s;return e[2]==="@"?(n=e[1],s="mailto:"+n):(n=e[1],s=n),{type:"link",raw:e[0],text:n,href:s,tokens:[{type:"text",raw:n,text:n}]}}}url(t){let e;if(e=this.rules.inline.url.exec(t)){let n,s;if(e[2]==="@")n=e[0],s="mailto:"+n;else{let r;do r=e[0],e[0]=this.rules.inline._backpedal.exec(e[0])?.[0]??"";while(r!==e[0]);n=e[0],e[1]==="www."?s="http://"+e[0]:s=e[0]}return{type:"link",raw:e[0],text:n,href:s,tokens:[{type:"text",raw:n,text:n}]}}}inlineText(t){let e=this.rules.inline.text.exec(t);if(e){let n=this.lexer.state.inRawBlock;return{type:"text",raw:e[0],text:e[0],escaped:n}}}},R=class X{tokens;options;state;inlineQueue;tokenizer;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||_,this.options.tokenizer=this.options.tokenizer||new O,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 n={other:x,block:D.normal,inline:B.normal};this.options.pedantic?(n.block=D.pedantic,n.inline=B.pedantic):this.options.gfm&&(n.block=D.gfm,this.options.breaks?n.inline=B.breaks:n.inline=B.gfm),this.tokenizer.rules=n}static get rules(){return{block:D,inline:B}}static lex(e,n){return new X(n).lex(e)}static lexInline(e,n){return new X(n).inlineTokens(e)}lex(e){e=e.replace(x.carriageReturn,`\n`),this.blockTokens(e,this.tokens);for(let n=0;n<this.inlineQueue.length;n++){let s=this.inlineQueue[n];this.inlineTokens(s.src,s.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,n=[],s=!1){this.tokenizer.lexer=this,this.options.pedantic&&(e=e.replace(x.tabCharGlobal," ").replace(x.spaceLine,""));let r=1/0;for(;e;){if(e.length<r)r=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}let l;if(this.options.extensions?.block?.some(i=>(l=i.call({lexer:this},e,n))?(e=e.substring(l.raw.length),n.push(l),!0):!1))continue;if(l=this.tokenizer.space(e)){e=e.substring(l.raw.length);let i=n.at(-1);l.raw.length===1&&i!==void 0?i.raw+=`\n`:n.push(l);continue}if(l=this.tokenizer.code(e)){e=e.substring(l.raw.length);let i=n.at(-1);i?.type==="paragraph"||i?.type==="text"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.text,this.inlineQueue.at(-1).src=i.text):n.push(l);continue}if(l=this.tokenizer.fences(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.heading(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.hr(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.blockquote(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.list(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.html(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.def(e)){e=e.substring(l.raw.length);let i=n.at(-1);i?.type==="paragraph"||i?.type==="text"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.raw,this.inlineQueue.at(-1).src=i.text):this.tokens.links[l.tag]||(this.tokens.links[l.tag]={href:l.href,title:l.title},n.push(l));continue}if(l=this.tokenizer.table(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.lheading(e)){e=e.substring(l.raw.length),n.push(l);continue}let a=e;if(this.options.extensions?.startBlock){let i=1/0,o=e.slice(1),c;this.options.extensions.startBlock.forEach(u=>{c=u.call({lexer:this},o),typeof c=="number"&&c>=0&&(i=Math.min(i,c))}),i<1/0&&i>=0&&(a=e.substring(0,i+1))}if(this.state.top&&(l=this.tokenizer.paragraph(a))){let i=n.at(-1);s&&i?.type==="paragraph"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=i.text):n.push(l),s=a.length!==e.length,e=e.substring(l.raw.length);continue}if(l=this.tokenizer.text(e)){e=e.substring(l.raw.length);let i=n.at(-1);i?.type==="text"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=i.text):n.push(l);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return this.state.top=!0,n}inline(e,n=[]){return this.inlineQueue.push({src:e,tokens:n}),n}inlineTokens(e,n=[]){this.tokenizer.lexer=this;let s=e;if(this.tokens.links){let i=Object.keys(this.tokens.links);i.length>0&&(s=s.replace(this.tokenizer.rules.inline.reflinkSearch,o=>i.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,(i,o,c)=>{let u=c?c.length:0;return i.slice(0,u)+"["+"a".repeat(i.length-u-2)+"]"}),s=this.options.hooks?.emStrongMask?.call({lexer:this},s)??s;let r=!1,l="",a=1/0;for(;e;){if(e.length<a)a=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}r||(l=""),r=!1;let i;if(this.options.extensions?.inline?.some(c=>(i=c.call({lexer:this},e,n))?(e=e.substring(i.raw.length),n.push(i),!0):!1))continue;if(i=this.tokenizer.escape(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.tag(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.link(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(i.raw.length);let c=n.at(-1);i.type==="text"&&c?.type==="text"?(c.raw+=i.raw,c.text+=i.text):n.push(i);continue}if(i=this.tokenizer.emStrong(e,s,l)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.codespan(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.br(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.del(e,s,l)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.autolink(e)){e=e.substring(i.raw.length),n.push(i);continue}if(!this.state.inLink&&(i=this.tokenizer.url(e))){e=e.substring(i.raw.length),n.push(i);continue}let o=e;if(this.options.extensions?.startInline){let c=1/0,u=e.slice(1),h;this.options.extensions.startInline.forEach(p=>{h=p.call({lexer:this},u),typeof h=="number"&&h>=0&&(c=Math.min(c,h))}),c<1/0&&c>=0&&(o=e.substring(0,c+1))}if(i=this.tokenizer.inlineText(o)){e=e.substring(i.raw.length),i.raw.slice(-1)!=="_"&&(l=i.raw.slice(-1)),r=!0;let c=n.at(-1);c?.type==="text"?(c.raw+=i.raw,c.text+=i.text):n.push(i);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return n}infiniteLoopError(e){let n="Infinite loop on byte: "+e;if(this.options.silent)console.error(n);else throw new Error(n)}},Q=class{options;parser;constructor(t){this.options=t||_}space(t){return""}code({text:t,lang:e,escaped:n}){let s=(e||"").match(x.notSpaceStart)?.[0],r=t.replace(x.endingNewline,"")+`\n`;return s?\'<pre><code class="language-\'+S(s)+\'">\'+(n?r:S(r,!0))+`</code></pre>\n`:"<pre><code>"+(n?r:S(r,!0))+`</code></pre>\n`}blockquote({tokens:t}){return`<blockquote>\n${this.parser.parse(t)}</blockquote>\n`}html({text:t}){return t}def(t){return""}heading({tokens:t,depth:e}){return`<h${e}>${this.parser.parseInline(t)}</h${e}>\n`}hr(t){return`<hr>\n`}list(t){let e=t.ordered,n=t.start,s="";for(let a=0;a<t.items.length;a++){let i=t.items[a];s+=this.listitem(i)}let r=e?"ol":"ul",l=e&&n!==1?\' start="\'+n+\'"\':"";return"<"+r+l+`>\n`+s+"</"+r+`>\n`}listitem(t){return`<li>${this.parser.parse(t.tokens)}</li>\n`}checkbox({checked:t}){return"<input "+(t?\'checked="" \':"")+\'disabled="" type="checkbox"> \'}paragraph({tokens:t}){return`<p>${this.parser.parseInline(t)}</p>\n`}table(t){let e="",n="";for(let r=0;r<t.header.length;r++)n+=this.tablecell(t.header[r]);e+=this.tablerow({text:n});let s="";for(let r=0;r<t.rows.length;r++){let l=t.rows[r];n="";for(let a=0;a<l.length;a++)n+=this.tablecell(l[a]);s+=this.tablerow({text:n})}return s&&(s=`<tbody>${s}</tbody>`),`<table>\n<thead>\n`+e+`</thead>\n`+s+`</table>\n`}tablerow({text:t}){return`<tr>\n${t}</tr>\n`}tablecell(t){let e=this.parser.parseInline(t.tokens),n=t.header?"th":"td";return(t.align?`<${n} align="${t.align}">`:`<${n}>`)+e+`</${n}>\n`}strong({tokens:t}){return`<strong>${this.parser.parseInline(t)}</strong>`}em({tokens:t}){return`<em>${this.parser.parseInline(t)}</em>`}codespan({text:t}){return`<code>${S(t,!0)}</code>`}br(t){return"<br>"}del({tokens:t}){return`<del>${this.parser.parseInline(t)}</del>`}link({href:t,title:e,tokens:n}){let s=this.parser.parseInline(n),r=he(t);if(r===null)return s;t=r;let l=\'<a href="\'+t+\'"\';return e&&(l+=\' title="\'+S(e)+\'"\'),l+=">"+s+"</a>",l}image({href:t,title:e,text:n,tokens:s}){s&&(n=this.parser.parseInline(s,this.parser.textRenderer));let r=he(t);if(r===null)return S(n);t=r;let l=`<img src="${t}" alt="${S(n)}"`;return e&&(l+=` title="${S(e)}"`),l+=">",l}text(t){return"tokens"in t&&t.tokens?this.parser.parseInline(t.tokens):"escaped"in t&&t.escaped?t.text:S(t.text)}},se=class{strong({text:t}){return t}em({text:t}){return t}codespan({text:t}){return t}del({text:t}){return t}html({text:t}){return t}text({text:t}){return t}link({text:t}){return""+t}image({text:t}){return""+t}br(){return""}checkbox({raw:t}){return t}},$=class U{options;renderer;textRenderer;constructor(e){this.options=e||_,this.options.renderer=this.options.renderer||new Q,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new se}static parse(e,n){return new U(n).parse(e)}static parseInline(e,n){return new U(n).parseInline(e)}parse(e){this.renderer.parser=this;let n="";for(let s=0;s<e.length;s++){let r=e[s];if(this.options.extensions?.renderers?.[r.type]){let a=r,i=this.options.extensions.renderers[a.type].call({parser:this},a);if(i!==!1||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(a.type)){n+=i||"";continue}}let l=r;switch(l.type){case"space":{n+=this.renderer.space(l);break}case"hr":{n+=this.renderer.hr(l);break}case"heading":{n+=this.renderer.heading(l);break}case"code":{n+=this.renderer.code(l);break}case"table":{n+=this.renderer.table(l);break}case"blockquote":{n+=this.renderer.blockquote(l);break}case"list":{n+=this.renderer.list(l);break}case"checkbox":{n+=this.renderer.checkbox(l);break}case"html":{n+=this.renderer.html(l);break}case"def":{n+=this.renderer.def(l);break}case"paragraph":{n+=this.renderer.paragraph(l);break}case"text":{n+=this.renderer.text(l);break}default:{let a=\'Token with "\'+l.type+\'" type was not found.\';if(this.options.silent)return console.error(a),"";throw new Error(a)}}}return n}parseInline(e,n=this.renderer){this.renderer.parser=this;let s="";for(let r=0;r<e.length;r++){let l=e[r];if(this.options.extensions?.renderers?.[l.type]){let i=this.options.extensions.renderers[l.type].call({parser:this},l);if(i!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(l.type)){s+=i||"";continue}}let a=l;switch(a.type){case"escape":{s+=n.text(a);break}case"html":{s+=n.html(a);break}case"link":{s+=n.link(a);break}case"image":{s+=n.image(a);break}case"checkbox":{s+=n.checkbox(a);break}case"strong":{s+=n.strong(a);break}case"em":{s+=n.em(a);break}case"codespan":{s+=n.codespan(a);break}case"br":{s+=n.br(a);break}case"del":{s+=n.del(a);break}case"text":{s+=n.text(a);break}default:{let i=\'Token with "\'+a.type+\'" type was not found.\';if(this.options.silent)return console.error(i),"";throw new Error(i)}}}return s}},q=class{options;block;constructor(t){this.options=t||_}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(t){return t}postprocess(t){return t}processAllTokens(t){return t}emStrongMask(t){return t}provideLexer(t=this.block){return t?R.lex:R.lexInline}provideParser(t=this.block){return t?$.parse:$.parseInline}},mt=class{defaults=V();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=$;Renderer=Q;TextRenderer=se;Lexer=R;Tokenizer=O;Hooks=q;constructor(...t){this.use(...t)}walkTokens(t,e){let n=[];for(let s of t)switch(n=n.concat(e.call(this,s)),s.type){case"table":{let r=s;for(let l of r.header)n=n.concat(this.walkTokens(l.tokens,e));for(let l of r.rows)for(let a of l)n=n.concat(this.walkTokens(a.tokens,e));break}case"list":{let r=s;n=n.concat(this.walkTokens(r.items,e));break}default:{let r=s;this.defaults.extensions?.childTokens?.[r.type]?this.defaults.extensions.childTokens[r.type].forEach(l=>{let a=r[l].flat(1/0);n=n.concat(this.walkTokens(a,e))}):r.tokens&&(n=n.concat(this.walkTokens(r.tokens,e)))}}return n}use(...t){let e=this.defaults.extensions||{renderers:{},childTokens:{}};return t.forEach(n=>{let s={...n};if(s.async=this.defaults.async||s.async||!1,n.extensions&&(n.extensions.forEach(r=>{if(!r.name)throw new Error("extension name required");if("renderer"in r){let l=e.renderers[r.name];l?e.renderers[r.name]=function(...a){let i=r.renderer.apply(this,a);return i===!1&&(i=l.apply(this,a)),i}:e.renderers[r.name]=r.renderer}if("tokenizer"in r){if(!r.level||r.level!=="block"&&r.level!=="inline")throw new Error("extension level must be \'block\' or \'inline\'");let l=e[r.level];l?l.unshift(r.tokenizer):e[r.level]=[r.tokenizer],r.start&&(r.level==="block"?e.startBlock?e.startBlock.push(r.start):e.startBlock=[r.start]:r.level==="inline"&&(e.startInline?e.startInline.push(r.start):e.startInline=[r.start]))}"childTokens"in r&&r.childTokens&&(e.childTokens[r.name]=r.childTokens)}),s.extensions=e),n.renderer){let r=this.defaults.renderer||new Q(this.defaults);for(let l in n.renderer){if(!(l in r))throw new Error(`renderer \'${l}\' does not exist`);if(["options","parser"].includes(l))continue;let a=l,i=n.renderer[a],o=r[a];r[a]=(...c)=>{let u=i.apply(r,c);return u===!1&&(u=o.apply(r,c)),u||""}}s.renderer=r}if(n.tokenizer){let r=this.defaults.tokenizer||new O(this.defaults);for(let l in n.tokenizer){if(!(l in r))throw new Error(`tokenizer \'${l}\' does not exist`);if(["options","rules","lexer"].includes(l))continue;let a=l,i=n.tokenizer[a],o=r[a];r[a]=(...c)=>{let u=i.apply(r,c);return u===!1&&(u=o.apply(r,c)),u}}s.tokenizer=r}if(n.hooks){let r=this.defaults.hooks||new q;for(let l in n.hooks){if(!(l in r))throw new Error(`hook \'${l}\' does not exist`);if(["options","block"].includes(l))continue;let a=l,i=n.hooks[a],o=r[a];q.passThroughHooks.has(l)?r[a]=c=>{if(this.defaults.async&&q.passThroughHooksRespectAsync.has(l))return(async()=>{let h=await i.call(r,c);return o.call(r,h)})();let u=i.call(r,c);return o.call(r,u)}:r[a]=(...c)=>{if(this.defaults.async)return(async()=>{let h=await i.apply(r,c);return h===!1&&(h=await o.apply(r,c)),h})();let u=i.apply(r,c);return u===!1&&(u=o.apply(r,c)),u}}s.hooks=r}if(n.walkTokens){let r=this.defaults.walkTokens,l=n.walkTokens;s.walkTokens=function(a){let i=[];return i.push(l.call(this,a)),r&&(i=i.concat(r.call(this,a))),i}}this.defaults={...this.defaults,...s}}),this}setOptions(t){return this.defaults={...this.defaults,...t},this}lexer(t,e){return R.lex(t,e??this.defaults)}parser(t,e){return $.parse(t,e??this.defaults)}parseMarkdown(t){return(e,n)=>{let s={...n},r={...this.defaults,...s},l=this.onError(!!r.silent,!!r.async);if(this.defaults.async===!0&&s.async===!1)return l(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 l(new Error("marked(): input parameter is undefined or null"));if(typeof e!="string")return l(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected"));if(r.hooks&&(r.hooks.options=r,r.hooks.block=t),r.async)return(async()=>{let a=r.hooks?await r.hooks.preprocess(e):e,i=await(r.hooks?await r.hooks.provideLexer(t):t?R.lex:R.lexInline)(a,r),o=r.hooks?await r.hooks.processAllTokens(i):i;r.walkTokens&&await Promise.all(this.walkTokens(o,r.walkTokens));let c=await(r.hooks?await r.hooks.provideParser(t):t?$.parse:$.parseInline)(o,r);return r.hooks?await r.hooks.postprocess(c):c})().catch(l);try{r.hooks&&(e=r.hooks.preprocess(e));let a=(r.hooks?r.hooks.provideLexer(t):t?R.lex:R.lexInline)(e,r);r.hooks&&(a=r.hooks.processAllTokens(a)),r.walkTokens&&this.walkTokens(a,r.walkTokens);let i=(r.hooks?r.hooks.provideParser(t):t?$.parse:$.parseInline)(a,r);return r.hooks&&(i=r.hooks.postprocess(i)),i}catch(a){return l(a)}}}onError(t,e){return n=>{if(n.message+=`\nPlease report this to https://github.com/markedjs/marked.`,t){let s="<p>An error occurred:</p><pre>"+S(n.message+"",!0)+"</pre>";return e?Promise.resolve(s):s}if(e)return Promise.reject(n);throw n}}},I=new mt;function g(t,e){return I.parse(t,e)}g.options=g.setOptions=function(t){return I.setOptions(t),g.defaults=I.defaults,ke(g.defaults),g};g.getDefaults=V;g.defaults=_;g.use=function(...t){return I.use(...t),g.defaults=I.defaults,ke(g.defaults),g};g.walkTokens=function(t,e){return I.walkTokens(t,e)};g.parseInline=I.parseInline;g.Parser=$;g.parser=$.parse;g.Renderer=Q;g.TextRenderer=se;g.Lexer=R;g.lexer=R.lex;g.Tokenizer=O;g.Hooks=q;g.parse=g;var zt=g.options,At=g.setOptions,Ct=g.use,It=g.walkTokens,_t=g.parseInline;var Pt=$.parse,Mt=R.lex;function Se(t,e,n){let s=0;for(let r=e;r<n;r++)s+=t[r].raw.length;return s}function wt(t,e){let n=t;return n.links=e,n}var yt=/^ {0,3}\\$\\$/m;function Le(t){return t.includes("$$")===!1?!1:yt.test(t)}function Rt(t,e){return t[e-2]?.type!=="list"?!0:e+1<t.length}function ze(t,e){for(let n=t.length-2;n>=e;n--)if(t[n].type==="space"&&Rt(t,n+1)!==!1)return n+1;return-1}function Ae(t){let e=t.links;if(!e)return!1;for(let n in e)return!0;return!1}function Ce(t,e,n,s,r){let l=r;for(let a=e;a<n;a++){let i=t[a].raw;if(s.startsWith(i,l)===!1)return!1;l+=i.length}return!0}function G(t,e,n){return{source:t,tail:t,tokens:e,stableCount:0,stableOffset:0,degraded:!0,degradedReason:n}}function Te(t,e){return{source:t,tail:t,tokens:e,stableCount:0,stableOffset:0,degraded:!1,degradedReason:null}}function $t(t,e){if(Ae(e))return G(t,e,"link-definition");if(t.includes("\\r"))return G(t,e,"carriage-return");if(Le(t))return G(t,e,"block-math");let n=ze(e,1);if(n<0||Ce(e,0,n,t,0)===!1)return Te(t,e);let s=Se(e,0,n);return{source:t,tail:t.slice(s),tokens:e,stableCount:n,stableOffset:s,degraded:!1,degradedReason:null}}function le(t){let e=g.lexer(t);return{tokens:e,cache:$t(t,e),charsLexed:t.length,reusedTokens:0}}function j(t,e){let n=g.lexer(t);return{tokens:n,cache:G(t,n,e),charsLexed:t.length,reusedTokens:0}}function Ie(t,e){let n=t.source+e;if(t.degraded)return j(n,t.degradedReason??"link-definition");if(e.includes("\\r"))return j(n,"carriage-return");if(t.stableCount===0)return le(n);let s=t.tail+e;if(Le(s))return j(n,"block-math");let r=g.lexer(s);if(Ae(r))return j(n,"link-definition");let l=t.tokens.slice(0,t.stableCount),a=wt([...l,...r],r.links),i=t.stableCount,o=t.stableOffset,c=s,u=ze(a,t.stableCount+1);if(u>t.stableCount&&Ce(a,t.stableCount,u,s,0)){let h=Se(a,t.stableCount,u);i=u,o=t.stableOffset+h,c=s.slice(h)}return{tokens:a,cache:{source:n,tail:c,tokens:a,stableCount:i,stableOffset:o,degraded:!1,degradedReason:null},charsLexed:s.length,reusedTokens:t.stableCount}}var Tt=0;function St(t){if(typeof t!="string"||typeof performance.mark!="function"||typeof performance.measure!="function")return null;let e=Tt++,n={name:t,startMark:`${t}:start:${e}`,endMark:`${t}:end:${e}`};try{return performance.mark(n.startMark),n}catch{return null}}function Lt(t){if(t)try{performance.mark(t.endMark),performance.measure(t.name,t.startMark,t.endMark)}catch{}finally{try{performance.clearMarks?.(t.startMark),performance.clearMarks?.(t.endMark)}catch{}}}g.use({extensions:[{name:"blockMath",level:"block",start(t){return t.match(/^ {0,3}\\$\\$/m)?.index},tokenizer(t){let e=/^ {0,3}\\$\\$([\\s\\S]+?)\\$\\$[ \\t]*(?:\\n|$)/.exec(t);if(e)return{type:"blockMath",raw:e[0],text:e[1].trim()}},renderer(t){return t.raw}},{name:"inlineMath",level:"inline",start(t){return t.match(/(?<![\\\\$])\\$(?![$\\s])/)?.index},tokenizer(t){let e=/^\\$(?![$\\s\\d])((?:\\\\\\$|[^$\\n])*?)(?<!\\s)\\$(?!\\d)/.exec(t);if(e)return{type:"inlineMath",raw:e[0],text:e[1].trim()}},renderer(t){return t.raw}}]});var E=new Map;self.onmessage=t=>{let e=t.data;if(typeof e!="object"||e===null)return;let{id:n,text:s,append:r,expectedLength:l,oldRaws:a,instance:i,baseVersion:o,dispose:c,userTimingName:u}=e;if(c===!0){typeof i=="string"&&E.delete(i);return}let h=typeof i=="string"?i:null,p=typeof o=="number"?o:null,d,f=null,m=null;if(typeof r=="string"){if(h===null||p===null){self.postMessage({id:n,needResync:!0});return}let w=E.get(h);if(!w||w.version!==p){self.postMessage({id:n,needResync:!0});return}if(typeof l=="number"&&w.lex.source.length+r.length!==l){E.delete(h),self.postMessage({id:n,needResync:!0});return}let y=w.lex;d=()=>Ie(y,r),m=y.tokens}else if(typeof s=="string"){let w=s;if(d=()=>le(w),Array.isArray(a))f=a;else if(h!==null&&p!==null){let y=E.get(h);if(y&&y.version===p)m=y.lex.tokens;else{self.postMessage({id:n,needResync:!0});return}}}else return;try{let w=typeof u=="string"?St(u):null,y=performance.now(),L;try{L=d()}finally{w&&Lt(w)}let W=performance.now()-y,A=L.tokens,b=0;if(f!==null){let T=Math.min(f.length,A.length);for(;b<T&&f[b]===A[b].raw;b++);}else if(m!==null){let T=m,ie=Math.min(T.length,A.length);for(b=Math.min(L.reusedTokens,ie);b<ie&&T[b].raw===A[b].raw;b++);}h!==null&&p!==null&&E.set(h,{version:p+1,lex:L.cache}),self.postMessage({id:n,matchLen:b,tail:A.slice(b),lexerMs:W,sourceCharsLexed:L.charsLexed})}catch(w){h!==null&&E.delete(h),self.postMessage({id:n,error:String(w)})}};})();\n';
524
-
525
- // src/Markdown.ts
526
- var now = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
527
- function lexMarkdown(text, userTiming) {
528
- if (!userTiming) return import_marked.marked.lexer(text);
529
- const timing = (0, import_core.beginVectoUserTiming)(import_core.VECTO_USER_TIMING.markdown.parse);
530
- try {
531
- return import_marked.marked.lexer(text);
532
- } finally {
533
- if (timing) (0, import_core.endVectoUserTiming)(timing);
480
+ render(r) {
481
+ r.beginPath();
482
+ r.moveTo(0, 0);
483
+ r.lineTo(this.width, 0);
484
+ r.stroke(this.color, 1);
534
485
  }
535
- }
536
- import_marked.marked.use({
537
- extensions: [
538
- {
539
- name: "blockMath",
540
- level: "block",
541
- start(src) {
542
- return src.match(/^ {0,3}\$\$/m)?.index;
543
- },
544
- tokenizer(src) {
545
- const match = /^ {0,3}\$\$([\s\S]+?)\$\$[ \t]*(?:\n|$)/.exec(src);
546
- if (match) {
547
- return {
548
- type: "blockMath",
549
- raw: match[0],
550
- text: match[1].trim()
551
- };
552
- }
553
- return void 0;
554
- },
555
- renderer(token) {
556
- return token.raw;
557
- }
558
- },
559
- {
560
- name: "inlineMath",
561
- level: "inline",
562
- start(src) {
563
- return src.match(/(?<![\\$])\$(?![$\s])/)?.index;
564
- },
565
- tokenizer(src) {
566
- const match = /^\$(?![$\s\d])((?:\\\$|[^$\n])*?)(?<!\s)\$(?!\d)/.exec(src);
567
- if (match) {
568
- return {
569
- type: "inlineMath",
570
- raw: match[0],
571
- text: match[1].trim()
572
- };
573
- }
574
- return void 0;
575
- },
576
- renderer(token) {
577
- return token.raw;
578
- }
579
- }
580
- ]
581
- });
582
- var mathConverter = null;
583
- var mathLoad = null;
584
- function interop(mod, key) {
585
- const ns = mod;
586
- if (typeof ns?.[key] !== "undefined") return ns;
587
- const fallback = ns?.default;
588
- if (fallback && typeof fallback[key] !== "undefined") return fallback;
589
- throw new Error(`mathjax-full module is missing export "${key}"`);
590
- }
591
- function preloadMathJax() {
592
- if (mathLoad) return mathLoad;
593
- mathLoad = (async () => {
594
- const [mathjaxMod, texMod, svgMod, adaptorMod, handlerMod, packagesMod] = await Promise.all([
595
- import("mathjax-full/js/mathjax.js"),
596
- import("mathjax-full/js/input/tex.js"),
597
- import("mathjax-full/js/output/svg.js"),
598
- import("mathjax-full/js/adaptors/liteAdaptor.js"),
599
- import("mathjax-full/js/handlers/html.js"),
600
- import("mathjax-full/js/input/tex/AllPackages.js")
601
- ]);
602
- const { mathjax } = interop(mathjaxMod, "mathjax");
603
- const { TeX } = interop(texMod, "TeX");
604
- const { SVG } = interop(svgMod, "SVG");
605
- const { liteAdaptor } = interop(adaptorMod, "liteAdaptor");
606
- const { RegisterHTMLHandler } = interop(handlerMod, "RegisterHTMLHandler");
607
- const { AllPackages } = interop(packagesMod, "AllPackages");
608
- const adaptor = liteAdaptor();
609
- RegisterHTMLHandler(adaptor);
610
- const tex = new TeX({ packages: AllPackages });
611
- const svg = new SVG({ fontCache: "local" });
612
- const htmlMathJax = mathjax.document("", { InputJax: tex, OutputJax: svg });
613
- mathConverter = (formula, displayMode, color) => convertMathToSVGDataURI(
614
- formula,
615
- displayMode,
616
- (f, d) => adaptor.innerHTML(htmlMathJax.convert(f, { display: d })),
617
- color
618
- );
619
- })().catch((e) => {
620
- console.error("MathJax failed to load; formulas will render as TeX source", e);
621
- });
622
- return mathLoad;
623
- }
624
- function isMathJaxReady() {
625
- return mathConverter !== null;
626
- }
627
- var EX_PER_EM = 0.4421;
628
- function exToPx(ex, fontSize) {
629
- return ex * fontSize * EX_PER_EM;
630
- }
631
- function fontSizeFromFont(font) {
632
- const pxIndex = font.indexOf("px");
633
- if (pxIndex <= 0) return void 0;
634
- let start = pxIndex;
635
- while (start > 0) {
636
- const ch = font[start - 1];
637
- if (ch >= "0" && ch <= "9" || ch === ".") start--;
638
- else break;
486
+ };
487
+ var QuoteBorder = class extends import_core.Entity {
488
+ color;
489
+ constructor(height, color, width = 4) {
490
+ super();
491
+ this.width = width;
492
+ this.height = height;
493
+ this.color = color;
639
494
  }
640
- if (start === pxIndex) return void 0;
641
- const size = parseFloat(font.slice(start, pxIndex));
642
- return Number.isFinite(size) ? size : void 0;
643
- }
644
- var mathCache = /* @__PURE__ */ new Map();
645
- var MATH_CACHE_LIMIT = 256;
646
- var inlineMathRasters = /* @__PURE__ */ new Map();
647
- var inlineMathRasterWaiters = /* @__PURE__ */ new Set();
648
- function ensureInlineMathRaster(uri) {
649
- const existing = inlineMathRasters.get(uri);
650
- if (existing) return existing;
651
- const entry = { decoded: false };
652
- inlineMathRasters.set(uri, entry);
653
- if (typeof globalThis.Image !== "undefined") {
654
- const bitmap = new globalThis.Image();
655
- bitmap.onload = () => {
656
- entry.decoded = true;
657
- for (const notify of inlineMathRasterWaiters) notify();
658
- };
659
- bitmap.src = uri;
660
- entry.bitmap = bitmap;
495
+ isPointInside() {
496
+ return false;
661
497
  }
662
- return entry;
663
- }
664
- function paintInlineMath(uri, surface, box) {
665
- const raster = ensureInlineMathRaster(uri);
666
- if (!raster.decoded || !raster.bitmap) return;
667
- surface.drawImage(raster.bitmap, box.x, box.y, box.width, box.height);
668
- }
669
- var MATH_LANGS = /* @__PURE__ */ new Set(["math", "latex", "tex"]);
670
- function containsInlineMath(token) {
671
- if (token.type === "inlineMath") return true;
672
- const anyToken = token;
673
- if (Array.isArray(anyToken.tokens) && anyToken.tokens.some(containsInlineMath)) {
674
- return true;
498
+ render(r) {
499
+ r.beginPath();
500
+ r.roundRect(0, 0, this.width, this.height, this.width / 2);
501
+ r.fill(this.color);
675
502
  }
676
- if (Array.isArray(anyToken.items) && anyToken.items.some(containsInlineMath)) {
677
- return true;
503
+ };
504
+ var MarkdownContainer = class extends import_core.Entity {
505
+ isPointInside(_globalX, _globalY) {
506
+ return false;
678
507
  }
679
- if (Array.isArray(anyToken.header) && anyToken.header.some(containsInlineMath)) {
680
- return true;
508
+ render(_r) {
681
509
  }
682
- if (Array.isArray(anyToken.rows)) {
683
- for (const row of anyToken.rows) {
684
- if (Array.isArray(row) && row.some(containsInlineMath)) return true;
685
- }
510
+ };
511
+
512
+ // src/markdown-code.ts
513
+ var import_core2 = require("@vectojs/core");
514
+ var import_ui = require("@vectojs/ui");
515
+
516
+ // src/theme.ts
517
+ var DEFAULT_THEME = {
518
+ textColor: "#e2e8f0",
519
+ headingColor: "#f8fafc",
520
+ codeColor: "#a5f3fc",
521
+ codeBgColor: "rgba(30, 41, 59, 0.85)",
522
+ quoteBorderColor: "#6366f1",
523
+ quoteTextColor: "#e2e8f0",
524
+ hrColor: "rgba(148, 163, 184, 0.3)",
525
+ tableBgColor: "rgba(15, 15, 25, 0.4)",
526
+ tableHeaderBgColor: "rgba(255, 255, 255, 0.08)",
527
+ linkColor: "#38bdf8",
528
+ mathFallbackColor: "#fcd34d",
529
+ syntaxKeywordColor: "#c084fc",
530
+ syntaxStringColor: "#86efac",
531
+ syntaxCommentColor: "#64748b",
532
+ syntaxNumberColor: "#fbbf24",
533
+ bodyFont: "Inter, system-ui, sans-serif",
534
+ codeFont: 'ui-monospace, "JetBrains Mono", "Fira Code", monospace',
535
+ fontSize: 16,
536
+ headingSizes: [32, 28, 24, 20, 18, 16],
537
+ codeFontSize: 15,
538
+ tableFontSize: 14,
539
+ codeLineHeight: 24,
540
+ bodyLineHeight: 24,
541
+ blockGap: 16,
542
+ codePadding: 18,
543
+ codeRadius: 8,
544
+ listGap: 6,
545
+ listItemGap: 4,
546
+ quoteIndent: 16,
547
+ quoteBorderWidth: 4,
548
+ quoteInnerGap: 8,
549
+ imageRadius: 8,
550
+ inlineImageScale: 1.15
551
+ };
552
+ function resolveTheme(theme) {
553
+ const merged = { ...DEFAULT_THEME, ...theme };
554
+ if (theme?.tableFontSize === void 0) {
555
+ merged.tableFontSize = Math.max(1, merged.fontSize - 2);
686
556
  }
687
- return false;
688
- }
689
- var FENCE_OPEN_RE = /^ {0,3}(`{3,}|~{3,})/;
690
- var FENCE_CLOSE_RE = /^ {0,3}(`+|~+)[ \t]*$/;
691
- function isFenceClosed(raw) {
692
- const lines = raw.split("\n");
693
- const open = FENCE_OPEN_RE.exec(lines[0]);
694
- if (!open) return false;
695
- const marker = open[1][0];
696
- const minLen = open[1].length;
697
- for (let i = 1; i < lines.length; i++) {
698
- const close = FENCE_CLOSE_RE.exec(lines[i]);
699
- if (close && close[1][0] === marker && close[1].length >= minLen) return true;
557
+ if (theme?.quoteTextColor === void 0) {
558
+ merged.quoteTextColor = merged.textColor;
700
559
  }
701
- return false;
702
- }
703
- function paragraphHasImage(token) {
704
- return token.tokens?.some((child) => child.type === "image") === true;
560
+ return merged;
705
561
  }
706
- function lastIndexOfImage(tokens) {
707
- for (let i = tokens.length - 1; i >= 0; i--) {
708
- if (tokens[i].type === "image") return i;
709
- }
710
- return -1;
562
+ function headingSize(theme, depth) {
563
+ const sizes = theme.headingSizes;
564
+ if (sizes.length === 0) return theme.fontSize;
565
+ const idx = Math.min(Math.max(depth, 1) - 1, sizes.length - 1);
566
+ return sizes[idx] ?? theme.fontSize;
711
567
  }
712
- function expectedImageParagraphChildren(tokens) {
713
- let children = 0;
714
- let inTextRun = false;
715
- for (const token of tokens) {
716
- if (token.type === "image") {
717
- children++;
718
- inTextRun = false;
719
- } else if (!inTextRun) {
720
- children++;
721
- inTextRun = true;
722
- }
723
- }
724
- return children;
725
- }
726
- function rendersAsMath(token) {
727
- return MATH_LANGS.has((token.lang ?? "").toLowerCase()) && token.text.trim() !== "" && isFenceClosed(token.raw);
728
- }
729
- function renderMathToSVGDataURI(formula, displayMode, color) {
730
- const key = `${displayMode ? 1 : 0}\0${color}\0${formula}`;
731
- const hit = mathCache.get(key);
732
- if (hit) return hit;
733
- if (!mathConverter) return null;
734
- const converted = mathConverter(formula, displayMode, color);
735
- if (converted) {
736
- if (mathCache.size >= MATH_CACHE_LIMIT) {
737
- const oldest = mathCache.keys().next().value;
738
- if (oldest !== void 0) mathCache.delete(oldest);
739
- }
740
- mathCache.set(key, converted);
741
- }
742
- return converted;
743
- }
744
- function applyMathColor(svg, color) {
745
- const openTag = svg.match(/<svg\b[^>]*>/);
746
- if (!openTag) return svg;
747
- const tag = openTag[0];
748
- const colored = /\bstyle="/.test(tag) ? tag.replace(/\bstyle="/, `style="color:${color};`) : tag.replace(/^<svg\b/, `<svg style="color:${color}"`);
749
- return svg.replace(tag, colored);
750
- }
751
- function convertMathToSVGDataURI(formula, displayMode, typeset, color) {
752
- try {
753
- const svgString = applyMathColor(typeset(formula, displayMode), color);
754
- const wMatch = svgString.match(/width="([^"]+)ex"/);
755
- const hMatch = svgString.match(/height="([^"]+)ex"/);
756
- const wEx = wMatch ? parseFloat(wMatch[1]) : 10;
757
- const hEx = hMatch ? parseFloat(hMatch[1]) : 2;
758
- const vMatch = svgString.match(/vertical-align:\s*(-?[\d.]+)ex/);
759
- const depthEx = vMatch ? Math.max(0, -parseFloat(vMatch[1])) : 0;
760
- const base64 = btoa(unescape(encodeURIComponent(svgString)));
761
- return {
762
- uri: `data:image/svg+xml;base64,${base64}`,
763
- widthEx: wEx,
764
- heightEx: hEx,
765
- depthEx
766
- };
767
- } catch (e) {
768
- console.error("MathJax error", e);
769
- return null;
770
- }
771
- }
772
- var markdownWorker = null;
773
- var workerIdCounter = 0;
774
- var workerInstanceCounter = 0;
775
- var workerCallbacks = /* @__PURE__ */ new Map();
776
- function runSyncFallback(entry) {
777
- try {
778
- entry.cb(0, lexMarkdown(entry.text, entry.userTiming), true);
779
- } catch (err) {
780
- console.warn("Markdown sync fallback parse failed", err);
781
- entry.onDropped?.();
782
- }
783
- }
784
- if (typeof Worker !== "undefined") {
785
- try {
786
- const blob = new Blob([WORKER_SOURCE_STRING], {
787
- type: "application/javascript"
788
- });
789
- markdownWorker = new Worker(URL.createObjectURL(blob));
790
- markdownWorker.onmessage = (e) => {
791
- const { id, matchLen, tail, error, needResync, lexerMs, sourceCharsLexed } = e.data;
792
- const entry = workerCallbacks.get(id);
793
- if (entry) {
794
- workerCallbacks.delete(id);
795
- if (needResync && entry.onNeedResync) {
796
- entry.onNeedResync();
797
- } else if (needResync) {
798
- runSyncFallback(entry);
799
- } else if (!error) {
800
- entry.cb(matchLen, tail, false, {
801
- lexerMs: typeof lexerMs === "number" ? lexerMs : 0,
802
- sourceCharsLexed: typeof sourceCharsLexed === "number" ? sourceCharsLexed : 0
803
- });
804
- } else {
805
- runSyncFallback(entry);
806
- }
807
- }
808
- };
809
- markdownWorker.onerror = () => {
810
- const pending = [...workerCallbacks.values()];
811
- workerCallbacks.clear();
812
- markdownWorker = null;
813
- for (const entry of pending) runSyncFallback(entry);
814
- };
815
- } catch (err) {
816
- console.warn("Failed to initialize MarkdownWorker", err);
817
- }
818
- }
819
- var DEFAULT_THEME = {
820
- textColor: "#e2e8f0",
821
- headingColor: "#f8fafc",
822
- codeColor: "#a5f3fc",
823
- codeBgColor: "rgba(30, 41, 59, 0.85)",
824
- quoteBorderColor: "#6366f1",
825
- quoteTextColor: "#94a3b8",
826
- hrColor: "rgba(148, 163, 184, 0.3)",
827
- tableBgColor: "rgba(15, 15, 25, 0.4)",
828
- tableHeaderBgColor: "rgba(255, 255, 255, 0.08)",
829
- bodyFont: "Inter, system-ui, sans-serif",
830
- codeFont: 'ui-monospace, "JetBrains Mono", "Fira Code", monospace',
831
- fontSize: 16
832
- };
833
- var HorizontalRule = class extends import_core.Entity {
834
- color;
835
- constructor(w, color) {
836
- super();
837
- this.width = w;
838
- this.height = 1;
839
- this.color = color;
840
- }
841
- isPointInside() {
842
- return false;
843
- }
844
- render(r) {
845
- r.beginPath();
846
- r.moveTo(0, 0);
847
- r.lineTo(this.width, 0);
848
- r.stroke(this.color, 1);
849
- }
850
- };
851
- var QuoteBorder = class extends import_core.Entity {
852
- color;
853
- constructor(height, color) {
854
- super();
855
- this.width = 4;
856
- this.height = height;
857
- this.color = color;
858
- }
859
- isPointInside() {
860
- return false;
861
- }
862
- render(r) {
863
- r.beginPath();
864
- r.roundRect(0, 0, this.width, this.height, 2);
865
- r.fill(this.color);
866
- }
867
- };
868
- var MarkdownContainer = class extends import_core.Entity {
869
- isPointInside(_globalX, _globalY) {
870
- return false;
871
- }
872
- render(_r) {
873
- }
874
- };
875
- var MathBlock = class extends MarkdownContainer {
876
- /**
877
- * The TeX source, exactly as written between the delimiters.
878
- *
879
- * Also the projected text and the accessible name, so this is the one string a
880
- * reader can find, select, and copy.
881
- */
882
- formula;
883
- /** The `data:image/svg+xml` URI of the typeset glyphs. */
884
- svgUri;
885
- constructor(formula, svgUri) {
886
- super();
887
- this.formula = formula;
888
- this.svgUri = svgUri;
889
- }
890
- getDevtoolsDescriptor() {
891
- return {
892
- kind: "MathBlock",
893
- groups: [
894
- {
895
- label: "Math",
896
- fields: [{ label: "formula", value: this.formula, readOnly: true }]
897
- }
898
- ]
899
- };
900
- }
901
- };
568
+
569
+ // src/markdown-code.ts
902
570
  var KEYWORD_SETS = {
903
571
  js: /* @__PURE__ */ new Set([
904
572
  "const",
@@ -1073,10 +741,10 @@ function highlightLine(line, lang, theme) {
1073
741
  return [{ text: line, color: theme.codeColor }];
1074
742
  }
1075
743
  const segments = [];
1076
- const KEYWORD_COLOR = "#c084fc";
1077
- const STRING_COLOR = "#86efac";
1078
- const COMMENT_COLOR = "#64748b";
1079
- const NUMBER_COLOR = "#fbbf24";
744
+ const KEYWORD_COLOR = theme.syntaxKeywordColor;
745
+ const STRING_COLOR = theme.syntaxStringColor;
746
+ const COMMENT_COLOR = theme.syntaxCommentColor;
747
+ const NUMBER_COLOR = theme.syntaxNumberColor;
1080
748
  let i = 0;
1081
749
  let buf = "";
1082
750
  const flush = (color) => {
@@ -1159,16 +827,32 @@ var CodeBlock = class extends import_ui.UIComponent {
1159
827
  contentEpoch = 0;
1160
828
  lang;
1161
829
  theme;
1162
- lineH = 24;
1163
- pad = 18;
830
+ /**
831
+ * Assigned in the constructor rather than as a field initializer: both come
832
+ * from `theme`, and a field initializer runs before the constructor body has
833
+ * a `theme` to read.
834
+ */
835
+ lineH;
836
+ pad;
1164
837
  codeFont;
1165
838
  selectable;
839
+ /**
840
+ * @param theme Any subset of {@link MarkdownTheme}; missing keys fall back to
841
+ * `DEFAULT_THEME` in `./theme`. Accepting a partial theme keeps callers that were
842
+ * written against an earlier, smaller `MarkdownTheme` working — this class
843
+ * is public API, and a hand-built theme literal would otherwise start
844
+ * throwing `lineHeight must be a positive finite number` the moment a new
845
+ * size key was added.
846
+ */
1166
847
  constructor(code, lang, maxWidth, theme, selectable = true) {
1167
848
  super();
849
+ const resolved = resolveTheme(theme);
1168
850
  this.source = code;
1169
851
  this.lang = lang;
1170
- this.theme = theme;
1171
- this.codeFont = `15px ${theme.codeFont}`;
852
+ this.theme = resolved;
853
+ this.lineH = resolved.codeLineHeight;
854
+ this.pad = resolved.codePadding;
855
+ this.codeFont = `${resolved.codeFontSize}px ${resolved.codeFont}`;
1172
856
  this.selectable = selectable;
1173
857
  this.lines = [];
1174
858
  this.width = maxWidth;
@@ -1219,7 +903,7 @@ var CodeBlock = class extends import_ui.UIComponent {
1219
903
  for (let row = 0; row < grid.lines.length; row++) {
1220
904
  const line = grid.lines[row];
1221
905
  const y = this.pad + row * this.lineH;
1222
- if (!(0, import_core.contentLineInHint)(hint, y, this.lineH)) continue;
906
+ if (!(0, import_core2.contentLineInHint)(hint, y, this.lineH)) continue;
1223
907
  rows[row] = {
1224
908
  text: this.source.slice(line.sourceStart, line.sourceEnd),
1225
909
  separatorAfter: this.source.slice(line.sourceEnd, line.nextSourceStart) || void 0,
@@ -1283,7 +967,7 @@ var CodeBlock = class extends import_ui.UIComponent {
1283
967
  ensureGrid() {
1284
968
  const cellWidth = this.cellWidth || Math.max(1, (0, import_ui.measureText)("M", this.codeFont));
1285
969
  if (!this.grid || this.grid.source !== this.source || this.grid.font !== this.codeFont || this.grid.cellWidth !== cellWidth) {
1286
- this.grid = (0, import_core.prepareContentGrid)(this.source, {
970
+ this.grid = (0, import_core2.prepareContentGrid)(this.source, {
1287
971
  font: this.codeFont,
1288
972
  cellWidth,
1289
973
  lineHeight: this.lineH,
@@ -1298,7 +982,7 @@ var CodeBlock = class extends import_ui.UIComponent {
1298
982
  }
1299
983
  render(r) {
1300
984
  r.beginPath();
1301
- r.roundRect(0, 0, this.width, this.height, 8);
985
+ r.roundRect(0, 0, this.width, this.height, this.theme.codeRadius);
1302
986
  r.fill(this.theme.codeBgColor);
1303
987
  const grid = this.ensureGrid();
1304
988
  const atlas = codeGlyphAtlas(r);
@@ -1361,7 +1045,7 @@ function codeGlyphAtlas(r) {
1361
1045
  lastCodeAtlas = existing;
1362
1046
  return existing;
1363
1047
  }
1364
- const atlas = new import_core.GlyphRasterAtlas({ dpr, maxSize: 2048 });
1048
+ const atlas = new import_core2.GlyphRasterAtlas({ dpr, maxSize: 2048 });
1365
1049
  codeAtlases.set(dpr, atlas);
1366
1050
  if (codeAtlases.size > MAX_CODE_ATLASES) {
1367
1051
  const oldestKey = codeAtlases.keys().next().value;
@@ -1378,6 +1062,302 @@ function codeAtlasStats() {
1378
1062
  function codeAtlas() {
1379
1063
  return lastCodeAtlas;
1380
1064
  }
1065
+
1066
+ // src/markdown-math.ts
1067
+ var mathConverter = null;
1068
+ var mathLoad = null;
1069
+ function preloadMathJax() {
1070
+ if (mathLoad) return mathLoad;
1071
+ mathLoad = (async () => {
1072
+ const { emitSVG, layout } = await import("@vectojs/tex");
1073
+ mathConverter = (formula, displayMode, color) => convertMathToSVGDataURI(formula, displayMode, color, layout, emitSVG);
1074
+ })().catch((e) => {
1075
+ console.error("Math engine failed to load; formulas will render as TeX source", e);
1076
+ });
1077
+ return mathLoad;
1078
+ }
1079
+ function isMathJaxReady() {
1080
+ return mathConverter !== null;
1081
+ }
1082
+ var EX_PER_EM = 0.4421;
1083
+ function exToPx(ex, fontSize) {
1084
+ return ex * fontSize * EX_PER_EM;
1085
+ }
1086
+ function fontSizeFromFont(font) {
1087
+ const pxIndex = font.indexOf("px");
1088
+ if (pxIndex <= 0) return void 0;
1089
+ let start = pxIndex;
1090
+ while (start > 0) {
1091
+ const ch = font[start - 1];
1092
+ if (ch >= "0" && ch <= "9" || ch === ".") start--;
1093
+ else break;
1094
+ }
1095
+ if (start === pxIndex) return void 0;
1096
+ const size = parseFloat(font.slice(start, pxIndex));
1097
+ return Number.isFinite(size) ? size : void 0;
1098
+ }
1099
+ var mathCache = /* @__PURE__ */ new Map();
1100
+ var MATH_CACHE_LIMIT = 256;
1101
+ var inlineMathRasters = /* @__PURE__ */ new Map();
1102
+ var inlineMathRasterWaiters = /* @__PURE__ */ new Set();
1103
+ function subscribeInlineMathRaster(notify) {
1104
+ inlineMathRasterWaiters.add(notify);
1105
+ }
1106
+ function unsubscribeInlineMathRaster(notify) {
1107
+ inlineMathRasterWaiters.delete(notify);
1108
+ }
1109
+ function ensureInlineMathRaster(uri) {
1110
+ const existing = inlineMathRasters.get(uri);
1111
+ if (existing) return existing;
1112
+ const entry = { decoded: false };
1113
+ inlineMathRasters.set(uri, entry);
1114
+ if (typeof globalThis.Image !== "undefined") {
1115
+ const bitmap = new globalThis.Image();
1116
+ bitmap.onload = () => {
1117
+ entry.decoded = true;
1118
+ for (const notify of inlineMathRasterWaiters) notify();
1119
+ };
1120
+ bitmap.src = uri;
1121
+ entry.bitmap = bitmap;
1122
+ }
1123
+ return entry;
1124
+ }
1125
+ function paintInlineMath(uri, surface, box) {
1126
+ const raster = ensureInlineMathRaster(uri);
1127
+ if (!raster.decoded || !raster.bitmap) return;
1128
+ surface.drawImage(raster.bitmap, box.x, box.y, box.width, box.height);
1129
+ }
1130
+ var MATH_LANGS = /* @__PURE__ */ new Set(["math", "latex", "tex"]);
1131
+ function containsInlineMath(token) {
1132
+ if (token.type === "inlineMath") return true;
1133
+ const anyToken = token;
1134
+ if (Array.isArray(anyToken.tokens) && anyToken.tokens.some(containsInlineMath)) {
1135
+ return true;
1136
+ }
1137
+ if (Array.isArray(anyToken.items) && anyToken.items.some(containsInlineMath)) {
1138
+ return true;
1139
+ }
1140
+ if (Array.isArray(anyToken.header) && anyToken.header.some(containsInlineMath)) {
1141
+ return true;
1142
+ }
1143
+ if (Array.isArray(anyToken.rows)) {
1144
+ for (const row of anyToken.rows) {
1145
+ if (Array.isArray(row) && row.some(containsInlineMath)) return true;
1146
+ }
1147
+ }
1148
+ return false;
1149
+ }
1150
+ var FENCE_OPEN_RE = /^ {0,3}(`{3,}|~{3,})/;
1151
+ var FENCE_CLOSE_RE = /^ {0,3}(`+|~+)[ \t]*$/;
1152
+ function isFenceClosed(raw) {
1153
+ const lines = raw.split("\n");
1154
+ const open = FENCE_OPEN_RE.exec(lines[0]);
1155
+ if (!open) return false;
1156
+ const marker = open[1][0];
1157
+ const minLen = open[1].length;
1158
+ for (let i = 1; i < lines.length; i++) {
1159
+ const close = FENCE_CLOSE_RE.exec(lines[i]);
1160
+ if (close && close[1][0] === marker && close[1].length >= minLen) return true;
1161
+ }
1162
+ return false;
1163
+ }
1164
+ function rendersAsMath(token) {
1165
+ return MATH_LANGS.has((token.lang ?? "").toLowerCase()) && token.text.trim() !== "" && isFenceClosed(token.raw);
1166
+ }
1167
+ function renderMathToSVGDataURI(formula, displayMode, color) {
1168
+ const key = `${displayMode ? 1 : 0}\0${color}\0${formula}`;
1169
+ const hit = mathCache.get(key);
1170
+ if (hit) return hit;
1171
+ if (!mathConverter) return null;
1172
+ const converted = mathConverter(formula, displayMode, color);
1173
+ if (converted) {
1174
+ if (mathCache.size >= MATH_CACHE_LIMIT) {
1175
+ const oldest = mathCache.keys().next().value;
1176
+ if (oldest !== void 0) mathCache.delete(oldest);
1177
+ }
1178
+ mathCache.set(key, converted);
1179
+ }
1180
+ return converted;
1181
+ }
1182
+ var MATH_PAD_EM = 0.05;
1183
+ var KATEX_FONT_SCALE = 1.21;
1184
+ var EX_PER_KATEX_EM = KATEX_FONT_SCALE / EX_PER_EM;
1185
+ function convertMathToSVGDataURI(formula, displayMode, color, layout, emitSVG) {
1186
+ try {
1187
+ const emitted = emitSVG(layout(formula, { displayMode }), {
1188
+ color,
1189
+ padEm: MATH_PAD_EM
1190
+ });
1191
+ if (emitted.missing.length > 0) return null;
1192
+ const pad2 = MATH_PAD_EM * 2;
1193
+ const base64 = btoa(unescape(encodeURIComponent(emitted.svg)));
1194
+ return {
1195
+ uri: `data:image/svg+xml;base64,${base64}`,
1196
+ widthEx: (emitted.width + pad2) * EX_PER_KATEX_EM,
1197
+ heightEx: (emitted.height + emitted.depth + pad2) * EX_PER_KATEX_EM,
1198
+ depthEx: (emitted.depth + MATH_PAD_EM) * EX_PER_KATEX_EM
1199
+ };
1200
+ } catch (e) {
1201
+ console.error("Math typesetting error", e);
1202
+ return null;
1203
+ }
1204
+ }
1205
+ var MathBlock = class extends MarkdownContainer {
1206
+ /**
1207
+ * The TeX source, exactly as written between the delimiters.
1208
+ *
1209
+ * Also the projected text and the accessible name, so this is the one string a
1210
+ * reader can find, select, and copy.
1211
+ */
1212
+ formula;
1213
+ /** The `data:image/svg+xml` URI of the typeset glyphs. */
1214
+ svgUri;
1215
+ constructor(formula, svgUri) {
1216
+ super();
1217
+ this.formula = formula;
1218
+ this.svgUri = svgUri;
1219
+ }
1220
+ getDevtoolsDescriptor() {
1221
+ return {
1222
+ kind: "MathBlock",
1223
+ groups: [
1224
+ {
1225
+ label: "Math",
1226
+ fields: [{ label: "formula", value: this.formula, readOnly: true }]
1227
+ }
1228
+ ]
1229
+ };
1230
+ }
1231
+ };
1232
+
1233
+ // src/markdown-inline.ts
1234
+ var import_core3 = require("@vectojs/core");
1235
+ var import_ui2 = require("@vectojs/ui");
1236
+
1237
+ // src/markdown-image.ts
1238
+ function paragraphHasImage(token) {
1239
+ return containsImage(token.tokens);
1240
+ }
1241
+ function containsImage(tokens) {
1242
+ if (!tokens) return false;
1243
+ for (const token of tokens) {
1244
+ if (token.type === "image") return true;
1245
+ const anyToken = token;
1246
+ if (containsImage(anyToken.tokens)) return true;
1247
+ if (Array.isArray(anyToken.items) && containsImage(anyToken.items)) {
1248
+ return true;
1249
+ }
1250
+ const table = token;
1251
+ if (Array.isArray(table.header) && table.header.some((cell) => containsImage(cell.tokens))) {
1252
+ return true;
1253
+ }
1254
+ if (Array.isArray(table.rows) && table.rows.some((row) => row.some((cell) => containsImage(cell.tokens)))) {
1255
+ return true;
1256
+ }
1257
+ }
1258
+ return false;
1259
+ }
1260
+ function imagesOf(tokens) {
1261
+ const images = [];
1262
+ for (const token of tokens ?? []) {
1263
+ if (token.type === "image") {
1264
+ images.push(token);
1265
+ continue;
1266
+ }
1267
+ images.push(...imagesOf(token.tokens));
1268
+ }
1269
+ return images;
1270
+ }
1271
+ function stripImages(token) {
1272
+ const children = token.tokens;
1273
+ if (!children) return token;
1274
+ const kept = [];
1275
+ for (const child of children) {
1276
+ if (child.type === "image") continue;
1277
+ const grandchildren = child.tokens;
1278
+ if (grandchildren && containsImage(grandchildren)) {
1279
+ const stripped = stripImages(child);
1280
+ const remaining = stripped.tokens;
1281
+ if (remaining && remaining.length > 0) kept.push(stripped);
1282
+ continue;
1283
+ }
1284
+ kept.push(child);
1285
+ }
1286
+ return { ...token, tokens: kept };
1287
+ }
1288
+ function liftNestedImages(tokens) {
1289
+ const lifted = [];
1290
+ for (const token of tokens) {
1291
+ if (token.type === "image") {
1292
+ lifted.push(token);
1293
+ continue;
1294
+ }
1295
+ const children = token.tokens;
1296
+ if (children && containsImage(children)) {
1297
+ lifted.push(...liftNestedImages(children));
1298
+ continue;
1299
+ }
1300
+ lifted.push(token);
1301
+ }
1302
+ return lifted;
1303
+ }
1304
+ function lastIndexOfImage(tokens) {
1305
+ for (let i = tokens.length - 1; i >= 0; i--) {
1306
+ if (tokens[i].type === "image") return i;
1307
+ }
1308
+ return -1;
1309
+ }
1310
+ var inlineImageRasters = /* @__PURE__ */ new Map();
1311
+ var inlineImageRasterWaiters = /* @__PURE__ */ new Set();
1312
+ function subscribeInlineImageRaster(notify) {
1313
+ inlineImageRasterWaiters.add(notify);
1314
+ }
1315
+ function unsubscribeInlineImageRaster(notify) {
1316
+ inlineImageRasterWaiters.delete(notify);
1317
+ }
1318
+ function ensureInlineImageRaster(src) {
1319
+ const existing = inlineImageRasters.get(src);
1320
+ if (existing) return existing;
1321
+ const entry = { decoded: false };
1322
+ inlineImageRasters.set(src, entry);
1323
+ if (typeof globalThis.Image !== "undefined") {
1324
+ const bitmap = new globalThis.Image();
1325
+ bitmap.onload = () => {
1326
+ entry.decoded = true;
1327
+ entry.naturalWidth = bitmap.naturalWidth || void 0;
1328
+ entry.naturalHeight = bitmap.naturalHeight || void 0;
1329
+ for (const notify of inlineImageRasterWaiters) notify();
1330
+ };
1331
+ bitmap.onerror = () => {
1332
+ entry.failed = true;
1333
+ for (const notify of inlineImageRasterWaiters) notify();
1334
+ };
1335
+ bitmap.src = src;
1336
+ entry.bitmap = bitmap;
1337
+ }
1338
+ return entry;
1339
+ }
1340
+ function paintInlineImage(src, surface, box) {
1341
+ const raster = ensureInlineImageRaster(src);
1342
+ if (!raster.decoded || !raster.bitmap) return;
1343
+ surface.drawImage(raster.bitmap, box.x, box.y, box.width, box.height);
1344
+ }
1345
+ function expectedImageParagraphChildren(tokens) {
1346
+ let children = 0;
1347
+ let inTextRun = false;
1348
+ for (const token of liftNestedImages(tokens)) {
1349
+ if (token.type === "image") {
1350
+ children++;
1351
+ inTextRun = false;
1352
+ } else if (!inTextRun) {
1353
+ children++;
1354
+ inTextRun = true;
1355
+ }
1356
+ }
1357
+ return children;
1358
+ }
1359
+
1360
+ // src/markdown-inline.ts
1381
1361
  function decodeEntities(text) {
1382
1362
  return text.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&amp;/g, "&");
1383
1363
  }
@@ -1453,7 +1433,7 @@ function collectSpans(tokens, inherited, theme, out, blockFontSize) {
1453
1433
  if (rendered) {
1454
1434
  const uri = rendered.uri;
1455
1435
  out.push({
1456
- text: import_core.OBJECT_REPLACEMENT,
1436
+ text: import_core3.OBJECT_REPLACEMENT,
1457
1437
  style: inherited,
1458
1438
  object: {
1459
1439
  width: exToPx(rendered.widthEx, runSize),
@@ -1470,17 +1450,50 @@ function collectSpans(tokens, inherited, theme, out, blockFontSize) {
1470
1450
  } else {
1471
1451
  out.push({
1472
1452
  text: decodeEntities(t.raw),
1473
- style: { ...inherited, color: "#fcd34d" }
1453
+ style: { ...inherited, color: theme.mathFallbackColor }
1474
1454
  });
1475
1455
  }
1476
1456
  break;
1477
1457
  }
1458
+ case "image": {
1459
+ const t = token;
1460
+ const runSize = inherited.fontSize ?? blockFontSize ?? theme.fontSize;
1461
+ const raster = ensureInlineImageRaster(t.href);
1462
+ if (raster.failed) {
1463
+ out.push({ text: decodeEntities(t.text), style: inherited });
1464
+ break;
1465
+ }
1466
+ const height = runSize * theme.inlineImageScale;
1467
+ const aspect = raster.naturalWidth && raster.naturalHeight ? raster.naturalWidth / raster.naturalHeight : 1;
1468
+ const src = t.href;
1469
+ out.push({
1470
+ text: import_core3.OBJECT_REPLACEMENT,
1471
+ style: inherited,
1472
+ object: {
1473
+ width: height * aspect,
1474
+ height,
1475
+ // Sits on the baseline like a cap-height glyph rather than hanging
1476
+ // below it; an image has no descender to align.
1477
+ depth: 0,
1478
+ // The accessible name, and what a copy yields. Without it the
1479
+ // invisible U+FFFC sentinel is all a screen reader receives.
1480
+ alt: t.text,
1481
+ // What this object PAINTS, which `alt` does not determine: two badges
1482
+ // can share alt text and differ in URL. Without it the paragraph memo
1483
+ // serves the first one's painter to the second and every row of a badge
1484
+ // column draws the first row's badge.
1485
+ key: src,
1486
+ paint: (surface, box) => paintInlineImage(src, surface, box)
1487
+ }
1488
+ });
1489
+ break;
1490
+ }
1478
1491
  case "link": {
1479
1492
  const t = token;
1480
1493
  const linkStyle = {
1481
1494
  ...inherited,
1482
1495
  href: t.href,
1483
- color: "#38bdf8"
1496
+ color: theme.linkColor
1484
1497
  };
1485
1498
  if (t.tokens && t.tokens.length > 0) {
1486
1499
  collectSpans(t.tokens, linkStyle, theme, out, blockFontSize);
@@ -1515,56 +1528,484 @@ function collectSpans(tokens, inherited, theme, out, blockFontSize) {
1515
1528
  }
1516
1529
  }
1517
1530
  }
1518
- function findUnclosedInline(text) {
1519
- let best = null;
1520
- const tick = text.lastIndexOf("`");
1521
- if (tick !== -1 && tick < text.length - 1) {
1522
- return { kind: "codespan", at: tick, contentAt: tick + 1 };
1531
+ function findUnclosedInline(text) {
1532
+ let best = null;
1533
+ const tick = text.lastIndexOf("`");
1534
+ if (tick !== -1 && tick < text.length - 1) {
1535
+ return { kind: "codespan", at: tick, contentAt: tick + 1 };
1536
+ }
1537
+ if (tick !== -1) return null;
1538
+ const emphasis = /(\*{1,2}(?!\*)|_{1,2}(?!_))(?=[^\s])/g;
1539
+ for (let match = emphasis.exec(text); match !== null; match = emphasis.exec(text)) {
1540
+ const marker = match[1];
1541
+ const at = match.index;
1542
+ if (marker[0] === "_" && at > 0 && /[\w]/.test(text[at - 1])) continue;
1543
+ best = {
1544
+ kind: marker.length === 2 ? "strong" : "em",
1545
+ at,
1546
+ contentAt: at + marker.length
1547
+ };
1548
+ }
1549
+ const bracket = text.lastIndexOf("[");
1550
+ if (bracket !== -1 && bracket < text.length - 1 && (best === null || bracket > best.at)) {
1551
+ const closed = /\]\([^)]*\)/.test(text.slice(bracket));
1552
+ if (!closed) {
1553
+ best = { kind: "link", at: bracket, contentAt: bracket + 1 };
1554
+ }
1555
+ }
1556
+ return best;
1557
+ }
1558
+ function renderInlineToRichText(tokens, fallbackText, font, color, maxWidth, theme, selectable, onLinkClick) {
1559
+ const spans = [];
1560
+ if (tokens && tokens.length > 0) {
1561
+ collectSpans(tokens, {}, theme, spans, fontSizeFromFont(font));
1562
+ }
1563
+ if (spans.length === 0) {
1564
+ spans.push({ text: decodeEntities(fallbackText) });
1565
+ }
1566
+ return new import_ui2.RichText(spans, {
1567
+ font,
1568
+ color,
1569
+ maxWidth,
1570
+ linkColor: theme.linkColor,
1571
+ selectable,
1572
+ onLinkClick
1573
+ });
1574
+ }
1575
+
1576
+ // src/Markdown.ts
1577
+ var import_ui4 = require("@vectojs/ui");
1578
+
1579
+ // src/blockAffordances.ts
1580
+ var import_ui3 = require("@vectojs/ui");
1581
+ var LANGUAGE_EXTENSIONS = {
1582
+ bash: "sh",
1583
+ c: "c",
1584
+ cpp: "cpp",
1585
+ cs: "cs",
1586
+ css: "css",
1587
+ diff: "diff",
1588
+ dockerfile: "dockerfile",
1589
+ go: "go",
1590
+ graphql: "graphql",
1591
+ haskell: "hs",
1592
+ html: "html",
1593
+ java: "java",
1594
+ javascript: "js",
1595
+ js: "js",
1596
+ json: "json",
1597
+ jsonc: "jsonc",
1598
+ jsx: "jsx",
1599
+ kotlin: "kt",
1600
+ latex: "tex",
1601
+ lua: "lua",
1602
+ make: "mk",
1603
+ markdown: "md",
1604
+ md: "md",
1605
+ nix: "nix",
1606
+ php: "php",
1607
+ python: "py",
1608
+ py: "py",
1609
+ ruby: "rb",
1610
+ rust: "rs",
1611
+ rs: "rs",
1612
+ scss: "scss",
1613
+ sh: "sh",
1614
+ shell: "sh",
1615
+ sql: "sql",
1616
+ svelte: "svelte",
1617
+ swift: "swift",
1618
+ tex: "tex",
1619
+ toml: "toml",
1620
+ ts: "ts",
1621
+ tsx: "tsx",
1622
+ typescript: "ts",
1623
+ vue: "vue",
1624
+ xml: "xml",
1625
+ yaml: "yaml",
1626
+ yml: "yaml",
1627
+ zig: "zig",
1628
+ zsh: "sh"
1629
+ };
1630
+ function extensionForLanguage(lang) {
1631
+ const first = lang.trim().toLowerCase().split(/[\s:,{]/)[0] ?? "";
1632
+ return LANGUAGE_EXTENSIONS[first] ?? "txt";
1633
+ }
1634
+ function mimeForLanguage(lang) {
1635
+ const ext = extensionForLanguage(lang);
1636
+ if (ext === "json" || ext === "jsonc") return "application/json";
1637
+ if (ext === "html") return "text/html";
1638
+ if (ext === "css") return "text/css";
1639
+ if (ext === "xml" || ext === "svelte" || ext === "vue") return "text/plain";
1640
+ return "text/plain";
1641
+ }
1642
+ function escapeCsvField(value) {
1643
+ let needsQuoting = false;
1644
+ let hasQuote = false;
1645
+ for (const char of value) {
1646
+ if (char === '"') {
1647
+ hasQuote = true;
1648
+ needsQuoting = true;
1649
+ break;
1650
+ }
1651
+ if (char === "," || char === "\n" || char === "\r") needsQuoting = true;
1652
+ }
1653
+ if (!needsQuoting) return value;
1654
+ return hasQuote ? `"${value.replace(/"/g, '""')}"` : `"${value}"`;
1655
+ }
1656
+ function escapeMarkdownTableCell(cell) {
1657
+ let needsEscaping = false;
1658
+ for (const char of cell) {
1659
+ if (char === "\\" || char === "|") {
1660
+ needsEscaping = true;
1661
+ break;
1662
+ }
1663
+ }
1664
+ if (!needsEscaping) return cell;
1665
+ return cell.replace(/\\/g, "\\\\").replace(/\|/g, "\\|");
1666
+ }
1667
+ function tableToCsv(table) {
1668
+ const lines = [table.headers.map(escapeCsvField).join(",")];
1669
+ for (const row of table.rows) lines.push(row.map(escapeCsvField).join(","));
1670
+ return `\uFEFF${lines.join("\r\n")}`;
1671
+ }
1672
+ function tableToMarkdown(table) {
1673
+ const header = `| ${table.headers.map(escapeMarkdownTableCell).join(" | ")} |`;
1674
+ const divider = `| ${table.headers.map((_cell, index) => {
1675
+ switch (table.align[index]) {
1676
+ case "left":
1677
+ return ":---";
1678
+ case "center":
1679
+ return ":---:";
1680
+ case "right":
1681
+ return "---:";
1682
+ default:
1683
+ return "---";
1684
+ }
1685
+ }).join(" | ")} |`;
1686
+ const body = table.rows.map(
1687
+ (row) => `| ${table.headers.map((_cell, index) => escapeMarkdownTableCell(row[index] ?? "")).join(" | ")} |`
1688
+ );
1689
+ return [header, divider, ...body].join("\n");
1690
+ }
1691
+ function defaultWriteClipboard(text) {
1692
+ const clipboard = globalThis.navigator?.clipboard;
1693
+ clipboard?.writeText?.(text);
1694
+ }
1695
+ function defaultSaveFile(filename, content, mimeType) {
1696
+ const doc = globalThis.document;
1697
+ if (!doc?.body) return;
1698
+ const blob = new Blob([content], { type: mimeType });
1699
+ const url = URL.createObjectURL(blob);
1700
+ const anchor = doc.createElement("a");
1701
+ anchor.href = url;
1702
+ anchor.download = filename;
1703
+ doc.body.appendChild(anchor);
1704
+ anchor.click();
1705
+ doc.body.removeChild(anchor);
1706
+ URL.revokeObjectURL(url);
1707
+ }
1708
+ var BlockAffordanceButton = class _BlockAffordanceButton extends import_ui3.Button {
1709
+ constructor(label, successLabel, act, opts = {}) {
1710
+ super(label, { ...opts, onClick: () => this.run() });
1711
+ this.act = act;
1712
+ this.restingLabel = label;
1713
+ this.successLabel = successLabel;
1714
+ this.width = Math.max(this.width, (0, import_ui3.measureText)(successLabel, this.font) + 24);
1715
+ }
1716
+ act;
1717
+ /** How long the confirmation label stays up, in ms. */
1718
+ static FEEDBACK_MS = 1600;
1719
+ restingLabel;
1720
+ successLabel;
1721
+ feedbackTimer;
1722
+ /**
1723
+ * Runs the action, then shows the confirmation.
1724
+ *
1725
+ * The action runs first and a throw propagates: a clipboard write the browser
1726
+ * rejected must not be reported as a success.
1727
+ */
1728
+ run() {
1729
+ this.act();
1730
+ this.setTransientLabel(this.successLabel);
1731
+ if (this.feedbackTimer !== void 0) clearTimeout(this.feedbackTimer);
1732
+ this.feedbackTimer = setTimeout(() => {
1733
+ this.setTransientLabel(this.restingLabel);
1734
+ this.feedbackTimer = void 0;
1735
+ }, _BlockAffordanceButton.FEEDBACK_MS);
1736
+ }
1737
+ setTransientLabel(label) {
1738
+ this.label = label;
1739
+ this.textWidth = (0, import_ui3.measureText)(label, this.font);
1740
+ this.scene?.markDirty();
1741
+ }
1742
+ /**
1743
+ * The label a reader hears is the one they see, transient confirmation
1744
+ * included, so an AT user gets the same feedback a sighted user does.
1745
+ */
1746
+ getA11yAttributes() {
1747
+ return { ...super.getA11yAttributes(), label: this.label };
1748
+ }
1749
+ /** Clears the pending revert so a destroyed block leaves no timer behind. */
1750
+ destroy() {
1751
+ if (this.feedbackTimer !== void 0) {
1752
+ clearTimeout(this.feedbackTimer);
1753
+ this.feedbackTimer = void 0;
1754
+ }
1755
+ super.destroy();
1756
+ }
1757
+ };
1758
+ var BlockWithAffordances = class _BlockWithAffordances extends import_ui3.UIComponent {
1759
+ constructor(block, controls) {
1760
+ super();
1761
+ this.block = block;
1762
+ this.controls = controls;
1763
+ this.add(block);
1764
+ for (const control of controls) this.add(control);
1765
+ this.layoutAffordances();
1766
+ }
1767
+ block;
1768
+ controls;
1769
+ /** Gap between the block's edges and the controls, in px. */
1770
+ static INSET = 8;
1771
+ /** Gap between adjacent controls, in px. */
1772
+ static GAP = 6;
1773
+ /**
1774
+ * Places the controls right-aligned along the block's top edge.
1775
+ *
1776
+ * Laid out right-to-left from the block's right edge so the first control in
1777
+ * the list ends up leftmost, which keeps DOM order (and therefore tab order and
1778
+ * the a11y reading order) matching the visual order.
1779
+ */
1780
+ layoutAffordances() {
1781
+ this.width = this.block.width;
1782
+ this.height = this.block.height;
1783
+ let right = this.block.width - _BlockWithAffordances.INSET;
1784
+ for (let i = this.controls.length - 1; i >= 0; i--) {
1785
+ const control = this.controls[i];
1786
+ control.x = right - control.width;
1787
+ control.y = _BlockWithAffordances.INSET;
1788
+ right = control.x - _BlockWithAffordances.GAP;
1789
+ }
1790
+ }
1791
+ /**
1792
+ * Re-places the controls after the block's own box changed.
1793
+ *
1794
+ * Called by the owner when a block is resized or its content grew; the controls
1795
+ * are anchored to the right edge, so a width change moves them.
1796
+ */
1797
+ refreshAffordances() {
1798
+ this.layoutAffordances();
1799
+ this.scene?.markDirty();
1800
+ }
1801
+ /** The wrapper is a pass-through: its size is the block's size. */
1802
+ getLayoutControlledProperties() {
1803
+ return ["x", "y"];
1804
+ }
1805
+ /**
1806
+ * Projected as a group so assistive technology reports one labelled region
1807
+ * containing the block and its controls, rather than two unrelated siblings.
1808
+ */
1809
+ getA11yAttributes() {
1810
+ return { role: "group", pointerEvents: "none" };
1811
+ }
1812
+ render() {
1813
+ }
1814
+ };
1815
+ function tableContentOf(token) {
1816
+ return {
1817
+ headers: token.header.map((cell) => cell.text),
1818
+ rows: token.rows.map((row) => row.map((cell) => cell.text)),
1819
+ align: token.align
1820
+ };
1821
+ }
1822
+
1823
+ // src/frontMatter.ts
1824
+ var OPEN_RE = /^---[ \t]*\r?\n/;
1825
+ var OPENER_PREFIX_RE = /^(?:-|--|---[ \t]*\r?)$/;
1826
+ var KEY_RE = /^[^\s:#][^:]*:(?:[ \t].*)?$/;
1827
+ var CLOSE_RE = /^(?:---|\.\.\.)[ \t]*$/;
1828
+ var MAX_PENDING_CHARS = 4096;
1829
+ var NONE = { kind: "none" };
1830
+ var PENDING = { kind: "pending" };
1831
+ function scanFrontMatter(text, complete) {
1832
+ if (text.length === 0) return PENDING;
1833
+ const open = OPEN_RE.exec(text);
1834
+ if (!open) {
1835
+ return !complete && OPENER_PREFIX_RE.test(text) ? PENDING : NONE;
1836
+ }
1837
+ const decide = complete || text.length > MAX_PENDING_CHARS;
1838
+ const contentStart = open[0].length;
1839
+ let cursor = contentStart;
1840
+ let keyChecked = false;
1841
+ while (cursor < text.length) {
1842
+ const nl = text.indexOf("\n", cursor);
1843
+ if (nl === -1 && !decide) return PENDING;
1844
+ const line = text.slice(cursor, nl === -1 ? text.length : nl).replace(/\r$/, "");
1845
+ if (!keyChecked) {
1846
+ if (!KEY_RE.test(line)) return NONE;
1847
+ keyChecked = true;
1848
+ } else if (CLOSE_RE.test(line)) {
1849
+ return {
1850
+ kind: "found",
1851
+ raw: text.slice(contentStart, cursor),
1852
+ // A closer with no trailing newline ends the document, so the body is
1853
+ // empty rather than starting one character past the end.
1854
+ bodyStart: nl === -1 ? text.length : nl + 1
1855
+ };
1856
+ }
1857
+ if (nl === -1) break;
1858
+ cursor = nl + 1;
1859
+ }
1860
+ return decide ? NONE : PENDING;
1861
+ }
1862
+ function parseFrontMatterFields(raw) {
1863
+ const out = {};
1864
+ for (const rawLine of raw.split("\n")) {
1865
+ const line = rawLine.replace(/\r$/, "");
1866
+ if (line.length === 0 || /^[\s#]/.test(line)) continue;
1867
+ const sep = line.indexOf(":");
1868
+ if (sep <= 0) continue;
1869
+ const value = line.slice(sep + 1);
1870
+ if (value.length > 0 && value[0] !== " " && value[0] !== " ") continue;
1871
+ out[line.slice(0, sep).trim()] = unquote(value.trim());
1523
1872
  }
1524
- if (tick !== -1) return null;
1525
- const emphasis = /(\*{1,2}(?!\*)|_{1,2}(?!_))(?=[^\s])/g;
1526
- for (let match = emphasis.exec(text); match !== null; match = emphasis.exec(text)) {
1527
- const marker = match[1];
1528
- const at = match.index;
1529
- if (marker[0] === "_" && at > 0 && /[\w]/.test(text[at - 1])) continue;
1530
- best = {
1531
- kind: marker.length === 2 ? "strong" : "em",
1532
- at,
1533
- contentAt: at + marker.length
1534
- };
1873
+ return out;
1874
+ }
1875
+ function unquote(value) {
1876
+ if (value.length < 2) return value;
1877
+ const first = value[0];
1878
+ if ((first === '"' || first === "'") && value.endsWith(first)) {
1879
+ return value.slice(1, -1);
1535
1880
  }
1536
- const bracket = text.lastIndexOf("[");
1537
- if (bracket !== -1 && bracket < text.length - 1 && (best === null || bracket > best.at)) {
1538
- const closed = /\]\([^)]*\)/.test(text.slice(bracket));
1539
- if (!closed) {
1540
- best = { kind: "link", at: bracket, contentAt: bracket + 1 };
1541
- }
1881
+ return value;
1882
+ }
1883
+
1884
+ // src/MarkdownWorkerSource.ts
1885
+ var WORKER_SOURCE_STRING = '"use strict";(()=>{function V(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var _=V();function ke(t){_=t}var C={exec:()=>null};function P(t){let e=[];return n=>{let s=Math.max(0,Math.min(3,n-1)),r=e[s];return r||(r=t(s),e[s]=r),r}}function k(t,e=""){let n=typeof t=="string"?t:t.source,s={replace:(r,l)=>{let a=typeof l=="string"?l:l.source;return a=a.replace(x.caret,"$1"),n=n.replace(r,a),s},getRegex:()=>new RegExp(n,e)};return s}var _e=((t="")=>{try{return!!new RegExp("(?<=1)(?<!1)"+t)}catch{return!1}})(),x={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:t=>new RegExp(`^( {0,3}${t})((?:[ ][^\\\\n]*)?(?:\\\\n|$))`),nextBulletRegex:P(t=>new RegExp(`^ {0,${t}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ ][^\\\\n]*)?(?:\\\\n|$))`)),hrRegex:P(t=>new RegExp(`^ {0,${t}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`)),fencesBeginRegex:P(t=>new RegExp(`^ {0,${t}}(?:\\`\\`\\`|~~~)`)),headingBeginRegex:P(t=>new RegExp(`^ {0,${t}}#`)),htmlBeginRegex:P(t=>new RegExp(`^ {0,${t}}<(?:[a-z].*>|!--)`,"i")),blockquoteBeginRegex:P(t=>new RegExp(`^ {0,${t}}>`))},Pe=/^(?:[ \\t]*(?:\\n|$))+/,Me=/^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/,Ee=/^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/,v=/^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/,Be=/^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/,K=/ {0,3}(?:[*+-]|\\d{1,9}[.)])/,fe=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,de=k(fe).replace(/bull/g,K).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(),qe=k(fe).replace(/bull/g,K).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(),J=/^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \\t]+\\n)[^\\n]+)*)/,ve=/^[^\\n]+/,Y=/(?!\\s*\\])(?:\\\\[\\s\\S]|[^\\[\\]\\\\])+/,De=k(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/).replace("label",Y).replace("title",/(?:"(?:\\\\"?|[^"\\\\])*"|\'[^\'\\n]*(?:\\n[^\'\\n]+)*\\n?\'|\\([^()]*\\))/).getRegex(),Ze=k(/^(bull)([ \\t][^\\n]*?)?(?:\\n|$)/).replace(/bull/g,K).getRegex(),N="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",ee=/<!--(?:-?>|[\\s\\S]*?(?:-->|$))/,Oe=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",ee).replace("tag",N).replace("attribute",/ +[a-zA-Z:_][\\w.:-]*(?: *= *"[^"\\n]*"| *= *\'[^\'\\n]*\'| *= *[^\\s"\'=<>`]+)?/).getRegex(),xe=t=>k(J).replace("hr",v).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",t).replace("html","</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",N).getRegex(),Qe=xe(/ {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]/),Ne=xe(/ {0,3}(?:[*+-]|\\d{1,9}[.)])(?:[ \\t]|\\n|$)/),He=k(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/).replace("paragraph",Ne).getRegex(),te={blockquote:He,code:Me,def:De,fences:Ee,heading:Be,hr:v,html:Oe,lheading:de,list:Ze,newline:Pe,paragraph:Qe,table:C,text:ve},ae=k("^ *([^\\\\n ].*)\\\\n {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)").replace("hr",v).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",N).getRegex(),je={...te,lheading:qe,table:ae,paragraph:k(J).replace("hr",v).replace("heading"," {0,3}#{1,6}(?:\\\\s|$)").replace("|lheading","").replace("table",ae).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",N).getRegex()},Ge={...te,html:k(`^ *(?:comment *(?:\\\\n|\\\\s*$)|<(tag)[\\\\s\\\\S]+?</\\\\1> *(?:\\\\n{2,}|\\\\s*$)|<tag(?:"[^"]*"|\'[^\']*\'|\\\\s[^\'"/>\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))`).replace("comment",ee).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:C,lheading:/^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,paragraph:k(J).replace("hr",v).replace("heading",` *#{1,6} *[^\n]`).replace("lheading",de).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},We=/^\\\\([!"#$%&\'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/,Fe=/^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/,be=/^( {2,}|\\\\)\\n(?!\\s*$)/,Xe=/^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/,M=/[\\p{P}\\p{S}]/u,H=/[\\s\\p{P}\\p{S}]/u,ne=/[^\\s\\p{P}\\p{S}]/u,Ue=k(/^((?![*_])punctSpace)/,"u").replace(/punctSpace/g,H).getRegex(),me=/(?!~)[\\p{P}\\p{S}]/u,Ve=/(?!~)[\\s\\p{P}\\p{S}]/u,Ke=/(?:[^\\s\\p{P}\\p{S}]|~)/u,Je=k(/link|precode-code|html/,"g").replace("link",/\\[(?:[^\\[\\]`]|(?<a>`+)[^`]+\\k<a>(?!`))*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)/).replace("precode-",_e?"(?<!`)()":"(^^|[^`])").replace("code",/(?<b>`+)[^`]+\\k<b>(?!`)/).replace("html",/<(?! )[^<>]*?>/).getRegex(),we=/^(?:\\*+(?:((?!\\*)punct)|([^\\s*]))?)|^_+(?:((?!_)punct)|([^\\s_]))?/,Ye=k(we,"u").replace(/punct/g,M).getRegex(),et=k(we,"u").replace(/punct/g,me).getRegex(),ye="^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\\\*)punct(\\\\*+)(?=[\\\\s]|$)|notPunctSpace(\\\\*+)(?!\\\\*)(?=punctSpace|$)|(?!\\\\*)punctSpace(\\\\*+)(?=notPunctSpace)|[\\\\s](\\\\*+)(?!\\\\*)(?=punct)|(?!\\\\*)punct(\\\\*+)(?!\\\\*)(?=punct)|notPunctSpace(\\\\*+)(?=notPunctSpace)",tt=k(ye,"gu").replace(/notPunctSpace/g,ne).replace(/punctSpace/g,H).replace(/punct/g,M).getRegex(),nt=k(ye,"gu").replace(/notPunctSpace/g,Ke).replace(/punctSpace/g,Ve).replace(/punct/g,me).getRegex(),rt=k("^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,ne).replace(/punctSpace/g,H).replace(/punct/g,M).getRegex(),st=k(/^~~?(?:((?!~)punct)|[^\\s~])/,"u").replace(/punct/g,M).getRegex(),lt="^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)",it=k(lt,"gu").replace(/notPunctSpace/g,ne).replace(/punctSpace/g,H).replace(/punct/g,M).getRegex(),at=k(/\\\\(punct)/,"gu").replace(/punct/g,M).getRegex(),ot=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(),ct=k(ee).replace("(?:-->|$)","-->").getRegex(),ht=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",ct).replace("attribute",/\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*"[^"]*"|\\s*=\\s*\'[^\']*\'|\\s*=\\s*[^\\s"\'=<>`]+)?/).getRegex(),Z=/(?:\\[(?:\\\\[\\s\\S]|[^\\[\\]\\\\])*\\]|\\\\[\\s\\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\\])|[^\\[\\]\\\\`])*?/,ut=k(/^!?\\[(label)\\]\\(\\s*(href)(?:(?:[ \\t]+(?:\\n[ \\t]*)?|\\n[ \\t]*)(title))?\\s*\\)/).replace("label",Z).replace("href",/<(?:\\\\.|[^\\n<>\\\\])+>|[^ \\t\\n\\x00-\\x1f]+|(?=\\))/).replace("title",/"(?:\\\\"?|[^"\\\\])*"|\'(?:\\\\\'?|[^\'\\\\])*\'|\\((?:\\\\\\)?|[^)\\\\])*\\)/).getRegex(),Re=k(/^!?\\[(label)\\]\\[(ref)\\]/).replace("label",Z).replace("ref",Y).getRegex(),$e=k(/^!?\\[(ref)\\](?:\\[\\])?/).replace("ref",Y).getRegex(),pt=k("reflink|nolink(?!\\\\()","g").replace("reflink",Re).replace("nolink",$e).getRegex(),oe=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,re={_backpedal:C,anyPunctuation:at,autolink:ot,blockSkip:Je,br:be,code:Fe,del:C,delLDelim:C,delRDelim:C,emStrongLDelim:Ye,emStrongRDelimAst:tt,emStrongRDelimUnd:rt,escape:We,link:ut,nolink:$e,punctuation:Ue,reflink:Re,reflinkSearch:pt,tag:ht,text:Xe,url:C},gt={...re,link:k(/^!?\\[(label)\\]\\((.*?)\\)/).replace("label",Z).getRegex(),reflink:k(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/).replace("label",Z).getRegex()},F={...re,emStrongRDelimAst:nt,emStrongLDelim:et,delLDelim:st,delRDelim:it,url:k(/^((?:protocol):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/).replace("protocol",oe).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",oe).getRegex()},kt={...F,br:k(be).replace("{2,}","*").getRegex(),text:k(F.text).replace("\\\\b_","\\\\b_| {2,}\\\\n").replace(/\\{2,\\}/g,"*").getRegex()},D={normal:te,gfm:je,pedantic:Ge},B={normal:re,gfm:F,breaks:kt,pedantic:gt},ft={"&":"&amp;","<":"&lt;",">":"&gt;",\'"\':"&quot;","\'":"&#39;"},ce=t=>ft[t];function S(t,e){if(e){if(x.escapeTest.test(t))return t.replace(x.escapeReplace,ce)}else if(x.escapeTestNoEncode.test(t))return t.replace(x.escapeReplaceNoEncode,ce);return t}function he(t){try{t=encodeURI(t).replace(x.percentDecode,"%")}catch{return null}return t}function ue(t,e){let n=t.replace(x.findPipe,(l,a,i)=>{let o=!1,c=a;for(;--c>=0&&i[c]==="\\\\";)o=!o;return o?"|":" |"}),s=n.split(x.splitPipe),r=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(;r<s.length;r++)s[r]=s[r].trim().replace(x.slashPipe,"|");return s}function z(t,e,n){let s=t.length;if(s===0)return"";let r=0;for(;r<s;){let l=t.charAt(s-r-1);if(l===e&&!n)r++;else if(l!==e&&n)r++;else break}return t.slice(0,s-r)}function pe(t){let e=t.split(`\n`),n=e.length-1;for(;n>=0&&x.blankLine.test(e[n]);)n--;return e.length-n<=2?t:e.slice(0,n+1).join(`\n`)}function dt(t,e){if(t.indexOf(e[1])===-1)return-1;let n=0;for(let s=0;s<t.length;s++)if(t[s]==="\\\\")s++;else if(t[s]===e[0])n++;else if(t[s]===e[1]&&(n--,n<0))return s;return n>0?-2:-1}function xt(t,e=0){let n=e,s="";for(let r of t)if(r===" "){let l=4-n%4;s+=" ".repeat(l),n+=l}else s+=r,n++;return s}function ge(t,e,n,s,r){let l=e.href,a=e.title||null,i=t[1].replace(r.other.outputLinkReplace,"$1");s.state.inLink=!0;let o={type:t[0].charAt(0)==="!"?"image":"link",raw:n,href:l,title:a,text:i,tokens:s.inlineTokens(i)};return s.state.inLink=!1,o}function bt(t,e,n){let s=t.match(n.other.indentCodeCompensation);if(s===null)return e;let r=s[1];return e.split(`\n`).map(l=>{let a=l.match(n.other.beginningSpace);if(a===null)return l;let[i]=a;return i.length>=r.length?l.slice(r.length):l}).join(`\n`)}var O=class{options;rules;lexer;constructor(t){this.options=t||_}space(t){let e=this.rules.block.newline.exec(t);if(e&&e[0].length>0)return{type:"space",raw:e[0]}}code(t){let e=this.rules.block.code.exec(t);if(e){let n=this.options.pedantic?e[0]:pe(e[0]),s=n.replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:n,codeBlockStyle:"indented",text:s}}}fences(t){let e=this.rules.block.fences.exec(t);if(e){let n=e[0],s=bt(n,e[3]||"",this.rules);return{type:"code",raw:n,lang:e[2]?e[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):e[2],text:s}}}heading(t){let e=this.rules.block.heading.exec(t);if(e){let n=e[2].trim();if(this.rules.other.endingHash.test(n)){let s=z(n,"#");(this.options.pedantic||!s||this.rules.other.endingSpaceChar.test(s))&&(n=s.trim())}return{type:"heading",raw:z(e[0],`\n`),depth:e[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(t){let e=this.rules.block.hr.exec(t);if(e)return{type:"hr",raw:z(e[0],`\n`)}}blockquote(t){let e=this.rules.block.blockquote.exec(t);if(e){let n=z(e[0],`\n`).split(`\n`),s="",r="",l=[];for(;n.length>0;){let a=!1,i=[],o;for(o=0;o<n.length;o++)if(this.rules.other.blockquoteStart.test(n[o]))i.push(n[o]),a=!0;else if(!a)i.push(n[o]);else break;n=n.slice(o);let c=i.join(`\n`),u=c.replace(this.rules.other.blockquoteSetextReplace,`\n $1`).replace(this.rules.other.blockquoteSetextReplace2,"");s=s?`${s}\n${c}`:c,r=r?`${r}\n${u}`:u;let h=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(u,l,!0),this.lexer.state.top=h,n.length===0)break;let p=l.at(-1);if(p?.type==="code")break;if(p?.type==="blockquote"){let d=p,f=d.raw+`\n`+n.join(`\n`),m=this.blockquote(f);l[l.length-1]=m,s=s.substring(0,s.length-d.raw.length)+m.raw,r=r.substring(0,r.length-d.text.length)+m.text;break}else if(p?.type==="list"){let d=p,f=d.raw+`\n`+n.join(`\n`),m=this.list(f);l[l.length-1]=m,s=s.substring(0,s.length-p.raw.length)+m.raw,r=r.substring(0,r.length-d.raw.length)+m.raw,n=f.substring(l.at(-1).raw.length).split(`\n`);continue}}return{type:"blockquote",raw:s,tokens:l,text:r}}}list(t){let e=this.rules.block.list.exec(t);if(e){let n=e[1].trim(),s=n.length>1,r={type:"list",raw:"",ordered:s,start:s?+n.slice(0,-1):"",loose:!1,items:[]};n=s?`\\\\d{1,9}\\\\${n.slice(-1)}`:`\\\\${n}`,this.options.pedantic&&(n=s?n:"[*+-]");let l=this.rules.other.listItemRegex(n),a=!1;for(;t;){let o=!1,c="",u="";if(!(e=l.exec(t))||this.rules.block.hr.test(t))break;c=e[0],t=t.substring(c.length);let h=xt(e[2].split(`\n`,1)[0],e[1].length),p=t.split(`\n`,1)[0],d=!h.trim(),f=0;if(this.options.pedantic?(f=2,u=h.trimStart()):d?f=e[1].length+1:(f=h.search(this.rules.other.nonSpaceChar),f=f>4?1:f,u=h.slice(f),f+=e[1].length),d&&this.rules.other.blankLine.test(p)&&(c+=p+`\n`,t=t.substring(p.length+1),o=!0),!o){let m=this.rules.other.nextBulletRegex(f),w=this.rules.other.hrRegex(f),y=this.rules.other.fencesBeginRegex(f),L=this.rules.other.headingBeginRegex(f),W=this.rules.other.htmlBeginRegex(f),A=this.rules.other.blockquoteBeginRegex(f);for(;t;){let b=t.split(`\n`,1)[0],T;if(p=b,this.options.pedantic?(p=p.replace(this.rules.other.listReplaceNesting," "),T=p):T=p.replace(this.rules.other.tabCharGlobal," "),y.test(p)||L.test(p)||W.test(p)||A.test(p)||m.test(p)||w.test(p))break;if(T.search(this.rules.other.nonSpaceChar)>=f||!p.trim())u+=`\n`+T.slice(f);else{if(d||h.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||y.test(h)||L.test(h)||w.test(h))break;u+=`\n`+p}d=!p.trim(),c+=b+`\n`,t=t.substring(b.length+1),h=T.slice(f)}}r.loose||(a?r.loose=!0:this.rules.other.doubleBlankLine.test(c)&&(a=!0)),r.items.push({type:"list_item",raw:c,task:!!this.options.gfm&&this.rules.other.listIsTask.test(u),loose:!1,text:u,tokens:[]}),r.raw+=c}let i=r.items.at(-1);if(i)i.raw=i.raw.trimEnd(),i.text=i.text.trimEnd();else return;r.raw=r.raw.trimEnd();for(let o of r.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 u=this.rules.other.listTaskCheckbox.exec(o.raw);if(u){let h={type:"checkbox",raw:u[0]+" ",checked:u[0]!=="[ ]"};o.checked=h.checked,r.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(!r.loose){let u=o.tokens.filter(p=>p.type==="space"),h=u.length>0&&u.some(p=>this.rules.other.anyLine.test(p.raw));r.loose=h}}if(r.loose)for(let o of r.items){o.loose=!0;for(let c of o.tokens)c.type==="text"&&(c.type="paragraph")}return r}}html(t){let e=this.rules.block.html.exec(t);if(e){let n=pe(e[0]);return{type:"html",block:!0,raw:n,pre:e[1]==="pre"||e[1]==="script"||e[1]==="style",text:n}}}def(t){let e=this.rules.block.def.exec(t);if(e){let n=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"):"",r=e[3]?e[3].substring(1,e[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):e[3];return{type:"def",tag:n,raw:z(e[0],`\n`),href:s,title:r}}}table(t){let e=this.rules.block.table.exec(t);if(!e||!this.rules.other.tableDelimiter.test(e[2]))return;let n=ue(e[1]),s=e[2].replace(this.rules.other.tableAlignChars,"").split("|"),r=e[3]?.trim()?e[3].replace(this.rules.other.tableRowBlankLine,"").split(`\n`):[],l={type:"table",raw:z(e[0],`\n`),header:[],align:[],rows:[]};if(n.length===s.length){for(let a of s)this.rules.other.tableAlignRight.test(a)?l.align.push("right"):this.rules.other.tableAlignCenter.test(a)?l.align.push("center"):this.rules.other.tableAlignLeft.test(a)?l.align.push("left"):l.align.push(null);for(let a=0;a<n.length;a++)l.header.push({text:n[a],tokens:this.lexer.inline(n[a]),header:!0,align:l.align[a]});for(let a of r)l.rows.push(ue(a,l.header.length).map((i,o)=>({text:i,tokens:this.lexer.inline(i),header:!1,align:l.align[o]})));return l}}lheading(t){let e=this.rules.block.lheading.exec(t);if(e){let n=e[1].trim();return{type:"heading",raw:z(e[0],`\n`),depth:e[2].charAt(0)==="="?1:2,text:n,tokens:this.lexer.inline(n)}}}paragraph(t){let e=this.rules.block.paragraph.exec(t);if(e){let n=e[1].charAt(e[1].length-1)===`\n`?e[1].slice(0,-1):e[1];return{type:"paragraph",raw:e[0],text:n,tokens:this.lexer.inline(n)}}}text(t){let e=this.rules.block.text.exec(t);if(e)return{type:"text",raw:e[0],text:e[0],tokens:this.lexer.inline(e[0])}}escape(t){let e=this.rules.inline.escape.exec(t);if(e)return{type:"escape",raw:e[0],text:e[1]}}tag(t){let e=this.rules.inline.tag.exec(t);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(t){let e=this.rules.inline.link.exec(t);if(e){let n=e[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(n)){if(!this.rules.other.endAngleBracket.test(n))return;let l=z(n.slice(0,-1),"\\\\");if((n.length-l.length)%2===0)return}else{let l=dt(e[2],"()");if(l===-2)return;if(l>-1){let a=(e[0].indexOf("!")===0?5:4)+e[1].length+l;e[2]=e[2].substring(0,l),e[0]=e[0].substring(0,a).trim(),e[3]=""}}let s=e[2],r="";if(this.options.pedantic){let l=this.rules.other.pedanticHrefTitle.exec(s);l&&(s=l[1],r=l[3])}else r=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(n)?s=s.slice(1):s=s.slice(1,-1)),ge(e,{href:s&&s.replace(this.rules.inline.anyPunctuation,"$1"),title:r&&r.replace(this.rules.inline.anyPunctuation,"$1")},e[0],this.lexer,this.rules)}}reflink(t,e){let n;if((n=this.rules.inline.reflink.exec(t))||(n=this.rules.inline.nolink.exec(t))){let s=(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal," "),r=e[s.toLowerCase()];if(!r){let l=n[0].charAt(0);return{type:"text",raw:l,text:l}}return ge(n,r,n[0],this.lexer,this.rules)}}emStrong(t,e,n=""){let s=this.rules.inline.emStrongLDelim.exec(t);if(!(!s||!s[1]&&!s[2]&&!s[3]&&!s[4]||s[4]&&n.match(this.rules.other.unicodeAlphaNumeric))&&(!(s[1]||s[3])||!n||this.rules.inline.punctuation.exec(n))){let r=[...s[0]].length-1,l,a,i=r,o=0,c=s[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(c.lastIndex=0,e=e.slice(-1*t.length+r);(s=c.exec(e))!==null;){if(l=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!l)continue;if(a=[...l].length,s[3]||s[4]){i+=a;continue}else if((s[5]||s[6])&&r%3&&!((r+a)%3)){o+=a;continue}if(i-=a,i>0)continue;a=Math.min(a,a+i+o);let u=[...s[0]][0].length,h=t.slice(0,r+s.index+u+a);if(Math.min(r,a)%2){let d=h.slice(1,-1);return{type:"em",raw:h,text:d,tokens:this.lexer.inlineTokens(d)}}let p=h.slice(2,-2);return{type:"strong",raw:h,text:p,tokens:this.lexer.inlineTokens(p)}}}}codespan(t){let e=this.rules.inline.code.exec(t);if(e){let n=e[2].replace(this.rules.other.newLineCharGlobal," "),s=this.rules.other.nonSpaceChar.test(n),r=this.rules.other.startingSpaceChar.test(n)&&this.rules.other.endingSpaceChar.test(n);return s&&r&&(n=n.substring(1,n.length-1)),{type:"codespan",raw:e[0],text:n}}}br(t){let e=this.rules.inline.br.exec(t);if(e)return{type:"br",raw:e[0]}}del(t,e,n=""){let s=this.rules.inline.delLDelim.exec(t);if(s&&(!s[1]||!n||this.rules.inline.punctuation.exec(n))){let r=[...s[0]].length-1,l,a,i=r,o=this.rules.inline.delRDelim;for(o.lastIndex=0,e=e.slice(-1*t.length+r);(s=o.exec(e))!==null;){if(l=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!l||(a=[...l].length,a!==r))continue;if(s[3]||s[4]){i+=a;continue}if(i-=a,i>0)continue;a=Math.min(a,a+i);let c=[...s[0]][0].length,u=t.slice(0,r+s.index+c+a),h=u.slice(r,-r);return{type:"del",raw:u,text:h,tokens:this.lexer.inlineTokens(h)}}}}autolink(t){let e=this.rules.inline.autolink.exec(t);if(e){let n,s;return e[2]==="@"?(n=e[1],s="mailto:"+n):(n=e[1],s=n),{type:"link",raw:e[0],text:n,href:s,tokens:[{type:"text",raw:n,text:n}]}}}url(t){let e;if(e=this.rules.inline.url.exec(t)){let n,s;if(e[2]==="@")n=e[0],s="mailto:"+n;else{let r;do r=e[0],e[0]=this.rules.inline._backpedal.exec(e[0])?.[0]??"";while(r!==e[0]);n=e[0],e[1]==="www."?s="http://"+e[0]:s=e[0]}return{type:"link",raw:e[0],text:n,href:s,tokens:[{type:"text",raw:n,text:n}]}}}inlineText(t){let e=this.rules.inline.text.exec(t);if(e){let n=this.lexer.state.inRawBlock;return{type:"text",raw:e[0],text:e[0],escaped:n}}}},R=class X{tokens;options;state;inlineQueue;tokenizer;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||_,this.options.tokenizer=this.options.tokenizer||new O,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 n={other:x,block:D.normal,inline:B.normal};this.options.pedantic?(n.block=D.pedantic,n.inline=B.pedantic):this.options.gfm&&(n.block=D.gfm,this.options.breaks?n.inline=B.breaks:n.inline=B.gfm),this.tokenizer.rules=n}static get rules(){return{block:D,inline:B}}static lex(e,n){return new X(n).lex(e)}static lexInline(e,n){return new X(n).inlineTokens(e)}lex(e){e=e.replace(x.carriageReturn,`\n`),this.blockTokens(e,this.tokens);for(let n=0;n<this.inlineQueue.length;n++){let s=this.inlineQueue[n];this.inlineTokens(s.src,s.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,n=[],s=!1){this.tokenizer.lexer=this,this.options.pedantic&&(e=e.replace(x.tabCharGlobal," ").replace(x.spaceLine,""));let r=1/0;for(;e;){if(e.length<r)r=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}let l;if(this.options.extensions?.block?.some(i=>(l=i.call({lexer:this},e,n))?(e=e.substring(l.raw.length),n.push(l),!0):!1))continue;if(l=this.tokenizer.space(e)){e=e.substring(l.raw.length);let i=n.at(-1);l.raw.length===1&&i!==void 0?i.raw+=`\n`:n.push(l);continue}if(l=this.tokenizer.code(e)){e=e.substring(l.raw.length);let i=n.at(-1);i?.type==="paragraph"||i?.type==="text"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.text,this.inlineQueue.at(-1).src=i.text):n.push(l);continue}if(l=this.tokenizer.fences(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.heading(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.hr(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.blockquote(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.list(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.html(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.def(e)){e=e.substring(l.raw.length);let i=n.at(-1);i?.type==="paragraph"||i?.type==="text"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.raw,this.inlineQueue.at(-1).src=i.text):this.tokens.links[l.tag]||(this.tokens.links[l.tag]={href:l.href,title:l.title},n.push(l));continue}if(l=this.tokenizer.table(e)){e=e.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.lheading(e)){e=e.substring(l.raw.length),n.push(l);continue}let a=e;if(this.options.extensions?.startBlock){let i=1/0,o=e.slice(1),c;this.options.extensions.startBlock.forEach(u=>{c=u.call({lexer:this},o),typeof c=="number"&&c>=0&&(i=Math.min(i,c))}),i<1/0&&i>=0&&(a=e.substring(0,i+1))}if(this.state.top&&(l=this.tokenizer.paragraph(a))){let i=n.at(-1);s&&i?.type==="paragraph"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=i.text):n.push(l),s=a.length!==e.length,e=e.substring(l.raw.length);continue}if(l=this.tokenizer.text(e)){e=e.substring(l.raw.length);let i=n.at(-1);i?.type==="text"?(i.raw+=(i.raw.endsWith(`\n`)?"":`\n`)+l.raw,i.text+=`\n`+l.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=i.text):n.push(l);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return this.state.top=!0,n}inline(e,n=[]){return this.inlineQueue.push({src:e,tokens:n}),n}inlineTokens(e,n=[]){this.tokenizer.lexer=this;let s=e;if(this.tokens.links){let i=Object.keys(this.tokens.links);i.length>0&&(s=s.replace(this.tokenizer.rules.inline.reflinkSearch,o=>i.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,(i,o,c)=>{let u=c?c.length:0;return i.slice(0,u)+"["+"a".repeat(i.length-u-2)+"]"}),s=this.options.hooks?.emStrongMask?.call({lexer:this},s)??s;let r=!1,l="",a=1/0;for(;e;){if(e.length<a)a=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}r||(l=""),r=!1;let i;if(this.options.extensions?.inline?.some(c=>(i=c.call({lexer:this},e,n))?(e=e.substring(i.raw.length),n.push(i),!0):!1))continue;if(i=this.tokenizer.escape(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.tag(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.link(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(i.raw.length);let c=n.at(-1);i.type==="text"&&c?.type==="text"?(c.raw+=i.raw,c.text+=i.text):n.push(i);continue}if(i=this.tokenizer.emStrong(e,s,l)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.codespan(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.br(e)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.del(e,s,l)){e=e.substring(i.raw.length),n.push(i);continue}if(i=this.tokenizer.autolink(e)){e=e.substring(i.raw.length),n.push(i);continue}if(!this.state.inLink&&(i=this.tokenizer.url(e))){e=e.substring(i.raw.length),n.push(i);continue}let o=e;if(this.options.extensions?.startInline){let c=1/0,u=e.slice(1),h;this.options.extensions.startInline.forEach(p=>{h=p.call({lexer:this},u),typeof h=="number"&&h>=0&&(c=Math.min(c,h))}),c<1/0&&c>=0&&(o=e.substring(0,c+1))}if(i=this.tokenizer.inlineText(o)){e=e.substring(i.raw.length),i.raw.slice(-1)!=="_"&&(l=i.raw.slice(-1)),r=!0;let c=n.at(-1);c?.type==="text"?(c.raw+=i.raw,c.text+=i.text):n.push(i);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return n}infiniteLoopError(e){let n="Infinite loop on byte: "+e;if(this.options.silent)console.error(n);else throw new Error(n)}},Q=class{options;parser;constructor(t){this.options=t||_}space(t){return""}code({text:t,lang:e,escaped:n}){let s=(e||"").match(x.notSpaceStart)?.[0],r=t.replace(x.endingNewline,"")+`\n`;return s?\'<pre><code class="language-\'+S(s)+\'">\'+(n?r:S(r,!0))+`</code></pre>\n`:"<pre><code>"+(n?r:S(r,!0))+`</code></pre>\n`}blockquote({tokens:t}){return`<blockquote>\n${this.parser.parse(t)}</blockquote>\n`}html({text:t}){return t}def(t){return""}heading({tokens:t,depth:e}){return`<h${e}>${this.parser.parseInline(t)}</h${e}>\n`}hr(t){return`<hr>\n`}list(t){let e=t.ordered,n=t.start,s="";for(let a=0;a<t.items.length;a++){let i=t.items[a];s+=this.listitem(i)}let r=e?"ol":"ul",l=e&&n!==1?\' start="\'+n+\'"\':"";return"<"+r+l+`>\n`+s+"</"+r+`>\n`}listitem(t){return`<li>${this.parser.parse(t.tokens)}</li>\n`}checkbox({checked:t}){return"<input "+(t?\'checked="" \':"")+\'disabled="" type="checkbox"> \'}paragraph({tokens:t}){return`<p>${this.parser.parseInline(t)}</p>\n`}table(t){let e="",n="";for(let r=0;r<t.header.length;r++)n+=this.tablecell(t.header[r]);e+=this.tablerow({text:n});let s="";for(let r=0;r<t.rows.length;r++){let l=t.rows[r];n="";for(let a=0;a<l.length;a++)n+=this.tablecell(l[a]);s+=this.tablerow({text:n})}return s&&(s=`<tbody>${s}</tbody>`),`<table>\n<thead>\n`+e+`</thead>\n`+s+`</table>\n`}tablerow({text:t}){return`<tr>\n${t}</tr>\n`}tablecell(t){let e=this.parser.parseInline(t.tokens),n=t.header?"th":"td";return(t.align?`<${n} align="${t.align}">`:`<${n}>`)+e+`</${n}>\n`}strong({tokens:t}){return`<strong>${this.parser.parseInline(t)}</strong>`}em({tokens:t}){return`<em>${this.parser.parseInline(t)}</em>`}codespan({text:t}){return`<code>${S(t,!0)}</code>`}br(t){return"<br>"}del({tokens:t}){return`<del>${this.parser.parseInline(t)}</del>`}link({href:t,title:e,tokens:n}){let s=this.parser.parseInline(n),r=he(t);if(r===null)return s;t=r;let l=\'<a href="\'+t+\'"\';return e&&(l+=\' title="\'+S(e)+\'"\'),l+=">"+s+"</a>",l}image({href:t,title:e,text:n,tokens:s}){s&&(n=this.parser.parseInline(s,this.parser.textRenderer));let r=he(t);if(r===null)return S(n);t=r;let l=`<img src="${t}" alt="${S(n)}"`;return e&&(l+=` title="${S(e)}"`),l+=">",l}text(t){return"tokens"in t&&t.tokens?this.parser.parseInline(t.tokens):"escaped"in t&&t.escaped?t.text:S(t.text)}},se=class{strong({text:t}){return t}em({text:t}){return t}codespan({text:t}){return t}del({text:t}){return t}html({text:t}){return t}text({text:t}){return t}link({text:t}){return""+t}image({text:t}){return""+t}br(){return""}checkbox({raw:t}){return t}},$=class U{options;renderer;textRenderer;constructor(e){this.options=e||_,this.options.renderer=this.options.renderer||new Q,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new se}static parse(e,n){return new U(n).parse(e)}static parseInline(e,n){return new U(n).parseInline(e)}parse(e){this.renderer.parser=this;let n="";for(let s=0;s<e.length;s++){let r=e[s];if(this.options.extensions?.renderers?.[r.type]){let a=r,i=this.options.extensions.renderers[a.type].call({parser:this},a);if(i!==!1||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(a.type)){n+=i||"";continue}}let l=r;switch(l.type){case"space":{n+=this.renderer.space(l);break}case"hr":{n+=this.renderer.hr(l);break}case"heading":{n+=this.renderer.heading(l);break}case"code":{n+=this.renderer.code(l);break}case"table":{n+=this.renderer.table(l);break}case"blockquote":{n+=this.renderer.blockquote(l);break}case"list":{n+=this.renderer.list(l);break}case"checkbox":{n+=this.renderer.checkbox(l);break}case"html":{n+=this.renderer.html(l);break}case"def":{n+=this.renderer.def(l);break}case"paragraph":{n+=this.renderer.paragraph(l);break}case"text":{n+=this.renderer.text(l);break}default:{let a=\'Token with "\'+l.type+\'" type was not found.\';if(this.options.silent)return console.error(a),"";throw new Error(a)}}}return n}parseInline(e,n=this.renderer){this.renderer.parser=this;let s="";for(let r=0;r<e.length;r++){let l=e[r];if(this.options.extensions?.renderers?.[l.type]){let i=this.options.extensions.renderers[l.type].call({parser:this},l);if(i!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(l.type)){s+=i||"";continue}}let a=l;switch(a.type){case"escape":{s+=n.text(a);break}case"html":{s+=n.html(a);break}case"link":{s+=n.link(a);break}case"image":{s+=n.image(a);break}case"checkbox":{s+=n.checkbox(a);break}case"strong":{s+=n.strong(a);break}case"em":{s+=n.em(a);break}case"codespan":{s+=n.codespan(a);break}case"br":{s+=n.br(a);break}case"del":{s+=n.del(a);break}case"text":{s+=n.text(a);break}default:{let i=\'Token with "\'+a.type+\'" type was not found.\';if(this.options.silent)return console.error(i),"";throw new Error(i)}}}return s}},q=class{options;block;constructor(t){this.options=t||_}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(t){return t}postprocess(t){return t}processAllTokens(t){return t}emStrongMask(t){return t}provideLexer(t=this.block){return t?R.lex:R.lexInline}provideParser(t=this.block){return t?$.parse:$.parseInline}},mt=class{defaults=V();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=$;Renderer=Q;TextRenderer=se;Lexer=R;Tokenizer=O;Hooks=q;constructor(...t){this.use(...t)}walkTokens(t,e){let n=[];for(let s of t)switch(n=n.concat(e.call(this,s)),s.type){case"table":{let r=s;for(let l of r.header)n=n.concat(this.walkTokens(l.tokens,e));for(let l of r.rows)for(let a of l)n=n.concat(this.walkTokens(a.tokens,e));break}case"list":{let r=s;n=n.concat(this.walkTokens(r.items,e));break}default:{let r=s;this.defaults.extensions?.childTokens?.[r.type]?this.defaults.extensions.childTokens[r.type].forEach(l=>{let a=r[l].flat(1/0);n=n.concat(this.walkTokens(a,e))}):r.tokens&&(n=n.concat(this.walkTokens(r.tokens,e)))}}return n}use(...t){let e=this.defaults.extensions||{renderers:{},childTokens:{}};return t.forEach(n=>{let s={...n};if(s.async=this.defaults.async||s.async||!1,n.extensions&&(n.extensions.forEach(r=>{if(!r.name)throw new Error("extension name required");if("renderer"in r){let l=e.renderers[r.name];l?e.renderers[r.name]=function(...a){let i=r.renderer.apply(this,a);return i===!1&&(i=l.apply(this,a)),i}:e.renderers[r.name]=r.renderer}if("tokenizer"in r){if(!r.level||r.level!=="block"&&r.level!=="inline")throw new Error("extension level must be \'block\' or \'inline\'");let l=e[r.level];l?l.unshift(r.tokenizer):e[r.level]=[r.tokenizer],r.start&&(r.level==="block"?e.startBlock?e.startBlock.push(r.start):e.startBlock=[r.start]:r.level==="inline"&&(e.startInline?e.startInline.push(r.start):e.startInline=[r.start]))}"childTokens"in r&&r.childTokens&&(e.childTokens[r.name]=r.childTokens)}),s.extensions=e),n.renderer){let r=this.defaults.renderer||new Q(this.defaults);for(let l in n.renderer){if(!(l in r))throw new Error(`renderer \'${l}\' does not exist`);if(["options","parser"].includes(l))continue;let a=l,i=n.renderer[a],o=r[a];r[a]=(...c)=>{let u=i.apply(r,c);return u===!1&&(u=o.apply(r,c)),u||""}}s.renderer=r}if(n.tokenizer){let r=this.defaults.tokenizer||new O(this.defaults);for(let l in n.tokenizer){if(!(l in r))throw new Error(`tokenizer \'${l}\' does not exist`);if(["options","rules","lexer"].includes(l))continue;let a=l,i=n.tokenizer[a],o=r[a];r[a]=(...c)=>{let u=i.apply(r,c);return u===!1&&(u=o.apply(r,c)),u}}s.tokenizer=r}if(n.hooks){let r=this.defaults.hooks||new q;for(let l in n.hooks){if(!(l in r))throw new Error(`hook \'${l}\' does not exist`);if(["options","block"].includes(l))continue;let a=l,i=n.hooks[a],o=r[a];q.passThroughHooks.has(l)?r[a]=c=>{if(this.defaults.async&&q.passThroughHooksRespectAsync.has(l))return(async()=>{let h=await i.call(r,c);return o.call(r,h)})();let u=i.call(r,c);return o.call(r,u)}:r[a]=(...c)=>{if(this.defaults.async)return(async()=>{let h=await i.apply(r,c);return h===!1&&(h=await o.apply(r,c)),h})();let u=i.apply(r,c);return u===!1&&(u=o.apply(r,c)),u}}s.hooks=r}if(n.walkTokens){let r=this.defaults.walkTokens,l=n.walkTokens;s.walkTokens=function(a){let i=[];return i.push(l.call(this,a)),r&&(i=i.concat(r.call(this,a))),i}}this.defaults={...this.defaults,...s}}),this}setOptions(t){return this.defaults={...this.defaults,...t},this}lexer(t,e){return R.lex(t,e??this.defaults)}parser(t,e){return $.parse(t,e??this.defaults)}parseMarkdown(t){return(e,n)=>{let s={...n},r={...this.defaults,...s},l=this.onError(!!r.silent,!!r.async);if(this.defaults.async===!0&&s.async===!1)return l(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 l(new Error("marked(): input parameter is undefined or null"));if(typeof e!="string")return l(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected"));if(r.hooks&&(r.hooks.options=r,r.hooks.block=t),r.async)return(async()=>{let a=r.hooks?await r.hooks.preprocess(e):e,i=await(r.hooks?await r.hooks.provideLexer(t):t?R.lex:R.lexInline)(a,r),o=r.hooks?await r.hooks.processAllTokens(i):i;r.walkTokens&&await Promise.all(this.walkTokens(o,r.walkTokens));let c=await(r.hooks?await r.hooks.provideParser(t):t?$.parse:$.parseInline)(o,r);return r.hooks?await r.hooks.postprocess(c):c})().catch(l);try{r.hooks&&(e=r.hooks.preprocess(e));let a=(r.hooks?r.hooks.provideLexer(t):t?R.lex:R.lexInline)(e,r);r.hooks&&(a=r.hooks.processAllTokens(a)),r.walkTokens&&this.walkTokens(a,r.walkTokens);let i=(r.hooks?r.hooks.provideParser(t):t?$.parse:$.parseInline)(a,r);return r.hooks&&(i=r.hooks.postprocess(i)),i}catch(a){return l(a)}}}onError(t,e){return n=>{if(n.message+=`\nPlease report this to https://github.com/markedjs/marked.`,t){let s="<p>An error occurred:</p><pre>"+S(n.message+"",!0)+"</pre>";return e?Promise.resolve(s):s}if(e)return Promise.reject(n);throw n}}},I=new mt;function g(t,e){return I.parse(t,e)}g.options=g.setOptions=function(t){return I.setOptions(t),g.defaults=I.defaults,ke(g.defaults),g};g.getDefaults=V;g.defaults=_;g.use=function(...t){return I.use(...t),g.defaults=I.defaults,ke(g.defaults),g};g.walkTokens=function(t,e){return I.walkTokens(t,e)};g.parseInline=I.parseInline;g.Parser=$;g.parser=$.parse;g.Renderer=Q;g.TextRenderer=se;g.Lexer=R;g.lexer=R.lex;g.Tokenizer=O;g.Hooks=q;g.parse=g;var zt=g.options,At=g.setOptions,Ct=g.use,It=g.walkTokens,_t=g.parseInline;var Pt=$.parse,Mt=R.lex;function Se(t,e,n){let s=0;for(let r=e;r<n;r++)s+=t[r].raw.length;return s}function wt(t,e){let n=t;return n.links=e,n}var yt=/^ {0,3}\\$\\$/m;function Le(t){return t.includes("$$")===!1?!1:yt.test(t)}function Rt(t,e){return t[e-2]?.type!=="list"?!0:e+1<t.length}function ze(t,e){for(let n=t.length-2;n>=e;n--)if(t[n].type==="space"&&Rt(t,n+1)!==!1)return n+1;return-1}function Ae(t){let e=t.links;if(!e)return!1;for(let n in e)return!0;return!1}function Ce(t,e,n,s,r){let l=r;for(let a=e;a<n;a++){let i=t[a].raw;if(s.startsWith(i,l)===!1)return!1;l+=i.length}return!0}function G(t,e,n){return{source:t,tail:t,tokens:e,stableCount:0,stableOffset:0,degraded:!0,degradedReason:n}}function Te(t,e){return{source:t,tail:t,tokens:e,stableCount:0,stableOffset:0,degraded:!1,degradedReason:null}}function $t(t,e){if(Ae(e))return G(t,e,"link-definition");if(t.includes("\\r"))return G(t,e,"carriage-return");if(Le(t))return G(t,e,"block-math");let n=ze(e,1);if(n<0||Ce(e,0,n,t,0)===!1)return Te(t,e);let s=Se(e,0,n);return{source:t,tail:t.slice(s),tokens:e,stableCount:n,stableOffset:s,degraded:!1,degradedReason:null}}function le(t){let e=g.lexer(t);return{tokens:e,cache:$t(t,e),charsLexed:t.length,reusedTokens:0}}function j(t,e){let n=g.lexer(t);return{tokens:n,cache:G(t,n,e),charsLexed:t.length,reusedTokens:0}}function Ie(t,e){let n=t.source+e;if(t.degraded)return j(n,t.degradedReason??"link-definition");if(e.includes("\\r"))return j(n,"carriage-return");if(t.stableCount===0)return le(n);let s=t.tail+e;if(Le(s))return j(n,"block-math");let r=g.lexer(s);if(Ae(r))return j(n,"link-definition");let l=t.tokens.slice(0,t.stableCount),a=wt([...l,...r],r.links),i=t.stableCount,o=t.stableOffset,c=s,u=ze(a,t.stableCount+1);if(u>t.stableCount&&Ce(a,t.stableCount,u,s,0)){let h=Se(a,t.stableCount,u);i=u,o=t.stableOffset+h,c=s.slice(h)}return{tokens:a,cache:{source:n,tail:c,tokens:a,stableCount:i,stableOffset:o,degraded:!1,degradedReason:null},charsLexed:s.length,reusedTokens:t.stableCount}}var Tt=0;function St(t){if(typeof t!="string"||typeof performance.mark!="function"||typeof performance.measure!="function")return null;let e=Tt++,n={name:t,startMark:`${t}:start:${e}`,endMark:`${t}:end:${e}`};try{return performance.mark(n.startMark),n}catch{return null}}function Lt(t){if(t)try{performance.mark(t.endMark),performance.measure(t.name,t.startMark,t.endMark)}catch{}finally{try{performance.clearMarks?.(t.startMark),performance.clearMarks?.(t.endMark)}catch{}}}g.use({extensions:[{name:"blockMath",level:"block",start(t){return t.match(/^ {0,3}\\$\\$/m)?.index},tokenizer(t){let e=/^ {0,3}\\$\\$([\\s\\S]+?)\\$\\$[ \\t]*(?:\\n|$)/.exec(t);if(e)return{type:"blockMath",raw:e[0],text:e[1].trim()}},renderer(t){return t.raw}},{name:"inlineMath",level:"inline",start(t){return t.match(/(?<![\\\\$])\\$(?![$\\s])/)?.index},tokenizer(t){let e=/^\\$(?![$\\s\\d])((?:\\\\\\$|[^$\\n])*?)(?<!\\s)\\$(?!\\d)/.exec(t);if(e)return{type:"inlineMath",raw:e[0],text:e[1].trim()}},renderer(t){return t.raw}}]});var E=new Map;self.onmessage=t=>{let e=t.data;if(typeof e!="object"||e===null)return;let{id:n,text:s,append:r,expectedLength:l,oldRaws:a,instance:i,baseVersion:o,dispose:c,userTimingName:u}=e;if(c===!0){typeof i=="string"&&E.delete(i);return}let h=typeof i=="string"?i:null,p=typeof o=="number"?o:null,d,f=null,m=null;if(typeof r=="string"){if(h===null||p===null){self.postMessage({id:n,needResync:!0});return}let w=E.get(h);if(!w||w.version!==p){self.postMessage({id:n,needResync:!0});return}if(typeof l=="number"&&w.lex.source.length+r.length!==l){E.delete(h),self.postMessage({id:n,needResync:!0});return}let y=w.lex;d=()=>Ie(y,r),m=y.tokens}else if(typeof s=="string"){let w=s;if(d=()=>le(w),Array.isArray(a))f=a;else if(h!==null&&p!==null){let y=E.get(h);if(y&&y.version===p)m=y.lex.tokens;else{self.postMessage({id:n,needResync:!0});return}}}else return;try{let w=typeof u=="string"?St(u):null,y=performance.now(),L;try{L=d()}finally{w&&Lt(w)}let W=performance.now()-y,A=L.tokens,b=0;if(f!==null){let T=Math.min(f.length,A.length);for(;b<T&&f[b]===A[b].raw;b++);}else if(m!==null){let T=m,ie=Math.min(T.length,A.length);for(b=Math.min(L.reusedTokens,ie);b<ie&&T[b].raw===A[b].raw;b++);}h!==null&&p!==null&&E.set(h,{version:p+1,lex:L.cache}),self.postMessage({id:n,matchLen:b,tail:A.slice(b),lexerMs:W,sourceCharsLexed:L.charsLexed})}catch(w){h!==null&&E.delete(h),self.postMessage({id:n,error:String(w)})}};})();\n';
1886
+
1887
+ // src/Markdown.ts
1888
+ var now = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
1889
+ function lexMarkdown(text, userTiming) {
1890
+ if (!userTiming) return import_marked.marked.lexer(text);
1891
+ const timing = (0, import_core4.beginVectoUserTiming)(import_core4.VECTO_USER_TIMING.markdown.parse);
1892
+ try {
1893
+ return import_marked.marked.lexer(text);
1894
+ } finally {
1895
+ if (timing) (0, import_core4.endVectoUserTiming)(timing);
1542
1896
  }
1543
- return best;
1544
1897
  }
1545
- function renderInlineToRichText(tokens, fallbackText, font, color, maxWidth, theme, selectable, onLinkClick) {
1546
- const spans = [];
1547
- if (tokens && tokens.length > 0) {
1548
- collectSpans(tokens, {}, theme, spans, fontSizeFromFont(font));
1898
+ import_marked.marked.use({
1899
+ extensions: [
1900
+ {
1901
+ name: "blockMath",
1902
+ level: "block",
1903
+ start(src) {
1904
+ return src.match(/^ {0,3}\$\$/m)?.index;
1905
+ },
1906
+ tokenizer(src) {
1907
+ const match = /^ {0,3}\$\$([\s\S]+?)\$\$[ \t]*(?:\n|$)/.exec(src);
1908
+ if (match) {
1909
+ return {
1910
+ type: "blockMath",
1911
+ raw: match[0],
1912
+ text: match[1].trim()
1913
+ };
1914
+ }
1915
+ return void 0;
1916
+ },
1917
+ renderer(token) {
1918
+ return token.raw;
1919
+ }
1920
+ },
1921
+ {
1922
+ name: "inlineMath",
1923
+ level: "inline",
1924
+ start(src) {
1925
+ return src.match(/(?<![\\$])\$(?![$\s])/)?.index;
1926
+ },
1927
+ tokenizer(src) {
1928
+ const match = /^\$(?![$\s\d])((?:\\\$|[^$\n])*?)(?<!\s)\$(?!\d)/.exec(src);
1929
+ if (match) {
1930
+ return {
1931
+ type: "inlineMath",
1932
+ raw: match[0],
1933
+ text: match[1].trim()
1934
+ };
1935
+ }
1936
+ return void 0;
1937
+ },
1938
+ renderer(token) {
1939
+ return token.raw;
1940
+ }
1941
+ }
1942
+ ]
1943
+ });
1944
+ var markdownWorker = null;
1945
+ var workerIdCounter = 0;
1946
+ var workerInstanceCounter = 0;
1947
+ var workerCallbacks = /* @__PURE__ */ new Map();
1948
+ function runSyncFallback(entry) {
1949
+ try {
1950
+ entry.cb(0, lexMarkdown(entry.text, entry.userTiming), true);
1951
+ } catch (err) {
1952
+ console.warn("Markdown sync fallback parse failed", err);
1953
+ entry.onDropped?.();
1549
1954
  }
1550
- if (spans.length === 0) {
1551
- spans.push({ text: decodeEntities(fallbackText) });
1955
+ }
1956
+ if (typeof Worker !== "undefined") {
1957
+ try {
1958
+ const blob = new Blob([WORKER_SOURCE_STRING], {
1959
+ type: "application/javascript"
1960
+ });
1961
+ markdownWorker = new Worker(URL.createObjectURL(blob));
1962
+ markdownWorker.onmessage = (e) => {
1963
+ const { id, matchLen, tail, error, needResync, lexerMs, sourceCharsLexed } = e.data;
1964
+ const entry = workerCallbacks.get(id);
1965
+ if (entry) {
1966
+ workerCallbacks.delete(id);
1967
+ if (needResync && entry.onNeedResync) {
1968
+ entry.onNeedResync();
1969
+ } else if (needResync) {
1970
+ runSyncFallback(entry);
1971
+ } else if (!error) {
1972
+ entry.cb(matchLen, tail, false, {
1973
+ lexerMs: typeof lexerMs === "number" ? lexerMs : 0,
1974
+ sourceCharsLexed: typeof sourceCharsLexed === "number" ? sourceCharsLexed : 0
1975
+ });
1976
+ } else {
1977
+ runSyncFallback(entry);
1978
+ }
1979
+ }
1980
+ };
1981
+ markdownWorker.onerror = () => {
1982
+ const pending = [...workerCallbacks.values()];
1983
+ workerCallbacks.clear();
1984
+ markdownWorker = null;
1985
+ for (const entry of pending) runSyncFallback(entry);
1986
+ };
1987
+ } catch (err) {
1988
+ console.warn("Failed to initialize MarkdownWorker", err);
1552
1989
  }
1553
- return new import_ui.RichText(spans, {
1554
- font,
1555
- color,
1556
- maxWidth,
1557
- linkColor: "#38bdf8",
1558
- selectable,
1559
- onLinkClick
1560
- });
1561
1990
  }
1562
- var Markdown = class _Markdown extends import_ui.UIComponent {
1991
+ var Markdown = class _Markdown extends import_ui4.UIComponent {
1563
1992
  content;
1564
1993
  maxWidth;
1565
1994
  theme;
1566
1995
  onLinkClick;
1567
1996
  selectable;
1997
+ /**
1998
+ * Whether code blocks and tables carry copy / download controls.
1999
+ *
2000
+ * Read when a block entity is built, so it affects blocks rendered from here on
2001
+ * rather than retroactively; a document does not rebuild to gain or lose an
2002
+ * affordance.
2003
+ */
2004
+ blockAffordances;
2005
+ /** Clipboard writer used by the copy controls. */
2006
+ writeClipboard;
2007
+ /** File saver used by the download controls. */
2008
+ saveFile;
1568
2009
  activeBlockMetrics = null;
1569
2010
  /**
1570
2011
  * Called after a streamed append has re-laid-out the document.
@@ -1640,6 +2081,20 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
1640
2081
  * field only so {@link destroy} can remove the exact closure it added.
1641
2082
  */
1642
2083
  inlineMathRepaint;
2084
+ /**
2085
+ * This instance's entry in the inline-image decode waiters, or `undefined` if it
2086
+ * has never rendered an image. Held as a field only so {@link destroy} can remove
2087
+ * the exact closure it added.
2088
+ */
2089
+ inlineImageRemeasure;
2090
+ /**
2091
+ * URLs whose decoded aspect ratio this document has already reserved a box for.
2092
+ *
2093
+ * The guard that makes the re-measure fire once per image rather than once per
2094
+ * decode-notification-per-image: the waiter set is module-level, so a page of
2095
+ * many documents tells all of them about all decodes.
2096
+ */
2097
+ inlineImagesMeasured = /* @__PURE__ */ new Set();
1643
2098
  /**
1644
2099
  * True while this document is waiting on the lazy MathJax load.
1645
2100
  *
@@ -1785,11 +2240,17 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
1785
2240
  constructor(markdownText, opts = {}) {
1786
2241
  super();
1787
2242
  this.maxWidth = opts.maxWidth ?? 800;
1788
- this.theme = { ...DEFAULT_THEME, ...opts.theme };
2243
+ this.theme = resolveTheme(opts.theme);
1789
2244
  this.onLinkClick = opts.onLinkClick;
1790
2245
  this.selectable = opts.selectable ?? true;
1791
2246
  this._userTiming = opts.userTiming ?? false;
1792
- this.content = new import_ui.Stack({ direction: "vertical", gap: 16 });
2247
+ this.blockAffordances = opts.blockAffordances ?? false;
2248
+ this.writeClipboard = opts.writeClipboard ?? defaultWriteClipboard;
2249
+ this.saveFile = opts.saveFile ?? defaultSaveFile;
2250
+ this.content = new import_ui4.Stack({
2251
+ direction: "vertical",
2252
+ gap: this.theme.blockGap
2253
+ });
1793
2254
  this.add(this.content);
1794
2255
  this.rawMarkdown = "";
1795
2256
  this.setTokens([]);
@@ -2008,15 +2469,15 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2008
2469
  switch (token.type) {
2009
2470
  case "heading":
2010
2471
  case "paragraph": {
2011
- if (entity instanceof import_ui.RichText) {
2472
+ if (entity instanceof import_ui4.RichText) {
2012
2473
  entity.setMaxWidth(availableWidth);
2013
2474
  return;
2014
2475
  }
2015
- if (entity instanceof import_ui.Stack) {
2476
+ if (entity instanceof import_ui4.Stack) {
2016
2477
  entity.maxWidth = availableWidth;
2017
2478
  for (const run of entity.children) {
2018
- if (run instanceof import_ui.RichText) run.setMaxWidth(availableWidth);
2019
- else if (run instanceof import_ui.Image) this.refitParagraphImage(run, availableWidth);
2479
+ if (run instanceof import_ui4.RichText) run.setMaxWidth(availableWidth);
2480
+ else if (run instanceof import_ui4.Image) this.refitParagraphImage(run, availableWidth);
2020
2481
  }
2021
2482
  entity.layout();
2022
2483
  }
@@ -2029,11 +2490,11 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2029
2490
  }
2030
2491
  case "blockquote": {
2031
2492
  const bqToken = token;
2032
- const innerStack = entity.children.find((c) => c instanceof import_ui.Stack);
2493
+ const innerStack = entity.children.find((c) => c instanceof import_ui4.Stack);
2033
2494
  const border = entity.children.find((c) => c instanceof QuoteBorder);
2034
- const indentStart = Math.min(16, availableWidth);
2495
+ const indentStart = Math.min(this.theme.quoteIndent, availableWidth);
2035
2496
  const childWidth = Math.max(0, availableWidth - indentStart);
2036
- if (innerStack instanceof import_ui.Stack && bqToken.tokens) {
2497
+ if (innerStack instanceof import_ui4.Stack && bqToken.tokens) {
2037
2498
  let index = 0;
2038
2499
  for (const inner of bqToken.tokens) {
2039
2500
  if (!this.producesEntity(inner)) continue;
@@ -2056,15 +2517,15 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2056
2517
  return;
2057
2518
  }
2058
2519
  case "list": {
2059
- if (!(entity instanceof import_ui.Stack)) return;
2520
+ if (!(entity instanceof import_ui4.Stack)) return;
2060
2521
  for (const item of entity.children) {
2061
- if (item instanceof import_ui.RichText) item.setMaxWidth(availableWidth);
2522
+ if (item instanceof import_ui4.RichText) item.setMaxWidth(availableWidth);
2062
2523
  }
2063
2524
  entity.layout();
2064
2525
  return;
2065
2526
  }
2066
2527
  case "table": {
2067
- if (entity instanceof import_ui.Table) entity.setWidth(availableWidth);
2528
+ if (entity instanceof import_ui4.Table) entity.setWidth(availableWidth);
2068
2529
  return;
2069
2530
  }
2070
2531
  case "hr": {
@@ -2072,7 +2533,7 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2072
2533
  return;
2073
2534
  }
2074
2535
  default: {
2075
- if (entity instanceof import_ui.Text) entity.setMaxWidth(availableWidth);
2536
+ if (entity instanceof import_ui4.Text) entity.setMaxWidth(availableWidth);
2076
2537
  return;
2077
2538
  }
2078
2539
  }
@@ -2134,7 +2595,98 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2134
2595
  this.scene?.markDirty();
2135
2596
  };
2136
2597
  this.inlineMathRepaint = repaint;
2137
- inlineMathRasterWaiters.add(repaint);
2598
+ subscribeInlineMathRaster(repaint);
2599
+ }
2600
+ /**
2601
+ * Re-measure this document when an inline image's raster finishes decoding.
2602
+ *
2603
+ * Inline images differ from inline formulas in one way that matters: a formula's
2604
+ * box is known synchronously the moment it typesets, while an image's aspect
2605
+ * ratio arrives only with the decode. The span reserved a square until then, so a
2606
+ * decode that reports anything else has invalidated a WIDTH, and a repaint into
2607
+ * the old box would letterbox or stretch the picture.
2608
+ *
2609
+ * So this rebuilds through {@link retypesetFromTokens} — the same late-arrival
2610
+ * path MathJax uses — but only when a reserved width actually changed. Every live
2611
+ * document is notified for every decode, including images it does not contain, so
2612
+ * an unconditional rebuild here would be O(documents x images) full re-renders
2613
+ * for a page of many blocks.
2614
+ *
2615
+ * Subscribed lazily and held as a field for the same two reasons as its math
2616
+ * counterpart: a document with no images costs nothing, and `destroy` must remove
2617
+ * the exact closure it added.
2618
+ */
2619
+ subscribeInlineImageRemeasure() {
2620
+ if (this.inlineImageRemeasure || this.isDestroyed) return;
2621
+ const remeasure = () => {
2622
+ if (this.isDestroyed) return;
2623
+ if (this.inlineImageBoxesStale()) this.retypesetFromTokens();
2624
+ else this.scene?.markDirty();
2625
+ };
2626
+ this.inlineImageRemeasure = remeasure;
2627
+ subscribeInlineImageRaster(remeasure);
2628
+ }
2629
+ /**
2630
+ * Whether any inline image in this document has just learned it is not square.
2631
+ *
2632
+ * An inline image's span reserves a square box before its raster decodes, because
2633
+ * that is the only shape available without a natural size. The decode supplies the
2634
+ * real aspect ratio, so a non-square image needs one rebuild to reserve the right
2635
+ * width — and exactly one. Every live document is notified of every decode on the
2636
+ * page, including images it does not contain, so this has to answer "did MY
2637
+ * geometry just change" and not merely "did something decode".
2638
+ *
2639
+ * Walks the tokens rather than the entity tree: the reserved box is a function of
2640
+ * the raster's aspect ratio, which is available here, and a token walk cannot be
2641
+ * confused by an entity a previous rebuild already corrected.
2642
+ *
2643
+ * Only headings and table cells are inspected. Every other context splits an image
2644
+ * into its own block whose `Image` entity resizes itself in `onLoad`, so a rebuild
2645
+ * for one of those would be pure cost.
2646
+ */
2647
+ inlineImageBoxesStale() {
2648
+ const stale = (tokens) => {
2649
+ let changed2 = false;
2650
+ for (const token of tokens ?? []) {
2651
+ if (token.type === "image") {
2652
+ const href = token.href;
2653
+ if (this.inlineImagesMeasured.has(href)) continue;
2654
+ const raster = ensureInlineImageRaster(href);
2655
+ if (raster.failed) {
2656
+ this.inlineImagesMeasured.add(href);
2657
+ changed2 = true;
2658
+ continue;
2659
+ }
2660
+ if (!raster.decoded || !raster.naturalWidth || !raster.naturalHeight) {
2661
+ continue;
2662
+ }
2663
+ this.inlineImagesMeasured.add(href);
2664
+ if (raster.naturalWidth !== raster.naturalHeight) changed2 = true;
2665
+ continue;
2666
+ }
2667
+ if (stale(token.tokens)) {
2668
+ changed2 = true;
2669
+ }
2670
+ }
2671
+ return changed2;
2672
+ };
2673
+ let changed = false;
2674
+ for (const token of this.tokens) {
2675
+ if (token.type === "heading") {
2676
+ if (stale(token.tokens)) changed = true;
2677
+ } else if (token.type === "table") {
2678
+ const table = token;
2679
+ for (const cell of table.header) {
2680
+ if (stale(cell.tokens)) changed = true;
2681
+ }
2682
+ for (const row of table.rows) {
2683
+ for (const cell of row) {
2684
+ if (stale(cell.tokens)) changed = true;
2685
+ }
2686
+ }
2687
+ }
2688
+ }
2689
+ return changed;
2138
2690
  }
2139
2691
  destroy() {
2140
2692
  this.isDestroyed = true;
@@ -2147,9 +2699,13 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2147
2699
  this.mathLoadPending = false;
2148
2700
  this.flushAppendSettledWaiters();
2149
2701
  if (this.inlineMathRepaint) {
2150
- inlineMathRasterWaiters.delete(this.inlineMathRepaint);
2702
+ unsubscribeInlineMathRaster(this.inlineMathRepaint);
2151
2703
  this.inlineMathRepaint = void 0;
2152
2704
  }
2705
+ if (this.inlineImageRemeasure) {
2706
+ unsubscribeInlineImageRaster(this.inlineImageRemeasure);
2707
+ this.inlineImageRemeasure = void 0;
2708
+ }
2153
2709
  markdownWorker?.postMessage({
2154
2710
  instance: this.workerInstanceId,
2155
2711
  dispose: true
@@ -2451,7 +3007,7 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2451
3007
  id,
2452
3008
  instance: this.workerInstanceId,
2453
3009
  baseVersion,
2454
- userTimingName: this._userTiming ? import_core.VECTO_USER_TIMING.markdown.parse : void 0,
3010
+ userTimingName: this._userTiming ? import_core4.VECTO_USER_TIMING.markdown.parse : void 0,
2455
3011
  ...canSendDelta ? {
2456
3012
  append: this.rawMarkdown.slice(this.workerSourceLen),
2457
3013
  // What the worker's source must total once it applies this append. It
@@ -2543,11 +3099,11 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2543
3099
  }
2544
3100
  /** One text run of an image-bearing paragraph, as both paths build it. */
2545
3101
  inlineRunRichText(tokens, availableWidth, t) {
2546
- return new import_ui.RichText(this.inlineRunSpans(tokens, t), {
3102
+ return new import_ui4.RichText(this.inlineRunSpans(tokens, t), {
2547
3103
  font: `${t.fontSize}px ${t.bodyFont}`,
2548
3104
  color: t.textColor,
2549
3105
  maxWidth: availableWidth,
2550
- linkColor: "#38bdf8",
3106
+ linkColor: t.linkColor,
2551
3107
  selectable: this.selectable,
2552
3108
  onLinkClick: this.onLinkClick
2553
3109
  });
@@ -2577,14 +3133,81 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2577
3133
  * policy for a zero-dimension source is a separate decision from notifying
2578
3134
  * the scene, which is the actual defect here.
2579
3135
  */
3136
+ /**
3137
+ * Wraps a block in its copy / download controls, or returns it untouched.
3138
+ *
3139
+ * The controls are built lazily through `make` so a document with
3140
+ * `blockAffordances` off pays nothing — not the closures, not the measurement
3141
+ * `BlockAffordanceButton` does in its constructor.
3142
+ */
3143
+ withBlockAffordances(block, make) {
3144
+ if (!this.blockAffordances) return block;
3145
+ const controls = make();
3146
+ return controls.length > 0 ? new BlockWithAffordances(block, controls) : block;
3147
+ }
3148
+ /** Copy and download controls for one fenced code block. */
3149
+ codeBlockAffordances(source, lang) {
3150
+ const opts = this.affordanceButtonOptions();
3151
+ return [
3152
+ new BlockAffordanceButton("Copy code", "Copied", () => this.writeClipboard(source), opts),
3153
+ new BlockAffordanceButton(
3154
+ "Download code",
3155
+ "Saved",
3156
+ () => this.saveFile(`code.${extensionForLanguage(lang)}`, source, mimeForLanguage(lang)),
3157
+ opts
3158
+ )
3159
+ ];
3160
+ }
3161
+ /** Copy (as Markdown) and download (as CSV) controls for one table. */
3162
+ tableAffordances(tblToken) {
3163
+ const content = tableContentOf(tblToken);
3164
+ const opts = this.affordanceButtonOptions();
3165
+ return [
3166
+ // Markdown rather than CSV for the clipboard: the reader copied it out of a
3167
+ // Markdown document and the overwhelmingly likely destination is another
3168
+ // one. CSV is what the download is for, where a spreadsheet is the target.
3169
+ new BlockAffordanceButton(
3170
+ "Copy table",
3171
+ "Copied",
3172
+ () => this.writeClipboard(tableToMarkdown(content)),
3173
+ opts
3174
+ ),
3175
+ new BlockAffordanceButton(
3176
+ "Download table",
3177
+ "Saved",
3178
+ () => this.saveFile("table.csv", tableToCsv(content), "text/csv;charset=utf-8"),
3179
+ opts
3180
+ )
3181
+ ];
3182
+ }
3183
+ /**
3184
+ * Button styling for the affordances, derived from the document theme.
3185
+ *
3186
+ * Themed rather than hardcoded so a light-theme document does not get the dark
3187
+ * default palette. `focusColor` is set explicitly from the theme's accent
3188
+ * because `Button`'s default cyan is tuned for the dark palette and reads as
3189
+ * off-brand elsewhere — while a focus ring is the one affordance a keyboard
3190
+ * user cannot do without.
3191
+ */
3192
+ affordanceButtonOptions() {
3193
+ return {
3194
+ font: `600 12px ${this.theme.bodyFont}`,
3195
+ padding: 6,
3196
+ radius: 6,
3197
+ bg: this.theme.codeBgColor,
3198
+ hoverBg: this.theme.tableHeaderBgColor,
3199
+ color: this.theme.textColor,
3200
+ focusColor: this.theme.codeColor
3201
+ };
3202
+ }
2580
3203
  paragraphImage(imgToken, availableWidth) {
2581
3204
  const initialWidth = Math.min(800, availableWidth);
2582
3205
  const initialHeight = Math.round(initialWidth * 0.6);
2583
- const img = new import_ui.Image(imgToken.href, {
3206
+ const img = new import_ui4.Image(imgToken.href, {
2584
3207
  width: initialWidth,
2585
3208
  height: initialHeight,
2586
3209
  alt: imgToken.text,
2587
- radius: 8,
3210
+ radius: this.theme.imageRadius,
2588
3211
  onLoad: () => {
2589
3212
  const bmp = img.bitmap;
2590
3213
  if (bmp && bmp.naturalWidth && bmp.naturalHeight) {
@@ -2599,11 +3222,11 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2599
3222
  }
2600
3223
  /** One table cell entity, shared by the render arm and the streamed-table path. */
2601
3224
  tableCellRichText(cell, header, t) {
2602
- return new import_ui.RichText(this.tableCellSpans(cell, t), {
2603
- font: `${t.fontSize - 2}px ${t.bodyFont}`,
3225
+ return new import_ui4.RichText(this.tableCellSpans(cell, t), {
3226
+ font: `${t.tableFontSize}px ${t.bodyFont}`,
2604
3227
  color: header ? t.headingColor : t.textColor,
2605
3228
  baseStyle: header ? { bold: true } : void 0,
2606
- linkColor: "#38bdf8",
3229
+ linkColor: t.linkColor,
2607
3230
  selectable: this.selectable,
2608
3231
  onLinkClick: this.onLinkClick
2609
3232
  });
@@ -2657,6 +3280,7 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2657
3280
  itemIsInlineOnly(item) {
2658
3281
  const children = item.tokens;
2659
3282
  if (!children || children.length === 0) return true;
3283
+ if (containsImage(children)) return false;
2660
3284
  if (children.length === 1 && children[0].type === "paragraph") return true;
2661
3285
  return children.every((child) => _Markdown.INLINE_ITEM_TOKENS.has(child.type));
2662
3286
  }
@@ -2684,9 +3308,12 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2684
3308
  listItemBlockStack(token, index, availableWidth, t) {
2685
3309
  const item = token.items[index];
2686
3310
  const children = item.tokens ?? [];
2687
- const stack = new import_ui.Stack({ direction: "vertical", gap: 4 });
3311
+ const stack = new import_ui4.Stack({ direction: "vertical", gap: t.listItemGap });
2688
3312
  const first = children[0];
2689
- const leadChildren = first && (first.type === "text" || first.type === "paragraph") ? [first] : [];
3313
+ const firstIsInline = Boolean(first) && (first.type === "text" || first.type === "paragraph");
3314
+ const leadHasImage = firstIsInline && containsImage(first.tokens);
3315
+ const leadChildren = firstIsInline ? [leadHasImage ? stripImages(first) : first] : [];
3316
+ const leadImages = leadHasImage ? imagesOf(first.tokens) : [];
2690
3317
  const leadToken = {
2691
3318
  ...token,
2692
3319
  items: token.items.map((it, i) => i === index ? { ...it, tokens: leadChildren } : it)
@@ -2699,6 +3326,13 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2699
3326
  indentStart: indent,
2700
3327
  availableWidth: Math.max(1, availableWidth - indent)
2701
3328
  };
3329
+ for (const image of leadImages) {
3330
+ const el = this.paragraphImage(image, childMetrics.availableWidth);
3331
+ const wrapper = new MarkdownContainer();
3332
+ el.x = indent;
3333
+ wrapper.add(el);
3334
+ stack.add(wrapper);
3335
+ }
2702
3336
  for (let i = leadChildren.length; i < children.length; i++) {
2703
3337
  const el = this.renderTokenWithMetrics(children[i], childMetrics);
2704
3338
  if (!el) continue;
@@ -2741,16 +3375,16 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2741
3375
  const box = item.task ? item.checked ? "\u2611 " : "\u2610 " : "";
2742
3376
  const leadingMarker = token.ordered ? `${num}. ${box}` : box || "\u2022 ";
2743
3377
  const trailingMarker = token.ordered ? ` ${box}.${num}` : box ? ` ${box.trimEnd()}` : " \u2022";
2744
- const itemIsRtl = import_core.BidiResolver.getBaseLevel(contentSpans.map((s) => s.text).join("")) % 2 === 1;
3378
+ const itemIsRtl = import_core4.BidiResolver.getBaseLevel(contentSpans.map((s) => s.text).join("")) % 2 === 1;
2745
3379
  return itemIsRtl ? [...contentSpans, { text: trailingMarker }] : [{ text: leadingMarker }, ...contentSpans];
2746
3380
  }
2747
3381
  /** Construct the `RichText` for one list item. */
2748
3382
  listItemRichText(token, index, availableWidth, t) {
2749
- return new import_ui.RichText(this.listItemSpans(token, index), {
3383
+ return new import_ui4.RichText(this.listItemSpans(token, index), {
2750
3384
  font: `${t.fontSize}px ${t.bodyFont}`,
2751
3385
  color: t.textColor,
2752
3386
  maxWidth: availableWidth,
2753
- linkColor: "#38bdf8",
3387
+ linkColor: t.linkColor,
2754
3388
  selectable: this.selectable,
2755
3389
  onLinkClick: this.onLinkClick
2756
3390
  });
@@ -2781,7 +3415,7 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2781
3415
  * and keep stale spans. Bail when `loose` flips.
2782
3416
  */
2783
3417
  updateStreamedList(stack, oldToken, newToken) {
2784
- if (!(stack instanceof import_ui.Stack)) return false;
3418
+ if (!(stack instanceof import_ui4.Stack)) return false;
2785
3419
  if (newToken.items.length < oldToken.items.length || oldToken.items.length === 0) return false;
2786
3420
  if (oldToken.ordered !== newToken.ordered) return false;
2787
3421
  if ((oldToken.start ?? 1) !== (newToken.start ?? 1)) return false;
@@ -2790,7 +3424,7 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2790
3424
  const lastRetained = oldToken.items.length - 1;
2791
3425
  for (let i = 0; i < lastRetained; i++) {
2792
3426
  if (oldToken.items[i].text !== newToken.items[i].text) return false;
2793
- const isStack = stack.children[i] instanceof import_ui.Stack;
3427
+ const isStack = stack.children[i] instanceof import_ui4.Stack;
2794
3428
  if (isStack !== !this.itemIsInlineOnly(newToken.items[i])) return false;
2795
3429
  }
2796
3430
  const availableWidth = this.activeBlockMetrics?.availableWidth ?? this.maxWidth;
@@ -2849,7 +3483,7 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2849
3483
  * *token runs* split at the last image, never token index against child index.
2850
3484
  */
2851
3485
  updateImageParagraph(entity, oldToken, newToken) {
2852
- if (!(entity instanceof import_ui.Stack)) return false;
3486
+ if (!(entity instanceof import_ui4.Stack)) return false;
2853
3487
  const oldTokens = oldToken.tokens;
2854
3488
  const newTokens = newToken.tokens;
2855
3489
  if (!oldTokens || !newTokens) return false;
@@ -2874,7 +3508,7 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2874
3508
  entity.add(this.inlineRunRichText(newTail, availableWidth, t));
2875
3509
  } else {
2876
3510
  const tailEntity = entity.children[entity.children.length - 1];
2877
- if (!(tailEntity instanceof import_ui.RichText)) return false;
3511
+ if (!(tailEntity instanceof import_ui4.RichText)) return false;
2878
3512
  tailEntity.setSpans(this.inlineRunSpans(newTail, t));
2879
3513
  }
2880
3514
  const last = entity.children[entity.children.length - 1];
@@ -2906,7 +3540,7 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2906
3540
  * (its keys are `text`/`tokens`/`header`/`align`).
2907
3541
  */
2908
3542
  updateStreamedTable(entity, oldToken, newToken) {
2909
- if (!(entity instanceof import_ui.Table)) return false;
3543
+ if (!(entity instanceof import_ui4.Table)) return false;
2910
3544
  if (oldToken.header.length !== newToken.header.length) return false;
2911
3545
  for (let c = 0; c < oldToken.header.length; c++) {
2912
3546
  if (oldToken.header[c].text !== newToken.header[c].text) return false;
@@ -2927,7 +3561,7 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2927
3561
  if (lastRetained >= 0) {
2928
3562
  for (let c = 0; c < oldToken.header.length; c++) {
2929
3563
  const cell = entity.rows[lastRetained]?.[c];
2930
- if (!(cell instanceof import_ui.RichText)) return false;
3564
+ if (!(cell instanceof import_ui4.RichText)) return false;
2931
3565
  }
2932
3566
  }
2933
3567
  const t = this.theme;
@@ -2960,7 +3594,7 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
2960
3594
  const newTail = newInner[tail];
2961
3595
  if (oldTail.type !== newTail.type) return false;
2962
3596
  const innerStack = container.children[1];
2963
- if (!(innerStack instanceof import_ui.Stack)) return false;
3597
+ if (!(innerStack instanceof import_ui4.Stack)) return false;
2964
3598
  const wrapper = innerStack.children.at(-1);
2965
3599
  if (!wrapper || wrapper.children.length !== 1) return false;
2966
3600
  const entity = wrapper.children[0];
@@ -3100,12 +3734,12 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
3100
3734
  * queued while the first is outstanding.
3101
3735
  */
3102
3736
  ensureMathJax() {
3103
- if (mathConverter || this.mathLoadPending || this.isDestroyed) return;
3737
+ if (isMathJaxReady() || this.mathLoadPending || this.isDestroyed) return;
3104
3738
  this.mathLoadPending = true;
3105
3739
  void preloadMathJax().then(() => {
3106
3740
  this.mathLoadPending = false;
3107
3741
  if (this.isDestroyed) return;
3108
- if (mathConverter) this.retypesetFromTokens();
3742
+ if (isMathJaxReady()) this.retypesetFromTokens();
3109
3743
  this.flushAppendSettledWaiters();
3110
3744
  });
3111
3745
  }
@@ -3425,10 +4059,10 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
3425
4059
  const width = intrinsicW * scale;
3426
4060
  const height = intrinsicH * scale;
3427
4061
  const uri = mathData.uri;
3428
- const math = new import_ui.RichText(
4062
+ const math = new import_ui4.RichText(
3429
4063
  [
3430
4064
  {
3431
- text: import_core.OBJECT_REPLACEMENT,
4065
+ text: import_core4.OBJECT_REPLACEMENT,
3432
4066
  object: {
3433
4067
  width,
3434
4068
  height,
@@ -3468,15 +4102,15 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
3468
4102
  };
3469
4103
  const availableWidth = metrics.availableWidth;
3470
4104
  if (containsInlineMath(token)) {
3471
- if (!mathConverter) this.ensureMathJax();
4105
+ if (!isMathJaxReady()) this.ensureMathJax();
3472
4106
  this.subscribeInlineMathRepaint();
3473
4107
  }
4108
+ if (containsImage([token])) this.subscribeInlineImageRemeasure();
3474
4109
  switch (token.type) {
3475
4110
  // ── Headings ─────────────────────────────────────────────────────
3476
4111
  case "heading": {
3477
4112
  const hToken = token;
3478
- const sizes = [32, 28, 24, 20, 18, 16];
3479
- const size = sizes[Math.min(hToken.depth - 1, 5)];
4113
+ const size = headingSize(t, hToken.depth);
3480
4114
  const headingFont = `bold ${size}px ${t.bodyFont}`;
3481
4115
  return renderInlineToRichText(
3482
4116
  hToken.tokens,
@@ -3504,9 +4138,9 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
3504
4138
  this.onLinkClick
3505
4139
  );
3506
4140
  }
3507
- const stack = new import_ui.Stack({
4141
+ const stack = new import_ui4.Stack({
3508
4142
  direction: "vertical",
3509
- gap: 16,
4143
+ gap: this.theme.blockGap,
3510
4144
  maxWidth: availableWidth
3511
4145
  });
3512
4146
  let currentTokens = [];
@@ -3516,7 +4150,7 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
3516
4150
  currentTokens = [];
3517
4151
  }
3518
4152
  };
3519
- for (const child of pToken.tokens) {
4153
+ for (const child of liftNestedImages(pToken.tokens)) {
3520
4154
  if (child.type === "image") {
3521
4155
  flushText();
3522
4156
  stack.add(this.paragraphImage(child, availableWidth));
@@ -3544,33 +4178,51 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
3544
4178
  const mathBlock = this.renderDisplayMath(codeToken.text, availableWidth);
3545
4179
  if (mathBlock) return mathBlock;
3546
4180
  }
3547
- return new CodeBlock(codeToken.text, lang, availableWidth, t, this.selectable);
4181
+ return this.withBlockAffordances(
4182
+ new CodeBlock(codeToken.text, lang, availableWidth, t, this.selectable),
4183
+ () => this.codeBlockAffordances(codeToken.text, lang)
4184
+ );
3548
4185
  }
3549
4186
  // ── Blockquotes ──────────────────────────────────────────────────
3550
4187
  case "blockquote": {
3551
4188
  const bqToken = token;
3552
- const innerStack = new import_ui.Stack({ direction: "vertical", gap: 8 });
3553
- const indentStart = Math.min(16, availableWidth);
4189
+ const innerStack = new import_ui4.Stack({
4190
+ direction: "vertical",
4191
+ gap: this.theme.quoteInnerGap
4192
+ });
4193
+ const indentStart = Math.min(this.theme.quoteIndent, availableWidth);
3554
4194
  const childMetrics = {
3555
4195
  marginBefore: 0,
3556
4196
  marginAfter: 0,
3557
4197
  indentStart,
3558
4198
  availableWidth: Math.max(0, availableWidth - indentStart)
3559
4199
  };
3560
- if (bqToken.tokens) {
3561
- for (const inner of bqToken.tokens) {
3562
- const el = this.renderTokenWithMetrics(inner, childMetrics);
3563
- if (el) {
3564
- const wrapper = new MarkdownContainer();
3565
- el.x = childMetrics.indentStart;
3566
- wrapper.add(el);
3567
- wrapper.width = el.width + childMetrics.indentStart;
3568
- wrapper.height = el.height;
3569
- innerStack.add(wrapper);
4200
+ const outerTheme = this.theme;
4201
+ if (t.quoteTextColor !== t.textColor) {
4202
+ this.theme = { ...outerTheme, textColor: t.quoteTextColor };
4203
+ }
4204
+ try {
4205
+ if (bqToken.tokens) {
4206
+ for (const inner of bqToken.tokens) {
4207
+ const el = this.renderTokenWithMetrics(inner, childMetrics);
4208
+ if (el) {
4209
+ const wrapper = new MarkdownContainer();
4210
+ el.x = childMetrics.indentStart;
4211
+ wrapper.add(el);
4212
+ wrapper.width = el.width + childMetrics.indentStart;
4213
+ wrapper.height = el.height;
4214
+ innerStack.add(wrapper);
4215
+ }
3570
4216
  }
3571
4217
  }
4218
+ } finally {
4219
+ this.theme = outerTheme;
3572
4220
  }
3573
- const border = new QuoteBorder(innerStack.height || 20, t.quoteBorderColor);
4221
+ const border = new QuoteBorder(
4222
+ innerStack.height || 20,
4223
+ t.quoteBorderColor,
4224
+ t.quoteBorderWidth
4225
+ );
3574
4226
  const container = new MarkdownContainer();
3575
4227
  border.x = 0;
3576
4228
  border.y = 0;
@@ -3585,7 +4237,10 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
3585
4237
  // ── Lists ────────────────────────────────────────────────
3586
4238
  case "list": {
3587
4239
  const listToken = token;
3588
- const listStack = new import_ui.Stack({ direction: "vertical", gap: 6 });
4240
+ const listStack = new import_ui4.Stack({
4241
+ direction: "vertical",
4242
+ gap: this.theme.listGap
4243
+ });
3589
4244
  for (let i = 0; i < listToken.items.length; i++) {
3590
4245
  listStack.add(
3591
4246
  this.itemIsInlineOnly(listToken.items[i]) ? this.listItemRichText(listToken, i, availableWidth, t) : this.listItemBlockStack(listToken, i, availableWidth, t)
@@ -3600,21 +4255,24 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
3600
4255
  const rows = tblToken.rows.map(
3601
4256
  (row) => row.map((cell) => this.tableCellRichText(cell, false, t))
3602
4257
  );
3603
- return new import_ui.Table({
3604
- headers,
3605
- rows,
3606
- // `| :--- | :---: | ---: |` already resolves to this on the token; it
3607
- // was previously discarded, so every column rendered left-aligned.
3608
- align: tblToken.align,
3609
- width: availableWidth,
3610
- textColor: t.textColor,
3611
- headerTextColor: t.headingColor,
3612
- font: `${t.fontSize - 2}px ${t.bodyFont}`,
3613
- borderColor: t.hrColor,
3614
- bg: t.tableBgColor,
3615
- headerBg: t.tableHeaderBgColor,
3616
- selectable: this.selectable
3617
- });
4258
+ return this.withBlockAffordances(
4259
+ new import_ui4.Table({
4260
+ headers,
4261
+ rows,
4262
+ // `| :--- | :---: | ---: |` already resolves to this on the token; it
4263
+ // was previously discarded, so every column rendered left-aligned.
4264
+ align: tblToken.align,
4265
+ width: availableWidth,
4266
+ textColor: t.textColor,
4267
+ headerTextColor: t.headingColor,
4268
+ font: `${t.tableFontSize}px ${t.bodyFont}`,
4269
+ borderColor: t.hrColor,
4270
+ bg: t.tableBgColor,
4271
+ headerBg: t.tableHeaderBgColor,
4272
+ selectable: this.selectable
4273
+ }),
4274
+ () => this.tableAffordances(tblToken)
4275
+ );
3618
4276
  }
3619
4277
  // ── Horizontal rule ──────────────────────────────────────────────
3620
4278
  case "hr":
@@ -3626,18 +4284,18 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
3626
4284
  case "html": {
3627
4285
  const htmlToken = token;
3628
4286
  if (htmlToken.text.toLowerCase().includes("<svg") && htmlToken.text.toLowerCase().includes("</svg>")) {
3629
- return new import_core.SVGEntity(htmlToken.text);
4287
+ return new import_core4.SVGEntity(htmlToken.text);
3630
4288
  }
3631
4289
  return null;
3632
4290
  }
3633
4291
  // ── Fallback ─────────────────────────────────────────────────────
3634
4292
  default:
3635
4293
  if ("text" in token) {
3636
- return new import_ui.Text(token.text, {
4294
+ return new import_ui4.Text(token.text, {
3637
4295
  font: bodyFont,
3638
4296
  color: t.textColor,
3639
4297
  maxWidth: availableWidth,
3640
- lineHeight: 24,
4298
+ lineHeight: t.bodyLineHeight,
3641
4299
  selectable: this.selectable
3642
4300
  });
3643
4301
  }
@@ -3650,13 +4308,22 @@ var Markdown = class _Markdown extends import_ui.UIComponent {
3650
4308
  };
3651
4309
  // Annotate the CommonJS export names for ESM import in node:
3652
4310
  0 && (module.exports = {
4311
+ BlockAffordanceButton,
4312
+ BlockWithAffordances,
3653
4313
  CodeBlock,
3654
4314
  Markdown,
3655
4315
  MathBlock,
3656
4316
  codeAtlas,
3657
4317
  codeAtlasStats,
4318
+ escapeCsvField,
4319
+ escapeMarkdownTableCell,
4320
+ extensionForLanguage,
3658
4321
  isMathJaxReady,
4322
+ mimeForLanguage,
3659
4323
  parseFrontMatterFields,
3660
4324
  preloadMathJax,
3661
- scanFrontMatter
4325
+ scanFrontMatter,
4326
+ tableContentOf,
4327
+ tableToCsv,
4328
+ tableToMarkdown
3662
4329
  });