@diagrammo/dgmo 0.90.0 → 0.91.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 (179) hide show
  1. package/dist/advanced.d.ts +156 -2
  2. package/dist/advanced.js +558 -115
  3. package/dist/block.d.ts +10 -1
  4. package/dist/block.js +46 -39
  5. package/dist/{calculator-PX3JHKAS.js → calculator-3LZUWOBK.js} +1 -1
  6. package/dist/chart-meta.js +12 -12
  7. package/dist/{charts-d3-QW4ERNUE.js → charts-d3-YXD6VGZQ.js} +3 -3
  8. package/dist/{chunk-64KSPLU2.js → chunk-273GB7WK.js} +4 -4
  9. package/dist/{chunk-GYBKG4Z6.js → chunk-2A4OFZ2Z.js} +2 -2
  10. package/dist/{chunk-YWRZG6GN.js → chunk-2AM6VA3A.js} +8 -8
  11. package/dist/{chunk-PQ5NW3QZ.js → chunk-2UV627GG.js} +4 -4
  12. package/dist/{chunk-AAC3XQWV.js → chunk-37QQXKFV.js} +8 -9
  13. package/dist/{chunk-RCBHL2B5.js → chunk-3LINSNJT.js} +112 -112
  14. package/dist/{chunk-5TZPIKNV.js → chunk-3SLRZKLB.js} +2 -2
  15. package/dist/{chunk-X3WYJ5T7.js → chunk-3YTAOMMN.js} +1 -1
  16. package/dist/{chunk-A5EE66RQ.js → chunk-53BJIOLF.js} +1 -1
  17. package/dist/{chunk-QRIW46LR.js → chunk-57L2JPP2.js} +6 -2
  18. package/dist/{chunk-IIOLFAGJ.js → chunk-5DIBB2QG.js} +51 -32
  19. package/dist/{chunk-7Z2VFRP5.js → chunk-5U6DXIMV.js} +47 -24
  20. package/dist/{chunk-5M6PMV5Z.js → chunk-5VPWIC6T.js} +3 -3
  21. package/dist/{chunk-SLO22FPS.js → chunk-634LDSN6.js} +1 -1
  22. package/dist/{chunk-G5BGW4BX.js → chunk-6NO3MNBC.js} +3 -3
  23. package/dist/{chunk-NUYWNKHH.js → chunk-6QEXWMBP.js} +12 -16
  24. package/dist/{chunk-POBNN5DP.js → chunk-7BBRSOKS.js} +2 -2
  25. package/dist/{chunk-NFWRIC2V.js → chunk-AR4QVMWG.js} +4 -1
  26. package/dist/{chunk-JRQ4LBQI.js → chunk-B6EUFLRP.js} +4 -4
  27. package/dist/{chunk-LNQDICFJ.js → chunk-CPGKRI7H.js} +5 -8
  28. package/dist/{chunk-ZNNVI5SR.js → chunk-CU2PZLZP.js} +53 -31
  29. package/dist/{chunk-LBRHDWEA.js → chunk-CVZBLHHW.js} +1 -1
  30. package/dist/{chunk-S4LLHDGK.js → chunk-CXIPV2FY.js} +3 -3
  31. package/dist/{chunk-ICYPGWOV.js → chunk-D7DXNQW5.js} +2 -2
  32. package/dist/{chunk-54YUDXGP.js → chunk-D7PP35BA.js} +1 -1
  33. package/dist/{chunk-RRBV4HIM.js → chunk-DLX7MEN4.js} +1 -1
  34. package/dist/{chunk-S7C32S2T.js → chunk-EDPDAUBL.js} +2 -2
  35. package/dist/{chunk-LC5LY5V2.js → chunk-EP7BT3HU.js} +1 -1
  36. package/dist/{chunk-ICZ7M6IZ.js → chunk-EQJ3U5EW.js} +1 -1
  37. package/dist/{chunk-K4GUO7FV.js → chunk-F2436VRR.js} +1 -1
  38. package/dist/{chunk-5M52RPAS.js → chunk-F26ZPBSF.js} +2 -2
  39. package/dist/{chunk-3BQCSQQJ.js → chunk-FJCYK4K3.js} +11 -11
  40. package/dist/{chunk-PXEUQ7EG.js → chunk-G22UV5AF.js} +4 -4
  41. package/dist/{chunk-CUY56BK4.js → chunk-G3EUQMV4.js} +3 -3
  42. package/dist/{chunk-I6FWHICD.js → chunk-GCDW3WAY.js} +5 -5
  43. package/dist/{chunk-WHRIN7N3.js → chunk-HFG7KQOY.js} +12 -14
  44. package/dist/{chunk-SVQDLYX7.js → chunk-HLVGZXM5.js} +1 -1
  45. package/dist/{chunk-3HBR3YAN.js → chunk-HSGWR2FL.js} +6 -6
  46. package/dist/{chunk-RNXX2GOQ.js → chunk-HWXUQCDY.js} +2 -2
  47. package/dist/{chunk-YE7D2S75.js → chunk-HYV6GSXM.js} +5 -2
  48. package/dist/{chunk-AHWA36O7.js → chunk-II4XJETG.js} +1 -1
  49. package/dist/{chunk-EB7AEM2H.js → chunk-IMKPFW67.js} +3 -3
  50. package/dist/{chunk-C4W62JZO.js → chunk-IS6WFBX7.js} +2 -2
  51. package/dist/{chunk-SMEVBJJJ.js → chunk-IUBCDNT2.js} +1 -1
  52. package/dist/{chunk-TQ644YGV.js → chunk-IWTUXGHN.js} +3 -3
  53. package/dist/{chunk-PNCKZFPE.js → chunk-J2SQNZ6D.js} +1 -1
  54. package/dist/{chunk-YKGUSW6D.js → chunk-JA2S7PHR.js} +7 -7
  55. package/dist/{chunk-IRVQT4GR.js → chunk-JJQWCI35.js} +2 -2
  56. package/dist/chunk-JJUDOR4I.js +110 -0
  57. package/dist/{chunk-VCHYS3RD.js → chunk-K3BYD3WU.js} +1 -1
  58. package/dist/{chunk-EEYQFJVK.js → chunk-KFXY5IW2.js} +2 -2
  59. package/dist/{chunk-Y6GQQ4Y2.js → chunk-LKR4FACF.js} +1 -3
  60. package/dist/{chunk-IJ27L3R4.js → chunk-MA42PIGJ.js} +1 -1
  61. package/dist/{chunk-GQVXYRPC.js → chunk-MI6SJJQU.js} +1 -1
  62. package/dist/{chunk-DXPT2HPH.js → chunk-MJKQ5ZYY.js} +2 -2
  63. package/dist/{chunk-J3ODKAWN.js → chunk-MNL547RV.js} +5 -5
  64. package/dist/{chunk-2EDJPHXQ.js → chunk-N254IJM2.js} +6 -6
  65. package/dist/{layout-search-YKUL4VBV.js → chunk-NWPMLX2V.js} +27 -30
  66. package/dist/{chunk-COPSI54O.js → chunk-PSGSFRRE.js} +2 -2
  67. package/dist/{chunk-FDRHBQUG.js → chunk-PUZ63XZM.js} +8 -8
  68. package/dist/{chunk-MIVSVEK4.js → chunk-PZVTFQI2.js} +2 -2
  69. package/dist/{chunk-W7QN5BC5.js → chunk-Q3N7PI3B.js} +180 -7
  70. package/dist/{chunk-HX2KJEPD.js → chunk-QKJ6MQXW.js} +1 -3
  71. package/dist/{chunk-NJYA4QSN.js → chunk-QVKTAU7P.js} +1 -1
  72. package/dist/{chunk-EK7JYFCL.js → chunk-R7BSF7Z7.js} +1 -1
  73. package/dist/{chunk-PIHAUVA4.js → chunk-RHXIUUWB.js} +1 -1
  74. package/dist/{chunk-GXP344YZ.js → chunk-RMTOZALT.js} +6 -3
  75. package/dist/{chunk-CYF2X3CG.js → chunk-ROCBGUJN.js} +7 -7
  76. package/dist/{chunk-RY5RRKYN.js → chunk-RVTYIGWZ.js} +3 -3
  77. package/dist/{chunk-NMKLX57Y.js → chunk-SKF7XLCM.js} +1 -1
  78. package/dist/{chunk-NP2SE6MQ.js → chunk-SMTWQ66K.js} +5 -5
  79. package/dist/{chunk-3AX6MCI6.js → chunk-SPQVER4T.js} +2 -2
  80. package/dist/{chunk-A5PUOHIS.js → chunk-SWBHH2UW.js} +1 -1
  81. package/dist/{chunk-7TF3QOOD.js → chunk-TIVMAITN.js} +14 -0
  82. package/dist/{chunk-4IYJOXGS.js → chunk-TLPY4ZBI.js} +604 -430
  83. package/dist/{chunk-U762HK4D.js → chunk-TPEYEOXA.js} +4 -4
  84. package/dist/{chunk-FS2LZBHG.js → chunk-UWJP4JSZ.js} +2 -2
  85. package/dist/{chunk-JX4RCC6B.js → chunk-V3KHZQPK.js} +2 -2
  86. package/dist/{chunk-RJYFHEP4.js → chunk-VGSSAMLA.js} +2 -2
  87. package/dist/{chunk-HIVJBESO.js → chunk-VMD2CYVP.js} +35 -36
  88. package/dist/{chunk-OSIUWQ3N.js → chunk-WNTPJZU7.js} +1 -1
  89. package/dist/{chunk-R2PTZ6QM.js → chunk-WTE27AJT.js} +7 -7
  90. package/dist/{chunk-OWJVSJLA.js → chunk-XLAREWBK.js} +2 -2
  91. package/dist/{chunk-NY56FM55.js → chunk-XLPJJ35N.js} +2 -2
  92. package/dist/{chunk-DNMICILX.js → chunk-XQTRGKQ3.js} +3 -3
  93. package/dist/{chunk-QOZ4RVQY.js → chunk-YZG37S7L.js} +3 -3
  94. package/dist/{chunk-62VWZ3SE.js → chunk-ZB2Q67NO.js} +10 -10
  95. package/dist/completion-registry.js +2 -2
  96. package/dist/{compute-JAP5E2E4.js → compute-2XWFVO7K.js} +1 -1
  97. package/dist/{dgmo-router-BJBXSZMV.js → dgmo-router-YHBMKTXY.js} +32 -32
  98. package/dist/{dimensions-AMA2S7RO.js → dimensions-QMGWJQTR.js} +3 -3
  99. package/dist/{flowchart-parser-ADZIFVCH.js → flowchart-parser-BLJ6RA53.js} +2 -2
  100. package/dist/{flowchart-renderer-CAG6ZNJ6.js → flowchart-renderer-FXRQKXAK.js} +10 -6
  101. package/dist/index.js +37 -37
  102. package/dist/{layout-5VSMZPMG.js → layout-5HCEF7VO.js} +1 -1
  103. package/dist/{layout-VQ2USZJ3.js → layout-6PLSBB5X.js} +2 -2
  104. package/dist/{layout-UIV56NUA.js → layout-B7PQRAMB.js} +1 -1
  105. package/dist/{layout-C6MKMOBI.js → layout-CCVCLZ6S.js} +1 -1
  106. package/dist/{layout-T2PGKQUQ.js → layout-CRUAP7JG.js} +2 -2
  107. package/dist/{layout-UFB2O4AO.js → layout-G42FDCF3.js} +2 -2
  108. package/dist/{layout-6OSF2UGP.js → layout-IV4H2FLB.js} +2 -2
  109. package/dist/{layout-4RRC7XU7.js → layout-JTNRSGOS.js} +6 -3
  110. package/dist/{layout-H4K54IW3.js → layout-RBLD5EGX.js} +6 -3
  111. package/dist/{layout-SW3XWYKC.js → layout-ROAVGBUC.js} +1 -1
  112. package/dist/{layout-QS2SESBU.js → layout-T2DQ4M77.js} +6 -2
  113. package/dist/{layout-ZP7XYVXF.js → layout-YKGQRFDM.js} +2 -4
  114. package/dist/layout-search-L75YOBME.js +42 -0
  115. package/dist/{parser-NAUUUCI3.js → parser-2XCDVLSN.js} +2 -2
  116. package/dist/{parser-ESZ5J5IJ.js → parser-4QNRCGU5.js} +2 -2
  117. package/dist/{parser-W2DWCCLO.js → parser-6NSQLPTS.js} +2 -2
  118. package/dist/{parser-223VOHSB.js → parser-6X4GGH2R.js} +2 -2
  119. package/dist/{parser-B2FWP7ZO.js → parser-D6YRVV75.js} +2 -2
  120. package/dist/{parser-T2RVIRDG.js → parser-EY3VJWBE.js} +2 -2
  121. package/dist/{parser-KFIK3EOO.js → parser-EYF4ZSZO.js} +2 -2
  122. package/dist/{parser-2PNV7UI3.js → parser-H2DJEAPG.js} +2 -2
  123. package/dist/{parser-OV2WDSEV.js → parser-ILWAA3QJ.js} +2 -2
  124. package/dist/{parser-FV6RGALQ.js → parser-KMFMNZYI.js} +2 -2
  125. package/dist/{parser-LGUT7KKH.js → parser-MDSVVCJP.js} +2 -2
  126. package/dist/{parser-HPR7G7F6.js → parser-QL4DEPVA.js} +3 -3
  127. package/dist/{parser-BJDQX4KV.js → parser-UEDPLM46.js} +2 -2
  128. package/dist/{parser-E5HFYL7B.js → parser-UL6WN6W5.js} +2 -2
  129. package/dist/{parser-5ZD2NKGU.js → parser-ULSUK36C.js} +2 -2
  130. package/dist/{parser-57YQEEMC.js → parser-UY3K4ROB.js} +1 -1
  131. package/dist/{parser-MYRGCK7Q.js → parser-UYQNNQKT.js} +2 -2
  132. package/dist/{parser-NJ5VEZA3.js → parser-VG747VR6.js} +2 -2
  133. package/dist/{parser-CA5WC5HF.js → parser-VK4PNDX4.js} +2 -2
  134. package/dist/{parser-JFNDS5E5.js → parser-X5FQ36KJ.js} +2 -2
  135. package/dist/{parser-I4HZVIHX.js → parser-XO5IAXMT.js} +2 -2
  136. package/dist/{parser-WFY4ZJUW.js → parser-YVHO2NRM.js} +2 -2
  137. package/dist/{parser-J3BM2AP2.js → parser-YWZGIU3C.js} +2 -2
  138. package/dist/{parser-4B2PIXHI.js → parser-ZFLSULFC.js} +2 -2
  139. package/dist/{parser-RARXAHC7.js → parser-ZR7JAKSW.js} +1 -1
  140. package/dist/{renderer-3QM2DK7I.js → renderer-43IVPARP.js} +3 -3
  141. package/dist/{renderer-GWH5ACJ5.js → renderer-4MEZYGU6.js} +2 -2
  142. package/dist/{renderer-A3PMPUO6.js → renderer-54GXA3UO.js} +5 -5
  143. package/dist/{renderer-W22GX72R.js → renderer-7EAWN7MC.js} +4 -4
  144. package/dist/{renderer-IO3D5E4E.js → renderer-7SEXPBGM.js} +3 -3
  145. package/dist/{renderer-B3CPMS5R.js → renderer-B7B7BQM3.js} +7 -7
  146. package/dist/{renderer-IG72UJHW.js → renderer-I2LYSQBV.js} +3 -3
  147. package/dist/{renderer-OPDSKCQS.js → renderer-J2LOMTBC.js} +3 -3
  148. package/dist/{renderer-TTKTBB4C.js → renderer-JUH6M3XF.js} +6 -6
  149. package/dist/{renderer-COSJM7UG.js → renderer-KY6O5JTX.js} +33 -33
  150. package/dist/{renderer-PLRMST57.js → renderer-LHTDI5RV.js} +4 -4
  151. package/dist/{renderer-3W5T3IU6.js → renderer-LWL3IJOF.js} +3 -3
  152. package/dist/{renderer-SBXCPA3S.js → renderer-NCIDGJ2R.js} +5 -5
  153. package/dist/{renderer-AM4VZSBQ.js → renderer-OPA4JJKX.js} +4 -4
  154. package/dist/{renderer-O5RQHGK2.js → renderer-QMNC7TGN.js} +4 -4
  155. package/dist/{renderer-UVFGW2O6.js → renderer-QQNPJGAP.js} +3 -3
  156. package/dist/{renderer-WQ654YT5.js → renderer-R7RK7FKI.js} +1 -1
  157. package/dist/{renderer-TMQNTUQS.js → renderer-RFP55AW7.js} +10 -7
  158. package/dist/{renderer-FXCVH2M5.js → renderer-S3NFBJCY.js} +10 -7
  159. package/dist/{renderer-OA5D3ZKB.js → renderer-SD4ZHHAR.js} +6 -4
  160. package/dist/{renderer-PSMRAL72.js → renderer-SE7Z5AOL.js} +3 -3
  161. package/dist/{renderer-ON4PTUHJ.js → renderer-T2WUA7MC.js} +5 -5
  162. package/dist/{renderer-KK5BU5K2.js → renderer-TWKEZ3DD.js} +3 -3
  163. package/dist/{renderer-MK47ESCB.js → renderer-U5PD72G7.js} +3 -3
  164. package/dist/{renderer-52CHSV6S.js → renderer-VCTKBUTR.js} +5 -5
  165. package/dist/{renderer-PXGCR7N4.js → renderer-VNZTWATB.js} +3 -3
  166. package/dist/{renderer-4Z7FRQ2A.js → renderer-YDNWK6RI.js} +1 -1
  167. package/dist/{renderer-B4KE3NM4.js → renderer-YDOWBIUB.js} +4 -4
  168. package/dist/{renderer-LD2H7WGP.js → renderer-YQPZ7O2C.js} +1 -1
  169. package/dist/{renderer-6OOJNEQE.js → renderer-ZQ77CM6Y.js} +4 -4
  170. package/dist/{renderer-radial-42LVSG74.js → renderer-radial-TNNEL3YN.js} +4 -4
  171. package/dist/{resolver-XSXE2TRX.js → resolver-6DJLZF6Y.js} +1 -1
  172. package/dist/{state-parser-ROKY5KSI.js → state-parser-NIIVOU2Y.js} +2 -2
  173. package/dist/{state-renderer-MMG23G4W.js → state-renderer-TVLEG32M.js} +11 -7
  174. package/package.json +1 -1
  175. package/dist/chunk-6EK55ART.js +0 -116
  176. package/dist/chunk-HTNLLT34.js +0 -72
  177. /package/dist/{chunk-3FCSOYN4.js → chunk-5P2L5QXE.js} +0 -0
  178. /package/dist/{chunk-HJRP6PXL.js → chunk-BQVTV4LB.js} +0 -0
  179. /package/dist/{chunk-LYRDIVSY.js → chunk-GLCMUTO5.js} +0 -0
@@ -1,15 +1,15 @@
1
+ import {
2
+ noteBoxSize
3
+ } from "./chunk-RJNZHFNG.js";
4
+ import {
5
+ NOTE_GAP
6
+ } from "./chunk-5DH3KYFH.js";
1
7
  import {
2
8
  LABEL_REACH_WIDE,
3
9
  NODE_HEIGHT,
4
10
  NODE_WIDTH,
5
11
  placeEdgeLabels
6
12
  } from "./chunk-QT3KDDXK.js";
7
- import {
8
- buildPlacedNotes
9
- } from "./chunk-HTNLLT34.js";
10
- import {
11
- noteCanvasShift
12
- } from "./chunk-6EK55ART.js";
13
13
  import {
14
14
  resolveNotes
15
15
  } from "./chunk-O753JUEZ.js";
@@ -18,6 +18,176 @@ import {
18
18
  wrapTextToWidth
19
19
  } from "./chunk-KAO7JL4I.js";
20
20
 
21
+ // src/utils/notes/place.ts
22
+ var NOTE_CLEAR = 14;
23
+ var intersects = (a, b, pad) => !(a.right + pad <= b.left || b.right + pad <= a.left || a.bottom + pad <= b.top || b.bottom + pad <= a.top);
24
+ function placeNotes(obstacles, requests, direction) {
25
+ const placements = /* @__PURE__ */ new Map();
26
+ const occupied = obstacles.map((p) => ({
27
+ left: p.x - p.width / 2,
28
+ top: p.y - p.height / 2,
29
+ right: p.x + p.width / 2,
30
+ bottom: p.y + p.height / 2
31
+ }));
32
+ for (const req of requests) {
33
+ if (req.collapsed) {
34
+ placements.set(req.key, {
35
+ collapsed: true,
36
+ side: "right",
37
+ x: 0,
38
+ y: 0
39
+ });
40
+ continue;
41
+ }
42
+ const p = req.node;
43
+ const cx = p.x;
44
+ const cy = p.y;
45
+ const nodeLeft = cx - p.width / 2;
46
+ const nodeRight = cx + p.width / 2;
47
+ const nodeTop = cy - p.height / 2;
48
+ const nodeBottom = cy + p.height / 2;
49
+ const { noteW, noteH } = req;
50
+ const rectFor = (side) => {
51
+ switch (side) {
52
+ case "right": {
53
+ const left = nodeRight + NOTE_GAP;
54
+ const top = cy - noteH / 2;
55
+ return { left, top, right: left + noteW, bottom: top + noteH };
56
+ }
57
+ case "left": {
58
+ const right = nodeLeft - NOTE_GAP;
59
+ const top = cy - noteH / 2;
60
+ return { left: right - noteW, top, right, bottom: top + noteH };
61
+ }
62
+ case "below": {
63
+ const left = cx - noteW / 2;
64
+ const top = nodeBottom + NOTE_GAP;
65
+ return { left, top, right: left + noteW, bottom: top + noteH };
66
+ }
67
+ case "above":
68
+ default: {
69
+ const left = cx - noteW / 2;
70
+ const bottom = nodeTop - NOTE_GAP;
71
+ return { left, top: bottom - noteH, right: left + noteW, bottom };
72
+ }
73
+ }
74
+ };
75
+ const order = direction === "LR" ? ["below", "above"] : ["right", "left"];
76
+ let chosen = null;
77
+ for (const side of order) {
78
+ const rect = rectFor(side);
79
+ if (!occupied.some((o) => intersects(rect, o, NOTE_CLEAR))) {
80
+ chosen = { rect, side };
81
+ break;
82
+ }
83
+ }
84
+ if (!chosen) {
85
+ const side = order[0];
86
+ let rect = rectFor(side);
87
+ const axisIsY = side === "above" || side === "below";
88
+ const outward = side === "below" || side === "right" ? 1 : -1;
89
+ for (let guard = 0; guard < 50; guard++) {
90
+ const blockers = occupied.filter(
91
+ (o) => intersects(rect, o, NOTE_CLEAR)
92
+ );
93
+ if (blockers.length === 0) break;
94
+ if (axisIsY && outward > 0) {
95
+ const top = Math.max(...blockers.map((b) => b.bottom)) + NOTE_CLEAR;
96
+ rect = { ...rect, top, bottom: top + noteH };
97
+ } else if (axisIsY) {
98
+ const bottom = Math.min(...blockers.map((b) => b.top)) - NOTE_CLEAR;
99
+ rect = { ...rect, bottom, top: bottom - noteH };
100
+ } else if (outward > 0) {
101
+ const left = Math.max(...blockers.map((b) => b.right)) + NOTE_CLEAR;
102
+ rect = { ...rect, left, right: left + noteW };
103
+ } else {
104
+ const right = Math.min(...blockers.map((b) => b.left)) - NOTE_CLEAR;
105
+ rect = { ...rect, right, left: right - noteW };
106
+ }
107
+ }
108
+ chosen = { rect, side };
109
+ }
110
+ occupied.push(chosen.rect);
111
+ placements.set(req.key, {
112
+ collapsed: false,
113
+ side: chosen.side,
114
+ x: chosen.rect.left - p.x,
115
+ y: chosen.rect.top - p.y
116
+ });
117
+ }
118
+ return placements;
119
+ }
120
+
121
+ // src/utils/notes/build.ts
122
+ function buildPlacedNotes(anchors, noteByNode, direction, collapsedNotes) {
123
+ const placed = /* @__PURE__ */ new Map();
124
+ if (noteByNode.size === 0) return placed;
125
+ const geoms = /* @__PURE__ */ new Map();
126
+ const requests = [];
127
+ for (const a of anchors) {
128
+ const note = noteByNode.get(a.id);
129
+ if (!note) continue;
130
+ const size = noteBoxSize(note.body);
131
+ geoms.set(a.id, {
132
+ noteW: size.width,
133
+ noteH: size.height,
134
+ ...note.color && { color: note.color },
135
+ lines: size.lines,
136
+ lineNumber: note.lineNumber,
137
+ endLineNumber: note.endLineNumber
138
+ });
139
+ requests.push({
140
+ key: a.id,
141
+ node: { x: a.x, y: a.y, width: a.width, height: a.height },
142
+ noteW: size.width,
143
+ noteH: size.height,
144
+ collapsed: collapsedNotes?.has(note.lineNumber) ?? false
145
+ });
146
+ }
147
+ const placements = placeNotes(
148
+ anchors.map((a) => ({ x: a.x, y: a.y, width: a.width, height: a.height })),
149
+ requests,
150
+ direction
151
+ );
152
+ for (const [id, g] of geoms) {
153
+ const p = placements.get(id);
154
+ placed.set(
155
+ id,
156
+ p.collapsed ? {
157
+ x: 0,
158
+ y: 0,
159
+ width: 0,
160
+ height: 0,
161
+ side: "right",
162
+ ...g.color && { color: g.color },
163
+ lines: [],
164
+ lineNumber: g.lineNumber,
165
+ endLineNumber: g.endLineNumber,
166
+ collapsed: true
167
+ } : {
168
+ x: p.x,
169
+ y: p.y,
170
+ width: g.noteW,
171
+ height: g.noteH,
172
+ side: p.side,
173
+ ...g.color && { color: g.color },
174
+ lines: g.lines,
175
+ lineNumber: g.lineNumber,
176
+ endLineNumber: g.endLineNumber
177
+ }
178
+ );
179
+ }
180
+ return placed;
181
+ }
182
+
183
+ // src/utils/notes/bounds.ts
184
+ function noteCanvasShift(minX, minY, margin = 20) {
185
+ return {
186
+ shiftX: minX < 0 ? margin - minX : 0,
187
+ shiftY: minY < 0 ? margin - minY : 0
188
+ };
189
+ }
190
+
21
191
  // src/boxes-and-lines/layout.ts
22
192
  var MARGIN = 40;
23
193
  var MAX_PARALLEL_EDGES = 5;
@@ -107,7 +277,7 @@ function computeNodeSize(node, reserveValueRow) {
107
277
  return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
108
278
  }
109
279
  async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
110
- const { layoutBoxesAndLinesSearch } = await import("./layout-search-YKUL4VBV.js");
280
+ const { layoutBoxesAndLinesSearch } = await import("./layout-search-L75YOBME.js");
111
281
  const searchOpts = {
112
282
  ...layoutOptions?.hideDescriptions !== void 0 && {
113
283
  hideDescriptions: layoutOptions.hideDescriptions
@@ -423,6 +593,9 @@ function applyParallelEdgeOffsets(layout) {
423
593
  }
424
594
 
425
595
  export {
596
+ placeNotes,
597
+ buildPlacedNotes,
598
+ noteCanvasShift,
426
599
  computeNodeSize,
427
600
  layoutBoxesAndLines
428
601
  };
@@ -44,9 +44,7 @@ function assignAutoTagColors(group, palette) {
44
44
  let chosen = cycle.find(
45
45
  (c) => !explicitHexes.has(c.hex.toLowerCase()) && !autoHexes.has(c.hex.toLowerCase())
46
46
  );
47
- if (!chosen) {
48
- chosen = cycle[autoHexes.size % cycle.length];
49
- }
47
+ chosen ??= cycle[autoHexes.size % cycle.length];
50
48
  autoHexes.add(chosen.hex.toLowerCase());
51
49
  entries[i] = { ...e, color: chosen.hex };
52
50
  }
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-ICLB27PZ.js";
7
7
  import {
8
8
  tagAttrKey
9
- } from "./chunk-HX2KJEPD.js";
9
+ } from "./chunk-QKJ6MQXW.js";
10
10
  import {
11
11
  CONTROLS_ICON_PATH,
12
12
  LEGEND_DOT_R,
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  isTagBlockHeading,
6
6
  matchTagBlockHeading
7
- } from "./chunk-HX2KJEPD.js";
7
+ } from "./chunk-QKJ6MQXW.js";
8
8
  import {
9
9
  makeDgmoError
10
10
  } from "./chunk-BYU54C3S.js";
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-24YPR5EH.js";
10
10
  import {
11
11
  renderIntegratedLegend
12
- } from "./chunk-NJYA4QSN.js";
12
+ } from "./chunk-QVKTAU7P.js";
13
13
  import {
14
14
  getMaxLegendReservedHeight
15
15
  } from "./chunk-NS7L7YKH.js";
@@ -20,7 +20,7 @@ import {
20
20
  tagAttrKey,
21
21
  validateTagGroupNames,
22
22
  validateTagValues
23
- } from "./chunk-HX2KJEPD.js";
23
+ } from "./chunk-QKJ6MQXW.js";
24
24
  import {
25
25
  AliasRegistry,
26
26
  BOXES_AND_LINES_REGISTRY,
@@ -585,7 +585,7 @@ function parseBoxesAndLines(content, palette) {
585
585
  validateTagGroupNames(result.tagGroups, pushWarning, (line, msg) => {
586
586
  const diag = makeDgmoError(line, msg);
587
587
  result.diagnostics.push(diag);
588
- if (!result.error) result.error = diag.message;
588
+ result.error ??= diag.message;
589
589
  });
590
590
  }
591
591
  const activeTagWarning = activeTagNoMatchMessage(
@@ -594,7 +594,10 @@ function parseBoxesAndLines(content, palette) {
594
594
  // The value metric is a legitimate `active-tag` target here (§13.9), named
595
595
  // by `box-metric` and defaulting to `Value` — but only when some box
596
596
  // actually carries a value, which is what the renderer gates on.
597
- result.nodes.some((n) => n.value !== void 0) ? [result.boxMetric?.trim() || "Value"] : [],
597
+ result.nodes.some((n) => n.value !== void 0) ? (
598
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- an empty metric name also falls back to 'Value'
599
+ [result.boxMetric?.trim() || "Value"]
600
+ ) : [],
598
601
  "the value metric"
599
602
  );
600
603
  if (activeTagWarning) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isTagBlockHeading
3
- } from "./chunk-HX2KJEPD.js";
3
+ } from "./chunk-QKJ6MQXW.js";
4
4
  import {
5
5
  OPTION_NOCOLON_RE,
6
6
  measureIndent,
@@ -254,7 +254,7 @@ function parseSegment(segment, lineNumber, indent, diagnostics) {
254
254
  const dropdownMatch = trimmed.match(DROPDOWN_RE);
255
255
  if (dropdownMatch) {
256
256
  const options = dropdownMatch[1].split("|").map((s) => s.trim()).filter(Boolean);
257
- const el = makeElement("dropdown", options[0] || "", lineNumber, indent);
257
+ const el = makeElement("dropdown", options[0] ?? "", lineNumber, indent);
258
258
  el.options = options;
259
259
  applyTrailingMeta(el, dropdownMatch[2]);
260
260
  return el;
@@ -270,7 +270,7 @@ function parseSegment(segment, lineNumber, indent, diagnostics) {
270
270
  )
271
271
  );
272
272
  const options = parenPipeMatch[1].split("|").map((s) => s.trim()).filter(Boolean);
273
- const el = makeElement("dropdown", options[0] || "", lineNumber, indent);
273
+ const el = makeElement("dropdown", options[0] ?? "", lineNumber, indent);
274
274
  el.options = options;
275
275
  return el;
276
276
  }
@@ -309,7 +309,7 @@ function parseSegment(segment, lineNumber, indent, diagnostics) {
309
309
  if (kwMatch) {
310
310
  const el = makeElement(
311
311
  kwMatch.type,
312
- kwMatch.param || "",
312
+ kwMatch.param ?? "",
313
313
  lineNumber,
314
314
  indent
315
315
  );
@@ -321,7 +321,7 @@ function parseSegment(segment, lineNumber, indent, diagnostics) {
321
321
  } else if (kwMatch.type === "chart") {
322
322
  el.chartHint = kwMatch.param || "line";
323
323
  } else if (kwMatch.type === "table") {
324
- const skelMatch = `table ${kwMatch.param || ""}`.match(TABLE_SKELETON_RE);
324
+ const skelMatch = `table ${kwMatch.param ?? ""}`.match(TABLE_SKELETON_RE);
325
325
  if (skelMatch) {
326
326
  el.tableRows = parseInt(skelMatch[1], 10);
327
327
  el.tableCols = parseInt(skelMatch[2], 10);
@@ -364,7 +364,7 @@ function parseSegment(segment, lineNumber, indent, diagnostics) {
364
364
  );
365
365
  const rawContent = trimmed.substring(1).trim();
366
366
  const options = rawContent.split("|").map((s) => s.trim()).filter(Boolean);
367
- const el = makeElement("dropdown", options[0] || "", lineNumber, indent);
367
+ const el = makeElement("dropdown", options[0] ?? "", lineNumber, indent);
368
368
  el.options = options;
369
369
  return el;
370
370
  }
@@ -556,7 +556,7 @@ function parseWireframe(content) {
556
556
  topNode.tableHeaders = cells;
557
557
  }
558
558
  } else {
559
- if (!topNode.tableData) topNode.tableData = [];
559
+ topNode.tableData ??= [];
560
560
  topNode.tableData.push(cells);
561
561
  }
562
562
  continue;
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-ABP5BUD6.js";
12
12
  import {
13
13
  renderIntegratedLegend
14
- } from "./chunk-NJYA4QSN.js";
14
+ } from "./chunk-QVKTAU7P.js";
15
15
  import {
16
16
  layoutInlineHeader
17
17
  } from "./chunk-CNUN5GO6.js";
@@ -30,7 +30,7 @@ import {
30
30
  import {
31
31
  resolveTagColor,
32
32
  tagAttrKey
33
- } from "./chunk-HX2KJEPD.js";
33
+ } from "./chunk-QKJ6MQXW.js";
34
34
  import {
35
35
  LEGEND_GROUP_GAP
36
36
  } from "./chunk-I6GGMCTV.js";
@@ -86,7 +86,7 @@ function paintForAccent(palette, isDark, accent, fillMode) {
86
86
  };
87
87
  }
88
88
  function paintFor(palette, isDark, sideColor, fillMode) {
89
- const accent = sideColor && resolveColor(sideColor, palette) || sideColor || getSeriesColors(palette)[0];
89
+ const accent = (sideColor && resolveColor(sideColor, palette)) ?? sideColor ?? getSeriesColors(palette)[0];
90
90
  return paintForAccent(palette, isDark, accent, fillMode);
91
91
  }
92
92
  function resolveBracketLegend(parsed, palette) {
@@ -16,7 +16,7 @@ import {
16
16
  tagAttrKey,
17
17
  validateTagGroupNames,
18
18
  validateTagValues
19
- } from "./chunk-HX2KJEPD.js";
19
+ } from "./chunk-QKJ6MQXW.js";
20
20
  import {
21
21
  SKETCH_REGISTRY,
22
22
  extractColor,
@@ -334,8 +334,8 @@ function renderTabs(g, node, ctx) {
334
334
  function renderTable(g, node, ctx) {
335
335
  const { palette, isTransparent } = ctx;
336
336
  const el = node.element;
337
- const headers = el.tableHeaders || [];
338
- const data = el.tableData || [];
337
+ const headers = el.tableHeaders ?? [];
338
+ const data = el.tableData ?? [];
339
339
  const isSkeleton = el.tableRows !== void 0 && el.tableCols !== void 0;
340
340
  const cols = headers.length || el.tableCols || 3;
341
341
  const colW = node.width / cols;
@@ -361,7 +361,7 @@ function renderTable(g, node, ctx) {
361
361
  if (isSkeleton) {
362
362
  g.append("rect").attr("x", c * colW + 10).attr("y", ry + 8).attr("width", colW * 0.6).attr("height", 12).attr("fill", palette.textMuted).attr("opacity", 0.25).attr("rx", 2);
363
363
  } else if (data[r]) {
364
- const cellText = data[r][c] || "";
364
+ const cellText = data[r][c] ?? "";
365
365
  renderTableCell(g, cellText, c * colW + 10, ry, colW - 20, rowH, ctx);
366
366
  }
367
367
  }
@@ -445,7 +445,7 @@ function renderSkeletonPlaceholder(g, node, ctx) {
445
445
  function renderAlert(g, node, ctx) {
446
446
  const { palette, isDark, isTransparent } = ctx;
447
447
  const el = node.element;
448
- const color = getElementSemanticColor(el, palette) || palette.accent;
448
+ const color = getElementSemanticColor(el, palette) ?? palette.accent;
449
449
  const fill = isTransparent ? null : shapeFill(palette, color, isDark, { mode: ctx.fillMode });
450
450
  if (fill) {
451
451
  g.append("rect").attr("width", node.width).attr("height", node.height).attr("fill", fill).attr("rx", 4);
@@ -473,7 +473,7 @@ function renderProgress(g, node, ctx) {
473
473
  function renderChart(g, node, ctx) {
474
474
  const { palette, isTransparent } = ctx;
475
475
  const el = node.element;
476
- const hint = el.chartHint || "line";
476
+ const hint = el.chartHint ?? "line";
477
477
  g.append("rect").attr("width", node.width).attr("height", node.height).attr(
478
478
  "fill",
479
479
  isTransparent ? "none" : mix(palette.textMuted, palette.bg, 8)
@@ -185,9 +185,9 @@ function resolveMap(parsed, data) {
185
185
  const f = fold(r.name);
186
186
  return usStateIndex.has(f) && !countryIndex.has(f);
187
187
  }) || parsed.regions.some(
188
- (r) => r.scope === "US" || r.scope?.startsWith("US-") || usStateFromBareScope(r.scope) !== null
188
+ (r) => r.scope === "US" || !!r.scope?.startsWith("US-") || usStateFromBareScope(r.scope) !== null
189
189
  ) || parsed.pois.some(
190
- (p) => p.pos.kind === "name" && (p.pos.scope?.startsWith("US-") || usStateFromBareScope(p.pos.scope) !== null)
190
+ (p) => p.pos.kind === "name" && (!!p.pos.scope?.startsWith("US-") || usStateFromBareScope(p.pos.scope) !== null)
191
191
  );
192
192
  const regions = [];
193
193
  const seenRegion = /* @__PURE__ */ new Map();
@@ -838,7 +838,7 @@ function renderCountdown(container, parsed, palette, isDark, exportDims) {
838
838
  }
839
839
  const seriesAccent = getSeriesColors(palette)[0];
840
840
  const defaultAccent = resolveColor("red", palette) ?? seriesAccent;
841
- const manualColor = parsed.color && resolveColor(parsed.color, palette) || parsed.color || null;
841
+ const manualColor = (parsed.color && resolveColor(parsed.color, palette)) ?? parsed.color ?? null;
842
842
  const accent = manualColor ?? defaultAccent;
843
843
  const muted = mix(palette.text, themeBaseBg(palette, isDark), 55);
844
844
  const banked = resolveColor("green", palette) ?? muted;
@@ -71,6 +71,20 @@ B
71
71
  hint: "Remove the trailing tag/metadata suffix \u2014 flowchart node colors come from shape.",
72
72
  example: `flowchart
73
73
  (Start) -> (Denied) s: Denied
74
+ `
75
+ },
76
+ FLOWCHART_STRUCTURE: {
77
+ // src/validate-diagram.ts — validateFlowchartStructure(), the agent-facing
78
+ // gate both MCP servers run; the editor itself never emits it.
79
+ code: "E_FLOWCHART_STRUCTURE",
80
+ severity: "error",
81
+ chartType: "flowchart",
82
+ title: "Flowchart is not one connected flow",
83
+ message: "A decision has fewer than two outgoing branches, the flow has no start or no end, or a node is not on a path from a start to an end.",
84
+ hint: "Give every decision two or more branches, and wire every node into a path from the start to an end.",
85
+ example: `flowchart
86
+ (Start) -> (End)
87
+ [Floating]
74
88
  `
75
89
  }
76
90
  };