@diagrammo/dgmo 0.92.0 → 0.93.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 (166) hide show
  1. package/dist/advanced.d.ts +85 -21
  2. package/dist/advanced.js +455 -422
  3. package/dist/block.d.ts +2 -2
  4. package/dist/block.js +75 -70
  5. package/dist/{chart-meta-BBqLnv5q.d.ts → chart-meta-BbjsRY7o.d.ts} +2 -2
  6. package/dist/chart-meta.d.ts +3 -3
  7. package/dist/chart-meta.js +25 -19
  8. package/dist/{chart-types-CbXlZFLd.d.ts → chart-types-Cppnp31G.d.ts} +173 -4
  9. package/dist/{charts-d3-QUUDVETP.js → charts-d3-ERYYVGP6.js} +7 -6
  10. package/dist/{chunk-HIWHIYLD.js → chunk-2TFXRBCD.js} +19 -19
  11. package/dist/{chunk-F7326NVM.js → chunk-3GCASUWA.js} +58 -25
  12. package/dist/{chunk-ZJAK6C7Y.js → chunk-3PP746YM.js} +6 -1
  13. package/dist/{chunk-WLLO3PZ3.js → chunk-472EOHVW.js} +17 -17
  14. package/dist/{chunk-LMP6Y7QO.js → chunk-4WQX55VX.js} +56 -24
  15. package/dist/{chunk-JLU52ZDT.js → chunk-5CBX66KB.js} +10 -10
  16. package/dist/{chunk-DEFBUZWV.js → chunk-5HAYT43L.js} +70 -54
  17. package/dist/{chunk-S7W75MIM.js → chunk-65GPEV5V.js} +21 -3
  18. package/dist/{chunk-Q6W2K33N.js → chunk-6XLMTAEX.js} +1 -1
  19. package/dist/{chunk-JKST4RTT.js → chunk-7OWK5K5C.js} +6 -6
  20. package/dist/{chunk-73EYNV4O.js → chunk-A5WIAMCT.js} +4 -6
  21. package/dist/{chunk-X5BUX2GK.js → chunk-ADVGV3P7.js} +1 -1
  22. package/dist/{chunk-45QUTYPD.js → chunk-CYDM2XII.js} +17 -17
  23. package/dist/chunk-CYTFO2LF.js +209 -0
  24. package/dist/{chunk-JRWUHLRP.js → chunk-D6PVMUCX.js} +51 -8
  25. package/dist/{chunk-BRSM6Z34.js → chunk-DAHQL57W.js} +14 -14
  26. package/dist/{chunk-RBFJT23E.js → chunk-EQWC76GQ.js} +6 -6
  27. package/dist/{chunk-ADNIO3XY.js → chunk-FIYW7JW4.js} +5 -5
  28. package/dist/{chunk-7ENDOHAA.js → chunk-FMAVHTYB.js} +919 -927
  29. package/dist/{chunk-3PFMGNOM.js → chunk-GJXMG4S3.js} +26 -11
  30. package/dist/chunk-GXCDD6NG.js +24 -0
  31. package/dist/{chunk-RJ2JW3FG.js → chunk-IESUM4N5.js} +2331 -2236
  32. package/dist/{chunk-62BP7AJU.js → chunk-IIV4SMJL.js} +18 -18
  33. package/dist/{chunk-5EBYPETE.js → chunk-J43OCO22.js} +3 -5
  34. package/dist/{chunk-L5NW3PVL.js → chunk-J6AEKIRQ.js} +1 -1
  35. package/dist/{chunk-2BJW7FSF.js → chunk-KBEWVCK3.js} +1 -1
  36. package/dist/{chunk-LRP5FXST.js → chunk-KCHQVED5.js} +18 -17
  37. package/dist/{chunk-Q6ZQX2HX.js → chunk-KCMGIYPO.js} +4 -6
  38. package/dist/{chunk-MDVJYRJT.js → chunk-KPGPK4SK.js} +22 -22
  39. package/dist/{chunk-Q2UFOKPB.js → chunk-KPSSNGAE.js} +22 -22
  40. package/dist/{chunk-V4D2ZQBE.js → chunk-KRPLP5LP.js} +6 -1
  41. package/dist/{chunk-BZX7QCXJ.js → chunk-KRU2LCIP.js} +15 -15
  42. package/dist/{chunk-HXULJZA2.js → chunk-LDDDKWL6.js} +6 -1
  43. package/dist/{chunk-NREU4JFE.js → chunk-LNVB75QU.js} +6 -8
  44. package/dist/{chunk-MX4SZLSV.js → chunk-LUDUDBO6.js} +16 -8
  45. package/dist/{chunk-2YAFDND3.js → chunk-M4NV5PPU.js} +4 -6
  46. package/dist/{chunk-26BBJUBW.js → chunk-M6ZQAFPD.js} +4 -6
  47. package/dist/{chunk-NPWVOFB3.js → chunk-MB2SQF7N.js} +1 -1
  48. package/dist/{chunk-6ZL2XYM7.js → chunk-MLY5ALOV.js} +6 -6
  49. package/dist/chunk-NJJCTEBM.js +416 -0
  50. package/dist/{chunk-OQW4ETJX.js → chunk-NM5V5EKY.js} +6 -1
  51. package/dist/{chunk-ONYO5WJW.js → chunk-NMK7KJZZ.js} +21 -21
  52. package/dist/{chunk-6BNNLVAR.js → chunk-NPDVWFAQ.js} +6 -1
  53. package/dist/{chunk-FTUMRSGT.js → chunk-P5FUWXPW.js} +4 -286
  54. package/dist/chunk-P7TRFL4P.js +54 -0
  55. package/dist/{chunk-A4PNWAUW.js → chunk-PGSGJLUR.js} +6 -1
  56. package/dist/{chunk-DRFGIOZ6.js → chunk-Q7Y6JQ3R.js} +4 -6
  57. package/dist/{chunk-J2E7EUER.js → chunk-QDRCWVV3.js} +17 -17
  58. package/dist/{chunk-MXAP37W6.js → chunk-TNV4F5WA.js} +16 -7
  59. package/dist/{chunk-EBSFSOJC.js → chunk-U7U64UUN.js} +22 -22
  60. package/dist/chunk-UCHZJJIT.js +421 -0
  61. package/dist/{chunk-FSJ3ZA6N.js → chunk-UG7AQQNR.js} +12 -12
  62. package/dist/{chunk-WFA6IULY.js → chunk-URRAWU5D.js} +5 -0
  63. package/dist/{chunk-VOR32OHN.js → chunk-USAGHYRD.js} +13 -15
  64. package/dist/{chunk-QUGC7GWB.js → chunk-UVX3IYXF.js} +15 -15
  65. package/dist/{chunk-B5PEKSRH.js → chunk-VSAKEMDD.js} +6 -1
  66. package/dist/{chunk-YRYKTYMQ.js → chunk-VSOZZYLK.js} +106 -12
  67. package/dist/{chunk-5SSTVFPX.js → chunk-WK5QEYFA.js} +5 -7
  68. package/dist/{chunk-KTGZDMDX.js → chunk-XUTR7GNT.js} +76 -28
  69. package/dist/{chunk-6WVX4KNP.js → chunk-YDZIVDVR.js} +97 -297
  70. package/dist/{chunk-URQIWIKX.js → chunk-YXXIRM4C.js} +3 -3
  71. package/dist/{chunk-H5UEVW6Q.js → chunk-ZD3QCNB7.js} +1 -1
  72. package/dist/{chunk-DUPZ2BBY.js → chunk-ZTLMEBAC.js} +66 -4
  73. package/dist/clock.js +168 -0
  74. package/dist/completion-registry.js +3 -1
  75. package/dist/countdown.js +36 -395
  76. package/dist/{dgmo-router-4UAPPIKN.js → dgmo-router-CZN36TR3.js} +50 -43
  77. package/dist/{dimensions-SCNVYLRF.js → dimensions-7HHKO5BS.js} +3 -3
  78. package/dist/{d3-BThYBTQk.d.ts → export-context-Ceh3wr0E.d.ts} +2 -8
  79. package/dist/{flowchart-parser-NA75YQ77.js → flowchart-parser-4MZPWYK6.js} +8 -3
  80. package/dist/{flowchart-renderer-6MGGX4RC.js → flowchart-renderer-5XDN575E.js} +13 -17
  81. package/dist/index.d.ts +8 -7
  82. package/dist/index.js +80 -74
  83. package/dist/{layout-S3RLVPH4.js → layout-33FHGDEV.js} +10 -12
  84. package/dist/{layout-MBVBAMPA.js → layout-3TSVAGWH.js} +2 -2
  85. package/dist/{layout-WRG4APSJ.js → layout-5GHV7HNM.js} +9 -13
  86. package/dist/layout-FTOGDNUL.js +23 -0
  87. package/dist/{layout-BNLFQHSB.js → layout-QXGPY7KA.js} +7 -9
  88. package/dist/{layout-search-PMYL3VWS.js → layout-search-EMTCDC3C.js} +8 -10
  89. package/dist/{palettes-IN7ZFRJM.js → palettes-4Y7CL2QL.js} +4 -2
  90. package/dist/{parser-3MK56JZC.js → parser-4Y6PODW6.js} +2 -2
  91. package/dist/{parser-2NWH5JUS.js → parser-A3AN76RQ.js} +2 -1
  92. package/dist/{parser-LCJ76UXS.js → parser-BT4NI6JY.js} +5 -1
  93. package/dist/{parser-FXDS4JDK.js → parser-F7NDRPMA.js} +2 -2
  94. package/dist/{parser-BES6LV3G.js → parser-GDLKUBTO.js} +5 -1
  95. package/dist/{parser-SEUTXN6U.js → parser-KJPPUN4D.js} +2 -2
  96. package/dist/{parser-SIKL4PLF.js → parser-KMKVFET2.js} +5 -1
  97. package/dist/{parser-5LW5JDYG.js → parser-NL73FSFI.js} +5 -1
  98. package/dist/{parser-VA7ZQQTA.js → parser-NUU3DVW4.js} +5 -1
  99. package/dist/{parser-L6RWDXQN.js → parser-OGF2CDA6.js} +8 -3
  100. package/dist/{parser-XZUKNZPB.js → parser-R3LPEQIT.js} +7 -1
  101. package/dist/{parser-X23GRTQJ.js → parser-RCIEKN7Y.js} +5 -1
  102. package/dist/{parser-GX5YLRIP.js → parser-VKYUAT4Y.js} +8 -3
  103. package/dist/{parser-QYISOAGR.js → parser-YX72VLDZ.js} +8 -3
  104. package/dist/redraw-MSXU4ZD2.js +73 -0
  105. package/dist/redraw-T324XAF3.js +1698 -0
  106. package/dist/{renderer-5VKPB4LL.js → renderer-37PLQHVB.js} +5 -5
  107. package/dist/{renderer-ISSDGK54.js → renderer-3F47TPZ2.js} +3 -3
  108. package/dist/{renderer-3QAFDXEY.js → renderer-5ITLW7MX.js} +14 -12
  109. package/dist/{renderer-ZZ6MWVB7.js → renderer-6GJWADLO.js} +4 -4
  110. package/dist/{renderer-MM27BSBO.js → renderer-7Y3LR4R2.js} +3 -4
  111. package/dist/{renderer-2FVUPBGV.js → renderer-AM7P4LN7.js} +1 -1
  112. package/dist/{renderer-ZHGHTSNG.js → renderer-BO73LSVT.js} +13 -12
  113. package/dist/{renderer-3IHQI4A4.js → renderer-CNRQFIEI.js} +11 -10
  114. package/dist/{renderer-OAR5VPH4.js → renderer-DAZWHNLI.js} +2 -2
  115. package/dist/{renderer-NDA2FFYB.js → renderer-DD6T3C4J.js} +5 -5
  116. package/dist/{renderer-WIU5BJUK.js → renderer-DDWDCM2K.js} +2 -2
  117. package/dist/{renderer-7ZZG5HR3.js → renderer-EVKWGUGT.js} +8 -9
  118. package/dist/{renderer-3JY6JAQJ.js → renderer-FL7EOSBU.js} +5 -6
  119. package/dist/{renderer-NIE5IW24.js → renderer-GFALLIYT.js} +8 -7
  120. package/dist/{renderer-O6DY46AV.js → renderer-GFGFHYWY.js} +7 -7
  121. package/dist/{renderer-5TZVFQ7K.js → renderer-GOXAP2IE.js} +7 -8
  122. package/dist/{renderer-NHTR7IRR.js → renderer-GPAVVUET.js} +4 -5
  123. package/dist/{renderer-TO2NVJP3.js → renderer-HJ54YXT3.js} +50 -45
  124. package/dist/{renderer-LM4ICK6I.js → renderer-HYGTMBHT.js} +4 -5
  125. package/dist/{renderer-S3YCLJKL.js → renderer-IHCWBFPI.js} +17 -20
  126. package/dist/{renderer-XO57LTU4.js → renderer-ISDKO3DI.js} +5 -5
  127. package/dist/{renderer-LQP3AGEJ.js → renderer-J3QWK6IM.js} +3 -4
  128. package/dist/{renderer-J666LZXJ.js → renderer-J6H4Q3RM.js} +7 -8
  129. package/dist/{renderer-ALWVK3EJ.js → renderer-JJ4QW3SK.js} +6 -6
  130. package/dist/{renderer-DC7C5Q3G.js → renderer-NOYLNVTI.js} +2 -2
  131. package/dist/{renderer-ZGY7P4BM.js → renderer-PBKTAWQV.js} +16 -20
  132. package/dist/{renderer-XGG2UNXT.js → renderer-POBGKIUT.js} +3 -4
  133. package/dist/{renderer-QGIHLZOJ.js → renderer-RDI2RYUP.js} +9 -10
  134. package/dist/{renderer-JEJT3YET.js → renderer-TSCSZ6CL.js} +2 -3
  135. package/dist/{renderer-VPIELEE5.js → renderer-VDBNC7A6.js} +8 -9
  136. package/dist/{renderer-J67LMOD5.js → renderer-VI34SD5V.js} +15 -15
  137. package/dist/{renderer-J5FKF423.js → renderer-W4MUMXJE.js} +7 -4
  138. package/dist/{renderer-RSK6QFWN.js → renderer-XJMVG2WJ.js} +7 -9
  139. package/dist/{state-parser-TIR2ORJY.js → state-parser-NPYTMRXP.js} +8 -3
  140. package/dist/{state-renderer-G6SUXU4J.js → state-renderer-44K2KDX7.js} +15 -19
  141. package/dist/{tag-groups-DsoVpAY-.d.ts → tag-groups-DydewK3D.d.ts} +2 -173
  142. package/dist/{themes-DRNjxX7Q.d.ts → themes-DzIH3Hjv.d.ts} +3 -2
  143. package/docs/ai-integration.md +1 -1
  144. package/docs/language-reference.md +23 -2
  145. package/gallery/fixtures/map-undirected-edges.dgmo +5 -5
  146. package/gallery/fixtures/whiteboard.dgmo +3 -0
  147. package/package.json +4 -6
  148. package/dist/chunk-3Y63RFJL.js +0 -75
  149. package/dist/chunk-5DH3KYFH.js +0 -20
  150. package/dist/chunk-O753JUEZ.js +0 -67
  151. package/dist/chunk-RJNZHFNG.js +0 -51
  152. package/dist/chunk-Z6DXWULM.js +0 -23
  153. package/dist/layout-5USEVQBY.js +0 -25
  154. package/dist/{chunk-YITHYQCL.js → chunk-4FT5KQ7H.js} +7 -7
  155. package/dist/{chunk-GE7ICBX6.js → chunk-4RY5D5RE.js} +4 -4
  156. package/dist/{chunk-DGUGE67L.js → chunk-CDYV46JE.js} +3 -3
  157. package/dist/{chunk-IGKFOHBG.js → chunk-CQYFZOUC.js} +13 -13
  158. package/dist/{chunk-TKAB3FTK.js → chunk-DRQSB72S.js} +11 -11
  159. package/dist/{chunk-ZKP77MB3.js → chunk-FVTYJUXR.js} +5 -5
  160. package/dist/{chunk-MA42PIGJ.js → chunk-H5NVCOEJ.js} +4 -4
  161. package/dist/{chunk-BEA4D7OS.js → chunk-IXHWS2HI.js} +3 -3
  162. package/dist/{chunk-QKY6W4NA.js → chunk-KHL652SX.js} +25 -25
  163. package/dist/{chunk-6OIMUSDX.js → chunk-MUJVNSEW.js} +9 -9
  164. package/dist/{chunk-YO6AQU4A.js → chunk-QJOVZ4TC.js} +12 -12
  165. package/dist/{chunk-SOHZDW6N.js → chunk-UXNA2H2V.js} +3 -3
  166. package/dist/{chunk-NO3UX6AP.js → chunk-V2NQV7VL.js} +4 -4
@@ -0,0 +1,416 @@
1
+ import {
2
+ normalizeName
3
+ } from "./chunk-NOTA6TEI.js";
4
+ import {
5
+ NOTE_GAP,
6
+ noteBoxSize,
7
+ noteConnectorPoints
8
+ } from "./chunk-D6PVMUCX.js";
9
+ import {
10
+ extractColor,
11
+ measureIndent
12
+ } from "./chunk-TIIZIAGS.js";
13
+ import {
14
+ makeDgmoError,
15
+ suggest
16
+ } from "./chunk-BYU54C3S.js";
17
+
18
+ // src/utils/notes/parse.ts
19
+ function parseNoteHeader(rest) {
20
+ const t = rest.trim();
21
+ const quoted = t.match(/^"([^"]+)"\s*(.*)$/);
22
+ if (quoted) {
23
+ return { ref: quoted[1].trim(), inlineBody: quoted[2].trim() };
24
+ }
25
+ const m = t.match(/^(\S+)\s*(.*)$/);
26
+ if (m) {
27
+ return { ref: m[1], inlineBody: m[2].trim() };
28
+ }
29
+ return { ref: t, inlineBody: "" };
30
+ }
31
+ function collectNoteBody(lines, noteIndex, noteIndent, inlineBody) {
32
+ const parts = [];
33
+ if (inlineBody) parts.push(inlineBody);
34
+ let lastIndex = noteIndex;
35
+ let endLineNumber = noteIndex + 1;
36
+ for (let j = noteIndex + 1; j < lines.length; j++) {
37
+ const raw = lines[j];
38
+ const trimmed = raw.trim();
39
+ if (!trimmed) break;
40
+ if (measureIndent(raw) <= noteIndent) break;
41
+ parts.push(trimmed);
42
+ lastIndex = j;
43
+ endLineNumber = j + 1;
44
+ }
45
+ return { body: parts.join("\n"), endLineNumber, lastIndex };
46
+ }
47
+ function tryCollectNote(lines, index, indent, palette, diagnostics) {
48
+ const trimmed = lines[index].trim();
49
+ const m = trimmed.match(/^note\s+(.+)$/i);
50
+ if (!m || /^note\s+->/i.test(trimmed)) return null;
51
+ const lineNumber = index + 1;
52
+ const { label: headerNoColor, color } = extractColor(
53
+ m[1],
54
+ palette,
55
+ diagnostics,
56
+ lineNumber
57
+ );
58
+ const { ref, inlineBody } = parseNoteHeader(headerNoColor);
59
+ const collected = collectNoteBody(lines, index, indent, inlineBody);
60
+ if (!collected.body.trim()) {
61
+ diagnostics.push(
62
+ makeDgmoError(
63
+ lineNumber,
64
+ `Note on "${ref}" has no text \u2014 ignored.`,
65
+ "warning"
66
+ )
67
+ );
68
+ return { lastIndex: collected.lastIndex };
69
+ }
70
+ return {
71
+ note: {
72
+ ref,
73
+ body: collected.body,
74
+ ...color && { color },
75
+ lineNumber,
76
+ endLineNumber: collected.endLineNumber
77
+ },
78
+ lastIndex: collected.lastIndex
79
+ };
80
+ }
81
+
82
+ // src/utils/notes/resolve.ts
83
+ function resolveNotes(notes, targets, diagnostics) {
84
+ const byNodeId = /* @__PURE__ */ new Map();
85
+ if (notes.length === 0) return byNodeId;
86
+ const byNormLabel = /* @__PURE__ */ new Map();
87
+ for (const t of targets) {
88
+ const key = normalizeName(t.label);
89
+ const arr = byNormLabel.get(key);
90
+ if (arr) arr.push(t);
91
+ else byNormLabel.set(key, [t]);
92
+ }
93
+ for (const note of notes) {
94
+ const matches = byNormLabel.get(normalizeName(note.ref));
95
+ if (!matches || matches.length === 0) {
96
+ if (diagnostics) {
97
+ const hint = suggest(
98
+ note.ref,
99
+ targets.map((t) => t.label)
100
+ );
101
+ diagnostics.push(
102
+ makeDgmoError(
103
+ note.lineNumber,
104
+ `Note references unknown node id "${note.ref}".${hint ? " " + hint : ""}`,
105
+ "error"
106
+ )
107
+ );
108
+ }
109
+ continue;
110
+ }
111
+ const target = matches[0];
112
+ if (matches.length > 1 && diagnostics) {
113
+ diagnostics.push(
114
+ makeDgmoError(
115
+ note.lineNumber,
116
+ `Note ref "${note.ref}" matches ${matches.length} nodes; attaching to the first.`,
117
+ "warning"
118
+ )
119
+ );
120
+ }
121
+ if (byNodeId.has(target.id)) {
122
+ if (diagnostics) {
123
+ diagnostics.push(
124
+ makeDgmoError(
125
+ note.lineNumber,
126
+ `Multiple notes on node "${target.label}"; keeping the first.`,
127
+ "warning"
128
+ )
129
+ );
130
+ }
131
+ continue;
132
+ }
133
+ byNodeId.set(target.id, note);
134
+ }
135
+ return byNodeId;
136
+ }
137
+
138
+ // src/utils/notes/place.ts
139
+ var NOTE_CLEAR = 14;
140
+ var intersects = (a, b, pad) => !(a.right + pad <= b.left || b.right + pad <= a.left || a.bottom + pad <= b.top || b.bottom + pad <= a.top);
141
+ var CONNECTOR_CLEAR = 4;
142
+ var EDGE_CLEAR = 6;
143
+ var SLIDE_STEP = 10;
144
+ var SEARCH_REACH = 480;
145
+ var segmentCrosses = (x1, y1, x2, y2, r) => {
146
+ const dx = x2 - x1;
147
+ const dy = y2 - y1;
148
+ const p = [-dx, dx, -dy, dy];
149
+ const q = [x1 - r.left, r.right - x1, y1 - r.top, r.bottom - y1];
150
+ let t0 = 0;
151
+ let t1 = 1;
152
+ for (let i = 0; i < 4; i++) {
153
+ const pi = p[i];
154
+ const qi = q[i];
155
+ if (pi === 0) {
156
+ if (qi <= 0) return false;
157
+ continue;
158
+ }
159
+ const t = qi / pi;
160
+ if (pi < 0) t0 = Math.max(t0, t);
161
+ else t1 = Math.min(t1, t);
162
+ }
163
+ return t0 < t1;
164
+ };
165
+ function placeNotes(obstacles, requests, direction, edges = []) {
166
+ const placements = /* @__PURE__ */ new Map();
167
+ const occupied = obstacles.map((p) => ({
168
+ left: p.x - p.width / 2,
169
+ top: p.y - p.height / 2,
170
+ right: p.x + p.width / 2,
171
+ bottom: p.y + p.height / 2
172
+ }));
173
+ for (const req of requests) {
174
+ if (req.collapsed) {
175
+ placements.set(req.key, {
176
+ collapsed: true,
177
+ side: "right",
178
+ x: 0,
179
+ y: 0
180
+ });
181
+ continue;
182
+ }
183
+ const p = req.node;
184
+ const cx = p.x;
185
+ const cy = p.y;
186
+ const nodeLeft = cx - p.width / 2;
187
+ const nodeRight = cx + p.width / 2;
188
+ const nodeTop = cy - p.height / 2;
189
+ const nodeBottom = cy + p.height / 2;
190
+ const { noteW, noteH } = req;
191
+ const rectFor = (side) => {
192
+ switch (side) {
193
+ case "right": {
194
+ const left = nodeRight + NOTE_GAP;
195
+ const top = cy - noteH / 2;
196
+ return { left, top, right: left + noteW, bottom: top + noteH };
197
+ }
198
+ case "left": {
199
+ const right = nodeLeft - NOTE_GAP;
200
+ const top = cy - noteH / 2;
201
+ return { left: right - noteW, top, right, bottom: top + noteH };
202
+ }
203
+ case "below": {
204
+ const left = cx - noteW / 2;
205
+ const top = nodeBottom + NOTE_GAP;
206
+ return { left, top, right: left + noteW, bottom: top + noteH };
207
+ }
208
+ case "above":
209
+ default: {
210
+ const left = cx - noteW / 2;
211
+ const bottom = nodeTop - NOTE_GAP;
212
+ return { left, top: bottom - noteH, right: left + noteW, bottom };
213
+ }
214
+ }
215
+ };
216
+ const order = direction === "LR" ? ["below", "above", "right", "left"] : ["right", "left", "below", "above"];
217
+ const anchor = {
218
+ left: nodeLeft,
219
+ top: nodeTop,
220
+ right: nodeRight,
221
+ bottom: nodeBottom
222
+ };
223
+ const isAnchor = (o) => o.left === anchor.left && o.top === anchor.top && o.right === anchor.right && o.bottom === anchor.bottom;
224
+ const connector = (rect, side) => {
225
+ const [x1, y1, x2, y2] = noteConnectorPoints(p, {
226
+ x: rect.left - cx,
227
+ y: rect.top - cy,
228
+ width: noteW,
229
+ height: noteH,
230
+ side
231
+ });
232
+ return [cx + x1, cy + y1, cx + x2, cy + y2];
233
+ };
234
+ const onEdge = (rect) => {
235
+ const padded = {
236
+ left: rect.left - EDGE_CLEAR,
237
+ top: rect.top - EDGE_CLEAR,
238
+ right: rect.right + EDGE_CLEAR,
239
+ bottom: rect.bottom + EDGE_CLEAR
240
+ };
241
+ return edges.some(
242
+ (path) => path.some(
243
+ (pt, i) => i > 0 && segmentCrosses(path[i - 1].x, path[i - 1].y, pt.x, pt.y, padded)
244
+ )
245
+ );
246
+ };
247
+ const isClear = (rect, side, avoidEdges) => {
248
+ if (occupied.some((o) => intersects(rect, o, NOTE_CLEAR))) return false;
249
+ if (avoidEdges && onEdge(rect)) return false;
250
+ const [x1, y1, x2, y2] = connector(rect, side);
251
+ return !occupied.some(
252
+ (o) => !isAnchor(o) && segmentCrosses(x1, y1, x2, y2, {
253
+ left: o.left - CONNECTOR_CLEAR,
254
+ top: o.top - CONNECTOR_CLEAR,
255
+ right: o.right + CONNECTOR_CLEAR,
256
+ bottom: o.bottom + CONNECTOR_CLEAR
257
+ })
258
+ );
259
+ };
260
+ const search = (avoidEdges) => {
261
+ let chosen2 = null;
262
+ for (const side of order.slice(0, 2)) {
263
+ const rect = rectFor(side);
264
+ if (isClear(rect, side, avoidEdges)) {
265
+ chosen2 = { rect, side };
266
+ break;
267
+ }
268
+ }
269
+ if (chosen2) return chosen2;
270
+ let bestLen = Infinity;
271
+ for (const side of order) {
272
+ const axisIsY = side === "above" || side === "below";
273
+ const outward = side === "below" || side === "right" ? 1 : -1;
274
+ const reach = axisIsY ? noteW / 2 : SEARCH_REACH;
275
+ const slides = [0];
276
+ for (let s = SLIDE_STEP; s <= reach; s += SLIDE_STEP) {
277
+ slides.push(s, -s);
278
+ }
279
+ const base = rectFor(side);
280
+ for (let out = 0; out <= SEARCH_REACH; out += NOTE_CLEAR) {
281
+ for (const slide of slides) {
282
+ const dx = axisIsY ? slide : out * outward;
283
+ const dy = axisIsY ? out * outward : slide;
284
+ const rect = {
285
+ left: base.left + dx,
286
+ top: base.top + dy,
287
+ right: base.right + dx,
288
+ bottom: base.bottom + dy
289
+ };
290
+ if (!isClear(rect, side, avoidEdges)) continue;
291
+ const [x1, y1, x2, y2] = connector(rect, side);
292
+ const len = Math.hypot(x2 - x1, y2 - y1);
293
+ if (len < bestLen) {
294
+ bestLen = len;
295
+ chosen2 = { rect, side };
296
+ }
297
+ }
298
+ }
299
+ }
300
+ return chosen2;
301
+ };
302
+ let chosen = search(true) ?? search(false);
303
+ if (!chosen) {
304
+ const side = order[0];
305
+ let rect = rectFor(side);
306
+ const axisIsY = side === "above" || side === "below";
307
+ const outward = side === "below" || side === "right" ? 1 : -1;
308
+ for (let guard = 0; guard < 50; guard++) {
309
+ const blockers = occupied.filter(
310
+ (o) => intersects(rect, o, NOTE_CLEAR)
311
+ );
312
+ if (blockers.length === 0) break;
313
+ if (axisIsY && outward > 0) {
314
+ const top = Math.max(...blockers.map((b) => b.bottom)) + NOTE_CLEAR;
315
+ rect = { ...rect, top, bottom: top + noteH };
316
+ } else if (axisIsY) {
317
+ const bottom = Math.min(...blockers.map((b) => b.top)) - NOTE_CLEAR;
318
+ rect = { ...rect, bottom, top: bottom - noteH };
319
+ } else if (outward > 0) {
320
+ const left = Math.max(...blockers.map((b) => b.right)) + NOTE_CLEAR;
321
+ rect = { ...rect, left, right: left + noteW };
322
+ } else {
323
+ const right = Math.min(...blockers.map((b) => b.left)) - NOTE_CLEAR;
324
+ rect = { ...rect, right, left: right - noteW };
325
+ }
326
+ }
327
+ chosen = { rect, side };
328
+ }
329
+ occupied.push(chosen.rect);
330
+ placements.set(req.key, {
331
+ collapsed: false,
332
+ side: chosen.side,
333
+ x: chosen.rect.left - p.x,
334
+ y: chosen.rect.top - p.y
335
+ });
336
+ }
337
+ return placements;
338
+ }
339
+
340
+ // src/utils/notes/build.ts
341
+ function buildPlacedNotes(anchors, noteByNode, direction, collapsedNotes) {
342
+ const placed = /* @__PURE__ */ new Map();
343
+ if (noteByNode.size === 0) return placed;
344
+ const geoms = /* @__PURE__ */ new Map();
345
+ const requests = [];
346
+ for (const a of anchors) {
347
+ const note = noteByNode.get(a.id);
348
+ if (!note) continue;
349
+ const size = noteBoxSize(note.body);
350
+ geoms.set(a.id, {
351
+ noteW: size.width,
352
+ noteH: size.height,
353
+ ...note.color && { color: note.color },
354
+ lines: size.lines,
355
+ lineNumber: note.lineNumber,
356
+ endLineNumber: note.endLineNumber
357
+ });
358
+ requests.push({
359
+ key: a.id,
360
+ node: { x: a.x, y: a.y, width: a.width, height: a.height },
361
+ noteW: size.width,
362
+ noteH: size.height,
363
+ collapsed: collapsedNotes?.has(note.lineNumber) ?? false
364
+ });
365
+ }
366
+ const placements = placeNotes(
367
+ anchors.map((a) => ({ x: a.x, y: a.y, width: a.width, height: a.height })),
368
+ requests,
369
+ direction
370
+ );
371
+ for (const [id, g] of geoms) {
372
+ const p = placements.get(id);
373
+ placed.set(
374
+ id,
375
+ p.collapsed ? {
376
+ x: 0,
377
+ y: 0,
378
+ width: 0,
379
+ height: 0,
380
+ side: "right",
381
+ ...g.color && { color: g.color },
382
+ lines: [],
383
+ lineNumber: g.lineNumber,
384
+ endLineNumber: g.endLineNumber,
385
+ collapsed: true
386
+ } : {
387
+ x: p.x,
388
+ y: p.y,
389
+ width: g.noteW,
390
+ height: g.noteH,
391
+ side: p.side,
392
+ ...g.color && { color: g.color },
393
+ lines: g.lines,
394
+ lineNumber: g.lineNumber,
395
+ endLineNumber: g.endLineNumber
396
+ }
397
+ );
398
+ }
399
+ return placed;
400
+ }
401
+
402
+ // src/utils/notes/bounds.ts
403
+ function noteCanvasShift(minX, minY, margin = 20) {
404
+ return {
405
+ shiftX: minX < 0 ? margin - minX : 0,
406
+ shiftY: minY < 0 ? margin - minY : 0
407
+ };
408
+ }
409
+
410
+ export {
411
+ tryCollectNote,
412
+ resolveNotes,
413
+ placeNotes,
414
+ buildPlacedNotes,
415
+ noteCanvasShift
416
+ };
@@ -1,3 +1,6 @@
1
+ import {
2
+ extractPaletteDirective
3
+ } from "./chunk-CYTFO2LF.js";
1
4
  import {
2
5
  RING_REGISTRY,
3
6
  measureIndent,
@@ -30,7 +33,9 @@ function parseRing(content) {
30
33
  diagnostics: [],
31
34
  error: null
32
35
  };
33
- const lines = content.split("\n");
36
+ const directive = extractPaletteDirective(content);
37
+ result.diagnostics.push(...directive.diagnostics);
38
+ const lines = directive.content.split("\n");
34
39
  let headerParsed = false;
35
40
  let currentLayer = null;
36
41
  const fail = makeFail(result);
@@ -1,44 +1,44 @@
1
1
  import {
2
2
  layoutERDiagram
3
- } from "./chunk-MXAP37W6.js";
3
+ } from "./chunk-TNV4F5WA.js";
4
4
  import {
5
- NOTE_BADGE_RADIUS,
6
- noteConnectorPoints,
7
- renderNoteBadge,
8
- renderNoteBox,
9
- renderNoteConnector
10
- } from "./chunk-JRWUHLRP.js";
5
+ serializeSvg
6
+ } from "./chunk-CYRB2JTN.js";
11
7
  import {
12
8
  ScaleContext
13
9
  } from "./chunk-24YPR5EH.js";
14
10
  import {
15
- renderIntegratedLegend
16
- } from "./chunk-NMS5XSLX.js";
11
+ layoutInlineHeader
12
+ } from "./chunk-42UJ23H3.js";
13
+ import {
14
+ TITLE_FONT_SIZE,
15
+ TITLE_FONT_WEIGHT,
16
+ TITLE_Y
17
+ } from "./chunk-VLC6WNRD.js";
17
18
  import {
18
19
  EDGE_LABEL_KNOCKOUT_OPACITY,
19
20
  EDGE_STROKE_WIDTH,
20
21
  NODE_STROKE_WIDTH
21
22
  } from "./chunk-XCKNFFKM.js";
22
23
  import {
23
- layoutInlineHeader
24
- } from "./chunk-42UJ23H3.js";
25
- import {
26
- serializeSvg
27
- } from "./chunk-CYRB2JTN.js";
24
+ renderIntegratedLegend
25
+ } from "./chunk-NMS5XSLX.js";
28
26
  import {
29
27
  getLegendExtent
30
28
  } from "./chunk-JILEYZ2V.js";
31
29
  import {
32
- TITLE_FONT_SIZE,
33
- TITLE_FONT_WEIGHT,
34
- TITLE_Y
35
- } from "./chunk-VLC6WNRD.js";
30
+ parseERDiagram
31
+ } from "./chunk-Q7Y6JQ3R.js";
32
+ import {
33
+ NOTE_BADGE_RADIUS,
34
+ noteConnectorPoints,
35
+ renderNoteBadge,
36
+ renderNoteBox,
37
+ renderNoteConnector
38
+ } from "./chunk-D6PVMUCX.js";
36
39
  import {
37
40
  FONT_FAMILY
38
41
  } from "./chunk-ICLB27PZ.js";
39
- import {
40
- parseERDiagram
41
- } from "./chunk-DRFGIOZ6.js";
42
42
  import {
43
43
  resolveTagColor,
44
44
  tagAttrKey
@@ -1,3 +1,6 @@
1
+ import {
2
+ extractPaletteDirective
3
+ } from "./chunk-CYTFO2LF.js";
1
4
  import {
2
5
  CYCLE_REGISTRY,
3
6
  measureIndent,
@@ -27,7 +30,9 @@ function parseCycle(content) {
27
30
  diagnostics: [],
28
31
  error: null
29
32
  };
30
- const lines = content.split("\n");
33
+ const directive = extractPaletteDirective(content);
34
+ result.diagnostics.push(...directive.diagnostics);
35
+ const lines = directive.content.split("\n");
31
36
  let headerParsed = false;
32
37
  let state = "top";
33
38
  let currentNode = null;