@cristianormazabal/triton-latex 0.1.15 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -24,8 +24,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/cli.ts
27
- var import_node_fs2 = require("node:fs");
28
- var import_node_path3 = require("node:path");
27
+ var import_node_fs4 = require("node:fs");
28
+ var import_node_path5 = require("node:path");
29
29
  var import_node_url = require("node:url");
30
30
 
31
31
  // ../src/contracts/animations.ts
@@ -460,6 +460,147 @@ function resolveTheme(input, base) {
460
460
  };
461
461
  }
462
462
 
463
+ // ../src/icons/resolver.ts
464
+ var PREFIX_RE = /^[a-z][a-z0-9-]*$/;
465
+ var NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
466
+ var DEFAULT_WIDTH = 16;
467
+ var DEFAULT_HEIGHT = 16;
468
+ var DEFAULT_LEFT = 0;
469
+ var DEFAULT_TOP = 0;
470
+ var MAX_ALIAS_DEPTH = 4;
471
+ function parseIconRef(token) {
472
+ if (typeof token !== "string" || token.length === 0) {
473
+ return err("ICON_NOT_FOUND", `Icon token must be a non-empty string, got ${JSON.stringify(token)}`);
474
+ }
475
+ const colonIdx = token.indexOf(":");
476
+ if (colonIdx === -1) {
477
+ return err("ICON_NOT_FOUND", `Invalid icon token ${JSON.stringify(token)}: must be "prefix:name"`);
478
+ }
479
+ if (token.indexOf(":", colonIdx + 1) !== -1) {
480
+ return err(
481
+ "ICON_NOT_FOUND",
482
+ `Invalid icon token ${JSON.stringify(token)}: too many colons \u2014 expected "prefix:name"`
483
+ );
484
+ }
485
+ const prefix = token.slice(0, colonIdx);
486
+ const name = token.slice(colonIdx + 1);
487
+ if (!PREFIX_RE.test(prefix)) {
488
+ return err(
489
+ "ICON_NOT_FOUND",
490
+ `Invalid icon token ${JSON.stringify(token)}: prefix ${JSON.stringify(prefix)} must match ^[a-z][a-z0-9-]*$`
491
+ );
492
+ }
493
+ if (!NAME_RE.test(name)) {
494
+ return err(
495
+ "ICON_NOT_FOUND",
496
+ `Invalid icon token ${JSON.stringify(token)}: name ${JSON.stringify(name)} must match ^[a-z0-9][a-z0-9-]*$`
497
+ );
498
+ }
499
+ return ok({ prefix, name });
500
+ }
501
+ function detectColorMode(body) {
502
+ if (body.includes("<linearGradient") || body.includes("<radialGradient")) {
503
+ return "brand";
504
+ }
505
+ const ATTR_RE = /(?:fill|stroke)=["']([^"']+)["']/g;
506
+ const NEUTRAL = /* @__PURE__ */ new Set(["none", "currentcolor", "inherit"]);
507
+ let match;
508
+ while ((match = ATTR_RE.exec(body)) !== null) {
509
+ const value = match[1];
510
+ if (value === void 0) continue;
511
+ const lower = value.toLowerCase();
512
+ if (!NEUTRAL.has(lower)) {
513
+ return "brand";
514
+ }
515
+ }
516
+ return "monochrome";
517
+ }
518
+ function mergeViewBox(aliasLevel, iconLevel, packLevel) {
519
+ return {
520
+ width: aliasLevel.width ?? iconLevel.width ?? packLevel.width ?? DEFAULT_WIDTH,
521
+ height: aliasLevel.height ?? iconLevel.height ?? packLevel.height ?? DEFAULT_HEIGHT,
522
+ left: aliasLevel.left ?? iconLevel.left ?? packLevel.left ?? DEFAULT_LEFT,
523
+ top: aliasLevel.top ?? iconLevel.top ?? packLevel.top ?? DEFAULT_TOP
524
+ };
525
+ }
526
+ function composeTransforms(icon, alias) {
527
+ const iconRotate = icon.rotate ?? 0;
528
+ const iconHFlip = icon.hFlip ?? false;
529
+ const iconVFlip = icon.vFlip ?? false;
530
+ if (alias === null) {
531
+ return {
532
+ rotate: iconRotate,
533
+ hFlip: iconHFlip,
534
+ vFlip: iconVFlip
535
+ };
536
+ }
537
+ const aliasRotate = alias.rotate ?? 0;
538
+ const aliasHFlip = alias.hFlip ?? false;
539
+ const aliasVFlip = alias.vFlip ?? false;
540
+ return {
541
+ rotate: (iconRotate + aliasRotate) % 4,
542
+ hFlip: iconHFlip !== aliasHFlip,
543
+ // XOR
544
+ vFlip: iconVFlip !== aliasVFlip
545
+ // XOR
546
+ };
547
+ }
548
+ function resolveIcon(ref, packs) {
549
+ const pack = packs.get(ref.prefix);
550
+ if (pack === void 0) {
551
+ return err("ICON_NOT_FOUND", `Icon pack "${ref.prefix}" not loaded (looking up "${ref.prefix}:${ref.name}")`);
552
+ }
553
+ const directIcon = pack.icons[ref.name];
554
+ if (directIcon !== void 0) {
555
+ const viewBox = mergeViewBox({}, directIcon, pack);
556
+ const transforms = composeTransforms(directIcon, null);
557
+ return ok({
558
+ body: directIcon.body,
559
+ viewBox,
560
+ transforms,
561
+ colorMode: detectColorMode(directIcon.body)
562
+ });
563
+ }
564
+ const aliases = pack.aliases;
565
+ if (aliases === void 0 || !(ref.name in aliases)) {
566
+ return err(
567
+ "ICON_NOT_FOUND",
568
+ `Icon "${ref.name}" not found in pack "${ref.prefix}" (checked icons and aliases)`
569
+ );
570
+ }
571
+ let currentName = ref.name;
572
+ let currentAlias = aliases[ref.name] ?? null;
573
+ const topAlias = currentAlias;
574
+ for (let depth = 0; depth < MAX_ALIAS_DEPTH; depth++) {
575
+ if (currentAlias === null) break;
576
+ const parentName = currentAlias.parent;
577
+ const parentIcon = pack.icons[parentName];
578
+ if (parentIcon !== void 0) {
579
+ const viewBox = mergeViewBox(topAlias ?? {}, parentIcon, pack);
580
+ const transforms = composeTransforms(parentIcon, topAlias);
581
+ return ok({
582
+ body: parentIcon.body,
583
+ viewBox,
584
+ transforms,
585
+ colorMode: detectColorMode(parentIcon.body)
586
+ });
587
+ }
588
+ const parentAlias = aliases[parentName];
589
+ if (parentAlias === void 0) {
590
+ return err(
591
+ "ICON_NOT_FOUND",
592
+ `Alias "${currentName}" in pack "${ref.prefix}" points to parent "${parentName}" which does not exist`
593
+ );
594
+ }
595
+ currentName = parentName;
596
+ currentAlias = parentAlias;
597
+ }
598
+ return err(
599
+ "ICON_NOT_FOUND",
600
+ `Alias chain for "${ref.name}" in pack "${ref.prefix}" exceeds maximum depth of ${MAX_ALIAS_DEPTH}`
601
+ );
602
+ }
603
+
463
604
  // ../src/routing/registry.ts
464
605
  var registry3 = /* @__PURE__ */ new Map();
465
606
  function registerRouter(style, router) {
@@ -1323,6 +1464,8 @@ function elementBoundsAt(el, ox, oy) {
1323
1464
  }
1324
1465
  case "path":
1325
1466
  return null;
1467
+ case "icon":
1468
+ return { x: el.x + ox, y: el.y + oy, width: el.size, height: el.size };
1326
1469
  }
1327
1470
  }
1328
1471
  function parseTranslate(transform) {
@@ -1451,14 +1594,234 @@ function pen(theme) {
1451
1594
  ...opts2.transform !== void 0 ? { transform: opts2.transform } : {},
1452
1595
  ...opts2.opacity !== void 0 ? { opacity: opts2.opacity } : {}
1453
1596
  };
1597
+ },
1598
+ icon(resolvedIcon, x, y, size, opts2 = {}) {
1599
+ return {
1600
+ type: "icon",
1601
+ icon: resolvedIcon,
1602
+ x,
1603
+ y,
1604
+ size,
1605
+ ...opts2.color !== void 0 ? { color: opts2.color } : {},
1606
+ ...opts2.opacity !== void 0 ? { opacity: opts2.opacity } : {}
1607
+ };
1454
1608
  }
1455
1609
  };
1456
1610
  }
1457
1611
 
1612
+ // ../src/text/metrics.ts
1613
+ var ADVANCE = {
1614
+ 32: 0.2793,
1615
+ 33: 0.2793,
1616
+ 34: 0.3574,
1617
+ 35: 0.5576,
1618
+ 36: 0.5576,
1619
+ 37: 0.8906,
1620
+ 38: 0.6699,
1621
+ 39: 0.1914,
1622
+ 40: 0.334,
1623
+ 41: 0.334,
1624
+ 42: 0.3906,
1625
+ 43: 0.5859,
1626
+ 44: 0.2793,
1627
+ 45: 0.334,
1628
+ 46: 0.2793,
1629
+ 47: 0.3125,
1630
+ 48: 0.5576,
1631
+ 49: 0.5576,
1632
+ 50: 0.5576,
1633
+ 51: 0.5576,
1634
+ 52: 0.5576,
1635
+ 53: 0.5576,
1636
+ 54: 0.5576,
1637
+ 55: 0.5576,
1638
+ 56: 0.5576,
1639
+ 57: 0.5576,
1640
+ 58: 0.2793,
1641
+ 59: 0.2793,
1642
+ 60: 0.5859,
1643
+ 61: 0.5859,
1644
+ 62: 0.5859,
1645
+ 63: 0.5576,
1646
+ 64: 1.0186,
1647
+ 65: 0.6699,
1648
+ 66: 0.6699,
1649
+ 67: 0.7227,
1650
+ 68: 0.7227,
1651
+ 69: 0.6699,
1652
+ 70: 0.6133,
1653
+ 71: 0.7793,
1654
+ 72: 0.7227,
1655
+ 73: 0.2783,
1656
+ 74: 0.5,
1657
+ 75: 0.6699,
1658
+ 76: 0.5576,
1659
+ 77: 0.8359,
1660
+ 78: 0.7227,
1661
+ 79: 0.7793,
1662
+ 80: 0.6133,
1663
+ 81: 0.7793,
1664
+ 82: 0.7227,
1665
+ 83: 0.6133,
1666
+ 84: 0.6133,
1667
+ 85: 0.7227,
1668
+ 86: 0.6699,
1669
+ 87: 0.9453,
1670
+ 88: 0.6699,
1671
+ 89: 0.6699,
1672
+ 90: 0.6133,
1673
+ 91: 0.2793,
1674
+ 92: 0.3125,
1675
+ 93: 0.2793,
1676
+ 94: 0.5859,
1677
+ 95: 0.5576,
1678
+ 96: 0.334,
1679
+ 97: 0.5576,
1680
+ 98: 0.5576,
1681
+ 99: 0.5,
1682
+ 100: 0.5576,
1683
+ 101: 0.5576,
1684
+ 102: 0.2793,
1685
+ 103: 0.5576,
1686
+ 104: 0.5576,
1687
+ 105: 0.2217,
1688
+ 106: 0.2217,
1689
+ 107: 0.5,
1690
+ 108: 0.2217,
1691
+ 109: 0.8359,
1692
+ 110: 0.5576,
1693
+ 111: 0.5576,
1694
+ 112: 0.5576,
1695
+ 113: 0.5576,
1696
+ 114: 0.334,
1697
+ 115: 0.5,
1698
+ 116: 0.334,
1699
+ 117: 0.5576,
1700
+ 118: 0.5,
1701
+ 119: 0.7227,
1702
+ 120: 0.5,
1703
+ 121: 0.5,
1704
+ 122: 0.5,
1705
+ 123: 0.334,
1706
+ 124: 0.2598,
1707
+ 125: 0.334,
1708
+ 126: 0.5859
1709
+ };
1710
+ var DEFAULT_ADVANCE = 0.5576;
1711
+ var LINE_HEIGHT_FACTOR = 1.2;
1712
+ function measureText(text, fontSizePx) {
1713
+ let totalEm = 0;
1714
+ for (let i = 0; i < text.length; i++) {
1715
+ const cp = text.codePointAt(i) ?? 32;
1716
+ totalEm += ADVANCE[cp] ?? DEFAULT_ADVANCE;
1717
+ }
1718
+ return {
1719
+ width: totalEm * fontSizePx,
1720
+ height: fontSizePx * LINE_HEIGHT_FACTOR
1721
+ };
1722
+ }
1723
+
1724
+ // ../src/text/wrap.ts
1725
+ var ELLIPSIS = "\u2026";
1726
+ function wrapText2(text, fontSizePx, maxWidth, maxLines) {
1727
+ if (!text || maxLines <= 0 || maxWidth <= 0) return { lines: [] };
1728
+ const words = text.split(/\s+/).filter(Boolean);
1729
+ if (words.length === 0) return { lines: [] };
1730
+ const lines2 = [];
1731
+ let current = "";
1732
+ for (let wi = 0; wi < words.length; wi++) {
1733
+ const word = words[wi];
1734
+ const candidate = current ? `${current} ${word}` : word;
1735
+ if (measureText(candidate, fontSizePx).width <= maxWidth) {
1736
+ current = candidate;
1737
+ } else {
1738
+ if (current) {
1739
+ if (lines2.length === maxLines - 1) {
1740
+ const remaining = words.slice(wi).join(" ");
1741
+ const full = current ? `${current} ${remaining}` : remaining;
1742
+ lines2.push(truncateText(full, fontSizePx, maxWidth));
1743
+ return { lines: lines2 };
1744
+ }
1745
+ lines2.push(current);
1746
+ current = word;
1747
+ } else {
1748
+ if (lines2.length === maxLines - 1) {
1749
+ lines2.push(truncateText(word, fontSizePx, maxWidth));
1750
+ return { lines: lines2 };
1751
+ }
1752
+ lines2.push(truncateText(word, fontSizePx, maxWidth));
1753
+ current = "";
1754
+ }
1755
+ }
1756
+ }
1757
+ if (current) {
1758
+ if (lines2.length < maxLines) {
1759
+ lines2.push(current);
1760
+ } else {
1761
+ const last = lines2[lines2.length - 1] ?? "";
1762
+ lines2[lines2.length - 1] = truncateText(`${last} ${current}`, fontSizePx, maxWidth);
1763
+ }
1764
+ }
1765
+ return { lines: lines2 };
1766
+ }
1767
+ function truncateText(text, fontSizePx, maxWidth) {
1768
+ if (measureText(text, fontSizePx).width <= maxWidth) return text;
1769
+ const ellipsisWidth = measureText(ELLIPSIS, fontSizePx).width;
1770
+ const budget = maxWidth - ellipsisWidth;
1771
+ if (budget <= 0) return ELLIPSIS;
1772
+ let lo = 0;
1773
+ let hi = text.length;
1774
+ while (lo < hi) {
1775
+ const mid = Math.floor((lo + hi + 1) / 2);
1776
+ if (measureText(text.slice(0, mid), fontSizePx).width <= budget) {
1777
+ lo = mid;
1778
+ } else {
1779
+ hi = mid - 1;
1780
+ }
1781
+ }
1782
+ return text.slice(0, lo) + ELLIPSIS;
1783
+ }
1784
+
1458
1785
  // ../src/diagrams/mermaid/flowchart/layout.ts
1459
1786
  var NODE_W = 120;
1460
1787
  var NODE_H = 40;
1461
1788
  var ARROW_MARKER_ID = "triton-arrow";
1789
+ var CARD_PAD = 8;
1790
+ var CARD_ICON_BOX = 40;
1791
+ var CARD_ICON_GAP = 12;
1792
+ var CARD_MIN_W = 192;
1793
+ var CARD_MAX_W = 400;
1794
+ var CARD_MAX_BODY_LINES = 3;
1795
+ function splitCardLabel(label) {
1796
+ const idx = label.search(/\\n|\n/);
1797
+ if (idx === -1) return { title: label.trim(), body: "" };
1798
+ const sep = label[idx] === "\n" ? 1 : 2;
1799
+ return { title: label.slice(0, idx).trim(), body: label.slice(idx + sep).trim() };
1800
+ }
1801
+ function measureCardNode(node, typography) {
1802
+ const { title, body } = splitCardLabel(node.label);
1803
+ const titleW = measureText(title, typography.baseFontSize).width * 1.1;
1804
+ const titleLH = typography.baseFontSize * 1.2;
1805
+ const maxRightW = CARD_MAX_W - CARD_ICON_BOX - CARD_ICON_GAP - 2 * CARD_PAD;
1806
+ let bodyH = 0;
1807
+ let bodyW = 0;
1808
+ if (body) {
1809
+ const wrapped = wrapText2(body, typography.smallFontSize, maxRightW, CARD_MAX_BODY_LINES);
1810
+ bodyH = wrapped.lines.length * typography.smallFontSize * 1.2;
1811
+ bodyW = wrapped.lines.reduce(
1812
+ (mx, l) => Math.max(mx, measureText(l, typography.smallFontSize).width),
1813
+ 0
1814
+ );
1815
+ }
1816
+ const textW = Math.max(titleW, bodyW);
1817
+ const width = Math.min(CARD_MAX_W, Math.max(
1818
+ CARD_MIN_W,
1819
+ CARD_ICON_BOX + CARD_ICON_GAP + textW + 2 * CARD_PAD
1820
+ ));
1821
+ const textH = body ? titleLH + bodyH : titleLH;
1822
+ const height = Math.max(CARD_ICON_BOX, textH) + 2 * CARD_PAD;
1823
+ return { width, height };
1824
+ }
1462
1825
  function layoutFlowchart(ir, theme, options) {
1463
1826
  const { spacing, palette, typography, edges: edgeTheme } = theme;
1464
1827
  const p = pen(theme);
@@ -1473,6 +1836,13 @@ function layoutFlowchart(ir, theme, options) {
1473
1836
  const rowGap = spacing.nodeGap;
1474
1837
  let maxNodesInLayer = 0;
1475
1838
  for (const [, nodes] of orderedByLayer) maxNodesInLayer = Math.max(maxNodesInLayer, nodes.length);
1839
+ const nodeSizeMap = /* @__PURE__ */ new Map();
1840
+ for (const node of ir.nodes) {
1841
+ nodeSizeMap.set(
1842
+ node.id,
1843
+ node.shape === "card" ? measureCardNode(node, typography) : { width: NODE_W, height: NODE_H }
1844
+ );
1845
+ }
1476
1846
  const nodePos = assignCoordinatesBK(
1477
1847
  orderedByLayer,
1478
1848
  ir.edges,
@@ -1484,7 +1854,8 @@ function layoutFlowchart(ir, theme, options) {
1484
1854
  NODE_H,
1485
1855
  colGap,
1486
1856
  rowGap,
1487
- margin
1857
+ margin,
1858
+ nodeSizeMap
1488
1859
  );
1489
1860
  const elements = [];
1490
1861
  if (ir.metadata.title) {
@@ -1560,14 +1931,67 @@ function layoutFlowchart(ir, theme, options) {
1560
1931
  elements.push(p.text(edge.label, lp.x, lp.y - 4, edgeTheme.labelFontSize, palette.textMuted, { anchor: "middle" }));
1561
1932
  }
1562
1933
  }
1934
+ const icons = options?.icons;
1563
1935
  for (const node of ir.nodes) {
1564
1936
  const r = nodePos.get(node.id);
1565
1937
  if (!r) continue;
1566
1938
  const nodeElements = [];
1567
1939
  const fill = nodeStatusFill(node, palette);
1568
1940
  const stroke = palette.border;
1569
- nodeElements.push(...renderNodeShape(node, r, fill, stroke, edgeTheme.strokeWidth));
1570
- nodeElements.push(p.text(node.label, r.x + NODE_W / 2, r.y + NODE_H / 2 + typography.baseFontSize * 0.35, typography.baseFontSize, palette.text, { anchor: "middle" }));
1941
+ const sw = edgeTheme.strokeWidth;
1942
+ if (node.shape === "card") {
1943
+ nodeElements.push(p.rect(r, fill, stroke, sw, { rx: 6, fillOpacity: 0.85 }));
1944
+ const { title, body } = splitCardLabel(node.label);
1945
+ const iconX = r.x + CARD_PAD;
1946
+ const iconY = r.y + (r.height - CARD_ICON_BOX) / 2;
1947
+ const textX = r.x + CARD_PAD + CARD_ICON_BOX + CARD_ICON_GAP;
1948
+ const rightW = r.width - 2 * CARD_PAD - CARD_ICON_BOX - CARD_ICON_GAP;
1949
+ if (node.icon !== void 0 && icons !== void 0) {
1950
+ const resolved = resolveIcon(node.icon, icons);
1951
+ if (resolved.ok) {
1952
+ const glyphSize = CARD_ICON_BOX - 8;
1953
+ const gx = iconX + (CARD_ICON_BOX - glyphSize) / 2;
1954
+ const gy = iconY + (CARD_ICON_BOX - glyphSize) / 2;
1955
+ nodeElements.push(p.icon(resolved.value, gx, gy, glyphSize, { color: palette.primary }));
1956
+ }
1957
+ }
1958
+ const bodyText = body ? body.replace(/\\n|\n/g, " ").trim() : "";
1959
+ const wrapped = bodyText ? wrapText2(bodyText, typography.smallFontSize, rightW, CARD_MAX_BODY_LINES) : { lines: [] };
1960
+ const hasBody = wrapped.lines.length > 0;
1961
+ const titleBaseY = hasBody ? r.y + CARD_PAD + typography.baseFontSize * 0.85 : r.y + r.height / 2 + typography.baseFontSize * 0.35;
1962
+ nodeElements.push(
1963
+ p.text(title, textX, titleBaseY, typography.baseFontSize, palette.text, { weight: "bold" })
1964
+ );
1965
+ if (hasBody) {
1966
+ const titleLH = typography.baseFontSize * 1.2;
1967
+ let bodyY = r.y + CARD_PAD + titleLH + typography.smallFontSize * 0.85;
1968
+ for (const line of wrapped.lines) {
1969
+ nodeElements.push(
1970
+ p.text(line, textX, bodyY, typography.smallFontSize, palette.textMuted)
1971
+ );
1972
+ bodyY += typography.smallFontSize * 1.2;
1973
+ }
1974
+ }
1975
+ } else {
1976
+ nodeElements.push(...renderNodeShape(node, r, fill, stroke, sw));
1977
+ nodeElements.push(p.text(
1978
+ node.label,
1979
+ r.x + r.width / 2,
1980
+ r.y + r.height / 2 + typography.baseFontSize * 0.35,
1981
+ typography.baseFontSize,
1982
+ palette.text,
1983
+ { anchor: "middle" }
1984
+ ));
1985
+ if (node.icon !== void 0 && icons !== void 0) {
1986
+ const resolved = resolveIcon(node.icon, icons);
1987
+ if (resolved.ok) {
1988
+ const iconSize = NODE_H - 8;
1989
+ const ix = r.x + 4;
1990
+ const iy = r.y + (NODE_H - iconSize) / 2;
1991
+ nodeElements.push(p.icon(resolved.value, ix, iy, iconSize, { color: palette.text }));
1992
+ }
1993
+ }
1994
+ }
1571
1995
  elements.push(p.group(nodeElements, { id: node.id }));
1572
1996
  }
1573
1997
  const allRects = [...nodePos.values()];
@@ -1736,7 +2160,9 @@ function minimizeCrossings(byLayer, edges2, backEdgeSet) {
1736
2160
  }
1737
2161
  return order;
1738
2162
  }
1739
- function assignCoordinatesBK(byLayer, edges2, backEdgeSet, isLR, isReverse, maxNodesInLayer, nodeW, nodeH, colGap, rowGap, margin) {
2163
+ function assignCoordinatesBK(byLayer, edges2, backEdgeSet, isLR, isReverse, maxNodesInLayer, nodeW, nodeH, colGap, rowGap, margin, nodeSizes) {
2164
+ const getW = (id) => nodeSizes?.get(id)?.width ?? nodeW;
2165
+ const getH = (id) => nodeSizes?.get(id)?.height ?? nodeH;
1740
2166
  const predMap = /* @__PURE__ */ new Map();
1741
2167
  const succMap = /* @__PURE__ */ new Map();
1742
2168
  for (const [, nodes] of byLayer) {
@@ -1752,12 +2178,31 @@ function assignCoordinatesBK(byLayer, edges2, backEdgeSet, isLR, isReverse, maxN
1752
2178
  });
1753
2179
  const layerKeys = [...byLayer.keys()].sort((a, b) => a - b);
1754
2180
  const numLayers = layerKeys.length;
1755
- const crossSize = isLR ? nodeH : nodeW;
1756
- const mainSize = isLR ? nodeW : nodeH;
1757
2181
  const crossGap = isLR ? rowGap : colGap;
1758
2182
  const mainGap = isLR ? colGap : rowGap;
1759
- const crossStep = crossSize + crossGap;
1760
- const mainStep = mainSize + mainGap;
2183
+ let globalCrossSize = isLR ? nodeH : nodeW;
2184
+ for (const [, nodes] of byLayer) {
2185
+ for (const n of nodes) {
2186
+ const cs = isLR ? getH(n.id) : getW(n.id);
2187
+ if (cs > globalCrossSize) globalCrossSize = cs;
2188
+ }
2189
+ }
2190
+ const crossStep = globalCrossSize + crossGap;
2191
+ const layerMainSizes = layerKeys.map((lk) => {
2192
+ const nodes = byLayer.get(lk);
2193
+ let mx = isLR ? nodeW : nodeH;
2194
+ for (const n of nodes) {
2195
+ const ms = isLR ? getW(n.id) : getH(n.id);
2196
+ if (ms > mx) mx = ms;
2197
+ }
2198
+ return mx;
2199
+ });
2200
+ const fwdMainPos = [];
2201
+ let cumMain = margin;
2202
+ for (let li = 0; li < numLayers; li++) {
2203
+ fwdMainPos.push(cumMain);
2204
+ cumMain += layerMainSizes[li] + mainGap;
2205
+ }
1761
2206
  function onePass(topDown) {
1762
2207
  const crossPos = /* @__PURE__ */ new Map();
1763
2208
  const neighborMap = topDown ? predMap : succMap;
@@ -1788,18 +2233,22 @@ function assignCoordinatesBK(byLayer, edges2, backEdgeSet, isLR, isReverse, maxN
1788
2233
  const nodePos = /* @__PURE__ */ new Map();
1789
2234
  for (let li = 0; li < numLayers; li++) {
1790
2235
  const layerIdx = layerKeys[li];
1791
- const layerNum = isReverse ? numLayers - 1 - li : li;
1792
2236
  const nodes = byLayer.get(layerIdx);
1793
- const mainPos = margin + layerNum * mainStep;
2237
+ const layerMainSz = layerMainSizes[li];
2238
+ const mainPos = isReverse ? fwdMainPos[numLayers - 1 - li] : fwdMainPos[li];
1794
2239
  for (const node of nodes) {
1795
2240
  const c1 = pass1.get(node.id) ?? margin;
1796
2241
  const c2 = pass2.get(node.id) ?? margin;
1797
- const crossP = (c1 + c2) / 2;
2242
+ const slotLeft = (c1 + c2) / 2;
2243
+ const nw = getW(node.id);
2244
+ const nh = getH(node.id);
2245
+ const crossOffset = (globalCrossSize - (isLR ? nh : nw)) / 2;
2246
+ const mainOffset = (layerMainSz - (isLR ? nw : nh)) / 2;
1798
2247
  nodePos.set(node.id, {
1799
- x: isLR ? mainPos : crossP,
1800
- y: isLR ? crossP : mainPos,
1801
- width: nodeW,
1802
- height: nodeH
2248
+ x: isLR ? mainPos + mainOffset : slotLeft + crossOffset,
2249
+ y: isLR ? slotLeft + crossOffset : mainPos + mainOffset,
2250
+ width: nw,
2251
+ height: nh
1803
2252
  });
1804
2253
  }
1805
2254
  }
@@ -1822,6 +2271,8 @@ function renderNodeShape(node, r, fill, stroke, sw) {
1822
2271
  { type: "rect", bounds: r, fill, stroke, strokeWidth: sw },
1823
2272
  { type: "rect", bounds: { x: x + 6, y, width: w - 12, height: h2 }, fill: "none", stroke, strokeWidth: sw * 0.5 }
1824
2273
  ];
2274
+ case "card":
2275
+ return [{ type: "rect", bounds: r, fill, stroke, strokeWidth: sw, rx: 6 }];
1825
2276
  default:
1826
2277
  return [{ type: "rect", bounds: r, fill, stroke, strokeWidth: sw, rx: 2 }];
1827
2278
  }
@@ -1851,14 +2302,14 @@ function edgeAnchor(r, dir, role, peer) {
1851
2302
  if (isLR) {
1852
2303
  const offAxis = Math.abs(dy);
1853
2304
  const onAxis = Math.abs(dx);
1854
- if (offAxis > onAxis && offAxis > r.height / 2) {
2305
+ if (offAxis > onAxis && offAxis > r.height / 2 && onAxis < r.width) {
1855
2306
  return dy > 0 ? { point: { x: cx, y: r.y + r.height }, portDir: "S" } : { point: { x: cx, y: r.y }, portDir: "N" };
1856
2307
  }
1857
2308
  return role === "exit" ? { point: { x: r.x + r.width, y: cy }, portDir: "E" } : { point: { x: r.x, y: cy }, portDir: "W" };
1858
2309
  } else {
1859
2310
  const offAxis = Math.abs(dx);
1860
2311
  const onAxis = Math.abs(dy);
1861
- if (offAxis > onAxis && offAxis > r.width / 2) {
2312
+ if (offAxis > onAxis && offAxis > r.width / 2 && onAxis < r.height) {
1862
2313
  return dx > 0 ? { point: { x: r.x + r.width, y: cy }, portDir: "E" } : { point: { x: r.x, y: cy }, portDir: "W" };
1863
2314
  }
1864
2315
  return role === "exit" ? { point: { x: cx, y: r.y + r.height }, portDir: "S" } : { point: { x: cx, y: r.y }, portDir: "N" };
@@ -2162,31 +2613,31 @@ function peg$parse(input, options) {
2162
2613
  var peg$c37 = "orthogonal";
2163
2614
  var peg$c38 = "bezier";
2164
2615
  var peg$c39 = "polyline";
2165
- var peg$c40 = "((";
2166
- var peg$c41 = "))";
2167
- var peg$c42 = "([";
2168
- var peg$c43 = "])";
2169
- var peg$c44 = "[[";
2170
- var peg$c45 = "]]";
2171
- var peg$c46 = "[(";
2172
- var peg$c47 = ")]";
2173
- var peg$c48 = "{{";
2174
- var peg$c49 = "}}";
2175
- var peg$c50 = "[/";
2176
- var peg$c51 = "/]";
2177
- var peg$c52 = "[\\";
2178
- var peg$c53 = "\\]";
2179
- var peg$c54 = ">";
2180
- var peg$c55 = "{";
2181
- var peg$c56 = "}";
2182
- var peg$c57 = "(";
2183
- var peg$c58 = ")";
2184
- var peg$c59 = "style";
2185
- var peg$c60 = "classDef";
2186
- var peg$c61 = "class";
2187
- var peg$c62 = "click";
2188
- var peg$c63 = "note";
2189
- var peg$c64 = '"';
2616
+ var peg$c40 = '"';
2617
+ var peg$c41 = "((";
2618
+ var peg$c42 = "))";
2619
+ var peg$c43 = "([";
2620
+ var peg$c44 = "])";
2621
+ var peg$c45 = "[[";
2622
+ var peg$c46 = "]]";
2623
+ var peg$c47 = "[(";
2624
+ var peg$c48 = ")]";
2625
+ var peg$c49 = "{{";
2626
+ var peg$c50 = "}}";
2627
+ var peg$c51 = "[/";
2628
+ var peg$c52 = "/]";
2629
+ var peg$c53 = "[\\";
2630
+ var peg$c54 = "\\]";
2631
+ var peg$c55 = ">";
2632
+ var peg$c56 = "{";
2633
+ var peg$c57 = "}";
2634
+ var peg$c58 = "(";
2635
+ var peg$c59 = ")";
2636
+ var peg$c60 = "style";
2637
+ var peg$c61 = "classDef";
2638
+ var peg$c62 = "class";
2639
+ var peg$c63 = "click";
2640
+ var peg$c64 = "note";
2190
2641
  var peg$c65 = "at";
2191
2642
  var peg$c66 = "offset";
2192
2643
  var peg$c67 = ",";
@@ -2204,16 +2655,19 @@ function peg$parse(input, options) {
2204
2655
  var peg$r4 = /^[^\n%]/;
2205
2656
  var peg$r5 = /^[^|]/;
2206
2657
  var peg$r6 = /^[ENSW]/;
2207
- var peg$r7 = /^[^)]/;
2208
- var peg$r8 = /^[^}]/;
2209
- var peg$r9 = /^[^\/]/;
2210
- var peg$r10 = /^[^\\]/;
2211
- var peg$r11 = /^[^\n;]/;
2212
- var peg$r12 = /^[^"]/;
2213
- var peg$r13 = /^[0-9]/;
2214
- var peg$r14 = /^[^:\n]/;
2215
- var peg$r15 = /^[ \t]/;
2216
- var peg$r16 = /^[\n\r]/;
2658
+ var peg$r7 = /^[a-z]/;
2659
+ var peg$r8 = /^[a-z0-9\-]/;
2660
+ var peg$r9 = /^[^"]/;
2661
+ var peg$r10 = /^[^ \t\r\n@[\](){};]/;
2662
+ var peg$r11 = /^[^)]/;
2663
+ var peg$r12 = /^[^}]/;
2664
+ var peg$r13 = /^[^\/]/;
2665
+ var peg$r14 = /^[^\\]/;
2666
+ var peg$r15 = /^[^\n;]/;
2667
+ var peg$r16 = /^[0-9]/;
2668
+ var peg$r17 = /^[^:\n]/;
2669
+ var peg$r18 = /^[ \t]/;
2670
+ var peg$r19 = /^[\n\r]/;
2217
2671
  var peg$e0 = peg$literalExpectation("---", false);
2218
2672
  var peg$e1 = peg$classExpectation(["\n"], true, false);
2219
2673
  var peg$e2 = peg$literalExpectation("flowchart", false);
@@ -2262,54 +2716,57 @@ function peg$parse(input, options) {
2262
2716
  var peg$e45 = peg$literalExpectation("bezier", false);
2263
2717
  var peg$e46 = peg$literalExpectation("polyline", false);
2264
2718
  var peg$e47 = peg$classExpectation(["E", "N", "S", "W"], false, false);
2265
- var peg$e48 = peg$literalExpectation("((", false);
2266
- var peg$e49 = peg$classExpectation([")"], true, false);
2267
- var peg$e50 = peg$literalExpectation("))", false);
2268
- var peg$e51 = peg$literalExpectation("([", false);
2269
- var peg$e52 = peg$literalExpectation("])", false);
2270
- var peg$e53 = peg$literalExpectation("[[", false);
2271
- var peg$e54 = peg$literalExpectation("]]", false);
2272
- var peg$e55 = peg$literalExpectation("[(", false);
2273
- var peg$e56 = peg$literalExpectation(")]", false);
2274
- var peg$e57 = peg$literalExpectation("{{", false);
2275
- var peg$e58 = peg$classExpectation(["}"], true, false);
2276
- var peg$e59 = peg$literalExpectation("}}", false);
2277
- var peg$e60 = peg$literalExpectation("[/", false);
2278
- var peg$e61 = peg$classExpectation(["/"], true, false);
2279
- var peg$e62 = peg$literalExpectation("/]", false);
2280
- var peg$e63 = peg$literalExpectation("[\\", false);
2281
- var peg$e64 = peg$classExpectation(["\\"], true, false);
2282
- var peg$e65 = peg$literalExpectation("\\]", false);
2283
- var peg$e66 = peg$literalExpectation(">", false);
2284
- var peg$e67 = peg$literalExpectation("{", false);
2285
- var peg$e68 = peg$literalExpectation("}", false);
2286
- var peg$e69 = peg$literalExpectation("(", false);
2287
- var peg$e70 = peg$literalExpectation(")", false);
2288
- var peg$e71 = peg$literalExpectation("style", false);
2289
- var peg$e72 = peg$classExpectation(["\n", ";"], true, false);
2290
- var peg$e73 = peg$literalExpectation("classDef", false);
2291
- var peg$e74 = peg$literalExpectation("class", false);
2292
- var peg$e75 = peg$literalExpectation("click", false);
2293
- var peg$e76 = peg$literalExpectation("note", false);
2294
- var peg$e77 = peg$literalExpectation('"', false);
2295
- var peg$e78 = peg$classExpectation(['"'], true, false);
2296
- var peg$e79 = peg$literalExpectation("at", false);
2297
- var peg$e80 = peg$literalExpectation("offset", false);
2298
- var peg$e81 = peg$literalExpectation(",", false);
2299
- var peg$e82 = peg$literalExpectation("-", false);
2300
- var peg$e83 = peg$classExpectation([["0", "9"]], false, false);
2301
- var peg$e84 = peg$literalExpectation("legend", false);
2302
- var peg$e85 = peg$literalExpectation("bottom-right", false);
2303
- var peg$e86 = peg$literalExpectation("bottom-left", false);
2304
- var peg$e87 = peg$literalExpectation("top-right", false);
2305
- var peg$e88 = peg$literalExpectation("top-left", false);
2306
- var peg$e89 = peg$classExpectation([":", "\n"], true, false);
2307
- var peg$e90 = peg$otherExpectation("optional whitespace");
2308
- var peg$e91 = peg$classExpectation([" ", " "], false, false);
2309
- var peg$e92 = peg$otherExpectation("required whitespace");
2310
- var peg$e93 = peg$otherExpectation("newline");
2311
- var peg$e94 = peg$literalExpectation("\r\n", false);
2312
- var peg$e95 = peg$classExpectation(["\n", "\r"], false, false);
2719
+ var peg$e48 = peg$classExpectation([["a", "z"]], false, false);
2720
+ var peg$e49 = peg$classExpectation([["a", "z"], ["0", "9"], "-"], false, false);
2721
+ var peg$e50 = peg$literalExpectation('"', false);
2722
+ var peg$e51 = peg$classExpectation(['"'], true, false);
2723
+ var peg$e52 = peg$classExpectation([" ", " ", "\r", "\n", "@", "[", "]", "(", ")", "{", "}", ";"], true, false);
2724
+ var peg$e53 = peg$literalExpectation("((", false);
2725
+ var peg$e54 = peg$classExpectation([")"], true, false);
2726
+ var peg$e55 = peg$literalExpectation("))", false);
2727
+ var peg$e56 = peg$literalExpectation("([", false);
2728
+ var peg$e57 = peg$literalExpectation("])", false);
2729
+ var peg$e58 = peg$literalExpectation("[[", false);
2730
+ var peg$e59 = peg$literalExpectation("]]", false);
2731
+ var peg$e60 = peg$literalExpectation("[(", false);
2732
+ var peg$e61 = peg$literalExpectation(")]", false);
2733
+ var peg$e62 = peg$literalExpectation("{{", false);
2734
+ var peg$e63 = peg$classExpectation(["}"], true, false);
2735
+ var peg$e64 = peg$literalExpectation("}}", false);
2736
+ var peg$e65 = peg$literalExpectation("[/", false);
2737
+ var peg$e66 = peg$classExpectation(["/"], true, false);
2738
+ var peg$e67 = peg$literalExpectation("/]", false);
2739
+ var peg$e68 = peg$literalExpectation("[\\", false);
2740
+ var peg$e69 = peg$classExpectation(["\\"], true, false);
2741
+ var peg$e70 = peg$literalExpectation("\\]", false);
2742
+ var peg$e71 = peg$literalExpectation(">", false);
2743
+ var peg$e72 = peg$literalExpectation("{", false);
2744
+ var peg$e73 = peg$literalExpectation("}", false);
2745
+ var peg$e74 = peg$literalExpectation("(", false);
2746
+ var peg$e75 = peg$literalExpectation(")", false);
2747
+ var peg$e76 = peg$literalExpectation("style", false);
2748
+ var peg$e77 = peg$classExpectation(["\n", ";"], true, false);
2749
+ var peg$e78 = peg$literalExpectation("classDef", false);
2750
+ var peg$e79 = peg$literalExpectation("class", false);
2751
+ var peg$e80 = peg$literalExpectation("click", false);
2752
+ var peg$e81 = peg$literalExpectation("note", false);
2753
+ var peg$e82 = peg$literalExpectation("at", false);
2754
+ var peg$e83 = peg$literalExpectation("offset", false);
2755
+ var peg$e84 = peg$literalExpectation(",", false);
2756
+ var peg$e85 = peg$literalExpectation("-", false);
2757
+ var peg$e86 = peg$classExpectation([["0", "9"]], false, false);
2758
+ var peg$e87 = peg$literalExpectation("legend", false);
2759
+ var peg$e88 = peg$literalExpectation("bottom-right", false);
2760
+ var peg$e89 = peg$literalExpectation("bottom-left", false);
2761
+ var peg$e90 = peg$literalExpectation("top-right", false);
2762
+ var peg$e91 = peg$literalExpectation("top-left", false);
2763
+ var peg$e92 = peg$classExpectation([":", "\n"], true, false);
2764
+ var peg$e93 = peg$otherExpectation("optional whitespace");
2765
+ var peg$e94 = peg$classExpectation([" ", " "], false, false);
2766
+ var peg$e95 = peg$otherExpectation("required whitespace");
2767
+ var peg$e96 = peg$otherExpectation("newline");
2768
+ var peg$e97 = peg$literalExpectation("\r\n", false);
2769
+ var peg$e98 = peg$classExpectation(["\n", "\r"], false, false);
2313
2770
  var peg$f0 = function(frontmatter, header, statements) {
2314
2771
  return {
2315
2772
  version: "1.0",
@@ -2458,74 +2915,89 @@ function peg$parse(input, options) {
2458
2915
  var peg$f43 = function(id, shape) {
2459
2916
  return { id: registerNode(id, shape ? shape.label : null, shape ? shape.shape : null) };
2460
2917
  };
2461
- var peg$f44 = function(ref) {
2918
+ var peg$f44 = function(ref, key, value) {
2919
+ return { key, value };
2920
+ };
2921
+ var peg$f45 = function(ref, anns) {
2922
+ if (anns.length > 0) {
2923
+ const node = nodeMap.get(ref.id);
2924
+ if (node) {
2925
+ for (const ann of anns) {
2926
+ if (ann.key === "shape") node.shape = ann.value;
2927
+ if (ann.key === "icon") node.iconToken = ann.value;
2928
+ }
2929
+ }
2930
+ }
2462
2931
  return { type: "node", ...ref };
2463
2932
  };
2464
- var peg$f45 = function(id) {
2933
+ var peg$f46 = function(val) {
2934
+ return val;
2935
+ };
2936
+ var peg$f47 = function(id) {
2465
2937
  return id;
2466
2938
  };
2467
- var peg$f46 = function(text2) {
2939
+ var peg$f48 = function(text2) {
2468
2940
  return { shape: "circle", label: stripQuotes(text2.trim()) };
2469
2941
  };
2470
- var peg$f47 = function(text2) {
2942
+ var peg$f49 = function(text2) {
2471
2943
  return { shape: "stadium", label: stripQuotes(text2.trim()) };
2472
2944
  };
2473
- var peg$f48 = function(text2) {
2945
+ var peg$f50 = function(text2) {
2474
2946
  return { shape: "subroutine", label: stripQuotes(text2.trim()) };
2475
2947
  };
2476
- var peg$f49 = function(text2) {
2948
+ var peg$f51 = function(text2) {
2477
2949
  return { shape: "cylinder", label: stripQuotes(text2.trim()) };
2478
2950
  };
2479
- var peg$f50 = function(text2) {
2951
+ var peg$f52 = function(text2) {
2480
2952
  return { shape: "hexagon", label: stripQuotes(text2.trim()) };
2481
2953
  };
2482
- var peg$f51 = function(text2) {
2954
+ var peg$f53 = function(text2) {
2483
2955
  return { shape: "parallelogram", label: stripQuotes(text2.trim()) };
2484
2956
  };
2485
- var peg$f52 = function(text2) {
2957
+ var peg$f54 = function(text2) {
2486
2958
  return { shape: "parallelogram-alt", label: stripQuotes(text2.trim()) };
2487
2959
  };
2488
- var peg$f53 = function(text2) {
2960
+ var peg$f55 = function(text2) {
2489
2961
  return { shape: "asymmetric", label: stripQuotes(text2.trim()) };
2490
2962
  };
2491
- var peg$f54 = function(text2) {
2963
+ var peg$f56 = function(text2) {
2492
2964
  return { shape: "rect", label: stripQuotes(text2.trim()) };
2493
2965
  };
2494
- var peg$f55 = function(text2) {
2966
+ var peg$f57 = function(text2) {
2495
2967
  return { shape: "diamond", label: stripQuotes(text2.trim()) };
2496
2968
  };
2497
- var peg$f56 = function(text2) {
2969
+ var peg$f58 = function(text2) {
2498
2970
  return { shape: "rounded-rect", label: stripQuotes(text2.trim()) };
2499
2971
  };
2500
- var peg$f57 = function(content) {
2972
+ var peg$f59 = function(content) {
2501
2973
  return { type: "style", raw: content };
2502
2974
  };
2503
- var peg$f58 = function(content) {
2975
+ var peg$f60 = function(content) {
2504
2976
  return { type: "class", raw: content };
2505
2977
  };
2506
- var peg$f59 = function(content) {
2978
+ var peg$f61 = function(content) {
2507
2979
  return { type: "click", raw: content };
2508
2980
  };
2509
- var peg$f60 = function(text2, target, offset2) {
2981
+ var peg$f62 = function(text2, target, offset2) {
2510
2982
  const note = { type: "note", text: text2, target, offset: offset2 || void 0 };
2511
2983
  overlays.push(note);
2512
2984
  return note;
2513
2985
  };
2514
- var peg$f61 = function(dx, dy) {
2986
+ var peg$f63 = function(dx, dy) {
2515
2987
  return { dx, dy };
2516
2988
  };
2517
- var peg$f62 = function(sign, digits) {
2989
+ var peg$f64 = function(sign, digits) {
2518
2990
  return parseInt((sign || "") + digits, 10);
2519
2991
  };
2520
- var peg$f63 = function(corner, t) {
2992
+ var peg$f65 = function(corner, t) {
2521
2993
  return t;
2522
2994
  };
2523
- var peg$f64 = function(corner, title, entries) {
2995
+ var peg$f66 = function(corner, title, entries) {
2524
2996
  const legend = { type: "legend", corner, title: title || void 0, entries };
2525
2997
  overlays.push(legend);
2526
2998
  return legend;
2527
2999
  };
2528
- var peg$f65 = function(key, value) {
3000
+ var peg$f67 = function(key, value) {
2529
3001
  return { key: key.trim(), value: value.trim() };
2530
3002
  };
2531
3003
  var peg$currPos = options.peg$currPos | 0;
@@ -4074,16 +4546,17 @@ function peg$parse(input, options) {
4074
4546
  return s0;
4075
4547
  }
4076
4548
  function peg$parseNodeRef() {
4077
- var s0, s1, s2;
4549
+ var s0, s1, s2, s3;
4078
4550
  s0 = peg$currPos;
4079
4551
  s1 = peg$parseNodeId();
4080
4552
  if (s1 !== peg$FAILED) {
4081
- s2 = peg$parseShape();
4082
- if (s2 === peg$FAILED) {
4083
- s2 = null;
4553
+ s2 = peg$parse_();
4554
+ s3 = peg$parseShape();
4555
+ if (s3 === peg$FAILED) {
4556
+ s3 = null;
4084
4557
  }
4085
4558
  peg$savedPos = s0;
4086
- s0 = peg$f43(s1, s2);
4559
+ s0 = peg$f43(s1, s3);
4087
4560
  } else {
4088
4561
  peg$currPos = s0;
4089
4562
  s0 = peg$FAILED;
@@ -4091,32 +4564,271 @@ function peg$parse(input, options) {
4091
4564
  return s0;
4092
4565
  }
4093
4566
  function peg$parseNodeDecl() {
4094
- var s0, s1, s2, s3, s4, s5;
4567
+ var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10;
4095
4568
  s0 = peg$currPos;
4096
4569
  s1 = peg$parseNodeRef();
4097
4570
  if (s1 !== peg$FAILED) {
4098
- s2 = peg$currPos;
4099
- peg$silentFails++;
4571
+ s2 = [];
4100
4572
  s3 = peg$currPos;
4101
4573
  s4 = peg$parse_();
4102
- s5 = peg$parseEdgeArrow();
4574
+ if (input.charCodeAt(peg$currPos) === 64) {
4575
+ s5 = peg$c14;
4576
+ peg$currPos++;
4577
+ } else {
4578
+ s5 = peg$FAILED;
4579
+ if (peg$silentFails === 0) {
4580
+ peg$fail(peg$e20);
4581
+ }
4582
+ }
4103
4583
  if (s5 !== peg$FAILED) {
4104
- s4 = [s4, s5];
4105
- s3 = s4;
4584
+ s6 = peg$currPos;
4585
+ s7 = peg$currPos;
4586
+ s8 = input.charAt(peg$currPos);
4587
+ if (peg$r7.test(s8)) {
4588
+ peg$currPos++;
4589
+ } else {
4590
+ s8 = peg$FAILED;
4591
+ if (peg$silentFails === 0) {
4592
+ peg$fail(peg$e48);
4593
+ }
4594
+ }
4595
+ if (s8 !== peg$FAILED) {
4596
+ s9 = [];
4597
+ s10 = input.charAt(peg$currPos);
4598
+ if (peg$r8.test(s10)) {
4599
+ peg$currPos++;
4600
+ } else {
4601
+ s10 = peg$FAILED;
4602
+ if (peg$silentFails === 0) {
4603
+ peg$fail(peg$e49);
4604
+ }
4605
+ }
4606
+ while (s10 !== peg$FAILED) {
4607
+ s9.push(s10);
4608
+ s10 = input.charAt(peg$currPos);
4609
+ if (peg$r8.test(s10)) {
4610
+ peg$currPos++;
4611
+ } else {
4612
+ s10 = peg$FAILED;
4613
+ if (peg$silentFails === 0) {
4614
+ peg$fail(peg$e49);
4615
+ }
4616
+ }
4617
+ }
4618
+ s8 = [s8, s9];
4619
+ s7 = s8;
4620
+ } else {
4621
+ peg$currPos = s7;
4622
+ s7 = peg$FAILED;
4623
+ }
4624
+ if (s7 !== peg$FAILED) {
4625
+ s6 = input.substring(s6, peg$currPos);
4626
+ } else {
4627
+ s6 = s7;
4628
+ }
4629
+ if (s6 !== peg$FAILED) {
4630
+ if (input.charCodeAt(peg$currPos) === 58) {
4631
+ s7 = peg$c35;
4632
+ peg$currPos++;
4633
+ } else {
4634
+ s7 = peg$FAILED;
4635
+ if (peg$silentFails === 0) {
4636
+ peg$fail(peg$e42);
4637
+ }
4638
+ }
4639
+ if (s7 !== peg$FAILED) {
4640
+ s8 = peg$parseAnnotationValue();
4641
+ if (s8 !== peg$FAILED) {
4642
+ peg$savedPos = s3;
4643
+ s3 = peg$f44(s1, s6, s8);
4644
+ } else {
4645
+ peg$currPos = s3;
4646
+ s3 = peg$FAILED;
4647
+ }
4648
+ } else {
4649
+ peg$currPos = s3;
4650
+ s3 = peg$FAILED;
4651
+ }
4652
+ } else {
4653
+ peg$currPos = s3;
4654
+ s3 = peg$FAILED;
4655
+ }
4106
4656
  } else {
4107
4657
  peg$currPos = s3;
4108
4658
  s3 = peg$FAILED;
4109
4659
  }
4660
+ while (s3 !== peg$FAILED) {
4661
+ s2.push(s3);
4662
+ s3 = peg$currPos;
4663
+ s4 = peg$parse_();
4664
+ if (input.charCodeAt(peg$currPos) === 64) {
4665
+ s5 = peg$c14;
4666
+ peg$currPos++;
4667
+ } else {
4668
+ s5 = peg$FAILED;
4669
+ if (peg$silentFails === 0) {
4670
+ peg$fail(peg$e20);
4671
+ }
4672
+ }
4673
+ if (s5 !== peg$FAILED) {
4674
+ s6 = peg$currPos;
4675
+ s7 = peg$currPos;
4676
+ s8 = input.charAt(peg$currPos);
4677
+ if (peg$r7.test(s8)) {
4678
+ peg$currPos++;
4679
+ } else {
4680
+ s8 = peg$FAILED;
4681
+ if (peg$silentFails === 0) {
4682
+ peg$fail(peg$e48);
4683
+ }
4684
+ }
4685
+ if (s8 !== peg$FAILED) {
4686
+ s9 = [];
4687
+ s10 = input.charAt(peg$currPos);
4688
+ if (peg$r8.test(s10)) {
4689
+ peg$currPos++;
4690
+ } else {
4691
+ s10 = peg$FAILED;
4692
+ if (peg$silentFails === 0) {
4693
+ peg$fail(peg$e49);
4694
+ }
4695
+ }
4696
+ while (s10 !== peg$FAILED) {
4697
+ s9.push(s10);
4698
+ s10 = input.charAt(peg$currPos);
4699
+ if (peg$r8.test(s10)) {
4700
+ peg$currPos++;
4701
+ } else {
4702
+ s10 = peg$FAILED;
4703
+ if (peg$silentFails === 0) {
4704
+ peg$fail(peg$e49);
4705
+ }
4706
+ }
4707
+ }
4708
+ s8 = [s8, s9];
4709
+ s7 = s8;
4710
+ } else {
4711
+ peg$currPos = s7;
4712
+ s7 = peg$FAILED;
4713
+ }
4714
+ if (s7 !== peg$FAILED) {
4715
+ s6 = input.substring(s6, peg$currPos);
4716
+ } else {
4717
+ s6 = s7;
4718
+ }
4719
+ if (s6 !== peg$FAILED) {
4720
+ if (input.charCodeAt(peg$currPos) === 58) {
4721
+ s7 = peg$c35;
4722
+ peg$currPos++;
4723
+ } else {
4724
+ s7 = peg$FAILED;
4725
+ if (peg$silentFails === 0) {
4726
+ peg$fail(peg$e42);
4727
+ }
4728
+ }
4729
+ if (s7 !== peg$FAILED) {
4730
+ s8 = peg$parseAnnotationValue();
4731
+ if (s8 !== peg$FAILED) {
4732
+ peg$savedPos = s3;
4733
+ s3 = peg$f44(s1, s6, s8);
4734
+ } else {
4735
+ peg$currPos = s3;
4736
+ s3 = peg$FAILED;
4737
+ }
4738
+ } else {
4739
+ peg$currPos = s3;
4740
+ s3 = peg$FAILED;
4741
+ }
4742
+ } else {
4743
+ peg$currPos = s3;
4744
+ s3 = peg$FAILED;
4745
+ }
4746
+ } else {
4747
+ peg$currPos = s3;
4748
+ s3 = peg$FAILED;
4749
+ }
4750
+ }
4751
+ s3 = peg$currPos;
4752
+ peg$silentFails++;
4753
+ s4 = peg$currPos;
4754
+ s5 = peg$parse_();
4755
+ s6 = peg$parseEdgeArrow();
4756
+ if (s6 !== peg$FAILED) {
4757
+ s5 = [s5, s6];
4758
+ s4 = s5;
4759
+ } else {
4760
+ peg$currPos = s4;
4761
+ s4 = peg$FAILED;
4762
+ }
4110
4763
  peg$silentFails--;
4111
- if (s3 === peg$FAILED) {
4112
- s2 = void 0;
4764
+ if (s4 === peg$FAILED) {
4765
+ s3 = void 0;
4113
4766
  } else {
4114
- peg$currPos = s2;
4115
- s2 = peg$FAILED;
4767
+ peg$currPos = s3;
4768
+ s3 = peg$FAILED;
4116
4769
  }
4117
- if (s2 !== peg$FAILED) {
4770
+ if (s3 !== peg$FAILED) {
4771
+ peg$savedPos = s0;
4772
+ s0 = peg$f45(s1, s2);
4773
+ } else {
4774
+ peg$currPos = s0;
4775
+ s0 = peg$FAILED;
4776
+ }
4777
+ } else {
4778
+ peg$currPos = s0;
4779
+ s0 = peg$FAILED;
4780
+ }
4781
+ return s0;
4782
+ }
4783
+ function peg$parseAnnotationValue() {
4784
+ var s0, s1, s2, s3, s4;
4785
+ s0 = peg$currPos;
4786
+ if (input.charCodeAt(peg$currPos) === 34) {
4787
+ s1 = peg$c40;
4788
+ peg$currPos++;
4789
+ } else {
4790
+ s1 = peg$FAILED;
4791
+ if (peg$silentFails === 0) {
4792
+ peg$fail(peg$e50);
4793
+ }
4794
+ }
4795
+ if (s1 !== peg$FAILED) {
4796
+ s2 = peg$currPos;
4797
+ s3 = [];
4798
+ s4 = input.charAt(peg$currPos);
4799
+ if (peg$r9.test(s4)) {
4800
+ peg$currPos++;
4801
+ } else {
4802
+ s4 = peg$FAILED;
4803
+ if (peg$silentFails === 0) {
4804
+ peg$fail(peg$e51);
4805
+ }
4806
+ }
4807
+ while (s4 !== peg$FAILED) {
4808
+ s3.push(s4);
4809
+ s4 = input.charAt(peg$currPos);
4810
+ if (peg$r9.test(s4)) {
4811
+ peg$currPos++;
4812
+ } else {
4813
+ s4 = peg$FAILED;
4814
+ if (peg$silentFails === 0) {
4815
+ peg$fail(peg$e51);
4816
+ }
4817
+ }
4818
+ }
4819
+ s2 = input.substring(s2, peg$currPos);
4820
+ if (input.charCodeAt(peg$currPos) === 34) {
4821
+ s3 = peg$c40;
4822
+ peg$currPos++;
4823
+ } else {
4824
+ s3 = peg$FAILED;
4825
+ if (peg$silentFails === 0) {
4826
+ peg$fail(peg$e50);
4827
+ }
4828
+ }
4829
+ if (s3 !== peg$FAILED) {
4118
4830
  peg$savedPos = s0;
4119
- s0 = peg$f44(s1);
4831
+ s0 = peg$f46(s2);
4120
4832
  } else {
4121
4833
  peg$currPos = s0;
4122
4834
  s0 = peg$FAILED;
@@ -4125,6 +4837,40 @@ function peg$parse(input, options) {
4125
4837
  peg$currPos = s0;
4126
4838
  s0 = peg$FAILED;
4127
4839
  }
4840
+ if (s0 === peg$FAILED) {
4841
+ s0 = peg$currPos;
4842
+ s1 = [];
4843
+ s2 = input.charAt(peg$currPos);
4844
+ if (peg$r10.test(s2)) {
4845
+ peg$currPos++;
4846
+ } else {
4847
+ s2 = peg$FAILED;
4848
+ if (peg$silentFails === 0) {
4849
+ peg$fail(peg$e52);
4850
+ }
4851
+ }
4852
+ if (s2 !== peg$FAILED) {
4853
+ while (s2 !== peg$FAILED) {
4854
+ s1.push(s2);
4855
+ s2 = input.charAt(peg$currPos);
4856
+ if (peg$r10.test(s2)) {
4857
+ peg$currPos++;
4858
+ } else {
4859
+ s2 = peg$FAILED;
4860
+ if (peg$silentFails === 0) {
4861
+ peg$fail(peg$e52);
4862
+ }
4863
+ }
4864
+ }
4865
+ } else {
4866
+ s1 = peg$FAILED;
4867
+ }
4868
+ if (s1 !== peg$FAILED) {
4869
+ s0 = input.substring(s0, peg$currPos);
4870
+ } else {
4871
+ s0 = s1;
4872
+ }
4873
+ }
4128
4874
  return s0;
4129
4875
  }
4130
4876
  function peg$parseNodeId() {
@@ -4277,7 +5023,7 @@ function peg$parse(input, options) {
4277
5023
  }
4278
5024
  if (s3 !== peg$FAILED) {
4279
5025
  peg$savedPos = s0;
4280
- s0 = peg$f45(s3);
5026
+ s0 = peg$f47(s3);
4281
5027
  } else {
4282
5028
  peg$currPos = s0;
4283
5029
  s0 = peg$FAILED;
@@ -4295,37 +5041,37 @@ function peg$parse(input, options) {
4295
5041
  function peg$parseShape() {
4296
5042
  var s0, s1, s2, s3, s4;
4297
5043
  s0 = peg$currPos;
4298
- if (input.substr(peg$currPos, 2) === peg$c40) {
4299
- s1 = peg$c40;
5044
+ if (input.substr(peg$currPos, 2) === peg$c41) {
5045
+ s1 = peg$c41;
4300
5046
  peg$currPos += 2;
4301
5047
  } else {
4302
5048
  s1 = peg$FAILED;
4303
5049
  if (peg$silentFails === 0) {
4304
- peg$fail(peg$e48);
5050
+ peg$fail(peg$e53);
4305
5051
  }
4306
5052
  }
4307
5053
  if (s1 !== peg$FAILED) {
4308
5054
  s2 = peg$currPos;
4309
5055
  s3 = [];
4310
5056
  s4 = input.charAt(peg$currPos);
4311
- if (peg$r7.test(s4)) {
5057
+ if (peg$r11.test(s4)) {
4312
5058
  peg$currPos++;
4313
5059
  } else {
4314
5060
  s4 = peg$FAILED;
4315
5061
  if (peg$silentFails === 0) {
4316
- peg$fail(peg$e49);
5062
+ peg$fail(peg$e54);
4317
5063
  }
4318
5064
  }
4319
5065
  if (s4 !== peg$FAILED) {
4320
5066
  while (s4 !== peg$FAILED) {
4321
5067
  s3.push(s4);
4322
5068
  s4 = input.charAt(peg$currPos);
4323
- if (peg$r7.test(s4)) {
5069
+ if (peg$r11.test(s4)) {
4324
5070
  peg$currPos++;
4325
5071
  } else {
4326
5072
  s4 = peg$FAILED;
4327
5073
  if (peg$silentFails === 0) {
4328
- peg$fail(peg$e49);
5074
+ peg$fail(peg$e54);
4329
5075
  }
4330
5076
  }
4331
5077
  }
@@ -4338,18 +5084,18 @@ function peg$parse(input, options) {
4338
5084
  s2 = s3;
4339
5085
  }
4340
5086
  if (s2 !== peg$FAILED) {
4341
- if (input.substr(peg$currPos, 2) === peg$c41) {
4342
- s3 = peg$c41;
5087
+ if (input.substr(peg$currPos, 2) === peg$c42) {
5088
+ s3 = peg$c42;
4343
5089
  peg$currPos += 2;
4344
5090
  } else {
4345
5091
  s3 = peg$FAILED;
4346
5092
  if (peg$silentFails === 0) {
4347
- peg$fail(peg$e50);
5093
+ peg$fail(peg$e55);
4348
5094
  }
4349
5095
  }
4350
5096
  if (s3 !== peg$FAILED) {
4351
5097
  peg$savedPos = s0;
4352
- s0 = peg$f46(s2);
5098
+ s0 = peg$f48(s2);
4353
5099
  } else {
4354
5100
  peg$currPos = s0;
4355
5101
  s0 = peg$FAILED;
@@ -4364,13 +5110,13 @@ function peg$parse(input, options) {
4364
5110
  }
4365
5111
  if (s0 === peg$FAILED) {
4366
5112
  s0 = peg$currPos;
4367
- if (input.substr(peg$currPos, 2) === peg$c42) {
4368
- s1 = peg$c42;
5113
+ if (input.substr(peg$currPos, 2) === peg$c43) {
5114
+ s1 = peg$c43;
4369
5115
  peg$currPos += 2;
4370
5116
  } else {
4371
5117
  s1 = peg$FAILED;
4372
5118
  if (peg$silentFails === 0) {
4373
- peg$fail(peg$e51);
5119
+ peg$fail(peg$e56);
4374
5120
  }
4375
5121
  }
4376
5122
  if (s1 !== peg$FAILED) {
@@ -4398,18 +5144,18 @@ function peg$parse(input, options) {
4398
5144
  }
4399
5145
  }
4400
5146
  s2 = input.substring(s2, peg$currPos);
4401
- if (input.substr(peg$currPos, 2) === peg$c43) {
4402
- s3 = peg$c43;
5147
+ if (input.substr(peg$currPos, 2) === peg$c44) {
5148
+ s3 = peg$c44;
4403
5149
  peg$currPos += 2;
4404
5150
  } else {
4405
5151
  s3 = peg$FAILED;
4406
5152
  if (peg$silentFails === 0) {
4407
- peg$fail(peg$e52);
5153
+ peg$fail(peg$e57);
4408
5154
  }
4409
5155
  }
4410
5156
  if (s3 !== peg$FAILED) {
4411
5157
  peg$savedPos = s0;
4412
- s0 = peg$f47(s2);
5158
+ s0 = peg$f49(s2);
4413
5159
  } else {
4414
5160
  peg$currPos = s0;
4415
5161
  s0 = peg$FAILED;
@@ -4420,13 +5166,13 @@ function peg$parse(input, options) {
4420
5166
  }
4421
5167
  if (s0 === peg$FAILED) {
4422
5168
  s0 = peg$currPos;
4423
- if (input.substr(peg$currPos, 2) === peg$c44) {
4424
- s1 = peg$c44;
5169
+ if (input.substr(peg$currPos, 2) === peg$c45) {
5170
+ s1 = peg$c45;
4425
5171
  peg$currPos += 2;
4426
5172
  } else {
4427
5173
  s1 = peg$FAILED;
4428
5174
  if (peg$silentFails === 0) {
4429
- peg$fail(peg$e53);
5175
+ peg$fail(peg$e58);
4430
5176
  }
4431
5177
  }
4432
5178
  if (s1 !== peg$FAILED) {
@@ -4454,18 +5200,18 @@ function peg$parse(input, options) {
4454
5200
  }
4455
5201
  }
4456
5202
  s2 = input.substring(s2, peg$currPos);
4457
- if (input.substr(peg$currPos, 2) === peg$c45) {
4458
- s3 = peg$c45;
5203
+ if (input.substr(peg$currPos, 2) === peg$c46) {
5204
+ s3 = peg$c46;
4459
5205
  peg$currPos += 2;
4460
5206
  } else {
4461
5207
  s3 = peg$FAILED;
4462
5208
  if (peg$silentFails === 0) {
4463
- peg$fail(peg$e54);
5209
+ peg$fail(peg$e59);
4464
5210
  }
4465
5211
  }
4466
5212
  if (s3 !== peg$FAILED) {
4467
5213
  peg$savedPos = s0;
4468
- s0 = peg$f48(s2);
5214
+ s0 = peg$f50(s2);
4469
5215
  } else {
4470
5216
  peg$currPos = s0;
4471
5217
  s0 = peg$FAILED;
@@ -4476,52 +5222,52 @@ function peg$parse(input, options) {
4476
5222
  }
4477
5223
  if (s0 === peg$FAILED) {
4478
5224
  s0 = peg$currPos;
4479
- if (input.substr(peg$currPos, 2) === peg$c46) {
4480
- s1 = peg$c46;
5225
+ if (input.substr(peg$currPos, 2) === peg$c47) {
5226
+ s1 = peg$c47;
4481
5227
  peg$currPos += 2;
4482
5228
  } else {
4483
5229
  s1 = peg$FAILED;
4484
5230
  if (peg$silentFails === 0) {
4485
- peg$fail(peg$e55);
5231
+ peg$fail(peg$e60);
4486
5232
  }
4487
5233
  }
4488
5234
  if (s1 !== peg$FAILED) {
4489
5235
  s2 = peg$currPos;
4490
5236
  s3 = [];
4491
5237
  s4 = input.charAt(peg$currPos);
4492
- if (peg$r7.test(s4)) {
5238
+ if (peg$r11.test(s4)) {
4493
5239
  peg$currPos++;
4494
5240
  } else {
4495
5241
  s4 = peg$FAILED;
4496
5242
  if (peg$silentFails === 0) {
4497
- peg$fail(peg$e49);
5243
+ peg$fail(peg$e54);
4498
5244
  }
4499
5245
  }
4500
5246
  while (s4 !== peg$FAILED) {
4501
5247
  s3.push(s4);
4502
5248
  s4 = input.charAt(peg$currPos);
4503
- if (peg$r7.test(s4)) {
5249
+ if (peg$r11.test(s4)) {
4504
5250
  peg$currPos++;
4505
5251
  } else {
4506
5252
  s4 = peg$FAILED;
4507
5253
  if (peg$silentFails === 0) {
4508
- peg$fail(peg$e49);
5254
+ peg$fail(peg$e54);
4509
5255
  }
4510
5256
  }
4511
5257
  }
4512
5258
  s2 = input.substring(s2, peg$currPos);
4513
- if (input.substr(peg$currPos, 2) === peg$c47) {
4514
- s3 = peg$c47;
5259
+ if (input.substr(peg$currPos, 2) === peg$c48) {
5260
+ s3 = peg$c48;
4515
5261
  peg$currPos += 2;
4516
5262
  } else {
4517
5263
  s3 = peg$FAILED;
4518
5264
  if (peg$silentFails === 0) {
4519
- peg$fail(peg$e56);
5265
+ peg$fail(peg$e61);
4520
5266
  }
4521
5267
  }
4522
5268
  if (s3 !== peg$FAILED) {
4523
5269
  peg$savedPos = s0;
4524
- s0 = peg$f49(s2);
5270
+ s0 = peg$f51(s2);
4525
5271
  } else {
4526
5272
  peg$currPos = s0;
4527
5273
  s0 = peg$FAILED;
@@ -4532,52 +5278,52 @@ function peg$parse(input, options) {
4532
5278
  }
4533
5279
  if (s0 === peg$FAILED) {
4534
5280
  s0 = peg$currPos;
4535
- if (input.substr(peg$currPos, 2) === peg$c48) {
4536
- s1 = peg$c48;
5281
+ if (input.substr(peg$currPos, 2) === peg$c49) {
5282
+ s1 = peg$c49;
4537
5283
  peg$currPos += 2;
4538
5284
  } else {
4539
5285
  s1 = peg$FAILED;
4540
5286
  if (peg$silentFails === 0) {
4541
- peg$fail(peg$e57);
5287
+ peg$fail(peg$e62);
4542
5288
  }
4543
5289
  }
4544
5290
  if (s1 !== peg$FAILED) {
4545
5291
  s2 = peg$currPos;
4546
5292
  s3 = [];
4547
5293
  s4 = input.charAt(peg$currPos);
4548
- if (peg$r8.test(s4)) {
5294
+ if (peg$r12.test(s4)) {
4549
5295
  peg$currPos++;
4550
5296
  } else {
4551
5297
  s4 = peg$FAILED;
4552
5298
  if (peg$silentFails === 0) {
4553
- peg$fail(peg$e58);
5299
+ peg$fail(peg$e63);
4554
5300
  }
4555
5301
  }
4556
5302
  while (s4 !== peg$FAILED) {
4557
5303
  s3.push(s4);
4558
5304
  s4 = input.charAt(peg$currPos);
4559
- if (peg$r8.test(s4)) {
5305
+ if (peg$r12.test(s4)) {
4560
5306
  peg$currPos++;
4561
5307
  } else {
4562
5308
  s4 = peg$FAILED;
4563
5309
  if (peg$silentFails === 0) {
4564
- peg$fail(peg$e58);
5310
+ peg$fail(peg$e63);
4565
5311
  }
4566
5312
  }
4567
5313
  }
4568
5314
  s2 = input.substring(s2, peg$currPos);
4569
- if (input.substr(peg$currPos, 2) === peg$c49) {
4570
- s3 = peg$c49;
5315
+ if (input.substr(peg$currPos, 2) === peg$c50) {
5316
+ s3 = peg$c50;
4571
5317
  peg$currPos += 2;
4572
5318
  } else {
4573
5319
  s3 = peg$FAILED;
4574
5320
  if (peg$silentFails === 0) {
4575
- peg$fail(peg$e59);
5321
+ peg$fail(peg$e64);
4576
5322
  }
4577
5323
  }
4578
5324
  if (s3 !== peg$FAILED) {
4579
5325
  peg$savedPos = s0;
4580
- s0 = peg$f50(s2);
5326
+ s0 = peg$f52(s2);
4581
5327
  } else {
4582
5328
  peg$currPos = s0;
4583
5329
  s0 = peg$FAILED;
@@ -4588,52 +5334,52 @@ function peg$parse(input, options) {
4588
5334
  }
4589
5335
  if (s0 === peg$FAILED) {
4590
5336
  s0 = peg$currPos;
4591
- if (input.substr(peg$currPos, 2) === peg$c50) {
4592
- s1 = peg$c50;
5337
+ if (input.substr(peg$currPos, 2) === peg$c51) {
5338
+ s1 = peg$c51;
4593
5339
  peg$currPos += 2;
4594
5340
  } else {
4595
5341
  s1 = peg$FAILED;
4596
5342
  if (peg$silentFails === 0) {
4597
- peg$fail(peg$e60);
5343
+ peg$fail(peg$e65);
4598
5344
  }
4599
5345
  }
4600
5346
  if (s1 !== peg$FAILED) {
4601
5347
  s2 = peg$currPos;
4602
5348
  s3 = [];
4603
5349
  s4 = input.charAt(peg$currPos);
4604
- if (peg$r9.test(s4)) {
5350
+ if (peg$r13.test(s4)) {
4605
5351
  peg$currPos++;
4606
5352
  } else {
4607
5353
  s4 = peg$FAILED;
4608
5354
  if (peg$silentFails === 0) {
4609
- peg$fail(peg$e61);
5355
+ peg$fail(peg$e66);
4610
5356
  }
4611
5357
  }
4612
5358
  while (s4 !== peg$FAILED) {
4613
5359
  s3.push(s4);
4614
5360
  s4 = input.charAt(peg$currPos);
4615
- if (peg$r9.test(s4)) {
5361
+ if (peg$r13.test(s4)) {
4616
5362
  peg$currPos++;
4617
5363
  } else {
4618
5364
  s4 = peg$FAILED;
4619
5365
  if (peg$silentFails === 0) {
4620
- peg$fail(peg$e61);
5366
+ peg$fail(peg$e66);
4621
5367
  }
4622
5368
  }
4623
5369
  }
4624
5370
  s2 = input.substring(s2, peg$currPos);
4625
- if (input.substr(peg$currPos, 2) === peg$c51) {
4626
- s3 = peg$c51;
5371
+ if (input.substr(peg$currPos, 2) === peg$c52) {
5372
+ s3 = peg$c52;
4627
5373
  peg$currPos += 2;
4628
5374
  } else {
4629
5375
  s3 = peg$FAILED;
4630
5376
  if (peg$silentFails === 0) {
4631
- peg$fail(peg$e62);
5377
+ peg$fail(peg$e67);
4632
5378
  }
4633
5379
  }
4634
5380
  if (s3 !== peg$FAILED) {
4635
5381
  peg$savedPos = s0;
4636
- s0 = peg$f51(s2);
5382
+ s0 = peg$f53(s2);
4637
5383
  } else {
4638
5384
  peg$currPos = s0;
4639
5385
  s0 = peg$FAILED;
@@ -4644,52 +5390,52 @@ function peg$parse(input, options) {
4644
5390
  }
4645
5391
  if (s0 === peg$FAILED) {
4646
5392
  s0 = peg$currPos;
4647
- if (input.substr(peg$currPos, 2) === peg$c52) {
4648
- s1 = peg$c52;
5393
+ if (input.substr(peg$currPos, 2) === peg$c53) {
5394
+ s1 = peg$c53;
4649
5395
  peg$currPos += 2;
4650
5396
  } else {
4651
5397
  s1 = peg$FAILED;
4652
5398
  if (peg$silentFails === 0) {
4653
- peg$fail(peg$e63);
5399
+ peg$fail(peg$e68);
4654
5400
  }
4655
5401
  }
4656
5402
  if (s1 !== peg$FAILED) {
4657
5403
  s2 = peg$currPos;
4658
5404
  s3 = [];
4659
5405
  s4 = input.charAt(peg$currPos);
4660
- if (peg$r10.test(s4)) {
5406
+ if (peg$r14.test(s4)) {
4661
5407
  peg$currPos++;
4662
5408
  } else {
4663
5409
  s4 = peg$FAILED;
4664
5410
  if (peg$silentFails === 0) {
4665
- peg$fail(peg$e64);
5411
+ peg$fail(peg$e69);
4666
5412
  }
4667
5413
  }
4668
5414
  while (s4 !== peg$FAILED) {
4669
5415
  s3.push(s4);
4670
5416
  s4 = input.charAt(peg$currPos);
4671
- if (peg$r10.test(s4)) {
5417
+ if (peg$r14.test(s4)) {
4672
5418
  peg$currPos++;
4673
5419
  } else {
4674
5420
  s4 = peg$FAILED;
4675
5421
  if (peg$silentFails === 0) {
4676
- peg$fail(peg$e64);
5422
+ peg$fail(peg$e69);
4677
5423
  }
4678
5424
  }
4679
5425
  }
4680
5426
  s2 = input.substring(s2, peg$currPos);
4681
- if (input.substr(peg$currPos, 2) === peg$c53) {
4682
- s3 = peg$c53;
5427
+ if (input.substr(peg$currPos, 2) === peg$c54) {
5428
+ s3 = peg$c54;
4683
5429
  peg$currPos += 2;
4684
5430
  } else {
4685
5431
  s3 = peg$FAILED;
4686
5432
  if (peg$silentFails === 0) {
4687
- peg$fail(peg$e65);
5433
+ peg$fail(peg$e70);
4688
5434
  }
4689
5435
  }
4690
5436
  if (s3 !== peg$FAILED) {
4691
5437
  peg$savedPos = s0;
4692
- s0 = peg$f52(s2);
5438
+ s0 = peg$f54(s2);
4693
5439
  } else {
4694
5440
  peg$currPos = s0;
4695
5441
  s0 = peg$FAILED;
@@ -4701,12 +5447,12 @@ function peg$parse(input, options) {
4701
5447
  if (s0 === peg$FAILED) {
4702
5448
  s0 = peg$currPos;
4703
5449
  if (input.charCodeAt(peg$currPos) === 62) {
4704
- s1 = peg$c54;
5450
+ s1 = peg$c55;
4705
5451
  peg$currPos++;
4706
5452
  } else {
4707
5453
  s1 = peg$FAILED;
4708
5454
  if (peg$silentFails === 0) {
4709
- peg$fail(peg$e66);
5455
+ peg$fail(peg$e71);
4710
5456
  }
4711
5457
  }
4712
5458
  if (s1 !== peg$FAILED) {
@@ -4745,7 +5491,7 @@ function peg$parse(input, options) {
4745
5491
  }
4746
5492
  if (s3 !== peg$FAILED) {
4747
5493
  peg$savedPos = s0;
4748
- s0 = peg$f53(s2);
5494
+ s0 = peg$f55(s2);
4749
5495
  } else {
4750
5496
  peg$currPos = s0;
4751
5497
  s0 = peg$FAILED;
@@ -4801,7 +5547,7 @@ function peg$parse(input, options) {
4801
5547
  }
4802
5548
  if (s3 !== peg$FAILED) {
4803
5549
  peg$savedPos = s0;
4804
- s0 = peg$f54(s2);
5550
+ s0 = peg$f56(s2);
4805
5551
  } else {
4806
5552
  peg$currPos = s0;
4807
5553
  s0 = peg$FAILED;
@@ -4813,51 +5559,51 @@ function peg$parse(input, options) {
4813
5559
  if (s0 === peg$FAILED) {
4814
5560
  s0 = peg$currPos;
4815
5561
  if (input.charCodeAt(peg$currPos) === 123) {
4816
- s1 = peg$c55;
5562
+ s1 = peg$c56;
4817
5563
  peg$currPos++;
4818
5564
  } else {
4819
5565
  s1 = peg$FAILED;
4820
5566
  if (peg$silentFails === 0) {
4821
- peg$fail(peg$e67);
5567
+ peg$fail(peg$e72);
4822
5568
  }
4823
5569
  }
4824
5570
  if (s1 !== peg$FAILED) {
4825
5571
  s2 = peg$currPos;
4826
5572
  s3 = [];
4827
5573
  s4 = input.charAt(peg$currPos);
4828
- if (peg$r8.test(s4)) {
5574
+ if (peg$r12.test(s4)) {
4829
5575
  peg$currPos++;
4830
5576
  } else {
4831
5577
  s4 = peg$FAILED;
4832
5578
  if (peg$silentFails === 0) {
4833
- peg$fail(peg$e58);
5579
+ peg$fail(peg$e63);
4834
5580
  }
4835
5581
  }
4836
5582
  while (s4 !== peg$FAILED) {
4837
5583
  s3.push(s4);
4838
5584
  s4 = input.charAt(peg$currPos);
4839
- if (peg$r8.test(s4)) {
5585
+ if (peg$r12.test(s4)) {
4840
5586
  peg$currPos++;
4841
5587
  } else {
4842
5588
  s4 = peg$FAILED;
4843
5589
  if (peg$silentFails === 0) {
4844
- peg$fail(peg$e58);
5590
+ peg$fail(peg$e63);
4845
5591
  }
4846
5592
  }
4847
5593
  }
4848
5594
  s2 = input.substring(s2, peg$currPos);
4849
5595
  if (input.charCodeAt(peg$currPos) === 125) {
4850
- s3 = peg$c56;
5596
+ s3 = peg$c57;
4851
5597
  peg$currPos++;
4852
5598
  } else {
4853
5599
  s3 = peg$FAILED;
4854
5600
  if (peg$silentFails === 0) {
4855
- peg$fail(peg$e68);
5601
+ peg$fail(peg$e73);
4856
5602
  }
4857
5603
  }
4858
5604
  if (s3 !== peg$FAILED) {
4859
5605
  peg$savedPos = s0;
4860
- s0 = peg$f55(s2);
5606
+ s0 = peg$f57(s2);
4861
5607
  } else {
4862
5608
  peg$currPos = s0;
4863
5609
  s0 = peg$FAILED;
@@ -4869,51 +5615,51 @@ function peg$parse(input, options) {
4869
5615
  if (s0 === peg$FAILED) {
4870
5616
  s0 = peg$currPos;
4871
5617
  if (input.charCodeAt(peg$currPos) === 40) {
4872
- s1 = peg$c57;
5618
+ s1 = peg$c58;
4873
5619
  peg$currPos++;
4874
5620
  } else {
4875
5621
  s1 = peg$FAILED;
4876
5622
  if (peg$silentFails === 0) {
4877
- peg$fail(peg$e69);
5623
+ peg$fail(peg$e74);
4878
5624
  }
4879
5625
  }
4880
5626
  if (s1 !== peg$FAILED) {
4881
5627
  s2 = peg$currPos;
4882
5628
  s3 = [];
4883
5629
  s4 = input.charAt(peg$currPos);
4884
- if (peg$r7.test(s4)) {
5630
+ if (peg$r11.test(s4)) {
4885
5631
  peg$currPos++;
4886
5632
  } else {
4887
5633
  s4 = peg$FAILED;
4888
5634
  if (peg$silentFails === 0) {
4889
- peg$fail(peg$e49);
5635
+ peg$fail(peg$e54);
4890
5636
  }
4891
5637
  }
4892
5638
  while (s4 !== peg$FAILED) {
4893
5639
  s3.push(s4);
4894
5640
  s4 = input.charAt(peg$currPos);
4895
- if (peg$r7.test(s4)) {
5641
+ if (peg$r11.test(s4)) {
4896
5642
  peg$currPos++;
4897
5643
  } else {
4898
5644
  s4 = peg$FAILED;
4899
5645
  if (peg$silentFails === 0) {
4900
- peg$fail(peg$e49);
5646
+ peg$fail(peg$e54);
4901
5647
  }
4902
5648
  }
4903
5649
  }
4904
5650
  s2 = input.substring(s2, peg$currPos);
4905
5651
  if (input.charCodeAt(peg$currPos) === 41) {
4906
- s3 = peg$c58;
5652
+ s3 = peg$c59;
4907
5653
  peg$currPos++;
4908
5654
  } else {
4909
5655
  s3 = peg$FAILED;
4910
5656
  if (peg$silentFails === 0) {
4911
- peg$fail(peg$e70);
5657
+ peg$fail(peg$e75);
4912
5658
  }
4913
5659
  }
4914
5660
  if (s3 !== peg$FAILED) {
4915
5661
  peg$savedPos = s0;
4916
- s0 = peg$f56(s2);
5662
+ s0 = peg$f58(s2);
4917
5663
  } else {
4918
5664
  peg$currPos = s0;
4919
5665
  s0 = peg$FAILED;
@@ -4937,13 +5683,13 @@ function peg$parse(input, options) {
4937
5683
  function peg$parseStyleDirective() {
4938
5684
  var s0, s1, s2, s3, s4, s5;
4939
5685
  s0 = peg$currPos;
4940
- if (input.substr(peg$currPos, 5) === peg$c59) {
4941
- s1 = peg$c59;
5686
+ if (input.substr(peg$currPos, 5) === peg$c60) {
5687
+ s1 = peg$c60;
4942
5688
  peg$currPos += 5;
4943
5689
  } else {
4944
5690
  s1 = peg$FAILED;
4945
5691
  if (peg$silentFails === 0) {
4946
- peg$fail(peg$e71);
5692
+ peg$fail(peg$e76);
4947
5693
  }
4948
5694
  }
4949
5695
  if (s1 !== peg$FAILED) {
@@ -4952,24 +5698,24 @@ function peg$parse(input, options) {
4952
5698
  s3 = peg$currPos;
4953
5699
  s4 = [];
4954
5700
  s5 = input.charAt(peg$currPos);
4955
- if (peg$r11.test(s5)) {
5701
+ if (peg$r15.test(s5)) {
4956
5702
  peg$currPos++;
4957
5703
  } else {
4958
5704
  s5 = peg$FAILED;
4959
5705
  if (peg$silentFails === 0) {
4960
- peg$fail(peg$e72);
5706
+ peg$fail(peg$e77);
4961
5707
  }
4962
5708
  }
4963
5709
  if (s5 !== peg$FAILED) {
4964
5710
  while (s5 !== peg$FAILED) {
4965
5711
  s4.push(s5);
4966
5712
  s5 = input.charAt(peg$currPos);
4967
- if (peg$r11.test(s5)) {
5713
+ if (peg$r15.test(s5)) {
4968
5714
  peg$currPos++;
4969
5715
  } else {
4970
5716
  s5 = peg$FAILED;
4971
5717
  if (peg$silentFails === 0) {
4972
- peg$fail(peg$e72);
5718
+ peg$fail(peg$e77);
4973
5719
  }
4974
5720
  }
4975
5721
  }
@@ -4983,7 +5729,7 @@ function peg$parse(input, options) {
4983
5729
  }
4984
5730
  if (s3 !== peg$FAILED) {
4985
5731
  peg$savedPos = s0;
4986
- s0 = peg$f57(s3);
5732
+ s0 = peg$f59(s3);
4987
5733
  } else {
4988
5734
  peg$currPos = s0;
4989
5735
  s0 = peg$FAILED;
@@ -5001,23 +5747,23 @@ function peg$parse(input, options) {
5001
5747
  function peg$parseClassDirective() {
5002
5748
  var s0, s1, s2, s3, s4, s5;
5003
5749
  s0 = peg$currPos;
5004
- if (input.substr(peg$currPos, 8) === peg$c60) {
5005
- s1 = peg$c60;
5750
+ if (input.substr(peg$currPos, 8) === peg$c61) {
5751
+ s1 = peg$c61;
5006
5752
  peg$currPos += 8;
5007
5753
  } else {
5008
5754
  s1 = peg$FAILED;
5009
5755
  if (peg$silentFails === 0) {
5010
- peg$fail(peg$e73);
5756
+ peg$fail(peg$e78);
5011
5757
  }
5012
5758
  }
5013
5759
  if (s1 === peg$FAILED) {
5014
- if (input.substr(peg$currPos, 5) === peg$c61) {
5015
- s1 = peg$c61;
5760
+ if (input.substr(peg$currPos, 5) === peg$c62) {
5761
+ s1 = peg$c62;
5016
5762
  peg$currPos += 5;
5017
5763
  } else {
5018
5764
  s1 = peg$FAILED;
5019
5765
  if (peg$silentFails === 0) {
5020
- peg$fail(peg$e74);
5766
+ peg$fail(peg$e79);
5021
5767
  }
5022
5768
  }
5023
5769
  }
@@ -5027,24 +5773,24 @@ function peg$parse(input, options) {
5027
5773
  s3 = peg$currPos;
5028
5774
  s4 = [];
5029
5775
  s5 = input.charAt(peg$currPos);
5030
- if (peg$r11.test(s5)) {
5776
+ if (peg$r15.test(s5)) {
5031
5777
  peg$currPos++;
5032
5778
  } else {
5033
5779
  s5 = peg$FAILED;
5034
5780
  if (peg$silentFails === 0) {
5035
- peg$fail(peg$e72);
5781
+ peg$fail(peg$e77);
5036
5782
  }
5037
5783
  }
5038
5784
  if (s5 !== peg$FAILED) {
5039
5785
  while (s5 !== peg$FAILED) {
5040
5786
  s4.push(s5);
5041
5787
  s5 = input.charAt(peg$currPos);
5042
- if (peg$r11.test(s5)) {
5788
+ if (peg$r15.test(s5)) {
5043
5789
  peg$currPos++;
5044
5790
  } else {
5045
5791
  s5 = peg$FAILED;
5046
5792
  if (peg$silentFails === 0) {
5047
- peg$fail(peg$e72);
5793
+ peg$fail(peg$e77);
5048
5794
  }
5049
5795
  }
5050
5796
  }
@@ -5058,7 +5804,7 @@ function peg$parse(input, options) {
5058
5804
  }
5059
5805
  if (s3 !== peg$FAILED) {
5060
5806
  peg$savedPos = s0;
5061
- s0 = peg$f58(s3);
5807
+ s0 = peg$f60(s3);
5062
5808
  } else {
5063
5809
  peg$currPos = s0;
5064
5810
  s0 = peg$FAILED;
@@ -5076,13 +5822,13 @@ function peg$parse(input, options) {
5076
5822
  function peg$parseClickDirective() {
5077
5823
  var s0, s1, s2, s3, s4, s5;
5078
5824
  s0 = peg$currPos;
5079
- if (input.substr(peg$currPos, 5) === peg$c62) {
5080
- s1 = peg$c62;
5825
+ if (input.substr(peg$currPos, 5) === peg$c63) {
5826
+ s1 = peg$c63;
5081
5827
  peg$currPos += 5;
5082
5828
  } else {
5083
5829
  s1 = peg$FAILED;
5084
5830
  if (peg$silentFails === 0) {
5085
- peg$fail(peg$e75);
5831
+ peg$fail(peg$e80);
5086
5832
  }
5087
5833
  }
5088
5834
  if (s1 !== peg$FAILED) {
@@ -5091,24 +5837,24 @@ function peg$parse(input, options) {
5091
5837
  s3 = peg$currPos;
5092
5838
  s4 = [];
5093
5839
  s5 = input.charAt(peg$currPos);
5094
- if (peg$r11.test(s5)) {
5840
+ if (peg$r15.test(s5)) {
5095
5841
  peg$currPos++;
5096
5842
  } else {
5097
5843
  s5 = peg$FAILED;
5098
5844
  if (peg$silentFails === 0) {
5099
- peg$fail(peg$e72);
5845
+ peg$fail(peg$e77);
5100
5846
  }
5101
5847
  }
5102
5848
  if (s5 !== peg$FAILED) {
5103
5849
  while (s5 !== peg$FAILED) {
5104
5850
  s4.push(s5);
5105
5851
  s5 = input.charAt(peg$currPos);
5106
- if (peg$r11.test(s5)) {
5852
+ if (peg$r15.test(s5)) {
5107
5853
  peg$currPos++;
5108
5854
  } else {
5109
5855
  s5 = peg$FAILED;
5110
5856
  if (peg$silentFails === 0) {
5111
- peg$fail(peg$e72);
5857
+ peg$fail(peg$e77);
5112
5858
  }
5113
5859
  }
5114
5860
  }
@@ -5122,7 +5868,7 @@ function peg$parse(input, options) {
5122
5868
  }
5123
5869
  if (s3 !== peg$FAILED) {
5124
5870
  peg$savedPos = s0;
5125
- s0 = peg$f59(s3);
5871
+ s0 = peg$f61(s3);
5126
5872
  } else {
5127
5873
  peg$currPos = s0;
5128
5874
  s0 = peg$FAILED;
@@ -5140,59 +5886,59 @@ function peg$parse(input, options) {
5140
5886
  function peg$parseNoteDirective() {
5141
5887
  var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13;
5142
5888
  s0 = peg$currPos;
5143
- if (input.substr(peg$currPos, 4) === peg$c63) {
5144
- s1 = peg$c63;
5889
+ if (input.substr(peg$currPos, 4) === peg$c64) {
5890
+ s1 = peg$c64;
5145
5891
  peg$currPos += 4;
5146
5892
  } else {
5147
5893
  s1 = peg$FAILED;
5148
5894
  if (peg$silentFails === 0) {
5149
- peg$fail(peg$e76);
5895
+ peg$fail(peg$e81);
5150
5896
  }
5151
5897
  }
5152
5898
  if (s1 !== peg$FAILED) {
5153
5899
  s2 = peg$parse__();
5154
5900
  if (s2 !== peg$FAILED) {
5155
5901
  if (input.charCodeAt(peg$currPos) === 34) {
5156
- s3 = peg$c64;
5902
+ s3 = peg$c40;
5157
5903
  peg$currPos++;
5158
5904
  } else {
5159
5905
  s3 = peg$FAILED;
5160
5906
  if (peg$silentFails === 0) {
5161
- peg$fail(peg$e77);
5907
+ peg$fail(peg$e50);
5162
5908
  }
5163
5909
  }
5164
5910
  if (s3 !== peg$FAILED) {
5165
5911
  s4 = peg$currPos;
5166
5912
  s5 = [];
5167
5913
  s6 = input.charAt(peg$currPos);
5168
- if (peg$r12.test(s6)) {
5914
+ if (peg$r9.test(s6)) {
5169
5915
  peg$currPos++;
5170
5916
  } else {
5171
5917
  s6 = peg$FAILED;
5172
5918
  if (peg$silentFails === 0) {
5173
- peg$fail(peg$e78);
5919
+ peg$fail(peg$e51);
5174
5920
  }
5175
5921
  }
5176
5922
  while (s6 !== peg$FAILED) {
5177
5923
  s5.push(s6);
5178
5924
  s6 = input.charAt(peg$currPos);
5179
- if (peg$r12.test(s6)) {
5925
+ if (peg$r9.test(s6)) {
5180
5926
  peg$currPos++;
5181
5927
  } else {
5182
5928
  s6 = peg$FAILED;
5183
5929
  if (peg$silentFails === 0) {
5184
- peg$fail(peg$e78);
5930
+ peg$fail(peg$e51);
5185
5931
  }
5186
5932
  }
5187
5933
  }
5188
5934
  s4 = input.substring(s4, peg$currPos);
5189
5935
  if (input.charCodeAt(peg$currPos) === 34) {
5190
- s5 = peg$c64;
5936
+ s5 = peg$c40;
5191
5937
  peg$currPos++;
5192
5938
  } else {
5193
5939
  s5 = peg$FAILED;
5194
5940
  if (peg$silentFails === 0) {
5195
- peg$fail(peg$e77);
5941
+ peg$fail(peg$e50);
5196
5942
  }
5197
5943
  }
5198
5944
  if (s5 !== peg$FAILED) {
@@ -5204,7 +5950,7 @@ function peg$parse(input, options) {
5204
5950
  } else {
5205
5951
  s7 = peg$FAILED;
5206
5952
  if (peg$silentFails === 0) {
5207
- peg$fail(peg$e79);
5953
+ peg$fail(peg$e82);
5208
5954
  }
5209
5955
  }
5210
5956
  if (s7 !== peg$FAILED) {
@@ -5261,7 +6007,7 @@ function peg$parse(input, options) {
5261
6007
  s10 = null;
5262
6008
  }
5263
6009
  peg$savedPos = s0;
5264
- s0 = peg$f60(s4, s9, s10);
6010
+ s0 = peg$f62(s4, s9, s10);
5265
6011
  } else {
5266
6012
  peg$currPos = s0;
5267
6013
  s0 = peg$FAILED;
@@ -5307,7 +6053,7 @@ function peg$parse(input, options) {
5307
6053
  } else {
5308
6054
  s2 = peg$FAILED;
5309
6055
  if (peg$silentFails === 0) {
5310
- peg$fail(peg$e80);
6056
+ peg$fail(peg$e83);
5311
6057
  }
5312
6058
  }
5313
6059
  if (s2 !== peg$FAILED) {
@@ -5322,7 +6068,7 @@ function peg$parse(input, options) {
5322
6068
  } else {
5323
6069
  s6 = peg$FAILED;
5324
6070
  if (peg$silentFails === 0) {
5325
- peg$fail(peg$e81);
6071
+ peg$fail(peg$e84);
5326
6072
  }
5327
6073
  }
5328
6074
  if (s6 !== peg$FAILED) {
@@ -5330,7 +6076,7 @@ function peg$parse(input, options) {
5330
6076
  s8 = peg$parseSignedInt();
5331
6077
  if (s8 !== peg$FAILED) {
5332
6078
  peg$savedPos = s0;
5333
- s0 = peg$f61(s4, s8);
6079
+ s0 = peg$f63(s4, s8);
5334
6080
  } else {
5335
6081
  peg$currPos = s0;
5336
6082
  s0 = peg$FAILED;
@@ -5366,7 +6112,7 @@ function peg$parse(input, options) {
5366
6112
  } else {
5367
6113
  s1 = peg$FAILED;
5368
6114
  if (peg$silentFails === 0) {
5369
- peg$fail(peg$e82);
6115
+ peg$fail(peg$e85);
5370
6116
  }
5371
6117
  }
5372
6118
  if (s1 === peg$FAILED) {
@@ -5375,24 +6121,24 @@ function peg$parse(input, options) {
5375
6121
  s2 = peg$currPos;
5376
6122
  s3 = [];
5377
6123
  s4 = input.charAt(peg$currPos);
5378
- if (peg$r13.test(s4)) {
6124
+ if (peg$r16.test(s4)) {
5379
6125
  peg$currPos++;
5380
6126
  } else {
5381
6127
  s4 = peg$FAILED;
5382
6128
  if (peg$silentFails === 0) {
5383
- peg$fail(peg$e83);
6129
+ peg$fail(peg$e86);
5384
6130
  }
5385
6131
  }
5386
6132
  if (s4 !== peg$FAILED) {
5387
6133
  while (s4 !== peg$FAILED) {
5388
6134
  s3.push(s4);
5389
6135
  s4 = input.charAt(peg$currPos);
5390
- if (peg$r13.test(s4)) {
6136
+ if (peg$r16.test(s4)) {
5391
6137
  peg$currPos++;
5392
6138
  } else {
5393
6139
  s4 = peg$FAILED;
5394
6140
  if (peg$silentFails === 0) {
5395
- peg$fail(peg$e83);
6141
+ peg$fail(peg$e86);
5396
6142
  }
5397
6143
  }
5398
6144
  }
@@ -5406,7 +6152,7 @@ function peg$parse(input, options) {
5406
6152
  }
5407
6153
  if (s2 !== peg$FAILED) {
5408
6154
  peg$savedPos = s0;
5409
- s0 = peg$f62(s1, s2);
6155
+ s0 = peg$f64(s1, s2);
5410
6156
  } else {
5411
6157
  peg$currPos = s0;
5412
6158
  s0 = peg$FAILED;
@@ -5422,7 +6168,7 @@ function peg$parse(input, options) {
5422
6168
  } else {
5423
6169
  s1 = peg$FAILED;
5424
6170
  if (peg$silentFails === 0) {
5425
- peg$fail(peg$e84);
6171
+ peg$fail(peg$e87);
5426
6172
  }
5427
6173
  }
5428
6174
  if (s1 !== peg$FAILED) {
@@ -5433,51 +6179,51 @@ function peg$parse(input, options) {
5433
6179
  s4 = peg$currPos;
5434
6180
  s5 = peg$parse_();
5435
6181
  if (input.charCodeAt(peg$currPos) === 34) {
5436
- s6 = peg$c64;
6182
+ s6 = peg$c40;
5437
6183
  peg$currPos++;
5438
6184
  } else {
5439
6185
  s6 = peg$FAILED;
5440
6186
  if (peg$silentFails === 0) {
5441
- peg$fail(peg$e77);
6187
+ peg$fail(peg$e50);
5442
6188
  }
5443
6189
  }
5444
6190
  if (s6 !== peg$FAILED) {
5445
6191
  s7 = peg$currPos;
5446
6192
  s8 = [];
5447
6193
  s9 = input.charAt(peg$currPos);
5448
- if (peg$r12.test(s9)) {
6194
+ if (peg$r9.test(s9)) {
5449
6195
  peg$currPos++;
5450
6196
  } else {
5451
6197
  s9 = peg$FAILED;
5452
6198
  if (peg$silentFails === 0) {
5453
- peg$fail(peg$e78);
6199
+ peg$fail(peg$e51);
5454
6200
  }
5455
6201
  }
5456
6202
  while (s9 !== peg$FAILED) {
5457
6203
  s8.push(s9);
5458
6204
  s9 = input.charAt(peg$currPos);
5459
- if (peg$r12.test(s9)) {
6205
+ if (peg$r9.test(s9)) {
5460
6206
  peg$currPos++;
5461
6207
  } else {
5462
6208
  s9 = peg$FAILED;
5463
6209
  if (peg$silentFails === 0) {
5464
- peg$fail(peg$e78);
6210
+ peg$fail(peg$e51);
5465
6211
  }
5466
6212
  }
5467
6213
  }
5468
6214
  s7 = input.substring(s7, peg$currPos);
5469
6215
  if (input.charCodeAt(peg$currPos) === 34) {
5470
- s8 = peg$c64;
6216
+ s8 = peg$c40;
5471
6217
  peg$currPos++;
5472
6218
  } else {
5473
6219
  s8 = peg$FAILED;
5474
6220
  if (peg$silentFails === 0) {
5475
- peg$fail(peg$e77);
6221
+ peg$fail(peg$e50);
5476
6222
  }
5477
6223
  }
5478
6224
  if (s8 !== peg$FAILED) {
5479
6225
  peg$savedPos = s4;
5480
- s4 = peg$f63(s3, s7);
6226
+ s4 = peg$f65(s3, s7);
5481
6227
  } else {
5482
6228
  peg$currPos = s4;
5483
6229
  s4 = peg$FAILED;
@@ -5510,7 +6256,7 @@ function peg$parse(input, options) {
5510
6256
  }
5511
6257
  if (s9 !== peg$FAILED) {
5512
6258
  peg$savedPos = s0;
5513
- s0 = peg$f64(s3, s4, s7);
6259
+ s0 = peg$f66(s3, s4, s7);
5514
6260
  } else {
5515
6261
  peg$currPos = s0;
5516
6262
  s0 = peg$FAILED;
@@ -5541,7 +6287,7 @@ function peg$parse(input, options) {
5541
6287
  } else {
5542
6288
  s0 = peg$FAILED;
5543
6289
  if (peg$silentFails === 0) {
5544
- peg$fail(peg$e85);
6290
+ peg$fail(peg$e88);
5545
6291
  }
5546
6292
  }
5547
6293
  if (s0 === peg$FAILED) {
@@ -5551,7 +6297,7 @@ function peg$parse(input, options) {
5551
6297
  } else {
5552
6298
  s0 = peg$FAILED;
5553
6299
  if (peg$silentFails === 0) {
5554
- peg$fail(peg$e86);
6300
+ peg$fail(peg$e89);
5555
6301
  }
5556
6302
  }
5557
6303
  if (s0 === peg$FAILED) {
@@ -5561,7 +6307,7 @@ function peg$parse(input, options) {
5561
6307
  } else {
5562
6308
  s0 = peg$FAILED;
5563
6309
  if (peg$silentFails === 0) {
5564
- peg$fail(peg$e87);
6310
+ peg$fail(peg$e90);
5565
6311
  }
5566
6312
  }
5567
6313
  if (s0 === peg$FAILED) {
@@ -5571,7 +6317,7 @@ function peg$parse(input, options) {
5571
6317
  } else {
5572
6318
  s0 = peg$FAILED;
5573
6319
  if (peg$silentFails === 0) {
5574
- peg$fail(peg$e88);
6320
+ peg$fail(peg$e91);
5575
6321
  }
5576
6322
  }
5577
6323
  }
@@ -5636,24 +6382,24 @@ function peg$parse(input, options) {
5636
6382
  s3 = peg$currPos;
5637
6383
  s4 = [];
5638
6384
  s5 = input.charAt(peg$currPos);
5639
- if (peg$r14.test(s5)) {
6385
+ if (peg$r17.test(s5)) {
5640
6386
  peg$currPos++;
5641
6387
  } else {
5642
6388
  s5 = peg$FAILED;
5643
6389
  if (peg$silentFails === 0) {
5644
- peg$fail(peg$e89);
6390
+ peg$fail(peg$e92);
5645
6391
  }
5646
6392
  }
5647
6393
  if (s5 !== peg$FAILED) {
5648
6394
  while (s5 !== peg$FAILED) {
5649
6395
  s4.push(s5);
5650
6396
  s5 = input.charAt(peg$currPos);
5651
- if (peg$r14.test(s5)) {
6397
+ if (peg$r17.test(s5)) {
5652
6398
  peg$currPos++;
5653
6399
  } else {
5654
6400
  s5 = peg$FAILED;
5655
6401
  if (peg$silentFails === 0) {
5656
- peg$fail(peg$e89);
6402
+ peg$fail(peg$e92);
5657
6403
  }
5658
6404
  }
5659
6405
  }
@@ -5712,7 +6458,7 @@ function peg$parse(input, options) {
5712
6458
  s6 = peg$parseNL();
5713
6459
  if (s6 !== peg$FAILED) {
5714
6460
  peg$savedPos = s0;
5715
- s0 = peg$f65(s3, s5);
6461
+ s0 = peg$f67(s3, s5);
5716
6462
  } else {
5717
6463
  peg$currPos = s0;
5718
6464
  s0 = peg$FAILED;
@@ -5740,30 +6486,30 @@ function peg$parse(input, options) {
5740
6486
  peg$silentFails++;
5741
6487
  s0 = [];
5742
6488
  s1 = input.charAt(peg$currPos);
5743
- if (peg$r15.test(s1)) {
6489
+ if (peg$r18.test(s1)) {
5744
6490
  peg$currPos++;
5745
6491
  } else {
5746
6492
  s1 = peg$FAILED;
5747
6493
  if (peg$silentFails === 0) {
5748
- peg$fail(peg$e91);
6494
+ peg$fail(peg$e94);
5749
6495
  }
5750
6496
  }
5751
6497
  while (s1 !== peg$FAILED) {
5752
6498
  s0.push(s1);
5753
6499
  s1 = input.charAt(peg$currPos);
5754
- if (peg$r15.test(s1)) {
6500
+ if (peg$r18.test(s1)) {
5755
6501
  peg$currPos++;
5756
6502
  } else {
5757
6503
  s1 = peg$FAILED;
5758
6504
  if (peg$silentFails === 0) {
5759
- peg$fail(peg$e91);
6505
+ peg$fail(peg$e94);
5760
6506
  }
5761
6507
  }
5762
6508
  }
5763
6509
  peg$silentFails--;
5764
6510
  s1 = peg$FAILED;
5765
6511
  if (peg$silentFails === 0) {
5766
- peg$fail(peg$e90);
6512
+ peg$fail(peg$e93);
5767
6513
  }
5768
6514
  return s0;
5769
6515
  }
@@ -5772,24 +6518,24 @@ function peg$parse(input, options) {
5772
6518
  peg$silentFails++;
5773
6519
  s0 = [];
5774
6520
  s1 = input.charAt(peg$currPos);
5775
- if (peg$r15.test(s1)) {
6521
+ if (peg$r18.test(s1)) {
5776
6522
  peg$currPos++;
5777
6523
  } else {
5778
6524
  s1 = peg$FAILED;
5779
6525
  if (peg$silentFails === 0) {
5780
- peg$fail(peg$e91);
6526
+ peg$fail(peg$e94);
5781
6527
  }
5782
6528
  }
5783
6529
  if (s1 !== peg$FAILED) {
5784
6530
  while (s1 !== peg$FAILED) {
5785
6531
  s0.push(s1);
5786
6532
  s1 = input.charAt(peg$currPos);
5787
- if (peg$r15.test(s1)) {
6533
+ if (peg$r18.test(s1)) {
5788
6534
  peg$currPos++;
5789
6535
  } else {
5790
6536
  s1 = peg$FAILED;
5791
6537
  if (peg$silentFails === 0) {
5792
- peg$fail(peg$e91);
6538
+ peg$fail(peg$e94);
5793
6539
  }
5794
6540
  }
5795
6541
  }
@@ -5800,7 +6546,7 @@ function peg$parse(input, options) {
5800
6546
  if (s0 === peg$FAILED) {
5801
6547
  s1 = peg$FAILED;
5802
6548
  if (peg$silentFails === 0) {
5803
- peg$fail(peg$e92);
6549
+ peg$fail(peg$e95);
5804
6550
  }
5805
6551
  }
5806
6552
  return s0;
@@ -5814,17 +6560,17 @@ function peg$parse(input, options) {
5814
6560
  } else {
5815
6561
  s0 = peg$FAILED;
5816
6562
  if (peg$silentFails === 0) {
5817
- peg$fail(peg$e94);
6563
+ peg$fail(peg$e97);
5818
6564
  }
5819
6565
  }
5820
6566
  if (s0 === peg$FAILED) {
5821
6567
  s0 = input.charAt(peg$currPos);
5822
- if (peg$r16.test(s0)) {
6568
+ if (peg$r19.test(s0)) {
5823
6569
  peg$currPos++;
5824
6570
  } else {
5825
6571
  s0 = peg$FAILED;
5826
6572
  if (peg$silentFails === 0) {
5827
- peg$fail(peg$e95);
6573
+ peg$fail(peg$e98);
5828
6574
  }
5829
6575
  }
5830
6576
  }
@@ -5832,7 +6578,7 @@ function peg$parse(input, options) {
5832
6578
  if (s0 === peg$FAILED) {
5833
6579
  s1 = peg$FAILED;
5834
6580
  if (peg$silentFails === 0) {
5835
- peg$fail(peg$e93);
6581
+ peg$fail(peg$e96);
5836
6582
  }
5837
6583
  }
5838
6584
  return s0;
@@ -5869,11 +6615,28 @@ function peg$parse(input, options) {
5869
6615
  var flowchart = {
5870
6616
  parseMermaid(input) {
5871
6617
  const raw = peg$parse(input);
6618
+ const nodes = raw.flow.nodes.map((n) => {
6619
+ const base = {
6620
+ id: n.id,
6621
+ label: n.label,
6622
+ shape: n.shape || "rect",
6623
+ status: n.status || "default",
6624
+ ...n.subgraph !== void 0 ? { subgraph: n.subgraph } : {}
6625
+ };
6626
+ if (n.iconToken !== void 0) {
6627
+ const result = parseIconRef(String(n.iconToken));
6628
+ if (!result.ok) {
6629
+ throw new Error(`Flowchart parse error: invalid @icon value "${n.iconToken}": ${result.error.message}`);
6630
+ }
6631
+ return { ...base, icon: result.value };
6632
+ }
6633
+ return base;
6634
+ });
5872
6635
  return {
5873
6636
  version: raw.version,
5874
6637
  metadata: raw.metadata ?? {},
5875
6638
  direction: raw.direction,
5876
- nodes: raw.flow.nodes,
6639
+ nodes,
5877
6640
  edges: raw.flow.edges,
5878
6641
  subgraphs: raw.subgraphs ?? [],
5879
6642
  overlays: raw.overlays?.length > 0 ? raw.overlays : void 0
@@ -6149,179 +6912,6 @@ function rhu(v, decimals = 2) {
6149
6912
  return Math.floor(v * f2 + 0.5) / f2;
6150
6913
  }
6151
6914
 
6152
- // ../src/text/metrics.ts
6153
- var ADVANCE = {
6154
- 32: 0.2793,
6155
- 33: 0.2793,
6156
- 34: 0.3574,
6157
- 35: 0.5576,
6158
- 36: 0.5576,
6159
- 37: 0.8906,
6160
- 38: 0.6699,
6161
- 39: 0.1914,
6162
- 40: 0.334,
6163
- 41: 0.334,
6164
- 42: 0.3906,
6165
- 43: 0.5859,
6166
- 44: 0.2793,
6167
- 45: 0.334,
6168
- 46: 0.2793,
6169
- 47: 0.3125,
6170
- 48: 0.5576,
6171
- 49: 0.5576,
6172
- 50: 0.5576,
6173
- 51: 0.5576,
6174
- 52: 0.5576,
6175
- 53: 0.5576,
6176
- 54: 0.5576,
6177
- 55: 0.5576,
6178
- 56: 0.5576,
6179
- 57: 0.5576,
6180
- 58: 0.2793,
6181
- 59: 0.2793,
6182
- 60: 0.5859,
6183
- 61: 0.5859,
6184
- 62: 0.5859,
6185
- 63: 0.5576,
6186
- 64: 1.0186,
6187
- 65: 0.6699,
6188
- 66: 0.6699,
6189
- 67: 0.7227,
6190
- 68: 0.7227,
6191
- 69: 0.6699,
6192
- 70: 0.6133,
6193
- 71: 0.7793,
6194
- 72: 0.7227,
6195
- 73: 0.2783,
6196
- 74: 0.5,
6197
- 75: 0.6699,
6198
- 76: 0.5576,
6199
- 77: 0.8359,
6200
- 78: 0.7227,
6201
- 79: 0.7793,
6202
- 80: 0.6133,
6203
- 81: 0.7793,
6204
- 82: 0.7227,
6205
- 83: 0.6133,
6206
- 84: 0.6133,
6207
- 85: 0.7227,
6208
- 86: 0.6699,
6209
- 87: 0.9453,
6210
- 88: 0.6699,
6211
- 89: 0.6699,
6212
- 90: 0.6133,
6213
- 91: 0.2793,
6214
- 92: 0.3125,
6215
- 93: 0.2793,
6216
- 94: 0.5859,
6217
- 95: 0.5576,
6218
- 96: 0.334,
6219
- 97: 0.5576,
6220
- 98: 0.5576,
6221
- 99: 0.5,
6222
- 100: 0.5576,
6223
- 101: 0.5576,
6224
- 102: 0.2793,
6225
- 103: 0.5576,
6226
- 104: 0.5576,
6227
- 105: 0.2217,
6228
- 106: 0.2217,
6229
- 107: 0.5,
6230
- 108: 0.2217,
6231
- 109: 0.8359,
6232
- 110: 0.5576,
6233
- 111: 0.5576,
6234
- 112: 0.5576,
6235
- 113: 0.5576,
6236
- 114: 0.334,
6237
- 115: 0.5,
6238
- 116: 0.334,
6239
- 117: 0.5576,
6240
- 118: 0.5,
6241
- 119: 0.7227,
6242
- 120: 0.5,
6243
- 121: 0.5,
6244
- 122: 0.5,
6245
- 123: 0.334,
6246
- 124: 0.2598,
6247
- 125: 0.334,
6248
- 126: 0.5859
6249
- };
6250
- var DEFAULT_ADVANCE = 0.5576;
6251
- var LINE_HEIGHT_FACTOR = 1.2;
6252
- function measureText(text, fontSizePx) {
6253
- let totalEm = 0;
6254
- for (let i = 0; i < text.length; i++) {
6255
- const cp = text.codePointAt(i) ?? 32;
6256
- totalEm += ADVANCE[cp] ?? DEFAULT_ADVANCE;
6257
- }
6258
- return {
6259
- width: totalEm * fontSizePx,
6260
- height: fontSizePx * LINE_HEIGHT_FACTOR
6261
- };
6262
- }
6263
-
6264
- // ../src/text/wrap.ts
6265
- var ELLIPSIS = "\u2026";
6266
- function wrapText2(text, fontSizePx, maxWidth, maxLines) {
6267
- if (!text || maxLines <= 0 || maxWidth <= 0) return { lines: [] };
6268
- const words = text.split(/\s+/).filter(Boolean);
6269
- if (words.length === 0) return { lines: [] };
6270
- const lines2 = [];
6271
- let current = "";
6272
- for (let wi = 0; wi < words.length; wi++) {
6273
- const word = words[wi];
6274
- const candidate = current ? `${current} ${word}` : word;
6275
- if (measureText(candidate, fontSizePx).width <= maxWidth) {
6276
- current = candidate;
6277
- } else {
6278
- if (current) {
6279
- if (lines2.length === maxLines - 1) {
6280
- const remaining = words.slice(wi).join(" ");
6281
- const full = current ? `${current} ${remaining}` : remaining;
6282
- lines2.push(truncateText(full, fontSizePx, maxWidth));
6283
- return { lines: lines2 };
6284
- }
6285
- lines2.push(current);
6286
- current = word;
6287
- } else {
6288
- if (lines2.length === maxLines - 1) {
6289
- lines2.push(truncateText(word, fontSizePx, maxWidth));
6290
- return { lines: lines2 };
6291
- }
6292
- lines2.push(truncateText(word, fontSizePx, maxWidth));
6293
- current = "";
6294
- }
6295
- }
6296
- }
6297
- if (current) {
6298
- if (lines2.length < maxLines) {
6299
- lines2.push(current);
6300
- } else {
6301
- const last = lines2[lines2.length - 1] ?? "";
6302
- lines2[lines2.length - 1] = truncateText(`${last} ${current}`, fontSizePx, maxWidth);
6303
- }
6304
- }
6305
- return { lines: lines2 };
6306
- }
6307
- function truncateText(text, fontSizePx, maxWidth) {
6308
- if (measureText(text, fontSizePx).width <= maxWidth) return text;
6309
- const ellipsisWidth = measureText(ELLIPSIS, fontSizePx).width;
6310
- const budget = maxWidth - ellipsisWidth;
6311
- if (budget <= 0) return ELLIPSIS;
6312
- let lo = 0;
6313
- let hi = text.length;
6314
- while (lo < hi) {
6315
- const mid = Math.floor((lo + hi + 1) / 2);
6316
- if (measureText(text.slice(0, mid), fontSizePx).width <= budget) {
6317
- lo = mid;
6318
- } else {
6319
- hi = mid - 1;
6320
- }
6321
- }
6322
- return text.slice(0, lo) + ELLIPSIS;
6323
- }
6324
-
6325
6915
  // ../src/palette/categorical.ts
6326
6916
  var CATEGORICAL_HUES = [
6327
6917
  "#7C3AED",
@@ -11191,6 +11781,8 @@ function translateElement(element, dx, dy) {
11191
11781
  return { ...element, position: { x: rhu(element.position.x + dx), y: rhu(element.position.y + dy) } };
11192
11782
  case "group":
11193
11783
  return { ...element, children: translateElements(element.children, dx, dy) };
11784
+ case "icon":
11785
+ return { ...element, x: rhu(element.x + dx), y: rhu(element.y + dy) };
11194
11786
  }
11195
11787
  }
11196
11788
  function translateAnchors(anchors, dx, dy) {
@@ -42634,6 +43226,8 @@ function translateElement2(element, dx, dy) {
42634
43226
  return { ...element, position: { x: rhu(element.position.x + dx), y: rhu(element.position.y + dy) } };
42635
43227
  case "group":
42636
43228
  return { ...element, children: translateElements2(element.children, dx, dy) };
43229
+ case "icon":
43230
+ return { ...element, x: rhu(element.x + dx), y: rhu(element.y + dy) };
42637
43231
  }
42638
43232
  }
42639
43233
  function translateAnchors2(anchors, dx, dy) {
@@ -43946,6 +44540,9 @@ ${circles}`;
43946
44540
  }
43947
44541
  return `${attrs} />`;
43948
44542
  }
44543
+ case "icon": {
44544
+ return renderIcon(el, depth);
44545
+ }
43949
44546
  case "group": {
43950
44547
  const id = el.id != null ? ` id="${escapeAttr(el.id)}"` : "";
43951
44548
  const transform = el.transform != null ? ` transform="${escapeAttr(el.transform)}"` : "";
@@ -43960,6 +44557,66 @@ ${pad}</g>`;
43960
44557
  }
43961
44558
  }
43962
44559
  }
44560
+ var iconEmitCounter = 0;
44561
+ function renderIcon(el, depth) {
44562
+ const pad = " ".repeat(depth);
44563
+ const { icon, x, y, size } = el;
44564
+ const { viewBox, transforms, colorMode } = icon;
44565
+ const vbW = viewBox.width;
44566
+ const vbH = viewBox.height;
44567
+ const vbL = viewBox.left;
44568
+ const vbT = viewBox.top;
44569
+ const scale = Math.min(size / vbW, size / vbH);
44570
+ const scaledW = formatNum(vbW * scale);
44571
+ const scaledH = formatNum(vbH * scale);
44572
+ const offX = formatNum(x + (size - vbW * scale) / 2);
44573
+ const offY = formatNum(y + (size - vbH * scale) / 2);
44574
+ const styleAttr = colorMode === "monochrome" && el.color ? ` style="color:${escapeAttr(el.color)}"` : "";
44575
+ const opacityAttr = el.opacity != null ? ` opacity="${el.opacity}"` : "";
44576
+ const body = colorMode === "brand" ? namespaceIconIds(icon.body, `icn${iconEmitCounter++}`) : icon.body;
44577
+ const cx = vbL + vbW / 2;
44578
+ const cy = vbT + vbH / 2;
44579
+ const innerTransform = buildIconTransform(transforms, cx, cy);
44580
+ const vbAttr = `${vbL} ${vbT} ${formatNum(vbW)} ${formatNum(vbH)}`;
44581
+ const inner = innerTransform ? `${pad} <g transform="${innerTransform}">${body}</g>` : `${pad} ${body}`;
44582
+ return [
44583
+ `${pad}<svg x="${offX}" y="${offY}" width="${scaledW}" height="${scaledH}" viewBox="${vbAttr}"${styleAttr}${opacityAttr}>`,
44584
+ inner,
44585
+ `${pad}</svg>`
44586
+ ].join("\n");
44587
+ }
44588
+ function buildIconTransform(t, cx, cy) {
44589
+ if (t.rotate === 0 && !t.hFlip && !t.vFlip) return null;
44590
+ const deg = t.rotate * 90;
44591
+ const sf = t.hFlip ? -1 : 1;
44592
+ const vf = t.vFlip ? -1 : 1;
44593
+ const cxs = formatNum(cx);
44594
+ const cys = formatNum(cy);
44595
+ const parts = [];
44596
+ parts.push(`translate(${cxs} ${cys})`);
44597
+ if (t.hFlip || t.vFlip) parts.push(`scale(${sf} ${vf})`);
44598
+ if (t.rotate !== 0) parts.push(`rotate(${deg})`);
44599
+ parts.push(`translate(${formatNum(-cx)} ${formatNum(-cy)})`);
44600
+ return parts.join(" ");
44601
+ }
44602
+ function namespaceIconIds(body, prefix) {
44603
+ const idRe = /\bid="([^"]+)"/g;
44604
+ const ids = /* @__PURE__ */ new Set();
44605
+ let m;
44606
+ while ((m = idRe.exec(body)) !== null) {
44607
+ ids.add(m[1]);
44608
+ }
44609
+ if (ids.size === 0) return body;
44610
+ let result = body;
44611
+ for (const id of ids) {
44612
+ const newId = `${prefix}-${id}`;
44613
+ result = result.split(`id="${id}"`).join(`id="${newId}"`);
44614
+ result = result.split(`url(#${id})`).join(`url(#${newId})`);
44615
+ result = result.split(`href="#${id}"`).join(`href="#${newId}"`);
44616
+ result = result.split(`href='#${id}'`).join(`href='#${newId}'`);
44617
+ }
44618
+ return result;
44619
+ }
43963
44620
  function parseDasharrayPeriod(dasharray) {
43964
44621
  return dasharray.trim().split(/[\s,]+/).map(Number).filter((n) => !isNaN(n) && n > 0).reduce((sum, n) => sum + n, 0);
43965
44622
  }
@@ -44354,7 +45011,7 @@ registerRouter("straight", straightRouter);
44354
45011
  registerRouter("orthogonal", orthogonalRouter);
44355
45012
  registerRouter("bezier", bezierRouter);
44356
45013
  registerRouter("polyline", polylineRouter);
44357
- function compileSync(input, themeInput, forcedThemeName) {
45014
+ function compileSync(input, themeInput, forcedThemeName, icons) {
44358
45015
  const cleaned = stripComments(input);
44359
45016
  const { format, diagramType } = detect(cleaned);
44360
45017
  const module2 = getModule(diagramType);
@@ -44367,15 +45024,16 @@ function compileSync(input, themeInput, forcedThemeName) {
44367
45024
  const base = resolveTheme(themeInput ?? {}, getThemePreset(forcedThemeName ?? themeName));
44368
45025
  const withModuleDefaults = module2.defaultThemeOverride ? resolveTheme(module2.defaultThemeOverride, base) : base;
44369
45026
  const finalTheme = ir.themeOverride ? resolveTheme(ir.themeOverride, withModuleDefaults) : withModuleDefaults;
44370
- const result = module2.layout(ir, finalTheme);
45027
+ const layoutOptions = icons !== void 0 ? { icons } : void 0;
45028
+ const result = module2.layout(ir, finalTheme, layoutOptions);
44371
45029
  return ok(result);
44372
45030
  } catch (cause) {
44373
45031
  const message = cause instanceof Error ? cause.message : String(cause);
44374
45032
  return err("PARSE_ERROR", message, cause);
44375
45033
  }
44376
45034
  }
44377
- function renderSync(input, themeInput, rendererName = "svg", forcedThemeName) {
44378
- const compileResult = compileSync(input, themeInput, forcedThemeName);
45035
+ function renderSync(input, themeInput, rendererName = "svg", forcedThemeName, icons) {
45036
+ const compileResult = compileSync(input, themeInput, forcedThemeName, icons);
44379
45037
  if (!compileResult.ok) return compileResult;
44380
45038
  const renderer = getRenderer(rendererName);
44381
45039
  if (!renderer) {
@@ -44565,6 +45223,341 @@ function resolveCliTheme(args, inputDir) {
44565
45223
  return void 0;
44566
45224
  }
44567
45225
 
45226
+ // src/icon-resolve.ts
45227
+ var import_node_fs3 = require("node:fs");
45228
+ var import_node_path4 = require("node:path");
45229
+
45230
+ // ../src/icons/discover.ts
45231
+ var import_node_fs2 = require("node:fs");
45232
+ var import_node_path3 = require("node:path");
45233
+
45234
+ // ../src/icons/validate.ts
45235
+ var TOP_LEVEL_KEYS2 = /* @__PURE__ */ new Set([
45236
+ "prefix",
45237
+ "icons",
45238
+ "aliases",
45239
+ "width",
45240
+ "height",
45241
+ "left",
45242
+ "top"
45243
+ ]);
45244
+ var ICON_DATA_KEYS = /* @__PURE__ */ new Set([
45245
+ "body",
45246
+ "width",
45247
+ "height",
45248
+ "left",
45249
+ "top",
45250
+ "rotate",
45251
+ "hFlip",
45252
+ "vFlip"
45253
+ ]);
45254
+ var ICON_ALIAS_KEYS = /* @__PURE__ */ new Set([
45255
+ "parent",
45256
+ "rotate",
45257
+ "hFlip",
45258
+ "vFlip",
45259
+ "width",
45260
+ "height",
45261
+ "left",
45262
+ "top"
45263
+ ]);
45264
+ var PREFIX_RE2 = /^[a-z][a-z0-9-]*$/;
45265
+ var NAME_RE2 = /^[a-z0-9][a-z0-9-]*$/;
45266
+ var VALID_ROTATE = /* @__PURE__ */ new Set([0, 1, 2, 3]);
45267
+ function isPlainObject2(v) {
45268
+ return v !== null && typeof v === "object" && !Array.isArray(v);
45269
+ }
45270
+ function fail2(message) {
45271
+ return err("ICON_VALIDATION_ERROR", message);
45272
+ }
45273
+ function validateIconData(iconName, obj) {
45274
+ const ctx = `icons["${iconName}"]`;
45275
+ if (!isPlainObject2(obj)) {
45276
+ return fail2(`${ctx} must be a plain object`);
45277
+ }
45278
+ for (const key of Object.keys(obj)) {
45279
+ if (!ICON_DATA_KEYS.has(key)) {
45280
+ return fail2(`Unknown key in ${ctx}: "${key}"`);
45281
+ }
45282
+ }
45283
+ if (!("body" in obj)) {
45284
+ return fail2(`${ctx} is missing required field "body"`);
45285
+ }
45286
+ const body = obj["body"];
45287
+ if (typeof body !== "string" || body.length === 0) {
45288
+ return fail2(`${ctx}.body must be a non-empty string, got ${JSON.stringify(body)}`);
45289
+ }
45290
+ for (const dim of ["width", "height"]) {
45291
+ if (dim in obj) {
45292
+ const val = obj[dim];
45293
+ if (typeof val !== "number" || val <= 0) {
45294
+ return fail2(`${ctx}.${dim} must be a positive number, got ${JSON.stringify(val)}`);
45295
+ }
45296
+ }
45297
+ }
45298
+ for (const origin of ["left", "top"]) {
45299
+ if (origin in obj) {
45300
+ const val = obj[origin];
45301
+ if (typeof val !== "number") {
45302
+ return fail2(`${ctx}.${origin} must be a number, got ${JSON.stringify(val)}`);
45303
+ }
45304
+ }
45305
+ }
45306
+ if ("rotate" in obj) {
45307
+ const val = obj["rotate"];
45308
+ if (!VALID_ROTATE.has(val)) {
45309
+ return fail2(`${ctx}.rotate must be 0, 1, 2, or 3, got ${JSON.stringify(val)}`);
45310
+ }
45311
+ }
45312
+ for (const flip2 of ["hFlip", "vFlip"]) {
45313
+ if (flip2 in obj) {
45314
+ const val = obj[flip2];
45315
+ if (typeof val !== "boolean") {
45316
+ return fail2(`${ctx}.${flip2} must be a boolean, got ${JSON.stringify(val)}`);
45317
+ }
45318
+ }
45319
+ }
45320
+ return ok(obj);
45321
+ }
45322
+ function validateIconAlias(aliasName, obj) {
45323
+ const ctx = `aliases["${aliasName}"]`;
45324
+ if (!isPlainObject2(obj)) {
45325
+ return fail2(`${ctx} must be a plain object`);
45326
+ }
45327
+ for (const key of Object.keys(obj)) {
45328
+ if (!ICON_ALIAS_KEYS.has(key)) {
45329
+ return fail2(`Unknown key in ${ctx}: "${key}"`);
45330
+ }
45331
+ }
45332
+ if (!("parent" in obj)) {
45333
+ return fail2(`${ctx} is missing required field "parent"`);
45334
+ }
45335
+ const parent = obj["parent"];
45336
+ if (typeof parent !== "string" || parent.length === 0) {
45337
+ return fail2(`${ctx}.parent must be a non-empty string, got ${JSON.stringify(parent)}`);
45338
+ }
45339
+ if ("rotate" in obj) {
45340
+ const val = obj["rotate"];
45341
+ if (!VALID_ROTATE.has(val)) {
45342
+ return fail2(`${ctx}.rotate must be 0, 1, 2, or 3, got ${JSON.stringify(val)}`);
45343
+ }
45344
+ }
45345
+ for (const flip2 of ["hFlip", "vFlip"]) {
45346
+ if (flip2 in obj) {
45347
+ const val = obj[flip2];
45348
+ if (typeof val !== "boolean") {
45349
+ return fail2(`${ctx}.${flip2} must be a boolean, got ${JSON.stringify(val)}`);
45350
+ }
45351
+ }
45352
+ }
45353
+ for (const dim of ["width", "height"]) {
45354
+ if (dim in obj) {
45355
+ const val = obj[dim];
45356
+ if (typeof val !== "number" || val <= 0) {
45357
+ return fail2(`${ctx}.${dim} must be a positive number, got ${JSON.stringify(val)}`);
45358
+ }
45359
+ }
45360
+ }
45361
+ for (const origin of ["left", "top"]) {
45362
+ if (origin in obj) {
45363
+ const val = obj[origin];
45364
+ if (typeof val !== "number") {
45365
+ return fail2(`${ctx}.${origin} must be a number, got ${JSON.stringify(val)}`);
45366
+ }
45367
+ }
45368
+ }
45369
+ return ok(obj);
45370
+ }
45371
+ function validateIconPack(json) {
45372
+ if (!isPlainObject2(json)) {
45373
+ return fail2(
45374
+ `IconifyJSON must be a non-null plain object, got ${json === null ? "null" : Array.isArray(json) ? "array" : typeof json}`
45375
+ );
45376
+ }
45377
+ for (const key of Object.keys(json)) {
45378
+ if (!TOP_LEVEL_KEYS2.has(key)) {
45379
+ return fail2(`Unknown top-level key: "${key}"`);
45380
+ }
45381
+ }
45382
+ if (!("prefix" in json)) {
45383
+ return fail2('Missing required field "prefix"');
45384
+ }
45385
+ const prefix = json["prefix"];
45386
+ if (typeof prefix !== "string") {
45387
+ return fail2(`"prefix" must be a string, got ${JSON.stringify(prefix)}`);
45388
+ }
45389
+ if (!PREFIX_RE2.test(prefix)) {
45390
+ return fail2(
45391
+ `"prefix" must match ^[a-z][a-z0-9-]*$ (lowercase letter start, then lowercase alnum/hyphens), got ${JSON.stringify(prefix)}`
45392
+ );
45393
+ }
45394
+ if (!("icons" in json)) {
45395
+ return fail2('Missing required field "icons"');
45396
+ }
45397
+ const iconsRaw = json["icons"];
45398
+ if (!isPlainObject2(iconsRaw)) {
45399
+ return fail2('"icons" must be a plain object');
45400
+ }
45401
+ const iconNames = Object.keys(iconsRaw);
45402
+ if (iconNames.length === 0) {
45403
+ return fail2('"icons" must contain at least one icon entry');
45404
+ }
45405
+ const icons = {};
45406
+ for (const name of iconNames) {
45407
+ if (!NAME_RE2.test(name)) {
45408
+ return fail2(
45409
+ `Icon name ${JSON.stringify(name)} must match ^[a-z0-9][a-z0-9-]*$ (lowercase alnum start, then lowercase alnum/hyphens)`
45410
+ );
45411
+ }
45412
+ const r = validateIconData(name, iconsRaw[name]);
45413
+ if (!r.ok) return r;
45414
+ icons[name] = r.value;
45415
+ }
45416
+ let aliases;
45417
+ if ("aliases" in json) {
45418
+ const aliasesRaw = json["aliases"];
45419
+ if (!isPlainObject2(aliasesRaw)) {
45420
+ return fail2('"aliases" must be a plain object');
45421
+ }
45422
+ aliases = {};
45423
+ for (const aliasName of Object.keys(aliasesRaw)) {
45424
+ if (!NAME_RE2.test(aliasName)) {
45425
+ return fail2(
45426
+ `Alias name ${JSON.stringify(aliasName)} must match ^[a-z0-9][a-z0-9-]*$`
45427
+ );
45428
+ }
45429
+ const r = validateIconAlias(aliasName, aliasesRaw[aliasName]);
45430
+ if (!r.ok) return r;
45431
+ aliases[aliasName] = r.value;
45432
+ }
45433
+ }
45434
+ for (const dim of ["width", "height"]) {
45435
+ if (dim in json) {
45436
+ const val = json[dim];
45437
+ if (typeof val !== "number" || val <= 0) {
45438
+ return fail2(`"${dim}" must be a positive number, got ${JSON.stringify(val)}`);
45439
+ }
45440
+ }
45441
+ }
45442
+ for (const origin of ["left", "top"]) {
45443
+ if (origin in json) {
45444
+ const val = json[origin];
45445
+ if (typeof val !== "number") {
45446
+ return fail2(`"${origin}" must be a number, got ${JSON.stringify(val)}`);
45447
+ }
45448
+ }
45449
+ }
45450
+ const result = {
45451
+ prefix,
45452
+ icons,
45453
+ ...aliases !== void 0 ? { aliases } : {},
45454
+ ..."width" in json ? { width: json["width"] } : {},
45455
+ ..."height" in json ? { height: json["height"] } : {},
45456
+ ..."left" in json ? { left: json["left"] } : {},
45457
+ ..."top" in json ? { top: json["top"] } : {}
45458
+ };
45459
+ return ok(result);
45460
+ }
45461
+
45462
+ // ../src/icons/discover.ts
45463
+ var ICON_SUFFIX = ".triton-icons.json";
45464
+ function discoverIconPacks(dir) {
45465
+ const map = /* @__PURE__ */ new Map();
45466
+ const warnings = [];
45467
+ let entries;
45468
+ try {
45469
+ entries = (0, import_node_fs2.readdirSync)(dir);
45470
+ } catch (cause) {
45471
+ warnings.push(`Cannot read icons directory "${dir}": ${String(cause)}`);
45472
+ return { map, warnings };
45473
+ }
45474
+ const iconFiles = entries.filter((e) => e.endsWith(ICON_SUFFIX));
45475
+ for (const filename of iconFiles) {
45476
+ const filePath = (0, import_node_path3.join)(dir, filename);
45477
+ let raw;
45478
+ try {
45479
+ raw = (0, import_node_fs2.readFileSync)(filePath, "utf8");
45480
+ } catch (cause) {
45481
+ warnings.push(`Cannot read icon pack file "${filePath}": ${String(cause)}`);
45482
+ continue;
45483
+ }
45484
+ let parsed;
45485
+ try {
45486
+ parsed = JSON.parse(raw);
45487
+ } catch (cause) {
45488
+ warnings.push(`Invalid JSON in icon pack file "${filePath}": ${String(cause)}`);
45489
+ continue;
45490
+ }
45491
+ const result = validateIconPack(parsed);
45492
+ if (!result.ok) {
45493
+ warnings.push(`Icon pack file "${filePath}" failed validation: ${result.error.message}`);
45494
+ continue;
45495
+ }
45496
+ const pack = result.value;
45497
+ if (map.has(pack.prefix)) {
45498
+ warnings.push(
45499
+ `Duplicate icon pack prefix "${pack.prefix}": "${filename}" overrides an earlier definition`
45500
+ );
45501
+ }
45502
+ map.set(pack.prefix, pack);
45503
+ }
45504
+ return { map, warnings };
45505
+ }
45506
+ function findTritonIconsDir(startDir) {
45507
+ const MAX_LEVELS = 10;
45508
+ let current = (0, import_node_path3.resolve)(startDir);
45509
+ for (let level = 0; level < MAX_LEVELS; level++) {
45510
+ const candidate = (0, import_node_path3.join)(current, ".triton", "icons");
45511
+ try {
45512
+ if ((0, import_node_fs2.existsSync)(candidate) && (0, import_node_fs2.statSync)(candidate).isDirectory()) {
45513
+ return candidate;
45514
+ }
45515
+ } catch {
45516
+ }
45517
+ const parent = (0, import_node_path3.resolve)((0, import_node_path3.join)(current, ".."));
45518
+ if (parent === current) break;
45519
+ current = parent;
45520
+ }
45521
+ return void 0;
45522
+ }
45523
+
45524
+ // src/icon-resolve.ts
45525
+ function resolveCliIcons(args, inputDir) {
45526
+ const merged = /* @__PURE__ */ new Map();
45527
+ const autoDir = findTritonIconsDir(inputDir);
45528
+ if (autoDir) {
45529
+ const { map, warnings } = discoverIconPacks(autoDir);
45530
+ for (const [prefix, pack] of map) merged.set(prefix, pack);
45531
+ for (const w of warnings) console.error(`warning: ${w}`);
45532
+ }
45533
+ if (args.iconsDir) {
45534
+ const { map, warnings } = discoverIconPacks((0, import_node_path4.resolve)(args.iconsDir));
45535
+ for (const [prefix, pack] of map) merged.set(prefix, pack);
45536
+ for (const w of warnings) console.error(`warning: ${w}`);
45537
+ }
45538
+ if (args.iconPack) {
45539
+ const packPath = (0, import_node_path4.resolve)(args.iconPack);
45540
+ let raw;
45541
+ try {
45542
+ raw = (0, import_node_fs3.readFileSync)(packPath, "utf8");
45543
+ } catch (cause) {
45544
+ throw new Error(`--icon-pack: cannot read "${packPath}": ${cause.message}`);
45545
+ }
45546
+ let parsed;
45547
+ try {
45548
+ parsed = JSON.parse(raw);
45549
+ } catch (cause) {
45550
+ throw new Error(`--icon-pack: invalid JSON in "${packPath}": ${cause.message}`);
45551
+ }
45552
+ const result = validateIconPack(parsed);
45553
+ if (!result.ok) {
45554
+ throw new Error(`--icon-pack: "${packPath}" failed validation: ${result.error.message}`);
45555
+ }
45556
+ merged.set(result.value.prefix, result.value);
45557
+ }
45558
+ return merged;
45559
+ }
45560
+
44568
45561
  // src/cli.ts
44569
45562
  var import_meta = {};
44570
45563
  function parseArgs(argv) {
@@ -44573,6 +45566,8 @@ function parseArgs(argv) {
44573
45566
  let theme;
44574
45567
  let themeFile;
44575
45568
  let themesDir;
45569
+ let iconPack;
45570
+ let iconsDir;
44576
45571
  let scale = 1;
44577
45572
  let help = false;
44578
45573
  for (let i = 0; i < argv.length; i++) {
@@ -44591,6 +45586,12 @@ function parseArgs(argv) {
44591
45586
  case "--themes-dir":
44592
45587
  themesDir = argv[++i];
44593
45588
  break;
45589
+ case "--icon-pack":
45590
+ iconPack = argv[++i];
45591
+ break;
45592
+ case "--icons-dir":
45593
+ iconsDir = argv[++i];
45594
+ break;
44594
45595
  case "--scale":
44595
45596
  scale = Number(argv[++i]) || 1;
44596
45597
  break;
@@ -44602,7 +45603,7 @@ function parseArgs(argv) {
44602
45603
  positionals.push(a);
44603
45604
  }
44604
45605
  }
44605
- return { command: positionals.shift(), positionals, out, theme, themeFile, themesDir, scale, help };
45606
+ return { command: positionals.shift(), positionals, out, theme, themeFile, themesDir, iconPack, iconsDir, scale, help };
44606
45607
  }
44607
45608
  var USAGE = `triton-latex \u2014 render Triton diagrams to vector PDF for LaTeX.
44608
45609
 
@@ -44619,6 +45620,12 @@ Options:
44619
45620
  --themes-dir <dir> Directory of .triton-theme.json files to register; merged
44620
45621
  on top of auto-discovered .triton/themes/ (overrides on
44621
45622
  name collision). Use with --theme <name>.
45623
+ --icon-pack <path> Path to a .triton-icons.json icon pack file. Loaded at
45624
+ highest precedence (overrides --icons-dir and auto-discovery
45625
+ on duplicate prefix). Fails loudly on load or validation error.
45626
+ --icons-dir <dir> Directory of .triton-icons.json files to register; merged
45627
+ on top of auto-discovered .triton/icons/ (overrides on
45628
+ duplicate prefix). Use alongside --icon-pack as needed.
44622
45629
  --scale <number> Uniform scale for the PDF page box (default 1).
44623
45630
  -h, --help Show this help.
44624
45631
 
@@ -44628,46 +45635,54 @@ Theme resolution order:
44628
45635
  --theme <name> \u2192 look up name in registry, then fall back to built-in preset
44629
45636
  3. No theme flags \u2192 core uses diagram frontmatter / default preset
44630
45637
 
45638
+ Icon resolution order:
45639
+ 1. --icon-pack <path> \u2192 load that exact file (errors are fatal); highest precedence
45640
+ 2. --icons-dir <dir> \u2192 discover packs in dir, merged over auto-discovery
45641
+ 3. Auto-discovery \u2192 walk up from input file looking for .triton/icons/
45642
+ (No icon flags + no .triton/icons/ found \u2192 no custom icon packs loaded)
45643
+
44631
45644
  Examples:
44632
45645
  triton-latex render diagram.mmd -o figures/diagram.pdf
44633
45646
  triton-latex render diagram.mmd -o diagram.svg # SVG pass-through
44634
45647
  triton-latex render diagram.mmd -o out.pdf --theme-file my.triton-theme.json
44635
45648
  triton-latex render diagram.mmd -o out.pdf --themes-dir .triton/themes --theme acme
45649
+ triton-latex render diagram.mmd -o out.pdf --icon-pack icons/azure.triton-icons.json
45650
+ triton-latex render diagram.mmd -o out.pdf --icons-dir .triton/icons
44636
45651
  triton-latex render-dir diagrams/ -o figures/ # batch \u2192 *.pdf
44637
45652
  `;
44638
45653
  var DIAGRAM_EXTS = /* @__PURE__ */ new Set([".triton", ".mmd"]);
44639
- function renderToSvg(source, themeInput) {
44640
- const result = renderSync(source, themeInput);
45654
+ function renderToSvg(source, themeInput, icons) {
45655
+ const result = renderSync(source, themeInput, void 0, void 0, icons);
44641
45656
  if (!result.ok) {
44642
45657
  throw new Error(`${result.error.code}: ${result.error.message}`);
44643
45658
  }
44644
45659
  return result.value;
44645
45660
  }
44646
- async function renderFile(inputPath, outPath, themeInput, scale) {
44647
- const source = (0, import_node_fs2.readFileSync)(inputPath, "utf8");
44648
- const svg = renderToSvg(source, themeInput);
44649
- (0, import_node_fs2.mkdirSync)((0, import_node_path3.dirname)((0, import_node_path3.resolve)(outPath)), { recursive: true });
44650
- if ((0, import_node_path3.extname)(outPath).toLowerCase() === ".svg") {
44651
- (0, import_node_fs2.writeFileSync)(outPath, svg, "utf8");
45661
+ async function renderFile(inputPath, outPath, themeInput, icons, scale) {
45662
+ const source = (0, import_node_fs4.readFileSync)(inputPath, "utf8");
45663
+ const svg = renderToSvg(source, themeInput, icons);
45664
+ (0, import_node_fs4.mkdirSync)((0, import_node_path5.dirname)((0, import_node_path5.resolve)(outPath)), { recursive: true });
45665
+ if ((0, import_node_path5.extname)(outPath).toLowerCase() === ".svg") {
45666
+ (0, import_node_fs4.writeFileSync)(outPath, svg, "utf8");
44652
45667
  return;
44653
45668
  }
44654
45669
  const pdf = await svgToPdf(svg, { scale });
44655
- (0, import_node_fs2.writeFileSync)(outPath, pdf);
45670
+ (0, import_node_fs4.writeFileSync)(outPath, pdf);
44656
45671
  }
44657
- async function renderDir(srcDir, outDir, themeInput, scale) {
44658
- (0, import_node_fs2.mkdirSync)(outDir, { recursive: true });
44659
- const entries = (0, import_node_fs2.readdirSync)(srcDir).filter((f2) => {
44660
- const full = (0, import_node_path3.join)(srcDir, f2);
44661
- return (0, import_node_fs2.statSync)(full).isFile() && DIAGRAM_EXTS.has((0, import_node_path3.extname)(f2).toLowerCase());
45672
+ async function renderDir(srcDir, outDir, themeInput, icons, scale) {
45673
+ (0, import_node_fs4.mkdirSync)(outDir, { recursive: true });
45674
+ const entries = (0, import_node_fs4.readdirSync)(srcDir).filter((f2) => {
45675
+ const full = (0, import_node_path5.join)(srcDir, f2);
45676
+ return (0, import_node_fs4.statSync)(full).isFile() && DIAGRAM_EXTS.has((0, import_node_path5.extname)(f2).toLowerCase());
44662
45677
  });
44663
45678
  let rendered = 0;
44664
45679
  const failed = [];
44665
45680
  for (const file of entries) {
44666
- const inputPath = (0, import_node_path3.join)(srcDir, file);
44667
- const name = (0, import_node_path3.basename)(file, (0, import_node_path3.extname)(file));
44668
- const outPath = (0, import_node_path3.join)(outDir, `${name}.pdf`);
45681
+ const inputPath = (0, import_node_path5.join)(srcDir, file);
45682
+ const name = (0, import_node_path5.basename)(file, (0, import_node_path5.extname)(file));
45683
+ const outPath = (0, import_node_path5.join)(outDir, `${name}.pdf`);
44669
45684
  try {
44670
- await renderFile(inputPath, outPath, themeInput, scale);
45685
+ await renderFile(inputPath, outPath, themeInput, icons, scale);
44671
45686
  console.log(` \u2713 ${file} \u2192 ${name}.pdf`);
44672
45687
  rendered++;
44673
45688
  } catch (cause) {
@@ -44691,15 +45706,22 @@ async function main() {
44691
45706
  console.error(USAGE);
44692
45707
  return 1;
44693
45708
  }
44694
- const inputPath = (0, import_node_path3.resolve)(input);
45709
+ const inputPath = (0, import_node_path5.resolve)(input);
44695
45710
  let themeInput;
45711
+ let icons;
45712
+ try {
45713
+ themeInput = resolveCliTheme(args, (0, import_node_path5.dirname)(inputPath));
45714
+ } catch (e) {
45715
+ console.error(`error: ${e.message}`);
45716
+ return 1;
45717
+ }
44696
45718
  try {
44697
- themeInput = resolveCliTheme(args, (0, import_node_path3.dirname)(inputPath));
45719
+ icons = resolveCliIcons(args, (0, import_node_path5.dirname)(inputPath));
44698
45720
  } catch (e) {
44699
45721
  console.error(`error: ${e.message}`);
44700
45722
  return 1;
44701
45723
  }
44702
- await renderFile(inputPath, (0, import_node_path3.resolve)(args.out), themeInput, args.scale);
45724
+ await renderFile(inputPath, (0, import_node_path5.resolve)(args.out), themeInput, icons, args.scale);
44703
45725
  console.log(`\u2713 ${input} \u2192 ${args.out}`);
44704
45726
  return 0;
44705
45727
  }
@@ -44710,18 +45732,26 @@ async function main() {
44710
45732
  console.error(USAGE);
44711
45733
  return 1;
44712
45734
  }
44713
- const resolvedSrcDir = (0, import_node_path3.resolve)(srcDir);
45735
+ const resolvedSrcDir = (0, import_node_path5.resolve)(srcDir);
44714
45736
  let themeInput;
45737
+ let icons;
44715
45738
  try {
44716
45739
  themeInput = resolveCliTheme(args, resolvedSrcDir);
44717
45740
  } catch (e) {
44718
45741
  console.error(`error: ${e.message}`);
44719
45742
  return 1;
44720
45743
  }
45744
+ try {
45745
+ icons = resolveCliIcons(args, resolvedSrcDir);
45746
+ } catch (e) {
45747
+ console.error(`error: ${e.message}`);
45748
+ return 1;
45749
+ }
44721
45750
  const { rendered, failed } = await renderDir(
44722
45751
  resolvedSrcDir,
44723
- (0, import_node_path3.resolve)(args.out),
45752
+ (0, import_node_path5.resolve)(args.out),
44724
45753
  themeInput,
45754
+ icons,
44725
45755
  args.scale
44726
45756
  );
44727
45757
  console.log(`