@diagrammo/dgmo 0.57.0 → 0.58.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 (196) hide show
  1. package/dist/advanced.d.ts +57 -7
  2. package/dist/advanced.js +127 -117
  3. package/dist/auto.css +38 -2
  4. package/dist/auto.js +161 -124
  5. package/dist/auto.mjs +1827 -1431
  6. package/dist/block.css +38 -2
  7. package/dist/block.js +94 -52
  8. package/dist/{chart-meta-CPNVUZ5J.d.ts → chart-meta-C6UaqhTP.d.ts} +1 -1
  9. package/dist/chart-meta.d.ts +2 -2
  10. package/dist/chart-meta.js +44 -42
  11. package/dist/{charts-d3-Z6FOKUAL.js → charts-d3-K5M5J5ZM.js} +5 -5
  12. package/dist/{chunk-VYCV5WKH.js → chunk-2JPEBOUQ.js} +60 -44
  13. package/dist/{chunk-FERE46TP.js → chunk-2UBTPFIF.js} +3 -3
  14. package/dist/{chunk-CXI6X54X.js → chunk-3DY7TNZ7.js} +2 -2
  15. package/dist/{chunk-D5FANMSG.js → chunk-3LMUMAUS.js} +2 -2
  16. package/dist/{chunk-5J2RQGFG.js → chunk-4CE2GOC2.js} +3 -3
  17. package/dist/{chunk-T2VMOWAM.js → chunk-4ESLORPX.js} +3 -3
  18. package/dist/chunk-4UNGFVVY.js +181 -0
  19. package/dist/{chunk-ADKDIWCW.js → chunk-52KLHCXQ.js} +3 -3
  20. package/dist/{chunk-VSFAJUEF.js → chunk-5RPSN32F.js} +3 -3
  21. package/dist/{chunk-PKFW6GJD.js → chunk-5RY4W7J6.js} +3 -3
  22. package/dist/{chunk-FMPYKUKI.js → chunk-6F3MVYUW.js} +3 -3
  23. package/dist/{chunk-ST3ZNEUQ.js → chunk-6JYE3SDK.js} +2 -2
  24. package/dist/{chunk-FZECLCCU.js → chunk-6KTRV3O5.js} +3 -3
  25. package/dist/{chunk-57RE4N22.js → chunk-7Q6HX7ON.js} +2 -2
  26. package/dist/{chunk-ULR3BVNH.js → chunk-7SGR7A5K.js} +4 -4
  27. package/dist/{chunk-J6V3SMR3.js → chunk-7UZFAIKI.js} +7 -7
  28. package/dist/{chunk-XBTJJLAU.js → chunk-ATKB7VEN.js} +4 -4
  29. package/dist/{chunk-5VLUAAAE.js → chunk-AU4AQYOA.js} +3 -3
  30. package/dist/{chunk-4MB4UOT5.js → chunk-B4U7RRQ4.js} +2 -2
  31. package/dist/{chunk-QWUYFUNO.js → chunk-BFYPHZ5M.js} +2 -2
  32. package/dist/{chunk-7YPSFQFA.js → chunk-C7IKQOEQ.js} +6 -6
  33. package/dist/{chunk-X3ON4M5S.js → chunk-CBPFVH3N.js} +4 -4
  34. package/dist/{chunk-3M6MKHIQ.js → chunk-CC6XIQDE.js} +2 -2
  35. package/dist/{chunk-G3L4GWLA.js → chunk-CZIFUXI2.js} +3 -3
  36. package/dist/chunk-D3K4U3ZM.js +232 -0
  37. package/dist/{chunk-RQGNELB3.js → chunk-DWAQXY6T.js} +3 -3
  38. package/dist/{chunk-KRKU6WRS.js → chunk-DWMJLEBT.js} +4 -4
  39. package/dist/{chunk-VS7DGDT3.js → chunk-DZUDSGGQ.js} +5 -5
  40. package/dist/chunk-E55OZDFH.js +65 -0
  41. package/dist/{chunk-SQWWYGPT.js → chunk-E6CCWMTT.js} +5 -5
  42. package/dist/{chunk-3KOPPSUQ.js → chunk-E7HANW62.js} +12 -3
  43. package/dist/{chunk-7Q35X3AL.js → chunk-EDJYIQZM.js} +9 -233
  44. package/dist/{chunk-HBRGNLF5.js → chunk-EEF7BUX7.js} +6 -6
  45. package/dist/{chunk-3ZONSZOX.js → chunk-FWNJ45NW.js} +2 -2
  46. package/dist/{chunk-RB4HOOKP.js → chunk-FXIG472W.js} +2 -2
  47. package/dist/{chunk-ORZQVUGW.js → chunk-GAFNYUNJ.js} +4 -4
  48. package/dist/{chunk-PRKPFRC2.js → chunk-GGKWKNOL.js} +4 -4
  49. package/dist/{chunk-OFEUXZPI.js → chunk-HBIGEWRC.js} +3 -3
  50. package/dist/{chunk-D64FRGKU.js → chunk-HUYAMTCD.js} +2 -2
  51. package/dist/{chunk-NIUE5VWY.js → chunk-HXTS54OV.js} +3 -3
  52. package/dist/{chunk-PUGUOFM6.js → chunk-ILZHMKYQ.js} +3 -3
  53. package/dist/{chunk-LZX3RLRP.js → chunk-IRN5GBBO.js} +6 -6
  54. package/dist/{chunk-OYCIVSL3.js → chunk-JM65HLBZ.js} +6 -6
  55. package/dist/{chunk-DIKIHU52.js → chunk-KAG5JCZV.js} +3 -3
  56. package/dist/{chunk-4MJOBVY7.js → chunk-KNCY7YHC.js} +2 -2
  57. package/dist/{chunk-M3IYDSI7.js → chunk-L5DQB4C7.js} +5 -5
  58. package/dist/{chunk-EEKGMS63.js → chunk-LLDNNANC.js} +3 -3
  59. package/dist/{chunk-7SXTD7L6.js → chunk-LYQMN35H.js} +2 -2
  60. package/dist/{chunk-ES3MUYRX.js → chunk-MF4FDLFG.js} +3 -3
  61. package/dist/{chunk-YNAHUNMA.js → chunk-MPPOQOCF.js} +2 -2
  62. package/dist/{chunk-44GBBTMU.js → chunk-N7PF5IRF.js} +2 -2
  63. package/dist/{chunk-QMOX5I3G.js → chunk-NGGVVTP2.js} +5 -5
  64. package/dist/{chunk-UG4MWUXE.js → chunk-NPBAV3QU.js} +5 -5
  65. package/dist/{chunk-6PRLPGJB.js → chunk-NQGE76NC.js} +3 -3
  66. package/dist/{chunk-5XMDSXZT.js → chunk-NSUAU6JQ.js} +2 -2
  67. package/dist/{chunk-OHBIN74X.js → chunk-NW2K6UU2.js} +3 -3
  68. package/dist/{chunk-WOMXS5R7.js → chunk-NYCBN7YE.js} +3 -3
  69. package/dist/{chunk-MXDT446P.js → chunk-OMOU2V3W.js} +3 -3
  70. package/dist/chunk-ON4MEUC4.js +50 -0
  71. package/dist/{chunk-3D6LDLIH.js → chunk-OXANJRNK.js} +2 -2
  72. package/dist/{chunk-X32RDWT5.js → chunk-PH5WK6G5.js} +3 -3
  73. package/dist/{chunk-U3DGAE7L.js → chunk-PIIORN3Q.js} +3 -3
  74. package/dist/{chunk-Q772PVKH.js → chunk-QDOSCTL5.js} +2 -2
  75. package/dist/{chunk-CY5KE2P5.js → chunk-QS37VUFZ.js} +2 -2
  76. package/dist/{chunk-NFAHDPCG.js → chunk-RB3AFVPT.js} +3 -3
  77. package/dist/{chunk-LV5BFA24.js → chunk-RDHZRHDG.js} +3 -3
  78. package/dist/{chunk-SADYIA5Q.js → chunk-S3AZMBK7.js} +3 -3
  79. package/dist/{chunk-6HSRT6WI.js → chunk-SBQXLX6Y.js} +3 -3
  80. package/dist/{chunk-SFVG4AIG.js → chunk-SQK4EKOW.js} +3 -3
  81. package/dist/{chunk-6DR2GMDM.js → chunk-STYJ6EOV.js} +157 -134
  82. package/dist/{chunk-BQLJAYVB.js → chunk-TQC2SUMJ.js} +2 -2
  83. package/dist/{chunk-TZ72UBOA.js → chunk-TXQXPJTG.js} +2 -2
  84. package/dist/{chunk-RV2N7COG.js → chunk-UFDLQKCR.js} +2 -2
  85. package/dist/{chunk-INU6ANOH.js → chunk-UPTAWSCG.js} +2 -2
  86. package/dist/{chunk-K2GDF2ZR.js → chunk-VBSKNQUO.js} +4 -4
  87. package/dist/{chunk-KH74OWHU.js → chunk-VJYERZ2Q.js} +3 -3
  88. package/dist/{chunk-USFZQPJ2.js → chunk-W22JRLNA.js} +3 -3
  89. package/dist/{chunk-CQJ5SE5T.js → chunk-W2RU24DD.js} +4 -4
  90. package/dist/{chunk-NHZAYL2X.js → chunk-W6T5QRIR.js} +4 -4
  91. package/dist/{chunk-APD52YJV.js → chunk-WQWVLAA5.js} +4 -4
  92. package/dist/{chunk-D76B4DMV.js → chunk-WYG5VJY2.js} +2 -2
  93. package/dist/{chunk-VYEQPPS6.js → chunk-WYGLKR4I.js} +3 -3
  94. package/dist/{chunk-MGLJA5TK.js → chunk-X3YNX4DR.js} +2 -2
  95. package/dist/{chunk-3G7BCZ4J.js → chunk-X4JEAY73.js} +5 -5
  96. package/dist/{chunk-M65UOFJA.js → chunk-XHTRLRZ5.js} +3 -3
  97. package/dist/{chunk-3NSOKT7C.js → chunk-XXAHWYQU.js} +2 -2
  98. package/dist/{chunk-A6XELFU6.js → chunk-YAG7WAQE.js} +8 -8
  99. package/dist/{chunk-KF575IXC.js → chunk-YILSSUEL.js} +3 -3
  100. package/dist/{chunk-U4FSWAOJ.js → chunk-YKMOI6ZG.js} +4 -4
  101. package/dist/{chunk-TGOMHUOV.js → chunk-ZEIYC7XO.js} +12 -1
  102. package/dist/{chunk-PFG3EVRD.js → chunk-ZKNSLC35.js} +3 -3
  103. package/dist/{chunk-5LBCOFA5.js → chunk-ZW7LTYW2.js} +2 -2
  104. package/dist/cli.cjs +143 -142
  105. package/dist/cloud-reference.d.ts +15 -8
  106. package/dist/cloud-reference.js +8 -39
  107. package/dist/completion-registry.js +24 -5
  108. package/dist/dgmo-router-2637N4DY.js +90 -0
  109. package/dist/{dimensions-XRWIPAFO.js → dimensions-HSIQYP5Z.js} +5 -5
  110. package/dist/editor.js +11 -2
  111. package/dist/element.js +164 -127
  112. package/dist/element.mjs +1827 -1431
  113. package/dist/{flowchart-parser-DA3V2SLH.js → flowchart-parser-I2TEUWAP.js} +4 -4
  114. package/dist/{flowchart-renderer-JGLZB5P5.js → flowchart-renderer-ER66DNCI.js} +5 -5
  115. package/dist/highlight.js +11 -2
  116. package/dist/index.d.ts +13 -4
  117. package/dist/index.js +55 -49
  118. package/dist/{layout-5CX27X7I.js → layout-3QMCSW6B.js} +3 -3
  119. package/dist/{layout-NU5LQ4UP.js → layout-DH6GSKAH.js} +2 -2
  120. package/dist/{layout-AO3TPZUS.js → layout-HTDK3DMG.js} +4 -4
  121. package/dist/{layout-EQTOVNEE.js → layout-K4S54TX7.js} +4 -4
  122. package/dist/{layout-WHOOLGPO.js → layout-V5X3U3WB.js} +4 -4
  123. package/dist/{layout-TZKPVXKJ.js → layout-VFUHKLTS.js} +3 -3
  124. package/dist/{layout-AQXLQVAJ.js → layout-VNEBCYPX.js} +4 -4
  125. package/dist/{layout-search-6CVR2MTZ.js → layout-search-N6NQI5OQ.js} +5 -5
  126. package/dist/{parser-5UZWYSIV.js → parser-2RTQF2LA.js} +4 -4
  127. package/dist/{parser-4ZIJDGPG.js → parser-2VTOUMJY.js} +4 -4
  128. package/dist/{parser-HMQZPPOK.js → parser-3M3QQRCZ.js} +4 -4
  129. package/dist/{parser-RBNOWHGM.js → parser-4WSJVVG6.js} +4 -4
  130. package/dist/{parser-Q3KNFXQR.js → parser-67JHR6I6.js} +4 -4
  131. package/dist/{parser-MH62NYKM.js → parser-6GXEHNZD.js} +4 -4
  132. package/dist/{parser-O5XCVGZG.js → parser-6I3NOLKL.js} +3 -3
  133. package/dist/{parser-6CM27UPA.js → parser-7VNCLF77.js} +4 -4
  134. package/dist/{parser-QL2LBPFE.js → parser-AE7RC4IJ.js} +4 -4
  135. package/dist/{parser-DQ2DGDYO.js → parser-BDGMJSZB.js} +3 -3
  136. package/dist/{parser-WT3DSNPQ.js → parser-BVHECXAJ.js} +4 -4
  137. package/dist/{parser-QEWSTNEJ.js → parser-FLCLHHOM.js} +4 -4
  138. package/dist/{parser-LMNFVTIV.js → parser-FSSAJO2M.js} +4 -4
  139. package/dist/{parser-73YUU35J.js → parser-GH2Y6CR4.js} +3 -3
  140. package/dist/{parser-AYZTKZC3.js → parser-GUUNA7WE.js} +3 -3
  141. package/dist/{parser-DTXM5ROT.js → parser-ISJJO7TJ.js} +5 -5
  142. package/dist/parser-J3FUTZAQ.js +12 -0
  143. package/dist/{parser-Q62VR2UJ.js → parser-JY7ZU5PP.js} +5 -5
  144. package/dist/{parser-4TX6U4ZU.js → parser-KKBW25LM.js} +3 -3
  145. package/dist/{parser-XWNSCDY6.js → parser-M74SVSPT.js} +4 -4
  146. package/dist/{parser-CCAUZLYI.js → parser-MKJ52TD7.js} +4 -4
  147. package/dist/{parser-A6M25MLK.js → parser-MPQTXCBQ.js} +3 -3
  148. package/dist/{parser-IQLLBMBQ.js → parser-N3AAAGTA.js} +3 -3
  149. package/dist/{parser-OPOGIKFR.js → parser-N7SSE4SK.js} +4 -4
  150. package/dist/{parser-D7YZX3CH.js → parser-NH6IAVZJ.js} +3 -3
  151. package/dist/{parser-IPBEW2DG.js → parser-NKHBUGAX.js} +4 -4
  152. package/dist/{parser-PQXN6SBB.js → parser-QVX4FR3J.js} +5 -5
  153. package/dist/{parser-XQNM7BGD.js → parser-S6QH3QIK.js} +4 -4
  154. package/dist/{parser-PEBXIOPX.js → parser-UODHU3EP.js} +4 -4
  155. package/dist/{parser-5WMH55UA.js → parser-UVS6OHCO.js} +4 -4
  156. package/dist/{parser-SJ7ECFAP.js → parser-X3TCE7P5.js} +4 -4
  157. package/dist/{parser-QN3GJJ3J.js → parser-XQKSQBOT.js} +3 -3
  158. package/dist/{parser-KTVDCWHG.js → parser-XXYB4TRG.js} +4 -4
  159. package/dist/{registry-CaSw0PSH.d.ts → registry-C0HvobTb.d.ts} +17 -0
  160. package/dist/renderer-2G7Q3L5W.js +77 -0
  161. package/dist/{renderer-2TEGR3RX.js → renderer-2IO3H53I.js} +5 -5
  162. package/dist/{renderer-Q6TJ52B4.js → renderer-2KDW3TWO.js} +5 -5
  163. package/dist/{renderer-W5GF5USI.js → renderer-2SK7UM4O.js} +5 -5
  164. package/dist/{renderer-BNEO5W3E.js → renderer-34GG6RHO.js} +6 -6
  165. package/dist/{renderer-LRQ3OPNJ.js → renderer-44EXXXRC.js} +7 -7
  166. package/dist/{renderer-XKMG3SYD.js → renderer-4SH6U6WF.js} +6 -6
  167. package/dist/{renderer-TIIHLRMM.js → renderer-4WQRF2SK.js} +5 -5
  168. package/dist/{renderer-KXMKAXPQ.js → renderer-7AVFPE3Q.js} +4 -4
  169. package/dist/{renderer-EJ3FETD2.js → renderer-BA6WTWVL.js} +5 -5
  170. package/dist/{renderer-5BFS4NBL.js → renderer-BLPXBLUP.js} +5 -5
  171. package/dist/{renderer-I2P5FTZ2.js → renderer-C7LFE5CB.js} +7 -7
  172. package/dist/{renderer-3WYLLPQL.js → renderer-CUXXNHFU.js} +6 -6
  173. package/dist/{renderer-B6XOO6EE.js → renderer-DRNJJNAE.js} +3 -3
  174. package/dist/{renderer-N4V7XVC3.js → renderer-DVUKHOFB.js} +7 -7
  175. package/dist/{renderer-6OFPEBHG.js → renderer-I7Q5U2TU.js} +5 -5
  176. package/dist/{renderer-ND7YIUHD.js → renderer-JIUVU3PF.js} +3 -3
  177. package/dist/{renderer-HDLM6OY6.js → renderer-LXIIZ3BH.js} +7 -7
  178. package/dist/{renderer-VWBNIZV3.js → renderer-MTX6PLPA.js} +6 -6
  179. package/dist/{renderer-LU4R3BP2.js → renderer-QGZ2BOJG.js} +4 -4
  180. package/dist/{renderer-AK2X3VRY.js → renderer-SL5IQJKB.js} +7 -7
  181. package/dist/{renderer-IAJMS5U5.js → renderer-SL5LE7MU.js} +7 -7
  182. package/dist/{renderer-JHYUK5TN.js → renderer-SXZBGMEH.js} +3 -3
  183. package/dist/{renderer-LNOBG226.js → renderer-UPANX7XK.js} +7 -7
  184. package/dist/{renderer-FQLFE3TQ.js → renderer-VDCGDJ6L.js} +5 -5
  185. package/dist/{renderer-BZZKS7KQ.js → renderer-XJFRVCF6.js} +7 -7
  186. package/dist/{renderer-LMLSA457.js → renderer-XRC5R3OP.js} +5 -5
  187. package/dist/{renderer-PLRNQ6T3.js → renderer-Y64MT4JM.js} +7 -7
  188. package/dist/{renderer-XSZ5MUIF.js → renderer-ZLJ5CCSO.js} +5 -5
  189. package/dist/{renderer-W3JK5YVD.js → renderer-ZY5TXTS5.js} +5 -5
  190. package/dist/{renderer-radial-LZAPQVM5.js → renderer-radial-4YKK4JNW.js} +6 -6
  191. package/dist/{state-parser-NQGVYSM3.js → state-parser-3PFFJO5M.js} +5 -5
  192. package/dist/{state-renderer-KSAKMFQ2.js → state-renderer-2HDVRUNG.js} +7 -7
  193. package/dist/{themes-tbBkIVsn.d.ts → themes-l406Vj2z.d.ts} +1 -1
  194. package/docs/language-reference.md +29 -0
  195. package/package.json +1 -1
  196. package/dist/dgmo-router-PMEKTIJ7.js +0 -88
package/dist/auto.mjs CHANGED
@@ -811,7 +811,14 @@ var init_directives_registry = __esm({
811
811
  { token: "no-rounds", category: "modifier" },
812
812
  { token: "single-elim", category: "modifier" },
813
813
  { token: "double-elim", category: "modifier" },
814
- { token: "seeded", category: "modifier" }
814
+ { token: "seeded", category: "modifier" },
815
+ // ── Live link (§38) ──────────────────────────────────────
816
+ // The pointer type's one directive. Registered so it highlights and
817
+ // autocompletes like `palette` does — §38 justifies the shape by calling it
818
+ // "the ordinary DGMO directive shape", and an unregistered `url` would make
819
+ // that sentence false in the editor: `editor/tokens.ts` specializes only
820
+ // against the keyword registries, so it would render as plain identifier text.
821
+ { token: "url", category: "directive" }
815
822
  ];
816
823
  ALL_REGISTRY_TOKENS = tokensWhere(() => true);
817
824
  INFRA_TOP_LEVEL_OPTION_SET = tokensWhere(
@@ -1528,7 +1535,9 @@ var init_parsing = __esm({
1528
1535
  "raci",
1529
1536
  "map",
1530
1537
  "family",
1531
- "bracket"
1538
+ "bracket",
1539
+ // pointer, not a drawing — internal (see ChartTypeMeta.internal)
1540
+ "live-link"
1532
1541
  ]);
1533
1542
  OPTION_NOCOLON_RE = /^([a-z][a-z0-9-]*)\s+(.+)$/i;
1534
1543
  GLOBAL_BOOLEANS = /* @__PURE__ */ new Set([
@@ -14747,6 +14756,17 @@ var init_chart_types = __esm({
14747
14756
  id: "boxes-and-lines",
14748
14757
  description: "General-purpose node-edge diagrams with groups and tags",
14749
14758
  fallback: true
14759
+ },
14760
+ // ── Not a tier — a pointer, not a drawing ─────────────────
14761
+ // `live-link` holds no diagram of its own; it names one published to
14762
+ // Diagrammo Cloud. Internal (see `internal` above): it arrives by being saved
14763
+ // from a shared link, never by being picked from a list. Kept LAST because
14764
+ // `chartTypes.slice(0, 8)` is a live window feeding language-reference checks
14765
+ // and the generated AI core — any insertion above position 8 shifts it.
14766
+ {
14767
+ id: "live-link",
14768
+ description: "A pointer to a diagram published at Diagrammo Cloud",
14769
+ internal: true
14750
14770
  }
14751
14771
  ];
14752
14772
  }
@@ -33131,6 +33151,221 @@ var init_parser38 = __esm({
33131
33151
  }
33132
33152
  });
33133
33153
 
33154
+ // src/cloud-reference.ts
33155
+ function parseCloudReference(text) {
33156
+ const fence = FENCE_RE.exec(text) ?? EMBED_RE.exec(text);
33157
+ if (fence) return reference(fence[1]);
33158
+ return parseCloudReferenceUrl(text);
33159
+ }
33160
+ function parseCloudReferenceUrl(text) {
33161
+ let url;
33162
+ try {
33163
+ url = new URL(text.trim());
33164
+ } catch {
33165
+ return null;
33166
+ }
33167
+ if (url.protocol !== "https:" && url.protocol !== "http:") return null;
33168
+ const match = URL_PATH_RE.exec(url.pathname);
33169
+ if (!match) return null;
33170
+ if (url.searchParams.has("at")) return null;
33171
+ return reference(match[1] ?? match[2] ?? match[3]);
33172
+ }
33173
+ function reference(id) {
33174
+ return id ? { id } : null;
33175
+ }
33176
+ var ID, FENCE_RE, EMBED_RE, URL_PATH_RE;
33177
+ var init_cloud_reference = __esm({
33178
+ "src/cloud-reference.ts"() {
33179
+ "use strict";
33180
+ ID = String.raw`[A-Za-z0-9_-]{3,64}`;
33181
+ FENCE_RE = new RegExp(`^\\s*live-link\\s+(${ID})\\s*$`);
33182
+ EMBED_RE = new RegExp(
33183
+ `^\\s*!\\[\\[\\s*live-link:\\s*(${ID})\\s*\\]\\]\\s*$`
33184
+ );
33185
+ URL_PATH_RE = new RegExp(
33186
+ `^/(?:public/diagrams/(${ID})/source|d/(${ID})|view/(${ID}))/?$`
33187
+ );
33188
+ }
33189
+ });
33190
+
33191
+ // src/live-link/parser.ts
33192
+ var parser_exports33 = {};
33193
+ __export(parser_exports33, {
33194
+ parseLiveLink: () => parseLiveLink
33195
+ });
33196
+ function resolveTarget(value) {
33197
+ const trimmed = value.trim();
33198
+ const asUrl = parseCloudReferenceUrl(trimmed)?.id;
33199
+ if (asUrl) return asUrl;
33200
+ if (!/^[^\s[\]]+$/.test(trimmed)) return null;
33201
+ return parseCloudReference(`live-link ${trimmed}`)?.id ?? null;
33202
+ }
33203
+ function pinnedRevision(value) {
33204
+ const trimmed = value.trim();
33205
+ if (resolveTarget(trimmed) !== null) return null;
33206
+ try {
33207
+ const url = new URL(trimmed);
33208
+ const at2 = url.searchParams.get("at");
33209
+ if (at2 !== null) {
33210
+ url.searchParams.delete("at");
33211
+ if (resolveTarget(url.toString()) !== null) return `?at=${at2}`;
33212
+ }
33213
+ } catch {
33214
+ }
33215
+ const at = trimmed.indexOf("@");
33216
+ if (at > 0) {
33217
+ const pin = trimmed.slice(at);
33218
+ if (resolveTarget(trimmed.slice(0, at)) !== null) return pin;
33219
+ }
33220
+ return null;
33221
+ }
33222
+ function parseLiveLink(content) {
33223
+ const diagnostics = [];
33224
+ let error = null;
33225
+ const fail = (line11, message) => {
33226
+ const diag = makeDgmoError(line11, message);
33227
+ diagnostics.push(diag);
33228
+ error ??= formatDgmoError(diag);
33229
+ };
33230
+ const warn2 = (line11, message) => {
33231
+ diagnostics.push(makeDgmoError(line11, message, "warning"));
33232
+ };
33233
+ const lines = content.split("\n");
33234
+ const isSkippable = (line11) => !line11 || line11.startsWith("//");
33235
+ let titleSlot = null;
33236
+ let titleLineNumber = 1;
33237
+ let bodyStart = lines.length;
33238
+ for (let i = 0; i < lines.length; i++) {
33239
+ const trimmed = lines[i].trim();
33240
+ if (isSkippable(trimmed)) continue;
33241
+ const first = parseFirstLine(trimmed);
33242
+ titleLineNumber = i + 1;
33243
+ titleSlot = first?.title ?? null;
33244
+ bodyStart = first ? i + 1 : i;
33245
+ break;
33246
+ }
33247
+ let sawUrlLine = false;
33248
+ const urls = [];
33249
+ for (let i = bodyStart; i < lines.length; i++) {
33250
+ const trimmed = lines[i].trim();
33251
+ if (isSkippable(trimmed)) continue;
33252
+ const spaceIdx = trimmed.search(/\s/);
33253
+ const key = (spaceIdx === -1 ? trimmed : trimmed.slice(0, spaceIdx)).toLowerCase();
33254
+ const value = spaceIdx === -1 ? "" : trimmed.slice(spaceIdx + 1).trim();
33255
+ if (key === "url") {
33256
+ sawUrlLine = true;
33257
+ if (!value) {
33258
+ fail(
33259
+ i + 1,
33260
+ `"url" needs a diagram \u2014 a link like ${EXAMPLE_URL}, or a bare diagram id.`
33261
+ );
33262
+ continue;
33263
+ }
33264
+ urls.push({ value, line: i + 1 });
33265
+ continue;
33266
+ }
33267
+ if (GLOBAL_DIRECTIVES.has(key)) continue;
33268
+ warn2(
33269
+ i + 1,
33270
+ `Unrecognized directive "${key}" \u2014 a live link takes only "url".`
33271
+ );
33272
+ }
33273
+ const titleIsPhrase = titleSlot !== null && /\s/.test(titleSlot);
33274
+ const done = (title, id2) => ({
33275
+ type: "live-link",
33276
+ title,
33277
+ titleLineNumber,
33278
+ id: id2,
33279
+ diagnostics,
33280
+ error
33281
+ });
33282
+ if (!sawUrlLine && titleSlot === null) {
33283
+ fail(
33284
+ titleLineNumber,
33285
+ "A live link needs a diagram \u2014 add `url <link>`, or write `live-link <id>`."
33286
+ );
33287
+ return done(null, null);
33288
+ }
33289
+ if (sawUrlLine && urls.length === 0) {
33290
+ return done(titleIsPhrase ? titleSlot : null, null);
33291
+ }
33292
+ if (urls.length > 1) {
33293
+ const [a, b] = [urls[0], urls[1]];
33294
+ fail(
33295
+ b.line,
33296
+ `Two targets: "${a.value}" on line ${a.line} and "${b.value}" on line ${b.line}. A live link points at one diagram \u2014 delete one.`
33297
+ );
33298
+ return done(titleIsPhrase ? titleSlot : null, null);
33299
+ }
33300
+ const url = urls[0];
33301
+ if (url && titleSlot !== null && !titleIsPhrase) {
33302
+ fail(
33303
+ titleLineNumber,
33304
+ `Two targets: "${titleSlot}" on line ${titleLineNumber} and "${url.value}" on line ${url.line}. A live link points at one diagram \u2014 keep the \`url\` line and give line ${titleLineNumber} a title, or delete the \`url\` line.`
33305
+ );
33306
+ return done(null, null);
33307
+ }
33308
+ if (url) {
33309
+ const pin = pinnedRevision(url.value);
33310
+ if (pin !== null) {
33311
+ fail(
33312
+ url.line,
33313
+ `A pinned revision cannot be served \u2014 a live link always shows the publisher's current version. Remove the "${pin}" from the link.`
33314
+ );
33315
+ return done(titleSlot, null);
33316
+ }
33317
+ const id2 = resolveTarget(url.value);
33318
+ if (id2 === null) {
33319
+ fail(
33320
+ url.line,
33321
+ `"${url.value}" is not a Diagrammo diagram \u2014 use a link like ${EXAMPLE_URL}, or a bare diagram id.`
33322
+ );
33323
+ return done(titleSlot, null);
33324
+ }
33325
+ return done(titleSlot, id2);
33326
+ }
33327
+ if (titleIsPhrase) {
33328
+ fail(
33329
+ titleLineNumber,
33330
+ `"${titleSlot}" is a title, not a diagram id \u2014 add a \`url <link>\` line naming the diagram this points at.`
33331
+ );
33332
+ return done(titleSlot, null);
33333
+ }
33334
+ const shorthandPin = pinnedRevision(titleSlot);
33335
+ if (shorthandPin !== null) {
33336
+ fail(
33337
+ titleLineNumber,
33338
+ `A pinned revision cannot be served \u2014 a live link always shows the publisher's current version. Remove the "${shorthandPin}" from the id.`
33339
+ );
33340
+ return done(null, null);
33341
+ }
33342
+ const id = resolveTarget(titleSlot);
33343
+ if (id === null) {
33344
+ fail(
33345
+ titleLineNumber,
33346
+ `"${titleSlot}" is not a diagram id \u2014 use a bare id, or add a \`url <link>\` line.`
33347
+ );
33348
+ return done(null, null);
33349
+ }
33350
+ return done(null, id);
33351
+ }
33352
+ var GLOBAL_DIRECTIVES, EXAMPLE_URL;
33353
+ var init_parser39 = __esm({
33354
+ "src/live-link/parser.ts"() {
33355
+ "use strict";
33356
+ init_diagnostics();
33357
+ init_cloud_reference();
33358
+ init_parsing();
33359
+ GLOBAL_DIRECTIVES = /* @__PURE__ */ new Set([
33360
+ "palette",
33361
+ "theme",
33362
+ "no-title",
33363
+ "legend-inline"
33364
+ ]);
33365
+ EXAMPLE_URL = "https://online.diagrammo.app/d/dgm_7f2a91";
33366
+ }
33367
+ });
33368
+
33134
33369
  // src/chart-type-registry.ts
33135
33370
  function measureSequence(content) {
33136
33371
  const parsed = parseSequenceDgmo(content);
@@ -33395,6 +33630,7 @@ var init_chart_type_registry = __esm({
33395
33630
  init_parser36();
33396
33631
  init_parser37();
33397
33632
  init_parser38();
33633
+ init_parser39();
33398
33634
  CHART_TYPE_REGISTRY = [
33399
33635
  // ── Structured diagrams ───────────────────────────────────
33400
33636
  {
@@ -33583,7 +33819,12 @@ var init_chart_type_registry = __esm({
33583
33819
  // no measure/minDims — it sizes to content and scales to fit its rectangle.
33584
33820
  { id: "bracket", category: "diagram", parse: parseBracket },
33585
33821
  // ── Geographic map (own parser → resolver → layout → renderer) ──
33586
- { id: "map", category: "visualization", parse: parseMap }
33822
+ { id: "map", category: "visualization", parse: parseMap },
33823
+ // Live link: a pointer to a diagram published at Diagrammo Cloud, rendered
33824
+ // as a reference card. `diagram` like every other card-shaped type, so the
33825
+ // export-handler cross-check covers it rather than being relaxed for it. No
33826
+ // measure/minDims — the card sizes to its own text and scales to fit.
33827
+ { id: "live-link", category: "diagram", parse: parseLiveLink }
33587
33828
  ];
33588
33829
  REGISTRY_BY_ID = new Map(
33589
33830
  CHART_TYPE_REGISTRY.map((d) => [d.id, d])
@@ -33682,13 +33923,19 @@ function parseDgmoUndeduped(content) {
33682
33923
  if (parser2) {
33683
33924
  const result2 = parser2(content);
33684
33925
  return {
33685
- diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)],
33926
+ diagnostics: [
33927
+ ...result2.diagnostics,
33928
+ ...detectEmptyContent(content, chartType)
33929
+ ],
33686
33930
  chartType
33687
33931
  };
33688
33932
  }
33689
33933
  const result = parseVisualization(content);
33690
33934
  return {
33691
- diagnostics: [...result.diagnostics, ...detectEmptyContent(content)],
33935
+ diagnostics: [
33936
+ ...result.diagnostics,
33937
+ ...detectEmptyContent(content, chartType)
33938
+ ],
33692
33939
  chartType
33693
33940
  };
33694
33941
  }
@@ -33720,7 +33967,8 @@ function detectColonChartType(content) {
33720
33967
  }
33721
33968
  return null;
33722
33969
  }
33723
- function detectEmptyContent(content) {
33970
+ function detectEmptyContent(content, chartType) {
33971
+ if (chartType && EMPTY_CONTENT_EXEMPT.has(chartType)) return [];
33724
33972
  const lines = content.split("\n");
33725
33973
  const nonEmpty = lines.filter(
33726
33974
  (l) => l.trim() && !l.trim().startsWith("#") && !l.trim().startsWith("//")
@@ -33732,7 +33980,7 @@ function detectEmptyContent(content) {
33732
33980
  }
33733
33981
  return [];
33734
33982
  }
33735
- var GANTT_DURATION_RE, GANTT_DATE_RE, C4_TYPE_RE, CHART_TYPE_DESCRIPTIONS, chartTypeParsers, knownChartTypeIds, PARSER_BY_ID, ALL_KNOWN_TYPES;
33983
+ var GANTT_DURATION_RE, GANTT_DATE_RE, C4_TYPE_RE, CHART_TYPE_DESCRIPTIONS, chartTypeParsers, knownChartTypeIds, PARSER_BY_ID, ALL_KNOWN_TYPES, EMPTY_CONTENT_EXEMPT;
33736
33984
  var init_dgmo_router = __esm({
33737
33985
  "src/dgmo-router.ts"() {
33738
33986
  "use strict";
@@ -33759,6 +34007,7 @@ var init_dgmo_router = __esm({
33759
34007
  );
33760
34008
  PARSER_BY_ID = new Map(chartTypeParsers);
33761
34009
  ALL_KNOWN_TYPES = new Set(knownChartTypeIds);
34010
+ EMPTY_CONTENT_EXEMPT = /* @__PURE__ */ new Set(["live-link"]);
33762
34011
  }
33763
34012
  });
33764
34013
 
@@ -37690,14 +37939,14 @@ function renderVersionControl(container, parsed, palette, isDark, onClickItem, e
37690
37939
  const exportMode = !!exportDims;
37691
37940
  const paneW = exportMode ? 0 : container.clientWidth || 0;
37692
37941
  const paneH = exportMode ? 0 : container.clientHeight || 0;
37693
- const W3 = Math.round(Math.max(baseW, paneW));
37942
+ const W4 = Math.round(Math.max(baseW, paneW));
37694
37943
  const H2 = Math.round(Math.max(baseH, paneH));
37695
- const vw = exportMode ? W3 : paneW || W3;
37944
+ const vw = exportMode ? W4 : paneW || W4;
37696
37945
  const vh = exportMode ? H2 : paneH || H2;
37697
- const svg = d3Selection8.select(container).append("svg").attr("width", vw).attr("height", vh).attr("viewBox", `0 0 ${W3} ${H2}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY);
37698
- svg.append("rect").attr("width", W3).attr("height", H2).attr("fill", palette.bg);
37946
+ const svg = d3Selection8.select(container).append("svg").attr("width", vw).attr("height", vh).attr("viewBox", `0 0 ${W4} ${H2}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY);
37947
+ svg.append("rect").attr("width", W4).attr("height", H2).attr("fill", palette.bg);
37699
37948
  if (showTitle) {
37700
- const t = svg.append("text").attr("class", "chart-title").attr("x", W3 / 2).attr("y", TITLE_Y).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-family", FONT_FAMILY).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).attr("data-line-number", parsed.titleLineNumber ?? 1).text(parsed.title);
37949
+ const t = svg.append("text").attr("class", "chart-title").attr("x", W4 / 2).attr("y", TITLE_Y).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-family", FONT_FAMILY).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).attr("data-line-number", parsed.titleLineNumber ?? 1).text(parsed.title);
37701
37950
  if (onClickItem && parsed.titleLineNumber && !exportMode) {
37702
37951
  const ln = parsed.titleLineNumber;
37703
37952
  t.style("cursor", "pointer").on("click", () => onClickItem(ln));
@@ -45422,7 +45671,7 @@ function findClearPosition(w, h, points, obstacles) {
45422
45671
  }
45423
45672
  function resolveLabelOverlaps(boxes) {
45424
45673
  const MAX_PASSES = 8;
45425
- const PAD3 = 4;
45674
+ const PAD4 = 4;
45426
45675
  for (let pass = 0; pass < MAX_PASSES; pass++) {
45427
45676
  let moved = false;
45428
45677
  for (let i = 0; i < boxes.length; i++) {
@@ -45431,8 +45680,8 @@ function resolveLabelOverlaps(boxes) {
45431
45680
  const b = boxes[j];
45432
45681
  const dx = Math.abs(a.cx - b.cx);
45433
45682
  const dy = Math.abs(a.cy - b.cy);
45434
- const overlapX = (a.w + b.w) / 2 + PAD3 - dx;
45435
- const overlapY = (a.h + b.h) / 2 + PAD3 - dy;
45683
+ const overlapX = (a.w + b.w) / 2 + PAD4 - dx;
45684
+ const overlapY = (a.h + b.h) / 2 + PAD4 - dy;
45436
45685
  if (overlapX > 0 && overlapY > 0) {
45437
45686
  const shift = overlapY / 2 + 1;
45438
45687
  if (a.cy < b.cy) {
@@ -49667,7 +49916,7 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
49667
49916
  const fillMode = fillModeFromOptions(parsed.options);
49668
49917
  const noDaggers = parsed.options["no-daggers"] === "true";
49669
49918
  const baseBg = themeBaseBg(palette, isDark);
49670
- const PAD3 = 20;
49919
+ const PAD4 = 20;
49671
49920
  const MAX_SCALE8 = 1.5;
49672
49921
  const titleReserve = parsed.title ? TITLE_RESERVE : 0;
49673
49922
  const legendGroups = parsed.tagGroups.filter((g) => g.entries.length > 0).map((g) => ({
@@ -49683,8 +49932,8 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
49683
49932
  };
49684
49933
  const contentW = layout.width;
49685
49934
  const contentH = layout.height;
49686
- const W3 = opts.fit?.width ?? opts.exportDims?.width ?? contentW + PAD3 * 2;
49687
- const legendReserve = hasLegend ? getMaxLegendReservedHeight(legendConfig, W3) + LEGEND_GROUP_GAP : 0;
49935
+ const W4 = opts.fit?.width ?? opts.exportDims?.width ?? contentW + PAD4 * 2;
49936
+ const legendReserve = hasLegend ? getMaxLegendReservedHeight(legendConfig, W4) + LEGEND_GROUP_GAP : 0;
49688
49937
  const inlineRequested = legendInlineRequested(parsed.options);
49689
49938
  const legendExtent = inlineRequested && hasLegend ? getLegendExtent(
49690
49939
  {
@@ -49697,7 +49946,7 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
49697
49946
  showInactivePills: true
49698
49947
  },
49699
49948
  { activeGroup: activeTagGroup },
49700
- W3
49949
+ W4
49701
49950
  ) : { width: 0, height: 0 };
49702
49951
  const header = layoutInlineHeader({
49703
49952
  requested: inlineRequested,
@@ -49705,7 +49954,7 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
49705
49954
  hasLegend,
49706
49955
  legendWidth: legendExtent.width,
49707
49956
  legendHeight: legendExtent.height,
49708
- containerWidth: W3,
49957
+ containerWidth: W4,
49709
49958
  titleBandHeight: titleReserve,
49710
49959
  legendReserve,
49711
49960
  titleBaselineY: TITLE_Y,
@@ -49716,14 +49965,14 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
49716
49965
  let H2;
49717
49966
  if (opts.fit) {
49718
49967
  H2 = opts.fit.height;
49719
- const availW = Math.max(1, W3 - PAD3 * 2);
49720
- const availH = Math.max(1, H2 - chrome - PAD3 * 2);
49968
+ const availW = Math.max(1, W4 - PAD4 * 2);
49969
+ const availH = Math.max(1, H2 - chrome - PAD4 * 2);
49721
49970
  scale = Math.min(MAX_SCALE8, availW / contentW, availH / contentH);
49722
49971
  if (!Number.isFinite(scale) || scale <= 0) scale = 1;
49723
49972
  } else {
49724
- H2 = contentH + chrome + PAD3 * 2;
49973
+ H2 = contentH + chrome + PAD4 * 2;
49725
49974
  }
49726
- const svg = d3Selection16.select(container).append("svg").attr("xmlns", "http://www.w3.org/2000/svg").attr("width", W3).attr("height", H2).attr("viewBox", `0 0 ${W3} ${H2}`).attr("preserveAspectRatio", "xMidYMin meet").attr("data-fit-scale", scale.toFixed(3)).style("font-family", FONT_FAMILY);
49975
+ const svg = d3Selection16.select(container).append("svg").attr("xmlns", "http://www.w3.org/2000/svg").attr("width", W4).attr("height", H2).attr("viewBox", `0 0 ${W4} ${H2}`).attr("preserveAspectRatio", "xMidYMin meet").attr("data-fit-scale", scale.toFixed(3)).style("font-family", FONT_FAMILY);
49727
49976
  svg.append("style").text(
49728
49977
  ".family-focus-icon{opacity:0;transition:opacity .15s ease;pointer-events:none}.family-card:hover .family-focus-icon{opacity:.6;pointer-events:all}.family-focus-icon:hover{opacity:1}"
49729
49978
  );
@@ -49745,15 +49994,15 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
49745
49994
  },
49746
49995
  palette,
49747
49996
  isDark,
49748
- width: W3,
49997
+ width: W4,
49749
49998
  activeGroup: activeTagGroup
49750
49999
  });
49751
50000
  legendParent.selectAll("[data-legend-group]").classed("family-legend-group", true);
49752
50001
  }
49753
- const contentX = (W3 - contentW * scale) / 2;
50002
+ const contentX = (W4 - contentW * scale) / 2;
49754
50003
  const root = svg.append("g").attr(
49755
50004
  "transform",
49756
- `translate(${contentX}, ${chrome + PAD3}) scale(${scale})`
50005
+ `translate(${contentX}, ${chrome + PAD4}) scale(${scale})`
49757
50006
  );
49758
50007
  if (parsed.options["generations"] === "true" && layout.rows.length > 0) {
49759
50008
  const bandG = root.append("g").attr("class", "family-generation-bands");
@@ -57030,7 +57279,7 @@ function nodeMapWithGroups(nodes, groups) {
57030
57279
  function computePortPts(edges, nodeMap, direction) {
57031
57280
  const srcPts = /* @__PURE__ */ new Map();
57032
57281
  const tgtPts = /* @__PURE__ */ new Map();
57033
- const PAD3 = 0.1;
57282
+ const PAD4 = 0.1;
57034
57283
  const activeEdges = edges.filter((e) => e.points.length > 0);
57035
57284
  const bySource = /* @__PURE__ */ new Map();
57036
57285
  for (const e of activeEdges) {
@@ -57046,7 +57295,7 @@ function computePortPts(edges, nodeMap, direction) {
57046
57295
  ).sort((a, b) => direction === "LR" ? a.t.y - b.t.y : a.t.x - b.t.x);
57047
57296
  const n = sorted.length;
57048
57297
  for (let i = 0; i < n; i++) {
57049
- const frac = n === 1 ? 0.5 : PAD3 + (1 - 2 * PAD3) * i / (n - 1);
57298
+ const frac = n === 1 ? 0.5 : PAD4 + (1 - 2 * PAD4) * i / (n - 1);
57050
57299
  const { e, t } = sorted[i];
57051
57300
  const isBackward = direction === "LR" ? t.x < source.x : t.y < source.y;
57052
57301
  if (direction === "LR") {
@@ -57076,7 +57325,7 @@ function computePortPts(edges, nodeMap, direction) {
57076
57325
  ).sort((a, b) => direction === "LR" ? a.s.y - b.s.y : a.s.x - b.s.x);
57077
57326
  const n = sorted.length;
57078
57327
  for (let i = 0; i < n; i++) {
57079
- const frac = n === 1 ? 0.5 : PAD3 + (1 - 2 * PAD3) * i / (n - 1);
57328
+ const frac = n === 1 ? 0.5 : PAD4 + (1 - 2 * PAD4) * i / (n - 1);
57080
57329
  const { e, s } = sorted[i];
57081
57330
  const isBackward = direction === "LR" ? target.x < s.x : target.y < s.y;
57082
57331
  if (direction === "LR") {
@@ -71275,7 +71524,7 @@ function layoutMap(resolvedIn, data, size, opts) {
71275
71524
  const akRef = resolved.regions.some((r) => r.iso === "US-AK") || resolved.pois.some((p) => inAlaska(p.lon, p.lat));
71276
71525
  const hiRef = resolved.regions.some((r) => r.iso === "US-HI") || resolved.pois.some((p) => inHawaii(p.lon, p.lat));
71277
71526
  if (resolved.projection === "albers-usa" && usLayer && (akRef || hiRef)) {
71278
- const PAD3 = 8;
71527
+ const PAD4 = 8;
71279
71528
  const GAP = 12;
71280
71529
  const yB = height - FIT_PAD;
71281
71530
  const BW = 8;
@@ -71318,22 +71567,22 @@ function layoutMap(resolvedIn, data, size, opts) {
71318
71567
  const f = usLayer.get(iso);
71319
71568
  if (!f) return boxX;
71320
71569
  const x0 = boxX;
71321
- const iw = Math.min(iwReq, width - FIT_PAD - x0 - 2 * PAD3);
71570
+ const iw = Math.min(iwReq, width - FIT_PAD - x0 - 2 * PAD4);
71322
71571
  if (iw < 24) return boxX;
71323
- const xr = x0 + iw + 2 * PAD3;
71572
+ const xr = x0 + iw + 2 * PAD4;
71324
71573
  const floor = coastFloor(x0, xr);
71325
71574
  const topGuess = floor > -Infinity ? floor + GAP : yB - height * 0.42;
71326
71575
  proj.fitWidth(iw, f);
71327
71576
  const bb = geoPath(proj).bounds(f);
71328
71577
  const sh = Number.isFinite(bb[0][0]) ? bb[1][1] - bb[0][1] : iw;
71329
- const needH = sh + 2 * PAD3;
71578
+ const needH = sh + 2 * PAD4;
71330
71579
  let topFit = topGuess;
71331
71580
  const bottom2 = Math.min(topFit + needH, yB);
71332
71581
  if (bottom2 - topFit < needH) topFit = bottom2 - needH;
71333
71582
  proj.fitExtent(
71334
71583
  [
71335
- [x0 + PAD3, topFit + PAD3],
71336
- [xr - PAD3, bottom2 - PAD3]
71584
+ [x0 + PAD4, topFit + PAD4],
71585
+ [xr - PAD4, bottom2 - PAD4]
71337
71586
  ],
71338
71587
  f
71339
71588
  );
@@ -72971,15 +73220,15 @@ function layoutMap(resolvedIn, data, size, opts) {
72971
73220
  }
72972
73221
  }
72973
73222
  if (regionLabelGuards.length > 0) {
72974
- const PAD3 = 2;
73223
+ const PAD4 = 2;
72975
73224
  const poiRects = labels.filter((l) => l.poiId !== void 0 && l.hidden !== true).map((l) => {
72976
73225
  const w = measureLegendText(l.text, FONT2);
72977
73226
  const x = l.anchor === "start" ? l.x : l.anchor === "end" ? l.x - w : l.x - w / 2;
72978
73227
  return {
72979
- x: x - PAD3,
73228
+ x: x - PAD4,
72980
73229
  y: l.y - FONT2,
72981
- w: w + 2 * PAD3,
72982
- h: FONT2 * 1.4 + 2 * PAD3
73230
+ w: w + 2 * PAD4,
73231
+ h: FONT2 * 1.4 + 2 * PAD4
72983
73232
  };
72984
73233
  });
72985
73234
  for (const g of regionLabelGuards) {
@@ -73592,7 +73841,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
73592
73841
  if (poiLabels.length) {
73593
73842
  const patchBlurId = nid("dgmo-map-label-patch-blur");
73594
73843
  defs.append("filter").attr("id", patchBlurId).attr("x", "-50%").attr("y", "-50%").attr("width", "200%").attr("height", "200%").append("feGaussianBlur").attr("in", "SourceGraphic").attr("stdDeviation", 2.5);
73595
- const PAD3 = 8;
73844
+ const PAD4 = 8;
73596
73845
  const buildPatch = (labels, maskId, decoCluster) => {
73597
73846
  if (!labels.length) return;
73598
73847
  const patchMask = defs.append("mask").attr("id", maskId).attr("maskUnits", "userSpaceOnUse").attr("x", 0).attr("y", 0).attr("width", width).attr("height", height);
@@ -73608,10 +73857,10 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
73608
73857
  const h = th + 6;
73609
73858
  blobs.append("rect").attr("x", cx - w / 2).attr("y", cy - h / 2).attr("width", w).attr("height", h).attr("rx", h / 2).attr("fill", "white");
73610
73859
  blobRects.push({
73611
- x0: cx - w / 2 - PAD3,
73612
- y0: cy - h / 2 - PAD3,
73613
- x1: cx + w / 2 + PAD3,
73614
- y1: cy + h / 2 + PAD3
73860
+ x0: cx - w / 2 - PAD4,
73861
+ y0: cy - h / 2 - PAD4,
73862
+ x1: cx + w / 2 + PAD4,
73863
+ y1: cy + h / 2 + PAD4
73615
73864
  });
73616
73865
  }
73617
73866
  const gPatch = svg.append("g").attr("class", "dgmo-map-label-patch").attr("mask", `url(#${maskId})`).style("pointer-events", "none");
@@ -74738,16 +74987,16 @@ function renderRing(container, parsed, palette, isDark, onClickItem, exportDims)
74738
74987
  }
74739
74988
  }
74740
74989
  function drawRingCurvedLabel(labelG, defs, pathId, text, cx, cy, rMid, labelFont, textColor, palette) {
74741
- const PAD3 = 1.18;
74990
+ const PAD4 = 1.18;
74742
74991
  let fs = labelFont;
74743
74992
  let rPath = rMid - fs * 0.32;
74744
74993
  const maxLen = MAX_LABEL_ARC * rPath;
74745
- const wPadded = measureText(text, labelFont) * PAD3;
74994
+ const wPadded = measureText(text, labelFont) * PAD4;
74746
74995
  if (wPadded > maxLen) {
74747
74996
  fs = Math.max(LABEL_FONT_MIN2, Math.floor(labelFont * maxLen / wPadded));
74748
74997
  rPath = rMid - fs * 0.32;
74749
74998
  }
74750
- const arcLen = measureText(text, fs) * PAD3;
74999
+ const arcLen = measureText(text, fs) * PAD4;
74751
75000
  const halfAngle = Math.min(arcLen / (2 * rPath), MAX_LABEL_ARC / 2);
74752
75001
  const largeArc = halfAngle * 2 > Math.PI ? 1 : 0;
74753
75002
  const p0x = cx - Math.sin(halfAngle) * rPath;
@@ -75699,13 +75948,13 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
75699
75948
  g.append("text").attr("class", "dgmo-treemap-header-value").attr("x", w - ICON_RESERVE - 4).attr("y", 13).attr("text-anchor", "end").attr("font-size", 10.5).attr("fill", ink).attr("opacity", 0.75).text(valStr);
75700
75949
  }
75701
75950
  }
75702
- const PAD3 = Math.max(4, Math.min(14, Math.floor(Math.min(w, h) / 5)));
75951
+ const PAD4 = Math.max(4, Math.min(14, Math.floor(Math.min(w, h) / 5)));
75703
75952
  const MIN_FS = 7;
75704
- if (!cell.isContainer && w >= 2 * PAD3 + 8 && h >= 2 * PAD3 + 8) {
75705
- const maxW = w - 2 * PAD3;
75953
+ if (!cell.isContainer && w >= 2 * PAD4 + 8 && h >= 2 * PAD4 + 8) {
75954
+ const maxW = w - 2 * PAD4;
75706
75955
  const horizMinW = measureText(cell.label, MIN_FS) * 1.06;
75707
- if (horizMinW > maxW && h > w * 1.25 && h - 2 * PAD3 > maxW) {
75708
- drawVerticalLabel(g, cell.label, w, h, PAD3, ink);
75956
+ if (horizMinW > maxW && h > w * 1.25 && h - 2 * PAD4 > maxW) {
75957
+ drawVerticalLabel(g, cell.label, w, h, PAD4, ink);
75709
75958
  if (drillable && w > 30 && h > 22) drawFocusIcon(g, w, ink, 9);
75710
75959
  continue;
75711
75960
  }
@@ -75716,8 +75965,8 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
75716
75965
  const nameOpacity = 0.95 - tg * 0.5;
75717
75966
  const vfs = clamp4(Math.round(fs * 0.42), 11, 28);
75718
75967
  const valOpacity = Math.max(0.45, nameOpacity - 0.1);
75719
- let y = PAD3 + Math.round(fs * 0.78);
75720
- g.append("text").attr("class", "dgmo-treemap-label").attr("x", PAD3).attr("y", y).attr("font-size", fs).attr("font-weight", 600).attr("fill", ink).attr("opacity", nameOpacity).text(clipLabel(cell.label, maxW, fs));
75968
+ let y = PAD4 + Math.round(fs * 0.78);
75969
+ g.append("text").attr("class", "dgmo-treemap-label").attr("x", PAD4).attr("y", y).attr("font-size", fs).attr("font-weight", 600).attr("fill", ink).attr("opacity", nameOpacity).text(clipLabel(cell.label, maxW, fs));
75721
75970
  const valParts = [
75722
75971
  opts.noValues ? "" : compactNumber2(cell.value),
75723
75972
  opts.noPercent ? "" : formatPct(cell.pctOfRoot)
@@ -75725,12 +75974,12 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
75725
75974
  const combined = valParts.join(" \xB7 ");
75726
75975
  const nameBaseY = y;
75727
75976
  const addLineAt = (text, yy, size, opacity) => {
75728
- g.append("text").attr("class", "dgmo-treemap-value").attr("x", PAD3).attr("y", yy).attr("font-size", size).attr("fill", ink).attr("opacity", opacity).text(text);
75977
+ g.append("text").attr("class", "dgmo-treemap-value").attr("x", PAD4).attr("y", yy).attr("font-size", size).attr("fill", ink).attr("opacity", opacity).text(text);
75729
75978
  };
75730
75979
  if (combined) {
75731
75980
  const fitsW = measureText(combined, vfs) <= maxW;
75732
75981
  const valY = y + lineDrop(fs, vfs);
75733
- const roomBelow = valY + descent(vfs) <= h - PAD3;
75982
+ const roomBelow = valY + descent(vfs) <= h - PAD4;
75734
75983
  if (fitsW && roomBelow) {
75735
75984
  addLineAt(combined, valY, vfs, valOpacity);
75736
75985
  } else if (fitsW) {
@@ -75738,24 +75987,24 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
75738
75987
  const rendered = clipLabel(cell.label, maxW, fs);
75739
75988
  const nW = measureText(rendered, fs) * 1.12;
75740
75989
  const gap = Math.max(12, Math.round(fs * 0.25));
75741
- if (PAD3 + nW + gap + measureText(combined, ivfs) <= w - PAD3) {
75742
- g.append("text").attr("class", "dgmo-treemap-value").attr("x", PAD3 + nW + gap).attr("y", nameBaseY).attr("font-size", ivfs).attr("fill", ink).attr("opacity", valOpacity).text(combined);
75990
+ if (PAD4 + nW + gap + measureText(combined, ivfs) <= w - PAD4) {
75991
+ g.append("text").attr("class", "dgmo-treemap-value").attr("x", PAD4 + nW + gap).attr("y", nameBaseY).attr("font-size", ivfs).attr("fill", ink).attr("opacity", valOpacity).text(combined);
75743
75992
  }
75744
75993
  } else if (valParts.length === 2) {
75745
75994
  const d1 = lineDrop(fs, vfs);
75746
- if (y + d1 + descent(vfs) <= h - PAD3) {
75995
+ if (y + d1 + descent(vfs) <= h - PAD4) {
75747
75996
  y += d1;
75748
75997
  addLineAt(valParts[0], y, vfs, valOpacity);
75749
75998
  }
75750
75999
  const pfs = Math.max(10, Math.round(vfs * 0.9));
75751
76000
  const d2 = lineDrop(vfs, pfs);
75752
- if (y + d2 + descent(pfs) <= h - PAD3) {
76001
+ if (y + d2 + descent(pfs) <= h - PAD4) {
75753
76002
  y += d2;
75754
76003
  addLineAt(valParts[1], y, pfs, valOpacity);
75755
76004
  }
75756
76005
  } else {
75757
76006
  const onlyY = y + lineDrop(fs, vfs);
75758
- if (onlyY + descent(vfs) <= h - PAD3) {
76007
+ if (onlyY + descent(vfs) <= h - PAD4) {
75759
76008
  addLineAt(combined, onlyY, vfs, valOpacity);
75760
76009
  }
75761
76010
  }
@@ -75871,422 +76120,1011 @@ var init_renderer26 = __esm({
75871
76120
  }
75872
76121
  });
75873
76122
 
75874
- // src/block/layout.ts
75875
- function layoutBlock(grid, opts = {}) {
75876
- const collapsed = opts.collapsed ?? /* @__PURE__ */ new Set();
75877
- const node = layoutGrid(grid, 0, 0, null, collapsed);
75878
- return { width: node.w, height: node.h, items: node.items };
75879
- }
75880
- function maxSpanSum(g) {
75881
- return Math.max(
75882
- 1,
75883
- ...g.rows.map((r) => r.reduce((s, c) => s + (c.span || 1), 0))
75884
- );
75885
- }
75886
- function leafW(node) {
75887
- return Math.max(
75888
- MIN_COL,
75889
- Math.min(MAX_COL, measureText(node.label, LABEL_FS) + 2 * BLOCK_PAD + 14)
75890
- );
75891
- }
75892
- function gridColW(g) {
75893
- let m = MIN_COL;
75894
- for (const row of g.rows)
75895
- for (const c of row) {
75896
- if (!isBlockNode(c)) continue;
75897
- const iw = c.grid ? intrinsicGridW(c.grid) + 2 * BLOCK_PAD : leafW(c);
75898
- m = Math.max(m, iw / (c.span || 1));
75899
- }
75900
- return m;
75901
- }
75902
- function intrinsicGridW(g) {
75903
- const cols = g.cols ?? maxSpanSum(g);
75904
- return cols * gridColW(g) + (cols + 1) * BLOCK_GAP;
75905
- }
75906
- function layoutGrid(g, ox, oy, forceColW, collapsed) {
75907
- const cols = g.cols ?? maxSpanSum(g);
75908
- const colW = forceColW ?? gridColW(g);
75909
- const gridW = cols * colW + (cols + 1) * BLOCK_GAP;
75910
- let cy = oy + BLOCK_GAP;
75911
- const items = [];
75912
- let maxRight = ox + BLOCK_GAP;
75913
- for (const row of g.rows) {
75914
- let cx = ox + BLOCK_GAP;
75915
- let rowH = BLOCK_LEAF_H;
75916
- const rowItems = [];
75917
- for (const cell of row) {
75918
- const span = cell.span || 1;
75919
- const cw = span * colW + (span - 1) * BLOCK_GAP;
75920
- if (!isBlockNode(cell)) {
75921
- rowItems.push({ type: "empty", x: cx, y: cy, w: cw, h: BLOCK_LEAF_H });
75922
- cx += cw + BLOCK_GAP;
75923
- maxRight = Math.max(maxRight, cx - BLOCK_GAP);
75924
- continue;
75925
- }
75926
- if (cell.grid && collapsed.has(cell.id)) {
75927
- const item = {
75928
- type: "collapsed",
75929
- x: cx,
75930
- y: cy,
75931
- w: cw,
75932
- h: BLOCK_COLLAPSED_H,
75933
- label: cell.label,
75934
- node: cell,
75935
- lineNumber: cell.lineNumber
75936
- };
75937
- rowItems.push(item);
75938
- rowH = Math.max(rowH, BLOCK_COLLAPSED_H);
75939
- cx += cw + BLOCK_GAP;
75940
- maxRight = Math.max(maxRight, cx - BLOCK_GAP);
75941
- continue;
75942
- }
75943
- if (cell.grid) {
75944
- const innerCols = cell.grid.cols ?? maxSpanSum(cell.grid);
75945
- const innerColW = Math.max(
75946
- MIN_COL * 0.66,
75947
- (cw - 2 * BLOCK_PAD - (innerCols + 1) * BLOCK_GAP) / innerCols
75948
- );
75949
- const inner = layoutGrid(
75950
- cell.grid,
75951
- cx + BLOCK_PAD,
75952
- cy + BLOCK_HEADER_H,
75953
- innerColW,
75954
- collapsed
75955
- );
75956
- const h = BLOCK_HEADER_H + inner.h + BLOCK_PAD;
75957
- rowItems.push({
75958
- type: "container",
75959
- x: cx,
75960
- y: cy,
75961
- w: cw,
75962
- h,
75963
- label: cell.label,
75964
- node: cell,
75965
- lineNumber: cell.lineNumber,
75966
- inner: inner.items
75967
- });
75968
- rowH = Math.max(rowH, h);
75969
- cx += cw + BLOCK_GAP;
75970
- maxRight = Math.max(maxRight, cx - BLOCK_GAP);
75971
- continue;
75972
- }
75973
- rowItems.push({
75974
- type: "leaf",
75975
- x: cx,
75976
- y: cy,
75977
- w: cw,
75978
- h: BLOCK_LEAF_H,
75979
- label: cell.label,
75980
- node: cell,
75981
- lineNumber: cell.lineNumber
75982
- });
75983
- cx += cw + BLOCK_GAP;
75984
- maxRight = Math.max(maxRight, cx - BLOCK_GAP);
75985
- }
75986
- items.push(...rowItems);
75987
- cy += rowH + BLOCK_GAP;
75988
- }
75989
- const fitW = Math.max(gridW, maxRight - ox + BLOCK_GAP);
75990
- return { x: ox, y: oy, w: fitW, h: cy - oy, items };
75991
- }
75992
- var BLOCK_GAP, BLOCK_PAD, BLOCK_LEAF_H, BLOCK_HEADER_H, BLOCK_COLLAPSED_H, BLOCK_BAR_H, MIN_COL, MAX_COL, LABEL_FS;
75993
- var init_layout20 = __esm({
75994
- "src/block/layout.ts"() {
76123
+ // node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js
76124
+ var require_lz_string = __commonJS({
76125
+ "node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js"(exports, module) {
75995
76126
  "use strict";
75996
- init_text_measure();
75997
- init_types4();
75998
- BLOCK_GAP = 12;
75999
- BLOCK_PAD = 10;
76000
- BLOCK_LEAF_H = 46;
76001
- BLOCK_HEADER_H = 28;
76002
- BLOCK_COLLAPSED_H = 46;
76003
- BLOCK_BAR_H = 6;
76004
- MIN_COL = 104;
76005
- MAX_COL = 250;
76006
- LABEL_FS = 13;
76007
- }
76008
- });
76009
-
76010
- // src/block/renderer.ts
76011
- var renderer_exports26 = {};
76012
- __export(renderer_exports26, {
76013
- authoredCollapsedIds: () => authoredCollapsedIds,
76014
- renderBlock: () => renderBlock,
76015
- renderBlockForExport: () => renderBlockForExport
76016
- });
76017
- import * as d3Selection33 from "d3-selection";
76018
- function renderBlockForExport(container, parsed, palette, isDark, exportDims, options) {
76019
- renderBlock(container, parsed, palette, isDark, exportDims, {
76020
- exportMode: true,
76021
- ...options
76022
- });
76023
- }
76024
- function renderBlock(container, parsed, palette, isDark, exportDims, options = {}) {
76025
- if (parsed.error || parsed.top.rows.length === 0) return;
76026
- d3Selection33.select(container).selectAll(":not([data-d3-tooltip])").remove();
76027
- const opts = parsed.options;
76028
- const showTitle = !!parsed.title;
76029
- const titleH = showTitle ? TITLE_BAND2 : 0;
76030
- const collapsed = options.collapsed ?? authoredCollapsedIds(parsed);
76031
- const layout = layoutBlock(parsed.top, { collapsed });
76032
- const legend = !opts.noLegend ? buildBlockLegend(parsed) : null;
76033
- let width;
76034
- let height;
76035
- if (options.exportMode) {
76036
- width = Math.max(layout.width, MIN_EXPORT_WIDTH) + PADDING5 * 2;
76037
- } else {
76038
- width = exportDims?.width ?? container.clientWidth;
76039
- }
76040
- const legendReserve = legend ? getMaxLegendReservedHeight(
76041
- { groups: legend.groups, position: LEGEND_POSITION3, mode: "preview" },
76042
- width
76043
- ) + LEGEND_GROUP_GAP : 0;
76044
- const inlineRequested = opts.legendInline === true;
76045
- const legendExtent = inlineRequested && legend ? getLegendExtent(
76046
- {
76047
- groups: legend.groups,
76048
- position: {
76049
- placement: "top-center",
76050
- titleRelation: "inline-with-title"
76051
- },
76052
- mode: options.exportMode ? "export" : "preview"
76053
- },
76054
- { activeGroup: legend.activeGroup ?? null },
76055
- width
76056
- ) : { width: 0, height: 0 };
76057
- const header = layoutInlineHeader({
76058
- requested: inlineRequested,
76059
- title: parsed.title ?? "",
76060
- hasLegend: !!legend,
76061
- legendWidth: legendExtent.width,
76062
- legendHeight: legendExtent.height,
76063
- containerWidth: width,
76064
- titleBandHeight: titleH,
76065
- legendReserve,
76066
- titleBaselineY: TITLE_Y,
76067
- titleFontSize: TITLE_FONT_SIZE
76068
- });
76069
- const areaY = (header.inline ? titleH : titleH + legendReserve) + PADDING5;
76070
- if (options.exportMode) {
76071
- height = areaY + layout.height + PADDING5;
76072
- } else {
76073
- height = exportDims?.height ?? container.clientHeight;
76074
- }
76075
- if (width <= 0 || height <= 0) return;
76076
- const areaX = PADDING5;
76077
- const areaW = Math.max(1, width - PADDING5 * 2);
76078
- const areaH = Math.max(1, height - areaY - PADDING5);
76079
- const scale = Math.min(1, areaW / layout.width, areaH / layout.height);
76080
- const offsetX = areaX + (areaW - layout.width * scale) / 2;
76081
- const offsetY = areaY;
76082
- const svg = d3Selection33.select(container).append("svg").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").attr("class", "dgmo-block").style("font-family", FONT_FAMILY);
76083
- if (showTitle) {
76084
- const title = svg.append("text").attr("class", "chart-title").attr("x", header.titleX).attr("y", TITLE_Y).attr("text-anchor", header.titleAnchor).attr("fill", palette.text).attr("font-family", FONT_FAMILY).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).text(parsed.title);
76085
- if (parsed.titleLineNumber !== null) {
76086
- title.attr("data-line-number", parsed.titleLineNumber);
76087
- }
76088
- }
76089
- const activeGroup = parsed.tagGroups.length > 0 ? parsed.tagGroups[0].name : null;
76090
- const neutral = mix(palette.text, palette.bg, 22);
76091
- const root = svg.append("g").attr("class", "dgmo-block-cells").attr("transform", `translate(${offsetX},${offsetY}) scale(${scale})`);
76092
- drawItems(root, layout.items, {
76093
- palette,
76094
- tagGroups: parsed.tagGroups,
76095
- activeGroup,
76096
- activeKey: activeGroup ? tagAttrKey(activeGroup) : null,
76097
- neutral,
76098
- fillMode: opts.fillMode,
76099
- isDark,
76100
- onToggle: options.onToggle
76101
- });
76102
- if (legend) {
76103
- const legendG = svg.append("g").attr("class", "dgmo-block-legend").attr(
76104
- "transform",
76105
- header.inline ? `translate(${header.legendX}, ${header.legendY})` : `translate(0, ${titleH})`
76106
- );
76107
- renderIntegratedLegend(legendG, {
76108
- groups: legend.groups,
76109
- palette: {
76110
- bg: palette.bg,
76111
- surface: palette.surface,
76112
- text: palette.text,
76113
- textMuted: palette.textMuted,
76114
- primary: palette.primary
76115
- },
76116
- isDark,
76117
- width,
76118
- mode: options.exportMode ? "export" : "preview",
76119
- position: {
76120
- placement: "top-center",
76121
- titleRelation: header.inline ? "inline-with-title" : "below-title"
76122
- },
76123
- activeGroup: legend.activeGroup
76124
- });
76125
- }
76126
- }
76127
- function colorOf(node, ctx) {
76128
- if (!node || !ctx.activeGroup) return null;
76129
- return resolveTagColor(node.metadata, ctx.tagGroups, ctx.activeGroup) ?? null;
76130
- }
76131
- function clipLabel2(s, maxWidth, fs) {
76132
- if (measureText(s, fs) <= maxWidth) return s;
76133
- let lo = 0;
76134
- let hi = s.length;
76135
- while (lo < hi) {
76136
- const mid = Math.ceil((lo + hi) / 2);
76137
- if (measureText(s.slice(0, mid) + "\u2026", fs) <= maxWidth) lo = mid;
76138
- else hi = mid - 1;
76139
- }
76140
- return lo <= 0 ? "" : s.slice(0, lo) + "\u2026";
76141
- }
76142
- function drawItems(g, items, ctx, path = []) {
76143
- const { palette, fillMode } = ctx;
76144
- for (const it of items) {
76145
- if (it.type === "empty") {
76146
- g.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 7).attr("fill", "none").attr("stroke", ctx.neutral).attr("stroke-width", 1).attr("stroke-dasharray", "3 4").attr("opacity", 0.7);
76147
- continue;
76148
- }
76149
- const node = it.node;
76150
- const itemPath = [...path, node.id];
76151
- const color = colorOf(node, ctx);
76152
- const stroke2 = color ?? ctx.neutral;
76153
- const cell = g.append("g").attr("class", "dgmo-block-cell").attr("data-block-id", node.id).attr("data-block-path", itemPath.join(" / "));
76154
- if (it.lineNumber !== void 0)
76155
- cell.attr("data-line-number", it.lineNumber);
76156
- if (ctx.activeKey) {
76157
- const v = node.metadata[ctx.activeKey];
76158
- if (v) cell.attr(`data-tag-${ctx.activeKey}`, v);
76159
- }
76160
- if (it.type === "collapsed") {
76161
- const fill3 = color ? fillMode === "solid" ? color : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 12) : palette.surface;
76162
- const cid = `dgmo-block-clip-${clipCounter++}`;
76163
- cell.append("clipPath").attr("id", cid).append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10);
76164
- cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10).attr("fill", fill3).attr("stroke", stroke2).attr("stroke-width", 1.5);
76165
- cell.append("text").attr("x", it.x + it.w / 2).attr("y", it.y + it.h / 2 + 4).attr("text-anchor", "middle").attr("font-size", 12.5).attr("font-weight", 700).attr("fill", palette.text).text(clipLabel2(it.label ?? "", it.w - 24, 12.5));
76166
- cell.append("rect").attr("x", it.x).attr("y", it.y + it.h - BLOCK_BAR_H).attr("width", it.w).attr("height", BLOCK_BAR_H).attr("fill", fillMode === "solid" && color ? palette.text : stroke2).attr("clip-path", `url(#${cid})`);
76167
- bindToggle(cell, it, ctx, it.h);
76168
- continue;
76169
- }
76170
- if (it.type === "container") {
76171
- const fill3 = color ? fillMode === "solid" ? color : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 7) : palette.surface;
76172
- cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10).attr("fill", fill3).attr("stroke", stroke2).attr("stroke-width", 1.5);
76173
- const sizeMetric = Math.min(it.w, it.h * 2.5);
76174
- const headerFs = Math.max(
76175
- 13,
76176
- Math.min(20, Math.round(13 + (sizeMetric - 220) / 70))
76177
- );
76178
- const grow = (headerFs - 13) / (20 - 13);
76179
- const headerOpacity = 0.92 - grow * 0.3;
76180
- const headerY = it.y + Math.round(headerFs * 0.7) + 7;
76181
- cell.append("text").attr("x", it.x + it.w / 2).attr("y", headerY).attr("text-anchor", "middle").attr("font-size", headerFs).attr("font-weight", 700).attr("fill", palette.text).attr("opacity", headerOpacity).text(clipLabel2(it.label ?? "", it.w - 24, headerFs));
76182
- bindToggle(cell, it, ctx, BLOCK_HEADER_H);
76183
- if (it.inner) drawItems(g, it.inner, ctx, itemPath);
76184
- continue;
76185
- }
76186
- const fill2 = color ? fillMode === "solid" ? mix(color, palette.bg, 80) : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 14) : palette.bg;
76187
- cell.attr("data-leaf", "true");
76188
- cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 8).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 1.25);
76189
- cell.append("text").attr("x", it.x + it.w / 2).attr("y", it.y + it.h / 2 + 5).attr("text-anchor", "middle").attr("font-size", 13).attr("font-weight", 600).attr("fill", palette.text).text(clipLabel2(it.label ?? "", it.w - 16, 13));
76190
- }
76191
- }
76192
- function bindToggle(cell, it, ctx, hitH) {
76193
- if (!ctx.onToggle || !it.node || it.lineNumber === void 0) return;
76194
- const id = it.node.id;
76195
- const ln = it.lineNumber;
76196
- cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", hitH).attr("rx", 10).attr("fill", "transparent").style("cursor", "pointer").on("click", () => ctx.onToggle(id, ln));
76197
- }
76198
- function authoredCollapsedIds(parsed) {
76199
- const into = /* @__PURE__ */ new Set();
76200
- collectCollapsed(parsed, into);
76201
- return into;
76202
- }
76203
- function collectCollapsed(parsed, into) {
76204
- const walk = (grid) => {
76205
- for (const row of grid.rows)
76206
- for (const c of row)
76207
- if (isBlockNode(c)) {
76208
- if (c.collapsed && c.grid) into.add(c.id);
76209
- if (c.grid) walk(c.grid);
76210
- }
76211
- };
76212
- walk(parsed.top);
76213
- }
76214
- function buildBlockLegend(parsed) {
76215
- if (parsed.tagGroups.length === 0) return null;
76216
- const tg = parsed.tagGroups[0];
76217
- const key = tagAttrKey(tg.name);
76218
- const used = /* @__PURE__ */ new Set();
76219
- const walk = (grid) => {
76220
- for (const row of grid.rows)
76221
- for (const c of row)
76222
- if (isBlockNode(c)) {
76223
- const v = c.metadata[key];
76224
- if (v) used.add(v.toLowerCase());
76225
- if (c.grid) walk(c.grid);
76127
+ var LZString = (function() {
76128
+ var f = String.fromCharCode;
76129
+ var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
76130
+ var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
76131
+ var baseReverseDic = {};
76132
+ function getBaseValue(alphabet, character) {
76133
+ if (!baseReverseDic[alphabet]) {
76134
+ baseReverseDic[alphabet] = {};
76135
+ for (var i = 0; i < alphabet.length; i++) {
76136
+ baseReverseDic[alphabet][alphabet.charAt(i)] = i;
76137
+ }
76226
76138
  }
76227
- };
76228
- walk(parsed.top);
76229
- const entries = tg.entries.filter((e) => used.has(e.value.toLowerCase())).map((e) => ({ value: e.value, color: e.color }));
76230
- if (entries.length === 0) return null;
76231
- return { groups: [{ name: tg.name, entries }], activeGroup: tg.name };
76232
- }
76233
- var PADDING5, TITLE_BAND2, MIN_EXPORT_WIDTH, LEGEND_POSITION3, clipCounter;
76234
- var init_renderer27 = __esm({
76235
- "src/block/renderer.ts"() {
76236
- "use strict";
76237
- init_fonts();
76238
- init_color_utils();
76239
- init_tag_groups();
76240
- init_inline_header();
76241
- init_legend_integration();
76242
- init_legend_layout();
76243
- init_legend_constants();
76244
- init_title_constants();
76245
- init_text_measure();
76246
- init_types4();
76247
- init_layout20();
76248
- PADDING5 = 12;
76249
- TITLE_BAND2 = 36;
76250
- MIN_EXPORT_WIDTH = 220;
76251
- LEGEND_POSITION3 = {
76252
- placement: "top-center",
76253
- titleRelation: "below-title"
76254
- };
76255
- clipCounter = 0;
76256
- }
76257
- });
76258
-
76259
- // src/goal/renderer.ts
76260
- var renderer_exports27 = {};
76261
- __export(renderer_exports27, {
76262
- renderGoal: () => renderGoal,
76263
- renderGoalForExport: () => renderGoalForExport
76264
- });
76265
- import * as d3Selection34 from "d3-selection";
76266
- function clamp5(x, lo, hi) {
76267
- return Math.max(lo, Math.min(hi, x));
76268
- }
76269
- function computeMetrics(parsed) {
76270
- const pctFrac = parsed.hasTarget ? parsed.now / parsed.target : 0;
76271
- const fillFrac = clamp5(pctFrac, 0, 1);
76272
- const pctLabel = `${Math.round(pctFrac * 100)}%`;
76273
- const targetLabel = parsed.hasTarget ? compactNumber2(parsed.target) : "?";
76274
- const valueLabel = `${compactNumber2(parsed.now)} / ${targetLabel}`;
76275
- const ariaTarget = parsed.hasTarget ? parsed.target : "?";
76276
- const ariaLabel = `${parsed.title ?? "Goal"}: ${parsed.now} of ${ariaTarget} (${Math.round(
76277
- pctFrac * 100
76278
- )}%)`;
76279
- return { pctFrac, fillFrac, pctLabel, valueLabel, ariaLabel };
76280
- }
76281
- function autoBandColor(pctFrac, palette) {
76282
- const name = pctFrac < 0.5 ? "red" : pctFrac < 0.8 ? "orange" : "green";
76283
- return resolveColor(name, palette) || name;
76284
- }
76285
- function resolvePaint(parsed, palette, isDark, pctFrac) {
76286
- const autoColor = !parsed.options.noAutoColor && parsed.hasTarget ? autoBandColor(pctFrac, palette) : null;
76287
- const base = parsed.color && resolveColor(parsed.color, palette) || parsed.color || autoColor || getSeriesColors(palette)[0];
76288
- return {
76289
- base,
76139
+ return baseReverseDic[alphabet][character];
76140
+ }
76141
+ var LZString2 = {
76142
+ compressToBase64: function(input) {
76143
+ if (input == null) return "";
76144
+ var res = LZString2._compress(input, 6, function(a) {
76145
+ return keyStrBase64.charAt(a);
76146
+ });
76147
+ switch (res.length % 4) {
76148
+ // To produce valid Base64
76149
+ default:
76150
+ // When could this happen ?
76151
+ case 0:
76152
+ return res;
76153
+ case 1:
76154
+ return res + "===";
76155
+ case 2:
76156
+ return res + "==";
76157
+ case 3:
76158
+ return res + "=";
76159
+ }
76160
+ },
76161
+ decompressFromBase64: function(input) {
76162
+ if (input == null) return "";
76163
+ if (input == "") return null;
76164
+ return LZString2._decompress(input.length, 32, function(index) {
76165
+ return getBaseValue(keyStrBase64, input.charAt(index));
76166
+ });
76167
+ },
76168
+ compressToUTF16: function(input) {
76169
+ if (input == null) return "";
76170
+ return LZString2._compress(input, 15, function(a) {
76171
+ return f(a + 32);
76172
+ }) + " ";
76173
+ },
76174
+ decompressFromUTF16: function(compressed) {
76175
+ if (compressed == null) return "";
76176
+ if (compressed == "") return null;
76177
+ return LZString2._decompress(compressed.length, 16384, function(index) {
76178
+ return compressed.charCodeAt(index) - 32;
76179
+ });
76180
+ },
76181
+ //compress into uint8array (UCS-2 big endian format)
76182
+ compressToUint8Array: function(uncompressed) {
76183
+ var compressed = LZString2.compress(uncompressed);
76184
+ var buf = new Uint8Array(compressed.length * 2);
76185
+ for (var i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
76186
+ var current_value = compressed.charCodeAt(i);
76187
+ buf[i * 2] = current_value >>> 8;
76188
+ buf[i * 2 + 1] = current_value % 256;
76189
+ }
76190
+ return buf;
76191
+ },
76192
+ //decompress from uint8array (UCS-2 big endian format)
76193
+ decompressFromUint8Array: function(compressed) {
76194
+ if (compressed === null || compressed === void 0) {
76195
+ return LZString2.decompress(compressed);
76196
+ } else {
76197
+ var buf = new Array(compressed.length / 2);
76198
+ for (var i = 0, TotalLen = buf.length; i < TotalLen; i++) {
76199
+ buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];
76200
+ }
76201
+ var result = [];
76202
+ buf.forEach(function(c) {
76203
+ result.push(f(c));
76204
+ });
76205
+ return LZString2.decompress(result.join(""));
76206
+ }
76207
+ },
76208
+ //compress into a string that is already URI encoded
76209
+ compressToEncodedURIComponent: function(input) {
76210
+ if (input == null) return "";
76211
+ return LZString2._compress(input, 6, function(a) {
76212
+ return keyStrUriSafe.charAt(a);
76213
+ });
76214
+ },
76215
+ //decompress from an output of compressToEncodedURIComponent
76216
+ decompressFromEncodedURIComponent: function(input) {
76217
+ if (input == null) return "";
76218
+ if (input == "") return null;
76219
+ input = input.replace(/ /g, "+");
76220
+ return LZString2._decompress(input.length, 32, function(index) {
76221
+ return getBaseValue(keyStrUriSafe, input.charAt(index));
76222
+ });
76223
+ },
76224
+ compress: function(uncompressed) {
76225
+ return LZString2._compress(uncompressed, 16, function(a) {
76226
+ return f(a);
76227
+ });
76228
+ },
76229
+ _compress: function(uncompressed, bitsPerChar, getCharFromInt) {
76230
+ if (uncompressed == null) return "";
76231
+ var i, value, context_dictionary = {}, context_dictionaryToCreate = {}, context_c = "", context_wc = "", context_w = "", context_enlargeIn = 2, context_dictSize = 3, context_numBits = 2, context_data = [], context_data_val = 0, context_data_position = 0, ii;
76232
+ for (ii = 0; ii < uncompressed.length; ii += 1) {
76233
+ context_c = uncompressed.charAt(ii);
76234
+ if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
76235
+ context_dictionary[context_c] = context_dictSize++;
76236
+ context_dictionaryToCreate[context_c] = true;
76237
+ }
76238
+ context_wc = context_w + context_c;
76239
+ if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) {
76240
+ context_w = context_wc;
76241
+ } else {
76242
+ if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
76243
+ if (context_w.charCodeAt(0) < 256) {
76244
+ for (i = 0; i < context_numBits; i++) {
76245
+ context_data_val = context_data_val << 1;
76246
+ if (context_data_position == bitsPerChar - 1) {
76247
+ context_data_position = 0;
76248
+ context_data.push(getCharFromInt(context_data_val));
76249
+ context_data_val = 0;
76250
+ } else {
76251
+ context_data_position++;
76252
+ }
76253
+ }
76254
+ value = context_w.charCodeAt(0);
76255
+ for (i = 0; i < 8; i++) {
76256
+ context_data_val = context_data_val << 1 | value & 1;
76257
+ if (context_data_position == bitsPerChar - 1) {
76258
+ context_data_position = 0;
76259
+ context_data.push(getCharFromInt(context_data_val));
76260
+ context_data_val = 0;
76261
+ } else {
76262
+ context_data_position++;
76263
+ }
76264
+ value = value >> 1;
76265
+ }
76266
+ } else {
76267
+ value = 1;
76268
+ for (i = 0; i < context_numBits; i++) {
76269
+ context_data_val = context_data_val << 1 | value;
76270
+ if (context_data_position == bitsPerChar - 1) {
76271
+ context_data_position = 0;
76272
+ context_data.push(getCharFromInt(context_data_val));
76273
+ context_data_val = 0;
76274
+ } else {
76275
+ context_data_position++;
76276
+ }
76277
+ value = 0;
76278
+ }
76279
+ value = context_w.charCodeAt(0);
76280
+ for (i = 0; i < 16; i++) {
76281
+ context_data_val = context_data_val << 1 | value & 1;
76282
+ if (context_data_position == bitsPerChar - 1) {
76283
+ context_data_position = 0;
76284
+ context_data.push(getCharFromInt(context_data_val));
76285
+ context_data_val = 0;
76286
+ } else {
76287
+ context_data_position++;
76288
+ }
76289
+ value = value >> 1;
76290
+ }
76291
+ }
76292
+ context_enlargeIn--;
76293
+ if (context_enlargeIn == 0) {
76294
+ context_enlargeIn = Math.pow(2, context_numBits);
76295
+ context_numBits++;
76296
+ }
76297
+ delete context_dictionaryToCreate[context_w];
76298
+ } else {
76299
+ value = context_dictionary[context_w];
76300
+ for (i = 0; i < context_numBits; i++) {
76301
+ context_data_val = context_data_val << 1 | value & 1;
76302
+ if (context_data_position == bitsPerChar - 1) {
76303
+ context_data_position = 0;
76304
+ context_data.push(getCharFromInt(context_data_val));
76305
+ context_data_val = 0;
76306
+ } else {
76307
+ context_data_position++;
76308
+ }
76309
+ value = value >> 1;
76310
+ }
76311
+ }
76312
+ context_enlargeIn--;
76313
+ if (context_enlargeIn == 0) {
76314
+ context_enlargeIn = Math.pow(2, context_numBits);
76315
+ context_numBits++;
76316
+ }
76317
+ context_dictionary[context_wc] = context_dictSize++;
76318
+ context_w = String(context_c);
76319
+ }
76320
+ }
76321
+ if (context_w !== "") {
76322
+ if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
76323
+ if (context_w.charCodeAt(0) < 256) {
76324
+ for (i = 0; i < context_numBits; i++) {
76325
+ context_data_val = context_data_val << 1;
76326
+ if (context_data_position == bitsPerChar - 1) {
76327
+ context_data_position = 0;
76328
+ context_data.push(getCharFromInt(context_data_val));
76329
+ context_data_val = 0;
76330
+ } else {
76331
+ context_data_position++;
76332
+ }
76333
+ }
76334
+ value = context_w.charCodeAt(0);
76335
+ for (i = 0; i < 8; i++) {
76336
+ context_data_val = context_data_val << 1 | value & 1;
76337
+ if (context_data_position == bitsPerChar - 1) {
76338
+ context_data_position = 0;
76339
+ context_data.push(getCharFromInt(context_data_val));
76340
+ context_data_val = 0;
76341
+ } else {
76342
+ context_data_position++;
76343
+ }
76344
+ value = value >> 1;
76345
+ }
76346
+ } else {
76347
+ value = 1;
76348
+ for (i = 0; i < context_numBits; i++) {
76349
+ context_data_val = context_data_val << 1 | value;
76350
+ if (context_data_position == bitsPerChar - 1) {
76351
+ context_data_position = 0;
76352
+ context_data.push(getCharFromInt(context_data_val));
76353
+ context_data_val = 0;
76354
+ } else {
76355
+ context_data_position++;
76356
+ }
76357
+ value = 0;
76358
+ }
76359
+ value = context_w.charCodeAt(0);
76360
+ for (i = 0; i < 16; i++) {
76361
+ context_data_val = context_data_val << 1 | value & 1;
76362
+ if (context_data_position == bitsPerChar - 1) {
76363
+ context_data_position = 0;
76364
+ context_data.push(getCharFromInt(context_data_val));
76365
+ context_data_val = 0;
76366
+ } else {
76367
+ context_data_position++;
76368
+ }
76369
+ value = value >> 1;
76370
+ }
76371
+ }
76372
+ context_enlargeIn--;
76373
+ if (context_enlargeIn == 0) {
76374
+ context_enlargeIn = Math.pow(2, context_numBits);
76375
+ context_numBits++;
76376
+ }
76377
+ delete context_dictionaryToCreate[context_w];
76378
+ } else {
76379
+ value = context_dictionary[context_w];
76380
+ for (i = 0; i < context_numBits; i++) {
76381
+ context_data_val = context_data_val << 1 | value & 1;
76382
+ if (context_data_position == bitsPerChar - 1) {
76383
+ context_data_position = 0;
76384
+ context_data.push(getCharFromInt(context_data_val));
76385
+ context_data_val = 0;
76386
+ } else {
76387
+ context_data_position++;
76388
+ }
76389
+ value = value >> 1;
76390
+ }
76391
+ }
76392
+ context_enlargeIn--;
76393
+ if (context_enlargeIn == 0) {
76394
+ context_enlargeIn = Math.pow(2, context_numBits);
76395
+ context_numBits++;
76396
+ }
76397
+ }
76398
+ value = 2;
76399
+ for (i = 0; i < context_numBits; i++) {
76400
+ context_data_val = context_data_val << 1 | value & 1;
76401
+ if (context_data_position == bitsPerChar - 1) {
76402
+ context_data_position = 0;
76403
+ context_data.push(getCharFromInt(context_data_val));
76404
+ context_data_val = 0;
76405
+ } else {
76406
+ context_data_position++;
76407
+ }
76408
+ value = value >> 1;
76409
+ }
76410
+ while (true) {
76411
+ context_data_val = context_data_val << 1;
76412
+ if (context_data_position == bitsPerChar - 1) {
76413
+ context_data.push(getCharFromInt(context_data_val));
76414
+ break;
76415
+ } else context_data_position++;
76416
+ }
76417
+ return context_data.join("");
76418
+ },
76419
+ decompress: function(compressed) {
76420
+ if (compressed == null) return "";
76421
+ if (compressed == "") return null;
76422
+ return LZString2._decompress(compressed.length, 32768, function(index) {
76423
+ return compressed.charCodeAt(index);
76424
+ });
76425
+ },
76426
+ _decompress: function(length, resetValue, getNextValue) {
76427
+ var dictionary = [], next, enlargeIn = 4, dictSize = 4, numBits = 3, entry = "", result = [], i, w, bits, resb, maxpower, power, c, data = { val: getNextValue(0), position: resetValue, index: 1 };
76428
+ for (i = 0; i < 3; i += 1) {
76429
+ dictionary[i] = i;
76430
+ }
76431
+ bits = 0;
76432
+ maxpower = Math.pow(2, 2);
76433
+ power = 1;
76434
+ while (power != maxpower) {
76435
+ resb = data.val & data.position;
76436
+ data.position >>= 1;
76437
+ if (data.position == 0) {
76438
+ data.position = resetValue;
76439
+ data.val = getNextValue(data.index++);
76440
+ }
76441
+ bits |= (resb > 0 ? 1 : 0) * power;
76442
+ power <<= 1;
76443
+ }
76444
+ switch (next = bits) {
76445
+ case 0:
76446
+ bits = 0;
76447
+ maxpower = Math.pow(2, 8);
76448
+ power = 1;
76449
+ while (power != maxpower) {
76450
+ resb = data.val & data.position;
76451
+ data.position >>= 1;
76452
+ if (data.position == 0) {
76453
+ data.position = resetValue;
76454
+ data.val = getNextValue(data.index++);
76455
+ }
76456
+ bits |= (resb > 0 ? 1 : 0) * power;
76457
+ power <<= 1;
76458
+ }
76459
+ c = f(bits);
76460
+ break;
76461
+ case 1:
76462
+ bits = 0;
76463
+ maxpower = Math.pow(2, 16);
76464
+ power = 1;
76465
+ while (power != maxpower) {
76466
+ resb = data.val & data.position;
76467
+ data.position >>= 1;
76468
+ if (data.position == 0) {
76469
+ data.position = resetValue;
76470
+ data.val = getNextValue(data.index++);
76471
+ }
76472
+ bits |= (resb > 0 ? 1 : 0) * power;
76473
+ power <<= 1;
76474
+ }
76475
+ c = f(bits);
76476
+ break;
76477
+ case 2:
76478
+ return "";
76479
+ }
76480
+ dictionary[3] = c;
76481
+ w = c;
76482
+ result.push(c);
76483
+ while (true) {
76484
+ if (data.index > length) {
76485
+ return "";
76486
+ }
76487
+ bits = 0;
76488
+ maxpower = Math.pow(2, numBits);
76489
+ power = 1;
76490
+ while (power != maxpower) {
76491
+ resb = data.val & data.position;
76492
+ data.position >>= 1;
76493
+ if (data.position == 0) {
76494
+ data.position = resetValue;
76495
+ data.val = getNextValue(data.index++);
76496
+ }
76497
+ bits |= (resb > 0 ? 1 : 0) * power;
76498
+ power <<= 1;
76499
+ }
76500
+ switch (c = bits) {
76501
+ case 0:
76502
+ bits = 0;
76503
+ maxpower = Math.pow(2, 8);
76504
+ power = 1;
76505
+ while (power != maxpower) {
76506
+ resb = data.val & data.position;
76507
+ data.position >>= 1;
76508
+ if (data.position == 0) {
76509
+ data.position = resetValue;
76510
+ data.val = getNextValue(data.index++);
76511
+ }
76512
+ bits |= (resb > 0 ? 1 : 0) * power;
76513
+ power <<= 1;
76514
+ }
76515
+ dictionary[dictSize++] = f(bits);
76516
+ c = dictSize - 1;
76517
+ enlargeIn--;
76518
+ break;
76519
+ case 1:
76520
+ bits = 0;
76521
+ maxpower = Math.pow(2, 16);
76522
+ power = 1;
76523
+ while (power != maxpower) {
76524
+ resb = data.val & data.position;
76525
+ data.position >>= 1;
76526
+ if (data.position == 0) {
76527
+ data.position = resetValue;
76528
+ data.val = getNextValue(data.index++);
76529
+ }
76530
+ bits |= (resb > 0 ? 1 : 0) * power;
76531
+ power <<= 1;
76532
+ }
76533
+ dictionary[dictSize++] = f(bits);
76534
+ c = dictSize - 1;
76535
+ enlargeIn--;
76536
+ break;
76537
+ case 2:
76538
+ return result.join("");
76539
+ }
76540
+ if (enlargeIn == 0) {
76541
+ enlargeIn = Math.pow(2, numBits);
76542
+ numBits++;
76543
+ }
76544
+ if (dictionary[c]) {
76545
+ entry = dictionary[c];
76546
+ } else {
76547
+ if (c === dictSize) {
76548
+ entry = w + w.charAt(0);
76549
+ } else {
76550
+ return null;
76551
+ }
76552
+ }
76553
+ result.push(entry);
76554
+ dictionary[dictSize++] = w + entry.charAt(0);
76555
+ enlargeIn--;
76556
+ w = entry;
76557
+ if (enlargeIn == 0) {
76558
+ enlargeIn = Math.pow(2, numBits);
76559
+ numBits++;
76560
+ }
76561
+ }
76562
+ }
76563
+ };
76564
+ return LZString2;
76565
+ })();
76566
+ if (typeof define === "function" && define.amd) {
76567
+ define(function() {
76568
+ return LZString;
76569
+ });
76570
+ } else if (typeof module !== "undefined" && module != null) {
76571
+ module.exports = LZString;
76572
+ } else if (typeof angular !== "undefined" && angular != null) {
76573
+ angular.module("LZString", []).factory("LZString", function() {
76574
+ return LZString;
76575
+ });
76576
+ }
76577
+ }
76578
+ });
76579
+
76580
+ // src/sharing.ts
76581
+ function encodeViewState(state) {
76582
+ const keys = Object.keys(state);
76583
+ if (keys.length === 0) return "";
76584
+ return (0, import_lz_string.compressToEncodedURIComponent)(JSON.stringify(state));
76585
+ }
76586
+ function encodeDiagramUrl(dsl, options) {
76587
+ const baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;
76588
+ const compressed = (0, import_lz_string.compressToEncodedURIComponent)(dsl);
76589
+ const byteSize = new TextEncoder().encode(compressed).byteLength;
76590
+ if (byteSize > COMPRESSED_SIZE_LIMIT) {
76591
+ return {
76592
+ error: "too-large",
76593
+ compressedSize: byteSize,
76594
+ limit: COMPRESSED_SIZE_LIMIT
76595
+ };
76596
+ }
76597
+ let hash = `dgmo=${compressed}`;
76598
+ if (options?.viewState) {
76599
+ const vsEncoded = encodeViewState(options.viewState);
76600
+ if (vsEncoded) {
76601
+ hash += `&vs=${vsEncoded}`;
76602
+ }
76603
+ }
76604
+ if (options?.palette && options.palette !== "nord") {
76605
+ hash += `&pal=${encodeURIComponent(options.palette)}`;
76606
+ }
76607
+ if (options?.theme && options.theme !== "dark") {
76608
+ hash += `&th=${encodeURIComponent(options.theme)}`;
76609
+ }
76610
+ if (options?.filename) {
76611
+ hash += `&fn=${encodeURIComponent(options.filename)}`;
76612
+ }
76613
+ return { url: `${baseUrl}?${hash}#${hash}` };
76614
+ }
76615
+ var import_lz_string, DEFAULT_BASE_URL, COMPRESSED_SIZE_LIMIT;
76616
+ var init_sharing = __esm({
76617
+ "src/sharing.ts"() {
76618
+ "use strict";
76619
+ import_lz_string = __toESM(require_lz_string(), 1);
76620
+ DEFAULT_BASE_URL = "https://online.diagrammo.app";
76621
+ COMPRESSED_SIZE_LIMIT = 8192;
76622
+ }
76623
+ });
76624
+
76625
+ // src/error-card.ts
76626
+ function docsLink(source) {
76627
+ const chartType = parseDgmoChartType(source);
76628
+ const hasGuide = chartType !== null && !chartTypes.some((c) => c.id === chartType && c.internal);
76629
+ return hasGuide ? {
76630
+ url: `${DOCS_BASE}/chart-${chartType}/`,
76631
+ label: `Read the ${chartType} guide \u2197`
76632
+ } : { url: `${DOCS_BASE}/`, label: "Browse the DGMO docs \u2197" };
76633
+ }
76634
+ var DOCS_BASE, MONO_FAMILY, W, PAD2, CONTENT_W;
76635
+ var init_error_card = __esm({
76636
+ "src/error-card.ts"() {
76637
+ "use strict";
76638
+ init_dgmo_router();
76639
+ init_chart_types();
76640
+ DOCS_BASE = "https://diagrammo.app/docs";
76641
+ MONO_FAMILY = "ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace";
76642
+ W = 660;
76643
+ PAD2 = 24;
76644
+ CONTENT_W = W - PAD2 * 2;
76645
+ }
76646
+ });
76647
+
76648
+ // src/live-link/renderer.ts
76649
+ var renderer_exports26 = {};
76650
+ __export(renderer_exports26, {
76651
+ renderLiveLinkCard: () => renderLiveLinkCard
76652
+ });
76653
+ function renderLiveLinkCard(parsed, palette, theme) {
76654
+ const isTransparent = theme === "transparent";
76655
+ const parts = [];
76656
+ let y = PAD3 + 18;
76657
+ parts.push(cloudGlyph(PAD3, y - 14, 24, palette.textMuted));
76658
+ const headline = parsed.title ?? parsed.id ?? "Unresolved live link";
76659
+ const headlineMono = parsed.title === null && parsed.id !== null;
76660
+ parts.push(
76661
+ `<text x="${CONTENT_X}" y="${y}" fill="${palette.text}" font-family="${headlineMono ? MONO_FAMILY : FONT_FAMILY}" font-size="${HEADLINE_FS}" font-weight="${headlineMono ? 500 : 700}">${escapeXml(truncateText(headline, HEADLINE_FS, CONTENT_W2))}</text>`
76662
+ );
76663
+ y += 30;
76664
+ parts.push(
76665
+ `<text x="${CONTENT_X}" y="${y}" fill="${palette.textMuted}" font-family="${FONT_FAMILY}" font-size="${SUBTITLE_FS}">${escapeXml(SUBTITLE)}</text>`
76666
+ );
76667
+ y += 22;
76668
+ if (parsed.title !== null && parsed.id !== null) {
76669
+ parts.push(
76670
+ `<text x="${CONTENT_X}" y="${y}" fill="${palette.textMuted}" font-family="${MONO_FAMILY}" font-size="${ID_FS}">${escapeXml(
76671
+ truncateText(parsed.id, ID_FS, CONTENT_W2)
76672
+ )}</text>`
76673
+ );
76674
+ y += 22;
76675
+ }
76676
+ const height = Math.round(y + PAD3 - 12);
76677
+ const pageBg = isTransparent ? "" : `<rect width="100%" height="100%" fill="${palette.bg}"/>`;
76678
+ return [
76679
+ `<svg xmlns="http://www.w3.org/2000/svg" width="${W2}" height="${height}" viewBox="0 0 ${W2} ${height}" preserveAspectRatio="xMidYMid meet" font-family="${FONT_FAMILY}">`,
76680
+ pageBg,
76681
+ `<rect x="0.5" y="0.5" width="${W2 - 1}" height="${height - 1}" rx="10" fill="${palette.surface}" stroke="${palette.border}" stroke-width="1"/>`,
76682
+ parts.join(""),
76683
+ `</svg>`
76684
+ ].join("");
76685
+ }
76686
+ function cloudGlyph(x, y, size, color) {
76687
+ const s = size / 24;
76688
+ const d = "M6.5 19a4.5 4.5 0 0 1-.6-8.96A6 6 0 0 1 17.6 8.7 4.15 4.15 0 0 1 17.5 19Z";
76689
+ return `<path transform="translate(${x},${y}) scale(${s})" d="${d}" fill="none" stroke="${color}" stroke-width="1.6" stroke-linejoin="round"/>`;
76690
+ }
76691
+ function escapeXml(s) {
76692
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
76693
+ }
76694
+ var W2, PAD3, CONTENT_X, CONTENT_W2, HEADLINE_FS, SUBTITLE_FS, ID_FS, SUBTITLE;
76695
+ var init_renderer27 = __esm({
76696
+ "src/live-link/renderer.ts"() {
76697
+ "use strict";
76698
+ init_text_measure();
76699
+ init_fonts();
76700
+ init_error_card();
76701
+ W2 = 560;
76702
+ PAD3 = 28;
76703
+ CONTENT_X = PAD3 + 40;
76704
+ CONTENT_W2 = W2 - CONTENT_X - PAD3;
76705
+ HEADLINE_FS = 18;
76706
+ SUBTITLE_FS = 13;
76707
+ ID_FS = 13;
76708
+ SUBTITLE = "Live link published at Diagrammo Cloud";
76709
+ }
76710
+ });
76711
+
76712
+ // src/block/layout.ts
76713
+ function layoutBlock(grid, opts = {}) {
76714
+ const collapsed = opts.collapsed ?? /* @__PURE__ */ new Set();
76715
+ const node = layoutGrid(grid, 0, 0, null, collapsed);
76716
+ return { width: node.w, height: node.h, items: node.items };
76717
+ }
76718
+ function maxSpanSum(g) {
76719
+ return Math.max(
76720
+ 1,
76721
+ ...g.rows.map((r) => r.reduce((s, c) => s + (c.span || 1), 0))
76722
+ );
76723
+ }
76724
+ function leafW(node) {
76725
+ return Math.max(
76726
+ MIN_COL,
76727
+ Math.min(MAX_COL, measureText(node.label, LABEL_FS) + 2 * BLOCK_PAD + 14)
76728
+ );
76729
+ }
76730
+ function gridColW(g) {
76731
+ let m = MIN_COL;
76732
+ for (const row of g.rows)
76733
+ for (const c of row) {
76734
+ if (!isBlockNode(c)) continue;
76735
+ const iw = c.grid ? intrinsicGridW(c.grid) + 2 * BLOCK_PAD : leafW(c);
76736
+ m = Math.max(m, iw / (c.span || 1));
76737
+ }
76738
+ return m;
76739
+ }
76740
+ function intrinsicGridW(g) {
76741
+ const cols = g.cols ?? maxSpanSum(g);
76742
+ return cols * gridColW(g) + (cols + 1) * BLOCK_GAP;
76743
+ }
76744
+ function layoutGrid(g, ox, oy, forceColW, collapsed) {
76745
+ const cols = g.cols ?? maxSpanSum(g);
76746
+ const colW = forceColW ?? gridColW(g);
76747
+ const gridW = cols * colW + (cols + 1) * BLOCK_GAP;
76748
+ let cy = oy + BLOCK_GAP;
76749
+ const items = [];
76750
+ let maxRight = ox + BLOCK_GAP;
76751
+ for (const row of g.rows) {
76752
+ let cx = ox + BLOCK_GAP;
76753
+ let rowH = BLOCK_LEAF_H;
76754
+ const rowItems = [];
76755
+ for (const cell of row) {
76756
+ const span = cell.span || 1;
76757
+ const cw = span * colW + (span - 1) * BLOCK_GAP;
76758
+ if (!isBlockNode(cell)) {
76759
+ rowItems.push({ type: "empty", x: cx, y: cy, w: cw, h: BLOCK_LEAF_H });
76760
+ cx += cw + BLOCK_GAP;
76761
+ maxRight = Math.max(maxRight, cx - BLOCK_GAP);
76762
+ continue;
76763
+ }
76764
+ if (cell.grid && collapsed.has(cell.id)) {
76765
+ const item = {
76766
+ type: "collapsed",
76767
+ x: cx,
76768
+ y: cy,
76769
+ w: cw,
76770
+ h: BLOCK_COLLAPSED_H,
76771
+ label: cell.label,
76772
+ node: cell,
76773
+ lineNumber: cell.lineNumber
76774
+ };
76775
+ rowItems.push(item);
76776
+ rowH = Math.max(rowH, BLOCK_COLLAPSED_H);
76777
+ cx += cw + BLOCK_GAP;
76778
+ maxRight = Math.max(maxRight, cx - BLOCK_GAP);
76779
+ continue;
76780
+ }
76781
+ if (cell.grid) {
76782
+ const innerCols = cell.grid.cols ?? maxSpanSum(cell.grid);
76783
+ const innerColW = Math.max(
76784
+ MIN_COL * 0.66,
76785
+ (cw - 2 * BLOCK_PAD - (innerCols + 1) * BLOCK_GAP) / innerCols
76786
+ );
76787
+ const inner = layoutGrid(
76788
+ cell.grid,
76789
+ cx + BLOCK_PAD,
76790
+ cy + BLOCK_HEADER_H,
76791
+ innerColW,
76792
+ collapsed
76793
+ );
76794
+ const h = BLOCK_HEADER_H + inner.h + BLOCK_PAD;
76795
+ rowItems.push({
76796
+ type: "container",
76797
+ x: cx,
76798
+ y: cy,
76799
+ w: cw,
76800
+ h,
76801
+ label: cell.label,
76802
+ node: cell,
76803
+ lineNumber: cell.lineNumber,
76804
+ inner: inner.items
76805
+ });
76806
+ rowH = Math.max(rowH, h);
76807
+ cx += cw + BLOCK_GAP;
76808
+ maxRight = Math.max(maxRight, cx - BLOCK_GAP);
76809
+ continue;
76810
+ }
76811
+ rowItems.push({
76812
+ type: "leaf",
76813
+ x: cx,
76814
+ y: cy,
76815
+ w: cw,
76816
+ h: BLOCK_LEAF_H,
76817
+ label: cell.label,
76818
+ node: cell,
76819
+ lineNumber: cell.lineNumber
76820
+ });
76821
+ cx += cw + BLOCK_GAP;
76822
+ maxRight = Math.max(maxRight, cx - BLOCK_GAP);
76823
+ }
76824
+ items.push(...rowItems);
76825
+ cy += rowH + BLOCK_GAP;
76826
+ }
76827
+ const fitW = Math.max(gridW, maxRight - ox + BLOCK_GAP);
76828
+ return { x: ox, y: oy, w: fitW, h: cy - oy, items };
76829
+ }
76830
+ var BLOCK_GAP, BLOCK_PAD, BLOCK_LEAF_H, BLOCK_HEADER_H, BLOCK_COLLAPSED_H, BLOCK_BAR_H, MIN_COL, MAX_COL, LABEL_FS;
76831
+ var init_layout20 = __esm({
76832
+ "src/block/layout.ts"() {
76833
+ "use strict";
76834
+ init_text_measure();
76835
+ init_types4();
76836
+ BLOCK_GAP = 12;
76837
+ BLOCK_PAD = 10;
76838
+ BLOCK_LEAF_H = 46;
76839
+ BLOCK_HEADER_H = 28;
76840
+ BLOCK_COLLAPSED_H = 46;
76841
+ BLOCK_BAR_H = 6;
76842
+ MIN_COL = 104;
76843
+ MAX_COL = 250;
76844
+ LABEL_FS = 13;
76845
+ }
76846
+ });
76847
+
76848
+ // src/block/renderer.ts
76849
+ var renderer_exports27 = {};
76850
+ __export(renderer_exports27, {
76851
+ authoredCollapsedIds: () => authoredCollapsedIds,
76852
+ renderBlock: () => renderBlock,
76853
+ renderBlockForExport: () => renderBlockForExport
76854
+ });
76855
+ import * as d3Selection33 from "d3-selection";
76856
+ function renderBlockForExport(container, parsed, palette, isDark, exportDims, options) {
76857
+ renderBlock(container, parsed, palette, isDark, exportDims, {
76858
+ exportMode: true,
76859
+ ...options
76860
+ });
76861
+ }
76862
+ function renderBlock(container, parsed, palette, isDark, exportDims, options = {}) {
76863
+ if (parsed.error || parsed.top.rows.length === 0) return;
76864
+ d3Selection33.select(container).selectAll(":not([data-d3-tooltip])").remove();
76865
+ const opts = parsed.options;
76866
+ const showTitle = !!parsed.title;
76867
+ const titleH = showTitle ? TITLE_BAND2 : 0;
76868
+ const collapsed = options.collapsed ?? authoredCollapsedIds(parsed);
76869
+ const layout = layoutBlock(parsed.top, { collapsed });
76870
+ const legend = !opts.noLegend ? buildBlockLegend(parsed) : null;
76871
+ let width;
76872
+ let height;
76873
+ if (options.exportMode) {
76874
+ width = Math.max(layout.width, MIN_EXPORT_WIDTH) + PADDING5 * 2;
76875
+ } else {
76876
+ width = exportDims?.width ?? container.clientWidth;
76877
+ }
76878
+ const legendReserve = legend ? getMaxLegendReservedHeight(
76879
+ { groups: legend.groups, position: LEGEND_POSITION3, mode: "preview" },
76880
+ width
76881
+ ) + LEGEND_GROUP_GAP : 0;
76882
+ const inlineRequested = opts.legendInline === true;
76883
+ const legendExtent = inlineRequested && legend ? getLegendExtent(
76884
+ {
76885
+ groups: legend.groups,
76886
+ position: {
76887
+ placement: "top-center",
76888
+ titleRelation: "inline-with-title"
76889
+ },
76890
+ mode: options.exportMode ? "export" : "preview"
76891
+ },
76892
+ { activeGroup: legend.activeGroup ?? null },
76893
+ width
76894
+ ) : { width: 0, height: 0 };
76895
+ const header = layoutInlineHeader({
76896
+ requested: inlineRequested,
76897
+ title: parsed.title ?? "",
76898
+ hasLegend: !!legend,
76899
+ legendWidth: legendExtent.width,
76900
+ legendHeight: legendExtent.height,
76901
+ containerWidth: width,
76902
+ titleBandHeight: titleH,
76903
+ legendReserve,
76904
+ titleBaselineY: TITLE_Y,
76905
+ titleFontSize: TITLE_FONT_SIZE
76906
+ });
76907
+ const areaY = (header.inline ? titleH : titleH + legendReserve) + PADDING5;
76908
+ if (options.exportMode) {
76909
+ height = areaY + layout.height + PADDING5;
76910
+ } else {
76911
+ height = exportDims?.height ?? container.clientHeight;
76912
+ }
76913
+ if (width <= 0 || height <= 0) return;
76914
+ const areaX = PADDING5;
76915
+ const areaW = Math.max(1, width - PADDING5 * 2);
76916
+ const areaH = Math.max(1, height - areaY - PADDING5);
76917
+ const scale = Math.min(1, areaW / layout.width, areaH / layout.height);
76918
+ const offsetX = areaX + (areaW - layout.width * scale) / 2;
76919
+ const offsetY = areaY;
76920
+ const svg = d3Selection33.select(container).append("svg").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").attr("class", "dgmo-block").style("font-family", FONT_FAMILY);
76921
+ if (showTitle) {
76922
+ const title = svg.append("text").attr("class", "chart-title").attr("x", header.titleX).attr("y", TITLE_Y).attr("text-anchor", header.titleAnchor).attr("fill", palette.text).attr("font-family", FONT_FAMILY).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).text(parsed.title);
76923
+ if (parsed.titleLineNumber !== null) {
76924
+ title.attr("data-line-number", parsed.titleLineNumber);
76925
+ }
76926
+ }
76927
+ const activeGroup = parsed.tagGroups.length > 0 ? parsed.tagGroups[0].name : null;
76928
+ const neutral = mix(palette.text, palette.bg, 22);
76929
+ const root = svg.append("g").attr("class", "dgmo-block-cells").attr("transform", `translate(${offsetX},${offsetY}) scale(${scale})`);
76930
+ drawItems(root, layout.items, {
76931
+ palette,
76932
+ tagGroups: parsed.tagGroups,
76933
+ activeGroup,
76934
+ activeKey: activeGroup ? tagAttrKey(activeGroup) : null,
76935
+ neutral,
76936
+ fillMode: opts.fillMode,
76937
+ isDark,
76938
+ onToggle: options.onToggle
76939
+ });
76940
+ if (legend) {
76941
+ const legendG = svg.append("g").attr("class", "dgmo-block-legend").attr(
76942
+ "transform",
76943
+ header.inline ? `translate(${header.legendX}, ${header.legendY})` : `translate(0, ${titleH})`
76944
+ );
76945
+ renderIntegratedLegend(legendG, {
76946
+ groups: legend.groups,
76947
+ palette: {
76948
+ bg: palette.bg,
76949
+ surface: palette.surface,
76950
+ text: palette.text,
76951
+ textMuted: palette.textMuted,
76952
+ primary: palette.primary
76953
+ },
76954
+ isDark,
76955
+ width,
76956
+ mode: options.exportMode ? "export" : "preview",
76957
+ position: {
76958
+ placement: "top-center",
76959
+ titleRelation: header.inline ? "inline-with-title" : "below-title"
76960
+ },
76961
+ activeGroup: legend.activeGroup
76962
+ });
76963
+ }
76964
+ }
76965
+ function colorOf(node, ctx) {
76966
+ if (!node || !ctx.activeGroup) return null;
76967
+ return resolveTagColor(node.metadata, ctx.tagGroups, ctx.activeGroup) ?? null;
76968
+ }
76969
+ function clipLabel2(s, maxWidth, fs) {
76970
+ if (measureText(s, fs) <= maxWidth) return s;
76971
+ let lo = 0;
76972
+ let hi = s.length;
76973
+ while (lo < hi) {
76974
+ const mid = Math.ceil((lo + hi) / 2);
76975
+ if (measureText(s.slice(0, mid) + "\u2026", fs) <= maxWidth) lo = mid;
76976
+ else hi = mid - 1;
76977
+ }
76978
+ return lo <= 0 ? "" : s.slice(0, lo) + "\u2026";
76979
+ }
76980
+ function drawItems(g, items, ctx, path = []) {
76981
+ const { palette, fillMode } = ctx;
76982
+ for (const it of items) {
76983
+ if (it.type === "empty") {
76984
+ g.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 7).attr("fill", "none").attr("stroke", ctx.neutral).attr("stroke-width", 1).attr("stroke-dasharray", "3 4").attr("opacity", 0.7);
76985
+ continue;
76986
+ }
76987
+ const node = it.node;
76988
+ const itemPath = [...path, node.id];
76989
+ const color = colorOf(node, ctx);
76990
+ const stroke2 = color ?? ctx.neutral;
76991
+ const cell = g.append("g").attr("class", "dgmo-block-cell").attr("data-block-id", node.id).attr("data-block-path", itemPath.join(" / "));
76992
+ if (it.lineNumber !== void 0)
76993
+ cell.attr("data-line-number", it.lineNumber);
76994
+ if (ctx.activeKey) {
76995
+ const v = node.metadata[ctx.activeKey];
76996
+ if (v) cell.attr(`data-tag-${ctx.activeKey}`, v);
76997
+ }
76998
+ if (it.type === "collapsed") {
76999
+ const fill3 = color ? fillMode === "solid" ? color : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 12) : palette.surface;
77000
+ const cid = `dgmo-block-clip-${clipCounter++}`;
77001
+ cell.append("clipPath").attr("id", cid).append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10);
77002
+ cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10).attr("fill", fill3).attr("stroke", stroke2).attr("stroke-width", 1.5);
77003
+ cell.append("text").attr("x", it.x + it.w / 2).attr("y", it.y + it.h / 2 + 4).attr("text-anchor", "middle").attr("font-size", 12.5).attr("font-weight", 700).attr("fill", palette.text).text(clipLabel2(it.label ?? "", it.w - 24, 12.5));
77004
+ cell.append("rect").attr("x", it.x).attr("y", it.y + it.h - BLOCK_BAR_H).attr("width", it.w).attr("height", BLOCK_BAR_H).attr("fill", fillMode === "solid" && color ? palette.text : stroke2).attr("clip-path", `url(#${cid})`);
77005
+ bindToggle(cell, it, ctx, it.h);
77006
+ continue;
77007
+ }
77008
+ if (it.type === "container") {
77009
+ const fill3 = color ? fillMode === "solid" ? color : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 7) : palette.surface;
77010
+ cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10).attr("fill", fill3).attr("stroke", stroke2).attr("stroke-width", 1.5);
77011
+ const sizeMetric = Math.min(it.w, it.h * 2.5);
77012
+ const headerFs = Math.max(
77013
+ 13,
77014
+ Math.min(20, Math.round(13 + (sizeMetric - 220) / 70))
77015
+ );
77016
+ const grow = (headerFs - 13) / (20 - 13);
77017
+ const headerOpacity = 0.92 - grow * 0.3;
77018
+ const headerY = it.y + Math.round(headerFs * 0.7) + 7;
77019
+ cell.append("text").attr("x", it.x + it.w / 2).attr("y", headerY).attr("text-anchor", "middle").attr("font-size", headerFs).attr("font-weight", 700).attr("fill", palette.text).attr("opacity", headerOpacity).text(clipLabel2(it.label ?? "", it.w - 24, headerFs));
77020
+ bindToggle(cell, it, ctx, BLOCK_HEADER_H);
77021
+ if (it.inner) drawItems(g, it.inner, ctx, itemPath);
77022
+ continue;
77023
+ }
77024
+ const fill2 = color ? fillMode === "solid" ? mix(color, palette.bg, 80) : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 14) : palette.bg;
77025
+ cell.attr("data-leaf", "true");
77026
+ cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 8).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 1.25);
77027
+ cell.append("text").attr("x", it.x + it.w / 2).attr("y", it.y + it.h / 2 + 5).attr("text-anchor", "middle").attr("font-size", 13).attr("font-weight", 600).attr("fill", palette.text).text(clipLabel2(it.label ?? "", it.w - 16, 13));
77028
+ }
77029
+ }
77030
+ function bindToggle(cell, it, ctx, hitH) {
77031
+ if (!ctx.onToggle || !it.node || it.lineNumber === void 0) return;
77032
+ const id = it.node.id;
77033
+ const ln = it.lineNumber;
77034
+ cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", hitH).attr("rx", 10).attr("fill", "transparent").style("cursor", "pointer").on("click", () => ctx.onToggle(id, ln));
77035
+ }
77036
+ function authoredCollapsedIds(parsed) {
77037
+ const into = /* @__PURE__ */ new Set();
77038
+ collectCollapsed(parsed, into);
77039
+ return into;
77040
+ }
77041
+ function collectCollapsed(parsed, into) {
77042
+ const walk = (grid) => {
77043
+ for (const row of grid.rows)
77044
+ for (const c of row)
77045
+ if (isBlockNode(c)) {
77046
+ if (c.collapsed && c.grid) into.add(c.id);
77047
+ if (c.grid) walk(c.grid);
77048
+ }
77049
+ };
77050
+ walk(parsed.top);
77051
+ }
77052
+ function buildBlockLegend(parsed) {
77053
+ if (parsed.tagGroups.length === 0) return null;
77054
+ const tg = parsed.tagGroups[0];
77055
+ const key = tagAttrKey(tg.name);
77056
+ const used = /* @__PURE__ */ new Set();
77057
+ const walk = (grid) => {
77058
+ for (const row of grid.rows)
77059
+ for (const c of row)
77060
+ if (isBlockNode(c)) {
77061
+ const v = c.metadata[key];
77062
+ if (v) used.add(v.toLowerCase());
77063
+ if (c.grid) walk(c.grid);
77064
+ }
77065
+ };
77066
+ walk(parsed.top);
77067
+ const entries = tg.entries.filter((e) => used.has(e.value.toLowerCase())).map((e) => ({ value: e.value, color: e.color }));
77068
+ if (entries.length === 0) return null;
77069
+ return { groups: [{ name: tg.name, entries }], activeGroup: tg.name };
77070
+ }
77071
+ var PADDING5, TITLE_BAND2, MIN_EXPORT_WIDTH, LEGEND_POSITION3, clipCounter;
77072
+ var init_renderer28 = __esm({
77073
+ "src/block/renderer.ts"() {
77074
+ "use strict";
77075
+ init_fonts();
77076
+ init_color_utils();
77077
+ init_tag_groups();
77078
+ init_inline_header();
77079
+ init_legend_integration();
77080
+ init_legend_layout();
77081
+ init_legend_constants();
77082
+ init_title_constants();
77083
+ init_text_measure();
77084
+ init_types4();
77085
+ init_layout20();
77086
+ PADDING5 = 12;
77087
+ TITLE_BAND2 = 36;
77088
+ MIN_EXPORT_WIDTH = 220;
77089
+ LEGEND_POSITION3 = {
77090
+ placement: "top-center",
77091
+ titleRelation: "below-title"
77092
+ };
77093
+ clipCounter = 0;
77094
+ }
77095
+ });
77096
+
77097
+ // src/goal/renderer.ts
77098
+ var renderer_exports28 = {};
77099
+ __export(renderer_exports28, {
77100
+ renderGoal: () => renderGoal,
77101
+ renderGoalForExport: () => renderGoalForExport
77102
+ });
77103
+ import * as d3Selection34 from "d3-selection";
77104
+ function clamp5(x, lo, hi) {
77105
+ return Math.max(lo, Math.min(hi, x));
77106
+ }
77107
+ function computeMetrics(parsed) {
77108
+ const pctFrac = parsed.hasTarget ? parsed.now / parsed.target : 0;
77109
+ const fillFrac = clamp5(pctFrac, 0, 1);
77110
+ const pctLabel = `${Math.round(pctFrac * 100)}%`;
77111
+ const targetLabel = parsed.hasTarget ? compactNumber2(parsed.target) : "?";
77112
+ const valueLabel = `${compactNumber2(parsed.now)} / ${targetLabel}`;
77113
+ const ariaTarget = parsed.hasTarget ? parsed.target : "?";
77114
+ const ariaLabel = `${parsed.title ?? "Goal"}: ${parsed.now} of ${ariaTarget} (${Math.round(
77115
+ pctFrac * 100
77116
+ )}%)`;
77117
+ return { pctFrac, fillFrac, pctLabel, valueLabel, ariaLabel };
77118
+ }
77119
+ function autoBandColor(pctFrac, palette) {
77120
+ const name = pctFrac < 0.5 ? "red" : pctFrac < 0.8 ? "orange" : "green";
77121
+ return resolveColor(name, palette) || name;
77122
+ }
77123
+ function resolvePaint(parsed, palette, isDark, pctFrac) {
77124
+ const autoColor = !parsed.options.noAutoColor && parsed.hasTarget ? autoBandColor(pctFrac, palette) : null;
77125
+ const base = parsed.color && resolveColor(parsed.color, palette) || parsed.color || autoColor || getSeriesColors(palette)[0];
77126
+ return {
77127
+ base,
76290
77128
  // §1.9 fill family: tint (default) / solid / outline. In outline mode the
76291
77129
  // progress region renders hollow (theme base bg) and the traffic-light /
76292
77130
  // override color moves to the border — advancement still reads from the
@@ -76597,7 +77435,7 @@ function renderGauge(svg, parsed, metrics, paint) {
76597
77435
  };
76598
77436
  }
76599
77437
  var GOAL_TITLE_SIZE;
76600
- var init_renderer28 = __esm({
77438
+ var init_renderer29 = __esm({
76601
77439
  "src/goal/renderer.ts"() {
76602
77440
  "use strict";
76603
77441
  init_fonts();
@@ -76611,8 +77449,8 @@ var init_renderer28 = __esm({
76611
77449
  });
76612
77450
 
76613
77451
  // src/countdown/renderer.ts
76614
- var renderer_exports28 = {};
76615
- __export(renderer_exports28, {
77452
+ var renderer_exports29 = {};
77453
+ __export(renderer_exports29, {
76616
77454
  renderCountdown: () => renderCountdown,
76617
77455
  renderCountdownForExport: () => renderCountdownForExport
76618
77456
  });
@@ -77583,7 +78421,7 @@ function renderCountdownForExport(container, parsed, palette, isDark, exportDims
77583
78421
  renderCountdown(container, parsed, palette, isDark, exportDims);
77584
78422
  }
77585
78423
  var MON_ABBR, WD_ABBR, DAY_START, dayDelta2, keyOf, REPEAT_ICON_PATH, MONTH_TARGET_PX;
77586
- var init_renderer29 = __esm({
78424
+ var init_renderer30 = __esm({
77587
78425
  "src/countdown/renderer.ts"() {
77588
78426
  "use strict";
77589
78427
  init_fonts();
@@ -77622,8 +78460,8 @@ var init_renderer29 = __esm({
77622
78460
  });
77623
78461
 
77624
78462
  // src/clock/renderer.ts
77625
- var renderer_exports29 = {};
77626
- __export(renderer_exports29, {
78463
+ var renderer_exports30 = {};
78464
+ __export(renderer_exports30, {
77627
78465
  renderClock: () => renderClock,
77628
78466
  renderClockForExport: () => renderClockForExport
77629
78467
  });
@@ -78146,7 +78984,7 @@ function renderClockForExport(container, parsed, palette, isDark, exportDims) {
78146
78984
  renderClock(container, parsed, palette, isDark, exportDims);
78147
78985
  }
78148
78986
  var PLACE_ACCENTS, clipSeq, WEEKDAY_ABBR4;
78149
- var init_renderer30 = __esm({
78987
+ var init_renderer31 = __esm({
78150
78988
  "src/clock/renderer.ts"() {
78151
78989
  "use strict";
78152
78990
  init_fonts();
@@ -78744,8 +79582,8 @@ var init_layout21 = __esm({
78744
79582
  });
78745
79583
 
78746
79584
  // src/bracket/renderer.ts
78747
- var renderer_exports30 = {};
78748
- __export(renderer_exports30, {
79585
+ var renderer_exports31 = {};
79586
+ __export(renderer_exports31, {
78749
79587
  bracketExportDimensions: () => bracketExportDimensions,
78750
79588
  renderBracket: () => renderBracket,
78751
79589
  renderBracketForExport: () => renderBracketForExport
@@ -79117,7 +79955,7 @@ function renderBracketForExport(container, parsed, palette, isDark, exportDims)
79117
79955
  renderBracket(container, parsed, palette, isDark, exportDims);
79118
79956
  }
79119
79957
  var PADDING6, TITLE_BAND3, HALF_SPAN2, COMMENT_LH, LEGEND_POSITION4;
79120
- var init_renderer31 = __esm({
79958
+ var init_renderer32 = __esm({
79121
79959
  "src/bracket/renderer.ts"() {
79122
79960
  "use strict";
79123
79961
  init_fonts();
@@ -79144,8 +79982,8 @@ var init_renderer31 = __esm({
79144
79982
  });
79145
79983
 
79146
79984
  // src/raci/renderer.ts
79147
- var renderer_exports31 = {};
79148
- __export(renderer_exports31, {
79985
+ var renderer_exports32 = {};
79986
+ __export(renderer_exports32, {
79149
79987
  MARKER_LABELS: () => MARKER_LABELS,
79150
79988
  renderRaci: () => renderRaci,
79151
79989
  renderRaciForExport: () => renderRaciForExport
@@ -79845,7 +80683,7 @@ function parseQuotedSegments(message) {
79845
80683
  return out;
79846
80684
  }
79847
80685
  var MARKER_LABELS, TITLE_AREA_HEIGHT4, H_MARGIN2, V_MARGIN3, LEGEND_HEIGHT2, LEGEND_CHIP_GAP, LEGEND_CHIP_LABEL_MIN, LEGEND_LETTER_CHIP_W, TITLE_LEGEND_GAP, LEGEND_LABEL_FONT, LEGEND_LETTER_FONT, HEADER_HEIGHT5, ROW_HEIGHT, PHASE_HEIGHT, TASK_LABEL_MIN, TASK_LABEL_MAX, ROLE_COL_MIN, ROLE_COL_MAX, CELL_PAD, VIOLATION_LINE_HEIGHT, STACK_TOP_GAP, DESC_FONT2, COLUMN_RADIUS3, COLUMN_INSET, COLUMN_BOTTOM_PAD, MARKER_FONT, MARKER_FONT_WEIGHT, LABEL_FONT5, ROLE_HEADER_FONT, PHASE_FONT, TINT_PCT, NODE_RADIUS3, AUTO_ACCENTS, SLICE_GAP, NAME_LINE_HEIGHT, DESC_LINE_HEIGHT9;
79848
- var init_renderer32 = __esm({
80686
+ var init_renderer33 = __esm({
79849
80687
  "src/raci/renderer.ts"() {
79850
80688
  "use strict";
79851
80689
  init_parsing();
@@ -80109,8 +80947,8 @@ var init_tag_resolution = __esm({
80109
80947
  });
80110
80948
 
80111
80949
  // src/sequence/renderer.ts
80112
- var renderer_exports32 = {};
80113
- __export(renderer_exports32, {
80950
+ var renderer_exports33 = {};
80951
+ __export(renderer_exports33, {
80114
80952
  applyGroupOrdering: () => applyGroupOrdering,
80115
80953
  applyPositionOverrides: () => applyPositionOverrides,
80116
80954
  buildNoteMessageMap: () => buildNoteMessageMap,
@@ -80160,7 +80998,7 @@ function wrapLabelWords(words, maxWidth, fontSize) {
80160
80998
  if (current) lines.push(current);
80161
80999
  return lines;
80162
81000
  }
80163
- function renderRectParticipant(g, palette, isDark, color, fillMode, w = W, h = H) {
81001
+ function renderRectParticipant(g, palette, isDark, color, fillMode, w = W3, h = H) {
80164
81002
  g.append("rect").attr("x", -w / 2).attr("y", 0).attr("width", w).attr("height", h).attr("rx", 2).attr("ry", 2).attr("fill", fill(palette, isDark, color, fillMode)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW);
80165
81003
  }
80166
81004
  function renderActorParticipant(g, palette, color, h = H) {
@@ -80182,7 +81020,7 @@ function renderActorParticipant(g, palette, color, h = H) {
80182
81020
  g.append("line").attr("x1", cx).attr("y1", bodyBottomY).attr("x2", cx - legSpan).attr("y2", legY).attr("stroke", s).attr("stroke-width", actorSW);
80183
81021
  g.append("line").attr("x1", cx).attr("y1", bodyBottomY).attr("x2", cx + legSpan).attr("y2", legY).attr("stroke", s).attr("stroke-width", actorSW);
80184
81022
  }
80185
- function renderDatabaseParticipant(g, palette, isDark, color, fillMode, w = W, h = H) {
81023
+ function renderDatabaseParticipant(g, palette, isDark, color, fillMode, w = W3, h = H) {
80186
81024
  const ry = 7;
80187
81025
  const topY = ry;
80188
81026
  const bodyH = h - ry * 2;
@@ -80194,7 +81032,7 @@ function renderDatabaseParticipant(g, palette, isDark, color, fillMode, w = W, h
80194
81032
  g.append("line").attr("x1", w / 2).attr("y1", topY).attr("x2", w / 2).attr("y2", topY + bodyH).attr("stroke", s).attr("stroke-width", SW);
80195
81033
  g.append("ellipse").attr("cx", 0).attr("cy", topY).attr("rx", w / 2).attr("ry", ry).attr("fill", f).attr("stroke", s).attr("stroke-width", SW);
80196
81034
  }
80197
- function renderQueueParticipant(g, palette, isDark, color, fillMode, w = W, h = H) {
81035
+ function renderQueueParticipant(g, palette, isDark, color, fillMode, w = W3, h = H) {
80198
81036
  const rx = 10;
80199
81037
  const leftX = -w / 2 + rx;
80200
81038
  const bodyW = w - rx * 2;
@@ -80206,7 +81044,7 @@ function renderQueueParticipant(g, palette, isDark, color, fillMode, w = W, h =
80206
81044
  g.append("line").attr("x1", leftX).attr("y1", h).attr("x2", leftX + bodyW).attr("y2", h).attr("stroke", s).attr("stroke-width", SW);
80207
81045
  g.append("ellipse").attr("cx", leftX).attr("cy", h / 2).attr("rx", rx).attr("ry", h / 2).attr("fill", f).attr("stroke", s).attr("stroke-width", SW);
80208
81046
  }
80209
- function renderCacheParticipant(g, palette, isDark, color, fillMode, w = W, h = H) {
81047
+ function renderCacheParticipant(g, palette, isDark, color, fillMode, w = W3, h = H) {
80210
81048
  const ry = 7;
80211
81049
  const topY = ry;
80212
81050
  const bodyH = h - ry * 2;
@@ -81421,846 +82259,389 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
81421
82259
  renderBlockFrames(el.children, depth + 1);
81422
82260
  if (el.elseIfBranches) {
81423
82261
  for (const branch of el.elseIfBranches) {
81424
- renderBlockFrames(branch.children, depth + 1);
81425
- }
81426
- }
81427
- renderBlockFrames(el.elseChildren, depth + 1);
81428
- }
81429
- };
81430
- if (elements && elements.length > 0) {
81431
- renderBlockFrames(elements, 0);
81432
- }
81433
- const ACTIVATION_NEST_OFFSET = ctx.structural(6);
81434
- activations.forEach((act) => {
81435
- const px = participantX.get(act.participantId);
81436
- if (px === void 0) return;
81437
- const x = px - sActivationWidth / 2 + act.depth * ACTIVATION_NEST_OFFSET;
81438
- const y1 = stepY(act.startStep);
81439
- const y2 = stepY(act.endStep);
81440
- const coveredLines = [];
81441
- for (let si = act.startStep; si <= act.endStep; si++) {
81442
- const step = renderSteps[si];
81443
- if (!step) continue;
81444
- const msg = messages[step.messageIndex];
81445
- if (msg) coveredLines.push(msg.lineNumber);
81446
- }
81447
- const triggerStep = renderSteps[act.startStep];
81448
- const triggerMsg = triggerStep !== void 0 ? messages[triggerStep.messageIndex] : void 0;
81449
- const actTagValue = triggerMsg ? tagMap?.messages.get(triggerMsg.lineNumber) : void 0;
81450
- const actTagColor = getTagColor(actTagValue);
81451
- const actBaseColor = actTagColor || palette.primary;
81452
- svg.append("rect").attr("x", x).attr("y", y1).attr("width", sActivationWidth).attr("height", y2 - y1).attr("fill", themeBaseBg(palette, isDark));
81453
- const actFill = shapeFill(palette, actBaseColor, isDark, {
81454
- mode: fillMode
81455
- });
81456
- const actRect = svg.append("rect").attr("x", x).attr("y", y1).attr("width", sActivationWidth).attr("height", y2 - y1).attr("fill", actFill).attr("stroke", actBaseColor).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("data-participant-id", act.participantId).attr("data-msg-lines", coveredLines.join(",")).attr("data-line-number", coveredLines[0] ?? "").attr("class", "activation");
81457
- if (tagKey && actTagValue) {
81458
- actRect.attr(`data-tag-${tagKey}`, actTagValue.toLowerCase());
81459
- }
81460
- });
81461
- for (const ln of deferredLines) {
81462
- const line11 = svg.append("line").attr("x1", ln.x1).attr("y1", ln.y1).attr("x2", ln.x2).attr("y2", ln.y2).attr("stroke", palette.textMuted).attr("stroke-width", 1).attr("stroke-dasharray", "2 3").attr("class", "block-divider");
81463
- if (ln.blockLine !== void 0)
81464
- line11.attr("data-block-line", String(ln.blockLine));
81465
- }
81466
- for (const lbl of deferredLabels) {
81467
- const t = svg.append("text").attr("x", lbl.x).attr("y", lbl.y).attr("fill", palette.text).attr("font-size", 11).attr("class", "block-label").text(lbl.text);
81468
- if (lbl.bold) t.attr("font-weight", "bold");
81469
- if (lbl.italic) t.attr("font-style", "italic");
81470
- if (lbl.blockLine !== void 0)
81471
- t.attr("data-block-line", String(lbl.blockLine));
81472
- }
81473
- const activeDepthAt = (pid, stepIdx) => {
81474
- let maxDepth = -1;
81475
- for (const act of activations) {
81476
- if (act.participantId === pid && act.startStep <= stepIdx && stepIdx <= act.endStep && act.depth > maxDepth) {
81477
- maxDepth = act.depth;
81478
- }
81479
- }
81480
- return maxDepth;
81481
- };
81482
- const arrowEdgeX = (pid, stepIdx, side) => {
81483
- const px = participantX.get(pid);
81484
- const depth = activeDepthAt(pid, stepIdx);
81485
- if (depth < 0) return px;
81486
- const offset = depth * ACTIVATION_NEST_OFFSET;
81487
- return side === "right" ? px + sActivationWidth / 2 + offset : px - sActivationWidth / 2 + offset;
81488
- };
81489
- const leftmostX = Math.min(...Array.from(participantX.values()));
81490
- const rightmostX = frameRightmostX;
81491
- const sectionLineX1 = leftmostX - sBoxW / 2 - 10;
81492
- const sectionLineX2 = rightmostX + sBoxW / 2 + 10;
81493
- for (const region of sectionRegions) {
81494
- const sec = region.section;
81495
- const secY = sectionYPositions.get(sec.lineNumber);
81496
- if (secY === void 0) continue;
81497
- const isCollapsed = collapsedSections?.has(sec.lineNumber) ?? false;
81498
- const lineColor = palette.textMuted;
81499
- const sectionG = svg.append("g").attr("data-section-toggle", "").attr("data-line-number", String(sec.lineNumber)).attr("data-section", "").attr("tabindex", "0").attr("role", "button").attr("aria-expanded", String(!isCollapsed));
81500
- const BAND_HEIGHT = 22;
81501
- const bandX = sectionLineX1 - 10;
81502
- const bandWidth = sectionLineX2 - sectionLineX1 + 20;
81503
- const bandOpacity = isCollapsed ? isDark ? 0.35 : 0.25 : isDark ? 0.1 : 0.08;
81504
- sectionG.append("rect").attr("x", bandX).attr("y", secY - BAND_HEIGHT / 2).attr("width", bandWidth).attr("height", BAND_HEIGHT).attr("fill", lineColor).attr("opacity", bandOpacity).attr("rx", 2).attr("pointer-events", "none").attr("class", "section-divider");
81505
- const msgCount = sectionMsgCounts.get(sec.lineNumber) ?? 0;
81506
- const labelText = isCollapsed ? `${sec.label} (${msgCount} ${msgCount === 1 ? "message" : "messages"})` : sec.label;
81507
- const labelX = (sectionLineX1 + sectionLineX2) / 2;
81508
- const labelHitW = Math.max(80, measureText(labelText, 11) + 24);
81509
- sectionG.append("rect").attr("x", labelX - labelHitW / 2).attr("y", secY - BAND_HEIGHT / 2).attr("width", labelHitW).attr("height", BAND_HEIGHT).attr("fill", "transparent").attr("class", "section-label-hit");
81510
- sectionG.append("text").attr("x", labelX).attr("y", secY + 4).attr("text-anchor", "middle").attr("fill", lineColor).attr("font-size", 11).attr("font-weight", "bold").attr("class", "section-label").text(labelText);
81511
- }
81512
- renderSteps.forEach((step, i) => {
81513
- const fromX = participantX.get(step.from);
81514
- const toX = participantX.get(step.to);
81515
- if (fromX === void 0 || toX === void 0) return;
81516
- const y = stepY(i);
81517
- const HIT_H = 20;
81518
- const msg = messages[step.messageIndex];
81519
- const msgTagValue = msg ? tagMap?.messages.get(msg.lineNumber) : void 0;
81520
- const msgTagColor = getTagColor(msgTagValue);
81521
- if (step.type === "call") {
81522
- const arrowColor = msgTagColor || palette.text;
81523
- if (step.from === step.to) {
81524
- const x = arrowEdgeX(step.from, i, "right");
81525
- const loopX = x + sSelfCallWidth;
81526
- const hitX = x;
81527
- svg.append("rect").attr("x", hitX).attr("y", y - 5).attr("width", sSelfCallWidth).attr("height", sSelfCallHeight + 10).attr("fill", "transparent").attr("class", "message-hit-area").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
81528
- const selfCallEl = svg.append("path").attr("d", `M ${x} ${y} H ${loopX} V ${y + sSelfCallHeight} H ${x}`).attr("fill", "none").attr("stroke", arrowColor).attr("stroke-width", 1.2).attr("marker-end", coloredMarker("call", msgTagColor)).attr("class", "message-arrow self-call").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i)).attr("data-from", step.from).attr("data-to", step.to);
81529
- if (tagKey && msgTagValue) {
81530
- selfCallEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
81531
- }
81532
- if (step.label) {
81533
- const labelEl = svg.append("text").attr("x", loopX + 5).attr("y", y + sSelfCallHeight / 2 + 4).attr("text-anchor", "start").attr("fill", arrowColor).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("font-size", 12).attr("class", "message-label").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
81534
- if (tagKey && msgTagValue) {
81535
- labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
81536
- }
81537
- labelEl.text(step.label);
81538
- }
81539
- } else {
81540
- const goingRight = fromX < toX;
81541
- const x1 = arrowEdgeX(step.from, i, goingRight ? "right" : "left");
81542
- const x2 = arrowEdgeX(step.to, i, goingRight ? "left" : "right");
81543
- svg.append("rect").attr("x", Math.min(x1, x2)).attr("y", y - HIT_H / 2).attr("width", Math.abs(x2 - x1)).attr("height", HIT_H).attr("fill", "transparent").attr("class", "message-hit-area").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
81544
- const markerRef = step.async ? coloredMarker("async", msgTagColor) : coloredMarker("call", msgTagColor);
81545
- const arrowEl = svg.append("line").attr("x1", x1).attr("y1", y).attr("x2", x2).attr("y2", y).attr("stroke", arrowColor).attr("stroke-width", 1.2).attr("marker-end", markerRef).attr("class", "message-arrow").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i)).attr("data-from", step.from).attr("data-to", step.to);
81546
- if (tagKey && msgTagValue) {
81547
- arrowEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
81548
- }
81549
- if (step.label) {
81550
- const midX = (x1 + x2) / 2;
81551
- const labelEl = svg.append("text").attr("x", midX).attr("y", y - 8).attr("text-anchor", "middle").attr("fill", arrowColor).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("font-size", 12).attr("class", "message-label").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
81552
- if (tagKey && msgTagValue) {
81553
- labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
81554
- }
81555
- labelEl.text(step.label);
81556
- }
81557
- }
81558
- } else {
81559
- if (step.from === step.to) {
81560
- return;
81561
- }
81562
- const goingRight = fromX < toX;
81563
- const x1 = arrowEdgeX(step.from, i, goingRight ? "right" : "left");
81564
- const x2 = arrowEdgeX(step.to, i, goingRight ? "left" : "right");
81565
- const returnColor = msgTagColor || palette.textMuted;
81566
- svg.append("rect").attr("x", Math.min(x1, x2)).attr("y", y - HIT_H / 2).attr("width", Math.abs(x2 - x1)).attr("height", HIT_H).attr("fill", "transparent").attr("class", "message-hit-area").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
81567
- const returnEl = svg.append("line").attr("x1", x1).attr("y1", y).attr("x2", x2).attr("y2", y).attr("stroke", returnColor).attr("stroke-width", 1).attr("stroke-dasharray", "6 4").attr("marker-end", coloredMarker("return", msgTagColor)).attr("class", "return-arrow").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i)).attr("data-from", step.from).attr("data-to", step.to);
81568
- if (tagKey && msgTagValue) {
81569
- returnEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
81570
- }
81571
- if (step.label) {
81572
- const midX = (x1 + x2) / 2;
81573
- const labelEl = svg.append("text").attr("x", midX).attr("y", y - 6).attr("text-anchor", "middle").attr("fill", returnColor).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("font-size", 11).attr("class", "message-label").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
81574
- if (tagKey && msgTagValue) {
81575
- labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
81576
- }
81577
- labelEl.text(step.label);
81578
- }
81579
- }
81580
- });
81581
- const noteFill = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.bg, palette.surface, 15);
81582
- const renderNoteElements = (els) => {
81583
- for (const el of els) {
81584
- if (isSequenceNote(el)) {
81585
- const px = participantX.get(el.participantId);
81586
- if (px === void 0) continue;
81587
- const noteTopY = noteYMap.get(el);
81588
- if (noteTopY === void 0) continue;
81589
- const position = effectiveNotePosition(el);
81590
- const isRight = position === "right";
81591
- const afterSelfCall = isNoteAfterSelfCall(el);
81592
- const maxW = noteEffectiveMaxW(
81593
- el.participantId,
81594
- position,
81595
- afterSelfCall
81596
- );
81597
- const textWidth = noteTextWidth(maxW);
81598
- const wrappedLines = wrapTextLines(el.text, textWidth, sNoteFontSize);
81599
- const noteH = wrappedLines.length * sNoteLineH + sNotePadV * 2;
81600
- const maxLineW = Math.max(
81601
- ...wrappedLines.map((l) => measureText(l.text, sNoteFontSize))
81602
- );
81603
- const noteW = Math.min(
81604
- maxW,
81605
- Math.max(80, maxLineW + sNotePadH * 2 + sNoteFold)
81606
- );
81607
- const rightOffset = afterSelfCall && isRight ? sActivationWidth / 2 + sSelfCallWidth + sNoteGap : sActivationWidth + sNoteGap;
81608
- const noteX = isRight ? px + rightOffset : px - sActivationWidth - sNoteGap - noteW;
81609
- const noteG = svg.append("g").attr("class", "note").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber)).attr("data-line-end", String(el.endLineNumber));
81610
- noteG.append("path").attr(
81611
- "d",
81612
- [
81613
- `M ${noteX} ${noteTopY}`,
81614
- `L ${noteX + noteW - sNoteFold} ${noteTopY}`,
81615
- `L ${noteX + noteW} ${noteTopY + sNoteFold}`,
81616
- `L ${noteX + noteW} ${noteTopY + noteH}`,
81617
- `L ${noteX} ${noteTopY + noteH}`,
81618
- "Z"
81619
- ].join(" ")
81620
- ).attr("fill", noteFill).attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-box");
81621
- noteG.append("path").attr(
81622
- "d",
81623
- [
81624
- `M ${noteX + noteW - sNoteFold} ${noteTopY}`,
81625
- `L ${noteX + noteW - sNoteFold} ${noteTopY + sNoteFold}`,
81626
- `L ${noteX + noteW} ${noteTopY + sNoteFold}`
81627
- ].join(" ")
81628
- ).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-fold");
81629
- const BULLET_BODY_INDENT3 = 10;
81630
- wrappedLines.forEach((line11, li) => {
81631
- const textY = noteTopY + sNotePadV + (li + 1) * sNoteLineH - 3;
81632
- const indent = line11.kind === "plain" ? 0 : BULLET_BODY_INDENT3;
81633
- if (line11.kind === "bullet-first") {
81634
- noteG.append("text").attr("x", noteX + sNotePadH).attr("y", textY).attr("fill", palette.text).attr("font-size", sNoteFontSize).text("\u2022");
81635
- }
81636
- const textEl = noteG.append("text").attr("x", noteX + sNotePadH + indent).attr("y", textY).attr("fill", palette.text).attr("font-size", sNoteFontSize).attr("class", "note-text");
81637
- renderInlineText(textEl, line11.text, palette, sNoteFontSize);
81638
- });
81639
- } else if (isSequenceBlock(el)) {
81640
- renderNoteElements(el.children);
81641
- if (el.elseIfBranches) {
81642
- for (const branch of el.elseIfBranches) {
81643
- renderNoteElements(branch.children);
81644
- }
82262
+ renderBlockFrames(branch.children, depth + 1);
81645
82263
  }
81646
- renderNoteElements(el.elseChildren);
81647
82264
  }
82265
+ renderBlockFrames(el.elseChildren, depth + 1);
81648
82266
  }
81649
82267
  };
81650
82268
  if (elements && elements.length > 0) {
81651
- renderNoteElements(elements);
81652
- }
81653
- if (hasTagGroups) {
81654
- const legendY = sTopMargin + titleOffset;
81655
- const legendCallbacks = {};
81656
- const legendG = svg.append("g").attr("class", "sequence-legend").attr(
81657
- "transform",
81658
- header.inline ? `translate(${header.legendX}, ${header.legendY})` : `translate(0,${legendY})`
81659
- );
81660
- renderIntegratedLegend(legendG, {
81661
- ...legendConfig,
81662
- // Inline → left-origin so the wrapper's right-flush translate lands the
81663
- // legend at the header's right edge; stacked → centered below the title
81664
- // (identical to legendConfig.position, so the stacked path is unchanged).
81665
- position: {
81666
- placement: "top-center",
81667
- titleRelation: header.inline ? "inline-with-title" : "below-title"
81668
- },
81669
- palette,
81670
- isDark,
81671
- width: svgWidth,
81672
- activeGroup: activeTagGroup ?? null,
81673
- controlsExpanded: false,
81674
- callbacks: legendCallbacks
81675
- });
82269
+ renderBlockFrames(elements, 0);
81676
82270
  }
81677
- }
81678
- function buildNoteMessageMap(elements) {
81679
- const map = /* @__PURE__ */ new Map();
81680
- let lastMessageLine = -1;
81681
- const walk = (els) => {
81682
- for (const el of els) {
81683
- if (isSequenceNote(el)) {
81684
- if (lastMessageLine >= 0) {
81685
- map.set(el.lineNumber, lastMessageLine);
81686
- }
81687
- } else if (isSequenceBlock(el)) {
81688
- walk(el.children);
81689
- if (el.elseIfBranches) {
81690
- for (const branch of el.elseIfBranches) {
81691
- walk(branch.children);
81692
- }
81693
- }
81694
- walk(el.elseChildren);
81695
- } else if (!isSequenceSection(el)) {
81696
- lastMessageLine = el.lineNumber;
81697
- }
82271
+ const ACTIVATION_NEST_OFFSET = ctx.structural(6);
82272
+ activations.forEach((act) => {
82273
+ const px = participantX.get(act.participantId);
82274
+ if (px === void 0) return;
82275
+ const x = px - sActivationWidth / 2 + act.depth * ACTIVATION_NEST_OFFSET;
82276
+ const y1 = stepY(act.startStep);
82277
+ const y2 = stepY(act.endStep);
82278
+ const coveredLines = [];
82279
+ for (let si = act.startStep; si <= act.endStep; si++) {
82280
+ const step = renderSteps[si];
82281
+ if (!step) continue;
82282
+ const msg = messages[step.messageIndex];
82283
+ if (msg) coveredLines.push(msg.lineNumber);
81698
82284
  }
81699
- };
81700
- walk(elements);
81701
- return map;
81702
- }
81703
- function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, fillMode, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE5) {
81704
- const g = svg.append("g").attr("transform", `translate(${cx}, ${cy})`).attr("class", "participant").attr("data-participant-id", participant.id);
81705
- if (tagAttr) {
81706
- g.attr(`data-tag-${tagAttr.key}`, tagAttr.value);
81707
- }
81708
- switch (participant.type) {
81709
- case "actor":
81710
- renderActorParticipant(g, palette, color, boxH);
81711
- break;
81712
- case "database":
81713
- renderDatabaseParticipant(
81714
- g,
81715
- palette,
81716
- isDark,
81717
- color,
81718
- fillMode,
81719
- boxW,
81720
- boxH
81721
- );
81722
- break;
81723
- case "queue":
81724
- renderQueueParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
81725
- break;
81726
- case "cache":
81727
- renderCacheParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
81728
- break;
81729
- default:
81730
- renderRectParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
81731
- break;
81732
- }
81733
- const isActor = participant.type === "actor";
81734
- const labelLines = splitParticipantLabel(
81735
- participant.label,
81736
- labelTextW,
81737
- labelFontSize2
81738
- );
81739
- const fontSize = labelFontSize2;
81740
- const lineHeight = fontSize + 2;
81741
- const labelFill = isActor ? palette.text : contrastText(
81742
- fill(palette, isDark, color, fillMode),
81743
- palette.textOnFillLight,
81744
- palette.textOnFillDark
81745
- );
81746
- const textEl = g.append("text").attr("x", 0).attr("text-anchor", "middle").attr("fill", labelFill).attr("font-size", fontSize).attr("font-weight", 500);
81747
- const maxLabelW = labelTextWidth(boxW);
81748
- const truncLine = (text) => truncateText(text, fontSize, maxLabelW);
81749
- if (labelLines.length === 1) {
81750
- textEl.attr("y", isActor ? boxH + 14 : boxH / 2 + 5).text(truncLine(participant.label));
81751
- } else {
81752
- const totalHeight = labelLines.length * lineHeight;
81753
- const baseY = isActor ? boxH + 14 - (labelLines.length - 1) * lineHeight / 2 : boxH / 2 + 5 - (totalHeight - lineHeight) / 2;
81754
- labelLines.forEach((line11, i) => {
81755
- textEl.append("tspan").attr("x", 0).attr("dy", i === 0 ? `${baseY}px` : `${lineHeight}px`).text(truncLine(line11));
82285
+ const triggerStep = renderSteps[act.startStep];
82286
+ const triggerMsg = triggerStep !== void 0 ? messages[triggerStep.messageIndex] : void 0;
82287
+ const actTagValue = triggerMsg ? tagMap?.messages.get(triggerMsg.lineNumber) : void 0;
82288
+ const actTagColor = getTagColor(actTagValue);
82289
+ const actBaseColor = actTagColor || palette.primary;
82290
+ svg.append("rect").attr("x", x).attr("y", y1).attr("width", sActivationWidth).attr("height", y2 - y1).attr("fill", themeBaseBg(palette, isDark));
82291
+ const actFill = shapeFill(palette, actBaseColor, isDark, {
82292
+ mode: fillMode
81756
82293
  });
82294
+ const actRect = svg.append("rect").attr("x", x).attr("y", y1).attr("width", sActivationWidth).attr("height", y2 - y1).attr("fill", actFill).attr("stroke", actBaseColor).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("data-participant-id", act.participantId).attr("data-msg-lines", coveredLines.join(",")).attr("data-line-number", coveredLines[0] ?? "").attr("class", "activation");
82295
+ if (tagKey && actTagValue) {
82296
+ actRect.attr(`data-tag-${tagKey}`, actTagValue.toLowerCase());
82297
+ }
82298
+ });
82299
+ for (const ln of deferredLines) {
82300
+ const line11 = svg.append("line").attr("x1", ln.x1).attr("y1", ln.y1).attr("x2", ln.x2).attr("y2", ln.y2).attr("stroke", palette.textMuted).attr("stroke-width", 1).attr("stroke-dasharray", "2 3").attr("class", "block-divider");
82301
+ if (ln.blockLine !== void 0)
82302
+ line11.attr("data-block-line", String(ln.blockLine));
81757
82303
  }
81758
- }
81759
- var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, LABEL_FONT_SIZE5, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W2, NOTE_FOLD2, NOTE_PAD_H2, NOTE_PAD_V2, NOTE_FONT_SIZE3, NOTE_LINE_H2, NOTE_GAP2, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, ACTOR_LABEL_CLEARANCE, labelTextWidth, fill, stroke, SW, W, H;
81760
- var init_renderer33 = __esm({
81761
- "src/sequence/renderer.ts"() {
81762
- "use strict";
81763
- init_tag_groups();
81764
- init_parsing();
81765
- init_color_utils();
81766
- init_inline_markdown();
81767
- init_fonts();
81768
- init_parser7();
81769
- init_collapse5();
81770
- init_wrapped_desc();
81771
- init_text_measure();
81772
- init_tag_resolution();
81773
- init_tag_groups();
81774
- init_legend_layout();
81775
- init_parsing();
81776
- init_inline_header();
81777
- init_legend_integration();
81778
- init_title_constants();
81779
- init_scaling();
81780
- PARTICIPANT_GAP = 160;
81781
- PARTICIPANT_BOX_WIDTH = 120;
81782
- PARTICIPANT_BOX_HEIGHT = 50;
81783
- LABEL_FONT_SIZE5 = 13;
81784
- TOP_MARGIN = 20;
81785
- TITLE_HEIGHT8 = 30;
81786
- PARTICIPANT_Y_OFFSET = 10;
81787
- MESSAGE_START_OFFSET = 50;
81788
- LIFELINE_TAIL = 30;
81789
- ARROWHEAD_SIZE = 8;
81790
- NOTE_MAX_W2 = 200;
81791
- NOTE_FOLD2 = 10;
81792
- NOTE_PAD_H2 = 8;
81793
- NOTE_PAD_V2 = 6;
81794
- NOTE_FONT_SIZE3 = 10;
81795
- NOTE_LINE_H2 = 14;
81796
- NOTE_GAP2 = 15;
81797
- ACTIVATION_WIDTH = 10;
81798
- SELF_CALL_HEIGHT = 25;
81799
- SELF_CALL_WIDTH = 30;
81800
- ACTOR_LABEL_CLEARANCE = 22;
81801
- labelTextWidth = (boxW) => boxW - 10;
81802
- fill = (palette, isDark, color, fillMode) => color ? shapeFill(palette, color, isDark, { mode: fillMode }) : isDark ? mix(palette.overlay, palette.surface, 50) : mix(palette.bg, palette.surface, 50);
81803
- stroke = (palette, color) => color || palette.border;
81804
- SW = 1.5;
81805
- W = PARTICIPANT_BOX_WIDTH;
81806
- H = PARTICIPANT_BOX_HEIGHT;
82304
+ for (const lbl of deferredLabels) {
82305
+ const t = svg.append("text").attr("x", lbl.x).attr("y", lbl.y).attr("fill", palette.text).attr("font-size", 11).attr("class", "block-label").text(lbl.text);
82306
+ if (lbl.bold) t.attr("font-weight", "bold");
82307
+ if (lbl.italic) t.attr("font-style", "italic");
82308
+ if (lbl.blockLine !== void 0)
82309
+ t.attr("data-block-line", String(lbl.blockLine));
81807
82310
  }
81808
- });
81809
-
81810
- // node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js
81811
- var require_lz_string = __commonJS({
81812
- "node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js"(exports, module) {
81813
- "use strict";
81814
- var LZString = (function() {
81815
- var f = String.fromCharCode;
81816
- var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
81817
- var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
81818
- var baseReverseDic = {};
81819
- function getBaseValue(alphabet, character) {
81820
- if (!baseReverseDic[alphabet]) {
81821
- baseReverseDic[alphabet] = {};
81822
- for (var i = 0; i < alphabet.length; i++) {
81823
- baseReverseDic[alphabet][alphabet.charAt(i)] = i;
81824
- }
81825
- }
81826
- return baseReverseDic[alphabet][character];
82311
+ const activeDepthAt = (pid, stepIdx) => {
82312
+ let maxDepth = -1;
82313
+ for (const act of activations) {
82314
+ if (act.participantId === pid && act.startStep <= stepIdx && stepIdx <= act.endStep && act.depth > maxDepth) {
82315
+ maxDepth = act.depth;
81827
82316
  }
81828
- var LZString2 = {
81829
- compressToBase64: function(input) {
81830
- if (input == null) return "";
81831
- var res = LZString2._compress(input, 6, function(a) {
81832
- return keyStrBase64.charAt(a);
81833
- });
81834
- switch (res.length % 4) {
81835
- // To produce valid Base64
81836
- default:
81837
- // When could this happen ?
81838
- case 0:
81839
- return res;
81840
- case 1:
81841
- return res + "===";
81842
- case 2:
81843
- return res + "==";
81844
- case 3:
81845
- return res + "=";
81846
- }
81847
- },
81848
- decompressFromBase64: function(input) {
81849
- if (input == null) return "";
81850
- if (input == "") return null;
81851
- return LZString2._decompress(input.length, 32, function(index) {
81852
- return getBaseValue(keyStrBase64, input.charAt(index));
81853
- });
81854
- },
81855
- compressToUTF16: function(input) {
81856
- if (input == null) return "";
81857
- return LZString2._compress(input, 15, function(a) {
81858
- return f(a + 32);
81859
- }) + " ";
81860
- },
81861
- decompressFromUTF16: function(compressed) {
81862
- if (compressed == null) return "";
81863
- if (compressed == "") return null;
81864
- return LZString2._decompress(compressed.length, 16384, function(index) {
81865
- return compressed.charCodeAt(index) - 32;
81866
- });
81867
- },
81868
- //compress into uint8array (UCS-2 big endian format)
81869
- compressToUint8Array: function(uncompressed) {
81870
- var compressed = LZString2.compress(uncompressed);
81871
- var buf = new Uint8Array(compressed.length * 2);
81872
- for (var i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
81873
- var current_value = compressed.charCodeAt(i);
81874
- buf[i * 2] = current_value >>> 8;
81875
- buf[i * 2 + 1] = current_value % 256;
81876
- }
81877
- return buf;
81878
- },
81879
- //decompress from uint8array (UCS-2 big endian format)
81880
- decompressFromUint8Array: function(compressed) {
81881
- if (compressed === null || compressed === void 0) {
81882
- return LZString2.decompress(compressed);
81883
- } else {
81884
- var buf = new Array(compressed.length / 2);
81885
- for (var i = 0, TotalLen = buf.length; i < TotalLen; i++) {
81886
- buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];
81887
- }
81888
- var result = [];
81889
- buf.forEach(function(c) {
81890
- result.push(f(c));
81891
- });
81892
- return LZString2.decompress(result.join(""));
81893
- }
81894
- },
81895
- //compress into a string that is already URI encoded
81896
- compressToEncodedURIComponent: function(input) {
81897
- if (input == null) return "";
81898
- return LZString2._compress(input, 6, function(a) {
81899
- return keyStrUriSafe.charAt(a);
81900
- });
81901
- },
81902
- //decompress from an output of compressToEncodedURIComponent
81903
- decompressFromEncodedURIComponent: function(input) {
81904
- if (input == null) return "";
81905
- if (input == "") return null;
81906
- input = input.replace(/ /g, "+");
81907
- return LZString2._decompress(input.length, 32, function(index) {
81908
- return getBaseValue(keyStrUriSafe, input.charAt(index));
81909
- });
81910
- },
81911
- compress: function(uncompressed) {
81912
- return LZString2._compress(uncompressed, 16, function(a) {
81913
- return f(a);
81914
- });
81915
- },
81916
- _compress: function(uncompressed, bitsPerChar, getCharFromInt) {
81917
- if (uncompressed == null) return "";
81918
- var i, value, context_dictionary = {}, context_dictionaryToCreate = {}, context_c = "", context_wc = "", context_w = "", context_enlargeIn = 2, context_dictSize = 3, context_numBits = 2, context_data = [], context_data_val = 0, context_data_position = 0, ii;
81919
- for (ii = 0; ii < uncompressed.length; ii += 1) {
81920
- context_c = uncompressed.charAt(ii);
81921
- if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
81922
- context_dictionary[context_c] = context_dictSize++;
81923
- context_dictionaryToCreate[context_c] = true;
81924
- }
81925
- context_wc = context_w + context_c;
81926
- if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) {
81927
- context_w = context_wc;
81928
- } else {
81929
- if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
81930
- if (context_w.charCodeAt(0) < 256) {
81931
- for (i = 0; i < context_numBits; i++) {
81932
- context_data_val = context_data_val << 1;
81933
- if (context_data_position == bitsPerChar - 1) {
81934
- context_data_position = 0;
81935
- context_data.push(getCharFromInt(context_data_val));
81936
- context_data_val = 0;
81937
- } else {
81938
- context_data_position++;
81939
- }
81940
- }
81941
- value = context_w.charCodeAt(0);
81942
- for (i = 0; i < 8; i++) {
81943
- context_data_val = context_data_val << 1 | value & 1;
81944
- if (context_data_position == bitsPerChar - 1) {
81945
- context_data_position = 0;
81946
- context_data.push(getCharFromInt(context_data_val));
81947
- context_data_val = 0;
81948
- } else {
81949
- context_data_position++;
81950
- }
81951
- value = value >> 1;
81952
- }
81953
- } else {
81954
- value = 1;
81955
- for (i = 0; i < context_numBits; i++) {
81956
- context_data_val = context_data_val << 1 | value;
81957
- if (context_data_position == bitsPerChar - 1) {
81958
- context_data_position = 0;
81959
- context_data.push(getCharFromInt(context_data_val));
81960
- context_data_val = 0;
81961
- } else {
81962
- context_data_position++;
81963
- }
81964
- value = 0;
81965
- }
81966
- value = context_w.charCodeAt(0);
81967
- for (i = 0; i < 16; i++) {
81968
- context_data_val = context_data_val << 1 | value & 1;
81969
- if (context_data_position == bitsPerChar - 1) {
81970
- context_data_position = 0;
81971
- context_data.push(getCharFromInt(context_data_val));
81972
- context_data_val = 0;
81973
- } else {
81974
- context_data_position++;
81975
- }
81976
- value = value >> 1;
81977
- }
81978
- }
81979
- context_enlargeIn--;
81980
- if (context_enlargeIn == 0) {
81981
- context_enlargeIn = Math.pow(2, context_numBits);
81982
- context_numBits++;
81983
- }
81984
- delete context_dictionaryToCreate[context_w];
81985
- } else {
81986
- value = context_dictionary[context_w];
81987
- for (i = 0; i < context_numBits; i++) {
81988
- context_data_val = context_data_val << 1 | value & 1;
81989
- if (context_data_position == bitsPerChar - 1) {
81990
- context_data_position = 0;
81991
- context_data.push(getCharFromInt(context_data_val));
81992
- context_data_val = 0;
81993
- } else {
81994
- context_data_position++;
81995
- }
81996
- value = value >> 1;
81997
- }
81998
- }
81999
- context_enlargeIn--;
82000
- if (context_enlargeIn == 0) {
82001
- context_enlargeIn = Math.pow(2, context_numBits);
82002
- context_numBits++;
82003
- }
82004
- context_dictionary[context_wc] = context_dictSize++;
82005
- context_w = String(context_c);
82006
- }
82007
- }
82008
- if (context_w !== "") {
82009
- if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
82010
- if (context_w.charCodeAt(0) < 256) {
82011
- for (i = 0; i < context_numBits; i++) {
82012
- context_data_val = context_data_val << 1;
82013
- if (context_data_position == bitsPerChar - 1) {
82014
- context_data_position = 0;
82015
- context_data.push(getCharFromInt(context_data_val));
82016
- context_data_val = 0;
82017
- } else {
82018
- context_data_position++;
82019
- }
82020
- }
82021
- value = context_w.charCodeAt(0);
82022
- for (i = 0; i < 8; i++) {
82023
- context_data_val = context_data_val << 1 | value & 1;
82024
- if (context_data_position == bitsPerChar - 1) {
82025
- context_data_position = 0;
82026
- context_data.push(getCharFromInt(context_data_val));
82027
- context_data_val = 0;
82028
- } else {
82029
- context_data_position++;
82030
- }
82031
- value = value >> 1;
82032
- }
82033
- } else {
82034
- value = 1;
82035
- for (i = 0; i < context_numBits; i++) {
82036
- context_data_val = context_data_val << 1 | value;
82037
- if (context_data_position == bitsPerChar - 1) {
82038
- context_data_position = 0;
82039
- context_data.push(getCharFromInt(context_data_val));
82040
- context_data_val = 0;
82041
- } else {
82042
- context_data_position++;
82043
- }
82044
- value = 0;
82045
- }
82046
- value = context_w.charCodeAt(0);
82047
- for (i = 0; i < 16; i++) {
82048
- context_data_val = context_data_val << 1 | value & 1;
82049
- if (context_data_position == bitsPerChar - 1) {
82050
- context_data_position = 0;
82051
- context_data.push(getCharFromInt(context_data_val));
82052
- context_data_val = 0;
82053
- } else {
82054
- context_data_position++;
82055
- }
82056
- value = value >> 1;
82057
- }
82058
- }
82059
- context_enlargeIn--;
82060
- if (context_enlargeIn == 0) {
82061
- context_enlargeIn = Math.pow(2, context_numBits);
82062
- context_numBits++;
82063
- }
82064
- delete context_dictionaryToCreate[context_w];
82065
- } else {
82066
- value = context_dictionary[context_w];
82067
- for (i = 0; i < context_numBits; i++) {
82068
- context_data_val = context_data_val << 1 | value & 1;
82069
- if (context_data_position == bitsPerChar - 1) {
82070
- context_data_position = 0;
82071
- context_data.push(getCharFromInt(context_data_val));
82072
- context_data_val = 0;
82073
- } else {
82074
- context_data_position++;
82075
- }
82076
- value = value >> 1;
82077
- }
82078
- }
82079
- context_enlargeIn--;
82080
- if (context_enlargeIn == 0) {
82081
- context_enlargeIn = Math.pow(2, context_numBits);
82082
- context_numBits++;
82083
- }
82084
- }
82085
- value = 2;
82086
- for (i = 0; i < context_numBits; i++) {
82087
- context_data_val = context_data_val << 1 | value & 1;
82088
- if (context_data_position == bitsPerChar - 1) {
82089
- context_data_position = 0;
82090
- context_data.push(getCharFromInt(context_data_val));
82091
- context_data_val = 0;
82092
- } else {
82093
- context_data_position++;
82094
- }
82095
- value = value >> 1;
82096
- }
82097
- while (true) {
82098
- context_data_val = context_data_val << 1;
82099
- if (context_data_position == bitsPerChar - 1) {
82100
- context_data.push(getCharFromInt(context_data_val));
82101
- break;
82102
- } else context_data_position++;
82317
+ }
82318
+ return maxDepth;
82319
+ };
82320
+ const arrowEdgeX = (pid, stepIdx, side) => {
82321
+ const px = participantX.get(pid);
82322
+ const depth = activeDepthAt(pid, stepIdx);
82323
+ if (depth < 0) return px;
82324
+ const offset = depth * ACTIVATION_NEST_OFFSET;
82325
+ return side === "right" ? px + sActivationWidth / 2 + offset : px - sActivationWidth / 2 + offset;
82326
+ };
82327
+ const leftmostX = Math.min(...Array.from(participantX.values()));
82328
+ const rightmostX = frameRightmostX;
82329
+ const sectionLineX1 = leftmostX - sBoxW / 2 - 10;
82330
+ const sectionLineX2 = rightmostX + sBoxW / 2 + 10;
82331
+ for (const region of sectionRegions) {
82332
+ const sec = region.section;
82333
+ const secY = sectionYPositions.get(sec.lineNumber);
82334
+ if (secY === void 0) continue;
82335
+ const isCollapsed = collapsedSections?.has(sec.lineNumber) ?? false;
82336
+ const lineColor = palette.textMuted;
82337
+ const sectionG = svg.append("g").attr("data-section-toggle", "").attr("data-line-number", String(sec.lineNumber)).attr("data-section", "").attr("tabindex", "0").attr("role", "button").attr("aria-expanded", String(!isCollapsed));
82338
+ const BAND_HEIGHT = 22;
82339
+ const bandX = sectionLineX1 - 10;
82340
+ const bandWidth = sectionLineX2 - sectionLineX1 + 20;
82341
+ const bandOpacity = isCollapsed ? isDark ? 0.35 : 0.25 : isDark ? 0.1 : 0.08;
82342
+ sectionG.append("rect").attr("x", bandX).attr("y", secY - BAND_HEIGHT / 2).attr("width", bandWidth).attr("height", BAND_HEIGHT).attr("fill", lineColor).attr("opacity", bandOpacity).attr("rx", 2).attr("pointer-events", "none").attr("class", "section-divider");
82343
+ const msgCount = sectionMsgCounts.get(sec.lineNumber) ?? 0;
82344
+ const labelText = isCollapsed ? `${sec.label} (${msgCount} ${msgCount === 1 ? "message" : "messages"})` : sec.label;
82345
+ const labelX = (sectionLineX1 + sectionLineX2) / 2;
82346
+ const labelHitW = Math.max(80, measureText(labelText, 11) + 24);
82347
+ sectionG.append("rect").attr("x", labelX - labelHitW / 2).attr("y", secY - BAND_HEIGHT / 2).attr("width", labelHitW).attr("height", BAND_HEIGHT).attr("fill", "transparent").attr("class", "section-label-hit");
82348
+ sectionG.append("text").attr("x", labelX).attr("y", secY + 4).attr("text-anchor", "middle").attr("fill", lineColor).attr("font-size", 11).attr("font-weight", "bold").attr("class", "section-label").text(labelText);
82349
+ }
82350
+ renderSteps.forEach((step, i) => {
82351
+ const fromX = participantX.get(step.from);
82352
+ const toX = participantX.get(step.to);
82353
+ if (fromX === void 0 || toX === void 0) return;
82354
+ const y = stepY(i);
82355
+ const HIT_H = 20;
82356
+ const msg = messages[step.messageIndex];
82357
+ const msgTagValue = msg ? tagMap?.messages.get(msg.lineNumber) : void 0;
82358
+ const msgTagColor = getTagColor(msgTagValue);
82359
+ if (step.type === "call") {
82360
+ const arrowColor = msgTagColor || palette.text;
82361
+ if (step.from === step.to) {
82362
+ const x = arrowEdgeX(step.from, i, "right");
82363
+ const loopX = x + sSelfCallWidth;
82364
+ const hitX = x;
82365
+ svg.append("rect").attr("x", hitX).attr("y", y - 5).attr("width", sSelfCallWidth).attr("height", sSelfCallHeight + 10).attr("fill", "transparent").attr("class", "message-hit-area").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
82366
+ const selfCallEl = svg.append("path").attr("d", `M ${x} ${y} H ${loopX} V ${y + sSelfCallHeight} H ${x}`).attr("fill", "none").attr("stroke", arrowColor).attr("stroke-width", 1.2).attr("marker-end", coloredMarker("call", msgTagColor)).attr("class", "message-arrow self-call").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i)).attr("data-from", step.from).attr("data-to", step.to);
82367
+ if (tagKey && msgTagValue) {
82368
+ selfCallEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
82369
+ }
82370
+ if (step.label) {
82371
+ const labelEl = svg.append("text").attr("x", loopX + 5).attr("y", y + sSelfCallHeight / 2 + 4).attr("text-anchor", "start").attr("fill", arrowColor).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("font-size", 12).attr("class", "message-label").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
82372
+ if (tagKey && msgTagValue) {
82373
+ labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
82103
82374
  }
82104
- return context_data.join("");
82105
- },
82106
- decompress: function(compressed) {
82107
- if (compressed == null) return "";
82108
- if (compressed == "") return null;
82109
- return LZString2._decompress(compressed.length, 32768, function(index) {
82110
- return compressed.charCodeAt(index);
82111
- });
82112
- },
82113
- _decompress: function(length, resetValue, getNextValue) {
82114
- var dictionary = [], next, enlargeIn = 4, dictSize = 4, numBits = 3, entry = "", result = [], i, w, bits, resb, maxpower, power, c, data = { val: getNextValue(0), position: resetValue, index: 1 };
82115
- for (i = 0; i < 3; i += 1) {
82116
- dictionary[i] = i;
82375
+ labelEl.text(step.label);
82376
+ }
82377
+ } else {
82378
+ const goingRight = fromX < toX;
82379
+ const x1 = arrowEdgeX(step.from, i, goingRight ? "right" : "left");
82380
+ const x2 = arrowEdgeX(step.to, i, goingRight ? "left" : "right");
82381
+ svg.append("rect").attr("x", Math.min(x1, x2)).attr("y", y - HIT_H / 2).attr("width", Math.abs(x2 - x1)).attr("height", HIT_H).attr("fill", "transparent").attr("class", "message-hit-area").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
82382
+ const markerRef = step.async ? coloredMarker("async", msgTagColor) : coloredMarker("call", msgTagColor);
82383
+ const arrowEl = svg.append("line").attr("x1", x1).attr("y1", y).attr("x2", x2).attr("y2", y).attr("stroke", arrowColor).attr("stroke-width", 1.2).attr("marker-end", markerRef).attr("class", "message-arrow").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i)).attr("data-from", step.from).attr("data-to", step.to);
82384
+ if (tagKey && msgTagValue) {
82385
+ arrowEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
82386
+ }
82387
+ if (step.label) {
82388
+ const midX = (x1 + x2) / 2;
82389
+ const labelEl = svg.append("text").attr("x", midX).attr("y", y - 8).attr("text-anchor", "middle").attr("fill", arrowColor).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("font-size", 12).attr("class", "message-label").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
82390
+ if (tagKey && msgTagValue) {
82391
+ labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
82117
82392
  }
82118
- bits = 0;
82119
- maxpower = Math.pow(2, 2);
82120
- power = 1;
82121
- while (power != maxpower) {
82122
- resb = data.val & data.position;
82123
- data.position >>= 1;
82124
- if (data.position == 0) {
82125
- data.position = resetValue;
82126
- data.val = getNextValue(data.index++);
82127
- }
82128
- bits |= (resb > 0 ? 1 : 0) * power;
82129
- power <<= 1;
82393
+ labelEl.text(step.label);
82394
+ }
82395
+ }
82396
+ } else {
82397
+ if (step.from === step.to) {
82398
+ return;
82399
+ }
82400
+ const goingRight = fromX < toX;
82401
+ const x1 = arrowEdgeX(step.from, i, goingRight ? "right" : "left");
82402
+ const x2 = arrowEdgeX(step.to, i, goingRight ? "left" : "right");
82403
+ const returnColor = msgTagColor || palette.textMuted;
82404
+ svg.append("rect").attr("x", Math.min(x1, x2)).attr("y", y - HIT_H / 2).attr("width", Math.abs(x2 - x1)).attr("height", HIT_H).attr("fill", "transparent").attr("class", "message-hit-area").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
82405
+ const returnEl = svg.append("line").attr("x1", x1).attr("y1", y).attr("x2", x2).attr("y2", y).attr("stroke", returnColor).attr("stroke-width", 1).attr("stroke-dasharray", "6 4").attr("marker-end", coloredMarker("return", msgTagColor)).attr("class", "return-arrow").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i)).attr("data-from", step.from).attr("data-to", step.to);
82406
+ if (tagKey && msgTagValue) {
82407
+ returnEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
82408
+ }
82409
+ if (step.label) {
82410
+ const midX = (x1 + x2) / 2;
82411
+ const labelEl = svg.append("text").attr("x", midX).attr("y", y - 6).attr("text-anchor", "middle").attr("fill", returnColor).attr("paint-order", "stroke fill").attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linejoin", "round").attr("font-size", 11).attr("class", "message-label").attr("data-line-number", String(msg.lineNumber)).attr("data-msg-index", String(step.messageIndex)).attr("data-step-index", String(i));
82412
+ if (tagKey && msgTagValue) {
82413
+ labelEl.attr(`data-tag-${tagKey}`, msgTagValue.toLowerCase());
82414
+ }
82415
+ labelEl.text(step.label);
82416
+ }
82417
+ }
82418
+ });
82419
+ const noteFill = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.bg, palette.surface, 15);
82420
+ const renderNoteElements = (els) => {
82421
+ for (const el of els) {
82422
+ if (isSequenceNote(el)) {
82423
+ const px = participantX.get(el.participantId);
82424
+ if (px === void 0) continue;
82425
+ const noteTopY = noteYMap.get(el);
82426
+ if (noteTopY === void 0) continue;
82427
+ const position = effectiveNotePosition(el);
82428
+ const isRight = position === "right";
82429
+ const afterSelfCall = isNoteAfterSelfCall(el);
82430
+ const maxW = noteEffectiveMaxW(
82431
+ el.participantId,
82432
+ position,
82433
+ afterSelfCall
82434
+ );
82435
+ const textWidth = noteTextWidth(maxW);
82436
+ const wrappedLines = wrapTextLines(el.text, textWidth, sNoteFontSize);
82437
+ const noteH = wrappedLines.length * sNoteLineH + sNotePadV * 2;
82438
+ const maxLineW = Math.max(
82439
+ ...wrappedLines.map((l) => measureText(l.text, sNoteFontSize))
82440
+ );
82441
+ const noteW = Math.min(
82442
+ maxW,
82443
+ Math.max(80, maxLineW + sNotePadH * 2 + sNoteFold)
82444
+ );
82445
+ const rightOffset = afterSelfCall && isRight ? sActivationWidth / 2 + sSelfCallWidth + sNoteGap : sActivationWidth + sNoteGap;
82446
+ const noteX = isRight ? px + rightOffset : px - sActivationWidth - sNoteGap - noteW;
82447
+ const noteG = svg.append("g").attr("class", "note").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber)).attr("data-line-end", String(el.endLineNumber));
82448
+ noteG.append("path").attr(
82449
+ "d",
82450
+ [
82451
+ `M ${noteX} ${noteTopY}`,
82452
+ `L ${noteX + noteW - sNoteFold} ${noteTopY}`,
82453
+ `L ${noteX + noteW} ${noteTopY + sNoteFold}`,
82454
+ `L ${noteX + noteW} ${noteTopY + noteH}`,
82455
+ `L ${noteX} ${noteTopY + noteH}`,
82456
+ "Z"
82457
+ ].join(" ")
82458
+ ).attr("fill", noteFill).attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-box");
82459
+ noteG.append("path").attr(
82460
+ "d",
82461
+ [
82462
+ `M ${noteX + noteW - sNoteFold} ${noteTopY}`,
82463
+ `L ${noteX + noteW - sNoteFold} ${noteTopY + sNoteFold}`,
82464
+ `L ${noteX + noteW} ${noteTopY + sNoteFold}`
82465
+ ].join(" ")
82466
+ ).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-fold");
82467
+ const BULLET_BODY_INDENT3 = 10;
82468
+ wrappedLines.forEach((line11, li) => {
82469
+ const textY = noteTopY + sNotePadV + (li + 1) * sNoteLineH - 3;
82470
+ const indent = line11.kind === "plain" ? 0 : BULLET_BODY_INDENT3;
82471
+ if (line11.kind === "bullet-first") {
82472
+ noteG.append("text").attr("x", noteX + sNotePadH).attr("y", textY).attr("fill", palette.text).attr("font-size", sNoteFontSize).text("\u2022");
82130
82473
  }
82131
- switch (next = bits) {
82132
- case 0:
82133
- bits = 0;
82134
- maxpower = Math.pow(2, 8);
82135
- power = 1;
82136
- while (power != maxpower) {
82137
- resb = data.val & data.position;
82138
- data.position >>= 1;
82139
- if (data.position == 0) {
82140
- data.position = resetValue;
82141
- data.val = getNextValue(data.index++);
82142
- }
82143
- bits |= (resb > 0 ? 1 : 0) * power;
82144
- power <<= 1;
82145
- }
82146
- c = f(bits);
82147
- break;
82148
- case 1:
82149
- bits = 0;
82150
- maxpower = Math.pow(2, 16);
82151
- power = 1;
82152
- while (power != maxpower) {
82153
- resb = data.val & data.position;
82154
- data.position >>= 1;
82155
- if (data.position == 0) {
82156
- data.position = resetValue;
82157
- data.val = getNextValue(data.index++);
82158
- }
82159
- bits |= (resb > 0 ? 1 : 0) * power;
82160
- power <<= 1;
82161
- }
82162
- c = f(bits);
82163
- break;
82164
- case 2:
82165
- return "";
82474
+ const textEl = noteG.append("text").attr("x", noteX + sNotePadH + indent).attr("y", textY).attr("fill", palette.text).attr("font-size", sNoteFontSize).attr("class", "note-text");
82475
+ renderInlineText(textEl, line11.text, palette, sNoteFontSize);
82476
+ });
82477
+ } else if (isSequenceBlock(el)) {
82478
+ renderNoteElements(el.children);
82479
+ if (el.elseIfBranches) {
82480
+ for (const branch of el.elseIfBranches) {
82481
+ renderNoteElements(branch.children);
82166
82482
  }
82167
- dictionary[3] = c;
82168
- w = c;
82169
- result.push(c);
82170
- while (true) {
82171
- if (data.index > length) {
82172
- return "";
82173
- }
82174
- bits = 0;
82175
- maxpower = Math.pow(2, numBits);
82176
- power = 1;
82177
- while (power != maxpower) {
82178
- resb = data.val & data.position;
82179
- data.position >>= 1;
82180
- if (data.position == 0) {
82181
- data.position = resetValue;
82182
- data.val = getNextValue(data.index++);
82183
- }
82184
- bits |= (resb > 0 ? 1 : 0) * power;
82185
- power <<= 1;
82186
- }
82187
- switch (c = bits) {
82188
- case 0:
82189
- bits = 0;
82190
- maxpower = Math.pow(2, 8);
82191
- power = 1;
82192
- while (power != maxpower) {
82193
- resb = data.val & data.position;
82194
- data.position >>= 1;
82195
- if (data.position == 0) {
82196
- data.position = resetValue;
82197
- data.val = getNextValue(data.index++);
82198
- }
82199
- bits |= (resb > 0 ? 1 : 0) * power;
82200
- power <<= 1;
82201
- }
82202
- dictionary[dictSize++] = f(bits);
82203
- c = dictSize - 1;
82204
- enlargeIn--;
82205
- break;
82206
- case 1:
82207
- bits = 0;
82208
- maxpower = Math.pow(2, 16);
82209
- power = 1;
82210
- while (power != maxpower) {
82211
- resb = data.val & data.position;
82212
- data.position >>= 1;
82213
- if (data.position == 0) {
82214
- data.position = resetValue;
82215
- data.val = getNextValue(data.index++);
82216
- }
82217
- bits |= (resb > 0 ? 1 : 0) * power;
82218
- power <<= 1;
82219
- }
82220
- dictionary[dictSize++] = f(bits);
82221
- c = dictSize - 1;
82222
- enlargeIn--;
82223
- break;
82224
- case 2:
82225
- return result.join("");
82226
- }
82227
- if (enlargeIn == 0) {
82228
- enlargeIn = Math.pow(2, numBits);
82229
- numBits++;
82230
- }
82231
- if (dictionary[c]) {
82232
- entry = dictionary[c];
82233
- } else {
82234
- if (c === dictSize) {
82235
- entry = w + w.charAt(0);
82236
- } else {
82237
- return null;
82238
- }
82239
- }
82240
- result.push(entry);
82241
- dictionary[dictSize++] = w + entry.charAt(0);
82242
- enlargeIn--;
82243
- w = entry;
82244
- if (enlargeIn == 0) {
82245
- enlargeIn = Math.pow(2, numBits);
82246
- numBits++;
82247
- }
82483
+ }
82484
+ renderNoteElements(el.elseChildren);
82485
+ }
82486
+ }
82487
+ };
82488
+ if (elements && elements.length > 0) {
82489
+ renderNoteElements(elements);
82490
+ }
82491
+ if (hasTagGroups) {
82492
+ const legendY = sTopMargin + titleOffset;
82493
+ const legendCallbacks = {};
82494
+ const legendG = svg.append("g").attr("class", "sequence-legend").attr(
82495
+ "transform",
82496
+ header.inline ? `translate(${header.legendX}, ${header.legendY})` : `translate(0,${legendY})`
82497
+ );
82498
+ renderIntegratedLegend(legendG, {
82499
+ ...legendConfig,
82500
+ // Inline → left-origin so the wrapper's right-flush translate lands the
82501
+ // legend at the header's right edge; stacked → centered below the title
82502
+ // (identical to legendConfig.position, so the stacked path is unchanged).
82503
+ position: {
82504
+ placement: "top-center",
82505
+ titleRelation: header.inline ? "inline-with-title" : "below-title"
82506
+ },
82507
+ palette,
82508
+ isDark,
82509
+ width: svgWidth,
82510
+ activeGroup: activeTagGroup ?? null,
82511
+ controlsExpanded: false,
82512
+ callbacks: legendCallbacks
82513
+ });
82514
+ }
82515
+ }
82516
+ function buildNoteMessageMap(elements) {
82517
+ const map = /* @__PURE__ */ new Map();
82518
+ let lastMessageLine = -1;
82519
+ const walk = (els) => {
82520
+ for (const el of els) {
82521
+ if (isSequenceNote(el)) {
82522
+ if (lastMessageLine >= 0) {
82523
+ map.set(el.lineNumber, lastMessageLine);
82524
+ }
82525
+ } else if (isSequenceBlock(el)) {
82526
+ walk(el.children);
82527
+ if (el.elseIfBranches) {
82528
+ for (const branch of el.elseIfBranches) {
82529
+ walk(branch.children);
82248
82530
  }
82249
82531
  }
82250
- };
82251
- return LZString2;
82252
- })();
82253
- if (typeof define === "function" && define.amd) {
82254
- define(function() {
82255
- return LZString;
82256
- });
82257
- } else if (typeof module !== "undefined" && module != null) {
82258
- module.exports = LZString;
82259
- } else if (typeof angular !== "undefined" && angular != null) {
82260
- angular.module("LZString", []).factory("LZString", function() {
82261
- return LZString;
82262
- });
82532
+ walk(el.elseChildren);
82533
+ } else if (!isSequenceSection(el)) {
82534
+ lastMessageLine = el.lineNumber;
82535
+ }
82263
82536
  }
82537
+ };
82538
+ walk(elements);
82539
+ return map;
82540
+ }
82541
+ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, fillMode, boxW = W3, boxH = H, labelTextW = labelTextWidth(W3), labelFontSize2 = LABEL_FONT_SIZE5) {
82542
+ const g = svg.append("g").attr("transform", `translate(${cx}, ${cy})`).attr("class", "participant").attr("data-participant-id", participant.id);
82543
+ if (tagAttr) {
82544
+ g.attr(`data-tag-${tagAttr.key}`, tagAttr.value);
82545
+ }
82546
+ switch (participant.type) {
82547
+ case "actor":
82548
+ renderActorParticipant(g, palette, color, boxH);
82549
+ break;
82550
+ case "database":
82551
+ renderDatabaseParticipant(
82552
+ g,
82553
+ palette,
82554
+ isDark,
82555
+ color,
82556
+ fillMode,
82557
+ boxW,
82558
+ boxH
82559
+ );
82560
+ break;
82561
+ case "queue":
82562
+ renderQueueParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
82563
+ break;
82564
+ case "cache":
82565
+ renderCacheParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
82566
+ break;
82567
+ default:
82568
+ renderRectParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
82569
+ break;
82570
+ }
82571
+ const isActor = participant.type === "actor";
82572
+ const labelLines = splitParticipantLabel(
82573
+ participant.label,
82574
+ labelTextW,
82575
+ labelFontSize2
82576
+ );
82577
+ const fontSize = labelFontSize2;
82578
+ const lineHeight = fontSize + 2;
82579
+ const labelFill = isActor ? palette.text : contrastText(
82580
+ fill(palette, isDark, color, fillMode),
82581
+ palette.textOnFillLight,
82582
+ palette.textOnFillDark
82583
+ );
82584
+ const textEl = g.append("text").attr("x", 0).attr("text-anchor", "middle").attr("fill", labelFill).attr("font-size", fontSize).attr("font-weight", 500);
82585
+ const maxLabelW = labelTextWidth(boxW);
82586
+ const truncLine = (text) => truncateText(text, fontSize, maxLabelW);
82587
+ if (labelLines.length === 1) {
82588
+ textEl.attr("y", isActor ? boxH + 14 : boxH / 2 + 5).text(truncLine(participant.label));
82589
+ } else {
82590
+ const totalHeight = labelLines.length * lineHeight;
82591
+ const baseY = isActor ? boxH + 14 - (labelLines.length - 1) * lineHeight / 2 : boxH / 2 + 5 - (totalHeight - lineHeight) / 2;
82592
+ labelLines.forEach((line11, i) => {
82593
+ textEl.append("tspan").attr("x", 0).attr("dy", i === 0 ? `${baseY}px` : `${lineHeight}px`).text(truncLine(line11));
82594
+ });
82595
+ }
82596
+ }
82597
+ var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, LABEL_FONT_SIZE5, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W2, NOTE_FOLD2, NOTE_PAD_H2, NOTE_PAD_V2, NOTE_FONT_SIZE3, NOTE_LINE_H2, NOTE_GAP2, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, ACTOR_LABEL_CLEARANCE, labelTextWidth, fill, stroke, SW, W3, H;
82598
+ var init_renderer34 = __esm({
82599
+ "src/sequence/renderer.ts"() {
82600
+ "use strict";
82601
+ init_tag_groups();
82602
+ init_parsing();
82603
+ init_color_utils();
82604
+ init_inline_markdown();
82605
+ init_fonts();
82606
+ init_parser7();
82607
+ init_collapse5();
82608
+ init_wrapped_desc();
82609
+ init_text_measure();
82610
+ init_tag_resolution();
82611
+ init_tag_groups();
82612
+ init_legend_layout();
82613
+ init_parsing();
82614
+ init_inline_header();
82615
+ init_legend_integration();
82616
+ init_title_constants();
82617
+ init_scaling();
82618
+ PARTICIPANT_GAP = 160;
82619
+ PARTICIPANT_BOX_WIDTH = 120;
82620
+ PARTICIPANT_BOX_HEIGHT = 50;
82621
+ LABEL_FONT_SIZE5 = 13;
82622
+ TOP_MARGIN = 20;
82623
+ TITLE_HEIGHT8 = 30;
82624
+ PARTICIPANT_Y_OFFSET = 10;
82625
+ MESSAGE_START_OFFSET = 50;
82626
+ LIFELINE_TAIL = 30;
82627
+ ARROWHEAD_SIZE = 8;
82628
+ NOTE_MAX_W2 = 200;
82629
+ NOTE_FOLD2 = 10;
82630
+ NOTE_PAD_H2 = 8;
82631
+ NOTE_PAD_V2 = 6;
82632
+ NOTE_FONT_SIZE3 = 10;
82633
+ NOTE_LINE_H2 = 14;
82634
+ NOTE_GAP2 = 15;
82635
+ ACTIVATION_WIDTH = 10;
82636
+ SELF_CALL_HEIGHT = 25;
82637
+ SELF_CALL_WIDTH = 30;
82638
+ ACTOR_LABEL_CLEARANCE = 22;
82639
+ labelTextWidth = (boxW) => boxW - 10;
82640
+ fill = (palette, isDark, color, fillMode) => color ? shapeFill(palette, color, isDark, { mode: fillMode }) : isDark ? mix(palette.overlay, palette.surface, 50) : mix(palette.bg, palette.surface, 50);
82641
+ stroke = (palette, color) => color || palette.border;
82642
+ SW = 1.5;
82643
+ W3 = PARTICIPANT_BOX_WIDTH;
82644
+ H = PARTICIPANT_BOX_HEIGHT;
82264
82645
  }
82265
82646
  });
82266
82647
 
@@ -84085,6 +84466,7 @@ var DIAGRAM_EXPORT_HANDLERS = {
84085
84466
  bracket: exportBracket,
84086
84467
  raci: exportRaci,
84087
84468
  body: exportBody,
84469
+ "live-link": exportLiveLink,
84088
84470
  // D3 visualizations — own handler per type (Story 109.2). Only `sequence`
84089
84471
  // still falls through to exportVisualization (no chart-type of its own).
84090
84472
  slope: exportSlope,
@@ -84131,7 +84513,9 @@ async function renderForExport(content, theme, palette, viewState, options) {
84131
84513
  viewState,
84132
84514
  options,
84133
84515
  exportMode,
84134
- isDark: theme === "dark"
84516
+ isDark: theme === "dark",
84517
+ width: options?.width && options.width > 0 ? Math.round(options.width) : EXPORT_WIDTH,
84518
+ height: options?.height && options.height > 0 ? Math.round(options.height) : EXPORT_HEIGHT
84135
84519
  };
84136
84520
  const handler = detectedType !== null ? DIAGRAM_EXPORT_HANDLERS[detectedType] : void 0;
84137
84521
  return (handler ?? exportVisualization)(ctx);
@@ -84146,13 +84530,13 @@ async function exportEventLine(ctx) {
84146
84530
  const effectivePalette = await resolveExportPalette(theme, palette);
84147
84531
  const parsed = parseEventLine2(content, effectivePalette);
84148
84532
  if (parsed.error || parsed.events.length === 0) return "";
84149
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
84533
+ const container = createExportContainer(ctx.width, ctx.height);
84150
84534
  renderEventLineForExport2(
84151
84535
  container,
84152
84536
  parsed,
84153
84537
  effectivePalette,
84154
84538
  ctx.isDark,
84155
- { width: EXPORT_WIDTH, height: EXPORT_HEIGHT },
84539
+ { width: ctx.width, height: ctx.height },
84156
84540
  ctxTagOverride(ctx),
84157
84541
  /* @__PURE__ */ new Date()
84158
84542
  );
@@ -84165,13 +84549,13 @@ async function exportBody(ctx) {
84165
84549
  const effectivePalette = await resolveExportPalette(theme, palette);
84166
84550
  const parsed = parseBody2(content, effectivePalette);
84167
84551
  if (parsed.error) return "";
84168
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
84552
+ const container = createExportContainer(ctx.width, ctx.height);
84169
84553
  renderBodyForExport2(
84170
84554
  container,
84171
84555
  parsed,
84172
84556
  effectivePalette,
84173
84557
  ctx.isDark,
84174
- { width: EXPORT_WIDTH, height: EXPORT_HEIGHT },
84558
+ { width: ctx.width, height: ctx.height },
84175
84559
  ctxTagOverride(ctx)
84176
84560
  );
84177
84561
  return finalizeSvgExport(container, theme, effectivePalette);
@@ -84183,15 +84567,15 @@ async function exportVersionControl(ctx) {
84183
84567
  const effectivePalette = await resolveExportPalette(theme, palette);
84184
84568
  const parsed = parseVersionControl2(content, effectivePalette);
84185
84569
  if (parsed.error || parsed.nodes.length === 0) return "";
84186
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
84570
+ const container = createExportContainer(ctx.width, ctx.height);
84187
84571
  renderVersionControlForExport2(
84188
84572
  container,
84189
84573
  parsed,
84190
84574
  effectivePalette,
84191
84575
  ctx.isDark,
84192
84576
  {
84193
- width: EXPORT_WIDTH,
84194
- height: EXPORT_HEIGHT
84577
+ width: ctx.width,
84578
+ height: ctx.height
84195
84579
  }
84196
84580
  );
84197
84581
  return finalizeSvgExport(container, theme, effectivePalette);
@@ -84662,7 +85046,7 @@ async function exportFlowchart(ctx) {
84662
85046
  const fcParsed = parseFlowchart2(content, effectivePalette);
84663
85047
  if (fcParsed.error || fcParsed.nodes.length === 0) return "";
84664
85048
  const layout = layoutGraph2(fcParsed);
84665
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85049
+ const container = createExportContainer(ctx.width, ctx.height);
84666
85050
  renderFlowchart2(
84667
85051
  container,
84668
85052
  fcParsed,
@@ -84670,7 +85054,7 @@ async function exportFlowchart(ctx) {
84670
85054
  effectivePalette,
84671
85055
  ctx.isDark,
84672
85056
  void 0,
84673
- { width: EXPORT_WIDTH, height: EXPORT_HEIGHT }
85057
+ { width: ctx.width, height: ctx.height }
84674
85058
  );
84675
85059
  return finalizeSvgExport(container, theme, effectivePalette);
84676
85060
  }
@@ -84835,7 +85219,7 @@ async function exportState(ctx) {
84835
85219
  collapsedChildCounts,
84836
85220
  originalGroups
84837
85221
  });
84838
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85222
+ const container = createExportContainer(ctx.width, ctx.height);
84839
85223
  renderState2(
84840
85224
  container,
84841
85225
  effectiveParsed,
@@ -84843,7 +85227,7 @@ async function exportState(ctx) {
84843
85227
  effectivePalette,
84844
85228
  ctx.isDark,
84845
85229
  void 0,
84846
- { width: EXPORT_WIDTH, height: EXPORT_HEIGHT }
85230
+ { width: ctx.width, height: ctx.height }
84847
85231
  );
84848
85232
  return finalizeSvgExport(container, theme, effectivePalette);
84849
85233
  }
@@ -84897,13 +85281,13 @@ async function exportCycle(ctx) {
84897
85281
  const effectivePalette = await resolveExportPalette(theme, palette);
84898
85282
  const cycleParsed = parseCycle2(content);
84899
85283
  if (cycleParsed.error || cycleParsed.nodes.length === 0) return "";
84900
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85284
+ const container = createExportContainer(ctx.width, ctx.height);
84901
85285
  renderCycleForExport2(
84902
85286
  container,
84903
85287
  cycleParsed,
84904
85288
  effectivePalette,
84905
85289
  ctx.isDark,
84906
- { width: EXPORT_WIDTH, height: EXPORT_HEIGHT },
85290
+ { width: ctx.width, height: ctx.height },
84907
85291
  viewState,
84908
85292
  exportMode
84909
85293
  );
@@ -84931,7 +85315,7 @@ async function exportMap(ctx) {
84931
85315
  const dims = mapExportDimensions2(
84932
85316
  mapResolved,
84933
85317
  mapData,
84934
- EXPORT_WIDTH,
85318
+ ctx.width,
84935
85319
  options?.mapAspect
84936
85320
  );
84937
85321
  const container = createExportContainer(dims.width, dims.height);
@@ -84952,13 +85336,13 @@ async function exportPyramid(ctx) {
84952
85336
  const effectivePalette = await resolveExportPalette(theme, palette);
84953
85337
  const pyramidParsed = parsePyramid2(content);
84954
85338
  if (pyramidParsed.error || pyramidParsed.layers.length === 0) return "";
84955
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85339
+ const container = createExportContainer(ctx.width, ctx.height);
84956
85340
  renderPyramidForExport2(
84957
85341
  container,
84958
85342
  pyramidParsed,
84959
85343
  effectivePalette,
84960
85344
  ctx.isDark,
84961
- { width: EXPORT_WIDTH, height: EXPORT_HEIGHT }
85345
+ { width: ctx.width, height: ctx.height }
84962
85346
  );
84963
85347
  return finalizeSvgExport(container, theme, effectivePalette);
84964
85348
  }
@@ -84969,10 +85353,10 @@ async function exportRing(ctx) {
84969
85353
  const effectivePalette = await resolveExportPalette(theme, palette);
84970
85354
  const ringParsed = parseRing2(content);
84971
85355
  if (ringParsed.error || ringParsed.layers.length === 0) return "";
84972
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85356
+ const container = createExportContainer(ctx.width, ctx.height);
84973
85357
  renderRingForExport2(container, ringParsed, effectivePalette, ctx.isDark, {
84974
- width: EXPORT_WIDTH,
84975
- height: EXPORT_HEIGHT
85358
+ width: ctx.width,
85359
+ height: ctx.height
84976
85360
  });
84977
85361
  return finalizeSvgExport(container, theme, effectivePalette);
84978
85362
  }
@@ -84982,8 +85366,8 @@ async function exportTreemap(ctx) {
84982
85366
  const effectivePalette = await resolveExportPalette(theme, palette);
84983
85367
  const treemapParsed = parseTreemap2(content, effectivePalette);
84984
85368
  if (treemapParsed.error || treemapParsed.roots.length === 0) return "";
84985
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
84986
- const dims = { width: EXPORT_WIDTH, height: EXPORT_HEIGHT };
85369
+ const container = createExportContainer(ctx.width, ctx.height);
85370
+ const dims = { width: ctx.width, height: ctx.height };
84987
85371
  if (treemapParsed.options.radial) {
84988
85372
  const { renderTreemapRadialForExport: renderTreemapRadialForExport2 } = await Promise.resolve().then(() => (init_renderer_radial(), renderer_radial_exports));
84989
85373
  renderTreemapRadialForExport2(
@@ -85005,66 +85389,73 @@ async function exportTreemap(ctx) {
85005
85389
  }
85006
85390
  return finalizeSvgExport(container, theme, effectivePalette);
85007
85391
  }
85392
+ async function exportLiveLink(ctx) {
85393
+ const { content, theme, palette } = ctx;
85394
+ const { parseLiveLink: parseLiveLink2 } = await Promise.resolve().then(() => (init_parser39(), parser_exports33));
85395
+ const { renderLiveLinkCard: renderLiveLinkCard2 } = await Promise.resolve().then(() => (init_renderer27(), renderer_exports26));
85396
+ const effectivePalette = await resolveExportPalette(theme, palette);
85397
+ return renderLiveLinkCard2(parseLiveLink2(content), effectivePalette, theme);
85398
+ }
85008
85399
  async function exportBlock(ctx) {
85009
85400
  const { content, theme, palette } = ctx;
85010
85401
  const { parseBlock: parseBlock2 } = await Promise.resolve().then(() => (init_parser32(), parser_exports26));
85011
- const { renderBlockForExport: renderBlockForExport2 } = await Promise.resolve().then(() => (init_renderer27(), renderer_exports26));
85402
+ const { renderBlockForExport: renderBlockForExport2 } = await Promise.resolve().then(() => (init_renderer28(), renderer_exports27));
85012
85403
  const effectivePalette = await resolveExportPalette(theme, palette);
85013
85404
  const blockParsed = parseBlock2(content, effectivePalette);
85014
85405
  if (blockParsed.error || blockParsed.top.rows.length === 0) return "";
85015
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85406
+ const container = createExportContainer(ctx.width, ctx.height);
85016
85407
  renderBlockForExport2(container, blockParsed, effectivePalette, ctx.isDark, {
85017
- width: EXPORT_WIDTH,
85018
- height: EXPORT_HEIGHT
85408
+ width: ctx.width,
85409
+ height: ctx.height
85019
85410
  });
85020
85411
  return finalizeSvgExport(container, theme, effectivePalette);
85021
85412
  }
85022
85413
  async function exportGoal(ctx) {
85023
85414
  const { content, theme, palette } = ctx;
85024
85415
  const { parseGoal: parseGoal2 } = await Promise.resolve().then(() => (init_parser33(), parser_exports27));
85025
- const { renderGoalForExport: renderGoalForExport2 } = await Promise.resolve().then(() => (init_renderer28(), renderer_exports27));
85416
+ const { renderGoalForExport: renderGoalForExport2 } = await Promise.resolve().then(() => (init_renderer29(), renderer_exports28));
85026
85417
  const effectivePalette = await resolveExportPalette(theme, palette);
85027
85418
  const parsed = parseGoal2(content, effectivePalette);
85028
85419
  if (parsed.error) return "";
85029
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85420
+ const container = createExportContainer(ctx.width, ctx.height);
85030
85421
  renderGoalForExport2(container, parsed, effectivePalette, ctx.isDark, {
85031
- width: EXPORT_WIDTH,
85032
- height: EXPORT_HEIGHT
85422
+ width: ctx.width,
85423
+ height: ctx.height
85033
85424
  });
85034
85425
  return finalizeSvgExport(container, theme, effectivePalette);
85035
85426
  }
85036
85427
  async function exportCountdown(ctx) {
85037
85428
  const { content, theme, palette } = ctx;
85038
85429
  const { parseCountdown: parseCountdown2 } = await Promise.resolve().then(() => (init_parser34(), parser_exports28));
85039
- const { renderCountdownForExport: renderCountdownForExport2 } = await Promise.resolve().then(() => (init_renderer29(), renderer_exports28));
85430
+ const { renderCountdownForExport: renderCountdownForExport2 } = await Promise.resolve().then(() => (init_renderer30(), renderer_exports29));
85040
85431
  const effectivePalette = await resolveExportPalette(theme, palette);
85041
85432
  const parsed = parseCountdown2(content, effectivePalette);
85042
85433
  if (parsed.error) return "";
85043
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85434
+ const container = createExportContainer(ctx.width, ctx.height);
85044
85435
  renderCountdownForExport2(container, parsed, effectivePalette, ctx.isDark, {
85045
- width: EXPORT_WIDTH,
85046
- height: EXPORT_HEIGHT
85436
+ width: ctx.width,
85437
+ height: ctx.height
85047
85438
  });
85048
85439
  return finalizeSvgExport(container, theme, effectivePalette);
85049
85440
  }
85050
85441
  async function exportClock(ctx) {
85051
85442
  const { content, theme, palette } = ctx;
85052
85443
  const { parseClock: parseClock2 } = await Promise.resolve().then(() => (init_parser35(), parser_exports29));
85053
- const { renderClockForExport: renderClockForExport2 } = await Promise.resolve().then(() => (init_renderer30(), renderer_exports29));
85444
+ const { renderClockForExport: renderClockForExport2 } = await Promise.resolve().then(() => (init_renderer31(), renderer_exports30));
85054
85445
  const effectivePalette = await resolveExportPalette(theme, palette);
85055
85446
  const parsed = parseClock2(content, effectivePalette);
85056
85447
  if (parsed.error) return "";
85057
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85448
+ const container = createExportContainer(ctx.width, ctx.height);
85058
85449
  renderClockForExport2(container, parsed, effectivePalette, ctx.isDark, {
85059
- width: EXPORT_WIDTH,
85060
- height: EXPORT_HEIGHT
85450
+ width: ctx.width,
85451
+ height: ctx.height
85061
85452
  });
85062
85453
  return finalizeSvgExport(container, theme, effectivePalette);
85063
85454
  }
85064
85455
  async function exportBracket(ctx) {
85065
85456
  const { content, theme, palette } = ctx;
85066
85457
  const { parseBracket: parseBracket2 } = await Promise.resolve().then(() => (init_parser36(), parser_exports30));
85067
- const { renderBracketForExport: renderBracketForExport2, bracketExportDimensions: bracketExportDimensions2 } = await Promise.resolve().then(() => (init_renderer31(), renderer_exports30));
85458
+ const { renderBracketForExport: renderBracketForExport2, bracketExportDimensions: bracketExportDimensions2 } = await Promise.resolve().then(() => (init_renderer32(), renderer_exports31));
85068
85459
  const effectivePalette = await resolveExportPalette(theme, palette);
85069
85460
  const parsed = parseBracket2(content, effectivePalette);
85070
85461
  if (parsed.error) return "";
@@ -85079,22 +85470,22 @@ async function exportBracket(ctx) {
85079
85470
  async function exportRaci(ctx) {
85080
85471
  const { content, theme, palette } = ctx;
85081
85472
  const { parseRaci: parseRaci2 } = await Promise.resolve().then(() => (init_parser37(), parser_exports31));
85082
- const { renderRaciForExport: renderRaciForExport2 } = await Promise.resolve().then(() => (init_renderer32(), renderer_exports31));
85473
+ const { renderRaciForExport: renderRaciForExport2 } = await Promise.resolve().then(() => (init_renderer33(), renderer_exports32));
85083
85474
  const effectivePalette = await resolveExportPalette(theme, palette);
85084
85475
  const raciParsed = parseRaci2(content, effectivePalette);
85085
85476
  if (raciParsed.error) return "";
85086
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85477
+ const container = createExportContainer(ctx.width, ctx.height);
85087
85478
  renderRaciForExport2(container, raciParsed, effectivePalette, ctx.isDark, {
85088
- width: EXPORT_WIDTH,
85089
- height: EXPORT_HEIGHT
85479
+ width: ctx.width,
85480
+ height: ctx.height
85090
85481
  });
85091
85482
  return finalizeSvgExport(container, theme, effectivePalette);
85092
85483
  }
85093
- function beginVizExport() {
85094
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85484
+ function beginVizExport(ctx) {
85485
+ const container = createExportContainer(ctx.width, ctx.height);
85095
85486
  const dims = {
85096
- width: EXPORT_WIDTH,
85097
- height: EXPORT_HEIGHT
85487
+ width: ctx.width,
85488
+ height: ctx.height
85098
85489
  };
85099
85490
  return { container, dims };
85100
85491
  }
@@ -85103,7 +85494,7 @@ async function exportSlope(ctx) {
85103
85494
  const parsed = parseSlope(content, palette);
85104
85495
  if (parsed.error || parsed.data.length === 0) return "";
85105
85496
  const effectivePalette = await resolveExportPalette(theme, palette);
85106
- const { container, dims } = beginVizExport();
85497
+ const { container, dims } = beginVizExport(ctx);
85107
85498
  renderSlopeChart(
85108
85499
  container,
85109
85500
  parsed,
@@ -85119,7 +85510,7 @@ async function exportArc(ctx) {
85119
85510
  const parsed = parseArc(content, palette);
85120
85511
  if (parsed.error || parsed.links.length === 0) return "";
85121
85512
  const effectivePalette = await resolveExportPalette(theme, palette);
85122
- const { container, dims } = beginVizExport();
85513
+ const { container, dims } = beginVizExport(ctx);
85123
85514
  renderArcDiagram(
85124
85515
  container,
85125
85516
  parsed,
@@ -85135,7 +85526,7 @@ async function exportTimeline(ctx) {
85135
85526
  const parsed = parseTimeline(content, palette);
85136
85527
  if (parsed.error || parsed.timelineEvents.length === 0) return "";
85137
85528
  const effectivePalette = await resolveExportPalette(theme, palette);
85138
- const { container, dims } = beginVizExport();
85529
+ const { container, dims } = beginVizExport(ctx);
85139
85530
  renderTimeline(
85140
85531
  container,
85141
85532
  parsed,
@@ -85162,7 +85553,7 @@ async function exportWordcloud(ctx) {
85162
85553
  const parsed = parseWordcloud(content, palette);
85163
85554
  if (parsed.error || parsed.words.length === 0) return "";
85164
85555
  const effectivePalette = await resolveExportPalette(theme, palette);
85165
- const { container, dims } = beginVizExport();
85556
+ const { container, dims } = beginVizExport(ctx);
85166
85557
  await renderWordCloudAsync(
85167
85558
  container,
85168
85559
  parsed,
@@ -85177,7 +85568,7 @@ async function exportVenn(ctx) {
85177
85568
  const parsed = parseVenn(content, palette);
85178
85569
  if (parsed.error || parsed.vennSets.length < 2) return "";
85179
85570
  const effectivePalette = await resolveExportPalette(theme, palette);
85180
- const { container, dims } = beginVizExport();
85571
+ const { container, dims } = beginVizExport(ctx);
85181
85572
  renderVenn(container, parsed, effectivePalette, ctx.isDark, void 0, dims);
85182
85573
  return finalizeSvgExport(container, theme, effectivePalette);
85183
85574
  }
@@ -85186,7 +85577,7 @@ async function exportQuadrant(ctx) {
85186
85577
  const parsed = parseQuadrant(content, palette);
85187
85578
  if (parsed.error || parsed.quadrantPoints.length === 0) return "";
85188
85579
  const effectivePalette = await resolveExportPalette(theme, palette);
85189
- const { container, dims } = beginVizExport();
85580
+ const { container, dims } = beginVizExport(ctx);
85190
85581
  renderQuadrant(
85191
85582
  container,
85192
85583
  parsed,
@@ -85210,9 +85601,9 @@ async function exportVisualization(ctx) {
85210
85601
  }
85211
85602
  const effectivePalette = await resolveExportPalette(theme, palette);
85212
85603
  const isDark = ctx.isDark;
85213
- const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
85604
+ const container = createExportContainer(ctx.width, ctx.height);
85214
85605
  const { parseSequenceDgmo: parseSequenceDgmo2 } = await Promise.resolve().then(() => (init_parser7(), parser_exports));
85215
- const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer33(), renderer_exports32));
85606
+ const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer34(), renderer_exports33));
85216
85607
  const seqParsed = parseSequenceDgmo2(content, effectivePalette);
85217
85608
  if (seqParsed.error || seqParsed.participants.length === 0) return "";
85218
85609
  const collapsedSections = viewState?.cs ? new Set(viewState.cs) : void 0;
@@ -85225,7 +85616,7 @@ async function exportVisualization(ctx) {
85225
85616
  isDark,
85226
85617
  void 0,
85227
85618
  {
85228
- exportWidth: EXPORT_WIDTH,
85619
+ exportWidth: ctx.width,
85229
85620
  ...seqActiveTagGroup !== void 0 && {
85230
85621
  activeTagGroup: seqActiveTagGroup
85231
85622
  },
@@ -85821,9 +86212,16 @@ async function render(content, options) {
85821
86212
  if (category === "data-chart") {
85822
86213
  await acquireDom();
85823
86214
  try {
85824
- const raw = await renderDataChartD3(renderContent, theme, paletteColors);
86215
+ const raw = await renderDataChartD3(renderContent, theme, paletteColors, {
86216
+ ...options?.width !== void 0 && { width: options.width },
86217
+ ...options?.height !== void 0 && { height: options.height }
86218
+ });
85825
86219
  const svg2 = injectHoverStyles(raw, chartType, { bakeHover });
85826
- return { svg: svg2, diagnostics: withLegendInlineWarning(diagnostics), chartType: chartType ?? void 0 };
86220
+ return {
86221
+ svg: svg2,
86222
+ diagnostics: withLegendInlineWarning(diagnostics),
86223
+ chartType: chartType ?? void 0
86224
+ };
85827
86225
  } finally {
85828
86226
  releaseDom();
85829
86227
  }
@@ -85845,6 +86243,8 @@ async function render(content, options) {
85845
86243
  },
85846
86244
  ...options?.tagGroup !== void 0 && { tagGroup: options.tagGroup },
85847
86245
  ...options?.mapData !== void 0 && { mapData: options.mapData },
86246
+ ...options?.width !== void 0 && { width: options.width },
86247
+ ...options?.height !== void 0 && { height: options.height },
85848
86248
  onMapResolverDiagnostics: (d) => {
85849
86249
  mapDiag.current = d;
85850
86250
  }
@@ -85857,7 +86257,11 @@ async function render(content, options) {
85857
86257
  if (chartType === "map" && mapDiag.current) {
85858
86258
  diagnostics = [...mapDiag.current];
85859
86259
  }
85860
- return { svg, diagnostics: withLegendInlineWarning(diagnostics), chartType: chartType ?? void 0 };
86260
+ return {
86261
+ svg,
86262
+ diagnostics: withLegendInlineWarning(diagnostics),
86263
+ chartType: chartType ?? void 0
86264
+ };
85861
86265
  }
85862
86266
 
85863
86267
  // src/countdown/ticker.ts
@@ -86202,46 +86606,11 @@ function startClocks(root = document) {
86202
86606
  init_registry();
86203
86607
  init_palettes();
86204
86608
 
86205
- // src/sharing.ts
86206
- var import_lz_string = __toESM(require_lz_string(), 1);
86207
- var DEFAULT_BASE_URL = "https://online.diagrammo.app";
86208
- var COMPRESSED_SIZE_LIMIT = 8192;
86209
- function encodeViewState(state) {
86210
- const keys = Object.keys(state);
86211
- if (keys.length === 0) return "";
86212
- return (0, import_lz_string.compressToEncodedURIComponent)(JSON.stringify(state));
86213
- }
86214
- function encodeDiagramUrl(dsl, options) {
86215
- const baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;
86216
- const compressed = (0, import_lz_string.compressToEncodedURIComponent)(dsl);
86217
- const byteSize = new TextEncoder().encode(compressed).byteLength;
86218
- if (byteSize > COMPRESSED_SIZE_LIMIT) {
86219
- return {
86220
- error: "too-large",
86221
- compressedSize: byteSize,
86222
- limit: COMPRESSED_SIZE_LIMIT
86223
- };
86224
- }
86225
- let hash = `dgmo=${compressed}`;
86226
- if (options?.viewState) {
86227
- const vsEncoded = encodeViewState(options.viewState);
86228
- if (vsEncoded) {
86229
- hash += `&vs=${vsEncoded}`;
86230
- }
86231
- }
86232
- if (options?.palette && options.palette !== "nord") {
86233
- hash += `&pal=${encodeURIComponent(options.palette)}`;
86234
- }
86235
- if (options?.theme && options.theme !== "dark") {
86236
- hash += `&th=${encodeURIComponent(options.theme)}`;
86237
- }
86238
- if (options?.filename) {
86239
- hash += `&fn=${encodeURIComponent(options.filename)}`;
86240
- }
86241
- return { url: `${baseUrl}?${hash}#${hash}` };
86242
- }
86609
+ // src/auto/shared.ts
86610
+ init_sharing();
86243
86611
 
86244
86612
  // src/embed/index.ts
86613
+ init_sharing();
86245
86614
  init_palettes();
86246
86615
 
86247
86616
  // src/editor/dgmo.grammar.js
@@ -86309,7 +86678,9 @@ var CHART_TYPES = /* @__PURE__ */ new Set([
86309
86678
  "venn",
86310
86679
  "quadrant",
86311
86680
  "map",
86312
- "body"
86681
+ "body",
86682
+ // Pointer type — internal, but it must still highlight when one is open
86683
+ "live-link"
86313
86684
  ]);
86314
86685
  var TAG_KEYWORD = "tag";
86315
86686
  var DIRECTIVE_KEYWORDS = /* @__PURE__ */ new Set([...REGISTRY_DIRECTIVE_TOKENS]);
@@ -86761,19 +87132,8 @@ function markTokensInRange(tokens, from, to, role) {
86761
87132
  }
86762
87133
  }
86763
87134
 
86764
- // src/error-card.ts
86765
- init_dgmo_router();
86766
- var DOCS_BASE = "https://diagrammo.app/docs";
86767
- function docsLink(source) {
86768
- const chartType = parseDgmoChartType(source);
86769
- return chartType ? {
86770
- url: `${DOCS_BASE}/chart-${chartType}/`,
86771
- label: `Read the ${chartType} guide \u2197`
86772
- } : { url: `${DOCS_BASE}/`, label: "Browse the DGMO docs \u2197" };
86773
- }
86774
- var W2 = 660;
86775
- var PAD2 = 24;
86776
- var CONTENT_W = W2 - PAD2 * 2;
87135
+ // src/embed/index.ts
87136
+ init_error_card();
86777
87137
 
86778
87138
  // src/embed/escape.ts
86779
87139
  var HTML_ENTITIES = {
@@ -87180,8 +87540,8 @@ var BLOCK_CSS = `
87180
87540
  font-style: italic;
87181
87541
  }
87182
87542
 
87183
- /* === Cloud references ===
87184
- * A withdrawn reference's placeholder, and the "this moved" affordance a host's
87543
+ /* === Live links ===
87544
+ * A withdrawn pointer's placeholder, and the "this moved" affordance a host's
87185
87545
  * client script falls back to when it can see a diagram has changed but cannot
87186
87546
  * safely swap it in. Both are deliberately quiet: a page peppered with badges
87187
87547
  * is worse than one that is a few days behind. */
@@ -87203,6 +87563,42 @@ var BLOCK_CSS = `
87203
87563
  opacity: 0.7;
87204
87564
  text-align: right;
87205
87565
  }
87566
+ /* The card a docs site shows when live links are switched OFF, plus its
87567
+ * hover-revealed way to turn them on. Hover-only on purpose: a READER never
87568
+ * meets it, and anyone mousing over a diagram-shaped thing on their own docs
87569
+ * site is almost certainly its author \u2014 which makes this the fix for a build
87570
+ * warning nobody reads. The markup is the WRAPPER's (only it knows the feature
87571
+ * is off); the styling is here because there is one stylesheet. */
87572
+ .dgmo-live-link-off {
87573
+ position: relative;
87574
+ }
87575
+ .dgmo-live-link-view {
87576
+ display: block;
87577
+ text-decoration: none;
87578
+ }
87579
+ /* pointer-events: none alongside the fade, or an invisible link sits over the
87580
+ * card's bottom-right corner and navigates a reader who clicks near it. Focus
87581
+ * still reveals it (:focus-within on the wrapper), so a keyboard user is not
87582
+ * shut out of something a mouse user can reach. */
87583
+ .dgmo-live-link-enable {
87584
+ bottom: 0.5rem;
87585
+ font-size: 0.8em;
87586
+ opacity: 0;
87587
+ pointer-events: none;
87588
+ position: absolute;
87589
+ right: 0.5rem;
87590
+ transition: opacity 0.15s ease-in-out;
87591
+ }
87592
+ .dgmo-live-link-off:hover .dgmo-live-link-enable,
87593
+ .dgmo-live-link-off:focus-within .dgmo-live-link-enable {
87594
+ opacity: 1;
87595
+ pointer-events: auto;
87596
+ }
87597
+ @media (prefers-reduced-motion: reduce) {
87598
+ .dgmo-live-link-enable {
87599
+ transition: none;
87600
+ }
87601
+ }
87206
87602
  `;
87207
87603
 
87208
87604
  // src/embed/index.ts
@@ -87327,7 +87723,7 @@ var CSS = AUTO_BASE_CSS + "\n" + BLOCK_CSS + "\n" + darkScopedBlockCss(BLOCK_CSS
87327
87723
 
87328
87724
  // src/auto/shared.ts
87329
87725
  init_safe_href();
87330
- var VERSION = "0.57.0";
87726
+ var VERSION = "0.58.0";
87331
87727
  var ARIA_LABEL_MAX = 200;
87332
87728
  var COPIED_INTERACTION_MS = 1500;
87333
87729
  var LOG_PREFIX = "[dgmo]";