@diagrammo/dgmo 0.85.0 → 0.87.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/advanced.d.ts +45 -9
  2. package/dist/advanced.js +83 -64
  3. package/dist/block.js +11 -23
  4. package/dist/chart-meta.js +3 -3
  5. package/dist/{chunk-FAV4RDVT.js → chunk-2A4DQAXG.js} +1 -1
  6. package/dist/{chunk-LRNIYQ6Y.js → chunk-33FQ6HNV.js} +1 -1
  7. package/dist/{chunk-JIPUBFAM.js → chunk-5KGM44TG.js} +2 -2
  8. package/dist/{chunk-23RWHHI5.js → chunk-5NU7NII2.js} +14 -2
  9. package/dist/{chunk-QJ2JOLFN.js → chunk-6I5UN4FD.js} +2 -2
  10. package/dist/{chunk-HMWZQ53A.js → chunk-7WGCQE2E.js} +1 -1
  11. package/dist/{chunk-NSS2EF5B.js → chunk-AAMCXQPP.js} +1 -1
  12. package/dist/{chunk-XD7XL3SF.js → chunk-AGO3PFGS.js} +1 -1
  13. package/dist/{chunk-JVRDKR5R.js → chunk-AQIBKTPG.js} +1 -1
  14. package/dist/{chunk-RYZNNXUV.js → chunk-AUS7V54P.js} +1 -1
  15. package/dist/{chunk-ITLPDLBH.js → chunk-B7CU2HW5.js} +3 -3
  16. package/dist/{chunk-X2VEJ5NT.js → chunk-BMUWF77V.js} +2 -2
  17. package/dist/{chunk-6HOVLE3H.js → chunk-BT2WH2XT.js} +1 -1
  18. package/dist/{chunk-3MXJMZAN.js → chunk-BV6PKJUS.js} +105 -28
  19. package/dist/{chunk-7256EOAE.js → chunk-CFBY77QJ.js} +129 -10
  20. package/dist/{chunk-BP4BT5TH.js → chunk-CLQIXD2C.js} +1 -1
  21. package/dist/{chunk-OZTDXMRQ.js → chunk-D4M25W6R.js} +1 -1
  22. package/dist/{chunk-A4PHPKNR.js → chunk-DAX42XVH.js} +1 -1
  23. package/dist/{chunk-C5FEPGSJ.js → chunk-DSG6GBUQ.js} +3 -3
  24. package/dist/{chunk-JLGN6S4B.js → chunk-EJS3K44P.js} +148 -80
  25. package/dist/{chunk-YWHGWLY6.js → chunk-FBKPSU3A.js} +5 -5
  26. package/dist/{chunk-5JO443MB.js → chunk-HAH5X345.js} +1 -1
  27. package/dist/{chunk-HBCAY3KR.js → chunk-HTNLLT34.js} +1 -1
  28. package/dist/{chunk-PEFPTQ3Z.js → chunk-HTPZDZKQ.js} +3 -3
  29. package/dist/{chunk-XXAZ5C4K.js → chunk-IJ27L3R4.js} +1 -1
  30. package/dist/{chunk-OGKP2XGJ.js → chunk-J7Q4VPBJ.js} +2 -2
  31. package/dist/{chunk-VDMG3MM4.js → chunk-JD4RHBNX.js} +1 -1
  32. package/dist/{chunk-HATTVAWX.js → chunk-LJFXC3IP.js} +1 -1
  33. package/dist/{chunk-REUEU5PU.js → chunk-LL6D3MES.js} +3 -3
  34. package/dist/{chunk-ULCB4BLF.js → chunk-LPXC4I4R.js} +19 -2
  35. package/dist/{chunk-BIQYWWJ2.js → chunk-LSQGJN5H.js} +2 -2
  36. package/dist/{chunk-T327J6CE.js → chunk-MSXRNVHB.js} +2 -2
  37. package/dist/{chunk-V3LJIPS4.js → chunk-N7XRBWXA.js} +3 -3
  38. package/dist/{chunk-UJRMARNX.js → chunk-NJIGYGZS.js} +19 -1
  39. package/dist/{chunk-WMIKC5XO.js → chunk-NPWVOFB3.js} +1 -1
  40. package/dist/{chunk-2QIGN7KL.js → chunk-O6MMQQLF.js} +9 -5
  41. package/dist/{chunk-MIZ46MOF.js → chunk-P5V63L35.js} +2 -2
  42. package/dist/{chunk-ADAGWVWJ.js → chunk-PJQZWJ5I.js} +70 -48
  43. package/dist/{chunk-RMAJIB6S.js → chunk-PUVTFUNH.js} +4 -4
  44. package/dist/{chunk-ETBXIKK6.js → chunk-Q2U5635V.js} +1 -1
  45. package/dist/chunk-QT3KDDXK.js +436 -0
  46. package/dist/{chunk-UNSN56OJ.js → chunk-R2K5L4UA.js} +1 -1
  47. package/dist/{chunk-SLMAAJPE.js → chunk-RGI64U3A.js} +1 -1
  48. package/dist/{chunk-ZGHV4QLK.js → chunk-RJNZHFNG.js} +1 -1
  49. package/dist/{chunk-FWNJDD4U.js → chunk-S7W75MIM.js} +3 -20
  50. package/dist/{chunk-ZUUNTOMG.js → chunk-UIUXIDBX.js} +1 -1
  51. package/dist/{chunk-XIYVGO24.js → chunk-UMRZPRAN.js} +3 -3
  52. package/dist/{chunk-67USWFFE.js → chunk-UY6TEJJH.js} +1 -1
  53. package/dist/{chunk-UGYZ5Q5Y.js → chunk-VJ2KROJ5.js} +1 -1
  54. package/dist/{chunk-PSH5DT26.js → chunk-WZ23JJ7U.js} +3 -3
  55. package/dist/{chunk-IIEI7VK5.js → chunk-XCKNFFKM.js} +2 -0
  56. package/dist/{chunk-Y7FTHOMD.js → chunk-XIFK423U.js} +129 -225
  57. package/dist/{chunk-LQSNWE3W.js → chunk-XUDGZJTJ.js} +3 -3
  58. package/dist/{chunk-D7D5YK4J.js → chunk-XVSJYAK7.js} +15 -3
  59. package/dist/{chunk-J2ICADUM.js → chunk-XWYR5T52.js} +3 -3
  60. package/dist/{chunk-QNKHJ5CK.js → chunk-YK4N6TBN.js} +4 -2
  61. package/dist/{chunk-NJS62BAG.js → chunk-YMG7JDEY.js} +17 -7
  62. package/dist/chunk-Z6DXWULM.js +23 -0
  63. package/dist/{chunk-PBEH52A2.js → chunk-ZNNVI5SR.js} +1 -1
  64. package/dist/cloud-reference.d.ts +11 -1
  65. package/dist/cloud-reference.js +1 -1
  66. package/dist/{dgmo-router-VILEOWQ2.js → dgmo-router-F2DSURTR.js} +4 -4
  67. package/dist/{dimensions-F3Y5T54V.js → dimensions-6QAWEGIR.js} +2 -2
  68. package/dist/{flowchart-renderer-TGQL4S4L.js → flowchart-renderer-THC6Y7EH.js} +8 -7
  69. package/dist/index.d.ts +68 -1
  70. package/dist/index.js +81 -13
  71. package/dist/{layout-WZCXK7DF.js → layout-5NPBHV5F.js} +2 -2
  72. package/dist/{layout-WXVGMSI3.js → layout-5VSMZPMG.js} +2 -2
  73. package/dist/{layout-CFTB7GKV.js → layout-BOVTLAOT.js} +7 -6
  74. package/dist/{layout-K6NI4VCS.js → layout-CUFA7XJD.js} +2 -2
  75. package/dist/{layout-6JARW64V.js → layout-EHTYSMV4.js} +6 -5
  76. package/dist/{layout-NB7TKAWN.js → layout-LUQKAGGT.js} +2 -2
  77. package/dist/{layout-YELNBVPC.js → layout-P6DTD4RT.js} +6 -5
  78. package/dist/{layout-PT7IKVCV.js → layout-QX5T6ZNE.js} +2 -2
  79. package/dist/layout-RANVNAKI.js +10 -0
  80. package/dist/{layout-FMKSENGL.js → layout-XUW444O5.js} +5 -4
  81. package/dist/{layout-search-GRJEBAUF.js → layout-search-VKSBUCDM.js} +67 -33
  82. package/dist/live-link-resolve.d.ts +21 -3
  83. package/dist/live-link-resolve.js +47 -17
  84. package/dist/{parser-6TXNMXNB.js → parser-XYY5NHP4.js} +2 -2
  85. package/dist/{renderer-YSH5EX54.js → renderer-222OTVQV.js} +3 -2
  86. package/dist/{renderer-DRLLZZ6P.js → renderer-2KVQGGTT.js} +5 -4
  87. package/dist/{renderer-E5EKGIX2.js → renderer-2OOPQ4CH.js} +4 -3
  88. package/dist/{renderer-OV3GUJRR.js → renderer-36JH4OMC.js} +4 -4
  89. package/dist/{renderer-G72GMBKA.js → renderer-3CTUWCO7.js} +7 -6
  90. package/dist/{renderer-XS42HEXW.js → renderer-3FF4QVGW.js} +4 -3
  91. package/dist/{renderer-R6VJDZFO.js → renderer-4BHOELCE.js} +4 -3
  92. package/dist/{renderer-EU27D4S6.js → renderer-4BIMRO4X.js} +5 -4
  93. package/dist/{renderer-HV6ZYJMC.js → renderer-4NZZ5J2F.js} +2 -2
  94. package/dist/{renderer-UGA5DGKR.js → renderer-A4LMOBZL.js} +9 -8
  95. package/dist/{renderer-3AOOLHJU.js → renderer-A6ACVK4X.js} +3 -2
  96. package/dist/{renderer-HWEGM72C.js → renderer-BICLPGAH.js} +2 -2
  97. package/dist/{renderer-ML2CLU25.js → renderer-DCFQDBGJ.js} +4 -3
  98. package/dist/{renderer-ADX4DWRJ.js → renderer-ELYPDPNF.js} +3 -2
  99. package/dist/{renderer-OXSLLQQC.js → renderer-KVAQE7PQ.js} +2 -2
  100. package/dist/{renderer-X4KFEKUK.js → renderer-LODEVN3V.js} +5 -4
  101. package/dist/{renderer-WUDVV363.js → renderer-NHPKNNBD.js} +6 -5
  102. package/dist/{renderer-TF3NTKP3.js → renderer-NX4YKWCJ.js} +2 -2
  103. package/dist/{renderer-P7LQBDU2.js → renderer-QM23SWAM.js} +2 -2
  104. package/dist/{renderer-5YOF2AHJ.js → renderer-R34GJL7U.js} +9 -8
  105. package/dist/{renderer-FBAFYSIQ.js → renderer-RAATRF6W.js} +3 -3
  106. package/dist/{renderer-FXX3XSNW.js → renderer-RENDISO5.js} +2 -2
  107. package/dist/{renderer-3F4K2X57.js → renderer-RMGN3Q7D.js} +2 -2
  108. package/dist/{renderer-FQAZ3KNU.js → renderer-SDUSBCJI.js} +4 -3
  109. package/dist/{renderer-OVDVFPAI.js → renderer-WH2HWE5Z.js} +5 -4
  110. package/dist/{renderer-J3O2KVTL.js → renderer-X5A5VIRD.js} +6 -5
  111. package/dist/{renderer-WRWVFEX7.js → renderer-XRALFCIN.js} +6 -4
  112. package/dist/{renderer-3XRDFNYF.js → renderer-YDAVCRTP.js} +5 -4
  113. package/dist/{renderer-5A6VWIVX.js → renderer-YIZ7G4HU.js} +5 -5
  114. package/dist/{state-renderer-B4ZF6ESS.js → state-renderer-5IQ4OJUI.js} +8 -7
  115. package/docs/language-reference.md +12 -12
  116. package/gallery/fixtures/journey-map.dgmo +28 -0
  117. package/gallery/fixtures/mindmap.dgmo +31 -0
  118. package/gallery/fixtures/pert.dgmo +27 -0
  119. package/gallery/fixtures/wireframe.dgmo +30 -0
  120. package/package.json +3 -3
  121. package/dist/chunk-WTTIODDV.js +0 -9
  122. package/dist/layout-JQ3IPJYR.js +0 -9
@@ -1,7 +1,13 @@
1
1
  import {
2
+ BOX_CLEAR_PAD,
3
+ EDGE_LABEL_FONT_SIZE,
2
4
  NODE_HEIGHT,
3
- NODE_WIDTH
4
- } from "./chunk-WTTIODDV.js";
5
+ NODE_WIDTH,
6
+ measureEdgeLabel
7
+ } from "./chunk-QT3KDDXK.js";
8
+ import {
9
+ measureText
10
+ } from "./chunk-KAO7JL4I.js";
5
11
 
6
12
  // src/boxes-and-lines/edge-clip.ts
7
13
  function rectBorderPoint(rect, toward) {
@@ -45,6 +51,8 @@ var DUMMY_THICK = 10;
45
51
  var MARGIN = 40;
46
52
  var GROUP_PAD = 16;
47
53
  var GROUP_LABEL_ZONE = 32;
54
+ var GROUP_TITLE_FONT_SIZE = 14;
55
+ var TITLE_CLEAR = 6;
48
56
  var GROUP_GAP = 24;
49
57
  var TIER_GAP = GROUP_LABEL_ZONE + 2 * GROUP_PAD;
50
58
  var W_REAL_REAL = 1;
@@ -297,6 +305,28 @@ function groupedTierCandidates(parsed, sizes, opts) {
297
305
  chain.push(e.target);
298
306
  chains.push({ edgeIdx: i, chain });
299
307
  }
308
+ const labelGap = Array.from({ length: maxRank + 1 }, () => 0);
309
+ if (opts?.reserveEdgeLabels) {
310
+ const leadWall = isTB ? GROUP_LABEL_ZONE : GROUP_PAD;
311
+ const wallsBetween = (a, b) => {
312
+ const pa = pathOf(a);
313
+ const pb = pathOf(b);
314
+ let shared = 0;
315
+ while (shared < pa.length && shared < pb.length && pa[shared] === pb[shared])
316
+ shared++;
317
+ return (pa.length - shared) * GROUP_PAD + (pb.length - shared) * leadWall;
318
+ };
319
+ for (const { e } of edges) {
320
+ if (!e.label) continue;
321
+ const rs = globalRank.get(e.source);
322
+ const rt = globalRank.get(e.target);
323
+ if (rt <= rs) continue;
324
+ const m = measureEdgeLabel(e.label, EDGE_LABEL_FONT_SIZE);
325
+ const need = (isTB ? m.height : m.width) + 2 * BOX_CLEAR_PAD + wallsBetween(e.source, e.target);
326
+ for (let r = rs + 1; r <= rt; r++)
327
+ labelGap[r] = Math.max(labelGap[r], need);
328
+ }
329
+ }
300
330
  const ranks = Array.from({ length: maxRank + 1 }, () => []);
301
331
  for (const n of node.values()) ranks[n.rank].push(n.id);
302
332
  const up = /* @__PURE__ */ new Map();
@@ -468,7 +498,11 @@ function groupedTierCandidates(parsed, sizes, opts) {
468
498
  const bandCenter = [];
469
499
  let acc = MARGIN;
470
500
  for (let r = 0; r <= maxRank; r++) {
471
- if (r > 0) acc += RANKSEP + (tierStartRanks.has(r) ? TIER_GAP : 0);
501
+ if (r > 0)
502
+ acc += Math.max(
503
+ RANKSEP + (tierStartRanks.has(r) ? TIER_GAP : 0),
504
+ labelGap[r]
505
+ );
472
506
  bandCenter[r] = acc + bandDepth[r] / 2;
473
507
  acc += bandDepth[r];
474
508
  }
@@ -527,6 +561,70 @@ function groupedTierCandidates(parsed, sizes, opts) {
527
561
  });
528
562
  const chainById = /* @__PURE__ */ new Map();
529
563
  for (const ch of chains) chainById.set(ch.edgeIdx, ch.chain);
564
+ const nodeBox = new Map(
565
+ layoutNodes.map((n) => [
566
+ n.label,
567
+ {
568
+ l: n.x - n.width / 2,
569
+ r: n.x + n.width / 2,
570
+ t: n.y - n.height / 2,
571
+ b: n.y + n.height / 2
572
+ }
573
+ ])
574
+ );
575
+ const depthOf = (label) => {
576
+ let d = 0;
577
+ let cur = label;
578
+ const guard = /* @__PURE__ */ new Set();
579
+ while (cur && !guard.has(cur)) {
580
+ guard.add(cur);
581
+ cur = groupByLabel.get(cur)?.parentGroup;
582
+ if (cur) d++;
583
+ }
584
+ return d;
585
+ };
586
+ const childGroups = /* @__PURE__ */ new Map();
587
+ for (const g of parsed.groups)
588
+ if (g.parentGroup)
589
+ (childGroups.get(g.parentGroup) ?? childGroups.set(g.parentGroup, []).get(g.parentGroup)).push(g.label);
590
+ const rectByGroup = /* @__PURE__ */ new Map();
591
+ const ordered = [...parsed.groups].sort(
592
+ (a, b) => depthOf(b.label) - depthOf(a.label)
593
+ );
594
+ const layoutGroups = [];
595
+ for (const grp of ordered) {
596
+ let l = Infinity, r = -Infinity, t = Infinity, bm = -Infinity;
597
+ const acc2 = (box) => {
598
+ l = Math.min(l, box.l);
599
+ r = Math.max(r, box.r);
600
+ t = Math.min(t, box.t);
601
+ bm = Math.max(bm, box.b);
602
+ };
603
+ for (const c of grp.children) {
604
+ const nb = nodeBox.get(c);
605
+ if (nb) acc2(nb);
606
+ }
607
+ for (const sub of childGroups.get(grp.label) ?? []) {
608
+ const sr = rectByGroup.get(sub);
609
+ if (sr) acc2(sr);
610
+ }
611
+ if (!Number.isFinite(l)) continue;
612
+ const x0 = l - GROUP_PAD;
613
+ const x1 = r + GROUP_PAD;
614
+ const y0 = t - GROUP_LABEL_ZONE;
615
+ const y1 = bm + GROUP_PAD;
616
+ rectByGroup.set(grp.label, { l: x0, r: x1, t: y0, b: y1 });
617
+ layoutGroups.push({
618
+ label: grp.label,
619
+ lineNumber: grp.lineNumber,
620
+ x: (x0 + x1) / 2,
621
+ y: (y0 + y1) / 2,
622
+ width: x1 - x0,
623
+ height: y1 - y0,
624
+ collapsed: false,
625
+ childCount: grp.children.length
626
+ });
627
+ }
530
628
  let minCross = Infinity, maxCross = -Infinity;
531
629
  for (const n of node.values()) {
532
630
  if (n.dummy) continue;
@@ -545,35 +643,69 @@ function groupedTierCandidates(parsed, sizes, opts) {
545
643
  side: sideOf(b),
546
644
  span: Math.abs(node.get(b.src).rank - node.get(b.tgt).rank)
547
645
  })).sort((a, b) => a.side - b.side || a.span - b.span);
548
- const sideCounts = /* @__PURE__ */ new Map();
549
- for (const b of backSorted)
550
- sideCounts.set(b.side, (sideCounts.get(b.side) ?? 0) + 1);
551
646
  const laneCounter = /* @__PURE__ */ new Map();
552
647
  const backPoints = /* @__PURE__ */ new Map();
648
+ const faceKey = (id, side) => `${id}\0${side}`;
649
+ const faceCount = /* @__PURE__ */ new Map();
650
+ for (const b of backSorted)
651
+ for (const id of [b.src, b.tgt])
652
+ faceCount.set(
653
+ faceKey(id, b.side),
654
+ (faceCount.get(faceKey(id, b.side)) ?? 0) + 1
655
+ );
656
+ const faceSeen = /* @__PURE__ */ new Map();
657
+ const portSlot = (id, side) => {
658
+ const key = faceKey(id, side);
659
+ const j = faceSeen.get(key) ?? 0;
660
+ faceSeen.set(key, j + 1);
661
+ return 2 * (j + 1) / (faceCount.get(key) + 1) - 1;
662
+ };
663
+ const titleStrips = layoutGroups.map((g) => {
664
+ const tw = measureText(g.label, GROUP_TITLE_FONT_SIZE, { bold: true });
665
+ const x0 = g.x - tw / 2 - TITLE_CLEAR;
666
+ const x1 = g.x + tw / 2 + TITLE_CLEAR;
667
+ const y0 = g.y - g.height / 2;
668
+ const y1 = y0 + GROUP_LABEL_ZONE;
669
+ return isTB ? { c0: x0, c1: x1, r0: y0, r1: y1 } : { c0: y0, c1: y1, r0: x0, r1: x1 };
670
+ });
671
+ const stubHitsTitle = (r, ca, cb) => titleStrips.some(
672
+ (t) => r > t.r0 && r < t.r1 && Math.min(ca, cb) < t.c1 && Math.max(ca, cb) > t.c0
673
+ );
674
+ const gapMid = (rank, dir) => {
675
+ const nb = rank + dir;
676
+ if (nb < 0 || nb > maxRank) return void 0;
677
+ const a = bandCenter[rank] + dir * bandDepth[rank] / 2;
678
+ const b = bandCenter[nb] - dir * bandDepth[nb] / 2;
679
+ return (a + b) / 2;
680
+ };
553
681
  for (const b of backSorted) {
554
682
  const s = b.side;
555
683
  const k = laneCounter.get(s) ?? 0;
556
684
  laneCounter.set(s, k + 1);
557
- const K = sideCounts.get(s);
558
685
  const src = node.get(b.src);
559
686
  const tgt = node.get(b.tgt);
560
687
  const laneC = s > 0 ? maxCross + GAP + k * LANE : minCross - GAP - k * LANE;
561
688
  const srcCtr = bandCenter[src.rank];
562
689
  const tgtCtr = bandCenter[tgt.rank];
563
- const frac = K > 1 ? (k + 1) / (K + 1) : 0;
564
- const srcR = srcCtr - frac * faceLim(src.depth);
565
- const tgtR = tgtCtr + frac * faceLim(tgt.depth);
690
+ const dir = srcCtr >= tgtCtr ? 1 : -1;
691
+ const srcR = srcCtr + dir * portSlot(b.src, s) * faceLim(src.depth);
692
+ const tgtR = tgtCtr - dir * portSlot(b.tgt, s) * faceLim(tgt.depth);
566
693
  const m = (c, rr) => isTB ? { x: c, y: rr } : { x: rr, y: c };
567
694
  const off = 10;
568
695
  const srcEdgeC = src.cross + s * (src.thick / 2 + off);
569
696
  const tgtEdgeC = tgt.cross + s * (tgt.thick / 2 + off);
697
+ const end = (n, ctr, r, edgeC, toward) => {
698
+ if (stubHitsTitle(r, n.cross, laneC)) {
699
+ const g = gapMid(n.rank, toward);
700
+ if (g !== void 0 && !stubHitsTitle(g, n.cross, laneC))
701
+ return [m(n.cross, ctr), m(n.cross, g), m(laneC, g)];
702
+ }
703
+ return [m(n.cross, ctr), m(edgeC, r), m(laneC, r)];
704
+ };
705
+ const toTgt = tgt.rank >= src.rank ? 1 : -1;
570
706
  backPoints.set(b.edgeIdx, [
571
- m(src.cross, srcCtr),
572
- m(srcEdgeC, srcR),
573
- m(laneC, srcR),
574
- m(laneC, tgtR),
575
- m(tgtEdgeC, tgtR),
576
- m(tgt.cross, tgtCtr)
707
+ ...end(src, srcCtr, srcR, srcEdgeC, toTgt),
708
+ ...end(tgt, tgtCtr, tgtR, tgtEdgeC, -toTgt).reverse()
577
709
  ]);
578
710
  }
579
711
  const flatPoints = /* @__PURE__ */ new Map();
@@ -630,70 +762,6 @@ function groupedTierCandidates(parsed, sizes, opts) {
630
762
  metadata: e.metadata
631
763
  });
632
764
  }
633
- const nodeBox = new Map(
634
- layoutNodes.map((n) => [
635
- n.label,
636
- {
637
- l: n.x - n.width / 2,
638
- r: n.x + n.width / 2,
639
- t: n.y - n.height / 2,
640
- b: n.y + n.height / 2
641
- }
642
- ])
643
- );
644
- const depthOf = (label) => {
645
- let d = 0;
646
- let cur = label;
647
- const guard = /* @__PURE__ */ new Set();
648
- while (cur && !guard.has(cur)) {
649
- guard.add(cur);
650
- cur = groupByLabel.get(cur)?.parentGroup;
651
- if (cur) d++;
652
- }
653
- return d;
654
- };
655
- const childGroups = /* @__PURE__ */ new Map();
656
- for (const g of parsed.groups)
657
- if (g.parentGroup)
658
- (childGroups.get(g.parentGroup) ?? childGroups.set(g.parentGroup, []).get(g.parentGroup)).push(g.label);
659
- const rectByGroup = /* @__PURE__ */ new Map();
660
- const ordered = [...parsed.groups].sort(
661
- (a, b) => depthOf(b.label) - depthOf(a.label)
662
- );
663
- const layoutGroups = [];
664
- for (const grp of ordered) {
665
- let l = Infinity, r = -Infinity, t = Infinity, bm = -Infinity;
666
- const acc2 = (box) => {
667
- l = Math.min(l, box.l);
668
- r = Math.max(r, box.r);
669
- t = Math.min(t, box.t);
670
- bm = Math.max(bm, box.b);
671
- };
672
- for (const c of grp.children) {
673
- const nb = nodeBox.get(c);
674
- if (nb) acc2(nb);
675
- }
676
- for (const sub of childGroups.get(grp.label) ?? []) {
677
- const sr = rectByGroup.get(sub);
678
- if (sr) acc2(sr);
679
- }
680
- if (!Number.isFinite(l)) continue;
681
- const x0 = l - GROUP_PAD;
682
- const x1 = r + GROUP_PAD;
683
- const y0 = t - GROUP_LABEL_ZONE;
684
- const y1 = bm + GROUP_PAD;
685
- rectByGroup.set(grp.label, { l: x0, r: x1, t: y0, b: y1 });
686
- layoutGroups.push({
687
- label: grp.label,
688
- lineNumber: grp.lineNumber,
689
- x: (x0 + x1) / 2,
690
- y: (y0 + y1) / 2,
691
- width: x1 - x0,
692
- height: y1 - y0,
693
- collapsed: false,
694
- childCount: grp.children.length
695
- });
696
- }
697
765
  let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
698
766
  const ext = (x0, y0, x1, y1) => {
699
767
  minX = Math.min(minX, x0);
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  wrapDescriptionLines
3
- } from "./chunk-WMIKC5XO.js";
3
+ } from "./chunk-NPWVOFB3.js";
4
4
  import {
5
5
  renderNodeCard
6
- } from "./chunk-UNSN56OJ.js";
6
+ } from "./chunk-R2K5L4UA.js";
7
7
  import {
8
8
  renderInlineText
9
- } from "./chunk-FWNJDD4U.js";
9
+ } from "./chunk-S7W75MIM.js";
10
10
  import {
11
11
  formatDateLabel
12
- } from "./chunk-ULCB4BLF.js";
12
+ } from "./chunk-LPXC4I4R.js";
13
13
  import {
14
14
  CARD_RADIUS,
15
15
  HAIRLINE_DASH,
@@ -17,7 +17,7 @@ import {
17
17
  LABEL_FONT_SIZE,
18
18
  NODE_STROKE_WIDTH,
19
19
  SEPARATOR_GAP
20
- } from "./chunk-IIEI7VK5.js";
20
+ } from "./chunk-XCKNFFKM.js";
21
21
  import {
22
22
  layoutInlineHeader
23
23
  } from "./chunk-3DOQOXXI.js";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-5DH3KYFH.js";
9
9
  import {
10
10
  renderInlineText
11
- } from "./chunk-FWNJDD4U.js";
11
+ } from "./chunk-S7W75MIM.js";
12
12
  import {
13
13
  mix
14
14
  } from "./chunk-7HWY4QAJ.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-6EK55ART.js";
4
4
  import {
5
5
  noteBoxSize
6
- } from "./chunk-ZGHV4QLK.js";
6
+ } from "./chunk-RJNZHFNG.js";
7
7
 
8
8
  // src/utils/notes/build.ts
9
9
  function buildPlacedNotes(anchors, noteByNode, direction, collapsedNotes) {
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  layoutERDiagram
3
- } from "./chunk-FAV4RDVT.js";
3
+ } from "./chunk-2A4DQAXG.js";
4
4
  import {
5
5
  NOTE_BADGE_RADIUS,
6
6
  noteConnectorPoints,
7
7
  renderNoteBadge,
8
8
  renderNoteBox,
9
9
  renderNoteConnector
10
- } from "./chunk-5JO443MB.js";
10
+ } from "./chunk-HAH5X345.js";
11
11
  import {
12
12
  ScaleContext
13
13
  } from "./chunk-24YPR5EH.js";
@@ -15,7 +15,7 @@ import {
15
15
  EDGE_LABEL_KNOCKOUT_OPACITY,
16
16
  EDGE_STROKE_WIDTH,
17
17
  NODE_STROKE_WIDTH
18
- } from "./chunk-IIEI7VK5.js";
18
+ } from "./chunk-XCKNFFKM.js";
19
19
  import {
20
20
  layoutInlineHeader
21
21
  } from "./chunk-3DOQOXXI.js";
@@ -7,7 +7,7 @@ import {
7
7
  META_FONT_SIZE,
8
8
  META_LINE_HEIGHT,
9
9
  SEPARATOR_GAP
10
- } from "./chunk-IIEI7VK5.js";
10
+ } from "./chunk-XCKNFFKM.js";
11
11
  import {
12
12
  buildCoupleQuotient,
13
13
  rankClasses
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  renderInlineText
3
- } from "./chunk-FWNJDD4U.js";
3
+ } from "./chunk-S7W75MIM.js";
4
4
  import {
5
5
  ScaleContext
6
6
  } from "./chunk-24YPR5EH.js";
7
7
  import {
8
8
  CARD_RADIUS
9
- } from "./chunk-IIEI7VK5.js";
9
+ } from "./chunk-XCKNFFKM.js";
10
10
  import {
11
11
  serializeSvg
12
12
  } from "./chunk-LD2JSKU3.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-24YPR5EH.js";
4
4
  import {
5
5
  NODE_STROKE_WIDTH
6
- } from "./chunk-IIEI7VK5.js";
6
+ } from "./chunk-XCKNFFKM.js";
7
7
  import {
8
8
  TITLE_FONT_SIZE,
9
9
  TITLE_FONT_WEIGHT,
@@ -15,7 +15,7 @@ import {
15
15
  META_LINE_HEIGHT,
16
16
  NODE_STROKE_WIDTH,
17
17
  SEPARATOR_GAP
18
- } from "./chunk-IIEI7VK5.js";
18
+ } from "./chunk-XCKNFFKM.js";
19
19
  import {
20
20
  layoutInlineHeader
21
21
  } from "./chunk-3DOQOXXI.js";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  computeNodeText,
3
3
  layoutMindmap
4
- } from "./chunk-ZUUNTOMG.js";
4
+ } from "./chunk-UIUXIDBX.js";
5
5
  import {
6
6
  renderInlineText
7
- } from "./chunk-FWNJDD4U.js";
7
+ } from "./chunk-S7W75MIM.js";
8
8
  import {
9
9
  ScaleContext
10
10
  } from "./chunk-24YPR5EH.js";
@@ -14,7 +14,7 @@ import {
14
14
  EDGE_STROKE_WIDTH,
15
15
  HEADER_HEIGHT,
16
16
  NODE_STROKE_WIDTH
17
- } from "./chunk-IIEI7VK5.js";
17
+ } from "./chunk-XCKNFFKM.js";
18
18
  import {
19
19
  extractExportSvg,
20
20
  runInExportContainer
@@ -9,7 +9,7 @@ import {
9
9
  EDGE_DASH,
10
10
  GRID_DASH,
11
11
  scaleDash
12
- } from "./chunk-IIEI7VK5.js";
12
+ } from "./chunk-XCKNFFKM.js";
13
13
  import {
14
14
  createTooltip,
15
15
  hideTooltip,
@@ -54,6 +54,21 @@ import {
54
54
  themeBaseBg
55
55
  } from "./chunk-7HWY4QAJ.js";
56
56
 
57
+ // src/embed/escape.ts
58
+ var HTML_ENTITIES = {
59
+ "&": "&amp;",
60
+ "<": "&lt;",
61
+ ">": "&gt;",
62
+ '"': "&quot;",
63
+ "'": "&#39;"
64
+ };
65
+ function escapeHtml(s) {
66
+ return s.replace(/[&<>"']/g, (ch) => HTML_ENTITIES[ch] ?? ch);
67
+ }
68
+ function escapeAttr(s) {
69
+ return s.replace(/[&<>"']/g, (ch) => HTML_ENTITIES[ch] ?? ch);
70
+ }
71
+
57
72
  // src/timeline/renderer.ts
58
73
  import * as d3Scale from "d3-scale";
59
74
  import * as d3Selection from "d3-selection";
@@ -281,7 +296,7 @@ function hideEventDatesOnScale(g) {
281
296
  }
282
297
  function buildEventTooltipHtml(ev) {
283
298
  const datePart = ev.endDate ? `${formatDateLabel(ev.date)} \u2192 ${formatDateLabel(ev.endDate)}` : formatDateLabel(ev.date);
284
- return `<strong>${ev.label}</strong><br>${datePart}`;
299
+ return `<strong>${escapeHtml(ev.label)}</strong><br>${datePart}`;
285
300
  }
286
301
  function renderTimelineGroupLegend(g, groups, groupColorMap, textColor, palette, isDark, legendY, onHover, onLeave) {
287
302
  const PILL_H = 22;
@@ -1672,6 +1687,8 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
1672
1687
  }
1673
1688
 
1674
1689
  export {
1690
+ escapeHtml,
1691
+ escapeAttr,
1675
1692
  formatDateLabel,
1676
1693
  renderTimeline
1677
1694
  };
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-XBJJP2HN.js";
10
10
  import {
11
11
  renderInlineText
12
- } from "./chunk-FWNJDD4U.js";
12
+ } from "./chunk-S7W75MIM.js";
13
13
  import {
14
14
  ScaleContext
15
15
  } from "./chunk-24YPR5EH.js";
@@ -22,7 +22,7 @@ import {
22
22
  EDGE_LABEL_KNOCKOUT_OPACITY,
23
23
  EDGE_STROKE_WIDTH,
24
24
  NODE_STROKE_WIDTH
25
- } from "./chunk-IIEI7VK5.js";
25
+ } from "./chunk-XCKNFFKM.js";
26
26
  import {
27
27
  layoutInlineHeader
28
28
  } from "./chunk-3DOQOXXI.js";
@@ -96,7 +96,7 @@ import {
96
96
  } from "./chunk-BAZT6CIF.js";
97
97
  import {
98
98
  parseDgmoChartType
99
- } from "./chunk-JVRDKR5R.js";
99
+ } from "./chunk-AQIBKTPG.js";
100
100
  import {
101
101
  parseRaci
102
102
  } from "./chunk-3RYBTEF5.js";
@@ -106,7 +106,7 @@ import {
106
106
  } from "./chunk-UNNJCSSQ.js";
107
107
  import {
108
108
  parseLiveLink
109
- } from "./chunk-HMWZQ53A.js";
109
+ } from "./chunk-7WGCQE2E.js";
110
110
  import {
111
111
  makeYearContext,
112
112
  parseDateToken,
@@ -6,13 +6,13 @@ import {
6
6
  } from "./chunk-DOXBS7F5.js";
7
7
  import {
8
8
  wrapNoteBody
9
- } from "./chunk-ZGHV4QLK.js";
9
+ } from "./chunk-RJNZHFNG.js";
10
10
  import {
11
11
  NOTE_BULLET_INDENT
12
12
  } from "./chunk-5DH3KYFH.js";
13
13
  import {
14
14
  renderInlineText
15
- } from "./chunk-FWNJDD4U.js";
15
+ } from "./chunk-S7W75MIM.js";
16
16
  import {
17
17
  ScaleContext
18
18
  } from "./chunk-24YPR5EH.js";
@@ -21,7 +21,7 @@ import {
21
21
  CONTAINER_RADIUS,
22
22
  GRID_DASH,
23
23
  NODE_STROKE_WIDTH
24
- } from "./chunk-IIEI7VK5.js";
24
+ } from "./chunk-XCKNFFKM.js";
25
25
  import {
26
26
  serializeSvg
27
27
  } from "./chunk-LD2JSKU3.js";
@@ -6,7 +6,7 @@ import {
6
6
  mapLegendConfig,
7
7
  mapLegendGroups,
8
8
  parsePathRings
9
- } from "./chunk-3MXJMZAN.js";
9
+ } from "./chunk-BV6PKJUS.js";
10
10
  import {
11
11
  parseClock
12
12
  } from "./chunk-WP2RLGDI.js";
@@ -270,6 +270,23 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
270
270
  }
271
271
  }
272
272
  );
273
+ drawMap(
274
+ container,
275
+ layout,
276
+ resolved,
277
+ palette,
278
+ isDark,
279
+ onClickItem,
280
+ exportDims
281
+ );
282
+ }
283
+ function renderMapLayout(container, layout, resolved, palette, isDark, onClickItem) {
284
+ d3Selection.select(container).selectAll(":not([data-d3-tooltip])").remove();
285
+ if (layout.width <= 0 || layout.height <= 0) return;
286
+ drawMap(container, layout, resolved, palette, isDark, onClickItem, void 0);
287
+ }
288
+ function drawMap(container, layout, resolved, palette, isDark, onClickItem, exportDims) {
289
+ const { width, height } = layout;
273
290
  const svg = d3Selection.select(container).append("svg").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY).style("background", layout.background);
274
291
  svg.append("rect").attr("width", width).attr("height", height).attr("fill", layout.background);
275
292
  const defs = svg.append("defs");
@@ -779,5 +796,6 @@ function emitText(g, x, y, text, anchor, color, halo, withHalo, fontSize, italic
779
796
 
780
797
  export {
781
798
  renderMap,
799
+ renderMapLayout,
782
800
  renderMapForExport
783
801
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  stripInlineMarkdown
3
- } from "./chunk-FWNJDD4U.js";
3
+ } from "./chunk-S7W75MIM.js";
4
4
 
5
5
  // src/utils/wrapped-desc.ts
6
6
  var BULLET_PREFIX = "\u2022 ";
@@ -4,18 +4,18 @@ import {
4
4
  renderNoteBadge,
5
5
  renderNoteBox,
6
6
  renderNoteConnector
7
- } from "./chunk-5JO443MB.js";
7
+ } from "./chunk-HAH5X345.js";
8
8
  import {
9
9
  appendArrowheadMarkers,
10
10
  appendReverseArrowheadMarkers
11
11
  } from "./chunk-XBJJP2HN.js";
12
12
  import {
13
13
  wrapDescriptionLines
14
- } from "./chunk-WMIKC5XO.js";
14
+ } from "./chunk-NPWVOFB3.js";
15
15
  import {
16
16
  renderInlineText,
17
17
  stripInlineMarkdown
18
- } from "./chunk-FWNJDD4U.js";
18
+ } from "./chunk-S7W75MIM.js";
19
19
  import {
20
20
  ScaleContext
21
21
  } from "./chunk-24YPR5EH.js";
@@ -25,9 +25,10 @@ import {
25
25
  CARD_RADIUS,
26
26
  CONTAINER_RADIUS,
27
27
  EDGE_LABEL_KNOCKOUT_OPACITY,
28
+ EDGE_LABEL_UNRESOLVED_KNOCKOUT_OPACITY,
28
29
  EDGE_STROKE_WIDTH,
29
30
  NODE_STROKE_WIDTH
30
- } from "./chunk-IIEI7VK5.js";
31
+ } from "./chunk-XCKNFFKM.js";
31
32
  import {
32
33
  layoutInlineHeader
33
34
  } from "./chunk-3DOQOXXI.js";
@@ -741,7 +742,10 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
741
742
  const lh = le.labelHeight ?? sEdgeLabelFontSize + 6;
742
743
  const lines = le.labelLines;
743
744
  const labelG = labelLayer.append("g").attr("class", "bl-edge-label").attr("data-line-number", String(le.lineNumber));
744
- labelG.append("rect").attr("x", lx - lw / 2).attr("y", ly - lh / 2).attr("width", lw).attr("height", lh).attr("rx", 3).attr("fill", palette.bg).attr("opacity", EDGE_LABEL_KNOCKOUT_OPACITY);
745
+ labelG.append("rect").attr("x", lx - lw / 2).attr("y", ly - lh / 2).attr("width", lw).attr("height", lh).attr("rx", 3).attr("fill", palette.bg).attr(
746
+ "opacity",
747
+ le.labelResolved === false ? EDGE_LABEL_UNRESOLVED_KNOCKOUT_OPACITY : EDGE_LABEL_KNOCKOUT_OPACITY
748
+ );
745
749
  const text = labelG.append("text").attr("x", lx).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", sEdgeLabelFontSize).attr("fill", palette.textMuted);
746
750
  const firstY = ly - (lines.length - 1) / 2 * labelLineHeight + sEdgeLabelFontSize / 3;
747
751
  lines.forEach((line2, k) => {
@@ -22,7 +22,7 @@ import {
22
22
  LABEL_FONT_SIZE,
23
23
  META_FONT_SIZE,
24
24
  NODE_STROKE_WIDTH
25
- } from "./chunk-IIEI7VK5.js";
25
+ } from "./chunk-XCKNFFKM.js";
26
26
  import {
27
27
  INLINE_HEADER_PAD,
28
28
  layoutInlineHeader
@@ -1579,7 +1579,7 @@ function renderScurveBlock(svg, data, args) {
1579
1579
  }));
1580
1580
  const curve = d3Shape.line().x((d) => d.x).y((d) => d.y).curve(d3Shape.curveMonotoneX)(points);
1581
1581
  if (curve) {
1582
- const clipId = `pert-scurve-clip-${Math.random().toString(36).slice(2, 10)}`;
1582
+ const clipId = `pert-scurve-clip-${[plotLeft, plotTop, plotW, plotH].map((v) => Math.round(v)).join("-")}`;
1583
1583
  block.append("clipPath").attr("id", clipId).append("rect").attr("x", plotLeft).attr("y", plotTop).attr("width", plotW).attr("height", plotH);
1584
1584
  block.append("path").attr("class", "pert-scurve-line").attr("d", curve).attr("fill", "none").attr("stroke", palette.colors.red).attr("stroke-width", 2).attr("clip-path", `url(#${clipId})`);
1585
1585
  }