@diagrammo/dgmo 0.45.0 → 0.47.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 (250) hide show
  1. package/dist/advanced.cjs +31 -25
  2. package/dist/advanced.d.cts +3 -855
  3. package/dist/advanced.d.ts +3 -855
  4. package/dist/advanced.js +541 -70101
  5. package/dist/analyzer-UYKBXAKR.js +15 -0
  6. package/dist/auto.cjs +500 -341
  7. package/dist/auto.css +342 -159
  8. package/dist/auto.d.cts +10 -8
  9. package/dist/auto.d.ts +10 -8
  10. package/dist/auto.js +373 -265
  11. package/dist/auto.mjs +500 -341
  12. package/dist/block.cjs +31 -25
  13. package/dist/block.js +83 -69411
  14. package/dist/calculator-LDYQCDDY.js +11 -0
  15. package/dist/charts-d3-QOZHKTCT.js +25 -0
  16. package/dist/chunk-2DXMZRWJ.js +800 -0
  17. package/dist/chunk-2LACINWN.js +786 -0
  18. package/dist/chunk-33LCUH4H.js +893 -0
  19. package/dist/chunk-3CIOJ5YJ.js +35 -0
  20. package/dist/chunk-3HDBAXF5.js +86 -0
  21. package/dist/chunk-3JLKYGBQ.js +290 -0
  22. package/dist/chunk-3MQQNXPD.js +415 -0
  23. package/dist/chunk-3R5POCTZ.js +967 -0
  24. package/dist/chunk-3SMGIJDD.js +112 -0
  25. package/dist/chunk-44CM72SQ.js +409 -0
  26. package/dist/chunk-4GRI7MEB.js +1604 -0
  27. package/dist/chunk-4OHACBGX.js +606 -0
  28. package/dist/chunk-5DH3KYFH.js +21 -0
  29. package/dist/chunk-5MLYVTYM.js +76 -0
  30. package/dist/chunk-5QXL4NYS.js +553 -0
  31. package/dist/chunk-5WRI5ZAA.js +31 -0
  32. package/dist/chunk-6EK55ART.js +117 -0
  33. package/dist/chunk-6FZYCKXB.js +2065 -0
  34. package/dist/chunk-6HO5ZTXK.js +277 -0
  35. package/dist/chunk-6KFWC4CO.js +7 -0
  36. package/dist/chunk-6MTWIQVO.js +121 -0
  37. package/dist/chunk-6NYWYNBI.js +329 -0
  38. package/dist/chunk-6SM5NJQH.js +620 -0
  39. package/dist/chunk-725LDASD.js +422 -0
  40. package/dist/chunk-76OWZ3BA.js +130 -0
  41. package/dist/chunk-7JEGTRLD.js +338 -0
  42. package/dist/chunk-A44USUV7.js +923 -0
  43. package/dist/chunk-A4GOY3PE.js +25 -0
  44. package/dist/chunk-A4VFQH5G.js +251 -0
  45. package/dist/chunk-AELOBFW5.js +375 -0
  46. package/dist/chunk-AN2MOO5T.js +522 -0
  47. package/dist/chunk-BMR4CIEO.js +41 -0
  48. package/dist/chunk-BS7SV7C3.js +51 -0
  49. package/dist/chunk-BUPDIHML.js +613 -0
  50. package/dist/chunk-BUVJFRPY.js +887 -0
  51. package/dist/chunk-C3Z4DX3V.js +112 -0
  52. package/dist/chunk-CI2G3OEB.js +1818 -0
  53. package/dist/chunk-CKNVO24D.js +54 -0
  54. package/dist/chunk-CUVHQHZ7.js +391 -0
  55. package/dist/chunk-CXK4DZH3.js +114 -0
  56. package/dist/chunk-DKEPS5LH.js +315 -0
  57. package/dist/chunk-DU7W62N5.js +487 -0
  58. package/dist/chunk-DZAQBW35.js +751 -0
  59. package/dist/chunk-EB6FPQUP.js +316 -0
  60. package/dist/chunk-EMS2SK26.js +376 -0
  61. package/dist/chunk-ERLBPDGU.js +510 -0
  62. package/dist/chunk-EVCVDTXE.js +732 -0
  63. package/dist/chunk-FCIIHT24.js +384 -0
  64. package/dist/chunk-FFUN5D66.js +97 -0
  65. package/dist/chunk-FITOLXSX.js +714 -0
  66. package/dist/chunk-FMDSF3OV.js +68 -0
  67. package/dist/chunk-FNB3PNGF.js +410 -0
  68. package/dist/chunk-G2H74XJZ.js +2104 -0
  69. package/dist/chunk-GMR5MFHJ.js +339 -0
  70. package/dist/chunk-H6PI3KJT.js +305 -0
  71. package/dist/chunk-I46X5VUA.js +59 -0
  72. package/dist/chunk-I5IGB56C.js +255 -0
  73. package/dist/chunk-IH6ZMVQ5.js +3950 -0
  74. package/dist/chunk-IJZFN3HM.js +463 -0
  75. package/dist/chunk-IPWPWM6R.js +3079 -0
  76. package/dist/chunk-IYULMRBE.js +23 -0
  77. package/dist/chunk-IZMRON6C.js +167 -0
  78. package/dist/chunk-J5FIXQRT.js +813 -0
  79. package/dist/chunk-JED6ZDEE.js +73 -0
  80. package/dist/chunk-JEUJOX5X.js +136 -0
  81. package/dist/chunk-JM4LEPY3.js +436 -0
  82. package/dist/chunk-L3UHP6TD.js +101 -0
  83. package/dist/chunk-L66GEFB6.js +524 -0
  84. package/dist/chunk-LIOHW36Z.js +469 -0
  85. package/dist/chunk-LP7EC4MI.js +16 -0
  86. package/dist/chunk-MITI6NOL.js +548 -0
  87. package/dist/chunk-MO5YHHMQ.js +168 -0
  88. package/dist/chunk-MZSBFAPJ.js +885 -0
  89. package/dist/chunk-NNAAJVBU.js +9 -0
  90. package/dist/chunk-NOTA6TEI.js +47 -0
  91. package/dist/chunk-NURGB5Z4.js +335 -0
  92. package/dist/chunk-NX4EQS3U.js +1062 -0
  93. package/dist/chunk-NXMESY4J.js +1 -0
  94. package/dist/chunk-OJR3MQYV.js +1458 -0
  95. package/dist/chunk-OURHMODR.js +454 -0
  96. package/dist/chunk-P235SVAH.js +1057 -0
  97. package/dist/chunk-P4RH4OSP.js +1038 -0
  98. package/dist/chunk-P6T66CCZ.js +226 -0
  99. package/dist/chunk-PBAHEPLQ.js +223 -0
  100. package/dist/chunk-PBHE5UG6.js +1530 -0
  101. package/dist/chunk-PDKUANDZ.js +35 -0
  102. package/dist/chunk-PWIHZ6NJ.js +296 -0
  103. package/dist/chunk-QEBUY5NY.js +1685 -0
  104. package/dist/chunk-QLCCJEJI.js +253 -0
  105. package/dist/chunk-QOOUC2J5.js +52 -0
  106. package/dist/chunk-QYTPPDAO.js +402 -0
  107. package/dist/chunk-R3XI2VC7.js +801 -0
  108. package/dist/chunk-RCERWOJR.js +154 -0
  109. package/dist/chunk-RJE5JTVK.js +362 -0
  110. package/dist/chunk-RTLBSQ3G.js +1155 -0
  111. package/dist/chunk-RUNNI6VE.js +448 -0
  112. package/dist/chunk-RVMRZAPB.js +354 -0
  113. package/dist/chunk-RYEGFMUO.js +955 -0
  114. package/dist/chunk-RZCF2VVM.js +528 -0
  115. package/dist/chunk-SML67VPV.js +1025 -0
  116. package/dist/chunk-SQ7IY53Q.js +44 -0
  117. package/dist/chunk-SQAG3UXH.js +161 -0
  118. package/dist/chunk-SRTU6HMQ.js +1851 -0
  119. package/dist/chunk-T2OE3YQB.js +550 -0
  120. package/dist/chunk-T3UBLACL.js +299 -0
  121. package/dist/chunk-TLVIHFRO.js +296 -0
  122. package/dist/chunk-TYS6CSS5.js +52 -0
  123. package/dist/chunk-U6EQI3U6.js +130 -0
  124. package/dist/chunk-UJ4FJLBF.js +86 -0
  125. package/dist/chunk-ULOEATBZ.js +347 -0
  126. package/dist/chunk-UNCCZ3NU.js +127 -0
  127. package/dist/chunk-USZW2HHU.js +197 -0
  128. package/dist/chunk-UWN33VNX.js +1610 -0
  129. package/dist/chunk-UZ7EZW3B.js +40 -0
  130. package/dist/chunk-VOKGH627.js +37 -0
  131. package/dist/chunk-WBRZJOEC.js +204 -0
  132. package/dist/chunk-WCSOJFU3.js +380 -0
  133. package/dist/chunk-WCT3NYCV.js +160 -0
  134. package/dist/chunk-WVAJFAIA.js +529 -0
  135. package/dist/chunk-X5LCYCL5.js +394 -0
  136. package/dist/chunk-XAKEUMEJ.js +1256 -0
  137. package/dist/chunk-Y2ZE3MSG.js +590 -0
  138. package/dist/chunk-Y3J7VR52.js +646 -0
  139. package/dist/chunk-Y5QGVTVC.js +33 -0
  140. package/dist/chunk-YAA6IID3.js +548 -0
  141. package/dist/chunk-YGJTDXVR.js +692 -0
  142. package/dist/chunk-YRYKTYMQ.js +186 -0
  143. package/dist/chunk-YYVTBZZC.js +61 -0
  144. package/dist/chunk-Z5CGSFJB.js +647 -0
  145. package/dist/chunk-Z72XRXD4.js +787 -0
  146. package/dist/chunk-ZGR7ULFJ.js +978 -0
  147. package/dist/chunk-ZJEL4H2R.js +851 -0
  148. package/dist/chunk-ZO27FGJS.js +554 -0
  149. package/dist/cli.cjs +112 -112
  150. package/dist/collapse-CLPJD2RL.js +11 -0
  151. package/dist/collapse-SLINJQW6.js +9 -0
  152. package/dist/collapse-ZWUFFCK2.js +9 -0
  153. package/dist/compute-G55RG53N.js +8 -0
  154. package/dist/dgmo-router-DZCIDUO5.js +73 -0
  155. package/dist/dimensions-J3FHIMJ6.js +22 -0
  156. package/dist/element.cjs +492 -325
  157. package/dist/element.js +367 -259
  158. package/dist/element.mjs +492 -325
  159. package/dist/flowchart-parser-ZNSKIBVR.js +21 -0
  160. package/dist/flowchart-renderer-ZAEOL4DX.js +35 -0
  161. package/dist/index.cjs +34 -28
  162. package/dist/index.d.cts +3 -469
  163. package/dist/index.d.ts +3 -469
  164. package/dist/index.js +137 -69679
  165. package/dist/layout-46N4JJYK.js +17 -0
  166. package/dist/layout-5RA6QWR6.js +26 -0
  167. package/dist/layout-5T6RH5M6.js +14 -0
  168. package/dist/layout-7QXCNOVS.js +13 -0
  169. package/dist/layout-EE6GE46Y.js +17 -0
  170. package/dist/layout-G23F7LDH.js +9 -0
  171. package/dist/layout-HRBZPFCN.js +23 -0
  172. package/dist/layout-HWDSRX5E.js +20 -0
  173. package/dist/layout-HYZPWAK5.js +18 -0
  174. package/dist/layout-N76NR4ZO.js +19 -0
  175. package/dist/layout-OB3RI63S.js +14 -0
  176. package/dist/layout-S2QBYSK2.js +15 -0
  177. package/dist/layout-UM5F4DJB.js +15 -0
  178. package/dist/layout-search-OYV77HHS.js +1655 -0
  179. package/dist/load-data-EHDDZ5ZS.js +8 -0
  180. package/dist/palettes-PRJ2RI6D.js +56 -0
  181. package/dist/parser-2MFP2H2E.js +11 -0
  182. package/dist/parser-3STE62GB.js +21 -0
  183. package/dist/parser-4FL2CMDG.js +18 -0
  184. package/dist/parser-4OGOBJJ4.js +13 -0
  185. package/dist/parser-6BTRLKRZ.js +15 -0
  186. package/dist/parser-AQETEVRW.js +21 -0
  187. package/dist/parser-CFZD5IBL.js +12 -0
  188. package/dist/parser-FUSKFGZN.js +16 -0
  189. package/dist/parser-I6KXEYFK.js +13 -0
  190. package/dist/parser-IXSZZQHY.js +18 -0
  191. package/dist/parser-JAL2HD4I.js +13 -0
  192. package/dist/parser-KNSQSKQO.js +20 -0
  193. package/dist/parser-N5O4IHUN.js +13 -0
  194. package/dist/parser-NGU3ETO6.js +16 -0
  195. package/dist/parser-NRAI6O25.js +19 -0
  196. package/dist/parser-O5J4VBII.js +11 -0
  197. package/dist/parser-OV7NOBW6.js +21 -0
  198. package/dist/parser-PQ3POX45.js +23 -0
  199. package/dist/parser-TFZFBVWN.js +11 -0
  200. package/dist/parser-TRTHDFPP.js +18 -0
  201. package/dist/parser-VQP2UJ6W.js +11 -0
  202. package/dist/parser-XDVELHRK.js +13 -0
  203. package/dist/parser-XKRP7QKP.js +11 -0
  204. package/dist/parser-Y6WTBU76.js +14 -0
  205. package/dist/parser-ZSDPZYQP.js +12 -0
  206. package/dist/renderer-2XQQQ6QR.js +28 -0
  207. package/dist/renderer-5NDVNDAZ.js +26 -0
  208. package/dist/renderer-6EEZHMH4.js +26 -0
  209. package/dist/renderer-6W5462RB.js +43 -0
  210. package/dist/renderer-7MVLWWQD.js +22 -0
  211. package/dist/renderer-AWWAF6XD.js +33 -0
  212. package/dist/renderer-BYCNMBF7.js +34 -0
  213. package/dist/renderer-CLJHQPBJ.js +29 -0
  214. package/dist/renderer-GHPZMFU2.js +15 -0
  215. package/dist/renderer-JGBKUCZD.js +16 -0
  216. package/dist/renderer-KQB7UGDS.js +19 -0
  217. package/dist/renderer-PGX2TKVS.js +24 -0
  218. package/dist/renderer-QIWVHWZO.js +15 -0
  219. package/dist/renderer-RPOA5YPZ.js +35 -0
  220. package/dist/renderer-SMIBCRVB.js +24 -0
  221. package/dist/renderer-T7YKC5VP.js +28 -0
  222. package/dist/renderer-TOCOVLHS.js +37 -0
  223. package/dist/renderer-UWA5XS74.js +39 -0
  224. package/dist/renderer-VACVQYML.js +25 -0
  225. package/dist/renderer-W4M6QLIJ.js +37 -0
  226. package/dist/renderer-WZRREQ2P.js +23 -0
  227. package/dist/renderer-YY2OSF6E.js +27 -0
  228. package/dist/renderer-Z7I3W2PP.js +24 -0
  229. package/dist/renderer-ZGNTUWC4.js +22 -0
  230. package/dist/renderer-ZTR3DER3.js +19 -0
  231. package/dist/renderer-radial-C32GPJQ7.js +21 -0
  232. package/dist/resolver-NOAA7ID7.js +13 -0
  233. package/dist/state-collapse-HCGD6IVJ.js +8 -0
  234. package/dist/state-parser-Z2V23ATR.js +18 -0
  235. package/dist/state-renderer-RFYHSP4K.js +34 -0
  236. package/dist/themes-1-CuKpeH.d.cts +908 -0
  237. package/dist/themes-1-CuKpeH.d.ts +908 -0
  238. package/package.json +1 -1
  239. package/src/auto/index.ts +55 -57
  240. package/src/auto/shared.ts +142 -142
  241. package/src/auto/styles.ts +44 -199
  242. package/src/c4/renderer.ts +2 -2
  243. package/src/element/index.ts +29 -21
  244. package/src/infra/renderer.ts +1 -1
  245. package/src/render.ts +34 -14
  246. package/src/sitemap/renderer.ts +1 -1
  247. package/src/timeline/renderer.ts +1 -1
  248. package/src/utils/hover-styles.ts +6 -1
  249. package/src/utils/legend-d3.ts +1 -4
  250. package/src/utils/legend-svg.ts +1 -1
@@ -0,0 +1,463 @@
1
+ import {
2
+ buildPlacedNotes
3
+ } from "./chunk-JED6ZDEE.js";
4
+ import {
5
+ noteCanvasShift
6
+ } from "./chunk-6EK55ART.js";
7
+ import {
8
+ measureText,
9
+ truncateText,
10
+ wrapTextToWidth
11
+ } from "./chunk-WCT3NYCV.js";
12
+ import {
13
+ resolveNotes
14
+ } from "./chunk-FMDSF3OV.js";
15
+
16
+ // src/boxes-and-lines/label-placement.ts
17
+ var EDGE_LABEL_FONT_SIZE = 11;
18
+ var LABEL_MAX_WIDTH = 160;
19
+ var MAX_LABEL_LINES = 3;
20
+ var LABEL_LINE_HEIGHT = 1.3;
21
+ var H_PAD = 6;
22
+ var V_PAD = 3;
23
+ var BOX_CLEAR_PAD = 4;
24
+ var PERP_STEP = 8;
25
+ var PERP_MAX = 40;
26
+ var SLIDE_SAMPLES = 9;
27
+ function measureEdgeLabel(label, fontSize = EDGE_LABEL_FONT_SIZE, maxWidth = LABEL_MAX_WIDTH) {
28
+ let lines = wrapTextToWidth(label, fontSize, maxWidth, { hardBreak: true });
29
+ if (lines.length > MAX_LABEL_LINES) {
30
+ const kept = lines.slice(0, MAX_LABEL_LINES - 1);
31
+ const rest = lines.slice(MAX_LABEL_LINES - 1).join(" ");
32
+ kept.push(truncateText(rest, fontSize, maxWidth));
33
+ lines = kept;
34
+ }
35
+ let textW = 0;
36
+ for (const ln of lines) {
37
+ const w = measureText(ln, fontSize);
38
+ if (w > textW) textW = w;
39
+ }
40
+ return {
41
+ lines,
42
+ width: textW + 2 * H_PAD,
43
+ height: lines.length * fontSize * LABEL_LINE_HEIGHT + 2 * V_PAD
44
+ };
45
+ }
46
+ function edgePolylineMidpoint(points) {
47
+ return pointAtArcFraction(points, 0.5).p;
48
+ }
49
+ function pointAtArcFraction(points, t) {
50
+ if (points.length === 0) return { p: { x: 0, y: 0 }, nx: 0, ny: 1 };
51
+ if (points.length === 1)
52
+ return { p: { x: points[0].x, y: points[0].y }, nx: 0, ny: 1 };
53
+ const segLen = [];
54
+ let total = 0;
55
+ for (let k = 1; k < points.length; k++) {
56
+ const len = Math.hypot(
57
+ points[k].x - points[k - 1].x,
58
+ points[k].y - points[k - 1].y
59
+ );
60
+ segLen.push(len);
61
+ total += len;
62
+ }
63
+ let want = total * Math.max(0, Math.min(1, t));
64
+ for (let k = 1; k < points.length; k++) {
65
+ const len = segLen[k - 1];
66
+ if (want <= len || k === points.length - 1) {
67
+ const f = len === 0 ? 0 : Math.min(1, want / len);
68
+ const ax = points[k - 1].x;
69
+ const ay = points[k - 1].y;
70
+ const bx = points[k].x;
71
+ const by = points[k].y;
72
+ const dx = bx - ax;
73
+ const dy = by - ay;
74
+ const dlen = Math.hypot(dx, dy) || 1;
75
+ return {
76
+ p: { x: ax + dx * f, y: ay + dy * f },
77
+ nx: -dy / dlen,
78
+ ny: dx / dlen
79
+ };
80
+ }
81
+ want -= len;
82
+ }
83
+ const last = points[points.length - 1];
84
+ return { p: { x: last.x, y: last.y }, nx: 0, ny: 1 };
85
+ }
86
+ function rectFromCenter(cx, cy, w, h) {
87
+ return {
88
+ minX: cx - w / 2,
89
+ minY: cy - h / 2,
90
+ maxX: cx + w / 2,
91
+ maxY: cy + h / 2
92
+ };
93
+ }
94
+ function overlapsAny(cx, cy, w, h, obstacles, pad) {
95
+ const minX = cx - w / 2 - pad;
96
+ const minY = cy - h / 2 - pad;
97
+ const maxX = cx + w / 2 + pad;
98
+ const maxY = cy + h / 2 + pad;
99
+ for (const o of obstacles) {
100
+ if (minX < o.maxX && maxX > o.minX && minY < o.maxY && maxY > o.minY)
101
+ return true;
102
+ }
103
+ return false;
104
+ }
105
+ function slideFractions() {
106
+ const out = [0.5];
107
+ for (let k = 1; k <= SLIDE_SAMPLES; k++) {
108
+ const off = k * 0.08;
109
+ if (0.5 - off >= 0.12) out.push(0.5 - off);
110
+ if (0.5 + off <= 0.88) out.push(0.5 + off);
111
+ }
112
+ return out;
113
+ }
114
+ function findClearPosition(w, h, points, obstacles) {
115
+ const ts = slideFractions();
116
+ for (const t of ts) {
117
+ const { p } = pointAtArcFraction(points, t);
118
+ if (!overlapsAny(p.x, p.y, w, h, obstacles, BOX_CLEAR_PAD)) return p;
119
+ }
120
+ for (let mag = PERP_STEP; mag <= PERP_MAX; mag += PERP_STEP) {
121
+ for (const t of ts) {
122
+ const { p, nx, ny } = pointAtArcFraction(points, t);
123
+ for (const sign of [-1, 1]) {
124
+ const x = p.x + nx * mag * sign;
125
+ const y = p.y + ny * mag * sign;
126
+ if (!overlapsAny(x, y, w, h, obstacles, BOX_CLEAR_PAD)) return { x, y };
127
+ }
128
+ }
129
+ }
130
+ return null;
131
+ }
132
+ function resolveLabelOverlaps(boxes) {
133
+ const MAX_PASSES = 8;
134
+ const PAD = 4;
135
+ for (let pass = 0; pass < MAX_PASSES; pass++) {
136
+ let moved = false;
137
+ for (let i = 0; i < boxes.length; i++) {
138
+ for (let j = i + 1; j < boxes.length; j++) {
139
+ const a = boxes[i];
140
+ const b = boxes[j];
141
+ const dx = Math.abs(a.cx - b.cx);
142
+ const dy = Math.abs(a.cy - b.cy);
143
+ const overlapX = (a.w + b.w) / 2 + PAD - dx;
144
+ const overlapY = (a.h + b.h) / 2 + PAD - dy;
145
+ if (overlapX > 0 && overlapY > 0) {
146
+ const shift = overlapY / 2 + 1;
147
+ if (a.cy < b.cy) {
148
+ a.cy -= shift;
149
+ b.cy += shift;
150
+ } else {
151
+ a.cy += shift;
152
+ b.cy -= shift;
153
+ }
154
+ moved = true;
155
+ }
156
+ }
157
+ }
158
+ if (!moved) break;
159
+ }
160
+ }
161
+ function placeEdgeLabels(layout, opts) {
162
+ const fontSize = opts?.fontSize ?? EDGE_LABEL_FONT_SIZE;
163
+ const maxWidth = opts?.maxWidth ?? LABEL_MAX_WIDTH;
164
+ const obstacles = [];
165
+ for (const n of layout.nodes)
166
+ obstacles.push(rectFromCenter(n.x, n.y, n.width, n.height));
167
+ for (const g of layout.groups)
168
+ if (g.collapsed)
169
+ obstacles.push(rectFromCenter(g.x, g.y, g.width, g.height));
170
+ const boxes = [];
171
+ layout.edges.forEach((e, idx) => {
172
+ if (!e.label || e.points.length < 2) return;
173
+ const m = measureEdgeLabel(e.label, fontSize, maxWidth);
174
+ const mid = edgePolylineMidpoint(e.points);
175
+ let cy = mid.y;
176
+ if (e.parallelCount > 1 && e.yOffset !== 0)
177
+ cy += (e.yOffset < 0 ? -1 : 1) * (m.height / 2);
178
+ boxes.push({
179
+ edgeIdx: idx,
180
+ cx: mid.x,
181
+ cy,
182
+ w: m.width,
183
+ h: m.height,
184
+ lines: m.lines,
185
+ resolved: true
186
+ });
187
+ });
188
+ for (const box of boxes) {
189
+ if (!overlapsAny(box.cx, box.cy, box.w, box.h, obstacles, BOX_CLEAR_PAD))
190
+ continue;
191
+ const e = layout.edges[box.edgeIdx];
192
+ const clear = findClearPosition(box.w, box.h, e.points, obstacles);
193
+ if (clear) {
194
+ box.cx = clear.x;
195
+ box.cy = clear.y;
196
+ } else {
197
+ box.resolved = false;
198
+ }
199
+ }
200
+ resolveLabelOverlaps(boxes);
201
+ for (const box of boxes) {
202
+ if (overlapsAny(box.cx, box.cy, box.w, box.h, obstacles, BOX_CLEAR_PAD))
203
+ box.resolved = false;
204
+ }
205
+ const boxByIdx = /* @__PURE__ */ new Map();
206
+ for (const b of boxes) boxByIdx.set(b.edgeIdx, b);
207
+ const edges = layout.edges.map((e, idx) => {
208
+ const b = boxByIdx.get(idx);
209
+ if (!b) return e;
210
+ return {
211
+ ...e,
212
+ labelX: b.cx,
213
+ labelY: b.cy,
214
+ labelWidth: b.w,
215
+ labelHeight: b.h,
216
+ labelLines: b.lines
217
+ };
218
+ });
219
+ return {
220
+ layout: { ...layout, edges },
221
+ unresolved: boxes.filter((b) => !b.resolved).map((b) => b.edgeIdx)
222
+ };
223
+ }
224
+
225
+ // src/boxes-and-lines/layout.ts
226
+ var MARGIN = 40;
227
+ var MAX_PARALLEL_EDGES = 5;
228
+ var PARALLEL_SPACING = 22;
229
+ var PHI = 1.618;
230
+ var NODE_HEIGHT = 60;
231
+ var NODE_WIDTH = Math.round(NODE_HEIGHT * PHI);
232
+ var DESC_NODE_WIDTH = 140;
233
+ var DESC_FONT_SIZE = 10;
234
+ var DESC_LINE_HEIGHT = 1.4;
235
+ var DESC_PADDING = 8;
236
+ var SEPARATOR_GAP = 4;
237
+ var MAX_DESC_LINES = 6;
238
+ var MAX_LABEL_LINES2 = 3;
239
+ var LABEL_LINE_HEIGHT2 = 1.3;
240
+ var LABEL_PAD = 12;
241
+ var VALUE_ROW_FONT = 11;
242
+ var VALUE_ROW_H = SEPARATOR_GAP + VALUE_ROW_FONT * DESC_LINE_HEIGHT + DESC_PADDING;
243
+ function splitCamelCase(word) {
244
+ const parts = [];
245
+ let start = 0;
246
+ for (let i = 1; i < word.length; i++) {
247
+ const prev = word.charAt(i - 1);
248
+ const curr = word.charAt(i);
249
+ const next = i + 1 < word.length ? word.charAt(i + 1) : "";
250
+ const lowerToUpper = prev >= "a" && prev <= "z" && curr >= "A" && curr <= "Z";
251
+ const upperRunEnd = prev >= "A" && prev <= "Z" && curr >= "A" && curr <= "Z" && next >= "a" && next <= "z";
252
+ if (lowerToUpper || upperRunEnd) {
253
+ parts.push(word.slice(start, i));
254
+ start = i;
255
+ }
256
+ }
257
+ parts.push(word.slice(start));
258
+ return parts.length > 1 ? parts : [word];
259
+ }
260
+ function estimateLabelLines(label, nodeWidth = NODE_WIDTH) {
261
+ const rawParts = label.split(/[\s-]+/);
262
+ const words = [];
263
+ for (const part of rawParts) {
264
+ if (!part) continue;
265
+ words.push(...splitCamelCase(part));
266
+ }
267
+ const maxTextWidth = nodeWidth - 24;
268
+ for (let fontSize = 13; fontSize >= 9; fontSize--) {
269
+ if (maxTextWidth < measureText("MM", fontSize)) continue;
270
+ let lines = 1;
271
+ let current = "";
272
+ for (const word of words) {
273
+ const test = current ? `${current} ${word}` : word;
274
+ if (measureText(test, fontSize) <= maxTextWidth) {
275
+ current = test;
276
+ } else {
277
+ lines++;
278
+ current = word;
279
+ }
280
+ }
281
+ if (lines <= MAX_LABEL_LINES2) return Math.min(lines, MAX_LABEL_LINES2);
282
+ }
283
+ return MAX_LABEL_LINES2;
284
+ }
285
+ function computeNodeSize(node, reserveValueRow) {
286
+ if (!node.description || node.description.length === 0) {
287
+ return { width: NODE_WIDTH, height: NODE_HEIGHT };
288
+ }
289
+ const w = DESC_NODE_WIDTH;
290
+ const labelLines = estimateLabelLines(node.label, w);
291
+ const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT2 + LABEL_PAD;
292
+ const maxTextWidth = w - 24;
293
+ let totalRenderedLines = 0;
294
+ for (const line of node.description) {
295
+ if (measureText(line, DESC_FONT_SIZE) <= maxTextWidth) {
296
+ totalRenderedLines += 1;
297
+ } else {
298
+ totalRenderedLines += wrapTextToWidth(
299
+ line,
300
+ DESC_FONT_SIZE,
301
+ maxTextWidth,
302
+ {
303
+ hardBreak: true
304
+ }
305
+ ).length;
306
+ }
307
+ }
308
+ totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES);
309
+ const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE * DESC_LINE_HEIGHT;
310
+ const totalHeight = labelHeight + SEPARATOR_GAP + DESC_PADDING + descriptionHeight + DESC_PADDING + (reserveValueRow ? VALUE_ROW_H : 0);
311
+ return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
312
+ }
313
+ async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
314
+ const { layoutBoxesAndLinesSearch } = await import("./layout-search-OYV77HHS.js");
315
+ const searchOpts = {
316
+ ...layoutOptions?.hideDescriptions !== void 0 && {
317
+ hideDescriptions: layoutOptions.hideDescriptions
318
+ },
319
+ ...layoutOptions?.previousPositions !== void 0 && {
320
+ previousPositions: layoutOptions.previousPositions
321
+ },
322
+ ...layoutOptions?.onProgress !== void 0 && {
323
+ onProgress: layoutOptions.onProgress
324
+ }
325
+ };
326
+ const searched = await layoutBoxesAndLinesSearch(
327
+ parsed,
328
+ collapseInfo,
329
+ searchOpts
330
+ );
331
+ let placed = placeEdgeLabels(applyParallelEdgeOffsets(searched));
332
+ if (placed.unresolved.length > 0) {
333
+ const relaid = await layoutBoxesAndLinesSearch(parsed, collapseInfo, {
334
+ ...searchOpts,
335
+ reserveEdgeLabels: true
336
+ });
337
+ const relaidPlaced = placeEdgeLabels(applyParallelEdgeOffsets(relaid));
338
+ if (relaidPlaced.unresolved.length < placed.unresolved.length)
339
+ placed = relaidPlaced;
340
+ }
341
+ return attachNotes(placed.layout, parsed, layoutOptions?.collapsedNotes);
342
+ }
343
+ function attachNotes(layout, parsed, collapsedNotes) {
344
+ const notesSuppressed = parsed.options?.["no-notes"] === "on";
345
+ const noteByNode = notesSuppressed || !parsed.notes ? /* @__PURE__ */ new Map() : resolveNotes(
346
+ parsed.notes,
347
+ parsed.nodes.map((n) => ({ id: n.label, label: n.label }))
348
+ );
349
+ if (noteByNode.size === 0) return layout;
350
+ const placed = buildPlacedNotes(
351
+ layout.nodes.map((n) => ({
352
+ id: n.label,
353
+ x: n.x,
354
+ y: n.y,
355
+ width: n.width,
356
+ height: n.height
357
+ })),
358
+ noteByNode,
359
+ parsed.direction === "TB" ? "TB" : "LR",
360
+ collapsedNotes
361
+ );
362
+ const notedNodes = layout.nodes.map((n) => {
363
+ const note = placed.get(n.label);
364
+ return note ? { ...n, note } : n;
365
+ });
366
+ let bbMinX = Infinity;
367
+ let bbMinY = Infinity;
368
+ let bbMaxX = -Infinity;
369
+ let bbMaxY = -Infinity;
370
+ const extend = (l, t, r, b) => {
371
+ if (l < bbMinX) bbMinX = l;
372
+ if (t < bbMinY) bbMinY = t;
373
+ if (r > bbMaxX) bbMaxX = r;
374
+ if (b > bbMaxY) bbMaxY = b;
375
+ };
376
+ for (const n of notedNodes) {
377
+ extend(
378
+ n.x - n.width / 2,
379
+ n.y - n.height / 2,
380
+ n.x + n.width / 2,
381
+ n.y + n.height / 2
382
+ );
383
+ if (n.note && !n.note.collapsed) {
384
+ extend(
385
+ n.x + n.note.x,
386
+ n.y + n.note.y,
387
+ n.x + n.note.x + n.note.width,
388
+ n.y + n.note.y + n.note.height
389
+ );
390
+ }
391
+ }
392
+ for (const grp of layout.groups) {
393
+ extend(
394
+ grp.x - grp.width / 2,
395
+ grp.y - grp.height / 2,
396
+ grp.x + grp.width / 2,
397
+ grp.y + grp.height / 2
398
+ );
399
+ }
400
+ if (!Number.isFinite(bbMinX)) return { ...layout, nodes: notedNodes };
401
+ const { shiftX, shiftY } = noteCanvasShift(bbMinX, bbMinY);
402
+ const shifted = shiftX !== 0 || shiftY !== 0;
403
+ const finalNodes = shifted ? notedNodes.map((n) => ({ ...n, x: n.x + shiftX, y: n.y + shiftY })) : notedNodes;
404
+ const finalEdges = shifted ? layout.edges.map((e) => ({
405
+ ...e,
406
+ points: e.points.map((pt) => ({ x: pt.x + shiftX, y: pt.y + shiftY })),
407
+ ...e.labelX !== void 0 && { labelX: e.labelX + shiftX },
408
+ ...e.labelY !== void 0 && { labelY: e.labelY + shiftY }
409
+ // labelWidth/labelHeight/labelLines are shift-invariant — carried via spread.
410
+ })) : layout.edges;
411
+ const finalGroups = shifted ? layout.groups.map((grp) => ({
412
+ ...grp,
413
+ x: grp.x + shiftX,
414
+ y: grp.y + shiftY
415
+ })) : layout.groups;
416
+ return {
417
+ nodes: finalNodes,
418
+ edges: finalEdges,
419
+ groups: finalGroups,
420
+ width: bbMaxX + shiftX + MARGIN,
421
+ height: bbMaxY + shiftY + MARGIN
422
+ };
423
+ }
424
+ function applyParallelEdgeOffsets(layout) {
425
+ const groups = /* @__PURE__ */ new Map();
426
+ layout.edges.forEach((e, i) => {
427
+ const [a, b] = e.source < e.target ? [e.source, e.target] : [e.target, e.source];
428
+ const key = `${a}\0${b}`;
429
+ const arr = groups.get(key);
430
+ if (arr) arr.push(i);
431
+ else groups.set(key, [i]);
432
+ });
433
+ if ([...groups.values()].every((g) => g.length < 2)) return layout;
434
+ const yOffset = new Array(layout.edges.length).fill(0);
435
+ const count = new Array(layout.edges.length).fill(1);
436
+ for (const idxs of groups.values()) {
437
+ const capped = idxs.slice(0, MAX_PARALLEL_EDGES);
438
+ for (const drop of idxs.slice(MAX_PARALLEL_EDGES)) count[drop] = 0;
439
+ if (capped.length < 2) continue;
440
+ capped.forEach((idx, j) => {
441
+ yOffset[idx] = (j - (capped.length - 1) / 2) * PARALLEL_SPACING;
442
+ count[idx] = capped.length;
443
+ });
444
+ }
445
+ return {
446
+ ...layout,
447
+ edges: layout.edges.map((e, i) => ({
448
+ ...e,
449
+ yOffset: yOffset[i],
450
+ parallelCount: count[i]
451
+ }))
452
+ };
453
+ }
454
+
455
+ export {
456
+ EDGE_LABEL_FONT_SIZE,
457
+ measureEdgeLabel,
458
+ NODE_HEIGHT,
459
+ NODE_WIDTH,
460
+ computeNodeSize,
461
+ layoutBoxesAndLines
462
+ };
463
+ //# sourceMappingURL=chunk-IJZFN3HM.js.map