@diagrammo/dgmo 0.46.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 (232) hide show
  1. package/dist/advanced.d.cts +3 -855
  2. package/dist/advanced.d.ts +3 -855
  3. package/dist/advanced.js +541 -70107
  4. package/dist/analyzer-UYKBXAKR.js +15 -0
  5. package/dist/auto.cjs +1 -1
  6. package/dist/auto.js +1 -1
  7. package/dist/auto.mjs +1 -1
  8. package/dist/block.js +83 -69417
  9. package/dist/calculator-LDYQCDDY.js +11 -0
  10. package/dist/charts-d3-QOZHKTCT.js +25 -0
  11. package/dist/chunk-2DXMZRWJ.js +800 -0
  12. package/dist/chunk-2LACINWN.js +786 -0
  13. package/dist/chunk-33LCUH4H.js +893 -0
  14. package/dist/chunk-3CIOJ5YJ.js +35 -0
  15. package/dist/chunk-3HDBAXF5.js +86 -0
  16. package/dist/chunk-3JLKYGBQ.js +290 -0
  17. package/dist/chunk-3MQQNXPD.js +415 -0
  18. package/dist/chunk-3R5POCTZ.js +967 -0
  19. package/dist/chunk-3SMGIJDD.js +112 -0
  20. package/dist/chunk-44CM72SQ.js +409 -0
  21. package/dist/chunk-4GRI7MEB.js +1604 -0
  22. package/dist/chunk-4OHACBGX.js +606 -0
  23. package/dist/chunk-5DH3KYFH.js +21 -0
  24. package/dist/chunk-5MLYVTYM.js +76 -0
  25. package/dist/chunk-5QXL4NYS.js +553 -0
  26. package/dist/chunk-5WRI5ZAA.js +31 -0
  27. package/dist/chunk-6EK55ART.js +117 -0
  28. package/dist/chunk-6FZYCKXB.js +2065 -0
  29. package/dist/chunk-6HO5ZTXK.js +277 -0
  30. package/dist/chunk-6KFWC4CO.js +7 -0
  31. package/dist/chunk-6MTWIQVO.js +121 -0
  32. package/dist/chunk-6NYWYNBI.js +329 -0
  33. package/dist/chunk-6SM5NJQH.js +620 -0
  34. package/dist/chunk-725LDASD.js +422 -0
  35. package/dist/chunk-76OWZ3BA.js +130 -0
  36. package/dist/chunk-7JEGTRLD.js +338 -0
  37. package/dist/chunk-A44USUV7.js +923 -0
  38. package/dist/chunk-A4GOY3PE.js +25 -0
  39. package/dist/chunk-A4VFQH5G.js +251 -0
  40. package/dist/chunk-AELOBFW5.js +375 -0
  41. package/dist/chunk-AN2MOO5T.js +522 -0
  42. package/dist/chunk-BMR4CIEO.js +41 -0
  43. package/dist/chunk-BS7SV7C3.js +51 -0
  44. package/dist/chunk-BUPDIHML.js +613 -0
  45. package/dist/chunk-BUVJFRPY.js +887 -0
  46. package/dist/chunk-C3Z4DX3V.js +112 -0
  47. package/dist/chunk-CI2G3OEB.js +1818 -0
  48. package/dist/chunk-CKNVO24D.js +54 -0
  49. package/dist/chunk-CUVHQHZ7.js +391 -0
  50. package/dist/chunk-CXK4DZH3.js +114 -0
  51. package/dist/chunk-DKEPS5LH.js +315 -0
  52. package/dist/chunk-DU7W62N5.js +487 -0
  53. package/dist/chunk-DZAQBW35.js +751 -0
  54. package/dist/chunk-EB6FPQUP.js +316 -0
  55. package/dist/chunk-EMS2SK26.js +376 -0
  56. package/dist/chunk-ERLBPDGU.js +510 -0
  57. package/dist/chunk-EVCVDTXE.js +732 -0
  58. package/dist/chunk-FCIIHT24.js +384 -0
  59. package/dist/chunk-FFUN5D66.js +97 -0
  60. package/dist/chunk-FITOLXSX.js +714 -0
  61. package/dist/chunk-FMDSF3OV.js +68 -0
  62. package/dist/chunk-FNB3PNGF.js +410 -0
  63. package/dist/chunk-G2H74XJZ.js +2104 -0
  64. package/dist/chunk-GMR5MFHJ.js +339 -0
  65. package/dist/chunk-H6PI3KJT.js +305 -0
  66. package/dist/chunk-I46X5VUA.js +59 -0
  67. package/dist/chunk-I5IGB56C.js +255 -0
  68. package/dist/chunk-IH6ZMVQ5.js +3950 -0
  69. package/dist/chunk-IJZFN3HM.js +463 -0
  70. package/dist/chunk-IPWPWM6R.js +3079 -0
  71. package/dist/chunk-IYULMRBE.js +23 -0
  72. package/dist/chunk-IZMRON6C.js +167 -0
  73. package/dist/chunk-J5FIXQRT.js +813 -0
  74. package/dist/chunk-JED6ZDEE.js +73 -0
  75. package/dist/chunk-JEUJOX5X.js +136 -0
  76. package/dist/chunk-JM4LEPY3.js +436 -0
  77. package/dist/chunk-L3UHP6TD.js +101 -0
  78. package/dist/chunk-L66GEFB6.js +524 -0
  79. package/dist/chunk-LIOHW36Z.js +469 -0
  80. package/dist/chunk-LP7EC4MI.js +16 -0
  81. package/dist/chunk-MITI6NOL.js +548 -0
  82. package/dist/chunk-MO5YHHMQ.js +168 -0
  83. package/dist/chunk-MZSBFAPJ.js +885 -0
  84. package/dist/chunk-NNAAJVBU.js +9 -0
  85. package/dist/chunk-NOTA6TEI.js +47 -0
  86. package/dist/chunk-NURGB5Z4.js +335 -0
  87. package/dist/chunk-NX4EQS3U.js +1062 -0
  88. package/dist/chunk-NXMESY4J.js +1 -0
  89. package/dist/chunk-OJR3MQYV.js +1458 -0
  90. package/dist/chunk-OURHMODR.js +454 -0
  91. package/dist/chunk-P235SVAH.js +1057 -0
  92. package/dist/chunk-P4RH4OSP.js +1038 -0
  93. package/dist/chunk-P6T66CCZ.js +226 -0
  94. package/dist/chunk-PBAHEPLQ.js +223 -0
  95. package/dist/chunk-PBHE5UG6.js +1530 -0
  96. package/dist/chunk-PDKUANDZ.js +35 -0
  97. package/dist/chunk-PWIHZ6NJ.js +296 -0
  98. package/dist/chunk-QEBUY5NY.js +1685 -0
  99. package/dist/chunk-QLCCJEJI.js +253 -0
  100. package/dist/chunk-QOOUC2J5.js +52 -0
  101. package/dist/chunk-QYTPPDAO.js +402 -0
  102. package/dist/chunk-R3XI2VC7.js +801 -0
  103. package/dist/chunk-RCERWOJR.js +154 -0
  104. package/dist/chunk-RJE5JTVK.js +362 -0
  105. package/dist/chunk-RTLBSQ3G.js +1155 -0
  106. package/dist/chunk-RUNNI6VE.js +448 -0
  107. package/dist/chunk-RVMRZAPB.js +354 -0
  108. package/dist/chunk-RYEGFMUO.js +955 -0
  109. package/dist/chunk-RZCF2VVM.js +528 -0
  110. package/dist/chunk-SML67VPV.js +1025 -0
  111. package/dist/chunk-SQ7IY53Q.js +44 -0
  112. package/dist/chunk-SQAG3UXH.js +161 -0
  113. package/dist/chunk-SRTU6HMQ.js +1851 -0
  114. package/dist/chunk-T2OE3YQB.js +550 -0
  115. package/dist/chunk-T3UBLACL.js +299 -0
  116. package/dist/chunk-TLVIHFRO.js +296 -0
  117. package/dist/chunk-TYS6CSS5.js +52 -0
  118. package/dist/chunk-U6EQI3U6.js +130 -0
  119. package/dist/chunk-UJ4FJLBF.js +86 -0
  120. package/dist/chunk-ULOEATBZ.js +347 -0
  121. package/dist/chunk-UNCCZ3NU.js +127 -0
  122. package/dist/chunk-USZW2HHU.js +197 -0
  123. package/dist/chunk-UWN33VNX.js +1610 -0
  124. package/dist/chunk-UZ7EZW3B.js +40 -0
  125. package/dist/chunk-VOKGH627.js +37 -0
  126. package/dist/chunk-WBRZJOEC.js +204 -0
  127. package/dist/chunk-WCSOJFU3.js +380 -0
  128. package/dist/chunk-WCT3NYCV.js +160 -0
  129. package/dist/chunk-WVAJFAIA.js +529 -0
  130. package/dist/chunk-X5LCYCL5.js +394 -0
  131. package/dist/chunk-XAKEUMEJ.js +1256 -0
  132. package/dist/chunk-Y2ZE3MSG.js +590 -0
  133. package/dist/chunk-Y3J7VR52.js +646 -0
  134. package/dist/chunk-Y5QGVTVC.js +33 -0
  135. package/dist/chunk-YAA6IID3.js +548 -0
  136. package/dist/chunk-YGJTDXVR.js +692 -0
  137. package/dist/chunk-YRYKTYMQ.js +186 -0
  138. package/dist/chunk-YYVTBZZC.js +61 -0
  139. package/dist/chunk-Z5CGSFJB.js +647 -0
  140. package/dist/chunk-Z72XRXD4.js +787 -0
  141. package/dist/chunk-ZGR7ULFJ.js +978 -0
  142. package/dist/chunk-ZJEL4H2R.js +851 -0
  143. package/dist/chunk-ZO27FGJS.js +554 -0
  144. package/dist/collapse-CLPJD2RL.js +11 -0
  145. package/dist/collapse-SLINJQW6.js +9 -0
  146. package/dist/collapse-ZWUFFCK2.js +9 -0
  147. package/dist/compute-G55RG53N.js +8 -0
  148. package/dist/dgmo-router-DZCIDUO5.js +73 -0
  149. package/dist/dimensions-J3FHIMJ6.js +22 -0
  150. package/dist/element.cjs +1 -1
  151. package/dist/element.js +1 -1
  152. package/dist/element.mjs +1 -1
  153. package/dist/flowchart-parser-ZNSKIBVR.js +21 -0
  154. package/dist/flowchart-renderer-ZAEOL4DX.js +35 -0
  155. package/dist/index.cjs +3 -3
  156. package/dist/index.d.cts +3 -469
  157. package/dist/index.d.ts +3 -469
  158. package/dist/index.js +137 -69685
  159. package/dist/layout-46N4JJYK.js +17 -0
  160. package/dist/layout-5RA6QWR6.js +26 -0
  161. package/dist/layout-5T6RH5M6.js +14 -0
  162. package/dist/layout-7QXCNOVS.js +13 -0
  163. package/dist/layout-EE6GE46Y.js +17 -0
  164. package/dist/layout-G23F7LDH.js +9 -0
  165. package/dist/layout-HRBZPFCN.js +23 -0
  166. package/dist/layout-HWDSRX5E.js +20 -0
  167. package/dist/layout-HYZPWAK5.js +18 -0
  168. package/dist/layout-N76NR4ZO.js +19 -0
  169. package/dist/layout-OB3RI63S.js +14 -0
  170. package/dist/layout-S2QBYSK2.js +15 -0
  171. package/dist/layout-UM5F4DJB.js +15 -0
  172. package/dist/layout-search-OYV77HHS.js +1655 -0
  173. package/dist/load-data-EHDDZ5ZS.js +8 -0
  174. package/dist/palettes-PRJ2RI6D.js +56 -0
  175. package/dist/parser-2MFP2H2E.js +11 -0
  176. package/dist/parser-3STE62GB.js +21 -0
  177. package/dist/parser-4FL2CMDG.js +18 -0
  178. package/dist/parser-4OGOBJJ4.js +13 -0
  179. package/dist/parser-6BTRLKRZ.js +15 -0
  180. package/dist/parser-AQETEVRW.js +21 -0
  181. package/dist/parser-CFZD5IBL.js +12 -0
  182. package/dist/parser-FUSKFGZN.js +16 -0
  183. package/dist/parser-I6KXEYFK.js +13 -0
  184. package/dist/parser-IXSZZQHY.js +18 -0
  185. package/dist/parser-JAL2HD4I.js +13 -0
  186. package/dist/parser-KNSQSKQO.js +20 -0
  187. package/dist/parser-N5O4IHUN.js +13 -0
  188. package/dist/parser-NGU3ETO6.js +16 -0
  189. package/dist/parser-NRAI6O25.js +19 -0
  190. package/dist/parser-O5J4VBII.js +11 -0
  191. package/dist/parser-OV7NOBW6.js +21 -0
  192. package/dist/parser-PQ3POX45.js +23 -0
  193. package/dist/parser-TFZFBVWN.js +11 -0
  194. package/dist/parser-TRTHDFPP.js +18 -0
  195. package/dist/parser-VQP2UJ6W.js +11 -0
  196. package/dist/parser-XDVELHRK.js +13 -0
  197. package/dist/parser-XKRP7QKP.js +11 -0
  198. package/dist/parser-Y6WTBU76.js +14 -0
  199. package/dist/parser-ZSDPZYQP.js +12 -0
  200. package/dist/renderer-2XQQQ6QR.js +28 -0
  201. package/dist/renderer-5NDVNDAZ.js +26 -0
  202. package/dist/renderer-6EEZHMH4.js +26 -0
  203. package/dist/renderer-6W5462RB.js +43 -0
  204. package/dist/renderer-7MVLWWQD.js +22 -0
  205. package/dist/renderer-AWWAF6XD.js +33 -0
  206. package/dist/renderer-BYCNMBF7.js +34 -0
  207. package/dist/renderer-CLJHQPBJ.js +29 -0
  208. package/dist/renderer-GHPZMFU2.js +15 -0
  209. package/dist/renderer-JGBKUCZD.js +16 -0
  210. package/dist/renderer-KQB7UGDS.js +19 -0
  211. package/dist/renderer-PGX2TKVS.js +24 -0
  212. package/dist/renderer-QIWVHWZO.js +15 -0
  213. package/dist/renderer-RPOA5YPZ.js +35 -0
  214. package/dist/renderer-SMIBCRVB.js +24 -0
  215. package/dist/renderer-T7YKC5VP.js +28 -0
  216. package/dist/renderer-TOCOVLHS.js +37 -0
  217. package/dist/renderer-UWA5XS74.js +39 -0
  218. package/dist/renderer-VACVQYML.js +25 -0
  219. package/dist/renderer-W4M6QLIJ.js +37 -0
  220. package/dist/renderer-WZRREQ2P.js +23 -0
  221. package/dist/renderer-YY2OSF6E.js +27 -0
  222. package/dist/renderer-Z7I3W2PP.js +24 -0
  223. package/dist/renderer-ZGNTUWC4.js +22 -0
  224. package/dist/renderer-ZTR3DER3.js +19 -0
  225. package/dist/renderer-radial-C32GPJQ7.js +21 -0
  226. package/dist/resolver-NOAA7ID7.js +13 -0
  227. package/dist/state-collapse-HCGD6IVJ.js +8 -0
  228. package/dist/state-parser-Z2V23ATR.js +18 -0
  229. package/dist/state-renderer-RFYHSP4K.js +34 -0
  230. package/dist/themes-1-CuKpeH.d.cts +908 -0
  231. package/dist/themes-1-CuKpeH.d.ts +908 -0
  232. package/package.json +1 -1
@@ -0,0 +1,606 @@
1
+ import {
2
+ measureText
3
+ } from "./chunk-WCT3NYCV.js";
4
+ import {
5
+ formatDuration,
6
+ formatScheduleValue,
7
+ formatSlackValue,
8
+ formatSprintCell
9
+ } from "./chunk-L3UHP6TD.js";
10
+
11
+ // src/pert/layout.ts
12
+ import dagre from "@dagrejs/dagre";
13
+ var DEFAULT_NODE_HEIGHT = 90;
14
+ var MILESTONE_NODE_HEIGHT = DEFAULT_NODE_HEIGHT;
15
+ var COLLAPSED_GROUP_HEIGHT = 90;
16
+ var DIAGRAM_PADDING = 20;
17
+ var GROUP_PADDING = 18;
18
+ var GROUP_TOP_PADDING = 28;
19
+ var SWIMLANE_SLOT_SEP = 40;
20
+ var SWIMLANE_GAP = 24;
21
+ var NODE_CELL_FONT_SIZE = 11;
22
+ var NODE_NAME_FONT_SIZE = 13;
23
+ var MILESTONE_NAME_FONT_SIZE = 12;
24
+ var CELL_PAD_X = 8;
25
+ var NAME_PAD_X = 6;
26
+ var NAME_PIN_WIDTH = 13 + 4;
27
+ var MIN_CELL_WIDTH = 30;
28
+ var MIN_NODE_WIDTH = 120;
29
+ var MAX_NODE_WIDTH = 280;
30
+ var MIN_MILESTONE_WIDTH = 80;
31
+ var MAX_MILESTONE_WIDTH = 160;
32
+ function computeNodeSizing(resolved) {
33
+ const unit = resolved.options.timeUnit;
34
+ const sprintMode = resolved.options.sprintMode;
35
+ const sprintNumber = resolved.options.sprintNumber ?? 1;
36
+ const projectStart = resolved.projectStart;
37
+ const fmtSchedule = (v, isTbd) => sprintMode ? formatSprintCell(v, sprintNumber, isTbd ? "?" : null) : formatScheduleValue(v, projectStart, unit, isTbd ? "?" : null);
38
+ const fmtSlack = (v, isTbd) => formatSlackValue(v, projectStart, unit, isTbd ? "?" : null);
39
+ const fmtDur = (v, isTbd) => formatDuration(v, unit, isTbd ? "?" : null);
40
+ let maxOuterW = 0;
41
+ let maxMidW = 0;
42
+ let maxNameW = 0;
43
+ let maxMilestoneTopW = 0;
44
+ let maxMilestoneSlackW = 0;
45
+ let maxMilestoneNameW = 0;
46
+ for (const r of resolved.activities) {
47
+ const isTbd = r.es === null;
48
+ if (r.activity.isMilestone) {
49
+ const dateStr = fmtSchedule(r.es, isTbd);
50
+ const slackStr2 = fmtSlack(r.slack, isTbd);
51
+ const slackHidden = !isTbd && /^0[a-z]?$/.test(slackStr2);
52
+ maxMilestoneTopW = Math.max(
53
+ maxMilestoneTopW,
54
+ measureText(dateStr, NODE_CELL_FONT_SIZE)
55
+ );
56
+ if (!slackHidden) {
57
+ maxMilestoneSlackW = Math.max(
58
+ maxMilestoneSlackW,
59
+ measureText(slackStr2, NODE_CELL_FONT_SIZE)
60
+ );
61
+ }
62
+ maxMilestoneNameW = Math.max(
63
+ maxMilestoneNameW,
64
+ measureText(`\u25C6 ${r.activity.name}`, MILESTONE_NAME_FONT_SIZE)
65
+ );
66
+ continue;
67
+ }
68
+ const esStr = fmtSchedule(r.es, isTbd);
69
+ const efStr = fmtSchedule(r.ef, isTbd);
70
+ const lsStr = fmtSchedule(r.ls, isTbd);
71
+ const lfStr = fmtSchedule(r.lf, isTbd);
72
+ const durStr = fmtDur(r.mu, isTbd);
73
+ const slackStr = fmtSlack(r.slack, isTbd);
74
+ maxOuterW = Math.max(
75
+ maxOuterW,
76
+ measureText(esStr, NODE_CELL_FONT_SIZE),
77
+ measureText(efStr, NODE_CELL_FONT_SIZE),
78
+ measureText(lsStr, NODE_CELL_FONT_SIZE),
79
+ measureText(lfStr, NODE_CELL_FONT_SIZE)
80
+ );
81
+ maxMidW = Math.max(
82
+ maxMidW,
83
+ measureText(durStr, NODE_CELL_FONT_SIZE),
84
+ measureText(slackStr, NODE_CELL_FONT_SIZE)
85
+ );
86
+ maxNameW = Math.max(
87
+ maxNameW,
88
+ measureText(r.activity.name, NODE_NAME_FONT_SIZE)
89
+ );
90
+ }
91
+ for (const rg of resolved.groups) {
92
+ maxNameW = Math.max(
93
+ maxNameW,
94
+ measureText(rg.group.name, NODE_NAME_FONT_SIZE)
95
+ );
96
+ }
97
+ const outerCell = Math.ceil(maxOuterW) + 2 * CELL_PAD_X;
98
+ const midCell = Math.ceil(maxMidW) + 2 * CELL_PAD_X;
99
+ const outerNeeded = Math.max(MIN_CELL_WIDTH, outerCell);
100
+ const midNeeded = Math.max(MIN_CELL_WIDTH, midCell);
101
+ const cellsTotalW = 2 * outerNeeded + midNeeded;
102
+ const nameTextW = Math.ceil(maxNameW);
103
+ const nameTotalW = nameTextW + NAME_PIN_WIDTH + 2 * NAME_PAD_X;
104
+ const activityWidth = Math.max(
105
+ MIN_NODE_WIDTH,
106
+ Math.min(MAX_NODE_WIDTH, Math.max(cellsTotalW, nameTotalW))
107
+ );
108
+ let midColW = midNeeded;
109
+ let outerColW = (activityWidth - midColW) / 2;
110
+ if (midColW > outerColW) {
111
+ outerColW = activityWidth / 3;
112
+ midColW = activityWidth - 2 * outerColW;
113
+ }
114
+ const mTop = Math.ceil(maxMilestoneTopW) + 2 * CELL_PAD_X;
115
+ const mSlack = maxMilestoneSlackW > 0 ? Math.ceil(maxMilestoneSlackW) + 2 * CELL_PAD_X : 0;
116
+ const mName = Math.ceil(maxMilestoneNameW) + NAME_PIN_WIDTH + 2 * NAME_PAD_X;
117
+ const milestoneWidth = Math.max(
118
+ MIN_MILESTONE_WIDTH,
119
+ Math.min(MAX_MILESTONE_WIDTH, Math.max(mTop, mSlack, mName))
120
+ );
121
+ return { activityWidth, milestoneWidth, outerColW, midColW };
122
+ }
123
+ function nodeDimensions(resolved, id, sizing, overrides) {
124
+ if (overrides?.[id]) {
125
+ return { width: overrides[id].width, height: overrides[id].height };
126
+ }
127
+ const r = resolved.activities.find((a) => a.activity.id === id);
128
+ if (r?.activity.isMilestone) {
129
+ return { width: sizing.milestoneWidth, height: MILESTONE_NODE_HEIGHT };
130
+ }
131
+ return { width: sizing.activityWidth, height: DEFAULT_NODE_HEIGHT };
132
+ }
133
+ function layoutPert(resolved) {
134
+ return relayoutPert(resolved, {});
135
+ }
136
+ function relayoutPert(resolved, overrides, collapsedGroupIds = /* @__PURE__ */ new Set()) {
137
+ if (resolved.activities.length === 0) {
138
+ return { nodes: [], edges: [], groups: [], width: 0, height: 0 };
139
+ }
140
+ const memberToGroup = /* @__PURE__ */ new Map();
141
+ for (const rg of resolved.groups) {
142
+ if (collapsedGroupIds.has(rg.group.id)) {
143
+ for (const aid of rg.group.activityIds) {
144
+ memberToGroup.set(aid, rg.group.id);
145
+ }
146
+ }
147
+ }
148
+ const dagreId = (id) => memberToGroup.get(id) ?? id;
149
+ const g = new dagre.graphlib.Graph();
150
+ g.setGraph({
151
+ rankdir: resolved.options.direction,
152
+ nodesep: 50,
153
+ ranksep: 60,
154
+ edgesep: 18,
155
+ marginx: DIAGRAM_PADDING,
156
+ marginy: DIAGRAM_PADDING
157
+ });
158
+ g.setDefaultEdgeLabel(() => ({}));
159
+ const sizing = computeNodeSizing(resolved);
160
+ for (const r of resolved.activities) {
161
+ if (memberToGroup.has(r.activity.id)) continue;
162
+ const { width, height } = nodeDimensions(
163
+ resolved,
164
+ r.activity.id,
165
+ sizing,
166
+ overrides
167
+ );
168
+ g.setNode(r.activity.id, { width, height });
169
+ }
170
+ for (const rg of resolved.groups) {
171
+ if (collapsedGroupIds.has(rg.group.id)) {
172
+ g.setNode(rg.group.id, {
173
+ width: sizing.activityWidth,
174
+ height: COLLAPSED_GROUP_HEIGHT
175
+ });
176
+ }
177
+ }
178
+ const seenEdges = /* @__PURE__ */ new Set();
179
+ for (const e of resolved.edges) {
180
+ const src = dagreId(e.source);
181
+ const tgt = dagreId(e.target);
182
+ if (src === tgt) continue;
183
+ const k = `${src}|${tgt}`;
184
+ if (seenEdges.has(k)) continue;
185
+ seenEdges.add(k);
186
+ g.setEdge(src, tgt, {});
187
+ }
188
+ dagre.layout(g);
189
+ const swimApplied = applySwimLanes(
190
+ g,
191
+ resolved,
192
+ memberToGroup,
193
+ collapsedGroupIds
194
+ );
195
+ if (!swimApplied) {
196
+ centerByCriticality(g, resolved, memberToGroup, collapsedGroupIds);
197
+ reduceCrossings(g, resolved.options.direction);
198
+ }
199
+ const nodes = resolved.activities.filter((r) => !memberToGroup.has(r.activity.id)).map((r) => {
200
+ const pos = g.node(r.activity.id);
201
+ return {
202
+ id: r.activity.id,
203
+ x: pos.x,
204
+ y: pos.y,
205
+ width: pos.width,
206
+ height: pos.height
207
+ };
208
+ });
209
+ const edges = Array.from(seenEdges).map((k) => {
210
+ const [source, target] = k.split("|");
211
+ const data = g.edge(source, target);
212
+ return { source, target, points: data?.points ?? [] };
213
+ });
214
+ const nodeMap = /* @__PURE__ */ new Map();
215
+ for (const n of nodes) nodeMap.set(n.id, n);
216
+ for (const rg of resolved.groups) {
217
+ if (collapsedGroupIds.has(rg.group.id)) {
218
+ const vn = g.node(rg.group.id);
219
+ nodeMap.set(rg.group.id, {
220
+ x: vn.x,
221
+ y: vn.y,
222
+ width: vn.width,
223
+ height: vn.height
224
+ });
225
+ }
226
+ }
227
+ const groups = resolved.groups.map((rg) => {
228
+ const classification = rg.group.classification ?? "cluster";
229
+ if (collapsedGroupIds.has(rg.group.id)) {
230
+ const vn = nodeMap.get(rg.group.id);
231
+ if (!vn) {
232
+ return {
233
+ id: rg.group.id,
234
+ x: 0,
235
+ y: 0,
236
+ width: 0,
237
+ height: 0,
238
+ classification,
239
+ collapsed: true
240
+ };
241
+ }
242
+ return {
243
+ id: rg.group.id,
244
+ x: vn.x - vn.width / 2,
245
+ y: vn.y - vn.height / 2,
246
+ width: vn.width,
247
+ height: vn.height,
248
+ classification,
249
+ collapsed: true
250
+ };
251
+ }
252
+ const members = rg.group.activityIds.map((id) => nodeMap.get(id)).filter(
253
+ (n) => n !== void 0
254
+ );
255
+ if (members.length === 0) {
256
+ return {
257
+ id: rg.group.id,
258
+ x: 0,
259
+ y: 0,
260
+ width: 0,
261
+ height: 0,
262
+ classification
263
+ };
264
+ }
265
+ let minX = Infinity;
266
+ let minY = Infinity;
267
+ let maxX = -Infinity;
268
+ let maxY = -Infinity;
269
+ for (const m of members) {
270
+ const left = m.x - m.width / 2;
271
+ const right = m.x + m.width / 2;
272
+ const top = m.y - m.height / 2;
273
+ const bottom = m.y + m.height / 2;
274
+ if (left < minX) minX = left;
275
+ if (right > maxX) maxX = right;
276
+ if (top < minY) minY = top;
277
+ if (bottom > maxY) maxY = bottom;
278
+ }
279
+ return {
280
+ id: rg.group.id,
281
+ x: minX - GROUP_PADDING,
282
+ y: minY - GROUP_TOP_PADDING,
283
+ width: maxX - minX + GROUP_PADDING * 2,
284
+ height: maxY - minY + GROUP_TOP_PADDING + GROUP_PADDING,
285
+ classification
286
+ };
287
+ });
288
+ let totalW = 0;
289
+ let totalH = 0;
290
+ for (const n of nodes) {
291
+ const right = n.x + n.width / 2;
292
+ const bottom = n.y + n.height / 2;
293
+ if (right > totalW) totalW = right;
294
+ if (bottom > totalH) totalH = bottom;
295
+ }
296
+ for (const grp of groups) {
297
+ if (grp.x + grp.width > totalW) totalW = grp.x + grp.width;
298
+ if (grp.y + grp.height > totalH) totalH = grp.y + grp.height;
299
+ }
300
+ return {
301
+ nodes,
302
+ edges,
303
+ groups,
304
+ width: totalW + DIAGRAM_PADDING,
305
+ height: totalH + DIAGRAM_PADDING
306
+ };
307
+ }
308
+ function applySwimLanes(g, resolved, _memberToGroup, collapsedGroupIds) {
309
+ const expanded = resolved.groups.filter(
310
+ (rg) => !collapsedGroupIds.has(rg.group.id)
311
+ );
312
+ if (expanded.length === 0) return false;
313
+ const isLR = resolved.options.direction !== "TB";
314
+ const rankAxis = isLR ? "x" : "y";
315
+ const slotAxis = isLR ? "y" : "x";
316
+ let spineIdx = 1;
317
+ let spineMembers = 0;
318
+ expanded.forEach((rg, i) => {
319
+ if (rg.group.activityIds.length > spineMembers) {
320
+ spineMembers = rg.group.activityIds.length;
321
+ spineIdx = i + 1;
322
+ }
323
+ });
324
+ const laneOf = /* @__PURE__ */ new Map();
325
+ expanded.forEach((rg, i) => {
326
+ for (const aid of rg.group.activityIds) laneOf.set(aid, i + 1);
327
+ });
328
+ for (const id of g.nodes()) {
329
+ if (!laneOf.has(id)) laneOf.set(id, spineIdx);
330
+ }
331
+ const spineMemberSet = new Set(
332
+ expanded[spineIdx - 1]?.group.activityIds ?? []
333
+ );
334
+ const numLanes = expanded.length + 1;
335
+ const rankBuckets = /* @__PURE__ */ new Map();
336
+ for (const id of g.nodes()) {
337
+ const node = g.node(id);
338
+ if (!node) continue;
339
+ const rankKey = Math.round(node[rankAxis]);
340
+ const laneIdx = laneOf.get(id) ?? spineIdx;
341
+ let byLane = rankBuckets.get(rankKey);
342
+ if (!byLane) {
343
+ byLane = /* @__PURE__ */ new Map();
344
+ rankBuckets.set(rankKey, byLane);
345
+ }
346
+ if (!byLane.has(laneIdx)) byLane.set(laneIdx, []);
347
+ byLane.get(laneIdx).push(id);
348
+ }
349
+ const laneSlots = new Array(numLanes).fill(0);
350
+ for (const byLane of rankBuckets.values()) {
351
+ for (const [li, members] of byLane) {
352
+ if (members.length > laneSlots[li]) laneSlots[li] = members.length;
353
+ }
354
+ }
355
+ const slotSize = isLR ? DEFAULT_NODE_HEIGHT : g.node(g.nodes()[0])?.width ?? DEFAULT_NODE_HEIGHT;
356
+ const laneSize = new Array(numLanes).fill(0);
357
+ for (let i = 1; i < numLanes; i++) {
358
+ const slots = laneSlots[i];
359
+ if (slots === 0) {
360
+ laneSize[i] = 0;
361
+ continue;
362
+ }
363
+ const slotsExtent = slots * slotSize + Math.max(0, slots - 1) * SWIMLANE_SLOT_SEP;
364
+ laneSize[i] = GROUP_TOP_PADDING + slotsExtent + GROUP_PADDING;
365
+ }
366
+ const laneOrder = [
367
+ spineIdx,
368
+ ...Array.from({ length: expanded.length }, (_, i) => i + 1).filter(
369
+ (i) => i !== spineIdx
370
+ )
371
+ ];
372
+ const laneStart = new Array(numLanes).fill(0);
373
+ let cursor = DIAGRAM_PADDING;
374
+ for (const li of laneOrder) {
375
+ laneStart[li] = cursor;
376
+ if (laneSize[li] > 0) cursor += laneSize[li] + SWIMLANE_GAP;
377
+ }
378
+ const critOf = (id) => {
379
+ const r = resolved.activities.find((a) => a.activity.id === id);
380
+ if (r) {
381
+ return r.criticality !== null ? r.criticality : r.isCriticalPath ? 1 : 0;
382
+ }
383
+ const rg = resolved.groups.find((x) => x.group.id === id);
384
+ if (!rg) return 0;
385
+ let m = 0;
386
+ for (const aid of rg.group.activityIds) {
387
+ const ar = resolved.activities.find((a) => a.activity.id === aid);
388
+ if (!ar) continue;
389
+ const c = ar.criticality !== null ? ar.criticality : ar.isCriticalPath ? 1 : 0;
390
+ if (c > m) m = c;
391
+ }
392
+ return m;
393
+ };
394
+ const oldSlot = /* @__PURE__ */ new Map();
395
+ for (const id of g.nodes()) {
396
+ oldSlot.set(id, g.node(id)[slotAxis]);
397
+ }
398
+ for (const byLane of rankBuckets.values()) {
399
+ for (const [li, members] of byLane) {
400
+ const slotStripStart = laneStart[li] + GROUP_TOP_PADDING;
401
+ const sorted = [...members].sort((a, b) => {
402
+ const aSpine = spineMemberSet.has(a) ? 0 : 1;
403
+ const bSpine = spineMemberSet.has(b) ? 0 : 1;
404
+ if (aSpine !== bSpine) return aSpine - bSpine;
405
+ const ca = critOf(a);
406
+ const cb = critOf(b);
407
+ if (cb !== ca) return cb - ca;
408
+ return (oldSlot.get(a) ?? 0) - (oldSlot.get(b) ?? 0);
409
+ });
410
+ sorted.forEach((id, idx) => {
411
+ const node = g.node(id);
412
+ node[slotAxis] = slotStripStart + slotSize / 2 + idx * (slotSize + SWIMLANE_SLOT_SEP);
413
+ });
414
+ }
415
+ }
416
+ const dir = resolved.options.direction;
417
+ for (const e of g.edges()) {
418
+ const src = g.node(e.v);
419
+ const tgt = g.node(e.w);
420
+ if (!src || !tgt) continue;
421
+ const data = g.edge(e);
422
+ if (!data) continue;
423
+ data.points = smoothEdge(src, tgt, dir);
424
+ }
425
+ return true;
426
+ }
427
+ function centerByCriticality(g, resolved, memberToGroup, collapsedGroupIds) {
428
+ const critById = /* @__PURE__ */ new Map();
429
+ for (const r of resolved.activities) {
430
+ if (memberToGroup.has(r.activity.id)) continue;
431
+ const c = r.criticality !== null ? r.criticality : r.isCriticalPath ? 1 : 0;
432
+ critById.set(r.activity.id, c);
433
+ }
434
+ for (const rg of resolved.groups) {
435
+ if (!collapsedGroupIds.has(rg.group.id)) continue;
436
+ let maxC = 0;
437
+ for (const aid of rg.group.activityIds) {
438
+ const r = resolved.activities.find((x) => x.activity.id === aid);
439
+ if (!r) continue;
440
+ const c = r.criticality !== null ? r.criticality : r.isCriticalPath ? 1 : 0;
441
+ if (c > maxC) maxC = c;
442
+ }
443
+ critById.set(rg.group.id, maxC);
444
+ }
445
+ const rankAxis = resolved.options.direction === "TB" ? "y" : "x";
446
+ const slotAxis = resolved.options.direction === "TB" ? "x" : "y";
447
+ const buckets = /* @__PURE__ */ new Map();
448
+ for (const id of g.nodes()) {
449
+ const node = g.node(id);
450
+ if (!node) continue;
451
+ const key = Math.round(node[rankAxis]);
452
+ if (!buckets.has(key)) buckets.set(key, []);
453
+ buckets.get(key).push(id);
454
+ }
455
+ const shifts = /* @__PURE__ */ new Map();
456
+ for (const ids of buckets.values()) {
457
+ if (ids.length < 2) continue;
458
+ const slots = ids.map((id) => g.node(id)[slotAxis]).sort((a, b) => a - b);
459
+ const currentSlot = /* @__PURE__ */ new Map();
460
+ for (const id of ids) currentSlot.set(id, g.node(id)[slotAxis]);
461
+ const sortedDesc = [...ids].sort((a, b) => {
462
+ const ca = critById.get(a) ?? 0;
463
+ const cb = critById.get(b) ?? 0;
464
+ if (cb !== ca) return cb - ca;
465
+ return (currentSlot.get(a) ?? 0) - (currentSlot.get(b) ?? 0);
466
+ });
467
+ const top = [];
468
+ const bottom = [];
469
+ let middle = null;
470
+ sortedDesc.forEach((id, i) => {
471
+ if (i === 0) middle = id;
472
+ else if (i % 2 === 1) top.unshift(id);
473
+ else bottom.push(id);
474
+ });
475
+ const newOrder = middle ? [...top, middle, ...bottom] : [...top, ...bottom];
476
+ newOrder.forEach((id, i) => {
477
+ const node = g.node(id);
478
+ const oldVal = node[slotAxis];
479
+ const newVal = slots[i];
480
+ shifts.set(id, newVal - oldVal);
481
+ node[slotAxis] = newVal;
482
+ });
483
+ }
484
+ if (shifts.size > 0) {
485
+ const dir = resolved.options.direction;
486
+ for (const e of g.edges()) {
487
+ if (!shifts.has(e.v) && !shifts.has(e.w)) continue;
488
+ const src = g.node(e.v);
489
+ const tgt = g.node(e.w);
490
+ if (!src || !tgt) continue;
491
+ const data = g.edge(e);
492
+ if (!data) continue;
493
+ data.points = smoothEdge(src, tgt, dir);
494
+ }
495
+ }
496
+ }
497
+ function smoothEdge(src, tgt, direction) {
498
+ if (direction === "TB") {
499
+ const sy = src.y + src.height / 2;
500
+ const ty = tgt.y - tgt.height / 2;
501
+ const span2 = ty - sy;
502
+ const pad2 = Math.max(20, Math.abs(span2) * 0.3);
503
+ return [
504
+ { x: src.x, y: sy },
505
+ { x: src.x, y: sy + Math.sign(span2 || 1) * pad2 },
506
+ { x: tgt.x, y: ty - Math.sign(span2 || 1) * pad2 },
507
+ { x: tgt.x, y: ty }
508
+ ];
509
+ }
510
+ const sx = src.x + src.width / 2;
511
+ const tx = tgt.x - tgt.width / 2;
512
+ const span = tx - sx;
513
+ const pad = Math.max(20, Math.abs(span) * 0.3);
514
+ return [
515
+ { x: sx, y: src.y },
516
+ { x: sx + Math.sign(span || 1) * pad, y: src.y },
517
+ { x: tx - Math.sign(span || 1) * pad, y: tgt.y },
518
+ { x: tx, y: tgt.y }
519
+ ];
520
+ }
521
+ function reduceCrossings(g, direction) {
522
+ const isLR = direction !== "TB";
523
+ const rankAxis = isLR ? "x" : "y";
524
+ const slotAxis = isLR ? "y" : "x";
525
+ const buckets = /* @__PURE__ */ new Map();
526
+ for (const id of g.nodes()) {
527
+ const node = g.node(id);
528
+ if (!node) continue;
529
+ const key = Math.round(node[rankAxis]);
530
+ if (!buckets.has(key)) buckets.set(key, []);
531
+ buckets.get(key).push(id);
532
+ }
533
+ const edges = g.edges().map((e) => ({ v: e.v, w: e.w }));
534
+ const countCrossings = () => {
535
+ let total = 0;
536
+ for (let i = 0; i < edges.length; i++) {
537
+ const a = edges[i];
538
+ const a1 = g.node(a.v);
539
+ const a2 = g.node(a.w);
540
+ if (!a1 || !a2) continue;
541
+ for (let j = i + 1; j < edges.length; j++) {
542
+ const b = edges[j];
543
+ if (a.v === b.v || a.v === b.w || a.w === b.v || a.w === b.w) continue;
544
+ const b1 = g.node(b.v);
545
+ const b2 = g.node(b.w);
546
+ if (!b1 || !b2) continue;
547
+ if (segmentsCross(a1, a2, b1, b2)) total++;
548
+ }
549
+ }
550
+ return total;
551
+ };
552
+ const MAX_ITER = 8;
553
+ let baseline = countCrossings();
554
+ if (baseline === 0) return;
555
+ for (let iter = 0; iter < MAX_ITER; iter++) {
556
+ let improved = false;
557
+ for (const ids of buckets.values()) {
558
+ if (ids.length < 2) continue;
559
+ const sorted = ids.slice().sort(
560
+ (a, b) => g.node(a)[slotAxis] - g.node(b)[slotAxis]
561
+ );
562
+ for (let i = 0; i < sorted.length - 1; i++) {
563
+ const a = sorted[i];
564
+ const b = sorted[i + 1];
565
+ const an = g.node(a);
566
+ const bn = g.node(b);
567
+ const av = an[slotAxis];
568
+ const bv = bn[slotAxis];
569
+ an[slotAxis] = bv;
570
+ bn[slotAxis] = av;
571
+ const after = countCrossings();
572
+ if (after < baseline) {
573
+ baseline = after;
574
+ improved = true;
575
+ } else {
576
+ an[slotAxis] = av;
577
+ bn[slotAxis] = bv;
578
+ }
579
+ }
580
+ }
581
+ if (!improved || baseline === 0) break;
582
+ }
583
+ for (const e of g.edges()) {
584
+ const src = g.node(e.v);
585
+ const tgt = g.node(e.w);
586
+ if (!src || !tgt) continue;
587
+ const data = g.edge(e);
588
+ if (!data) continue;
589
+ data.points = smoothEdge(src, tgt, direction);
590
+ }
591
+ }
592
+ function segmentsCross(a1, a2, b1, b2) {
593
+ const ccw = (p, q, r) => (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);
594
+ const d1 = ccw(b1, b2, a1);
595
+ const d2 = ccw(b1, b2, a2);
596
+ const d3 = ccw(a1, a2, b1);
597
+ const d4 = ccw(a1, a2, b2);
598
+ return (d1 > 0 && d2 < 0 || d1 < 0 && d2 > 0) && (d3 > 0 && d4 < 0 || d3 < 0 && d4 > 0);
599
+ }
600
+
601
+ export {
602
+ computeNodeSizing,
603
+ layoutPert,
604
+ relayoutPert
605
+ };
606
+ //# sourceMappingURL=chunk-4OHACBGX.js.map
@@ -0,0 +1,21 @@
1
+ // src/utils/note-box/constants.ts
2
+ var NOTE_MAX_W = 200;
3
+ var NOTE_FOLD = 10;
4
+ var NOTE_PAD_H = 8;
5
+ var NOTE_PAD_V = 6;
6
+ var NOTE_FONT_SIZE = 10;
7
+ var NOTE_LINE_H = 14;
8
+ var NOTE_GAP = 22;
9
+ var NOTE_BULLET_INDENT = 10;
10
+
11
+ export {
12
+ NOTE_MAX_W,
13
+ NOTE_FOLD,
14
+ NOTE_PAD_H,
15
+ NOTE_PAD_V,
16
+ NOTE_FONT_SIZE,
17
+ NOTE_LINE_H,
18
+ NOTE_GAP,
19
+ NOTE_BULLET_INDENT
20
+ };
21
+ //# sourceMappingURL=chunk-5DH3KYFH.js.map
@@ -0,0 +1,76 @@
1
+ import {
2
+ extractColor,
3
+ measureIndent
4
+ } from "./chunk-Y3J7VR52.js";
5
+ import {
6
+ makeDgmoError
7
+ } from "./chunk-CXK4DZH3.js";
8
+
9
+ // src/utils/notes/parse.ts
10
+ function parseNoteHeader(rest) {
11
+ const t = rest.trim();
12
+ const quoted = t.match(/^"([^"]+)"\s*(.*)$/);
13
+ if (quoted) {
14
+ return { ref: quoted[1].trim(), inlineBody: quoted[2].trim() };
15
+ }
16
+ const m = t.match(/^(\S+)\s*(.*)$/);
17
+ if (m) {
18
+ return { ref: m[1], inlineBody: m[2].trim() };
19
+ }
20
+ return { ref: t, inlineBody: "" };
21
+ }
22
+ function collectNoteBody(lines, noteIndex, noteIndent, inlineBody) {
23
+ const parts = [];
24
+ if (inlineBody) parts.push(inlineBody);
25
+ let lastIndex = noteIndex;
26
+ let endLineNumber = noteIndex + 1;
27
+ for (let j = noteIndex + 1; j < lines.length; j++) {
28
+ const raw = lines[j];
29
+ const trimmed = raw.trim();
30
+ if (!trimmed) break;
31
+ if (measureIndent(raw) <= noteIndent) break;
32
+ parts.push(trimmed);
33
+ lastIndex = j;
34
+ endLineNumber = j + 1;
35
+ }
36
+ return { body: parts.join("\n"), endLineNumber, lastIndex };
37
+ }
38
+ function tryCollectNote(lines, index, indent, palette, diagnostics) {
39
+ const trimmed = lines[index].trim();
40
+ const m = trimmed.match(/^note\s+(.+)$/i);
41
+ if (!m || /^note\s+->/i.test(trimmed)) return null;
42
+ const lineNumber = index + 1;
43
+ const { label: headerNoColor, color } = extractColor(
44
+ m[1],
45
+ palette,
46
+ diagnostics,
47
+ lineNumber
48
+ );
49
+ const { ref, inlineBody } = parseNoteHeader(headerNoColor);
50
+ const collected = collectNoteBody(lines, index, indent, inlineBody);
51
+ if (!collected.body.trim()) {
52
+ diagnostics.push(
53
+ makeDgmoError(
54
+ lineNumber,
55
+ `Note on "${ref}" has no text \u2014 ignored.`,
56
+ "warning"
57
+ )
58
+ );
59
+ return { lastIndex: collected.lastIndex };
60
+ }
61
+ return {
62
+ note: {
63
+ ref,
64
+ body: collected.body,
65
+ ...color && { color },
66
+ lineNumber,
67
+ endLineNumber: collected.endLineNumber
68
+ },
69
+ lastIndex: collected.lastIndex
70
+ };
71
+ }
72
+
73
+ export {
74
+ tryCollectNote
75
+ };
76
+ //# sourceMappingURL=chunk-5MLYVTYM.js.map