clone

a personal forge on plain git: static pages, stacked-diff reviews, signed local ci, repo sites and releases

Draw mermaid diagrams at build time, with Pele #15

cat description

Mermaid diagrams in markdown are drawn at build time by Pele 1.6.0 and land in the page as inline SVG, coloured by the stylesheet's tokens through --pele-*, so they follow light and dark mode. No diagram script ships any more: mermaid and its plumbing are gone.

wider than a phonedoes not parsea mermaid fencePele draws itits own sanitizerinline SVGa second drawing forphonesthe source and a notewider than a phonedoes not parsea mermaid fencePele draws itits own sanitizerinline SVGa second drawing forphonesthe source and a note
  • Labels are measured with the sans font's own widths (lib/text-widths.sh), not Pele's Helvetica table, so they fit.
  • The SVG passes a sanitizer of its own that keeps only what Pele draws with; scenario diagram-hostile freezes what hostile diagram text can do.
  • A workaround for Pele reporting syntax error lines in its preprocessed text (errorLine, scenario diagram-error-line), to drop when Pele fixes it.
commits3oldest firstcombined diff 18 files, +545 -1297
revisions2
r2catd08b3dawhat changed since r1
r1catd0e7b0b
discussion0 comments

No comments yet: forge comment 15 adds one.

1/3 Draw mermaid diagrams at build time, with Pele

A ```mermaid fence in markdown was a <pre> that ui.ts filled in the
browser, loading mermaid and picking a light or dark theme
once. Now the build draws it as inline SVG with Pele 1.6.0 (pinned), and
pages ship no diagram script: mermaid, its asset, the data-mermaid
attribute and CI's check for it are gone.

style.css maps Pele's --pele-* variables to the page's tokens (nodes on
--raised outlined in --border-strong, square corners, the sans and mono, bold
at --fw-strong, the chart and syntax colours for series), so a diagram
follows light and dark mode without being drawn again.

Pele sizes nodes by measuring their labels: with a canvas in a browser,
and at build time with a table of Helvetica's widths. The labels are set
in the page's sans, so diagrams.ts gives it a measurer with that font's
widths instead (regular, and bold at 650), made by lib/text-widths.sh;
the mono is 0.6em, as Pele assumes. Over 174 labels of the diagram types
in a browser, its widths are within 0.2% of Open Sans as drawn; Pele's
own table is off by up to 14%.

Markdown is anyone's who can push a repo. Pele escapes a diagram's text,
drops HTML in labels, ignores init directives' CSS and fonts, and keeps
links to safe schemes. Its SVG then goes through a sanitizer of its own,
which keeps only the tags, attributes and style properties Pele draws
with, no images and no url(), and Pele's own classes; raw SVG in the
markdown is still dropped. The markdown's sanitizer sees a placeholder
named by a random token where each diagram goes.

A diagram that doesn't parse shows its source and Pele's reason, and the
page builds. The demo wiki has a diagram, and CI checks it is drawn;
link previews leave diagrams' labels out of their text.
17 files changed, +465 -1297
M.forge/ci4+-
MREADME.md15+-
Mdemo/make-demo.sh14+
Mguide/internals.html2+-
Mlib/assets.ts6+-
Alib/diagrams.ts111++
Mlib/forge.ts9+-
Mlib/markdown.ts29+-
Alib/text-widths.sh32+
Mpackage-lock.json1375+++---------------------------
Mpackage.json2+-
Msite/_includes/base.njk2+-
Msite/assets/style.css14+-
Msite/assets/ui.ts17+-
Atest/scenarios/diagram-broken.sh35+
Atest/scenarios/diagram-hostile.sh58+
Atest/scenarios/diagram-svg.sh37+
M .forge/ci +3 -1
M README.md +14 -1
@@ -704,6 +704,19 @@ files are cached in `.forge/cache/highlight/` by blob id, so pushing a new
704704 branch doesn't redo files that other branches already have. Token colors are705705 CSS variables (`--tok-*`) in `style.css`.706706 707+Mermaid diagrams in markdown (` ```mermaid ` fences) are drawn at build708+time too, as inline SVG, by [Pele](https://pele.run), so pages ship no709+diagram script. `style.css` colours them through Pele's `--pele-*`710+variables, which follow light and dark mode without drawing them again.711+There is no browser at build time to measure text in, so labels are sized712+from a table of the sans font's character widths in `lib/diagrams.ts`713+(`lib/text-widths.sh` makes it from the font). A diagram that doesn't parse714+shows its source and the reason instead. Markdown is anyone's who can push715+a repo: Pele escapes a diagram's text and filters its links and styles,716+then the SVG goes through a sanitizer of its own that keeps only the717+shapes, text and links Pele draws with (no images, no `url()`), while raw718+SVG in the markdown itself is still dropped.719+707720 ## The lake and insights708721 709722 The forge's facts are append-only, but they don't last: `events.jsonl` is
@@ -1332,7 +1345,7 @@ rendered, `/assets/<hash>.css`, shared by pages of a kind. Import
13321345 `macros.njk` with context, or blocks in macros don't reach the bundle.13331346 13341347 Assets ship under content-hashed names (`/assets/style.<hash>.css`,1335-`ui.<hash>.js`, mermaid, sqlite-wasm), so browsers can cache them for good;1348+`ui.<hash>.js`, sqlite-wasm), so browsers can cache them for good;13361349 the stylesheet's `url(./fonts/open-sans.woff2)` becomes the font's hashed name. The same13371350 sources give the same names, and pages' fingerprints include them, so13381351 unchanged pages are still hard-linked. A build keeps the files of the last
M demo/make-demo.sh +14 -0
M guide/internals.html +1 -1
M lib/assets.ts +2 -4
@@ -1,7 +1,7 @@
11 // Assets under content-hashed names, /assets/style.<hash>.css, so browsers22 // can cache them forever: the stylesheet, the logo, the fonts (in fonts/,33 // shipped next to the rest), the vendored scripts, our TypeScript with its4-// types stripped, mermaid, sqlite-wasm (its script and4+// types stripped, sqlite-wasm (its script and55 // its .wasm, for code search), and @simplewebauthn/browser (passkeys, on66 // the sign-in page). 11ty's bundle plugin77 // writes the templates' own CSS next to them, also named by a hash.
@@ -19,12 +19,10 @@ import { fileURLToPath } from 'node:url';
1919 const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');2020 const src = path.join(root, 'site', 'assets');2121 const fonts = path.join(src, 'fonts');22-const MERMAID = path.join(root, 'node_modules', 'mermaid', 'dist', 'mermaid.min.js');2322 const SQLITE = path.join(root, 'node_modules', '@sqlite.org', 'sqlite-wasm', 'dist');2423 const WEBAUTHN = path.join(root, 'node_modules', '@simplewebauthn', 'browser', 'dist', 'bundle', 'index.umd.min.js');2524 // Files from node_modules: short name, the name they ship as, the source.2625 const VENDOR: [string, string, string][] = [27- ['mermaid', 'mermaid.js', MERMAID],2826 // The browser build, an ES module that codesearch.ts imports in its worker.2927 ['sqlite3', 'sqlite3.js', path.join(SQLITE, 'index.mjs')],3028 ['sqlite3wasm', 'sqlite3.wasm', path.join(SQLITE, 'sqlite3.wasm')],
@@ -46,7 +44,7 @@ export interface Asset {
4644 4745 // By short name: style, logo, open-sans, noto-sans-mono, noto-serif,4846 // noto-serif-italic, fixi, ssexi, diffs, keys, live,49-// search, query, codesearch, login, ui, mermaid, sqlite3, sqlite3wasm, webauthn.47+// search, query, codesearch, login, ui, sqlite3, sqlite3wasm, webauthn.5048 export type Assets = Record<string, Asset>;5149 5250 let memo: { key: string; assets: Assets } | null = null;
A lib/diagrams.ts +111 -0
@@ -0,0 +1,111 @@
1+// Mermaid diagrams, drawn at build time: a ```mermaid fence in markdown2+// becomes inline SVG (Pele, https://pele.run) that the stylesheet colours3+// through its --pele-* variables, so it follows light and dark with no4+// script. A diagram that doesn't parse stays its source, with a note.5+//6+// The markdown is anyone's who can push a repo. Pele escapes the text in a7+// diagram and filters its links and styles; then the SVG goes through a8+// sanitizer of its own that keeps only what Pele draws with, apart from9+// the markdown's, whose raw HTML still can't have SVG.10+import { createHash } from 'node:crypto';11+import { PeleError, render, type TextMeasurer } from 'pele';12+import sanitize from 'sanitize-html';13+14+// Text widths of the sans (Open Sans), regular and bold (--fw-strong,15+// which style.css sets diagrams' bold in), in thousandths of an em:16+// U+0020-007E then U+00A0-017F, two base-36 digits each, made by17+// lib/text-widths.sh. Pele measures labels to size nodes, with a canvas in18+// a browser; at build time there is none, and its own table is Helvetica's.19+const REGULAR = '787cb2hyfwmzk9638787fbfw778y7ba7fwfwfwfwfwfwfwfwfwfw7b7bfwfwfwc0owhkhyhik6fgeck7kh7r7hh0eiozkxlmgqlmh5f8fbk9gkpng2fjfw93a793fwc67pfgh0dbh0fm9cf3h17070el70pqh1gqh0h0bdd99wh1dwljejdxd1aff9affw787cfwfwfwfwf9eag4n49tdsfw8yn4dwbwfw9o9o7ph6i77b669oaedskklclmc0hkhkhkhkhkhko4hifgfgfgfg7r7r7r7rk6kxlmlmlmlmlmfwlmk9k9k9k9fjgqhbfgfgfgfgfgfgnydbfmfmfmfm70707070goh1gqgqgqgqgqfwgqh1h1h1h1dxh0dxhkfghkfghkfghidbhidbhidbhidbk6h0k6h1fgfmfgfmfgfmfgfmfgfmk7f3k7f3k7f3k7f3khh1khh17r707r707r707r707r70f8e17h70h0elelei70ei70ei70ei79ei70kxh1kxh1kxh1iskxh1lmgqlmgqlmgqppqch5bdh5bdh5bdf8d9f8d9f8d9f8d9fb9wfb9wfb9wk9h1k9h1k9h1k9h1k9h1k9h1pnljfjdxfjfwd1fwd1fwd18z';20+const BOLD = '787tcmhyfwoikp729494f6fw7r8y7sb5fwfwfwfwfwfwfwfwfwfw7s7sfwfwfwcyoxisiihnkhfjf1k5l28u8ri3fepwm6m0ham0i1fafwkthpqkhxgwg296b596fwbm9hgghfe1hfg7affkhy8484gl84qwhyh3hfhfcbdobjhyfcn8fofcdfatfaatfw787tfwfwfwfwfadpgon4afg9fw8yn4dwbwfwabab9hi2i77s5tabapg9mgnkn1cyisisisisisispvhnfjfjfjfj8u8u8u8ukhm6m0m0m0m0m0fwm0ktktktktgwhaj5ggggggggggggp3e1g7g7g7g784848484h2hyh3h3h3h3h3fwh3hyhyhyhyfchffcisggisggisgghne1hne1hne1hne1khhfkhhsfjg7fjg7fjg7fjg7fjg7k5fkk5fkk5fkk5fkl2hyl2hy8u848u848u848u848u84hmg78r84i3glglfe84fe84fe84fe9dfe84m6hym6hym6hykrm6hym0h3m0h3m0h3qpqzi1cbi1cbi1cbfadofadofadofadofwbjfwbjfwbjkthykthykthykthykthykthyqkn8gwfcgwg2dfg2dfg2dfa8';21+const table = (s: string): Map<number, number> => {22+ const codes = [...Array(0x7f - 0x20).keys()].map((i) => i + 0x20).concat([...Array(0x180 - 0xa0).keys()].map((i) => i + 0xa0));23+ return new Map(codes.map((c, i) => [c, parseInt(s.slice(i * 2, i * 2 + 2), 36)]));24+};25+const widths = [table(REGULAR), table(BOLD)];26+// Characters the sans lacks come from other fonts, as in Pele's own table:27+// marks and zero-width spaces take no room, East Asian wide ones an em,28+// the rest a guess. The mono (Noto Sans Mono) is 0.6em throughout.29+const ZERO = /[̀-ͯ​-‏︀-️]/;30+const WIDE = /[ᄀ-ᅟ⺀-꓏가-힣豈-﫿︰-﹏＀-⦆¢-₩]|[^\0-￿]/u;31+const measurer: TextMeasurer = {32+ width(text, size, style) {33+ const mono = (style & 4) !== 0, w = widths[style & 1];34+ let sum = 0;35+ for (const ch of text) {36+ const c = ch.codePointAt(0)!;37+ if (c < 0x20 || ZERO.test(ch)) continue;38+ sum += WIDE.test(ch) ? (mono ? 1200 : 1000) : mono ? 600 : (w.get(c) ?? 580);39+ }40+ return (sum * size) / 1000;41+ },42+};43+44+// What Pele draws with, and no more: shapes, text, links. No images, no45+// foreign objects, no <style>, no use or xlink references; inline styles only46+// with these properties, and no url() in them or in any attribute.47+const PRESENTATION = ['class', 'style', 'transform', 'fill', 'fill-opacity', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap', 'stroke-linejoin', 'opacity'];48+const SHAPE = [...PRESENTATION, 'x', 'y', 'width', 'height', 'rx', 'ry', 'cx', 'cy', 'r', 'd', 'points'];49+const TEXT = [...PRESENTATION, 'x', 'y', 'font-size', 'font-weight', 'font-style', 'font-family', 'text-anchor', 'xml:space'];50+const SAFE = /^(?![\s\S]*url\s*\()[-\w\s#%.,()+*/"']*$/i;51+const STYLES = [52+ '--_a', '--_b', '--_bg', '--_c', '--_fg', '--_fm', '--_hw', '--_l', '--_m', '--_r', '--_s', '--_tw', '--_w',53+ 'max-width', 'height', 'color', 'direction', 'font', 'font-family', 'font-size', 'font-style', 'font-weight',54+ 'letter-spacing', 'word-spacing', 'text-transform', 'text-decoration', 'fill', 'stroke', 'stroke-width',55+ 'stroke-dasharray', 'opacity', 'rx',56+];57+const SVG: sanitize.IOptions = {58+ allowedTags: ['svg', 'g', 'path', 'rect', 'circle', 'ellipse', 'polygon', 'text', 'tspan', 'title', 'desc', 'a'],59+ allowedAttributes: {60+ svg: [...SHAPE, 'xmlns', 'viewBox', 'preserveAspectRatio', 'role', 'aria-roledescription', 'aria-labelledby', 'aria-describedby', 'aria-hidden'],61+ g: [...TEXT],62+ path: SHAPE, rect: SHAPE, circle: SHAPE, ellipse: SHAPE, polygon: SHAPE,63+ text: TEXT, tspan: TEXT,64+ title: ['id'], desc: ['id'],65+ a: ['href', 'rel', 'target'],66+ },67+ // Pele's own classes; a diagram's classDef names aren't kept, so they68+ // can't pick up the page's styles.69+ allowedClasses: { '*': [/^pele(-[\w-]+)?$/, 'clickable'] },70+ allowedStyles: { '*': Object.fromEntries(STYLES.map((p) => [p, [SAFE]])) },71+ allowedSchemes: ['http', 'https', 'mailto'],72+ allowProtocolRelative: false,73+ // SVG's attribute names have capitals (viewBox); keep them as Pele wrote them.74+ parser: { lowerCaseAttributeNames: false },75+};76+77+const escape = (s: string): string => s.replace(/[&<>"]/g, (c) => `&${{ '&': 'amp', '<': 'lt', '>': 'gt', '"': 'quot' }[c]};`);78+79+// One diagram's HTML. `href` rewrites a link in it, as the markdown's own80+// links are (relative ones resolve to forge pages).81+export function diagram(src: string, href: (url: string) => string = (u) => u): string {82+ // Ids (for the title and description) from the source, so a page that83+ // didn't change builds the same.84+ const idPrefix = 'diagram-' + createHash('sha256').update(src).digest('hex').slice(0, 8);85+ const options = { measurer, images: false, linkSchemes: ['http', 'https', 'mailto'] };86+ let svg;87+ try {88+ svg = render(src, { ...options, idPrefix }).svg;89+ } catch (e) {90+ // Pele's message names the line, and can quote it: shown as text.91+ let why = 'Pele failed on it';92+ if (e instanceof PeleError) why = e.message.split('\n')[0].replace(/[.:]$/, '').slice(0, 160);93+ return `<figure class="diagram-source"><pre><code class="language-mermaid">${escape(src)}</code></pre><figcaption>Not drawn: ${escape(why)}.</figcaption></figure>\n`;94+ }95+ const clean = sanitize(svg, {96+ ...SVG,97+ // Every tag: no url() in any attribute; a link's href rewritten. (A98+ // transform for '*' replaces one for the tag, so it is all here.)99+ transformTags: {100+ '*': (tag, attribs) => ({101+ tagName: tag,102+ attribs: Object.fromEntries(103+ Object.entries(attribs)104+ .filter(([, v]) => !/url\s*\(/i.test(v))105+ .map(([k, v]) => [k, tag === 'a' && k === 'href' ? href(v) : v]),106+ ),107+ }),108+ },109+ });110+ return `<figure class="diagram">${clean}</figure>\n`;111+}
M lib/forge.ts +5 -4
@@ -167,8 +167,8 @@ export function loadForge(env: NodeJS.ProcessEnv = process.env): Forge {
167167 // fingerprint matches the last build (and whose file still exists) isn't168168 // rendered; its file is hard-linked from the live site instead.169169 const live = env.FORGE_LIVE_WWW || null;170- // Pages link assets by hashed name, so a new name (mermaid or Node updated,171- // say) must re-render them too.170+ // Pages link assets by hashed name, so a new name (sqlite-wasm or Node171+ // updated, say) must re-render them too.172172 const code = fingerprint(codeVersion(), Object.values(assets()).map((a) => a.file));173173 const skipped: string[] = [];174174 const pageCaches: Forge['pageCaches'] = [];
@@ -556,10 +556,11 @@ export const filters = {
556556 },557557 // A page's description, for link previews: one line of plain text, cut at558558 // a word near n characters. With html, the text of rendered markdown559- // (markdown-it puts a newline between blocks, so tags can just go).559+ // (markdown-it puts a newline between blocks, so tags can just go), less560+ // its diagrams, whose labels are no sentence.560561 excerpt(s: string | null | undefined, html = false, n = 200): string {561562 let text = String(s ?? '');562- if (html) text = decode(text.replace(/<[^>]*>/g, ''));563+ if (html) text = decode(text.replace(/<figure class="diagram">.*?<\/figure>/gs, '').replace(/<[^>]*>/g, ''));563564 text = text.replace(/\s+/g, ' ').trim();564565 if (text.length <= n) return text;565566 const cut = text.lastIndexOf(' ', n);
M lib/markdown.ts +20 -9
@@ -2,10 +2,12 @@
22 //33 // Raw HTML is allowed through a sanitizer (the common README idioms:44 // centered paragraphs, sized images, <details>, <picture>), never scripts,5-// styles or event handlers. Relative links and images resolve to forge pages6-// and raw files, in markdown and in raw HTML alike.5+// styles, event handlers or SVG. Relative links and images resolve to forge6+// pages and raw files, in markdown and in raw HTML alike.7+import { randomUUID } from 'node:crypto';78 import MarkdownIt from 'markdown-it';89 import sanitize from 'sanitize-html';10+import { diagram } from './diagrams.ts';911 import { highlight, resolve } from './highlight.ts';1012 1113 type Token = ReturnType<MarkdownIt['parse']>[number];
@@ -15,12 +17,20 @@ const md = new MarkdownIt({ html: true, linkify: true, typographer: false, highl
1517 // "NOTICE.md" is not a website, even though .md is a TLD.1618 md.linkify.set({ fuzzyLink: false });1719 18-// ```mermaid blocks become diagrams in the browser (site/assets/diagrams.ts).20+// ```mermaid blocks become SVG diagrams (lib/diagrams.ts), sanitized on21+// their own. In their place the markdown's HTML has a placeholder, which22+// names a random token the source can't know, until it has been sanitized.23+interface Env {24+ token: string;25+ diagrams: string[];26+ href: (url: string) => string;27+}1928 const fence = md.renderer.rules.fence!;20-md.renderer.rules.fence = (tokens, idx, options, env, self) => {29+md.renderer.rules.fence = (tokens, idx, options, env: Env, self) => {2130 const t = tokens[idx];22- if (t.info.trim() === 'mermaid') return `<pre class="mermaid">${md.utils.escapeHtml(t.content)}</pre>\n`;23- return fence(tokens, idx, options, env, self);31+ if (t.info.trim() !== 'mermaid') return fence(tokens, idx, options, env, self);32+ env.diagrams.push(diagram(t.content, env.href));33+ return `<div>${env.token}:${env.diagrams.length - 1}</div>\n`;2434 };2535 2636 const isRelative = (u: string | null | undefined): u is string => !!u && !/^([a-z][a-z0-9+.-]*:|\/\/|#|\/)/i.test(u);
@@ -61,13 +71,13 @@ const ALLOWED = {
6171 input: ['type', 'checked', 'disabled'],6272 },6373 // highlight.js tokens: "hljs-title" plus sub-scopes like "function_".64- allowedClasses: { '*': ['mermaid', /^language-/], span: [/^hljs-/, /^[a-z]+_+$/] },74+ allowedClasses: { '*': [/^language-/], span: [/^hljs-/, /^[a-z]+_+$/] },6575 allowedSchemes: ['http', 'https', 'mailto'],6676 allowProtocolRelative: false,6777 };6878 6979 export function renderMarkdown(src: string, { link = (u) => u, image = (u) => u }: LinkResolver = {}): string {70- const env = {};80+ const env: Env = { token: randomUUID(), diagrams: [], href: (u) => (isRelative(u) ? link(u) : u) };7181 const tokens = md.parse(src, env);7282 const slug = slugger();7383 const walk = (list: Token[]): void => {
@@ -90,7 +100,7 @@ export function renderMarkdown(src: string, { link = (u) => u, image = (u) => u
90100 });91101 const rendered = md.renderer.render(tokens, md.options, env);92102 // Raw HTML in the source (img, a, source) resolves the same way markdown does.93- return sanitize(rendered, {103+ const html = sanitize(rendered, {94104 ...ALLOWED,95105 transformTags: {96106 img: (tag, attribs) => ({ tagName: tag, attribs: { ...attribs, src: isRelative(attribs.src) ? image(attribs.src) : attribs.src, loading: 'lazy', decoding: 'async' } }),
@@ -104,6 +114,7 @@ export function renderMarkdown(src: string, { link = (u) => u, image = (u) => u
104114 }),105115 },106116 });117+ return env.diagrams.length ? html.replace(new RegExp(`<div>${env.token}:(\\d+)</div>`, 'g'), (_, i: string) => env.diagrams[Number(i)]) : html;107118 }108119 109120 // Resolve a relative link against the directory of the file it appears in.
A lib/text-widths.sh +32 -0
M package-lock.json +117 -1258 mechanical
@@ -14,7 +14,7 @@
1414 "@typesafe-ai/sdk": "^0.7.0",1515 "highlight.js": "^11.12.0",1616 "markdown-it": "^14.1.0",17- "mermaid": "^12.2.0",17+ "pele": "1.6.0",1818 "sanitize-html": "^2.18.1"1919 },2020 "devDependencies": {
@@ -217,62 +217,6 @@
217217 "node": ">=18"218218 }219219 },220- "node_modules/@antfu/install-pkg": {221- "version": "2.1.0",222- "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-2.1.0.tgz",223- "integrity": "sha512-sdg9NxU3zR4Mnawfbc/x6GB5Wf17WYud5qOuEuxXjaKpYpMkISSJEjItGebXJ2bQ4DIcly4NYH23mtkGJjvKUw==",224- "license": "MIT",225- "dependencies": {226- "package-manager-detector": "^1.8.0",227- "tinyexec": "^1.3.1"228- },229- "funding": {230- "url": "https://github.com/sponsors/antfu"231- }232- },233- "node_modules/@braintree/sanitize-url": {234- "version": "7.1.2",235- "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.2.tgz",236- "integrity": "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==",237- "license": "MIT"238- },239- "node_modules/@chevrotain/cst-dts-gen": {240- "version": "13.2.0",241- "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-13.2.0.tgz",242- "integrity": "sha512-bA9dvWlhAUcHkNwU+8w9yiUxJPlj/Lm3VqS7MD+NbIR/7LmpNLuK/AWNFdCo/T3SK5ND0/UHf3IJvl/Jn/i6yg==",243- "license": "Apache-2.0",244- "dependencies": {245- "@chevrotain/gast": "13.2.0",246- "@chevrotain/types": "13.2.0"247- }248- },249- "node_modules/@chevrotain/gast": {250- "version": "13.2.0",251- "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-13.2.0.tgz",252- "integrity": "sha512-bCARdAsG+eEbOveSXcOAC7pVxA04I1ionzeMOwIYf5NX7SaS7zgn4Dgug2BSqoL+iyKeMNSorQjsFSHJHsCNwg==",253- "license": "Apache-2.0",254- "dependencies": {255- "@chevrotain/types": "13.2.0"256- }257- },258- "node_modules/@chevrotain/regexp-to-ast": {259- "version": "13.2.0",260- "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-13.2.0.tgz",261- "integrity": "sha512-kxpUkLtiaK09ph+dib+Yvm+3sWSnuwlo25gqfKRgTPNmF6H7uW4gVkMjaRdtnN783S9sM6vUNWh9CsxYX4QwKw==",262- "license": "Apache-2.0"263- },264- "node_modules/@chevrotain/types": {265- "version": "13.2.0",266- "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-13.2.0.tgz",267- "integrity": "sha512-7qrYHRlKfWf2AvBfJi5eVOrKAkbxvMFsy/iIHTGIiApNcEecCaVIdR+mIQhyCBsTDJxBz4JWXHMo6krbhR9hVg==",268- "license": "Apache-2.0"269- },270- "node_modules/@chevrotain/utils": {271- "version": "13.2.0",272- "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-13.2.0.tgz",273- "integrity": "sha512-SzKYY68rseOrb9KILVzPsl6SjkQtdWw01SRGB5aCVI5kFcHltQsOYV3JB0Ffst72DgkvHCyDQ0NLwxtmCCf97Q==",274- "license": "Apache-2.0"275- },276220 "node_modules/@duckdb/node-api": {277221 "version": "1.5.6-r.1",278222 "resolved": "https://registry.npmjs.org/@duckdb/node-api/-/node-api-1.5.6-r.1.tgz",
@@ -411,41 +355,12 @@
411355 "integrity": "sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==",412356 "license": "MIT"413357 },414- "node_modules/@iconify/types": {415- "version": "2.0.0",416- "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",417- "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",418- "license": "MIT"419- },420- "node_modules/@iconify/utils": {421- "version": "3.1.7",422- "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.7.tgz",423- "integrity": "sha512-JZHlwdID+dy+lTgbYC8NEC4zeugqeYsc6jewvzb4c58kHauJn+X7rNwQjxz5p2qSjqaEeQoLkCIQ9v/H4PK0/w==",424- "license": "MIT",425- "dependencies": {426- "@antfu/install-pkg": "^2.0.1",427- "@iconify/types": "^2.0.0",428- "import-meta-resolve": "^4.2.0"429- }430- },431358 "node_modules/@levischuck/tiny-cbor": {432359 "version": "0.2.11",433360 "resolved": "https://registry.npmjs.org/@levischuck/tiny-cbor/-/tiny-cbor-0.2.11.tgz",434361 "integrity": "sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==",435362 "license": "MIT"436363 },437- "node_modules/@mermaid-js/parser": {438- "version": "2.0.1",439- "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-2.0.1.tgz",440- "integrity": "sha512-j37dj/h6p6pots1L7pLPPNuABEEu9WP4OYg9pW1g+nYG331j0+3canE9OagtYdytYvdSAMG+2fKU5cxep6LgjA==",441- "license": "MIT",442- "dependencies": {443- "@chevrotain/types": "~13.2.0"444- },445- "engines": {446- "node": ">=22.12.0"447- }448- },449364 "node_modules/@peculiar/asn1-android": {450365 "version": "2.11.0",451366 "resolved": "https://registry.npmjs.org/@peculiar/asn1-android/-/asn1-android-2.11.0.tgz",
@@ -749,265 +664,6 @@
749664 "node": ">=22"750665 }751666 },752- "node_modules/@types/d3": {753- "version": "7.4.3",754- "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz",755- "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==",756- "license": "MIT",757- "dependencies": {758- "@types/d3-array": "*",759- "@types/d3-axis": "*",760- "@types/d3-brush": "*",761- "@types/d3-chord": "*",762- "@types/d3-color": "*",763- "@types/d3-contour": "*",764- "@types/d3-delaunay": "*",765- "@types/d3-dispatch": "*",766- "@types/d3-drag": "*",767- "@types/d3-dsv": "*",768- "@types/d3-ease": "*",769- "@types/d3-fetch": "*",770- "@types/d3-force": "*",771- "@types/d3-format": "*",772- "@types/d3-geo": "*",773- "@types/d3-hierarchy": "*",774- "@types/d3-interpolate": "*",775- "@types/d3-path": "*",776- "@types/d3-polygon": "*",777- "@types/d3-quadtree": "*",778- "@types/d3-random": "*",779- "@types/d3-scale": "*",780- "@types/d3-scale-chromatic": "*",781- "@types/d3-selection": "*",782- "@types/d3-shape": "*",783- "@types/d3-time": "*",784- "@types/d3-time-format": "*",785- "@types/d3-timer": "*",786- "@types/d3-transition": "*",787- "@types/d3-zoom": "*"788- }789- },790- "node_modules/@types/d3-array": {791- "version": "3.2.2",792- "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz",793- "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==",794- "license": "MIT"795- },796- "node_modules/@types/d3-axis": {797- "version": "3.0.6",798- "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz",799- "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==",800- "license": "MIT",801- "dependencies": {802- "@types/d3-selection": "*"803- }804- },805- "node_modules/@types/d3-brush": {806- "version": "3.0.6",807- "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz",808- "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==",809- "license": "MIT",810- "dependencies": {811- "@types/d3-selection": "*"812- }813- },814- "node_modules/@types/d3-chord": {815- "version": "3.0.6",816- "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz",817- "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==",818- "license": "MIT"819- },820- "node_modules/@types/d3-color": {821- "version": "3.1.3",822- "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",823- "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",824- "license": "MIT"825- },826- "node_modules/@types/d3-contour": {827- "version": "3.0.6",828- "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz",829- "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==",830- "license": "MIT",831- "dependencies": {832- "@types/d3-array": "*",833- "@types/geojson": "*"834- }835- },836- "node_modules/@types/d3-delaunay": {837- "version": "6.0.4",838- "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz",839- "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==",840- "license": "MIT"841- },842- "node_modules/@types/d3-dispatch": {843- "version": "3.0.7",844- "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz",845- "integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==",846- "license": "MIT"847- },848- "node_modules/@types/d3-drag": {849- "version": "3.0.7",850- "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz",851- "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==",852- "license": "MIT",853- "dependencies": {854- "@types/d3-selection": "*"855- }856- },857- "node_modules/@types/d3-dsv": {858- "version": "3.0.7",859- "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz",860- "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==",861- "license": "MIT"862- },863- "node_modules/@types/d3-ease": {864- "version": "3.0.2",865- "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",866- "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",867- "license": "MIT"868- },869- "node_modules/@types/d3-fetch": {870- "version": "3.0.7",871- "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz",872- "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==",873- "license": "MIT",874- "dependencies": {875- "@types/d3-dsv": "*"876- }877- },878- "node_modules/@types/d3-force": {879- "version": "3.0.10",880- "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz",881- "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==",882- "license": "MIT"883- },884- "node_modules/@types/d3-format": {885- "version": "3.0.4",886- "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz",887- "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==",888- "license": "MIT"889- },890- "node_modules/@types/d3-geo": {891- "version": "3.1.1",892- "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.1.tgz",893- "integrity": "sha512-65Emv9fQiQQqphLlRkuQ5ypPsOmWPhtBGCMv61JDPEPMvsx+gzhGf74yw1a78xFKPj6zw4AgQICJoQv0vK9M2w==",894- "license": "MIT",895- "dependencies": {896- "@types/geojson": "*"897- }898- },899- "node_modules/@types/d3-hierarchy": {900- "version": "3.1.7",901- "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz",902- "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==",903- "license": "MIT"904- },905- "node_modules/@types/d3-interpolate": {906- "version": "3.0.4",907- "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",908- "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",909- "license": "MIT",910- "dependencies": {911- "@types/d3-color": "*"912- }913- },914- "node_modules/@types/d3-path": {915- "version": "3.1.1",916- "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz",917- "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==",918- "license": "MIT"919- },920- "node_modules/@types/d3-polygon": {921- "version": "3.0.2",922- "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz",923- "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==",924- "license": "MIT"925- },926- "node_modules/@types/d3-quadtree": {927- "version": "3.0.6",928- "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz",929- "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==",930- "license": "MIT"931- },932- "node_modules/@types/d3-random": {933- "version": "3.0.4",934- "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.4.tgz",935- "integrity": "sha512-UHYId5WTCx4L4YNel7NU00XUXXgvgpgZOvp10PuvsQENjMDXhh2RyFc0KBjO7B45ne4Ha1yVH7ii0vnzKkuzWA==",936- "license": "MIT"937- },938- "node_modules/@types/d3-scale": {939- "version": "4.0.9",940- "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz",941- "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==",942- "license": "MIT",943- "dependencies": {944- "@types/d3-time": "*"945- }946- },947- "node_modules/@types/d3-scale-chromatic": {948- "version": "3.1.0",949- "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",950- "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==",951- "license": "MIT"952- },953- "node_modules/@types/d3-selection": {954- "version": "3.0.12",955- "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.12.tgz",956- "integrity": "sha512-Qe/KWYhEiIIxGs7HrAAjMfShxKldx19SJtr5zu53f3afPsdZNz7HHtdTLXo/kqeiWNXVycI24kSnfzBYkTzpgw==",957- "license": "MIT"958- },959- "node_modules/@types/d3-shape": {960- "version": "3.2.0",961- "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.2.0.tgz",962- "integrity": "sha512-kVd74ta9eof3eJOvbNd1vGKS/XERRyQbT26Og63hIsvDO84cjD5gEOhsXf26w3FSoNlPVz84DOFcKv/oou+fMw==",963- "license": "MIT",964- "dependencies": {965- "@types/d3-path": "*"966- }967- },968- "node_modules/@types/d3-time": {969- "version": "3.0.4",970- "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz",971- "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==",972- "license": "MIT"973- },974- "node_modules/@types/d3-time-format": {975- "version": "4.0.3",976- "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz",977- "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==",978- "license": "MIT"979- },980- "node_modules/@types/d3-timer": {981- "version": "3.0.2",982- "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",983- "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",984- "license": "MIT"985- },986- "node_modules/@types/d3-transition": {987- "version": "3.0.9",988- "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz",989- "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==",990- "license": "MIT",991- "dependencies": {992- "@types/d3-selection": "*"993- }994- },995- "node_modules/@types/d3-zoom": {996- "version": "3.0.9",997- "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.9.tgz",998- "integrity": "sha512-0sE1406XBYJGiqD3AusTl9ZqC//2mIXix51tbom25gDCA8ri4xnSZg28CaSE8Srl6FClqABUKfsn0qghgdepMA==",999- "license": "MIT",1000- "dependencies": {1001- "@types/d3-interpolate": "*",1002- "@types/d3-selection": "*"1003- }1004- },1005- "node_modules/@types/geojson": {1006- "version": "7946.0.16",1007- "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz",1008- "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==",1009- "license": "MIT"1010- },1011667 "node_modules/@types/linkify-it": {1012668 "version": "5.0.0",1013669 "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
@@ -1160,13 +816,6 @@
1160816 "node": ">=20.19.0"1161817 }1162818 },1163- "node_modules/@types/trusted-types": {1164- "version": "2.0.7",1165- "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",1166- "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",1167- "license": "MIT",1168- "optional": true1169- },1170819 "node_modules/@typesafe-ai/sdk": {1171820 "version": "0.7.0",1172821 "resolved": "https://registry.npmjs.org/@typesafe-ai/sdk/-/sdk-0.7.0.tgz",
@@ -1510,696 +1159,153 @@
15101159 "license": "Apache-2.0",15111160 "optional": true,15121161 "os": [1513- "win32"1514- ],1515- "engines": {1516- "node": ">=16.20.0"1517- }1518- },1519- "node_modules/@upsetjs/venn.js": {1520- "version": "2.0.0",1521- "resolved": "https://registry.npmjs.org/@upsetjs/venn.js/-/venn.js-2.0.0.tgz",1522- "integrity": "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==",1523- "license": "MIT",1524- "optionalDependencies": {1525- "d3-selection": "^3.0.0",1526- "d3-transition": "^3.0.1"1527- }1528- },1529- "node_modules/a-sync-waterfall": {1530- "version": "1.0.1",1531- "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",1532- "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==",1533- "license": "MIT"1534- },1535- "node_modules/acorn": {1536- "version": "8.19.0",1537- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz",1538- "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==",1539- "license": "MIT",1540- "bin": {1541- "acorn": "bin/acorn"1542- },1543- "engines": {1544- "node": ">=0.4.0"1545- }1546- },1547- "node_modules/acorn-walk": {1548- "version": "8.3.5",1549- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz",1550- "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==",1551- "license": "MIT",1552- "dependencies": {1553- "acorn": "^8.11.0"1554- },1555- "engines": {1556- "node": ">=0.4.0"1557- }1558- },1559- "node_modules/argparse": {1560- "version": "2.0.1",1561- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",1562- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",1563- "license": "Python-2.0"1564- },1565- "node_modules/asap": {1566- "version": "2.0.6",1567- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",1568- "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",1569- "license": "MIT"1570- },1571- "node_modules/asn1js": {1572- "version": "3.1.0",1573- "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.1.0.tgz",1574- "integrity": "sha512-HWYi1THkOqguCiO+vwj09ZkQFD2kKEsejYHAYCtX0D80WVdoDnvRc9IukXX/jeb0T9NRWJnRtqwdbHltnFjwXA==",1575- "license": "BSD-3-Clause",1576- "dependencies": {1577- "pvtsutils": "^1.3.6",1578- "pvutils": "^1.2.0",1579- "tslib": "^2.8.1"1580- },1581- "engines": {1582- "node": ">=12.0.0"1583- }1584- },1585- "node_modules/balanced-match": {1586- "version": "1.0.2",1587- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",1588- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",1589- "license": "MIT"1590- },1591- "node_modules/bcp-47": {1592- "version": "2.1.1",1593- "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.1.tgz",1594- "integrity": "sha512-KLw+H/gd2p4zly1X7Yh/qziuyae5/w/QFnvTng9eZL5fvszL7Whl3MBoWF8yxL7ksUjBfOD+OxkytiqbBpG+Fw==",1595- "license": "MIT",1596- "dependencies": {1597- "is-alphabetical": "^2.0.0",1598- "is-alphanumerical": "^2.0.0",1599- "is-decimal": "^2.0.0"1600- },1601- "funding": {1602- "type": "github",1603- "url": "https://github.com/sponsors/wooorm"1604- }1605- },1606- "node_modules/bcp-47-match": {1607- "version": "2.0.3",1608- "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz",1609- "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==",1610- "license": "MIT",1611- "funding": {1612- "type": "github",1613- "url": "https://github.com/sponsors/wooorm"1614- }1615- },1616- "node_modules/bcp-47-normalize": {1617- "version": "2.3.0",1618- "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-2.3.0.tgz",1619- "integrity": "sha512-8I/wfzqQvttUFz7HVJgIZ7+dj3vUaIyIxYXaTRP1YWoSDfzt6TUmxaKZeuXR62qBmYr+nvuWINFRl6pZ5DlN4Q==",1620- "license": "MIT",1621- "dependencies": {1622- "bcp-47": "^2.0.0",1623- "bcp-47-match": "^2.0.0"1624- },1625- "funding": {1626- "type": "github",1627- "url": "https://github.com/sponsors/wooorm"1628- }1629- },1630- "node_modules/brace-expansion": {1631- "version": "1.1.21",1632- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz",1633- "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==",1634- "license": "MIT",1635- "dependencies": {1636- "balanced-match": "^1.0.0",1637- "concat-map": "0.0.1"1638- }1639- },1640- "node_modules/chevrotain": {1641- "version": "13.2.0",1642- "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-13.2.0.tgz",1643- "integrity": "sha512-GTouk5YzgBxlTPCaDn5q0q2EJKkrYmnPF+HmF8v0Qo4r3iyPG7HJivkN1wthCXZcm3sIcZFpGTRovLPNdJNRCA==",1644- "license": "Apache-2.0",1645- "dependencies": {1646- "@chevrotain/cst-dts-gen": "13.2.0",1647- "@chevrotain/gast": "13.2.0",1648- "@chevrotain/regexp-to-ast": "13.2.0",1649- "@chevrotain/types": "13.2.0",1650- "@chevrotain/utils": "13.2.0"1651- },1652- "engines": {1653- "node": ">=22.0.0"1654- }1655- },1656- "node_modules/chokidar": {1657- "version": "4.0.3",1658- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",1659- "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",1660- "license": "MIT",1661- "dependencies": {1662- "readdirp": "^4.0.1"1663- },1664- "engines": {1665- "node": ">= 14.16.0"1666- },1667- "funding": {1668- "url": "https://paulmillr.com/funding/"1669- }1670- },1671- "node_modules/commander": {1672- "version": "10.0.1",1673- "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",1674- "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",1675- "license": "MIT",1676- "engines": {1677- "node": ">=14"1678- }1679- },1680- "node_modules/concat-map": {1681- "version": "0.0.1",1682- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",1683- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",1684- "license": "MIT"1685- },1686- "node_modules/cose-base": {1687- "version": "1.0.3",1688- "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz",1689- "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==",1690- "license": "MIT",1691- "dependencies": {1692- "layout-base": "^1.0.0"1693- }1694- },1695- "node_modules/cytoscape": {1696- "version": "3.34.4",1697- "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.34.4.tgz",1698- "integrity": "sha512-msY99tMY8iWTg+sIPGfSqDcPNOt4xcj+v/K/7qUFaCUxxlqnMkUYLBjRUzn9W5CU/R2hrmtJa5+UtovrEM2ctg==",1699- "license": "MIT",1700- "engines": {1701- "node": ">=0.10"1702- }1703- },1704- "node_modules/cytoscape-cose-bilkent": {1705- "version": "4.1.0",1706- "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz",1707- "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==",1708- "license": "MIT",1709- "dependencies": {1710- "cose-base": "^1.0.0"1711- },1712- "peerDependencies": {1713- "cytoscape": "^3.2.0"1714- }1715- },1716- "node_modules/cytoscape-fcose": {1717- "version": "2.2.0",1718- "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz",1719- "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==",1720- "license": "MIT",1721- "dependencies": {1722- "cose-base": "^2.2.0"1723- },1724- "peerDependencies": {1725- "cytoscape": "^3.2.0"1726- }1727- },1728- "node_modules/cytoscape-fcose/node_modules/cose-base": {1729- "version": "2.2.0",1730- "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz",1731- "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==",1732- "license": "MIT",1733- "dependencies": {1734- "layout-base": "^2.0.0"1735- }1736- },1737- "node_modules/cytoscape-fcose/node_modules/layout-base": {1738- "version": "2.0.1",1739- "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz",1740- "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==",1741- "license": "MIT"1742- },1743- "node_modules/d3": {1744- "version": "7.9.0",1745- "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz",1746- "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==",1747- "license": "ISC",1748- "dependencies": {1749- "d3-array": "3",1750- "d3-axis": "3",1751- "d3-brush": "3",1752- "d3-chord": "3",1753- "d3-color": "3",1754- "d3-contour": "4",1755- "d3-delaunay": "6",1756- "d3-dispatch": "3",1757- "d3-drag": "3",1758- "d3-dsv": "3",1759- "d3-ease": "3",1760- "d3-fetch": "3",1761- "d3-force": "3",1762- "d3-format": "3",1763- "d3-geo": "3",1764- "d3-hierarchy": "3",1765- "d3-interpolate": "3",1766- "d3-path": "3",1767- "d3-polygon": "3",1768- "d3-quadtree": "3",1769- "d3-random": "3",1770- "d3-scale": "4",1771- "d3-scale-chromatic": "3",1772- "d3-selection": "3",1773- "d3-shape": "3",1774- "d3-time": "3",1775- "d3-time-format": "4",1776- "d3-timer": "3",1777- "d3-transition": "3",1778- "d3-zoom": "3"1779- },1780- "engines": {1781- "node": ">=12"1782- }1783- },1784- "node_modules/d3-array": {1785- "version": "3.2.4",1786- "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",1787- "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",1788- "license": "ISC",1789- "dependencies": {1790- "internmap": "1 - 2"1791- },1792- "engines": {1793- "node": ">=12"1794- }1795- },1796- "node_modules/d3-axis": {1797- "version": "3.0.0",1798- "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz",1799- "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==",1800- "license": "ISC",1801- "engines": {1802- "node": ">=12"1803- }1804- },1805- "node_modules/d3-brush": {1806- "version": "3.0.0",1807- "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",1808- "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",1809- "license": "ISC",1810- "dependencies": {1811- "d3-dispatch": "1 - 3",1812- "d3-drag": "2 - 3",1813- "d3-interpolate": "1 - 3",1814- "d3-selection": "3",1815- "d3-transition": "3"1816- },1817- "engines": {1818- "node": ">=12"1819- }1820- },1821- "node_modules/d3-chord": {1822- "version": "3.0.1",1823- "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz",1824- "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==",1825- "license": "ISC",1826- "dependencies": {1827- "d3-path": "1 - 3"1828- },1829- "engines": {1830- "node": ">=12"1831- }1832- },1833- "node_modules/d3-color": {1834- "version": "3.1.0",1835- "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",1836- "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",1837- "license": "ISC",1838- "engines": {1839- "node": ">=12"1840- }1841- },1842- "node_modules/d3-contour": {1843- "version": "4.0.2",1844- "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz",1845- "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==",1846- "license": "ISC",1847- "dependencies": {1848- "d3-array": "^3.2.0"1849- },1850- "engines": {1851- "node": ">=12"1852- }1853- },1854- "node_modules/d3-delaunay": {1855- "version": "6.0.4",1856- "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz",1857- "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==",1858- "license": "ISC",1859- "dependencies": {1860- "delaunator": "5"1861- },1862- "engines": {1863- "node": ">=12"1864- }1865- },1866- "node_modules/d3-dispatch": {1867- "version": "3.0.1",1868- "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",1869- "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",1870- "license": "ISC",1871- "engines": {1872- "node": ">=12"1873- }1874- },1875- "node_modules/d3-drag": {1876- "version": "3.0.0",1877- "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",1878- "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",1879- "license": "ISC",1880- "dependencies": {1881- "d3-dispatch": "1 - 3",1882- "d3-selection": "3"1883- },1884- "engines": {1885- "node": ">=12"1886- }1887- },1888- "node_modules/d3-dsv": {1889- "version": "3.0.1",1890- "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz",1891- "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==",1892- "license": "ISC",1893- "dependencies": {1894- "commander": "7",1895- "iconv-lite": "0.6",1896- "rw": "1"1897- },1898- "bin": {1899- "csv2json": "bin/dsv2json.js",1900- "csv2tsv": "bin/dsv2dsv.js",1901- "dsv2dsv": "bin/dsv2dsv.js",1902- "dsv2json": "bin/dsv2json.js",1903- "json2csv": "bin/json2dsv.js",1904- "json2dsv": "bin/json2dsv.js",1905- "json2tsv": "bin/json2dsv.js",1906- "tsv2csv": "bin/dsv2dsv.js",1907- "tsv2json": "bin/dsv2json.js"1908- },1909- "engines": {1910- "node": ">=12"1911- }1912- },1913- "node_modules/d3-dsv/node_modules/commander": {1914- "version": "7.2.0",1915- "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",1916- "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",1917- "license": "MIT",1918- "engines": {1919- "node": ">= 10"1920- }1921- },1922- "node_modules/d3-ease": {1923- "version": "3.0.1",1924- "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",1925- "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",1926- "license": "BSD-3-Clause",1927- "engines": {1928- "node": ">=12"1929- }1930- },1931- "node_modules/d3-fetch": {1932- "version": "3.0.1",1933- "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz",1934- "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==",1935- "license": "ISC",1936- "dependencies": {1937- "d3-dsv": "1 - 3"1938- },1939- "engines": {1940- "node": ">=12"1941- }1942- },1943- "node_modules/d3-force": {1944- "version": "3.0.0",1945- "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",1946- "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",1947- "license": "ISC",1948- "dependencies": {1949- "d3-dispatch": "1 - 3",1950- "d3-quadtree": "1 - 3",1951- "d3-timer": "1 - 3"1952- },1953- "engines": {1954- "node": ">=12"1955- }1956- },1957- "node_modules/d3-format": {1958- "version": "3.1.2",1959- "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz",1960- "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==",1961- "license": "ISC",1962- "engines": {1963- "node": ">=12"1964- }1965- },1966- "node_modules/d3-geo": {1967- "version": "3.1.1",1968- "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz",1969- "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==",1970- "license": "ISC",1971- "dependencies": {1972- "d3-array": "2.5.0 - 3"1973- },1974- "engines": {1975- "node": ">=12"1976- }1977- },1978- "node_modules/d3-hierarchy": {1979- "version": "3.1.2",1980- "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",1981- "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",1982- "license": "ISC",1983- "engines": {1984- "node": ">=12"1985- }1986- },1987- "node_modules/d3-interpolate": {1988- "version": "3.0.1",1989- "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",1990- "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",1991- "license": "ISC",1992- "dependencies": {1993- "d3-color": "1 - 3"1994- },1995- "engines": {1996- "node": ">=12"1997- }1998- },1999- "node_modules/d3-path": {2000- "version": "3.1.0",2001- "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",2002- "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",2003- "license": "ISC",2004- "engines": {2005- "node": ">=12"2006- }2007- },2008- "node_modules/d3-polygon": {2009- "version": "3.0.1",2010- "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz",2011- "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==",2012- "license": "ISC",2013- "engines": {2014- "node": ">=12"2015- }2016- },2017- "node_modules/d3-quadtree": {2018- "version": "3.0.1",2019- "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz",2020- "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==",2021- "license": "ISC",2022- "engines": {2023- "node": ">=12"2024- }2025- },2026- "node_modules/d3-random": {2027- "version": "3.0.1",2028- "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz",2029- "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==",2030- "license": "ISC",2031- "engines": {2032- "node": ">=12"2033- }2034- },2035- "node_modules/d3-sankey": {2036- "version": "0.12.3",2037- "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz",2038- "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==",2039- "license": "BSD-3-Clause",2040- "dependencies": {2041- "d3-array": "1 - 2",2042- "d3-shape": "^1.2.0"2043- }2044- },2045- "node_modules/d3-sankey/node_modules/d3-array": {2046- "version": "2.12.1",2047- "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",2048- "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",2049- "license": "BSD-3-Clause",2050- "dependencies": {2051- "internmap": "^1.0.0"2052- }2053- },2054- "node_modules/d3-sankey/node_modules/d3-path": {2055- "version": "1.0.9",2056- "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",2057- "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==",2058- "license": "BSD-3-Clause"2059- },2060- "node_modules/d3-sankey/node_modules/d3-shape": {2061- "version": "1.3.7",2062- "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",2063- "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",2064- "license": "BSD-3-Clause",2065- "dependencies": {2066- "d3-path": "1"1162+ "win32"1163+ ],1164+ "engines": {1165+ "node": ">=16.20.0"20671166 }20681167 },2069- "node_modules/d3-sankey/node_modules/internmap": {1168+ "node_modules/a-sync-waterfall": {20701169 "version": "1.0.1",2071- "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz",2072- "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==",2073- "license": "ISC"1170+ "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",1171+ "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==",1172+ "license": "MIT"20741173 },2075- "node_modules/d3-scale": {2076- "version": "4.0.2",2077- "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",2078- "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",2079- "license": "ISC",2080- "dependencies": {2081- "d3-array": "2.10.0 - 3",2082- "d3-format": "1 - 3",2083- "d3-interpolate": "1.2.0 - 3",2084- "d3-time": "2.1.1 - 3",2085- "d3-time-format": "2 - 4"1174+ "node_modules/acorn": {1175+ "version": "8.19.0",1176+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz",1177+ "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==",1178+ "license": "MIT",1179+ "bin": {1180+ "acorn": "bin/acorn"20861181 },20871182 "engines": {2088- "node": ">=12"1183+ "node": ">=0.4.0"20891184 }20901185 },2091- "node_modules/d3-scale-chromatic": {2092- "version": "3.1.0",2093- "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",2094- "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==",2095- "license": "ISC",1186+ "node_modules/acorn-walk": {1187+ "version": "8.3.5",1188+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz",1189+ "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==",1190+ "license": "MIT",20961191 "dependencies": {2097- "d3-color": "1 - 3",2098- "d3-interpolate": "1 - 3"1192+ "acorn": "^8.11.0"20991193 },21001194 "engines": {2101- "node": ">=12"1195+ "node": ">=0.4.0"21021196 }21031197 },2104- "node_modules/d3-selection": {2105- "version": "3.0.0",2106- "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",2107- "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",2108- "license": "ISC",2109- "engines": {2110- "node": ">=12"2111- }1198+ "node_modules/argparse": {1199+ "version": "2.0.1",1200+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",1201+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",1202+ "license": "Python-2.0"21121203 },2113- "node_modules/d3-shape": {2114- "version": "3.2.0",2115- "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",2116- "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",2117- "license": "ISC",2118- "dependencies": {2119- "d3-path": "^3.1.0"2120- },2121- "engines": {2122- "node": ">=12"2123- }1204+ "node_modules/asap": {1205+ "version": "2.0.6",1206+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",1207+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",1208+ "license": "MIT"21241209 },2125- "node_modules/d3-time": {1210+ "node_modules/asn1js": {21261211 "version": "3.1.0",2127- "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",2128- "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",2129- "license": "ISC",1212+ "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.1.0.tgz",1213+ "integrity": "sha512-HWYi1THkOqguCiO+vwj09ZkQFD2kKEsejYHAYCtX0D80WVdoDnvRc9IukXX/jeb0T9NRWJnRtqwdbHltnFjwXA==",1214+ "license": "BSD-3-Clause",21301215 "dependencies": {2131- "d3-array": "2 - 3"1216+ "pvtsutils": "^1.3.6",1217+ "pvutils": "^1.2.0",1218+ "tslib": "^2.8.1"21321219 },21331220 "engines": {2134- "node": ">=12"1221+ "node": ">=12.0.0"21351222 }21361223 },2137- "node_modules/d3-time-format": {2138- "version": "4.1.0",2139- "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",2140- "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",2141- "license": "ISC",1224+ "node_modules/balanced-match": {1225+ "version": "1.0.2",1226+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",1227+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",1228+ "license": "MIT"1229+ },1230+ "node_modules/bcp-47": {1231+ "version": "2.1.1",1232+ "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.1.tgz",1233+ "integrity": "sha512-KLw+H/gd2p4zly1X7Yh/qziuyae5/w/QFnvTng9eZL5fvszL7Whl3MBoWF8yxL7ksUjBfOD+OxkytiqbBpG+Fw==",1234+ "license": "MIT",21421235 "dependencies": {2143- "d3-time": "1 - 3"1236+ "is-alphabetical": "^2.0.0",1237+ "is-alphanumerical": "^2.0.0",1238+ "is-decimal": "^2.0.0"21441239 },2145- "engines": {2146- "node": ">=12"1240+ "funding": {1241+ "type": "github",1242+ "url": "https://github.com/sponsors/wooorm"21471243 }21481244 },2149- "node_modules/d3-timer": {2150- "version": "3.0.1",2151- "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",2152- "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",2153- "license": "ISC",2154- "engines": {2155- "node": ">=12"1245+ "node_modules/bcp-47-match": {1246+ "version": "2.0.3",1247+ "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz",1248+ "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==",1249+ "license": "MIT",1250+ "funding": {1251+ "type": "github",1252+ "url": "https://github.com/sponsors/wooorm"21561253 }21571254 },2158- "node_modules/d3-transition": {2159- "version": "3.0.1",2160- "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",2161- "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",2162- "license": "ISC",1255+ "node_modules/bcp-47-normalize": {1256+ "version": "2.3.0",1257+ "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-2.3.0.tgz",1258+ "integrity": "sha512-8I/wfzqQvttUFz7HVJgIZ7+dj3vUaIyIxYXaTRP1YWoSDfzt6TUmxaKZeuXR62qBmYr+nvuWINFRl6pZ5DlN4Q==",1259+ "license": "MIT",21631260 "dependencies": {2164- "d3-color": "1 - 3",2165- "d3-dispatch": "1 - 3",2166- "d3-ease": "1 - 3",2167- "d3-interpolate": "1 - 3",2168- "d3-timer": "1 - 3"2169- },2170- "engines": {2171- "node": ">=12"1261+ "bcp-47": "^2.0.0",1262+ "bcp-47-match": "^2.0.0"21721263 },2173- "peerDependencies": {2174- "d3-selection": "2 - 3"1264+ "funding": {1265+ "type": "github",1266+ "url": "https://github.com/sponsors/wooorm"21751267 }21761268 },2177- "node_modules/d3-zoom": {2178- "version": "3.0.0",2179- "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz",2180- "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",2181- "license": "ISC",1269+ "node_modules/brace-expansion": {1270+ "version": "1.1.21",1271+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz",1272+ "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==",1273+ "license": "MIT",1274+ "dependencies": {1275+ "balanced-match": "^1.0.0",1276+ "concat-map": "0.0.1"1277+ }1278+ },1279+ "node_modules/chokidar": {1280+ "version": "4.0.3",1281+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",1282+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",1283+ "license": "MIT",21821284 "dependencies": {2183- "d3-dispatch": "1 - 3",2184- "d3-drag": "2 - 3",2185- "d3-interpolate": "1 - 3",2186- "d3-selection": "2 - 3",2187- "d3-transition": "2 - 3"1285+ "readdirp": "^4.0.1"21881286 },21891287 "engines": {2190- "node": ">=12"1288+ "node": ">= 14.16.0"1289+ },1290+ "funding": {1291+ "url": "https://paulmillr.com/funding/"21911292 }21921293 },2193- "node_modules/dagre-d3-es": {2194- "version": "7.0.14",2195- "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.14.tgz",2196- "integrity": "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==",1294+ "node_modules/commander": {1295+ "version": "10.0.1",1296+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",1297+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",21971298 "license": "MIT",2198- "dependencies": {2199- "d3": "^7.9.0",2200- "lodash-es": "^4.17.21"1299+ "engines": {1300+ "node": ">=14"22011301 }22021302 },1303+ "node_modules/concat-map": {1304+ "version": "0.0.1",1305+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",1306+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",1307+ "license": "MIT"1308+ },22031309 "node_modules/dayjs": {22041310 "version": "1.11.23",22051311 "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.23.tgz",
@@ -2223,15 +1329,6 @@
22231329 }22241330 }22251331 },2226- "node_modules/delaunator": {2227- "version": "5.1.0",2228- "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.1.0.tgz",2229- "integrity": "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==",2230- "license": "ISC",2231- "dependencies": {2232- "robust-predicates": "^3.0.2"2233- }2234- },22351332 "node_modules/depd": {22361333 "version": "2.0.0",22371334 "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -2309,15 +1406,6 @@
23091406 "url": "https://github.com/fb55/domhandler?sponsor=1"23101407 }23111408 },2312- "node_modules/dompurify": {2313- "version": "3.4.17",2314- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.17.tgz",2315- "integrity": "sha512-B/pSlYVHQ58kqISD/yDjuJ1yfzI34m1gF4lAod2bwSRhiN4K5Cl3H8Af7hqB2PmTL911tdEudnnXn5FnhRoz0w==",2316- "license": "(MPL-2.0 OR Apache-2.0)",2317- "optionalDependencies": {2318- "@types/trusted-types": "^2.0.7"2319- }2320- },23211409 "node_modules/domutils": {23221410 "version": "2.8.0",23231411 "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
@@ -2338,12 +1426,6 @@
23381426 "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",23391427 "license": "MIT"23401428 },2341- "node_modules/elkjs": {2342- "version": "0.9.3",2343- "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz",2344- "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==",2345- "license": "EPL-2.0"2346- },23471429 "node_modules/encodeurl": {23481430 "version": "2.0.0",23491431 "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
@@ -2377,18 +1459,6 @@
23771459 "errno": "cli.js"23781460 }23791461 },2380- "node_modules/es-toolkit": {2381- "version": "1.52.0",2382- "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.52.0.tgz",2383- "integrity": "sha512-XTNEJQh1tY1ZJVcf6ayP/2n4ZPyaHlW2FWs7xvw5ddPuhUVjLD3olQVQS7kf58JbAB48iL0uL/jerTrjtV3lDA==",2384- "license": "MIT",2385- "workspaces": [2386- "docs",2387- "benchmarks",2388- "tests/types",2389- "tests/browser-compat"2390- ]2391- },23921462 "node_modules/escape-html": {23931463 "version": "1.0.3",23941464 "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -2530,12 +1600,6 @@
25301600 "node": ">=11"25311601 }25321602 },2533- "node_modules/hachure-fill": {2534- "version": "0.5.2",2535- "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz",2536- "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==",2537- "license": "MIT"2538- },25391603 "node_modules/highlight.js": {25401604 "version": "11.12.0",25411605 "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.12.0.tgz",
@@ -2605,43 +1669,12 @@
26051669 "url": "https://opencollective.com/express"26061670 }26071671 },2608- "node_modules/iconv-lite": {2609- "version": "0.6.3",2610- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",2611- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",2612- "license": "MIT",2613- "dependencies": {2614- "safer-buffer": ">= 2.1.2 < 3.0.0"2615- },2616- "engines": {2617- "node": ">=0.10.0"2618- }2619- },2620- "node_modules/import-meta-resolve": {2621- "version": "4.2.0",2622- "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz",2623- "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==",2624- "license": "MIT",2625- "funding": {2626- "type": "github",2627- "url": "https://github.com/sponsors/wooorm"2628- }2629- },26301672 "node_modules/inherits": {26311673 "version": "2.0.4",26321674 "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",26331675 "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",26341676 "license": "ISC"26351677 },2636- "node_modules/internmap": {2637- "version": "2.0.3",2638- "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",2639- "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",2640- "license": "ISC",2641- "engines": {2642- "node": ">=12"2643- }2644- },26451678 "node_modules/is-alphabetical": {26461679 "version": "2.0.1",26471680 "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
@@ -2740,36 +1773,6 @@
27401773 "node": ">=8"27411774 }27421775 },2743- "node_modules/katex": {2744- "version": "0.18.10",2745- "resolved": "https://registry.npmjs.org/katex/-/katex-0.18.10.tgz",2746- "integrity": "sha512-/B6p9eY9DX7aHBfpkHdpirDTZ5QH9xTwL9y837PWuzuv41O5jFdqNQwVQEQsimY0/iVNkwBY4+4hMfhQ7d4Dbw==",2747- "funding": [2748- "https://opencollective.com/katex",2749- "https://github.com/sponsors/katex"2750- ],2751- "license": "MIT",2752- "dependencies": {2753- "commander": "^15.0.0"2754- },2755- "bin": {2756- "katex": "cli.js"2757- }2758- },2759- "node_modules/katex/node_modules/commander": {2760- "version": "15.0.0",2761- "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz",2762- "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==",2763- "license": "MIT",2764- "engines": {2765- "node": ">=22.12.0"2766- }2767- },2768- "node_modules/khroma": {2769- "version": "2.1.0",2770- "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz",2771- "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw=="2772- },27731776 "node_modules/kind-of": {27741777 "version": "6.0.3",27751778 "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@@ -2797,12 +1800,6 @@
27971800 "dayjs": "^1.11.23"27981801 }27991802 },2800- "node_modules/layout-base": {2801- "version": "1.0.2",2802- "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz",2803- "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==",2804- "license": "MIT"2805- },28061803 "node_modules/linkify-it": {28071804 "version": "5.0.2",28081805 "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz",
@@ -2848,12 +1845,6 @@
28481845 "integrity": "sha512-+dAZZ2mM+/m+vY9ezfoueVvrgnHIGi5FvgSymbIgJOFwiznWyA59mav95L+Mc6xPtL3s9gm5eNTlNtxJLbNM1g==",28491846 "license": "MIT"28501847 },2851- "node_modules/lodash-es": {2852- "version": "4.18.1",2853- "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz",2854- "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==",2855- "license": "MIT"2856- },28571848 "node_modules/luxon": {28581849 "version": "3.7.2",28591850 "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz",
@@ -2902,58 +1893,12 @@
29021893 "url": "https://github.com/fb55/entities?sponsor=1"29031894 }29041895 },2905- "node_modules/marked": {2906- "version": "16.4.2",2907- "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz",2908- "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==",2909- "license": "MIT",2910- "bin": {2911- "marked": "bin/marked.js"2912- },2913- "engines": {2914- "node": ">= 20"2915- }2916- },29171896 "node_modules/mdurl": {29181897 "version": "2.1.0",29191898 "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.1.0.tgz",29201899 "integrity": "sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==",29211900 "license": "MIT"29221901 },2923- "node_modules/mermaid": {2924- "version": "12.2.0",2925- "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-12.2.0.tgz",2926- "integrity": "sha512-w7nr/SFrLO7BaVTs3dQTvYSV6nYSBj0Yy9DjBhsIJtAcHqRzXSq4Pg32ujHZ/AdWsAMNEvvhbm5dt9E2tOiHzw==",2927- "license": "MIT",2928- "dependencies": {2929- "@braintree/sanitize-url": "^7.1.2",2930- "@iconify/utils": "^3.0.2",2931- "@mermaid-js/parser": "^2.0.1",2932- "@types/d3": "^7.4.3",2933- "@upsetjs/venn.js": "^2.0.0",2934- "chevrotain": "~13.2.0",2935- "cytoscape": "^3.34.0",2936- "cytoscape-cose-bilkent": "^4.1.0",2937- "cytoscape-fcose": "^2.2.0",2938- "d3": "^7.9.0",2939- "d3-sankey": "^0.12.3",2940- "dagre-d3-es": "7.0.14",2941- "dayjs": "^1.11.21",2942- "dompurify": "^3.4.12",2943- "elkjs": "^0.9.3",2944- "es-toolkit": "^1.45.1",2945- "katex": "^0.18.0",2946- "khroma": "^2.1.0",2947- "marked": "^16.3.0",2948- "roughjs": "^4.6.6",2949- "stylis": "^4.3.6",2950- "ts-dedent": "^2.2.0",2951- "uuid": "^11.1.0 || ^12 || ^13 || ^14.0.0"2952- },2953- "engines": {2954- "node": ">=22.12.0"2955- }2956- },29571902 "node_modules/mime": {29581903 "version": "3.0.0",29591904 "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
@@ -3121,12 +2066,6 @@
31212066 "node": ">= 0.8"31222067 }31232068 },3124- "node_modules/package-manager-detector": {3125- "version": "1.9.0",3126- "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.9.0.tgz",3127- "integrity": "sha512-zAMfbta9nPA8AKkA4WdmNAT8R8s6Dk0/xwPsqNnRidMFcLo1YkLuPDTgs2f64XdzS8vbLNnoJ+uUIkgbz7oRHA==",3128- "license": "MIT"3129- },31302069 "node_modules/parse-srcset": {31312070 "version": "1.0.2",31322071 "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
@@ -3142,11 +2081,14 @@
31422081 "node": ">= 0.8"31432082 }31442083 },3145- "node_modules/path-data-parser": {3146- "version": "0.1.0",3147- "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz",3148- "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==",3149- "license": "MIT"2084+ "node_modules/pele": {2085+ "version": "1.6.0",2086+ "resolved": "https://registry.npmjs.org/pele/-/pele-1.6.0.tgz",2087+ "integrity": "sha512-VfAiVItsOGlGhvnBfphdT28VCG7mXMZxQNOwAGsCtxI2ztbUsT39MraEOYjsapLxVETkdUZscm0DdotYDQMLdw==",2088+ "license": "MIT",2089+ "engines": {2090+ "node": ">=20"2091+ }31502092 },31512093 "node_modules/picocolors": {31522094 "version": "1.1.1",
@@ -3175,22 +2117,6 @@
31752117 "semver-compare": "^1.0.0"31762118 }31772119 },3178- "node_modules/points-on-curve": {3179- "version": "0.2.0",3180- "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz",3181- "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==",3182- "license": "MIT"3183- },3184- "node_modules/points-on-path": {3185- "version": "0.2.1",3186- "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz",3187- "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==",3188- "license": "MIT",3189- "dependencies": {3190- "path-data-parser": "0.1.0",3191- "points-on-curve": "0.2.0"3192- }3193- },31942120 "node_modules/postcss": {31952121 "version": "8.5.30",31962122 "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.30.tgz",
@@ -3333,36 +2259,6 @@
33332259 "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",33342260 "license": "Apache-2.0"33352261 },3336- "node_modules/robust-predicates": {3337- "version": "3.0.3",3338- "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz",3339- "integrity": "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==",3340- "license": "Unlicense"3341- },3342- "node_modules/roughjs": {3343- "version": "4.6.6",3344- "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz",3345- "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==",3346- "license": "MIT",3347- "dependencies": {3348- "hachure-fill": "^0.5.2",3349- "path-data-parser": "^0.1.0",3350- "points-on-curve": "^0.2.0",3351- "points-on-path": "^0.2.1"3352- }3353- },3354- "node_modules/rw": {3355- "version": "1.3.3",3356- "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",3357- "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==",3358- "license": "BSD-3-Clause"3359- },3360- "node_modules/safer-buffer": {3361- "version": "2.1.2",3362- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",3363- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",3364- "license": "MIT"3365- },33662262 "node_modules/sanitize-html": {33672263 "version": "2.18.1",33682264 "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.18.1.tgz",
@@ -3613,21 +2509,6 @@
36132509 "node": ">=0.10.0"36142510 }36152511 },3616- "node_modules/stylis": {3617- "version": "4.4.0",3618- "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.4.0.tgz",3619- "integrity": "sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==",3620- "license": "MIT"3621- },3622- "node_modules/tinyexec": {3623- "version": "1.3.1",3624- "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz",3625- "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==",3626- "license": "MIT",3627- "engines": {3628- "node": ">=18"3629- }3630- },36312512 "node_modules/tinyglobby": {36322513 "version": "0.2.17",36332514 "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
@@ -3653,15 +2534,6 @@
36532534 "node": ">=0.6"36542535 }36552536 },3656- "node_modules/ts-dedent": {3657- "version": "2.3.0",3658- "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.3.0.tgz",3659- "integrity": "sha512-JfJeIHke7y2egdGGgRAvpCwYFUsHlM2gPcrVOxFkznt/4uzQ7HFmvE63iFHVLBJNDuyDOQgijDK/tXH/f6Msjg==",3660- "license": "MIT",3661- "engines": {3662- "node": ">=6.10"3663- }3664- },36652537 "node_modules/tslib": {36662538 "version": "2.8.1",36672539 "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@@ -3749,19 +2621,6 @@
37492621 "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==",37502622 "license": "MIT"37512623 },3752- "node_modules/uuid": {3753- "version": "14.0.3",3754- "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.3.tgz",3755- "integrity": "sha512-Sc5u1VVln93y1Xnz4R+CunOZc7R9LUcTmhj7Rc7Eg3HVcf7rVn2FOoa812fe0W8p3jD7xeoGSYbfqCGGH2B6xw==",3756- "funding": [3757- "https://github.com/sponsors/broofa",3758- "https://github.com/sponsors/ctavan"3759- ],3760- "license": "MIT",3761- "bin": {3762- "uuid": "dist-node/bin/uuid"3763- }3764- },37652624 "node_modules/ws": {37662625 "version": "8.22.0",37672626 "resolved": "https://registry.npmjs.org/ws/-/ws-8.22.0.tgz",
M package.json +1 -1
M site/_includes/base.njk +1 -1
M site/assets/style.css +13 -1
@@ -462,7 +462,19 @@ details.att pre, details.howto pre { white-space: pre-wrap; overflow-wrap: anywh
462462 /* In the raised file viewer, code sits on the page's colour, not in a second box. */463463 .viewer .markdown pre, .viewer .markdown code { background: var(--bg); border-color: var(--bg); }464464 .viewer .markdown pre code { background: none; }465-.markdown pre.mermaid { background: none; border: 0; text-align: center; }465+/* Diagrams, drawn at build time (lib/diagrams.ts): Pele's SVG takes its466+ colours and fonts from these, so it follows light and dark as it is. */467+.markdown .diagram { margin: var(--space-4) 0; text-align: center; }468+.markdown .diagram-source { margin: var(--space-4) 0; }469+.markdown .diagram-source figcaption { color: var(--muted); font-size: var(--text-sm); }470+.pele {471+ --pele-bg: var(--bg); --pele-fg: var(--fg); --pele-muted: var(--muted); --pele-line: var(--muted);472+ --pele-surface: var(--raised); --pele-surface-alt: var(--hover); --pele-border: var(--border-strong); --pele-accent: var(--accent);473+ --pele-critical: var(--fail); --pele-error: var(--fail); --pele-font: var(--sans); --pele-font-mono: var(--mono); --pele-radius: var(--radius);474+ --pele-title-weight: var(--fw-strong); --pele-heading-weight: var(--fw-strong); --pele-bold-weight: var(--fw-strong);475+ --pele-series-1: var(--viz-1); --pele-series-2: var(--pass); --pele-series-3: var(--warn); --pele-series-4: var(--fail);476+ --pele-series-5: var(--tok-title); --pele-series-6: var(--tok-const); --pele-series-7: var(--tok-builtin); --pele-series-8: var(--muted);477+}466478 .markdown blockquote { margin: var(--space-4) 0; padding: 0 var(--space-4); color: var(--muted); border-left: var(--bar) solid var(--border); }467479 .markdown table { display: block; max-width: 100%; overflow-x: auto; border-collapse: collapse; margin: var(--space-4) 0; font-size: var(--text-md); }468480 .markdown th, .markdown td { border-bottom: var(--hairline) solid var(--border); padding: var(--space-2) var(--space-3) var(--space-2) 0; text-align: left; vertical-align: top; }
M site/assets/ui.ts +1 -16
A test/scenarios/diagram-broken.sh +35 -0
A test/scenarios/diagram-hostile.sh +58 -0
@@ -0,0 +1,58 @@
1+# Markdown is anyone's who can push a repo, and a diagram's text goes into2+# the page as SVG: none of it can run a script, load anything, restyle the3+# page or link anywhere but where links may go. Pele escapes and filters4+# it, and its SVG passes a sanitizer that keeps only what Pele draws with;5+# SVG written straight into the markdown is still dropped.6+. "$(dirname "$0")/../lib.sh"7+user dami8+repo dami/greet9+clone dami dami/greet "$T/w/d"10+cat >"$T/w/d/README.md" <<'EOF'11+# greet12+13+```mermaid14+---15+title: "<script>alert('title')</script>"16+---17+%%{init: {"themeCSS": "body { display: none }", "fontFamily": "x;background:url(https://evil.example/f)"}}%%18+flowchart LR19+ accTitle: </title><script>alert('acc')</script>20+ A["<script>alert(1)</script>"] --> B["<img src=x onerror=alert(2)>"]21+ B --> C["</text></svg><style>body{display:none}</style>"]22+ C --> D["#lt;a href=#quot;javascript:alert(3)#quot;#gt;x#lt;/a#gt;"]23+ D --> E@{ img: "https://evil.example/pixel.png", label: "img" }24+ click A "javascript:alert(4)"25+ click B href "data:text/html,<script>alert(5)</script>"26+ click C "//evil.example/x"27+ click D "docs/guide.md" "tip"28+ style A fill:red,stroke:#000,font-family:x29+ classDef box fill:#f9f30+ class B box31+```32+33+<svg onload="alert(6)"><rect width="9999" height="9999"/><a href="javascript:alert(7)"><text>raw</text></a></svg>34+EOF35+at "$T/w/d" commit "first" docs/guide.md36+push_as dami "$T/w/d" origin main37+build38+p=$FORGE_WWW/dami/greet/index.html39+fig=$(grep -o '<figure class="diagram">.*</figure>' "$p")40+[ -n "$fig" ] || fail "no diagram on $p"41+tags() { printf '%s' "$fig" | grep -oE '<[^>]*>'; }42+# Only Pele's shapes, text and links: no script, style, image or foreign43+# object, and no attribute but these.44+eq "$(tags | grep -oE '^<[a-z]+' | LC_ALL=C sort -u | tr '\n' ' ')" '<a <figure <g <path <rect <svg <text <title <tspan '45+eq "$(tags | grep -oE ' [a-zA-Z:-]+=' | tr -d ' =' | LC_ALL=C sort -u | tr '\n' ' ')" 'aria-labelledby aria-roledescription class d fill font-weight height href id rel role stroke stroke-linecap style text-anchor transform viewBox width x xml:space xmlns y '46+if tags | grep -qi 'url('; then fail "a url() in the diagram"; fi47+# One link: the relative one, resolved to the forge's page. javascript:,48+# data: and network-path links are dropped.49+eq "$(tags | grep -oE '<a [^>]*>' | sort -u)" '<a href="/dami/greet/blob/main/docs/guide.md/" rel="noopener">'50+# Inline styles keep only drawing properties; classDef names don't reach51+# the page's classes.52+eq "$(tags | grep -oE ' class="[^"]*"' | sed 's/ class="//; s/"$//' | tr ' ' '\n' | grep -vE '^(pele(-[a-zA-Z-]+)?|clickable|diagram)$' | sort -u)" ''53+# The text is text: what looked like markup is escaped or gone.54+printf '%s' "$fig" | grep -q '<title id="diagram-[0-9a-f]\{8\}-title">&lt;/title&gt;&lt;script&gt;alert(.acc.)&lt;/script&gt;</title>' || fail "accTitle not escaped"55+# Init directives don't reach the SVG (their CSS stays out of its tags; the56+# label that says it is text), and raw SVG in the markdown is dropped.57+if tags | grep -q 'display'; then fail "the diagram's CSS reached a tag"; fi58+lacks "$p" 'evil\.example|onload|onerror|<rect width="9999"'
A test/scenarios/diagram-svg.sh +37 -0
@@ -0,0 +1,37 @@
1+# A ```mermaid fence in markdown is drawn at build time: the page has the2+# diagram as inline SVG with its labels as text, and no script draws it.3+. "$(dirname "$0")/../lib.sh"4+user dami5+repo dami/greet6+clone dami dami/greet "$T/w/d"7+cat >"$T/w/d/README.md" <<'EOF'8+# greet9+10+```mermaid11+flowchart LR12+ push[git push] --> pre{pre-receive} -->|ok| post[post-receive] --> build[forge build] --> pages[pages]13+```14+15+Pushes become pages.16+17+```mermaid18+flowchart LR19+ a --> b20+```21+EOF22+at "$T/w/d" commit "first" greet.sh23+push_as dami "$T/w/d" origin main24+build25+p=$FORGE_WWW/dami/greet/index.html26+has "$p" '<figure class="diagram"><svg xmlns="http://www\.w3\.org/2000/svg" class="pele pele-flowchart" viewBox="0 0 [0-9.]+ [0-9.]+"'27+has "$p" '<text class="pele-label"[^>]*>git push</text>'28+has "$p" '>post-receive</text>'29+# Coloured by the stylesheet's --pele-* variables, not colours of its own.30+has "$p" 'style="max-width:100%;height:auto;--_bg:var\(--pele-bg,'31+has "$FORGE_WWW/assets/$(cd "$FORGE_WWW/assets" && ls style.*.css)" '--pele-fg: var\(--fg\)'32+# A link preview's text skips the labels.33+has "$p" '<meta property="og:description" content="greet Pushes become pages\.">'34+# The scripts are the ones every page has; none is for diagrams.35+eq "$(grep -o '<script[^>]*>' "$p" | sed -E 's/\.[A-Za-z0-9_-]{10}\.js//')" "$(grep -o '<script[^>]*>' "$FORGE_WWW/dami/greet/log/main/index.html" | sed -E 's/\.[A-Za-z0-9_-]{10}\.js//')"36+lacks "$p" 'mermaid'37+eq "$(ls "$FORGE_WWW/assets" | grep -ci -e mermaid -e pele)" 0

2/3 Draw a wide diagram again for phones

A diagram is as wide as its layout, and scaled down to fit the column:
a flowchart of eight steps left to right came out 1256px wide, which a
phone shows at 350px, its labels about 4px tall. In a browser Pele's
mount() would draw it again for the width it has; pages here have no
script for that.

So one wider than a phone (340px) is drawn a second time with Pele's
maxWidth at that width, which wraps labels and turns a left-to-right
flowchart top to bottom, and the figure holds both. A container query
shows the second below 640px of column and the first above it. Each
has its own ids, and the hidden one is display: none, so screen readers
read one. Only diagrams that come out narrower get the second drawing.
4 files changed, +34 -8
MREADME.md14++++++++------
Mlib/diagrams.ts17++++++++++++++++-
Msite/assets/style.css8+++++++-
Mtest/scenarios/diagram-svg.sh3+++
M README.md +8 -6
M lib/diagrams.ts +16 -1
M site/assets/style.css +7 -1
M test/scenarios/diagram-svg.sh +3 -0

3/3 Name the line a diagram's syntax error is on

Pele 1.6.0 locates a syntax error in the text its parsers see, which is
not quite the diagram's: front matter and %% comment lines are taken out
first and a newline is added at the end, as Mermaid does. So an error
after front matter or a comment was reported lines early, and one at the
end of a diagram a line past its last (a fence's text ends in a newline,
so two past):

    render('flowchart LR\n  A-->')   // PeleError: line 3, snippet ""

The fallback's note now names the source's line. Pele's snippet quotes
the line it means, which is the source's line as written, at or after
the one Pele counted, so diagrams.ts looks for it there; an error at the
end is on the last line with anything on it. If neither works out (an
entity in the line changes its text), Pele's number stays.

This is a workaround, in one function (errorLine), to drop when Pele
reports lines in the source; scenario diagram-error-line holds the
expected lines either way. Not yet reported upstream.
3 files changed, +56 -2
Mlib/diagrams.ts24++++++++++++++++++++++-
Mtest/scenarios/diagram-broken.sh2+-
Atest/scenarios/diagram-error-line.sh32++++++++++++++++++++++++++++++
M lib/diagrams.ts +23 -1
@@ -74,6 +74,25 @@ const SVG: sanitize.IOptions = {
7474 parser: { lowerCaseAttributeNames: false },7575 };7676 77+// Which line of the source a syntax error is on. Pele 1.6.0 counts lines in78+// the text it parses, which is the source less its front matter and %%79+// comment lines, plus a newline, as Mermaid does: an error after either is80+// reported lines early, and one at the end a line past the last. The line81+// its snippet quotes is the source's, so find it, at or after the line82+// Pele counted; at the end, it is the last line with anything on it. Drop83+// this when Pele reports lines in the source (upstream: see the commit that84+// added it).85+function errorLine(src: string, e: PeleError): number {86+ const lines = src.split(/\r\n?|\n/);87+ const quoted = e.snippet.split('\n')[0];88+ if (quoted.trim() === '') {89+ const last = lines.findLastIndex((l) => l.trim() !== '') + 1;90+ return last > 0 && e.line > last ? last : e.line;91+ }92+ const at = lines.findIndex((l, i) => i >= e.line - 1 && l === quoted);93+ return at === -1 ? e.line : at + 1;94+}95+7796 const escape = (s: string): string => s.replace(/[&<>"]/g, (c) => `&${{ '&': 'amp', '<': 'lt', '>': 'gt', '"': 'quot' }[c]};`);7897 7998 // The width a phone gives a diagram, about. One drawn wider than this gets
@@ -104,7 +123,10 @@ export function diagram(src: string, href: (url: string) => string = (u) => u):
104123 } catch (e) {105124 // Pele's message names the line, and can quote it: shown as text.106125 let why = 'Pele failed on it';107- if (e instanceof PeleError) why = e.message.split('\n')[0].replace(/[.:]$/, '').slice(0, 160);126+ if (e instanceof PeleError) {127+ why = e.message.split('\n')[0].replace(/[.:]$/, '').slice(0, 160);128+ if (e.code === 'syntax' && e.line) why = why.replace(/ on line \d+/, ` on line ${errorLine(src, e)}`);129+ }108130 return `<figure class="diagram-source"><pre><code class="language-mermaid">${escape(src)}</code></pre><figcaption>Not drawn: ${escape(why)}.</figcaption></figure>\n`;109131 }110132 const clean = sanitize(svg, {
M test/scenarios/diagram-broken.sh +1 -1
A test/scenarios/diagram-error-line.sh +32 -0