@simon_he/vue-tui 1.1.3 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +18 -18
  2. package/dist/{TMermaidText-frVr8Ysb.js → TMermaidText-wLnMMvVS.js} +1 -1
  3. package/dist/{TSelect-Dx34M1pF.js → TSelect-CMBOOFwK.js} +5 -5
  4. package/dist/{TTree-DdAjCPHu.js → TTree-kk8ntrpg.js} +6 -5
  5. package/dist/agent/mermaid.d.cts +2 -2
  6. package/dist/agent/mermaid.d.ts +2 -2
  7. package/dist/agent.cjs +542 -266
  8. package/dist/agent.js +25 -82
  9. package/dist/{block-source-Crro3mxi.js → block-source-DhzajB9H.js} +299 -239
  10. package/dist/cli.cjs +57 -16
  11. package/dist/cli.js +70 -15
  12. package/dist/core.js +3 -3
  13. package/dist/{hyperlink-_1FAj7Wq.js → create-terminal-Db_-UGVQ.js} +474 -102
  14. package/dist/{dom-renderer-DXx8fWzD.js → dom-renderer-BfwAEQMf.js} +3 -2
  15. package/dist/experimental.cjs +103 -66
  16. package/dist/experimental.js +20 -74
  17. package/dist/hyperlink-clbb_ha_.js +100 -0
  18. package/dist/index.js +8 -8
  19. package/dist/{linkify-BjI4zVfY.js → linkify-CL9wwnZN.js} +3 -3
  20. package/dist/markdown.cjs +521 -212
  21. package/dist/markdown.d.cts +3 -0
  22. package/dist/markdown.d.ts +3 -0
  23. package/dist/markdown.js +75 -8
  24. package/dist/math-image-BZhmfUeu.js +308 -0
  25. package/dist/mermaid-N3kGTHFy.js +1697 -0
  26. package/dist/mermaid.cjs +1460 -6
  27. package/dist/mermaid.d.cts +4 -0
  28. package/dist/mermaid.d.ts +4 -0
  29. package/dist/mermaid.js +7 -5
  30. package/dist/{rect-DUpeDfBg.js → rect-JzWMJxxc.js} +1 -1
  31. package/dist/renderer/cli/stdout-renderer.d.ts +44 -0
  32. package/dist/renderer/terminal-graphics.d.ts +61 -0
  33. package/dist/renderer-dom.js +4 -4
  34. package/dist/{terminal-graphics-Bbe83wSr.js → terminal-graphics-2FTRg9x3.js} +90 -2
  35. package/dist/{tlog-theme-i6S_Oftd.js → tlog-theme-B91Wv7Zj.js} +5 -4
  36. package/dist/vue/components/TAgentTerminalGraphic.d.ts +1 -1
  37. package/dist/vue/components/TMarkdownText.d.ts +70 -2
  38. package/dist/vue/components/TMermaidImage.d.ts +920 -0
  39. package/dist/vue/components/TMermaidText.d.ts +2 -2
  40. package/dist/vue/components/TVirtualMarkdown.d.ts +70 -2
  41. package/dist/vue/markdown/ast.d.ts +5 -0
  42. package/dist/vue/markdown/document.d.ts +3 -0
  43. package/dist/vue/markdown/math-image.d.ts +68 -0
  44. package/dist/vue/markdown/theme.d.ts +12 -0
  45. package/dist/vue/markdown/types.d.ts +12 -2
  46. package/dist/vue/mermaid/beautiful-mermaid.d.ts +284 -240
  47. package/dist/vue/mermaid/mermaid-image.d.ts +73 -0
  48. package/dist/vue.js +9 -9
  49. package/package.json +24 -10
  50. package/dist/mermaid-BNhM1jAZ.js +0 -123
  51. package/dist/width-GqllnV8C.js +0 -474
  52. /package/dist/{ansi-palette-CH6jc2Z7.js → ansi-palette-BHF1rN7R.js} +0 -0
package/dist/markdown.cjs CHANGED
@@ -31,11 +31,19 @@ __export(markdown_exports, {
31
31
  TVirtualMarkdown: () => TVirtualMarkdown,
32
32
  buildMarkdownBlocks: () => buildMarkdownBlocks,
33
33
  buildMarkdownVisualRows: () => buildMarkdownVisualRows,
34
+ clearMarkdownMathImageCache: () => clearMarkdownMathImageCache,
34
35
  createMarkdownBlockSource: () => createMarkdownBlockSource,
35
36
  createTuiMarkdownParser: () => createTuiMarkdownParser,
37
+ enqueueMarkdownMathImages: () => enqueueMarkdownMathImages,
38
+ getCachedMarkdownMathImage: () => getCachedMarkdownMathImage,
39
+ getMarkdownMathImage: () => getMarkdownMathImage,
40
+ isMarkdownMathImageRendererReady: () => isMarkdownMathImageRendererReady,
36
41
  isSafeMarkdownLink: () => isSafeMarkdownLink,
37
42
  layoutMarkdownBlocks: () => layoutMarkdownBlocks,
38
- loadMarkdownMathRenderer: () => loadMarkdownMathRenderer
43
+ loadMarkdownMathImageRenderer: () => loadMarkdownMathImageRenderer,
44
+ loadMarkdownMathRenderer: () => loadMarkdownMathRenderer,
45
+ setMarkdownMathRasterizer: () => setMarkdownMathRasterizer,
46
+ subscribeMarkdownMathImage: () => subscribeMarkdownMathImage
39
47
  });
40
48
  module.exports = __toCommonJS(markdown_exports);
41
49
 
@@ -1033,185 +1041,242 @@ function readMarkdownImageDimensions(base64) {
1033
1041
  return null;
1034
1042
  }
1035
1043
 
1036
- // src/vue/markdown/math.ts
1037
- var loadedKatex = null, katexLoad = null, katexListeners = /* @__PURE__ */ new Set();
1038
- function resolveKatexRenderer(value) {
1039
- if (!value || typeof value != "object")
1040
- return null;
1041
- let renderToString = value.renderToString;
1042
- return typeof renderToString == "function" ? { renderToString } : null;
1044
+ // src/vue/markdown/math-image.ts
1045
+ var DEFAULT_MATH_IMAGE_OPTIONS = Object.freeze({
1046
+ cellWidthPx: 8,
1047
+ cellHeightPx: 16,
1048
+ scale: 2,
1049
+ color: "#f8f8f2",
1050
+ maxWidthCells: 0,
1051
+ baselineRatio: 0.78
1052
+ }), MAX_CACHE_ENTRIES = 64, MAX_FAILED_ENTRIES = 128, mathImageCache = /* @__PURE__ */ new Map(), mathImageFailed = /* @__PURE__ */ new Set(), mathImageInflight = /* @__PURE__ */ new Map(), mathImageListeners = /* @__PURE__ */ new Set(), customRasterizer = null, builtinRasterizerLoad = null, builtinRasterizerReady = !1, NAMED_STYLE_FG_HEX = Object.freeze({
1053
+ black: "#000000",
1054
+ red: "#e53935",
1055
+ green: "#43a047",
1056
+ yellow: "#fdd835",
1057
+ blue: "#1e88e5",
1058
+ magenta: "#d81b60",
1059
+ cyan: "#00acc1",
1060
+ white: "#ffffff",
1061
+ gray: "#9e9e9e",
1062
+ grey: "#9e9e9e",
1063
+ blackBright: "#4a4a4a",
1064
+ redBright: "#ff6e6e",
1065
+ greenBright: "#69db7c",
1066
+ yellowBright: "#ffe066",
1067
+ blueBright: "#74c0fc",
1068
+ magentaBright: "#f783ac",
1069
+ cyanBright: "#3bc9db",
1070
+ whiteBright: "#f8f8f2",
1071
+ grayBright: "#bdbdbd",
1072
+ greyBright: "#bdbdbd"
1073
+ });
1074
+ function resolveMarkdownMathColor(fg) {
1075
+ if (typeof fg != "string" || !fg)
1076
+ return;
1077
+ let trimmed = fg.trim();
1078
+ return trimmed.startsWith("#") && /^#[0-9a-f]{3,8}$/i.test(trimmed) ? trimmed.toLowerCase() : NAMED_STYLE_FG_HEX[trimmed.toLowerCase()];
1043
1079
  }
1044
- function subscribeMarkdownMathRenderer(listener) {
1045
- return katexListeners.add(listener), () => katexListeners.delete(listener);
1080
+ function normalizeMathImageOptions(options) {
1081
+ return {
1082
+ cellWidthPx: Math.max(
1083
+ 1,
1084
+ Math.floor(options?.cellWidthPx ?? DEFAULT_MATH_IMAGE_OPTIONS.cellWidthPx)
1085
+ ),
1086
+ cellHeightPx: Math.max(
1087
+ 1,
1088
+ Math.floor(options?.cellHeightPx ?? DEFAULT_MATH_IMAGE_OPTIONS.cellHeightPx)
1089
+ ),
1090
+ scale: Math.max(1, Math.floor(options?.scale ?? DEFAULT_MATH_IMAGE_OPTIONS.scale)),
1091
+ color: options?.color ?? DEFAULT_MATH_IMAGE_OPTIONS.color,
1092
+ maxWidthCells: Math.max(0, Math.floor(options?.maxWidthCells ?? 0)),
1093
+ baselineRatio: clamp01(options?.baselineRatio ?? DEFAULT_MATH_IMAGE_OPTIONS.baselineRatio)
1094
+ };
1046
1095
  }
1047
- async function loadMarkdownMathRenderer() {
1048
- return loadedKatex ? !0 : (katexLoad || (katexLoad = import("katex").then((mod) => {
1049
- let renderer = resolveKatexRenderer(mod.default) ?? resolveKatexRenderer(mod);
1050
- if (!renderer)
1051
- return !1;
1052
- loadedKatex = renderer;
1053
- for (let listener of katexListeners)
1054
- listener();
1055
- return !0;
1056
- }).catch(() => !1)), katexLoad);
1096
+ function clamp01(value) {
1097
+ return Number.isFinite(value) ? Math.min(1, Math.max(0, value)) : 0.78;
1057
1098
  }
1058
- var KATEX_TEXT_OPTIONS = Object.freeze({
1059
- output: "mathml",
1060
- throwOnError: !1,
1061
- strict: "ignore",
1062
- trust: !1,
1063
- maxSize: 20,
1064
- maxExpand: 200
1065
- }), KATEX_VALIDATE_OPTIONS = Object.freeze({
1066
- ...KATEX_TEXT_OPTIONS,
1067
- throwOnError: !0
1068
- }), TEX_SYMBOLS = Object.freeze({
1069
- alpha: "\u03B1",
1070
- beta: "\u03B2",
1071
- gamma: "\u03B3",
1072
- delta: "\u03B4",
1073
- epsilon: "\u03B5",
1074
- theta: "\u03B8",
1075
- lambda: "\u03BB",
1076
- mu: "\u03BC",
1077
- pi: "\u03C0",
1078
- rho: "\u03C1",
1079
- sigma: "\u03C3",
1080
- tau: "\u03C4",
1081
- phi: "\u03C6",
1082
- omega: "\u03C9",
1083
- Gamma: "\u0393",
1084
- Delta: "\u0394",
1085
- Theta: "\u0398",
1086
- Lambda: "\u039B",
1087
- Pi: "\u03A0",
1088
- Sigma: "\u03A3",
1089
- Phi: "\u03A6",
1090
- Omega: "\u03A9",
1091
- int: "\u222B",
1092
- sum: "\u2211",
1093
- prod: "\u220F",
1094
- infty: "\u221E",
1095
- infinity: "\u221E",
1096
- pm: "\xB1",
1097
- times: "\xD7",
1098
- cdot: "\xB7",
1099
- div: "\xF7",
1100
- le: "\u2264",
1101
- leq: "\u2264",
1102
- ge: "\u2265",
1103
- geq: "\u2265",
1104
- neq: "\u2260",
1105
- ne: "\u2260",
1106
- approx: "\u2248",
1107
- equiv: "\u2261",
1108
- to: "\u2192",
1109
- rightarrow: "\u2192",
1110
- leftarrow: "\u2190",
1111
- leftrightarrow: "\u2194",
1112
- partial: "\u2202",
1113
- nabla: "\u2207",
1114
- sqrt: "\u221A"
1115
- }), SUPPORTED_COMMANDS = /* @__PURE__ */ new Set([...Object.keys(TEX_SYMBOLS), "frac", "sqrt"]);
1116
- function decodeXmlEntities(value) {
1117
- return value.replace(/&(?:#(\d+)|#x([0-9a-f]+)|([a-z]+));/gi, (match, dec, hex, named) => {
1118
- if (dec)
1119
- return String.fromCodePoint(Number(dec));
1120
- if (hex)
1121
- return String.fromCodePoint(Number.parseInt(hex, 16));
1122
- switch (String(named).toLowerCase()) {
1123
- case "amp":
1124
- return "&";
1125
- case "lt":
1126
- return "<";
1127
- case "gt":
1128
- return ">";
1129
- case "quot":
1130
- return '"';
1131
- case "apos":
1132
- return "'";
1133
- default:
1134
- return match;
1135
- }
1136
- });
1099
+ function setMarkdownMathRasterizer(rasterizer) {
1100
+ customRasterizer = rasterizer;
1137
1101
  }
1138
- function mathmlTagName(tag) {
1139
- let start = tag.startsWith("/") ? 1 : 0, end = start;
1140
- for (; end < tag.length; ) {
1141
- let ch = tag[end];
1142
- if (ch === " " || ch === " " || ch === `
1143
- ` || ch === "\r" || ch === "/")
1144
- break;
1145
- end++;
1146
- }
1147
- return tag.slice(start, end).toLowerCase();
1102
+ function subscribeMarkdownMathImage(listener) {
1103
+ return mathImageListeners.add(listener), () => mathImageListeners.delete(listener);
1148
1104
  }
1149
- function textFromKatexMathml(html) {
1150
- let readable = "", offset = 0, lowerHtml = html.toLowerCase();
1151
- for (; offset < html.length; ) {
1152
- let tagStart = html.indexOf("<", offset);
1153
- if (tagStart < 0) {
1154
- readable += html.slice(offset);
1155
- break;
1156
- }
1157
- readable += html.slice(offset, tagStart);
1158
- let tagEnd = html.indexOf(">", tagStart + 1);
1159
- if (tagEnd < 0)
1160
- break;
1161
- let tag = html.slice(tagStart + 1, tagEnd).trim(), tagName = mathmlTagName(tag), closing = tag.startsWith("/");
1162
- if (!closing && tagName === "annotation") {
1163
- let annotationEnd = lowerHtml.indexOf("</annotation>", tagEnd + 1);
1164
- offset = annotationEnd < 0 ? tagEnd + 1 : annotationEnd + 13;
1165
- continue;
1166
- }
1167
- !closing && tagName === "mfrac" ? readable += "(" : closing && tagName === "mfrac" ? readable += ")" : !closing && tagName === "mspace" && (readable += " "), offset = tagEnd + 1;
1168
- }
1169
- return sanitizeInlineText(
1170
- decodeXmlEntities(readable).replace(/[<>]/g, "").replace(/\s+/g, " ").trim()
1105
+ function isMarkdownMathImageRendererReady() {
1106
+ return customRasterizer != null || builtinRasterizerReady;
1107
+ }
1108
+ async function loadMarkdownMathImageRenderer() {
1109
+ return isMarkdownMathImageRendererReady() ? !0 : (builtinRasterizerReady = (customRasterizer ?? await loadBuiltinMathRasterizer()) != null, builtinRasterizerReady);
1110
+ }
1111
+ function hashMathImageKey(value) {
1112
+ let hash = 2166136261;
1113
+ for (let i = 0; i < value.length; i++)
1114
+ hash ^= value.charCodeAt(i), hash = Math.imul(hash, 16777619);
1115
+ return (hash >>> 0).toString(36);
1116
+ }
1117
+ function mathImageCacheKey(tex, mode, options) {
1118
+ return hashMathImageKey(
1119
+ [
1120
+ mode,
1121
+ tex,
1122
+ options.cellWidthPx,
1123
+ options.cellHeightPx,
1124
+ options.scale,
1125
+ options.maxWidthCells,
1126
+ options.color,
1127
+ options.baselineRatio
1128
+ ].join("")
1171
1129
  );
1172
1130
  }
1173
- function approximateTexToUnicode(tex) {
1174
- let out = String(tex ?? "");
1175
- return out = out.replace(/\\frac\s*\{([^{}]*)\}\s*\{([^{}]*)\}/g, "$1/$2"), out = out.replace(/\\sqrt\s*\{([^{}]*)\}/g, "\u221A($1)"), out = out.replace(
1176
- /\\([A-Za-z]+)\b/g,
1177
- (_match, command) => TEX_SYMBOLS[command] ?? command
1178
- ), out = out.replace(/\\([^A-Za-z])/g, "$1"), out = out.replace(/[{}]/g, ""), out = out.replace(/\s+/g, " ").trim(), sanitizeInlineText(out.replace(/[<>]/g, ""));
1131
+ function notifyMathImageListeners() {
1132
+ for (let listener of mathImageListeners)
1133
+ try {
1134
+ listener();
1135
+ } catch {
1136
+ }
1137
+ }
1138
+ function getCachedMarkdownMathImage(tex, mode, options) {
1139
+ return mathImageCache.get(mathImageCacheKey(tex, mode, normalizeMathImageOptions(options))) ?? null;
1179
1140
  }
1180
- function canRenderTerminalMath(tex, katex) {
1141
+ function clearMarkdownMathImageCache() {
1142
+ mathImageCache.clear(), mathImageFailed.clear();
1143
+ }
1144
+ function evictOldestMathImageEntry() {
1145
+ let oldest = mathImageCache.keys().next().value;
1146
+ oldest != null && mathImageCache.delete(oldest);
1147
+ }
1148
+ async function getMarkdownMathImage(tex, mode, options) {
1181
1149
  let source = String(tex ?? "").trim();
1182
- if (!source || source.length > 160 || /\\(?:begin|end|left|right|matrix|cases|array|align|color|href|html|includegraphics|class|style|tag|text|operatorname)\b/.test(
1183
- source
1184
- ))
1185
- return !1;
1186
- let commands = source.matchAll(/\\([A-Za-z]+)\b/g);
1187
- for (let match of commands)
1188
- if (!SUPPORTED_COMMANDS.has(match[1] ?? ""))
1189
- return !1;
1190
- try {
1191
- katex.renderToString(source, KATEX_VALIDATE_OPTIONS);
1192
- } catch {
1193
- return !1;
1150
+ if (!source)
1151
+ return null;
1152
+ let normalized = normalizeMathImageOptions(options), key = mathImageCacheKey(source, mode, normalized), cached = mathImageCache.get(key);
1153
+ if (cached)
1154
+ return cached;
1155
+ if (mathImageFailed.has(key))
1156
+ return null;
1157
+ let inflight = mathImageInflight.get(key);
1158
+ if (inflight)
1159
+ return inflight;
1160
+ let pending = (async () => {
1161
+ try {
1162
+ let rasterizer = customRasterizer ?? await loadBuiltinMathRasterizer();
1163
+ if (!rasterizer)
1164
+ return null;
1165
+ let result = await rasterizer(source, mode, normalized);
1166
+ if (result && result.base64)
1167
+ mathImageCache.set(key, result), mathImageCache.size > MAX_CACHE_ENTRIES && evictOldestMathImageEntry(), notifyMathImageListeners();
1168
+ else if (result === null && (mathImageFailed.add(key), mathImageFailed.size > MAX_FAILED_ENTRIES)) {
1169
+ let oldest = mathImageFailed.values().next().value;
1170
+ oldest != null && mathImageFailed.delete(oldest);
1171
+ }
1172
+ return result;
1173
+ } catch {
1174
+ return null;
1175
+ } finally {
1176
+ mathImageInflight.delete(key);
1177
+ }
1178
+ })();
1179
+ return mathImageInflight.set(key, pending), pending;
1180
+ }
1181
+ function enqueueMarkdownMathImages(rows, options, viewport) {
1182
+ let first = Math.max(0, Math.floor(viewport?.firstRow ?? 0)), last = Math.min(rows.length, Math.max(first, Math.ceil(viewport?.lastRow ?? rows.length)));
1183
+ for (let index = first; index < last; index++) {
1184
+ let row = rows[index];
1185
+ if (row)
1186
+ for (let segment of row.segments) {
1187
+ let graphic = segment.graphic;
1188
+ if (graphic?.kind === "math") {
1189
+ !graphic.base64 && graphic.tex && getMarkdownMathImage(graphic.tex, "display", options);
1190
+ continue;
1191
+ }
1192
+ segment.mathAction?.pendingImage && segment.mathAction?.source && getMarkdownMathImage(
1193
+ segment.mathAction.source,
1194
+ segment.mathAction.mode ?? "display",
1195
+ options
1196
+ );
1197
+ }
1194
1198
  }
1195
- return !0;
1196
1199
  }
1197
- function renderMarkdownInlineMathSegment(tex) {
1198
- let source = String(tex ?? "");
1199
- if (!source.trim())
1200
- return { text: "", supported: !1 };
1201
- let katex = loadedKatex;
1202
- if (!katex)
1203
- return loadMarkdownMathRenderer(), { text: "", supported: !1 };
1204
- if (!canRenderTerminalMath(source, katex))
1205
- return { text: "", supported: !1 };
1206
- try {
1207
- let html = katex.renderToString(source, KATEX_TEXT_OPTIONS), rendered = /\\frac\b/.test(source) ? approximateTexToUnicode(source) : textFromKatexMathml(html);
1208
- if (rendered && !rendered.includes("\\"))
1209
- return { text: rendered, supported: !0 };
1210
- } catch {
1211
- return { text: "", supported: !1 };
1212
- }
1213
- let approximate = approximateTexToUnicode(source);
1214
- return approximate && !approximate.includes("\\") ? { text: approximate, supported: !0 } : { text: "", supported: !1 };
1200
+ function base64FromBytes(bytes) {
1201
+ let binary = "";
1202
+ for (let offset = 0; offset < bytes.length; offset += 32768)
1203
+ binary += String.fromCharCode(...bytes.subarray(offset, offset + 32768));
1204
+ return typeof btoa == "function" ? btoa(binary) : Buffer.from(bytes).toString("base64");
1205
+ }
1206
+ function extractSvgMarkup(containerMarkup) {
1207
+ let start = containerMarkup.indexOf("<svg");
1208
+ if (start < 0)
1209
+ return "";
1210
+ let end = containerMarkup.lastIndexOf("</svg>");
1211
+ return end < start ? "" : containerMarkup.slice(start, end + 6);
1212
+ }
1213
+ var RESVG_MODULE_ID = "@resvg/resvg-js";
1214
+ function loadBuiltinMathRasterizer() {
1215
+ return builtinRasterizerLoad || (builtinRasterizerLoad = (async () => {
1216
+ try {
1217
+ let [
1218
+ { mathjax },
1219
+ { TeX },
1220
+ { SVG },
1221
+ { liteAdaptor },
1222
+ { RegisterHTMLHandler },
1223
+ { AllPackages },
1224
+ { Resvg }
1225
+ ] = await Promise.all([
1226
+ import("mathjax-full/js/mathjax.js"),
1227
+ import("mathjax-full/js/input/tex.js"),
1228
+ import("mathjax-full/js/output/svg.js"),
1229
+ import("mathjax-full/js/adaptors/liteAdaptor.js"),
1230
+ import("mathjax-full/js/handlers/html.js"),
1231
+ import("mathjax-full/js/input/tex/AllPackages.js"),
1232
+ import(RESVG_MODULE_ID)
1233
+ ]), adaptor = liteAdaptor();
1234
+ RegisterHTMLHandler(adaptor);
1235
+ let texInput = new TeX({
1236
+ packages: AllPackages,
1237
+ formatError: () => {
1238
+ throw new Error("Malformed TeX");
1239
+ }
1240
+ }), svgOutput = new SVG({ fontCache: "none" }), document = mathjax.document("", { InputJax: texInput, OutputJax: svgOutput });
1241
+ return async (source, mode, options) => {
1242
+ let node = document.convert(source, { display: mode === "display" }), svg = extractSvgMarkup(adaptor.outerHTML(node));
1243
+ if (!svg)
1244
+ return null;
1245
+ let widthEx = Number(/width="([\d.]+)ex"/.exec(svg)?.[1] ?? 0), heightEx = Number(/height="([\d.]+)ex"/.exec(svg)?.[1] ?? 0);
1246
+ if (!(widthEx > 0) || !(heightEx > 0))
1247
+ return null;
1248
+ let exPx = options.cellHeightPx / 2 * options.scale;
1249
+ if (mode === "inline") {
1250
+ let naturalH = heightEx * exPx, naturalW = widthEx * exPx;
1251
+ if (naturalH > options.cellHeightPx * options.scale * 2)
1252
+ return null;
1253
+ let rectH = options.cellHeightPx * options.scale, k = rectH / naturalH, contentW = Math.max(1, Math.round(naturalW * k)), widthCells = Math.max(
1254
+ 1,
1255
+ Math.ceil(contentW / (options.cellWidthPx * options.scale))
1256
+ ), rectW = widthCells * options.cellWidthPx * options.scale, verticalAlignEx = Number(/vertical-align:\s*(-?[\d.]+)ex/.exec(svg)?.[1] ?? 0), formulaBaseline = (heightEx - Math.abs(verticalAlignEx)) * exPx * k, offsetY = options.baselineRatio * rectH - formulaBaseline, inner = svg.replace(/style="vertical-align:[^"]*"/, "").replace(/width="[\d.]+ex"/, `width="${contentW}px"`).replace(/height="[\d.]+ex"/, `height="${rectH}px"`), wrapped = `<svg xmlns="http://www.w3.org/2000/svg" color="${options.color}" width="${rectW}px" height="${rectH}px" viewBox="0 0 ${rectW} ${rectH}"><g transform="translate(0 ${offsetY.toFixed(2)})">${inner}</g></svg>`, pngInline = new Resvg(wrapped, { background: "rgba(0,0,0,0)" }).render().asPng();
1257
+ return !pngInline || pngInline.length < 8 ? null : {
1258
+ base64: base64FromBytes(pngInline),
1259
+ widthCells,
1260
+ heightCells: 1
1261
+ };
1262
+ }
1263
+ let widthPx = Math.max(1, Math.round(widthEx * exPx)), heightPx = Math.max(1, Math.round(heightEx * exPx));
1264
+ if (options.maxWidthCells > 0) {
1265
+ let maxPx = options.maxWidthCells * options.cellWidthPx * options.scale;
1266
+ widthPx > maxPx && (heightPx = Math.max(1, Math.round(heightPx * (maxPx / widthPx))), widthPx = maxPx);
1267
+ }
1268
+ svg = svg.replace(/style="vertical-align:[^"]*"/, "").replace(/width="[\d.]+ex"/, `width="${widthPx}px"`).replace(/height="[\d.]+ex"/, `height="${heightPx}px"`).replace(/<svg/, `<svg color="${options.color}"`);
1269
+ let png = new Resvg(svg, { background: "rgba(0,0,0,0)" }).render().asPng();
1270
+ return !png || png.length < 8 ? null : {
1271
+ base64: base64FromBytes(png),
1272
+ widthCells: Math.max(1, Math.round(widthPx / (options.cellWidthPx * options.scale))),
1273
+ heightCells: Math.max(1, Math.round(heightPx / (options.cellHeightPx * options.scale)))
1274
+ };
1275
+ };
1276
+ } catch {
1277
+ return null;
1278
+ }
1279
+ })()), builtinRasterizerLoad;
1215
1280
  }
1216
1281
 
1217
1282
  // node_modules/.pnpm/stream-markdown-parser@1.1.9/node_modules/stream-markdown-parser/dist/index.js
@@ -18439,17 +18504,26 @@ function inlineNodeSegments(nodes, theme, inheritedStyle, options = {}) {
18439
18504
  break;
18440
18505
  case "math_inline":
18441
18506
  {
18442
- let source = stringProp(node, "content"), raw = stringProp(node, "raw") || `$${source}$`, rendered = renderMarkdownInlineMathSegment(source);
18443
- pushTextSegments(
18507
+ let source = stringProp(node, "content"), markup = stringProp(node, "markup") || "$", raw = stringProp(node, "raw") || `${markup}${source}${markup}`, mathStyle = mergeStyle(inheritedStyle, theme.inlineCode), tex = sanitizeInlineText(source), mathEnabled = options.math?.enabled !== !1, cached = tex && mathEnabled ? getCachedMarkdownMathImage(tex, "inline", options.math) : null;
18508
+ cached ? pushTextSegments(
18444
18509
  out,
18445
- rendered.supported ? rendered.text : raw,
18446
- mergeStyle(inheritedStyle, theme.inlineCode),
18447
- void 0,
18510
+ raw,
18511
+ mathStyle,
18448
18512
  {
18449
- source,
18513
+ kind: "math",
18514
+ tex,
18450
18515
  raw,
18451
- rendered: rendered.supported
18452
- }
18516
+ base64: cached.base64,
18517
+ displayWidth: cached.widthCells,
18518
+ displayHeight: cached.heightCells
18519
+ },
18520
+ { source: tex, raw, rendered: !0 }
18521
+ ) : pushTextSegments(
18522
+ out,
18523
+ raw,
18524
+ mathStyle,
18525
+ void 0,
18526
+ tex && mathEnabled ? { source: tex, raw, rendered: !1, pendingImage: !0, mode: "inline" } : { source, raw, rendered: !1 }
18453
18527
  );
18454
18528
  }
18455
18529
  break;
@@ -18489,7 +18563,8 @@ function blockFromParagraph(node, key, context, theme) {
18489
18563
  key,
18490
18564
  inlineNodeSegments(nodeChildren(node), theme, void 0, {
18491
18565
  imageResolver: context.imageResolver,
18492
- imageSize: context.imageSize
18566
+ imageSize: context.imageSize,
18567
+ math: context.math
18493
18568
  }),
18494
18569
  context
18495
18570
  );
@@ -18500,7 +18575,8 @@ function blockFromHeading(node, key, context, theme) {
18500
18575
  key,
18501
18576
  inlineNodeSegments(nodeChildren(node), theme, theme.heading[level - 1], {
18502
18577
  imageResolver: context.imageResolver,
18503
- imageSize: context.imageSize
18578
+ imageSize: context.imageSize,
18579
+ math: context.math
18504
18580
  }),
18505
18581
  context
18506
18582
  );
@@ -18530,7 +18606,7 @@ function blockFromHtmlBlock(node, key, context, theme) {
18530
18606
  ],
18531
18607
  theme,
18532
18608
  void 0,
18533
- { imageResolver: context.imageResolver }
18609
+ { imageResolver: context.imageResolver, math: context.math }
18534
18610
  ),
18535
18611
  context
18536
18612
  );
@@ -18553,14 +18629,16 @@ function blockFromTable(node, key, context, theme) {
18553
18629
  ).map((cell) => ({
18554
18630
  segments: inlineNodeSegments(nodeChildren(cell), theme, theme.strong, {
18555
18631
  imageResolver: context.imageResolver,
18556
- imageSize: context.imageSize
18632
+ imageSize: context.imageSize,
18633
+ math: context.math
18557
18634
  }),
18558
18635
  align: tableCellAlign(cell)
18559
18636
  })), rows = tableRows(node, "rows").map(
18560
18637
  (row) => tableCells(row).map((cell) => ({
18561
18638
  segments: inlineNodeSegments(nodeChildren(cell), theme, void 0, {
18562
18639
  imageResolver: context.imageResolver,
18563
- imageSize: context.imageSize
18640
+ imageSize: context.imageSize,
18641
+ math: context.math
18564
18642
  }),
18565
18643
  align: tableCellAlign(cell)
18566
18644
  }))
@@ -18590,10 +18668,12 @@ function listItemBlocks(item, index, ordered, start, context, theme, keyPrefix)
18590
18668
  text: spaces(markerCells)
18591
18669
  }, firstContext = {
18592
18670
  prefixSegments: [...context.prefixSegments, markerSegment],
18593
- continuationPrefixSegments: [...context.continuationPrefixSegments, indentSegment]
18671
+ continuationPrefixSegments: [...context.continuationPrefixSegments, indentSegment],
18672
+ math: context.math
18594
18673
  }, nestedContext = {
18595
18674
  prefixSegments: [...context.continuationPrefixSegments, indentSegment],
18596
- continuationPrefixSegments: [...context.continuationPrefixSegments, indentSegment]
18675
+ continuationPrefixSegments: [...context.continuationPrefixSegments, indentSegment],
18676
+ math: context.math
18597
18677
  }, children = nodeChildren(item);
18598
18678
  if (!children.length)
18599
18679
  return [inlineBlock(`${keyPrefix}-empty`, [], firstContext)];
@@ -18632,6 +18712,37 @@ function listBlocks(node, context, theme, keyPrefix) {
18632
18712
  );
18633
18713
  return out;
18634
18714
  }
18715
+ function blockMathSegments(source, raw, math, theme) {
18716
+ let tex = sanitizeInlineText(source), canUseImage = !!tex && math.enabled !== !1, cached = canUseImage ? getCachedMarkdownMathImage(tex, "display", math) : null;
18717
+ if (canUseImage && cached)
18718
+ return [
18719
+ {
18720
+ text: raw,
18721
+ style: theme.math,
18722
+ graphic: {
18723
+ kind: "math",
18724
+ tex,
18725
+ raw,
18726
+ base64: cached.base64,
18727
+ displayWidth: cached.widthCells,
18728
+ displayHeight: cached.heightCells
18729
+ },
18730
+ mathAction: { source: tex, raw, rendered: !0 }
18731
+ }
18732
+ ];
18733
+ let maxWidth = Math.max(8, Math.floor(math.maxWidthCells ?? 0) || 40), rawCells = textCellWidth(raw), inner = Math.min(Math.max(1, rawCells + 2), maxWidth), pad = Math.max(0, inner - rawCells);
18734
+ return [
18735
+ { text: `\u250C${"\u2500".repeat(inner)}\u2510`, style: theme.math },
18736
+ HARD_BREAK_SEGMENT,
18737
+ {
18738
+ text: `\u2502 ${raw}${" ".repeat(pad)}\u2502`,
18739
+ style: theme.math,
18740
+ mathAction: { source: tex, raw, rendered: !1, pendingImage: !0 }
18741
+ },
18742
+ HARD_BREAK_SEGMENT,
18743
+ { text: `\u2514${"\u2500".repeat(inner)}\u2518`, style: theme.math }
18744
+ ];
18745
+ }
18635
18746
  function nodeToBlocks(node, context, theme, keyPrefix) {
18636
18747
  switch (node.type) {
18637
18748
  case "paragraph":
@@ -18656,6 +18767,19 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
18656
18767
  prefixSegments: context.prefixSegments
18657
18768
  }
18658
18769
  ];
18770
+ case "math_block":
18771
+ return [
18772
+ inlineBlock(
18773
+ keyPrefix,
18774
+ blockMathSegments(
18775
+ stringProp(node, "content"),
18776
+ stringProp(node, "raw") || `$${stringProp(node, "content")}$`,
18777
+ context.math ?? { enabled: !0 },
18778
+ theme
18779
+ ),
18780
+ context
18781
+ )
18782
+ ];
18659
18783
  case "blockquote": {
18660
18784
  let quoteSegment = {
18661
18785
  text: "\u2502 ",
@@ -18664,7 +18788,8 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
18664
18788
  prefixSegments: [...context.prefixSegments, quoteSegment],
18665
18789
  continuationPrefixSegments: [...context.continuationPrefixSegments, quoteSegment],
18666
18790
  imageResolver: context.imageResolver,
18667
- imageSize: context.imageSize
18791
+ imageSize: context.imageSize,
18792
+ math: context.math
18668
18793
  };
18669
18794
  return childSequenceToBlocks(nodeChildren(node), quoteContext, theme, keyPrefix);
18670
18795
  }
@@ -18680,7 +18805,8 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
18680
18805
  keyPrefix,
18681
18806
  inlineNodeSegments(nodeChildren(node), theme, void 0, {
18682
18807
  imageResolver: context.imageResolver,
18683
- imageSize: context.imageSize
18808
+ imageSize: context.imageSize,
18809
+ math: context.math
18684
18810
  }),
18685
18811
  context
18686
18812
  )
@@ -18693,7 +18819,10 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
18693
18819
  return [
18694
18820
  inlineBlock(
18695
18821
  keyPrefix,
18696
- inlineNodeSegments([node], theme, void 0, { imageResolver: context.imageResolver }),
18822
+ inlineNodeSegments([node], theme, void 0, {
18823
+ imageResolver: context.imageResolver,
18824
+ math: context.math
18825
+ }),
18697
18826
  context
18698
18827
  )
18699
18828
  ];
@@ -18701,7 +18830,10 @@ function nodeToBlocks(node, context, theme, keyPrefix) {
18701
18830
  return nodeChildren(node).length ? childSequenceToBlocks(nodeChildren(node), context, theme, keyPrefix) : [
18702
18831
  inlineBlock(
18703
18832
  keyPrefix,
18704
- inlineNodeSegments([node], theme, void 0, { imageResolver: context.imageResolver }),
18833
+ inlineNodeSegments([node], theme, void 0, {
18834
+ imageResolver: context.imageResolver,
18835
+ math: context.math
18836
+ }),
18705
18837
  context
18706
18838
  )
18707
18839
  ];
@@ -18714,7 +18846,8 @@ function markdownAstToBlocks(nodes, theme, options = {}) {
18714
18846
  prefixSegments: EMPTY_PREFIX,
18715
18847
  continuationPrefixSegments: EMPTY_PREFIX,
18716
18848
  imageResolver: options.imageResolver,
18717
- imageSize: options.imageSize
18849
+ imageSize: options.imageSize,
18850
+ math: options.math
18718
18851
  },
18719
18852
  theme,
18720
18853
  "md"
@@ -18835,7 +18968,8 @@ function wrapLineSegments(source, prefixSegments, continuationPrefixSegments, wi
18835
18968
  style: segment.style,
18836
18969
  cells,
18837
18970
  graphic: segment.graphic,
18838
- fallbackText: segment.text
18971
+ fallbackText: segment.text,
18972
+ ...segment.mathAction ? { mathAction: segment.mathAction } : {}
18839
18973
  }), row.remaining -= cells;
18840
18974
  continue;
18841
18975
  }
@@ -19061,7 +19195,8 @@ function styleSignature(style) {
19061
19195
  function inlineSegmentSignature(segment) {
19062
19196
  let graphic = segment.graphic ? [
19063
19197
  segment.graphic.kind,
19064
- segment.graphic.src,
19198
+ segment.graphic.src ?? "",
19199
+ segment.graphic.tex ?? "",
19065
19200
  segment.graphic.alt ?? "",
19066
19201
  segment.graphic.mime ?? "",
19067
19202
  segment.graphic.base64 ?? "",
@@ -19196,7 +19331,8 @@ var DEFAULT_HEADING = Object.freeze([
19196
19331
  listMarker: freezeStyle({ fg: "cyanBright", bold: !0 }),
19197
19332
  codeBlock: freezeStyle({ fg: "yellowBright" }),
19198
19333
  thematicBreak: freezeStyle({ dim: !0 }),
19199
- html: freezeStyle({ dim: !0 })
19334
+ html: freezeStyle({ dim: !0 }),
19335
+ math: freezeStyle({ fg: "cyanBright" })
19200
19336
  });
19201
19337
  function stableSerialize(value) {
19202
19338
  return value == null ? "null" : typeof value != "object" ? JSON.stringify(value) : Array.isArray(value) ? `[${value.map((item) => stableSerialize(item)).join(",")}]` : `{${Object.entries(value).sort(
@@ -19229,7 +19365,8 @@ function resolveTuiMarkdownTheme(overrides) {
19229
19365
  DEFAULT_TUI_MARKDOWN_THEME.thematicBreak,
19230
19366
  overrides.thematicBreak
19231
19367
  ),
19232
- html: mergeFrozenStyle(DEFAULT_TUI_MARKDOWN_THEME.html, overrides.html)
19368
+ html: mergeFrozenStyle(DEFAULT_TUI_MARKDOWN_THEME.html, overrides.html),
19369
+ math: mergeFrozenStyle(DEFAULT_TUI_MARKDOWN_THEME.math, overrides.math)
19233
19370
  });
19234
19371
  }
19235
19372
 
@@ -19239,7 +19376,8 @@ function buildMarkdownBlocks(content, parser, options) {
19239
19376
  try {
19240
19377
  let nodes = parser.parse(content, options?.final ?? !0), blocks = markdownAstToBlocks(nodes, theme, {
19241
19378
  imageResolver: options?.imageResolver,
19242
- imageSize: options?.imageSize
19379
+ imageSize: options?.imageSize,
19380
+ math: options?.math
19243
19381
  });
19244
19382
  return { nodes, blocks };
19245
19383
  } catch (error) {
@@ -19389,11 +19527,11 @@ function findMarkdownMathActionAt(rows, point, options) {
19389
19527
  let math = segment.mathAction;
19390
19528
  if (!math || segmentEnd <= clipStart || segmentStart >= clipEnd)
19391
19529
  continue;
19392
- let visibleStart = Math.max(segmentStart, clipStart), visibleEnd = Math.min(segmentEnd, clipEnd), rect = {
19530
+ let visibleStart = Math.max(segmentStart, clipStart), visibleEnd = Math.min(segmentEnd, clipEnd), graphicHeight = segment.graphic ? Math.max(1, Math.floor(segment.graphic.displayHeight ?? 1)) : 1, rect = {
19393
19531
  x: r.x + visibleStart - clipStart,
19394
19532
  y: r.y + rowIndex - firstRow,
19395
19533
  w: visibleEnd - visibleStart,
19396
- h: 1
19534
+ h: graphicHeight
19397
19535
  };
19398
19536
  if (!(point.cellX < rect.x || point.cellY < rect.y || point.cellX >= rect.x + rect.w || point.cellY >= rect.y + rect.h))
19399
19537
  return {
@@ -19409,6 +19547,87 @@ function findMarkdownMathActionAt(rows, point, options) {
19409
19547
  return null;
19410
19548
  }
19411
19549
 
19550
+ // src/vue/markdown/math.ts
19551
+ var loadedKatex = null, katexLoad = null, katexListeners = /* @__PURE__ */ new Set();
19552
+ function resolveKatexRenderer(value) {
19553
+ if (!value || typeof value != "object")
19554
+ return null;
19555
+ let renderToString = value.renderToString;
19556
+ return typeof renderToString == "function" ? { renderToString } : null;
19557
+ }
19558
+ function subscribeMarkdownMathRenderer(listener) {
19559
+ return katexListeners.add(listener), () => katexListeners.delete(listener);
19560
+ }
19561
+ async function loadMarkdownMathRenderer() {
19562
+ return loadedKatex ? !0 : (katexLoad || (katexLoad = import("katex").then((mod) => {
19563
+ let renderer = resolveKatexRenderer(mod.default) ?? resolveKatexRenderer(mod);
19564
+ if (!renderer)
19565
+ return !1;
19566
+ loadedKatex = renderer;
19567
+ for (let listener of katexListeners)
19568
+ listener();
19569
+ return !0;
19570
+ }).catch(() => !1)), katexLoad);
19571
+ }
19572
+ var KATEX_TEXT_OPTIONS = Object.freeze({
19573
+ output: "mathml",
19574
+ throwOnError: !1,
19575
+ strict: "ignore",
19576
+ trust: !1,
19577
+ maxSize: 20,
19578
+ maxExpand: 200
19579
+ }), KATEX_VALIDATE_OPTIONS = Object.freeze({
19580
+ ...KATEX_TEXT_OPTIONS,
19581
+ throwOnError: !0
19582
+ }), TEX_SYMBOLS = Object.freeze({
19583
+ alpha: "\u03B1",
19584
+ beta: "\u03B2",
19585
+ gamma: "\u03B3",
19586
+ delta: "\u03B4",
19587
+ epsilon: "\u03B5",
19588
+ theta: "\u03B8",
19589
+ lambda: "\u03BB",
19590
+ mu: "\u03BC",
19591
+ pi: "\u03C0",
19592
+ rho: "\u03C1",
19593
+ sigma: "\u03C3",
19594
+ tau: "\u03C4",
19595
+ phi: "\u03C6",
19596
+ omega: "\u03C9",
19597
+ Gamma: "\u0393",
19598
+ Delta: "\u0394",
19599
+ Theta: "\u0398",
19600
+ Lambda: "\u039B",
19601
+ Pi: "\u03A0",
19602
+ Sigma: "\u03A3",
19603
+ Phi: "\u03A6",
19604
+ Omega: "\u03A9",
19605
+ int: "\u222B",
19606
+ sum: "\u2211",
19607
+ prod: "\u220F",
19608
+ infty: "\u221E",
19609
+ infinity: "\u221E",
19610
+ pm: "\xB1",
19611
+ times: "\xD7",
19612
+ cdot: "\xB7",
19613
+ div: "\xF7",
19614
+ le: "\u2264",
19615
+ leq: "\u2264",
19616
+ ge: "\u2265",
19617
+ geq: "\u2265",
19618
+ neq: "\u2260",
19619
+ ne: "\u2260",
19620
+ approx: "\u2248",
19621
+ equiv: "\u2261",
19622
+ to: "\u2192",
19623
+ rightarrow: "\u2192",
19624
+ leftarrow: "\u2190",
19625
+ leftrightarrow: "\u2194",
19626
+ partial: "\u2202",
19627
+ nabla: "\u2207",
19628
+ sqrt: "\u221A"
19629
+ }), SUPPORTED_COMMANDS = /* @__PURE__ */ new Set([...Object.keys(TEX_SYMBOLS), "frac", "sqrt"]);
19630
+
19412
19631
  // src/utils/env.ts
19413
19632
  function firstNonEmptyEnv(env, primary, legacy) {
19414
19633
  let primaryValue = env?.[primary];
@@ -19514,7 +19733,7 @@ function mergeStyle2(base, overlay) {
19514
19733
  var activeMarkdownImageGraphics = /* @__PURE__ */ new WeakMap();
19515
19734
  function markdownImageGraphicId(segment, identity) {
19516
19735
  return `md-image:${stableTerminalGraphicNumericId(
19517
- `${identity}:${segment.src}:${segment.displayWidth ?? 0}:${segment.displayHeight ?? 0}:${segment.base64 ?? ""}`
19736
+ `${identity}:${segment.src ?? segment.tex ?? ""}:${segment.displayWidth ?? 0}:${segment.displayHeight ?? 0}:${segment.base64 ?? ""}`
19518
19737
  )}`;
19519
19738
  }
19520
19739
  function rememberMarkdownImageGraphic(terminal, id, rect) {
@@ -19535,7 +19754,7 @@ function clearStaleMarkdownImageGraphicsForRow(terminal, y, keepIds, keepVisible
19535
19754
  !(keepVisibleIds ? y >= rect.y && y < rect.y + rect.h : rect.y === y) || keepIds.has(id) || keepVisibleIds?.has(id) || clearTrackedMarkdownImageGraphic(terminal, id);
19536
19755
  }
19537
19756
  function canAttemptMarkdownImageGraphic(terminal, segment) {
19538
- if (segment.kind !== "image" || !segment.base64)
19757
+ if (!segment.base64)
19539
19758
  return !1;
19540
19759
  let output = getTerminalGraphicsOutput(terminal), protocol = output?.capabilities.preferredProtocol;
19541
19760
  return !!(output?.capabilities.supported && isTerminalGraphicsProtocol(protocol));
@@ -19547,7 +19766,7 @@ function clearMarkdownImageGraphics(terminal, rect) {
19547
19766
  rect && (item.x >= rect.x + rect.w || item.x + item.w <= rect.x || item.y >= rect.y + rect.h || item.y + item.h <= rect.y) || clearTrackedMarkdownImageGraphic(terminal, id);
19548
19767
  }
19549
19768
  function queueMarkdownImageGraphic(terminal, segment, identity, rect) {
19550
- if (segment.kind !== "image" || !segment.base64)
19769
+ if (!segment.base64)
19551
19770
  return "unavailable";
19552
19771
  let output = getTerminalGraphicsOutput(terminal), protocol = output?.capabilities.preferredProtocol;
19553
19772
  if (!output?.capabilities.supported || !isTerminalGraphicsProtocol(protocol))
@@ -19584,7 +19803,7 @@ function queueMarkdownImageGraphic(terminal, segment, identity, rect) {
19584
19803
  sequence,
19585
19804
  resizeSequence,
19586
19805
  clearSequence,
19587
- fallbackText: segment.alt ?? "image"
19806
+ fallbackText: segment.alt ?? (segment.kind === "math" ? segment.raw ?? segment.tex ?? "math" : "image")
19588
19807
  });
19589
19808
  return markdownImageDebug(
19590
19809
  `queue id=${id}`,
@@ -19669,7 +19888,7 @@ function paintMarkdownVisualRow(terminal, row, options) {
19669
19888
  }), graphicAvailable = queueResult || canAttemptMarkdownImageGraphic(terminal, segment.graphic), queuedGraphic = queueResult === "queued", suppressFallback = queuedGraphic || queueResult === "rejected" || graphicAvailable === !0;
19670
19889
  queuedGraphic && queuedGraphics.add(markdownImageGraphicId(segment.graphic, `${row.key}:${segmentIndex}`)), terminal.write(
19671
19890
  suppressFallback ? spaces(visibleCells) : sliceByCellsRange(
19672
- segment.fallbackText ?? segment.graphic.alt ?? "image",
19891
+ segment.fallbackText ?? segment.graphic.alt ?? (segment.graphic.kind === "math" ? segment.graphic.raw ?? segment.graphic.tex ?? "math" : "image"),
19673
19892
  0,
19674
19893
  visibleCells
19675
19894
  ) || spaces(visibleCells),
@@ -20002,6 +20221,13 @@ var TMarkdownText = (0, import_vue8.defineComponent)({
20002
20221
  imageMinHeight: { type: Number, default: void 0 },
20003
20222
  imageMaxHeight: { type: Number, default: void 0 },
20004
20223
  imagePreserveAspectRatio: { type: Boolean, default: !0 },
20224
+ mathImages: { type: Boolean, default: !0 },
20225
+ mathCellWidthPx: { type: Number, default: void 0 },
20226
+ mathCellHeightPx: { type: Number, default: void 0 },
20227
+ mathScale: { type: Number, default: void 0 },
20228
+ mathColor: { type: String, default: void 0 },
20229
+ mathMaxWidthCells: { type: Number, default: void 0 },
20230
+ mathBaselineRatio: { type: Number, default: void 0 },
20005
20231
  imageActions: { type: Boolean, default: !1 },
20006
20232
  mathActions: { type: Boolean, default: !1 },
20007
20233
  linkActions: { type: Boolean, default: !1 },
@@ -20024,9 +20250,11 @@ var TMarkdownText = (0, import_vue8.defineComponent)({
20024
20250
  })
20025
20251
  )
20026
20252
  ), graphicsOutputVersion = (0, import_vue8.shallowRef)(getTerminalGraphicsOutputVersion(terminal)), unsubscribeGraphicsOutput = subscribeTerminalGraphicsOutput(terminal, () => {
20027
- graphicsOutputVersion.value = getTerminalGraphicsOutputVersion(terminal);
20253
+ graphicsOutputVersion.value = getTerminalGraphicsOutputVersion(terminal), enqueuePendingMathImages();
20028
20254
  }), unsubscribeMathRenderer = subscribeMarkdownMathRenderer(() => {
20029
20255
  scheduleRebuild();
20256
+ }), unsubscribeMathImage = subscribeMarkdownMathImage(() => {
20257
+ scheduleRebuild();
20030
20258
  });
20031
20259
  (0, import_vue8.watch)(
20032
20260
  () => `${props.streaming ? 1 : 0}:${(props.customHtmlTags ?? []).join("\0")}`,
@@ -20039,6 +20267,31 @@ var TMarkdownText = (0, import_vue8.defineComponent)({
20039
20267
  );
20040
20268
  }
20041
20269
  );
20270
+ function mathOptions() {
20271
+ if (props.mathImages === !1)
20272
+ return { enabled: !1 };
20273
+ let resolvedColor = props.mathColor ?? resolveMarkdownMathColor(defaultStyle.value.fg);
20274
+ return {
20275
+ enabled: !0,
20276
+ ...props.mathCellWidthPx != null ? { cellWidthPx: props.mathCellWidthPx } : {},
20277
+ ...props.mathCellHeightPx != null ? { cellHeightPx: props.mathCellHeightPx } : {},
20278
+ ...props.mathScale != null ? { scale: props.mathScale } : {},
20279
+ ...resolvedColor != null ? { color: resolvedColor } : {},
20280
+ ...props.mathBaselineRatio != null ? { baselineRatio: props.mathBaselineRatio } : {},
20281
+ maxWidthCells: props.mathMaxWidthCells ?? props.w
20282
+ };
20283
+ }
20284
+ function enqueuePendingMathImages() {
20285
+ if (props.mathImages !== !1 && getTerminalGraphicsOutput(terminal)?.capabilities.supported) {
20286
+ if (!isMarkdownMathImageRendererReady()) {
20287
+ loadMarkdownMathImageRenderer().then((ready) => {
20288
+ ready && alive && scheduleRebuild();
20289
+ });
20290
+ return;
20291
+ }
20292
+ enqueueMarkdownMathImages(rows.value, mathOptions());
20293
+ }
20294
+ }
20042
20295
  function rebuildRows() {
20043
20296
  rows.value = (0, import_vue8.markRaw)(
20044
20297
  withTextWidthProvider(
@@ -20053,10 +20306,11 @@ var TMarkdownText = (0, import_vue8.defineComponent)({
20053
20306
  minHeight: props.imageMinHeight,
20054
20307
  maxHeight: props.imageMaxHeight,
20055
20308
  preserveAspectRatio: props.imagePreserveAspectRatio
20056
- }
20309
+ },
20310
+ math: mathOptions()
20057
20311
  })
20058
20312
  )
20059
- ), documentVersion.value++;
20313
+ ), documentVersion.value++, enqueuePendingMathImages();
20060
20314
  }
20061
20315
  function scheduleRebuild() {
20062
20316
  let currentVersion = ++rebuildVersion;
@@ -20086,14 +20340,21 @@ var TMarkdownText = (0, import_vue8.defineComponent)({
20086
20340
  () => props.imageMaxWidth,
20087
20341
  () => props.imageMinHeight,
20088
20342
  () => props.imageMaxHeight,
20089
- () => props.imagePreserveAspectRatio
20343
+ () => props.imagePreserveAspectRatio,
20344
+ () => props.mathImages,
20345
+ () => props.mathCellWidthPx,
20346
+ () => props.mathCellHeightPx,
20347
+ () => props.mathScale,
20348
+ () => props.mathColor,
20349
+ () => props.mathMaxWidthCells,
20350
+ () => props.mathBaselineRatio
20090
20351
  ],
20091
20352
  () => {
20092
20353
  scheduleRebuild();
20093
20354
  },
20094
20355
  { immediate: !0 }
20095
20356
  ), (0, import_vue8.onBeforeUnmount)(() => {
20096
- alive = !1, rebuildVersion++, unsubscribeGraphicsOutput(), unsubscribeMathRenderer(), clearMarkdownImageGraphics(terminal, fullRect.value);
20357
+ alive = !1, rebuildVersion++, unsubscribeGraphicsOutput(), unsubscribeMathRenderer(), unsubscribeMathImage(), clearMarkdownImageGraphics(terminal, fullRect.value);
20097
20358
  });
20098
20359
  let fullRect = (0, import_vue8.computed)(() => {
20099
20360
  let height = props.h ?? Math.max(1, rows.value.length);
@@ -20407,6 +20668,13 @@ var TVirtualMarkdown = (0, import_vue10.defineComponent)({
20407
20668
  imageMinHeight: { type: Number, default: void 0 },
20408
20669
  imageMaxHeight: { type: Number, default: void 0 },
20409
20670
  imagePreserveAspectRatio: { type: Boolean, default: !0 },
20671
+ mathImages: { type: Boolean, default: !0 },
20672
+ mathCellWidthPx: { type: Number, default: void 0 },
20673
+ mathCellHeightPx: { type: Number, default: void 0 },
20674
+ mathScale: { type: Number, default: void 0 },
20675
+ mathColor: { type: String, default: void 0 },
20676
+ mathMaxWidthCells: { type: Number, default: void 0 },
20677
+ mathBaselineRatio: { type: Number, default: void 0 },
20410
20678
  imageActions: { type: Boolean, default: !1 },
20411
20679
  mathActions: { type: Boolean, default: !1 },
20412
20680
  linkActions: { type: Boolean, default: !1 },
@@ -20434,10 +20702,41 @@ var TVirtualMarkdown = (0, import_vue10.defineComponent)({
20434
20702
  })
20435
20703
  )
20436
20704
  ), graphicsOutputVersion = (0, import_vue10.shallowRef)(getTerminalGraphicsOutputVersion(terminal)), unsubscribeGraphicsOutput = subscribeTerminalGraphicsOutput(terminal, () => {
20437
- graphicsOutputVersion.value = getTerminalGraphicsOutputVersion(terminal);
20705
+ graphicsOutputVersion.value = getTerminalGraphicsOutputVersion(terminal), enqueuePendingMathImages();
20438
20706
  }), unsubscribeMathRenderer = subscribeMarkdownMathRenderer(() => {
20439
20707
  scheduleRebuild();
20708
+ }), unsubscribeMathImage = subscribeMarkdownMathImage(() => {
20709
+ scheduleRebuild();
20440
20710
  });
20711
+ function mathOptions() {
20712
+ if (props.mathImages === !1)
20713
+ return { enabled: !1 };
20714
+ let resolvedColor = props.mathColor ?? resolveMarkdownMathColor(defaultStyle.value.fg);
20715
+ return {
20716
+ enabled: !0,
20717
+ ...props.mathCellWidthPx != null ? { cellWidthPx: props.mathCellWidthPx } : {},
20718
+ ...props.mathCellHeightPx != null ? { cellHeightPx: props.mathCellHeightPx } : {},
20719
+ ...props.mathScale != null ? { scale: props.mathScale } : {},
20720
+ ...resolvedColor != null ? { color: resolvedColor } : {},
20721
+ ...props.mathBaselineRatio != null ? { baselineRatio: props.mathBaselineRatio } : {},
20722
+ maxWidthCells: props.mathMaxWidthCells ?? props.w
20723
+ };
20724
+ }
20725
+ function enqueuePendingMathImages() {
20726
+ if (props.mathImages === !1 || !getTerminalGraphicsOutput(terminal)?.capabilities.supported)
20727
+ return;
20728
+ if (!isMarkdownMathImageRendererReady()) {
20729
+ loadMarkdownMathImageRenderer().then((ready) => {
20730
+ ready && alive && scheduleRebuild();
20731
+ });
20732
+ return;
20733
+ }
20734
+ let h3 = Math.max(0, Math.floor(props.h ?? absRect.value.h));
20735
+ enqueueMarkdownMathImages(rows.value, mathOptions(), {
20736
+ firstRow: internalScrollTop.value,
20737
+ lastRow: internalScrollTop.value + h3
20738
+ });
20739
+ }
20441
20740
  (0, import_vue10.watch)(
20442
20741
  () => `${props.streaming ? 1 : 0}:${(props.customHtmlTags ?? []).join("\0")}`,
20443
20742
  () => {
@@ -20461,13 +20760,14 @@ var TVirtualMarkdown = (0, import_vue10.defineComponent)({
20461
20760
  minHeight: props.imageMinHeight,
20462
20761
  maxHeight: props.imageMaxHeight,
20463
20762
  preserveAspectRatio: props.imagePreserveAspectRatio
20464
- }
20763
+ },
20764
+ math: mathOptions()
20465
20765
  }).blocks;
20466
20766
  return layoutMarkdownBlocksCached(blocks, props.w, layoutCache);
20467
20767
  });
20468
20768
  layoutCache = (0, import_vue10.markRaw)(nextLayout.cache);
20469
20769
  let nextRows = nextLayout.rows;
20470
- rows.value = (0, import_vue10.markRaw)(nextRows), reconcileScrollTop();
20770
+ rows.value = (0, import_vue10.markRaw)(nextRows), enqueuePendingMathImages(), reconcileScrollTop();
20471
20771
  let nextScrollTop = internalScrollTop.value, nextVisibleRows = visibleRowSignatures(nextRows, nextScrollTop), nextVisibleGraphics = visibleRowGraphics(nextRows, nextScrollTop), visibleChanged = prevVisibleRows.length !== nextVisibleRows.length || prevVisibleRows.some((row, index) => row !== nextVisibleRows[index]) || prevVisibleGraphics.some((row, index) => row !== nextVisibleGraphics[index]);
20472
20772
  (!builtOnce || prevScrollTop !== nextScrollTop || visibleChanged) && (documentVersion.value++, selection.refresh());
20473
20773
  }
@@ -20549,7 +20849,9 @@ var TVirtualMarkdown = (0, import_vue10.defineComponent)({
20549
20849
  let remap = pendingSelectionScrollFocusRemap;
20550
20850
  pendingSelectionScrollFocusRemap = !1, applyControlledScrollTop(props.scrollTop, remap);
20551
20851
  }
20552
- ), (0, import_vue10.watch)(
20852
+ ), (0, import_vue10.watch)(internalScrollTop, () => {
20853
+ enqueuePendingMathImages();
20854
+ }), (0, import_vue10.watch)(
20553
20855
  [
20554
20856
  () => props.content,
20555
20857
  () => props.blocks,
@@ -20562,7 +20864,14 @@ var TVirtualMarkdown = (0, import_vue10.defineComponent)({
20562
20864
  () => props.imageMaxWidth,
20563
20865
  () => props.imageMinHeight,
20564
20866
  () => props.imageMaxHeight,
20565
- () => props.imagePreserveAspectRatio
20867
+ () => props.imagePreserveAspectRatio,
20868
+ () => props.mathImages,
20869
+ () => props.mathCellWidthPx,
20870
+ () => props.mathCellHeightPx,
20871
+ () => props.mathScale,
20872
+ () => props.mathColor,
20873
+ () => props.mathMaxWidthCells,
20874
+ () => props.mathBaselineRatio
20566
20875
  ],
20567
20876
  () => {
20568
20877
  scheduleRebuild();
@@ -20743,7 +21052,7 @@ var TVirtualMarkdown = (0, import_vue10.defineComponent)({
20743
21052
  let manager = events.value, nodeId = eventNode.id.value;
20744
21053
  nodeId && manager && manager.getFocused() !== nodeId && manager.focus(nodeId);
20745
21054
  }), (0, import_vue10.onBeforeUnmount)(() => {
20746
- alive = !1, rebuildVersion++, unsubscribeGraphicsOutput(), unsubscribeMathRenderer(), clearMarkdownImageGraphics(terminal, fullRect.value);
21055
+ alive = !1, rebuildVersion++, unsubscribeGraphicsOutput(), unsubscribeMathRenderer(), unsubscribeMathImage(), clearMarkdownImageGraphics(terminal, fullRect.value);
20747
21056
  }), useRenderNode(() => ({
20748
21057
  zIndex: props.zIndex,
20749
21058
  rect: visible.value ? normalizedRect() : { x: 0, y: 0, w: 0, h: 0 },