@diagrammo/dgmo 0.49.0 → 0.50.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 (192) hide show
  1. package/.cursorrules +6 -2
  2. package/.github/copilot-instructions.md +6 -2
  3. package/.windsurfrules +6 -2
  4. package/SKILL.md +6 -2
  5. package/dist/advanced.d.ts +419 -12
  6. package/dist/advanced.js +557 -195
  7. package/dist/auto.js +129 -119
  8. package/dist/auto.mjs +11543 -4815
  9. package/dist/block.js +145 -48
  10. package/dist/{charts-d3-EW3YQTEA.js → charts-d3-DKUD7MQE.js} +5 -5
  11. package/dist/{chunk-5FGDJIJX.js → chunk-2C56LEML.js} +3 -3
  12. package/dist/{chunk-35BBZDFE.js → chunk-2JJ2KNPI.js} +4 -4
  13. package/dist/{chunk-ZTLWVRNS.js → chunk-2QYTMIRR.js} +2 -2
  14. package/dist/{chunk-VC3TR4NL.js → chunk-3G6TMNVF.js} +3 -3
  15. package/dist/{chunk-ZDUQGL3N.js → chunk-3LKM6FMW.js} +2 -2
  16. package/dist/{chunk-4BD7EVPK.js → chunk-3P2DKJCG.js} +2 -2
  17. package/dist/{chunk-6CLKNXVP.js → chunk-3TDRHT4J.js} +457 -78
  18. package/dist/chunk-3XPUDB7B.js +420 -0
  19. package/dist/{chunk-DDTJ5N7Q.js → chunk-3ZPC476N.js} +6 -6
  20. package/dist/{chunk-BPIJLRYE.js → chunk-4BMJQFNK.js} +3 -3
  21. package/dist/{chunk-N4J5KGWG.js → chunk-4S723I74.js} +8 -8
  22. package/dist/{chunk-4YNP6O47.js → chunk-5JSWBPZZ.js} +3 -3
  23. package/dist/{chunk-KUBBJ2CD.js → chunk-5Z736BSU.js} +6 -6
  24. package/dist/{chunk-MJCG5K2O.js → chunk-6BFZKBGD.js} +2 -2
  25. package/dist/{chunk-XCC2RENT.js → chunk-6IAA2QQ2.js} +2 -2
  26. package/dist/{chunk-FUCAB3KQ.js → chunk-6M5PJFQG.js} +3 -3
  27. package/dist/{chunk-T7IKPCMI.js → chunk-6X4AKWLF.js} +3 -3
  28. package/dist/{chunk-JFPY3UJ7.js → chunk-6ZT4U37Q.js} +8 -8
  29. package/dist/{chunk-CLR4A2N2.js → chunk-7G2ER4CY.js} +4 -4
  30. package/dist/chunk-7PQYTZMA.js +681 -0
  31. package/dist/{chunk-LG4TWW4U.js → chunk-7RB5Q6MB.js} +8 -8
  32. package/dist/{chunk-7OVSJI2V.js → chunk-A3WQVFBS.js} +3 -3
  33. package/dist/{chunk-X2CH42BN.js → chunk-ASS5YYIZ.js} +7 -7
  34. package/dist/{chunk-3NFJWFNP.js → chunk-BDXC7MDK.js} +1045 -124
  35. package/dist/chunk-BTUTZMPT.js +482 -0
  36. package/dist/{chunk-UVCXZEGU.js → chunk-CVV36CWI.js} +2 -2
  37. package/dist/{chunk-TC3YWBFO.js → chunk-DMJJ3CEQ.js} +29 -8
  38. package/dist/{chunk-NVT6C2VE.js → chunk-EJTKV7CY.js} +4 -4
  39. package/dist/{chunk-4NQ3IKUM.js → chunk-ER5SCQWQ.js} +5 -5
  40. package/dist/{chunk-7VLUGEMJ.js → chunk-F5UDBSJY.js} +4 -4
  41. package/dist/{chunk-IHLSHCPZ.js → chunk-FAL7NOK3.js} +5 -5
  42. package/dist/{chunk-YRVLP7UU.js → chunk-FB2WHOEQ.js} +4 -4
  43. package/dist/chunk-FL4IOQ37.js +379 -0
  44. package/dist/{chunk-6VE3VLWM.js → chunk-GBE54KY6.js} +6 -5
  45. package/dist/{chunk-ZXL6MB4R.js → chunk-GL5UZ6NY.js} +3 -3
  46. package/dist/{chunk-3BIAFYD2.js → chunk-GPWHQ5FJ.js} +2 -2
  47. package/dist/chunk-GROQGHCT.js +960 -0
  48. package/dist/{chunk-GB3YZTAM.js → chunk-H73FP42Q.js} +5 -5
  49. package/dist/{chunk-O5MQPK7E.js → chunk-I4IFRCUB.js} +3 -3
  50. package/dist/{chunk-IUK7AGD4.js → chunk-I7F2A35O.js} +2 -2
  51. package/dist/{chunk-YTN572Q2.js → chunk-IA3FJYWR.js} +2 -2
  52. package/dist/{chunk-RI4NIMFP.js → chunk-JFYIP7XU.js} +75 -35
  53. package/dist/{chunk-UWDO3O52.js → chunk-JZNMXEIV.js} +2 -2
  54. package/dist/chunk-KJXIHOVL.js +940 -0
  55. package/dist/{chunk-26RVGM44.js → chunk-L2ZTFHAY.js} +2 -2
  56. package/dist/{chunk-PU3AUQPA.js → chunk-M5RXSRO2.js} +2 -2
  57. package/dist/{chunk-XKTN7CZF.js → chunk-NFFIKVNO.js} +4 -4
  58. package/dist/{chunk-SVDWQGX2.js → chunk-NISQC5KW.js} +139 -78
  59. package/dist/{chunk-4HVNZ7WF.js → chunk-O4VUFXIH.js} +3 -3
  60. package/dist/{chunk-F743CM2N.js → chunk-O76UD6VJ.js} +3 -3
  61. package/dist/{chunk-TLKMTQYL.js → chunk-OHQEMBLI.js} +3 -3
  62. package/dist/{chunk-BGJV5ATD.js → chunk-ONA5KPV3.js} +2 -2
  63. package/dist/{chunk-ZNQX6QWH.js → chunk-OTAL43EH.js} +6 -2
  64. package/dist/{chunk-FMKTYMP4.js → chunk-OTP5KVLO.js} +3 -3
  65. package/dist/{chunk-5ZZLLBFK.js → chunk-PGEGPSCZ.js} +2 -2
  66. package/dist/{chunk-XJ7J6WOO.js → chunk-PJUGRJHJ.js} +4 -4
  67. package/dist/{chunk-6SA7FJE4.js → chunk-PLZI6KPM.js} +10 -10
  68. package/dist/{chunk-AJ2PEY7J.js → chunk-PMN3Q7RJ.js} +2 -2
  69. package/dist/chunk-Q4V4XQWV.js +158 -0
  70. package/dist/{chunk-5XCM7UUW.js → chunk-QDFNCATJ.js} +99 -35
  71. package/dist/{chunk-CEHZOPGM.js → chunk-QFQ35BTO.js} +2 -2
  72. package/dist/{chunk-4UDKKGHH.js → chunk-QUJGFNFN.js} +2 -2
  73. package/dist/{chunk-IBC35BTK.js → chunk-R56LASIN.js} +2 -2
  74. package/dist/{chunk-SJEGO2QL.js → chunk-RV26LTUU.js} +4 -4
  75. package/dist/chunk-RV6A2B5S.js +354 -0
  76. package/dist/{chunk-65RTDUZH.js → chunk-S5GRONXL.js} +3 -3
  77. package/dist/{chunk-K6HNAY5V.js → chunk-SCHXJTZL.js} +2 -2
  78. package/dist/{chunk-ALRHIR6I.js → chunk-SGFZZAUO.js} +4 -4
  79. package/dist/{chunk-KV6Y2HE6.js → chunk-SU2VBK4L.js} +4 -4
  80. package/dist/{chunk-D5AVQCDN.js → chunk-T4BRO3Z6.js} +3 -3
  81. package/dist/{chunk-IFK3GIUW.js → chunk-TSA237IM.js} +2 -2
  82. package/dist/{chunk-SQDFK5ZQ.js → chunk-TWCLK2GA.js} +3 -3
  83. package/dist/{chunk-DKEPS5LH.js → chunk-U2HGPLZS.js} +36 -2
  84. package/dist/{chunk-EYN7VFKL.js → chunk-URSQLCTR.js} +3 -3
  85. package/dist/{chunk-BCT5G2VN.js → chunk-UUS2GIJZ.js} +5 -5
  86. package/dist/{chunk-LVHPTBO3.js → chunk-UXOSVCLJ.js} +4 -4
  87. package/dist/{chunk-HBVD67XG.js → chunk-WCUHAQKB.js} +2 -2
  88. package/dist/{chunk-YYX3SU6H.js → chunk-WWN566I7.js} +257 -101
  89. package/dist/{chunk-YM2BSPYW.js → chunk-X2NMFTG3.js} +2 -2
  90. package/dist/{chunk-ZREZOIGS.js → chunk-XCLHOZAM.js} +6 -6
  91. package/dist/{chunk-KQAEKMIX.js → chunk-XDXNDSKO.js} +2 -2
  92. package/dist/{chunk-RTERS6S5.js → chunk-XMVQ5F4M.js} +4 -4
  93. package/dist/{chunk-4FIV4K4Z.js → chunk-YA7D2N2O.js} +7 -7
  94. package/dist/{chunk-B57V3DWN.js → chunk-YB3FW24O.js} +3 -3
  95. package/dist/chunk-YNRDWYZP.js +295 -0
  96. package/dist/{chunk-2WMBWZY2.js → chunk-YZLMKW4T.js} +3 -3
  97. package/dist/{chunk-SGHSY3LU.js → chunk-Z6XJQ6KO.js} +81 -6
  98. package/dist/cli.cjs +153 -144
  99. package/dist/clock.d.ts +10 -0
  100. package/dist/clock.js +235 -0
  101. package/dist/countdown.d.ts +12 -0
  102. package/dist/countdown.js +450 -0
  103. package/dist/dgmo-router-QOMFCOOV.js +84 -0
  104. package/dist/{dimensions-WSIJXT5Q.js → dimensions-P5FSX2QN.js} +5 -5
  105. package/dist/editor.js +39 -1
  106. package/dist/element.js +131 -121
  107. package/dist/element.mjs +11543 -4815
  108. package/dist/{flowchart-parser-IVZN7CQN.js → flowchart-parser-OE4WHLTF.js} +4 -4
  109. package/dist/{flowchart-renderer-GMI2U3DD.js → flowchart-renderer-GPCSMTOR.js} +6 -6
  110. package/dist/highlight.d.ts +17 -1
  111. package/dist/highlight.js +156 -5
  112. package/dist/index.js +50 -45
  113. package/dist/{layout-HQMBPJVS.js → layout-46366KBT.js} +2 -2
  114. package/dist/{layout-D42XE4RE.js → layout-5BG6DFCU.js} +3 -3
  115. package/dist/{layout-K2ZN3Q42.js → layout-T3OZU5QW.js} +4 -4
  116. package/dist/{layout-S3EK4IYO.js → layout-TJIWF7EM.js} +4 -4
  117. package/dist/{layout-GZ2CWONU.js → layout-VYELEAW7.js} +4 -4
  118. package/dist/{layout-4Z5JM7PT.js → layout-WZHNDT2O.js} +4 -4
  119. package/dist/{parser-OBQG655V.js → parser-45DENHFZ.js} +4 -4
  120. package/dist/{parser-MCJWF5G3.js → parser-4AI5ZN5F.js} +3 -3
  121. package/dist/{parser-SMBJO3XN.js → parser-4P36TUVD.js} +4 -4
  122. package/dist/{parser-ZYC3XGNS.js → parser-5AURY4A6.js} +4 -4
  123. package/dist/{parser-WISPH7LW.js → parser-A2BEFMGK.js} +4 -4
  124. package/dist/parser-B5FVS7O6.js +11 -0
  125. package/dist/{parser-KPMN5KKE.js → parser-C2HF2C2E.js} +4 -4
  126. package/dist/parser-CSFUN3CT.js +14 -0
  127. package/dist/{parser-TITK4YW6.js → parser-D3QT6GWN.js} +5 -5
  128. package/dist/{parser-ZKF5K2H2.js → parser-D5637H5H.js} +4 -4
  129. package/dist/{parser-IKZFTLOJ.js → parser-DFFEDKHH.js} +3 -3
  130. package/dist/parser-DOKMZXVZ.js +13 -0
  131. package/dist/parser-FMPCVFRK.js +15 -0
  132. package/dist/{parser-UBGPTIZD.js → parser-HYRTF3DO.js} +3 -3
  133. package/dist/{parser-TNYX5S7E.js → parser-I2UIJKVQ.js} +4 -4
  134. package/dist/{parser-K647FRI4.js → parser-IBWNAPY4.js} +3 -3
  135. package/dist/{parser-JD7OQ2E6.js → parser-KUQWRPIT.js} +4 -4
  136. package/dist/{parser-HVJFTOXL.js → parser-LWKKBNSA.js} +3 -3
  137. package/dist/{parser-4ROBKVUR.js → parser-O4QFCUW7.js} +5 -5
  138. package/dist/{parser-BL7Z72EY.js → parser-PGMQDD4G.js} +4 -4
  139. package/dist/{parser-QJYS7KQQ.js → parser-Q4QKCIWQ.js} +4 -4
  140. package/dist/{parser-UGA23PYK.js → parser-QTOB4KFL.js} +4 -4
  141. package/dist/{parser-DERPY5KC.js → parser-QYYM4QVW.js} +4 -4
  142. package/dist/{parser-GFSOPDB7.js → parser-RZMQP7MM.js} +4 -4
  143. package/dist/parser-RZPVAQVX.js +11 -0
  144. package/dist/parser-SOUJOEYI.js +13 -0
  145. package/dist/{parser-MBJSBTL5.js → parser-UQE5OWZI.js} +5 -5
  146. package/dist/{parser-MRBPXXIV.js → parser-WAV5JRPT.js} +4 -4
  147. package/dist/{parser-4BKIFG2C.js → parser-YLKYBRIT.js} +5 -5
  148. package/dist/{parser-D6ONJQFR.js → parser-YS7TOS2K.js} +3 -3
  149. package/dist/{parser-CLMFZWCC.js → parser-ZSOWUBML.js} +5 -5
  150. package/dist/{parser-XWUDFJ7P.js → parser-ZTBATMLX.js} +4 -4
  151. package/dist/{renderer-LWGJFT3D.js → renderer-35HSIDMZ.js} +5 -5
  152. package/dist/{renderer-BB5PREMY.js → renderer-4ITCHBT7.js} +4 -4
  153. package/dist/{renderer-YHXPN3GF.js → renderer-67NPCBIS.js} +7 -7
  154. package/dist/{renderer-TPIBXNOS.js → renderer-6GHYK7DX.js} +6 -6
  155. package/dist/{renderer-VICQ4WNY.js → renderer-6RNGHC5Z.js} +5 -5
  156. package/dist/renderer-72LGR2YF.js +14 -0
  157. package/dist/{renderer-W5RMOURB.js → renderer-7SWMIFMM.js} +6 -6
  158. package/dist/{renderer-6L3NBEY5.js → renderer-BBCEFILK.js} +6 -6
  159. package/dist/{renderer-VFUVRNLK.js → renderer-BSW7SRIZ.js} +4 -4
  160. package/dist/{renderer-CGW7QPNA.js → renderer-BY533UWU.js} +7 -7
  161. package/dist/{renderer-V3JEMWMM.js → renderer-BZSBPTZJ.js} +6 -6
  162. package/dist/{renderer-DKESNMU5.js → renderer-CXUC4KAD.js} +6 -6
  163. package/dist/{renderer-XEKIRPI6.js → renderer-FZUKFUNZ.js} +5 -5
  164. package/dist/renderer-G2NLGNKF.js +17 -0
  165. package/dist/{renderer-THD6V5TL.js → renderer-GO3FE3RA.js} +9 -7
  166. package/dist/{renderer-ROV756WT.js → renderer-HPGR6USK.js} +5 -5
  167. package/dist/renderer-ICJN2SA2.js +24 -0
  168. package/dist/{renderer-4IUPINAE.js → renderer-INEXO7B6.js} +7 -7
  169. package/dist/{renderer-SQ3JUAI7.js → renderer-KDYCFRBX.js} +6 -6
  170. package/dist/renderer-KY4KQBTF.js +19 -0
  171. package/dist/{renderer-MJDDU27W.js → renderer-LBN65V45.js} +10 -10
  172. package/dist/{renderer-UZF3JROD.js → renderer-MGBWOCXG.js} +8 -8
  173. package/dist/{renderer-MFJ7HY2H.js → renderer-O4JKUGKO.js} +5 -5
  174. package/dist/{renderer-QL5KO6SK.js → renderer-OOGFODWP.js} +7 -7
  175. package/dist/{renderer-A5VFZQQK.js → renderer-Q6ZKPLS6.js} +6 -6
  176. package/dist/{renderer-TYXRHMRI.js → renderer-SZQ326M5.js} +9 -9
  177. package/dist/{renderer-6T3KK4S3.js → renderer-TKG6LS4U.js} +7 -7
  178. package/dist/{renderer-QNHUXCRL.js → renderer-TQMZGDAX.js} +9 -9
  179. package/dist/{renderer-radial-MHO2VDXN.js → renderer-radial-JELMHQ24.js} +6 -6
  180. package/dist/{state-parser-RX3GXOIB.js → state-parser-3REXRK3R.js} +4 -4
  181. package/dist/{state-renderer-AJUKGNWU.js → state-renderer-XYLNRWXR.js} +6 -6
  182. package/docs/ai-integration.md +6 -2
  183. package/docs/language-reference.md +253 -22
  184. package/gallery/fixtures/body.dgmo +17 -0
  185. package/gallery/fixtures/bracket.dgmo +30 -0
  186. package/gallery/fixtures/clock.dgmo +8 -0
  187. package/gallery/fixtures/countdown.dgmo +3 -0
  188. package/gallery/fixtures/goal.dgmo +4 -0
  189. package/package.json +12 -4
  190. package/dist/dgmo-router-ODKPEJ3P.js +0 -79
  191. package/dist/parser-667RGSUW.js +0 -13
  192. package/dist/parser-J3P2D6IP.js +0 -13
@@ -9,12 +9,12 @@ import {
9
9
  tagAttrKey,
10
10
  validateTagGroupNames,
11
11
  validateTagValues
12
- } from "./chunk-HBVD67XG.js";
12
+ } from "./chunk-WCUHAQKB.js";
13
13
  import {
14
14
  extractColor,
15
15
  measureIndent,
16
16
  parseFirstLine
17
- } from "./chunk-ZNQX6QWH.js";
17
+ } from "./chunk-OTAL43EH.js";
18
18
  import {
19
19
  formatDgmoError,
20
20
  makeDgmoError,
@@ -335,4 +335,4 @@ function parseBlockTail(tail, aliasMap) {
335
335
  export {
336
336
  parseBlock
337
337
  };
338
- //# sourceMappingURL=chunk-B57V3DWN.js.map
338
+ //# sourceMappingURL=chunk-YB3FW24O.js.map
@@ -0,0 +1,295 @@
1
+ // src/countdown/resolve.ts
2
+ var DAY_MS = 864e5;
3
+ var WEEK_MS = 7 * DAY_MS;
4
+ function monthIndex(token) {
5
+ const t = token.trim().toLowerCase().slice(0, 3);
6
+ const i = [
7
+ "jan",
8
+ "feb",
9
+ "mar",
10
+ "apr",
11
+ "may",
12
+ "jun",
13
+ "jul",
14
+ "aug",
15
+ "sep",
16
+ "oct",
17
+ "nov",
18
+ "dec"
19
+ ].indexOf(t);
20
+ return i < 0 ? null : i;
21
+ }
22
+ function weekdayIndex(token) {
23
+ const t = token.trim().toLowerCase().slice(0, 3);
24
+ const i = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"].indexOf(t);
25
+ return i < 0 ? null : i;
26
+ }
27
+ function ordinalWord(n) {
28
+ const abs = Math.abs(n);
29
+ const tens = abs % 100;
30
+ let suffix = "th";
31
+ if (tens < 11 || tens > 13) {
32
+ const ones = abs % 10;
33
+ suffix = ones === 1 ? "st" : ones === 2 ? "nd" : ones === 3 ? "rd" : "th";
34
+ }
35
+ return `${n}${suffix}`;
36
+ }
37
+ function applyOrdinalTemplate(template, n) {
38
+ return template.replace(/\bNth\b/g, ordinalWord(n)).replace(/\bN\b/g, String(n));
39
+ }
40
+ function dayStart(ms) {
41
+ const d = new Date(ms);
42
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
43
+ }
44
+ function nthWeekdayOfMonth(year, month, weekday, nth, hour, minute) {
45
+ if (nth < 0) {
46
+ const last = new Date(year, month + 1, 0).getDate();
47
+ for (let d = last; d >= 1; d--) {
48
+ if (new Date(year, month, d).getDay() === weekday) {
49
+ return new Date(year, month, d, hour, minute).getTime();
50
+ }
51
+ }
52
+ return null;
53
+ }
54
+ const firstDow = new Date(year, month, 1).getDay();
55
+ const offset = (weekday - firstDow + 7) % 7;
56
+ const day = 1 + offset + (nth - 1) * 7;
57
+ if (day > new Date(year, month + 1, 0).getDate()) return null;
58
+ return new Date(year, month, day, hour, minute).getTime();
59
+ }
60
+ function resolveNext(rule, now) {
61
+ const nowD = new Date(now);
62
+ const { hour, minute } = rule;
63
+ const passes = rule.allDay ? (t) => dayStart(t) >= dayStart(now) : (t) => t > now;
64
+ const dayExists = (y, m, d) => new Date(y, m, d).getMonth() === m;
65
+ switch (rule.kind) {
66
+ case "month-day": {
67
+ const month = rule.month;
68
+ const day = rule.day;
69
+ for (let y = nowD.getFullYear(); ; y++) {
70
+ if (!dayExists(y, month, day)) continue;
71
+ const t = new Date(y, month, day, hour, minute).getTime();
72
+ if (passes(t)) return t;
73
+ }
74
+ }
75
+ case "nth-weekday":
76
+ case "last-weekday": {
77
+ const weekday = rule.weekday;
78
+ const nth = rule.kind === "last-weekday" ? -1 : rule.nth;
79
+ let y = nowD.getFullYear();
80
+ let m = nowD.getMonth();
81
+ for (let i = 0; i < 24; i++) {
82
+ const t = nthWeekdayOfMonth(y, m, weekday, nth, hour, minute);
83
+ if (t !== null && passes(t)) return t;
84
+ m++;
85
+ if (m > 11) {
86
+ m = 0;
87
+ y++;
88
+ }
89
+ }
90
+ return now + WEEK_MS;
91
+ }
92
+ case "weekly": {
93
+ const weekday = rule.weekday;
94
+ for (let i = 0; i < 8; i++) {
95
+ const d = new Date(
96
+ nowD.getFullYear(),
97
+ nowD.getMonth(),
98
+ nowD.getDate() + i,
99
+ hour,
100
+ minute
101
+ );
102
+ if (d.getDay() === weekday && passes(d.getTime())) return d.getTime();
103
+ }
104
+ return now + WEEK_MS;
105
+ }
106
+ case "interval": {
107
+ const n = rule.intervalN ?? 1;
108
+ const anchor = rule.anchorMs ?? now;
109
+ if (rule.intervalUnit === "month") {
110
+ const a = new Date(anchor);
111
+ const day = a.getDate();
112
+ for (let k = 0; ; k++) {
113
+ const y = a.getFullYear();
114
+ const m = a.getMonth() + k * n;
115
+ const yy = y + Math.floor(m / 12);
116
+ const mm = (m % 12 + 12) % 12;
117
+ if (!dayExists(yy, mm, day)) continue;
118
+ const t2 = new Date(yy, mm, day, hour, minute).getTime();
119
+ if (passes(t2)) return t2;
120
+ }
121
+ }
122
+ const step = (rule.intervalUnit === "week" ? WEEK_MS : DAY_MS) * n;
123
+ let t = anchor;
124
+ if (!passes(t)) {
125
+ const k = Math.max(0, Math.floor((now - anchor) / step));
126
+ t = anchor + k * step;
127
+ while (!passes(t)) t += step;
128
+ }
129
+ return t;
130
+ }
131
+ }
132
+ }
133
+ function ordinalFor(resolvedMs, since) {
134
+ return new Date(resolvedMs).getFullYear() - since;
135
+ }
136
+ function roundBy(value, mode) {
137
+ return mode === "down" ? Math.floor(value) : mode === "nearest" ? Math.round(value) : Math.ceil(value);
138
+ }
139
+ function pad2(n) {
140
+ return n < 10 ? "0" + n : String(n);
141
+ }
142
+ function plural(n, unit) {
143
+ return `${n} ${unit}${n === 1 ? "" : "s"}`;
144
+ }
145
+ function formatCount(remainingMs, opts) {
146
+ const { units, round, fields } = opts;
147
+ if (units === "days")
148
+ return plural(roundBy(remainingMs / DAY_MS, round), "day");
149
+ if (units === "weeks")
150
+ return plural(roundBy(remainingMs / WEEK_MS, round), "week");
151
+ const totalSec = Math.floor(remainingMs / 1e3);
152
+ if (units === "clock") {
153
+ const h2 = Math.floor(totalSec / 3600);
154
+ const m2 = Math.floor(totalSec % 3600 / 60);
155
+ const s2 = totalSec % 60;
156
+ return `${pad2(h2)}:${pad2(m2)}:${pad2(s2)}`;
157
+ }
158
+ if (units === "words") {
159
+ const days2 = Math.ceil(remainingMs / DAY_MS);
160
+ if (days2 <= 0) return "now";
161
+ if (days2 === 1) return "tomorrow";
162
+ if (days2 < 14) return `${days2} days`;
163
+ if (days2 < 60) return `${Math.round(days2 / 7)} weeks`;
164
+ return `${Math.round(days2 / 30)} months`;
165
+ }
166
+ const days = Math.floor(totalSec / 86400);
167
+ const h = Math.floor(totalSec % 86400 / 3600);
168
+ const m = Math.floor(totalSec % 3600 / 60);
169
+ const s = totalSec % 60;
170
+ const has = (f) => fields.includes(f);
171
+ const clockParts = [];
172
+ if (has("h")) clockParts.push(pad2(h));
173
+ if (has("m")) clockParts.push(pad2(m));
174
+ if (has("s")) clockParts.push(pad2(s));
175
+ const clock = clockParts.join(":");
176
+ const dayPrefix = has("d") && days > 0 ? `${days}d${clock ? " " : ""}` : "";
177
+ return dayPrefix + clock || plural(days, "day");
178
+ }
179
+ function formatWordsDetail(remainingMs) {
180
+ const totalMin = Math.floor(Math.max(0, remainingMs) / 6e4);
181
+ const d = Math.floor(totalMin / 1440);
182
+ const h = Math.floor(totalMin % 1440 / 60);
183
+ const m = totalMin % 60;
184
+ const parts = [];
185
+ if (d > 0) parts.push(`${d} day${d === 1 ? "" : "s"}`);
186
+ if (d > 0 || h > 0) parts.push(`${h} hour${h === 1 ? "" : "s"}`);
187
+ parts.push(`${m} minute${m === 1 ? "" : "s"}`);
188
+ return parts.join(" ");
189
+ }
190
+ function breakdown(nowMs, targetMs) {
191
+ const n = new Date(nowMs);
192
+ const t = new Date(targetMs);
193
+ let y = t.getFullYear() - n.getFullYear();
194
+ let mo = t.getMonth() - n.getMonth();
195
+ let d = t.getDate() - n.getDate();
196
+ let h = t.getHours() - n.getHours();
197
+ let mi = t.getMinutes() - n.getMinutes();
198
+ let s = t.getSeconds() - n.getSeconds();
199
+ if (s < 0) {
200
+ s += 60;
201
+ mi--;
202
+ }
203
+ if (mi < 0) {
204
+ mi += 60;
205
+ h--;
206
+ }
207
+ if (h < 0) {
208
+ h += 24;
209
+ d--;
210
+ }
211
+ if (d < 0) {
212
+ d += new Date(t.getFullYear(), t.getMonth(), 0).getDate();
213
+ mo--;
214
+ }
215
+ if (mo < 0) {
216
+ mo += 12;
217
+ y--;
218
+ }
219
+ return { years: y, months: mo, days: d, hours: h, minutes: mi, seconds: s };
220
+ }
221
+ function humanUnits(nowMs, targetMs) {
222
+ const b = breakdown(nowMs, targetMs);
223
+ return [
224
+ [b.years, "year"],
225
+ [b.months, "month"],
226
+ [b.days, "day"],
227
+ [b.hours, "hour"],
228
+ [b.minutes, "minute"]
229
+ ];
230
+ }
231
+ function formatHuman(nowMs, targetMs) {
232
+ const units = humanUnits(nowMs, targetMs);
233
+ let i = 0;
234
+ while (i < units.length - 1 && units[i][0] === 0) i++;
235
+ const rest = units.slice(i);
236
+ const say = (arr) => arr.map(([n, u]) => `${n} ${u}${n === 1 ? "" : "s"}`).join(", ");
237
+ const primary = rest.slice(0, 2).filter((p, idx) => p[0] > 0 || idx === 0);
238
+ const secondary = rest.slice(2).filter((p) => p[0] > 0);
239
+ return { big: say(primary) || "now", sub: say(secondary) };
240
+ }
241
+ function formatCompound(nowMs, targetMs, maxUnits = 2) {
242
+ const all = humanUnits(nowMs, targetMs);
243
+ let i = 0;
244
+ while (i < all.length - 1 && all[i][0] === 0) i++;
245
+ const chosen = all.slice(i, i + maxUnits).filter((p, idx) => p[0] > 0 || idx === 0);
246
+ if (!chosen.length) return "now";
247
+ return chosen.map(([n, u]) => `${n} ${u}${n === 1 ? "" : "s"}`).join(", ");
248
+ }
249
+ var WEEKDAY_ABBR = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
250
+ var MONTH_ABBR = [
251
+ "Jan",
252
+ "Feb",
253
+ "Mar",
254
+ "Apr",
255
+ "May",
256
+ "Jun",
257
+ "Jul",
258
+ "Aug",
259
+ "Sep",
260
+ "Oct",
261
+ "Nov",
262
+ "Dec"
263
+ ];
264
+ function formatDate(ms) {
265
+ const d = new Date(ms);
266
+ return `${WEEKDAY_ABBR[d.getDay()]} ${MONTH_ABBR[d.getMonth()]} ${d.getDate()} ${d.getFullYear()}`;
267
+ }
268
+ function formatDateShort(ms) {
269
+ const d = new Date(ms);
270
+ return `${MONTH_ABBR[d.getMonth()]} ${d.getDate()} ${d.getFullYear()}`;
271
+ }
272
+ function formatFooter(resolvedMs, hasTime) {
273
+ const parts = [formatDate(resolvedMs)];
274
+ if (hasTime) {
275
+ const d = new Date(resolvedMs);
276
+ parts.push(`${pad2(d.getHours())}:${pad2(d.getMinutes())}`);
277
+ }
278
+ return parts.join(" \xB7 ");
279
+ }
280
+
281
+ export {
282
+ DAY_MS,
283
+ monthIndex,
284
+ weekdayIndex,
285
+ applyOrdinalTemplate,
286
+ resolveNext,
287
+ ordinalFor,
288
+ formatCount,
289
+ formatWordsDetail,
290
+ formatHuman,
291
+ formatCompound,
292
+ formatDateShort,
293
+ formatFooter
294
+ };
295
+ //# sourceMappingURL=chunk-YNRDWYZP.js.map
@@ -8,7 +8,7 @@ import {
8
8
  stripDefaultModifier,
9
9
  tagAttrKey,
10
10
  validateTagGroupNames
11
- } from "./chunk-HBVD67XG.js";
11
+ } from "./chunk-WCUHAQKB.js";
12
12
  import {
13
13
  JOURNEY_MAP_REGISTRY,
14
14
  OPTION_NOCOLON_RE,
@@ -19,7 +19,7 @@ import {
19
19
  splitNameAndMeta,
20
20
  warnUnknownMetaKeys,
21
21
  withTagAliases
22
- } from "./chunk-ZNQX6QWH.js";
22
+ } from "./chunk-OTAL43EH.js";
23
23
  import {
24
24
  resolveColorWithDiagnostic
25
25
  } from "./chunk-TLVIHFRO.js";
@@ -406,4 +406,4 @@ function parseStepLine(trimmed, lineNumber, counter, aliasMap, warn, diagnostics
406
406
  export {
407
407
  parseJourneyMap
408
408
  };
409
- //# sourceMappingURL=chunk-2WMBWZY2.js.map
409
+ //# sourceMappingURL=chunk-YZLMKW4T.js.map
@@ -12,7 +12,10 @@ var SKETCH_GEOMETRY = {
12
12
  cellPx: 26,
13
13
  /** universal footprint width, in grid cells */
14
14
  footprintCellsW: 8,
15
- /** mandatory gap between footprints, in cells */
15
+ /**
16
+ * Legacy — the gap is now a derived half-unit (footprint/2 per axis), not
17
+ * these cell counts. Kept only so the shape of SKETCH_GEOMETRY is stable.
18
+ */
16
19
  gapCellsX: 4,
17
20
  gapCellsY: 4,
18
21
  /** box reserved top band, px (spec decision 12) */
@@ -23,10 +26,12 @@ var SKETCH_GEOMETRY = {
23
26
  ringFrac: 0.22
24
27
  };
25
28
  var SKETCH_FOOT_W = SKETCH_GEOMETRY.footprintCellsW * SKETCH_GEOMETRY.cellPx;
26
- var SKETCH_FOOT_H = Math.round(SKETCH_FOOT_W / SKETCH_PHI);
27
- var SKETCH_HALF_SLOT_X = (SKETCH_FOOT_W + SKETCH_GEOMETRY.gapCellsX * SKETCH_GEOMETRY.cellPx) / 2;
28
- var SKETCH_HALF_SLOT_Y = (SKETCH_FOOT_H + SKETCH_GEOMETRY.gapCellsY * SKETCH_GEOMETRY.cellPx) / 2;
29
- var SKETCH_SEP = 2;
29
+ var SKETCH_FOOT_H = 2 * Math.round(SKETCH_FOOT_W / SKETCH_PHI / 2);
30
+ var SKETCH_HALF_SLOT_X = SKETCH_FOOT_W / 2;
31
+ var SKETCH_HALF_SLOT_Y = SKETCH_FOOT_H / 2;
32
+ var SKETCH_SEP = 3;
33
+ var SKETCH_SLOT_X = SKETCH_HALF_SLOT_X * SKETCH_SEP;
34
+ var SKETCH_SLOT_Y = SKETCH_HALF_SLOT_Y * SKETCH_SEP;
30
35
  function sketchSlotToPx(c, r) {
31
36
  return { x: c * SKETCH_HALF_SLOT_X, y: r * SKETCH_HALF_SLOT_Y };
32
37
  }
@@ -343,6 +348,74 @@ function layoutSketch(parsed, options = {}) {
343
348
  });
344
349
  }
345
350
  }
351
+ {
352
+ const centerOf = (id) => {
353
+ const n = nodes.find((nd) => nd.id === id);
354
+ if (n) return { x: n.x + n.w / 2, y: n.y + n.h / 2 };
355
+ const b = boxes.find((bx) => bx.id === id);
356
+ if (b) return { x: b.x + b.w / 2, y: b.y + b.h / 2 };
357
+ return null;
358
+ };
359
+ const segHitsRect = (ax, ay, bx, by, rx0, ry0, rx1, ry1) => {
360
+ let t0 = 0;
361
+ let t1 = 1;
362
+ const p = [-(bx - ax), bx - ax, -(by - ay), by - ay];
363
+ const q = [ax - rx0, rx1 - ax, ay - ry0, ry1 - ay];
364
+ for (let i = 0; i < 4; i++) {
365
+ if (p[i] === 0) {
366
+ if (q[i] < 0) return false;
367
+ } else {
368
+ const t = q[i] / p[i];
369
+ if (p[i] < 0) {
370
+ if (t > t1) return false;
371
+ if (t > t0) t0 = t;
372
+ } else {
373
+ if (t < t0) return false;
374
+ if (t < t1) t1 = t;
375
+ }
376
+ }
377
+ }
378
+ return t0 <= t1;
379
+ };
380
+ const warned = /* @__PURE__ */ new Set();
381
+ for (let pass = 0; pass < 4; pass++) {
382
+ let moved = false;
383
+ for (const n of nodes) {
384
+ if (n.boxLabel) continue;
385
+ for (const e of collapsed.edges) {
386
+ if (e.sourceId === n.id || e.targetId === n.id) continue;
387
+ const a = centerOf(e.sourceId);
388
+ const b = centerOf(e.targetId);
389
+ if (!a || !b) continue;
390
+ if (!segHitsRect(a.x, a.y, b.x, b.y, n.x, n.y, n.x + n.w, n.y + n.h))
391
+ continue;
392
+ const ncx = n.x + n.w / 2;
393
+ const ncy = n.y + n.h / 2;
394
+ const m = n;
395
+ if (Math.abs(b.x - a.x) >= Math.abs(b.y - a.y)) {
396
+ const lineY = a.y + (b.y - a.y) * (ncx - a.x) / (b.x - a.x || 1);
397
+ let dir = ncy >= lineY ? 1 : -1;
398
+ if (n.slot.r + dir * SKETCH_SEP < 0) dir = 1;
399
+ m.y += dir * SKETCH_SLOT_Y;
400
+ m.slot = { c: n.slot.c, r: n.slot.r + dir * SKETCH_SEP };
401
+ } else {
402
+ const lineX = a.x + (b.x - a.x) * (ncy - a.y) / (b.y - a.y || 1);
403
+ let dir = ncx >= lineX ? 1 : -1;
404
+ if (n.slot.c + dir * SKETCH_SEP < 0) dir = 1;
405
+ m.x += dir * SKETCH_SLOT_X;
406
+ m.slot = { c: n.slot.c + dir * SKETCH_SEP, r: n.slot.r };
407
+ }
408
+ if (!warned.has(n.id)) {
409
+ overlapWarn(n.lineNumber, n.label);
410
+ warned.add(n.id);
411
+ }
412
+ moved = true;
413
+ break;
414
+ }
415
+ }
416
+ if (!moved) break;
417
+ }
418
+ }
346
419
  let width = 0;
347
420
  let height = 0;
348
421
  for (const n of nodes) {
@@ -370,8 +443,10 @@ export {
370
443
  SKETCH_HALF_SLOT_X,
371
444
  SKETCH_HALF_SLOT_Y,
372
445
  SKETCH_SEP,
446
+ SKETCH_SLOT_X,
447
+ SKETCH_SLOT_Y,
373
448
  sketchSlotToPx,
374
449
  collapseSketch,
375
450
  layoutSketch
376
451
  };
377
- //# sourceMappingURL=chunk-SGHSY3LU.js.map
452
+ //# sourceMappingURL=chunk-Z6XJQ6KO.js.map