@diagrammo/dgmo 0.49.0 → 0.50.1

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 (198) 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.js +557 -195
  6. package/dist/auto.js +129 -119
  7. package/dist/auto.mjs +19496 -12761
  8. package/dist/block.js +145 -48
  9. package/dist/{charts-d3-EW3YQTEA.js → charts-d3-LR6D3D7A.js} +5 -5
  10. package/dist/{chunk-5FGDJIJX.js → chunk-2C56LEML.js} +3 -3
  11. package/dist/{chunk-XJ7J6WOO.js → chunk-2KGXHFYK.js} +4 -4
  12. package/dist/{chunk-T7IKPCMI.js → chunk-3LH5CLP4.js} +3 -3
  13. package/dist/{chunk-ZDUQGL3N.js → chunk-3LKM6FMW.js} +2 -2
  14. package/dist/{chunk-4FIV4K4Z.js → chunk-3NODSS6A.js} +7 -7
  15. package/dist/{chunk-4BD7EVPK.js → chunk-3P2DKJCG.js} +2 -2
  16. package/dist/{chunk-TC3YWBFO.js → chunk-3UIKSPFB.js} +35 -9
  17. package/dist/{chunk-SJEGO2QL.js → chunk-3XGZF2QJ.js} +4 -4
  18. package/dist/chunk-3XPUDB7B.js +420 -0
  19. package/dist/{chunk-O5MQPK7E.js → chunk-3Y2DRD7S.js} +3 -3
  20. package/dist/chunk-3YPY3OXD.js +354 -0
  21. package/dist/{chunk-N4J5KGWG.js → chunk-4MJ7M6YL.js} +8 -8
  22. package/dist/{chunk-JFPY3UJ7.js → chunk-4S52SK6G.js} +8 -8
  23. package/dist/{chunk-ALRHIR6I.js → chunk-5GJYGP5Z.js} +4 -4
  24. package/dist/{chunk-SQDFK5ZQ.js → chunk-5OWVC2A6.js} +3 -3
  25. package/dist/{chunk-7VLUGEMJ.js → chunk-66NVRO4K.js} +4 -4
  26. package/dist/{chunk-ZREZOIGS.js → chunk-66RUL3XF.js} +6 -6
  27. package/dist/{chunk-MJCG5K2O.js → chunk-6BFZKBGD.js} +2 -2
  28. package/dist/{chunk-2WMBWZY2.js → chunk-6HJBFVLO.js} +3 -3
  29. package/dist/{chunk-XCC2RENT.js → chunk-6IAA2QQ2.js} +2 -2
  30. package/dist/{chunk-B57V3DWN.js → chunk-7L3R6I3U.js} +3 -3
  31. package/dist/chunk-7PQYTZMA.js +681 -0
  32. package/dist/{chunk-6SA7FJE4.js → chunk-7QKLIMRZ.js} +10 -10
  33. package/dist/{chunk-YTN572Q2.js → chunk-7TV5Y53Y.js} +2 -2
  34. package/dist/{chunk-6CLKNXVP.js → chunk-BBGDM4NQ.js} +457 -78
  35. package/dist/{chunk-3NFJWFNP.js → chunk-BDXC7MDK.js} +1045 -124
  36. package/dist/{chunk-D5AVQCDN.js → chunk-BH3UYK36.js} +3 -3
  37. package/dist/chunk-BTUTZMPT.js +482 -0
  38. package/dist/{chunk-LVHPTBO3.js → chunk-C2CVAM3U.js} +4 -4
  39. package/dist/{chunk-BCT5G2VN.js → chunk-DFTFPYUD.js} +5 -5
  40. package/dist/{chunk-KV6Y2HE6.js → chunk-DSWVNQVS.js} +4 -4
  41. package/dist/{chunk-4YNP6O47.js → chunk-DZXYF2F5.js} +13 -3
  42. package/dist/{chunk-FUCAB3KQ.js → chunk-EAMEADTV.js} +3 -3
  43. package/dist/chunk-FA6K3FWM.js +940 -0
  44. package/dist/{chunk-HBVD67XG.js → chunk-FJUNPCYI.js} +2 -2
  45. package/dist/{chunk-6VE3VLWM.js → chunk-GBE54KY6.js} +6 -5
  46. package/dist/{chunk-YRVLP7UU.js → chunk-GKC3HILQ.js} +4 -4
  47. package/dist/{chunk-ZXL6MB4R.js → chunk-GL5UZ6NY.js} +3 -3
  48. package/dist/{chunk-GB3YZTAM.js → chunk-H73FP42Q.js} +5 -5
  49. package/dist/{chunk-4UDKKGHH.js → chunk-HEVYAHLW.js} +2 -2
  50. package/dist/{chunk-DDTJ5N7Q.js → chunk-HLJVEAOF.js} +6 -6
  51. package/dist/{chunk-CLR4A2N2.js → chunk-HTMN2Z6U.js} +4 -4
  52. package/dist/{chunk-TLKMTQYL.js → chunk-I2WKW7C7.js} +3 -3
  53. package/dist/{chunk-IUK7AGD4.js → chunk-I7F2A35O.js} +2 -2
  54. package/dist/{chunk-IBC35BTK.js → chunk-IUMPEA64.js} +2 -2
  55. package/dist/{chunk-5XCM7UUW.js → chunk-J6K7RP6P.js} +100 -36
  56. package/dist/{chunk-AJ2PEY7J.js → chunk-JJUOHGX2.js} +2 -2
  57. package/dist/{chunk-CEHZOPGM.js → chunk-KFZYNWWO.js} +2 -2
  58. package/dist/{chunk-4NQ3IKUM.js → chunk-KHEYDLMT.js} +5 -5
  59. package/dist/{chunk-YM2BSPYW.js → chunk-LE4MYMLI.js} +2 -2
  60. package/dist/{chunk-PU3AUQPA.js → chunk-M5RXSRO2.js} +2 -2
  61. package/dist/{chunk-XKTN7CZF.js → chunk-MCZ5LBZD.js} +4 -4
  62. package/dist/{chunk-35BBZDFE.js → chunk-NU3XLTGP.js} +4 -4
  63. package/dist/{chunk-BPIJLRYE.js → chunk-NWED7CYO.js} +3 -3
  64. package/dist/{chunk-YYX3SU6H.js → chunk-OMNGQPEZ.js} +257 -101
  65. package/dist/{chunk-BGJV5ATD.js → chunk-ONA5KPV3.js} +2 -2
  66. package/dist/{chunk-ZNQX6QWH.js → chunk-OTAL43EH.js} +6 -2
  67. package/dist/{chunk-F743CM2N.js → chunk-OTQKUHRS.js} +3 -3
  68. package/dist/{chunk-KUBBJ2CD.js → chunk-P7CE7LXL.js} +6 -6
  69. package/dist/{chunk-UVCXZEGU.js → chunk-PFHVU7UA.js} +2 -2
  70. package/dist/{chunk-5ZZLLBFK.js → chunk-PGEGPSCZ.js} +2 -2
  71. package/dist/chunk-Q4V4XQWV.js +158 -0
  72. package/dist/{chunk-IHLSHCPZ.js → chunk-QJP6PG7F.js} +5 -5
  73. package/dist/{chunk-EYN7VFKL.js → chunk-QROYX7TT.js} +3 -3
  74. package/dist/chunk-QXKWYZNR.js +379 -0
  75. package/dist/{chunk-VC3TR4NL.js → chunk-RZ6YKEUJ.js} +3 -3
  76. package/dist/{chunk-K6HNAY5V.js → chunk-SCHXJTZL.js} +2 -2
  77. package/dist/{chunk-7OVSJI2V.js → chunk-SQLNBA64.js} +3 -3
  78. package/dist/{chunk-65RTDUZH.js → chunk-SXRTRMEE.js} +3 -3
  79. package/dist/{chunk-3BIAFYD2.js → chunk-T4VOVZT5.js} +2 -2
  80. package/dist/{chunk-UWDO3O52.js → chunk-TN35C5KM.js} +2 -2
  81. package/dist/{chunk-IFK3GIUW.js → chunk-TSA237IM.js} +2 -2
  82. package/dist/{chunk-DKEPS5LH.js → chunk-U2HGPLZS.js} +36 -2
  83. package/dist/{chunk-4HVNZ7WF.js → chunk-VBYSIOOY.js} +3 -3
  84. package/dist/{chunk-ZTLWVRNS.js → chunk-VDOOQZUD.js} +2 -2
  85. package/dist/{chunk-RTERS6S5.js → chunk-VUJGMJE6.js} +4 -4
  86. package/dist/{chunk-X2CH42BN.js → chunk-VVW3F3MD.js} +7 -7
  87. package/dist/{chunk-RI4NIMFP.js → chunk-VVZRV54S.js} +75 -35
  88. package/dist/{chunk-LG4TWW4U.js → chunk-WW32K72E.js} +8 -8
  89. package/dist/{chunk-NVT6C2VE.js → chunk-X6EZPSW6.js} +4 -4
  90. package/dist/{chunk-KQAEKMIX.js → chunk-XDXNDSKO.js} +2 -2
  91. package/dist/{chunk-FMKTYMP4.js → chunk-XJLKLU4D.js} +3 -3
  92. package/dist/chunk-Y4RNXEAO.js +952 -0
  93. package/dist/{chunk-26RVGM44.js → chunk-YIA4LEX4.js} +15 -7
  94. package/dist/chunk-YNRDWYZP.js +295 -0
  95. package/dist/{chunk-SGHSY3LU.js → chunk-Z6XJQ6KO.js} +81 -6
  96. package/dist/{chunk-SVDWQGX2.js → chunk-ZAD4HV2G.js} +139 -78
  97. package/dist/cli.cjs +153 -144
  98. package/dist/clock.d.ts +10 -0
  99. package/dist/clock.js +235 -0
  100. package/dist/countdown.d.ts +12 -0
  101. package/dist/countdown.js +450 -0
  102. package/dist/dgmo-router-YTU3ENAX.js +84 -0
  103. package/dist/{dimensions-WSIJXT5Q.js → dimensions-OTBKC5M6.js} +5 -5
  104. package/dist/editor.js +39 -1
  105. package/dist/element.js +131 -121
  106. package/dist/element.mjs +19496 -12761
  107. package/dist/{flowchart-parser-IVZN7CQN.js → flowchart-parser-OE4WHLTF.js} +4 -4
  108. package/dist/{flowchart-renderer-GMI2U3DD.js → flowchart-renderer-GPCSMTOR.js} +6 -6
  109. package/dist/highlight.d.ts +17 -1
  110. package/dist/highlight.js +156 -5
  111. package/dist/index.js +50 -45
  112. package/dist/{layout-HQMBPJVS.js → layout-46366KBT.js} +2 -2
  113. package/dist/{layout-D42XE4RE.js → layout-5BG6DFCU.js} +3 -3
  114. package/dist/{layout-K2ZN3Q42.js → layout-7MZ5NF2N.js} +4 -4
  115. package/dist/{layout-4Z5JM7PT.js → layout-FWODLIMP.js} +4 -4
  116. package/dist/{layout-GZ2CWONU.js → layout-J36454XU.js} +4 -4
  117. package/dist/{layout-S3EK4IYO.js → layout-LD6XTLD6.js} +4 -4
  118. package/dist/{parser-CLMFZWCC.js → parser-36HVKU5U.js} +5 -5
  119. package/dist/{parser-MCJWF5G3.js → parser-4AI5ZN5F.js} +3 -3
  120. package/dist/{parser-DERPY5KC.js → parser-4NO6VZ6S.js} +4 -4
  121. package/dist/parser-4WQQQXCG.js +13 -0
  122. package/dist/{parser-4ROBKVUR.js → parser-5OXGPNBF.js} +5 -5
  123. package/dist/{parser-XWUDFJ7P.js → parser-AGVYTQXV.js} +4 -4
  124. package/dist/{parser-TITK4YW6.js → parser-AXKBDGNO.js} +5 -5
  125. package/dist/parser-B5FVS7O6.js +11 -0
  126. package/dist/parser-CSFUN3CT.js +14 -0
  127. package/dist/parser-CVMEDULU.js +15 -0
  128. package/dist/{parser-KPMN5KKE.js → parser-D5VILGN2.js} +4 -4
  129. package/dist/{parser-IKZFTLOJ.js → parser-DFFEDKHH.js} +3 -3
  130. package/dist/{parser-JD7OQ2E6.js → parser-H3XEPFPV.js} +4 -4
  131. package/dist/{parser-UBGPTIZD.js → parser-HYRTF3DO.js} +3 -3
  132. package/dist/{parser-K647FRI4.js → parser-IBWNAPY4.js} +3 -3
  133. package/dist/{parser-4BKIFG2C.js → parser-IJBMRXMC.js} +5 -5
  134. package/dist/{parser-MBJSBTL5.js → parser-JJR52VAT.js} +5 -5
  135. package/dist/{parser-SMBJO3XN.js → parser-K3XXLMUW.js} +4 -4
  136. package/dist/{parser-OBQG655V.js → parser-KCR2WS3V.js} +4 -4
  137. package/dist/{parser-HVJFTOXL.js → parser-LWKKBNSA.js} +3 -3
  138. package/dist/{parser-ZYC3XGNS.js → parser-MPCE5JBG.js} +4 -4
  139. package/dist/{parser-QJYS7KQQ.js → parser-MTOMTWTD.js} +4 -4
  140. package/dist/{parser-GFSOPDB7.js → parser-O4HIUN6G.js} +4 -4
  141. package/dist/{parser-BL7Z72EY.js → parser-PSA4UBSP.js} +4 -4
  142. package/dist/{parser-TNYX5S7E.js → parser-RV4M6AS2.js} +4 -4
  143. package/dist/parser-RZPVAQVX.js +11 -0
  144. package/dist/{parser-UGA23PYK.js → parser-TGQZJ5OT.js} +4 -4
  145. package/dist/parser-TXND652E.js +13 -0
  146. package/dist/{parser-WISPH7LW.js → parser-VKOJM7KS.js} +4 -4
  147. package/dist/{parser-ZKF5K2H2.js → parser-W4PQUGX3.js} +4 -4
  148. package/dist/{parser-MRBPXXIV.js → parser-WAV5JRPT.js} +4 -4
  149. package/dist/{parser-D6ONJQFR.js → parser-YS7TOS2K.js} +3 -3
  150. package/dist/pert.d.ts +8 -0
  151. package/dist/{renderer-VFUVRNLK.js → renderer-2AZ5HJFK.js} +4 -4
  152. package/dist/{renderer-V3JEMWMM.js → renderer-2QPMJ2DA.js} +6 -6
  153. package/dist/renderer-45PSOL3E.js +19 -0
  154. package/dist/{renderer-BB5PREMY.js → renderer-4ITCHBT7.js} +4 -4
  155. package/dist/{renderer-XEKIRPI6.js → renderer-5DSEWF74.js} +5 -5
  156. package/dist/{renderer-QNHUXCRL.js → renderer-6OKF44KS.js} +9 -9
  157. package/dist/renderer-72LGR2YF.js +14 -0
  158. package/dist/{renderer-YHXPN3GF.js → renderer-7SD6MSBS.js} +7 -7
  159. package/dist/renderer-A5VE5BCI.js +24 -0
  160. package/dist/{renderer-A5VFZQQK.js → renderer-AUW2BE6G.js} +6 -6
  161. package/dist/{renderer-LWGJFT3D.js → renderer-B5TBNZJE.js} +5 -5
  162. package/dist/{renderer-4IUPINAE.js → renderer-BSR2O2H6.js} +7 -7
  163. package/dist/{renderer-DKESNMU5.js → renderer-CYB4LK3G.js} +6 -6
  164. package/dist/{renderer-MFJ7HY2H.js → renderer-FF24KZCI.js} +5 -5
  165. package/dist/{renderer-CGW7QPNA.js → renderer-FPE3J5VZ.js} +7 -7
  166. package/dist/{renderer-6T3KK4S3.js → renderer-FYSVXL7M.js} +7 -7
  167. package/dist/{renderer-THD6V5TL.js → renderer-HDCCZURL.js} +9 -7
  168. package/dist/{renderer-TPIBXNOS.js → renderer-JCCHNECZ.js} +6 -6
  169. package/dist/{renderer-QL5KO6SK.js → renderer-KS7YZJE2.js} +7 -7
  170. package/dist/{renderer-SQ3JUAI7.js → renderer-NGXZTRK6.js} +6 -6
  171. package/dist/{renderer-MJDDU27W.js → renderer-ODUUOPVT.js} +10 -10
  172. package/dist/renderer-PJM35LJN.js +17 -0
  173. package/dist/{renderer-TYXRHMRI.js → renderer-PPIHO5FI.js} +9 -9
  174. package/dist/{renderer-W5RMOURB.js → renderer-PSMMZCKH.js} +6 -6
  175. package/dist/{renderer-UZF3JROD.js → renderer-QAOBLRXV.js} +8 -8
  176. package/dist/{renderer-ROV756WT.js → renderer-R2WNIC2C.js} +5 -5
  177. package/dist/{renderer-VICQ4WNY.js → renderer-SBS3YWU5.js} +5 -5
  178. package/dist/{renderer-6L3NBEY5.js → renderer-UYMQQCJK.js} +6 -6
  179. package/dist/{renderer-radial-MHO2VDXN.js → renderer-radial-F7X5F2VU.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/advanced.d.ts +0 -6162
  191. package/dist/auto.d.ts +0 -54
  192. package/dist/block.d.ts +0 -123
  193. package/dist/dgmo-router-ODKPEJ3P.js +0 -79
  194. package/dist/element.d.ts +0 -62
  195. package/dist/index.d.ts +0 -166
  196. package/dist/parser-667RGSUW.js +0 -13
  197. package/dist/parser-J3P2D6IP.js +0 -13
  198. package/dist/themes-1-CuKpeH.d.ts +0 -908
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  encodeDiagramUrl
3
- } from "./chunk-SVDWQGX2.js";
3
+ } from "./chunk-ZAD4HV2G.js";
4
4
  import {
5
5
  FONT_FAMILY
6
6
  } from "./chunk-6KFWC4CO.js";
@@ -290,16 +290,24 @@ function computeBBox(svg) {
290
290
  const x = attr(tag, "x");
291
291
  const y = attr(tag, "y");
292
292
  if (x !== null && y !== null) {
293
- const w = text.length * 7;
293
+ const fontSize = attr(tag, "font-size") ?? (() => {
294
+ const s = tag.match(/font-size:\s*([\d.]+)/);
295
+ return s ? parseFloat(s[1]) : 14;
296
+ })();
297
+ const w = text.length * fontSize * 0.5;
294
298
  const anchor = tag.match(/\btext-anchor="([^"]*)"/)?.[1] ?? "start";
295
299
  const left = anchor === "middle" ? x - w / 2 : anchor === "end" ? x - w : x;
296
300
  const right = anchor === "middle" ? x + w / 2 : anchor === "end" ? x : x + w;
297
- push(left, y - 14);
298
- push(right, y + 4);
301
+ push(left, y - fontSize * 0.9);
302
+ push(right, y + fontSize * 0.25);
299
303
  }
300
304
  }
301
- for (const m of svg.matchAll(/<path\b[^>]*?\bd="([^"]+)"/g)) {
302
- const d = m[1];
305
+ for (const m of svg.matchAll(/<path\b[^>]*?>/g)) {
306
+ const tag = m[0];
307
+ if (tag.includes("data-embed-ignore-bbox")) continue;
308
+ const dm = tag.match(/\bd="([^"]+)"/);
309
+ if (!dm) continue;
310
+ const d = dm[1];
303
311
  const nums = d.match(/-?\d+(?:\.\d+)?/g);
304
312
  if (!nums) continue;
305
313
  for (let i = 0; i + 1 < nums.length; i += 2) {
@@ -328,4 +336,4 @@ export {
328
336
  normalizeSvgForEmbed,
329
337
  getEmbedSvgViewBox
330
338
  };
331
- //# sourceMappingURL=chunk-26RVGM44.js.map
339
+ //# sourceMappingURL=chunk-YIA4LEX4.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
@@ -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