@chengchenccc/tui 0.1.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/dist/autocomplete.d.ts +56 -0
  2. package/dist/autocomplete.d.ts.map +1 -0
  3. package/dist/autocomplete.js +647 -0
  4. package/dist/components/box.d.ts +22 -0
  5. package/dist/components/box.d.ts.map +1 -0
  6. package/dist/components/box.js +103 -0
  7. package/dist/components/card.d.ts +33 -0
  8. package/dist/components/card.d.ts.map +1 -0
  9. package/dist/components/card.js +49 -0
  10. package/dist/components/editor.d.ts +257 -0
  11. package/dist/components/editor.d.ts.map +1 -0
  12. package/dist/components/editor.js +1980 -0
  13. package/dist/components/input.d.ts +37 -0
  14. package/dist/components/input.d.ts.map +1 -0
  15. package/dist/components/input.js +389 -0
  16. package/dist/components/loader.d.ts +33 -0
  17. package/dist/components/loader.d.ts.map +1 -0
  18. package/dist/components/loader.js +100 -0
  19. package/dist/components/markdown.d.ts +108 -0
  20. package/dist/components/markdown.d.ts.map +1 -0
  21. package/dist/components/markdown.js +847 -0
  22. package/dist/components/markdown.test.d.ts +2 -0
  23. package/dist/components/markdown.test.d.ts.map +1 -0
  24. package/dist/components/markdown.test.js +81 -0
  25. package/dist/components/output-block.d.ts +44 -0
  26. package/dist/components/output-block.d.ts.map +1 -0
  27. package/dist/components/output-block.js +131 -0
  28. package/dist/components/select-list.d.ts +50 -0
  29. package/dist/components/select-list.d.ts.map +1 -0
  30. package/dist/components/select-list.js +166 -0
  31. package/dist/components/spacer.d.ts +12 -0
  32. package/dist/components/spacer.d.ts.map +1 -0
  33. package/dist/components/spacer.js +22 -0
  34. package/dist/components/statusline.d.ts +30 -0
  35. package/dist/components/statusline.d.ts.map +1 -0
  36. package/dist/components/statusline.js +46 -0
  37. package/dist/components/text.d.ts +19 -0
  38. package/dist/components/text.d.ts.map +1 -0
  39. package/dist/components/text.js +90 -0
  40. package/dist/components/truncated-text.d.ts +13 -0
  41. package/dist/components/truncated-text.d.ts.map +1 -0
  42. package/dist/components/truncated-text.js +50 -0
  43. package/dist/editor-component.d.ts +39 -0
  44. package/dist/editor-component.d.ts.map +1 -0
  45. package/dist/editor-component.js +1 -0
  46. package/dist/fuzzy.d.ts +16 -0
  47. package/dist/fuzzy.d.ts.map +1 -0
  48. package/dist/fuzzy.js +109 -0
  49. package/dist/index.d.ts +25 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +36 -0
  52. package/dist/keybindings.d.ts +193 -0
  53. package/dist/keybindings.d.ts.map +1 -0
  54. package/dist/keybindings.js +191 -0
  55. package/dist/keys.d.ts +184 -0
  56. package/dist/keys.d.ts.map +1 -0
  57. package/dist/keys.js +1191 -0
  58. package/dist/kill-ring.d.ts +28 -0
  59. package/dist/kill-ring.d.ts.map +1 -0
  60. package/dist/kill-ring.js +43 -0
  61. package/dist/mermaid.d.ts +23 -0
  62. package/dist/mermaid.d.ts.map +1 -0
  63. package/dist/mermaid.js +77 -0
  64. package/dist/mouse.d.ts +40 -0
  65. package/dist/mouse.d.ts.map +1 -0
  66. package/dist/mouse.js +39 -0
  67. package/dist/mouse.test.d.ts +2 -0
  68. package/dist/mouse.test.d.ts.map +1 -0
  69. package/dist/mouse.test.js +36 -0
  70. package/dist/native-modifiers.d.ts +3 -0
  71. package/dist/native-modifiers.d.ts.map +1 -0
  72. package/dist/native-modifiers.js +52 -0
  73. package/dist/stdin-buffer.d.ts +50 -0
  74. package/dist/stdin-buffer.d.ts.map +1 -0
  75. package/dist/stdin-buffer.js +360 -0
  76. package/dist/terminal-colors.d.ts +10 -0
  77. package/dist/terminal-colors.d.ts.map +1 -0
  78. package/dist/terminal-colors.js +58 -0
  79. package/dist/terminal-image.d.ts +90 -0
  80. package/dist/terminal-image.d.ts.map +1 -0
  81. package/dist/terminal-image.js +375 -0
  82. package/dist/terminal.d.ts +110 -0
  83. package/dist/terminal.d.ts.map +1 -0
  84. package/dist/terminal.js +432 -0
  85. package/dist/tui-scrollback.test.d.ts +2 -0
  86. package/dist/tui-scrollback.test.d.ts.map +1 -0
  87. package/dist/tui-scrollback.test.js +51 -0
  88. package/dist/tui.d.ts +330 -0
  89. package/dist/tui.d.ts.map +1 -0
  90. package/dist/tui.js +1568 -0
  91. package/dist/undo-stack.d.ts +17 -0
  92. package/dist/undo-stack.d.ts.map +1 -0
  93. package/dist/undo-stack.js +24 -0
  94. package/dist/utils.d.ts +85 -0
  95. package/dist/utils.d.ts.map +1 -0
  96. package/dist/utils.js +1066 -0
  97. package/dist/vendor/mermaid-ascii/ascii/ansi.d.ts +42 -0
  98. package/dist/vendor/mermaid-ascii/ascii/ansi.d.ts.map +1 -0
  99. package/dist/vendor/mermaid-ascii/ascii/ansi.js +361 -0
  100. package/dist/vendor/mermaid-ascii/ascii/canvas.d.ts +90 -0
  101. package/dist/vendor/mermaid-ascii/ascii/canvas.d.ts.map +1 -0
  102. package/dist/vendor/mermaid-ascii/ascii/canvas.js +414 -0
  103. package/dist/vendor/mermaid-ascii/ascii/class-diagram.d.ts +8 -0
  104. package/dist/vendor/mermaid-ascii/ascii/class-diagram.d.ts.map +1 -0
  105. package/dist/vendor/mermaid-ascii/ascii/class-diagram.js +623 -0
  106. package/dist/vendor/mermaid-ascii/ascii/converter.d.ts +13 -0
  107. package/dist/vendor/mermaid-ascii/ascii/converter.d.ts.map +1 -0
  108. package/dist/vendor/mermaid-ascii/ascii/converter.js +233 -0
  109. package/dist/vendor/mermaid-ascii/ascii/draw.d.ts +67 -0
  110. package/dist/vendor/mermaid-ascii/ascii/draw.d.ts.map +1 -0
  111. package/dist/vendor/mermaid-ascii/ascii/draw.js +1313 -0
  112. package/dist/vendor/mermaid-ascii/ascii/edge-bundling.d.ts +49 -0
  113. package/dist/vendor/mermaid-ascii/ascii/edge-bundling.d.ts.map +1 -0
  114. package/dist/vendor/mermaid-ascii/ascii/edge-bundling.js +289 -0
  115. package/dist/vendor/mermaid-ascii/ascii/edge-routing.d.ts +44 -0
  116. package/dist/vendor/mermaid-ascii/ascii/edge-routing.d.ts.map +1 -0
  117. package/dist/vendor/mermaid-ascii/ascii/edge-routing.js +302 -0
  118. package/dist/vendor/mermaid-ascii/ascii/er-diagram.d.ts +8 -0
  119. package/dist/vendor/mermaid-ascii/ascii/er-diagram.d.ts.map +1 -0
  120. package/dist/vendor/mermaid-ascii/ascii/er-diagram.js +380 -0
  121. package/dist/vendor/mermaid-ascii/ascii/grid.d.ts +57 -0
  122. package/dist/vendor/mermaid-ascii/ascii/grid.d.ts.map +1 -0
  123. package/dist/vendor/mermaid-ascii/ascii/grid.js +516 -0
  124. package/dist/vendor/mermaid-ascii/ascii/index.d.ts +66 -0
  125. package/dist/vendor/mermaid-ascii/ascii/index.d.ts.map +1 -0
  126. package/dist/vendor/mermaid-ascii/ascii/index.js +133 -0
  127. package/dist/vendor/mermaid-ascii/ascii/multiline-utils.d.ts +28 -0
  128. package/dist/vendor/mermaid-ascii/ascii/multiline-utils.d.ts.map +1 -0
  129. package/dist/vendor/mermaid-ascii/ascii/multiline-utils.js +60 -0
  130. package/dist/vendor/mermaid-ascii/ascii/pathfinder.d.ts +18 -0
  131. package/dist/vendor/mermaid-ascii/ascii/pathfinder.d.ts.map +1 -0
  132. package/dist/vendor/mermaid-ascii/ascii/pathfinder.js +224 -0
  133. package/dist/vendor/mermaid-ascii/ascii/sequence.d.ts +8 -0
  134. package/dist/vendor/mermaid-ascii/ascii/sequence.d.ts.map +1 -0
  135. package/dist/vendor/mermaid-ascii/ascii/sequence.js +416 -0
  136. package/dist/vendor/mermaid-ascii/ascii/shapes/circle.d.ts +12 -0
  137. package/dist/vendor/mermaid-ascii/ascii/shapes/circle.d.ts.map +1 -0
  138. package/dist/vendor/mermaid-ascii/ascii/shapes/circle.js +22 -0
  139. package/dist/vendor/mermaid-ascii/ascii/shapes/corners.d.ts +35 -0
  140. package/dist/vendor/mermaid-ascii/ascii/shapes/corners.d.ts.map +1 -0
  141. package/dist/vendor/mermaid-ascii/ascii/shapes/corners.js +91 -0
  142. package/dist/vendor/mermaid-ascii/ascii/shapes/diamond.d.ts +12 -0
  143. package/dist/vendor/mermaid-ascii/ascii/shapes/diamond.d.ts.map +1 -0
  144. package/dist/vendor/mermaid-ascii/ascii/shapes/diamond.js +22 -0
  145. package/dist/vendor/mermaid-ascii/ascii/shapes/hexagon.d.ts +12 -0
  146. package/dist/vendor/mermaid-ascii/ascii/shapes/hexagon.d.ts.map +1 -0
  147. package/dist/vendor/mermaid-ascii/ascii/shapes/hexagon.js +22 -0
  148. package/dist/vendor/mermaid-ascii/ascii/shapes/index.d.ts +27 -0
  149. package/dist/vendor/mermaid-ascii/ascii/shapes/index.d.ts.map +1 -0
  150. package/dist/vendor/mermaid-ascii/ascii/shapes/index.js +66 -0
  151. package/dist/vendor/mermaid-ascii/ascii/shapes/rectangle.d.ts +32 -0
  152. package/dist/vendor/mermaid-ascii/ascii/shapes/rectangle.d.ts.map +1 -0
  153. package/dist/vendor/mermaid-ascii/ascii/shapes/rectangle.js +149 -0
  154. package/dist/vendor/mermaid-ascii/ascii/shapes/rounded.d.ts +12 -0
  155. package/dist/vendor/mermaid-ascii/ascii/shapes/rounded.d.ts.map +1 -0
  156. package/dist/vendor/mermaid-ascii/ascii/shapes/rounded.js +22 -0
  157. package/dist/vendor/mermaid-ascii/ascii/shapes/special.d.ts +60 -0
  158. package/dist/vendor/mermaid-ascii/ascii/shapes/special.d.ts.map +1 -0
  159. package/dist/vendor/mermaid-ascii/ascii/shapes/special.js +253 -0
  160. package/dist/vendor/mermaid-ascii/ascii/shapes/stadium.d.ts +18 -0
  161. package/dist/vendor/mermaid-ascii/ascii/shapes/stadium.d.ts.map +1 -0
  162. package/dist/vendor/mermaid-ascii/ascii/shapes/stadium.js +103 -0
  163. package/dist/vendor/mermaid-ascii/ascii/shapes/state.d.ts +31 -0
  164. package/dist/vendor/mermaid-ascii/ascii/shapes/state.d.ts.map +1 -0
  165. package/dist/vendor/mermaid-ascii/ascii/shapes/state.js +167 -0
  166. package/dist/vendor/mermaid-ascii/ascii/shapes/types.d.ts +56 -0
  167. package/dist/vendor/mermaid-ascii/ascii/shapes/types.d.ts.map +1 -0
  168. package/dist/vendor/mermaid-ascii/ascii/shapes/types.js +4 -0
  169. package/dist/vendor/mermaid-ascii/ascii/types.d.ts +207 -0
  170. package/dist/vendor/mermaid-ascii/ascii/types.d.ts.map +1 -0
  171. package/dist/vendor/mermaid-ascii/ascii/types.js +39 -0
  172. package/dist/vendor/mermaid-ascii/ascii/validate.d.ts +52 -0
  173. package/dist/vendor/mermaid-ascii/ascii/validate.d.ts.map +1 -0
  174. package/dist/vendor/mermaid-ascii/ascii/validate.js +97 -0
  175. package/dist/vendor/mermaid-ascii/ascii/xychart.d.ts +3 -0
  176. package/dist/vendor/mermaid-ascii/ascii/xychart.d.ts.map +1 -0
  177. package/dist/vendor/mermaid-ascii/ascii/xychart.js +719 -0
  178. package/dist/vendor/mermaid-ascii/class/parser.d.ts +7 -0
  179. package/dist/vendor/mermaid-ascii/class/parser.d.ts.map +1 -0
  180. package/dist/vendor/mermaid-ascii/class/parser.js +265 -0
  181. package/dist/vendor/mermaid-ascii/class/types.d.ts +103 -0
  182. package/dist/vendor/mermaid-ascii/class/types.d.ts.map +1 -0
  183. package/dist/vendor/mermaid-ascii/class/types.js +7 -0
  184. package/dist/vendor/mermaid-ascii/er/parser.d.ts +7 -0
  185. package/dist/vendor/mermaid-ascii/er/parser.d.ts.map +1 -0
  186. package/dist/vendor/mermaid-ascii/er/parser.js +162 -0
  187. package/dist/vendor/mermaid-ascii/er/types.d.ts +77 -0
  188. package/dist/vendor/mermaid-ascii/er/types.d.ts.map +1 -0
  189. package/dist/vendor/mermaid-ascii/er/types.js +7 -0
  190. package/dist/vendor/mermaid-ascii/index.d.ts +2 -0
  191. package/dist/vendor/mermaid-ascii/index.d.ts.map +1 -0
  192. package/dist/vendor/mermaid-ascii/index.js +13 -0
  193. package/dist/vendor/mermaid-ascii/multiline-utils.d.ts +10 -0
  194. package/dist/vendor/mermaid-ascii/multiline-utils.d.ts.map +1 -0
  195. package/dist/vendor/mermaid-ascii/multiline-utils.js +29 -0
  196. package/dist/vendor/mermaid-ascii/parser.d.ts +8 -0
  197. package/dist/vendor/mermaid-ascii/parser.d.ts.map +1 -0
  198. package/dist/vendor/mermaid-ascii/parser.js +558 -0
  199. package/dist/vendor/mermaid-ascii/sequence/parser.d.ts +7 -0
  200. package/dist/vendor/mermaid-ascii/sequence/parser.d.ts.map +1 -0
  201. package/dist/vendor/mermaid-ascii/sequence/parser.js +182 -0
  202. package/dist/vendor/mermaid-ascii/sequence/types.d.ts +131 -0
  203. package/dist/vendor/mermaid-ascii/sequence/types.d.ts.map +1 -0
  204. package/dist/vendor/mermaid-ascii/sequence/types.js +7 -0
  205. package/dist/vendor/mermaid-ascii/text-metrics.d.ts +24 -0
  206. package/dist/vendor/mermaid-ascii/text-metrics.d.ts.map +1 -0
  207. package/dist/vendor/mermaid-ascii/text-metrics.js +69 -0
  208. package/dist/vendor/mermaid-ascii/types.d.ts +115 -0
  209. package/dist/vendor/mermaid-ascii/types.d.ts.map +1 -0
  210. package/dist/vendor/mermaid-ascii/types.js +4 -0
  211. package/dist/vendor/mermaid-ascii/xychart/colors.d.ts +26 -0
  212. package/dist/vendor/mermaid-ascii/xychart/colors.d.ts.map +1 -0
  213. package/dist/vendor/mermaid-ascii/xychart/colors.js +145 -0
  214. package/dist/vendor/mermaid-ascii/xychart/parser.d.ts +7 -0
  215. package/dist/vendor/mermaid-ascii/xychart/parser.d.ts.map +1 -0
  216. package/dist/vendor/mermaid-ascii/xychart/parser.js +105 -0
  217. package/dist/vendor/mermaid-ascii/xychart/types.d.ts +146 -0
  218. package/dist/vendor/mermaid-ascii/xychart/types.d.ts.map +1 -0
  219. package/dist/vendor/mermaid-ascii/xychart/types.js +8 -0
  220. package/dist/virtual-terminal.d.ts +80 -0
  221. package/dist/virtual-terminal.d.ts.map +1 -0
  222. package/dist/virtual-terminal.js +284 -0
  223. package/dist/word-navigation.d.ts +25 -0
  224. package/dist/word-navigation.d.ts.map +1 -0
  225. package/dist/word-navigation.js +97 -0
  226. package/package.json +38 -0
@@ -0,0 +1,416 @@
1
+ // ============================================================================
2
+ // ASCII renderer — sequence diagrams
3
+ //
4
+ // Renders sequenceDiagram text to ASCII/Unicode art using a column-based layout.
5
+ // Each actor occupies a column with a vertical lifeline; messages are horizontal
6
+ // arrows between lifelines. Blocks (loop/alt/opt/par) wrap around message groups.
7
+ //
8
+ // Layout is fundamentally different from flowcharts — no grid or A* pathfinding.
9
+ // Instead: actors → columns, messages → rows, all positioned linearly.
10
+ // ============================================================================
11
+ import { parseSequenceDiagram } from "../sequence/parser.js";
12
+ import { mkCanvas, mkRoleCanvas, canvasToString, increaseSize, increaseRoleCanvasSize, setRole } from "./canvas.js";
13
+ import { splitLines, maxLineWidth, lineCount } from "./multiline-utils.js";
14
+ import { displayWidth, toCells, WIDE_PAD } from "../text-metrics.js";
15
+ /** Classify a box-drawing character as 'border' or 'text'. */
16
+ function classifyBoxChar(ch) {
17
+ if (/^[┌┐└┘├┤┬┴┼│─╭╮╰╯+\-|]$/.test(ch))
18
+ return 'border';
19
+ return 'text';
20
+ }
21
+ /**
22
+ * Render a Mermaid sequence diagram to ASCII/Unicode text.
23
+ *
24
+ * Pipeline: parse → layout (columns + rows) → draw onto canvas → string.
25
+ */
26
+ export function renderSequenceAscii(text, config, colorMode, theme) {
27
+ const lines = text.split('\n').map(l => l.trim()).filter(l => l.length > 0 && !l.startsWith('%%'));
28
+ const diagram = parseSequenceDiagram(lines);
29
+ if (diagram.actors.length === 0)
30
+ return '';
31
+ const useAscii = config.useAscii;
32
+ // Box-drawing characters
33
+ const H = useAscii ? '-' : '─';
34
+ const V = useAscii ? '|' : '│';
35
+ const TL = useAscii ? '+' : '┌';
36
+ const TR = useAscii ? '+' : '┐';
37
+ const BL = useAscii ? '+' : '└';
38
+ const BR = useAscii ? '+' : '┘';
39
+ const JT = useAscii ? '+' : '┬'; // top junction on lifeline
40
+ const JB = useAscii ? '+' : '┴'; // bottom junction on lifeline
41
+ const JL = useAscii ? '+' : '├'; // left junction
42
+ const JR = useAscii ? '+' : '┤'; // right junction
43
+ // ---- LAYOUT: compute lifeline X positions ----
44
+ const actorIdx = new Map();
45
+ diagram.actors.forEach((a, i) => actorIdx.set(a.id, i));
46
+ const boxPad = 1;
47
+ // Use max line width for multi-line actor labels
48
+ const actorBoxWidths = diagram.actors.map(a => maxLineWidth(a.label) + 2 * boxPad + 2);
49
+ const halfBox = actorBoxWidths.map(w => Math.ceil(w / 2));
50
+ // Calculate actor box heights based on number of lines in label
51
+ const actorBoxHeights = diagram.actors.map(a => lineCount(a.label) + 2); // lines + top/bottom border
52
+ const actorBoxH = Math.max(...actorBoxHeights, 3); // Use max height for consistent lifeline positioning
53
+ // Compute minimum gap between adjacent lifelines based on message labels.
54
+ // For messages spanning multiple actors, distribute the required width across gaps.
55
+ const adjMaxWidth = new Array(Math.max(diagram.actors.length - 1, 0)).fill(0);
56
+ for (const msg of diagram.messages) {
57
+ const fi = actorIdx.get(msg.from);
58
+ const ti = actorIdx.get(msg.to);
59
+ if (fi === ti)
60
+ continue; // self-messages don't affect spacing
61
+ const lo = Math.min(fi, ti);
62
+ const hi = Math.max(fi, ti);
63
+ // Required gap per span = (max line width + arrow decorations) / number of gaps
64
+ const needed = maxLineWidth(msg.label) + 4;
65
+ const numGaps = hi - lo;
66
+ const perGap = Math.ceil(needed / numGaps);
67
+ for (let g = lo; g < hi; g++) {
68
+ adjMaxWidth[g] = Math.max(adjMaxWidth[g], perGap);
69
+ }
70
+ }
71
+ // Compute lifeline x-positions (greedy left-to-right)
72
+ const llX = [halfBox[0]];
73
+ for (let i = 1; i < diagram.actors.length; i++) {
74
+ const gap = Math.max(halfBox[i - 1] + halfBox[i] + 2, adjMaxWidth[i - 1] + 2, 10);
75
+ llX[i] = llX[i - 1] + gap;
76
+ }
77
+ // ---- LAYOUT: compute vertical positions for messages ----
78
+ // For each message index, track the y where its arrow is drawn.
79
+ // Also track block start/end y positions and divider y positions.
80
+ const msgArrowY = [];
81
+ const msgLabelY = [];
82
+ const blockStartY = new Map();
83
+ const blockEndY = new Map();
84
+ const divYMap = new Map(); // "blockIdx:divIdx" → y
85
+ const notePositions = [];
86
+ let curY = actorBoxH; // start right below header boxes
87
+ for (let m = 0; m < diagram.messages.length; m++) {
88
+ // Block openings at this message
89
+ for (let b = 0; b < diagram.blocks.length; b++) {
90
+ if (diagram.blocks[b].startIndex === m) {
91
+ curY += 2; // 1 blank + 1 header row
92
+ blockStartY.set(b, curY - 1);
93
+ }
94
+ }
95
+ // Dividers at this message index
96
+ for (let b = 0; b < diagram.blocks.length; b++) {
97
+ for (let d = 0; d < diagram.blocks[b].dividers.length; d++) {
98
+ if (diagram.blocks[b].dividers[d].index === m) {
99
+ curY += 1;
100
+ divYMap.set(`${b}:${d}`, curY);
101
+ curY += 1;
102
+ }
103
+ }
104
+ }
105
+ curY += 1; // blank row before message
106
+ const msg = diagram.messages[m];
107
+ const isSelf = msg.from === msg.to;
108
+ // Calculate height needed for multi-line message labels
109
+ const msgLineCount = lineCount(msg.label);
110
+ if (isSelf) {
111
+ // Self-message occupies 3+ rows: top-arm, label-col(s), bottom-arm
112
+ msgLabelY[m] = curY + 1;
113
+ msgArrowY[m] = curY;
114
+ curY += 2 + msgLineCount; // top-arm + label lines + bottom-arm
115
+ }
116
+ else {
117
+ // Normal message: label row(s) then arrow row
118
+ msgLabelY[m] = curY;
119
+ msgArrowY[m] = curY + msgLineCount; // arrow goes after all label lines
120
+ curY += msgLineCount + 1; // label lines + arrow row
121
+ }
122
+ // Notes after this message
123
+ for (let n = 0; n < diagram.notes.length; n++) {
124
+ if (diagram.notes[n].afterIndex === m) {
125
+ curY += 1;
126
+ const note = diagram.notes[n];
127
+ const nLines = splitLines(note.text);
128
+ const nWidth = Math.max(...nLines.map(l => displayWidth(l))) + 4;
129
+ const nHeight = nLines.length + 2;
130
+ // Determine x position based on note.position
131
+ const aIdx = actorIdx.get(note.actorIds[0]) ?? 0;
132
+ let nx;
133
+ if (note.position === 'left') {
134
+ nx = llX[aIdx] - nWidth - 1;
135
+ }
136
+ else if (note.position === 'right') {
137
+ nx = llX[aIdx] + 2;
138
+ }
139
+ else {
140
+ // 'over' — center over actor(s)
141
+ if (note.actorIds.length >= 2) {
142
+ const aIdx2 = actorIdx.get(note.actorIds[1]) ?? aIdx;
143
+ nx = Math.floor((llX[aIdx] + llX[aIdx2]) / 2) - Math.floor(nWidth / 2);
144
+ }
145
+ else {
146
+ nx = llX[aIdx] - Math.floor(nWidth / 2);
147
+ }
148
+ }
149
+ nx = Math.max(0, nx);
150
+ notePositions.push({ x: nx, y: curY, width: nWidth, height: nHeight, lines: nLines });
151
+ curY += nHeight;
152
+ }
153
+ }
154
+ // Block closings after this message
155
+ for (let b = 0; b < diagram.blocks.length; b++) {
156
+ if (diagram.blocks[b].endIndex === m) {
157
+ curY += 1;
158
+ blockEndY.set(b, curY);
159
+ curY += 1;
160
+ }
161
+ }
162
+ }
163
+ curY += 1; // gap before footer
164
+ const footerY = curY;
165
+ const totalH = footerY + actorBoxH;
166
+ // Total canvas width
167
+ const lastLL = llX[llX.length - 1] ?? 0;
168
+ const lastHalf = halfBox[halfBox.length - 1] ?? 0;
169
+ let totalW = lastLL + lastHalf + 2;
170
+ // Ensure canvas is wide enough for self-message labels and notes
171
+ for (let m = 0; m < diagram.messages.length; m++) {
172
+ const msg = diagram.messages[m];
173
+ if (msg.from === msg.to) {
174
+ const fi = actorIdx.get(msg.from);
175
+ const selfRight = llX[fi] + 6 + 2 + displayWidth(msg.label);
176
+ totalW = Math.max(totalW, selfRight + 1);
177
+ }
178
+ }
179
+ for (const np of notePositions) {
180
+ totalW = Math.max(totalW, np.x + np.width + 1);
181
+ }
182
+ const canvas = mkCanvas(totalW, totalH - 1);
183
+ const rc = mkRoleCanvas(totalW, totalH - 1);
184
+ /** Set a character on the canvas and track its role. */
185
+ function setC(x, y, ch, role) {
186
+ if (x >= 0 && x < canvas.length && y >= 0 && y < (canvas[0]?.length ?? 0)) {
187
+ canvas[x][y] = ch;
188
+ setRole(rc, x, y, role);
189
+ }
190
+ }
191
+ /**
192
+ * Write label cells starting at x0, keeping wide-glyph pairs atomic:
193
+ * a glyph and its WIDE_PAD continuation land together or not at all,
194
+ * clamped to [minX, maxXExcl) and the canvas bounds.
195
+ */
196
+ function setCells(x0, y, cells, role, minX = 0, maxXExcl = canvas.length) {
197
+ const limit = Math.min(maxXExcl, canvas.length);
198
+ for (let i = 0; i < cells.length; i++) {
199
+ const cell = cells[i];
200
+ if (cell === WIDE_PAD)
201
+ continue; // written atomically with its lead
202
+ const x = x0 + i;
203
+ const wide = cells[i + 1] === WIDE_PAD;
204
+ if (x < minX || x + (wide ? 1 : 0) >= limit)
205
+ continue;
206
+ setC(x, y, cell, role);
207
+ if (wide)
208
+ setC(x + 1, y, WIDE_PAD, role);
209
+ }
210
+ }
211
+ // ---- DRAW: helper to place a bordered actor box (supports multi-line labels) ----
212
+ function drawActorBox(cx, topY, label) {
213
+ const lines = splitLines(label);
214
+ const maxW = maxLineWidth(label);
215
+ const w = maxW + 2 * boxPad + 2;
216
+ const h = lines.length + 2; // lines + top/bottom border
217
+ const left = cx - Math.floor(w / 2);
218
+ // Top border
219
+ setC(left, topY, TL, 'border');
220
+ for (let x = 1; x < w - 1; x++)
221
+ setC(left + x, topY, H, 'border');
222
+ setC(left + w - 1, topY, TR, 'border');
223
+ // Content lines (centered horizontally within the box)
224
+ for (let i = 0; i < lines.length; i++) {
225
+ const row = topY + 1 + i;
226
+ setC(left, row, V, 'border');
227
+ setC(left + w - 1, row, V, 'border');
228
+ // Center this line within the box
229
+ const line = lines[i];
230
+ const cells = toCells(line);
231
+ const ls = left + 1 + boxPad + Math.floor((maxW - cells.length) / 2);
232
+ setCells(ls, row, cells, 'text');
233
+ }
234
+ // Bottom border
235
+ const bottomY = topY + h - 1;
236
+ setC(left, bottomY, BL, 'border');
237
+ for (let x = 1; x < w - 1; x++)
238
+ setC(left + x, bottomY, H, 'border');
239
+ setC(left + w - 1, bottomY, BR, 'border');
240
+ }
241
+ // ---- DRAW: lifelines ----
242
+ for (let i = 0; i < diagram.actors.length; i++) {
243
+ const x = llX[i];
244
+ for (let y = actorBoxH; y <= footerY; y++) {
245
+ setC(x, y, V, 'line');
246
+ }
247
+ }
248
+ // ---- DRAW: actor header + footer boxes (drawn over lifelines) ----
249
+ for (let i = 0; i < diagram.actors.length; i++) {
250
+ const actor = diagram.actors[i];
251
+ drawActorBox(llX[i], 0, actor.label);
252
+ drawActorBox(llX[i], footerY, actor.label);
253
+ // Lifeline junctions on box borders (Unicode only)
254
+ if (!useAscii) {
255
+ setC(llX[i], actorBoxH - 1, JT, 'junction');
256
+ setC(llX[i], footerY, JB, 'junction');
257
+ }
258
+ }
259
+ // ---- DRAW: messages ----
260
+ for (let m = 0; m < diagram.messages.length; m++) {
261
+ const msg = diagram.messages[m];
262
+ const fi = actorIdx.get(msg.from);
263
+ const ti = actorIdx.get(msg.to);
264
+ const fromX = llX[fi];
265
+ const toX = llX[ti];
266
+ const isSelf = fi === ti;
267
+ const isDashed = msg.lineStyle === 'dashed';
268
+ const isFilled = msg.arrowHead === 'filled';
269
+ // Arrow line character (solid vs dashed)
270
+ const lineChar = isDashed ? (useAscii ? '.' : '╌') : H;
271
+ if (isSelf) {
272
+ // Self-message: 3-row loop to the right of the lifeline
273
+ // ├──┐ (row 0 = msgArrowY)
274
+ // │ │ Label (row 1)
275
+ // │◄─┘ (row 2)
276
+ const y0 = msgArrowY[m];
277
+ const loopW = Math.max(4, 4);
278
+ // Row 0: start junction + horizontal + top-right corner
279
+ setC(fromX, y0, JL, 'junction');
280
+ for (let x = fromX + 1; x < fromX + loopW; x++)
281
+ setC(x, y0, lineChar, 'line');
282
+ setC(fromX + loopW, y0, useAscii ? '+' : '┐', 'corner');
283
+ // Row 1: vertical on right side + label
284
+ setC(fromX + loopW, y0 + 1, V, 'line');
285
+ const labelX = fromX + loopW + 2;
286
+ const selfCells = toCells(msg.label);
287
+ setCells(labelX, y0 + 1, selfCells, 'text', 0, totalW);
288
+ // Row 2: arrow-back + horizontal + bottom-right corner
289
+ const arrowChar = isFilled ? (useAscii ? '<' : '◀') : (useAscii ? '<' : '◁');
290
+ setC(fromX, y0 + 2, arrowChar, 'arrow');
291
+ for (let x = fromX + 1; x < fromX + loopW; x++)
292
+ setC(x, y0 + 2, lineChar, 'line');
293
+ setC(fromX + loopW, y0 + 2, useAscii ? '+' : '┘', 'corner');
294
+ }
295
+ else {
296
+ // Normal message: label on row above, arrow on row below
297
+ const labelY = msgLabelY[m];
298
+ const arrowY = msgArrowY[m];
299
+ const leftToRight = fromX < toX;
300
+ // Draw label centered between the two lifelines (supports multi-line)
301
+ const midX = Math.floor((fromX + toX) / 2);
302
+ const msgLines = splitLines(msg.label);
303
+ for (let lineIdx = 0; lineIdx < msgLines.length; lineIdx++) {
304
+ const cells = toCells(msgLines[lineIdx]);
305
+ const labelStart = midX - Math.floor(cells.length / 2);
306
+ const y = labelY + lineIdx;
307
+ setCells(labelStart, y, cells, 'text', 0, totalW);
308
+ }
309
+ // Draw arrow line
310
+ if (leftToRight) {
311
+ for (let x = fromX + 1; x < toX; x++)
312
+ setC(x, arrowY, lineChar, 'line');
313
+ // Arrowhead at destination
314
+ const ah = isFilled ? (useAscii ? '>' : '▶') : (useAscii ? '>' : '▷');
315
+ setC(toX, arrowY, ah, 'arrow');
316
+ }
317
+ else {
318
+ for (let x = toX + 1; x < fromX; x++)
319
+ setC(x, arrowY, lineChar, 'line');
320
+ const ah = isFilled ? (useAscii ? '<' : '◀') : (useAscii ? '<' : '◁');
321
+ setC(toX, arrowY, ah, 'arrow');
322
+ }
323
+ }
324
+ }
325
+ // ---- DRAW: blocks (loop, alt, opt, par, etc.) ----
326
+ for (let b = 0; b < diagram.blocks.length; b++) {
327
+ const block = diagram.blocks[b];
328
+ const topY = blockStartY.get(b);
329
+ const botY = blockEndY.get(b);
330
+ if (topY === undefined || botY === undefined)
331
+ continue;
332
+ // Find the leftmost/rightmost lifelines involved in this block's messages
333
+ let minLX = totalW;
334
+ let maxLX = 0;
335
+ for (let m = block.startIndex; m <= block.endIndex; m++) {
336
+ if (m >= diagram.messages.length)
337
+ break;
338
+ const msg = diagram.messages[m];
339
+ const f = actorIdx.get(msg.from) ?? 0;
340
+ const t = actorIdx.get(msg.to) ?? 0;
341
+ minLX = Math.min(minLX, llX[Math.min(f, t)]);
342
+ maxLX = Math.max(maxLX, llX[Math.max(f, t)]);
343
+ }
344
+ const bLeft = Math.max(0, minLX - 4);
345
+ const bRight = Math.min(totalW - 1, maxLX + 4);
346
+ // Top border with block type label
347
+ setC(bLeft, topY, TL, 'border');
348
+ for (let x = bLeft + 1; x < bRight; x++)
349
+ setC(x, topY, H, 'border');
350
+ setC(bRight, topY, TR, 'border');
351
+ // Write block header label over the top border (supports multi-line)
352
+ const hdrLabel = block.label ? `${block.type} [${block.label}]` : block.type;
353
+ const hdrLines = splitLines(hdrLabel);
354
+ for (let lineIdx = 0; lineIdx < hdrLines.length && topY + lineIdx < botY; lineIdx++) {
355
+ const cells = toCells(hdrLines[lineIdx]);
356
+ setCells(bLeft + 1, topY + lineIdx, cells, 'text', bLeft + 1, bRight);
357
+ }
358
+ // Bottom border
359
+ setC(bLeft, botY, BL, 'border');
360
+ for (let x = bLeft + 1; x < bRight; x++)
361
+ setC(x, botY, H, 'border');
362
+ setC(bRight, botY, BR, 'border');
363
+ // Side borders
364
+ for (let y = topY + 1; y < botY; y++) {
365
+ setC(bLeft, y, V, 'border');
366
+ setC(bRight, y, V, 'border');
367
+ }
368
+ // Dividers
369
+ for (let d = 0; d < block.dividers.length; d++) {
370
+ const dY = divYMap.get(`${b}:${d}`);
371
+ if (dY === undefined)
372
+ continue;
373
+ const dashChar = isDashedH();
374
+ setC(bLeft, dY, JL, 'junction');
375
+ for (let x = bLeft + 1; x < bRight; x++)
376
+ setC(x, dY, dashChar, 'line');
377
+ setC(bRight, dY, JR, 'junction');
378
+ // Divider label
379
+ const dLabel = block.dividers[d].label;
380
+ if (dLabel) {
381
+ const dCells = toCells(`[${dLabel}]`);
382
+ setCells(bLeft + 1, dY, dCells, 'text', bLeft + 1, bRight);
383
+ }
384
+ }
385
+ }
386
+ // ---- DRAW: notes ----
387
+ for (const np of notePositions) {
388
+ // Ensure canvas is big enough
389
+ increaseSize(canvas, np.x + np.width, np.y + np.height);
390
+ increaseRoleCanvasSize(rc, np.x + np.width, np.y + np.height);
391
+ // Top border
392
+ setC(np.x, np.y, TL, 'border');
393
+ for (let x = 1; x < np.width - 1; x++)
394
+ setC(np.x + x, np.y, H, 'border');
395
+ setC(np.x + np.width - 1, np.y, TR, 'border');
396
+ // Content rows
397
+ for (let l = 0; l < np.lines.length; l++) {
398
+ const ly = np.y + 1 + l;
399
+ setC(np.x, ly, V, 'border');
400
+ setC(np.x + np.width - 1, ly, V, 'border');
401
+ const cells = toCells(np.lines[l]);
402
+ setCells(np.x + 2, ly, cells, 'text');
403
+ }
404
+ // Bottom border
405
+ const by = np.y + np.height - 1;
406
+ setC(np.x, by, BL, 'border');
407
+ for (let x = 1; x < np.width - 1; x++)
408
+ setC(np.x + x, by, H, 'border');
409
+ setC(np.x + np.width - 1, by, BR, 'border');
410
+ }
411
+ return canvasToString(canvas, { roleCanvas: rc, colorMode, theme });
412
+ // ---- Helper: dashed horizontal character ----
413
+ function isDashedH() {
414
+ return useAscii ? '-' : '╌';
415
+ }
416
+ }
@@ -0,0 +1,12 @@
1
+ import type { ShapeRenderer } from './types.ts';
2
+ /**
3
+ * Circle shape renderer.
4
+ * Uses circle markers (◯) at corners to indicate circular shape semantics.
5
+ *
6
+ * Renders as:
7
+ * ◯─────────◯
8
+ * │ Label │
9
+ * ◯─────────◯
10
+ */
11
+ export declare const circleRenderer: ShapeRenderer;
12
+ //# sourceMappingURL=circle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circle.d.ts","sourceRoot":"","sources":["../../../../../src/vendor/mermaid-ascii/ascii/shapes/circle.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAI/C;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,EAAE,aAS5B,CAAA"}
@@ -0,0 +1,22 @@
1
+ // ============================================================================
2
+ // Circle shape renderer — uses corner decorators instead of curves
3
+ // ============================================================================
4
+ import { getBoxDimensions, renderBox, getBoxAttachmentPoint } from "./rectangle.js";
5
+ import { getCorners } from "./corners.js";
6
+ /**
7
+ * Circle shape renderer.
8
+ * Uses circle markers (◯) at corners to indicate circular shape semantics.
9
+ *
10
+ * Renders as:
11
+ * ◯─────────◯
12
+ * │ Label │
13
+ * ◯─────────◯
14
+ */
15
+ export const circleRenderer = {
16
+ getDimensions: getBoxDimensions,
17
+ render(label, dimensions, options) {
18
+ const corners = getCorners('circle', options.useAscii);
19
+ return renderBox(label, dimensions, corners, options.useAscii);
20
+ },
21
+ getAttachmentPoint: getBoxAttachmentPoint,
22
+ };
@@ -0,0 +1,35 @@
1
+ import type { AsciiNodeShape } from '../types.ts';
2
+ /**
3
+ * Corner characters for a shape in both Unicode and ASCII modes.
4
+ */
5
+ export interface CornerChars {
6
+ /** Top-left corner */
7
+ tl: string;
8
+ /** Top-right corner */
9
+ tr: string;
10
+ /** Bottom-left corner */
11
+ bl: string;
12
+ /** Bottom-right corner */
13
+ br: string;
14
+ }
15
+ /**
16
+ * Shape corner configuration with both Unicode and ASCII variants.
17
+ */
18
+ export interface ShapeCorners {
19
+ unicode: CornerChars;
20
+ ascii: CornerChars;
21
+ }
22
+ /**
23
+ * Corner character lookup table for all shape types.
24
+ *
25
+ * Design principles:
26
+ * - All shapes use orthogonal box structure (no diagonals)
27
+ * - Corner characters indicate shape semantics
28
+ * - ASCII fallbacks use available punctuation
29
+ */
30
+ export declare const SHAPE_CORNERS: Record<AsciiNodeShape, ShapeCorners>;
31
+ /**
32
+ * Get corner characters for a shape type.
33
+ */
34
+ export declare function getCorners(shape: AsciiNodeShape, useAscii: boolean): CornerChars;
35
+ //# sourceMappingURL=corners.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corners.d.ts","sourceRoot":"","sources":["../../../../../src/vendor/mermaid-ascii/ascii/shapes/corners.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,sBAAsB;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,yBAAyB;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAA;CACX;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,WAAW,CAAA;IACpB,KAAK,EAAE,WAAW,CAAA;CACnB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,cAAc,EAAE,YAAY,CA8E9D,CAAA;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,GAAG,WAAW,CAGhF"}
@@ -0,0 +1,91 @@
1
+ // ============================================================================
2
+ // Corner character lookup table for shape rendering
3
+ // ============================================================================
4
+ //
5
+ // All shapes are rendered as rectangles with distinctive corner characters
6
+ // to indicate shape type. This eliminates diagonal characters while keeping
7
+ // shapes visually distinguishable.
8
+ /**
9
+ * Corner character lookup table for all shape types.
10
+ *
11
+ * Design principles:
12
+ * - All shapes use orthogonal box structure (no diagonals)
13
+ * - Corner characters indicate shape semantics
14
+ * - ASCII fallbacks use available punctuation
15
+ */
16
+ export const SHAPE_CORNERS = {
17
+ // Standard rectangular shapes
18
+ rectangle: {
19
+ unicode: { tl: '┌', tr: '┐', bl: '└', br: '┘' },
20
+ ascii: { tl: '+', tr: '+', bl: '+', br: '+' },
21
+ },
22
+ rounded: {
23
+ unicode: { tl: '╭', tr: '╮', bl: '╰', br: '╯' },
24
+ ascii: { tl: '.', tr: '.', bl: "'", br: "'" },
25
+ },
26
+ // Circular shapes - use circle markers at corners
27
+ circle: {
28
+ unicode: { tl: '◯', tr: '◯', bl: '◯', br: '◯' },
29
+ ascii: { tl: 'o', tr: 'o', bl: 'o', br: 'o' },
30
+ },
31
+ doublecircle: {
32
+ unicode: { tl: '◎', tr: '◎', bl: '◎', br: '◎' },
33
+ ascii: { tl: '@', tr: '@', bl: '@', br: '@' },
34
+ },
35
+ // Diamond - decision nodes
36
+ diamond: {
37
+ unicode: { tl: '◇', tr: '◇', bl: '◇', br: '◇' },
38
+ ascii: { tl: '<', tr: '>', bl: '<', br: '>' },
39
+ },
40
+ // Hexagon - process nodes (crop corners — monospace-safe, distinct from rectangle)
41
+ hexagon: {
42
+ unicode: { tl: '⌜', tr: '⌝', bl: '⌞', br: '⌟' },
43
+ ascii: { tl: '*', tr: '*', bl: '*', br: '*' },
44
+ },
45
+ // Stadium/pill shape
46
+ stadium: {
47
+ unicode: { tl: '(', tr: ')', bl: '(', br: ')' },
48
+ ascii: { tl: '(', tr: ')', bl: '(', br: ')' },
49
+ },
50
+ // Subroutine - double vertical bars
51
+ subroutine: {
52
+ unicode: { tl: '╟', tr: '╢', bl: '╟', br: '╢' },
53
+ ascii: { tl: '|', tr: '|', bl: '|', br: '|' },
54
+ },
55
+ // Cylinder/database
56
+ cylinder: {
57
+ unicode: { tl: '╭', tr: '╮', bl: '╰', br: '╯' },
58
+ ascii: { tl: '.', tr: '.', bl: "'", br: "'" },
59
+ },
60
+ // Asymmetric/flag - pointer on left side
61
+ asymmetric: {
62
+ unicode: { tl: '▷', tr: '┐', bl: '▷', br: '┘' },
63
+ ascii: { tl: '>', tr: '+', bl: '>', br: '+' },
64
+ },
65
+ // Trapezoid - wider at bottom (top corners slope inward)
66
+ trapezoid: {
67
+ unicode: { tl: '/', tr: '\\', bl: '└', br: '┘' },
68
+ ascii: { tl: '/', tr: '\\', bl: '+', br: '+' },
69
+ },
70
+ // Trapezoid-alt - wider at top (bottom corners slope inward)
71
+ 'trapezoid-alt': {
72
+ unicode: { tl: '┌', tr: '┐', bl: '\\', br: '/' },
73
+ ascii: { tl: '+', tr: '+', bl: '\\', br: '/' },
74
+ },
75
+ // State diagram pseudostates (special handling, not corner-based)
76
+ 'state-start': {
77
+ unicode: { tl: '●', tr: '●', bl: '●', br: '●' },
78
+ ascii: { tl: '*', tr: '*', bl: '*', br: '*' },
79
+ },
80
+ 'state-end': {
81
+ unicode: { tl: '◉', tr: '◉', bl: '◉', br: '◉' },
82
+ ascii: { tl: '@', tr: '@', bl: '@', br: '@' },
83
+ },
84
+ };
85
+ /**
86
+ * Get corner characters for a shape type.
87
+ */
88
+ export function getCorners(shape, useAscii) {
89
+ const corners = SHAPE_CORNERS[shape] ?? SHAPE_CORNERS.rectangle;
90
+ return useAscii ? corners.ascii : corners.unicode;
91
+ }
@@ -0,0 +1,12 @@
1
+ import type { ShapeRenderer } from './types.ts';
2
+ /**
3
+ * Diamond shape renderer.
4
+ * Uses diamond markers (◇) at corners to indicate decision node semantics.
5
+ *
6
+ * Renders as:
7
+ * ◇─────────◇
8
+ * │ Label │
9
+ * ◇─────────◇
10
+ */
11
+ export declare const diamondRenderer: ShapeRenderer;
12
+ //# sourceMappingURL=diamond.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diamond.d.ts","sourceRoot":"","sources":["../../../../../src/vendor/mermaid-ascii/ascii/shapes/diamond.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAI/C;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,EAAE,aAS7B,CAAA"}
@@ -0,0 +1,22 @@
1
+ // ============================================================================
2
+ // Diamond shape renderer — uses corner decorators instead of diagonals
3
+ // ============================================================================
4
+ import { getBoxDimensions, renderBox, getBoxAttachmentPoint } from "./rectangle.js";
5
+ import { getCorners } from "./corners.js";
6
+ /**
7
+ * Diamond shape renderer.
8
+ * Uses diamond markers (◇) at corners to indicate decision node semantics.
9
+ *
10
+ * Renders as:
11
+ * ◇─────────◇
12
+ * │ Label │
13
+ * ◇─────────◇
14
+ */
15
+ export const diamondRenderer = {
16
+ getDimensions: getBoxDimensions,
17
+ render(label, dimensions, options) {
18
+ const corners = getCorners('diamond', options.useAscii);
19
+ return renderBox(label, dimensions, corners, options.useAscii);
20
+ },
21
+ getAttachmentPoint: getBoxAttachmentPoint,
22
+ };
@@ -0,0 +1,12 @@
1
+ import type { ShapeRenderer } from './types.ts';
2
+ /**
3
+ * Hexagon shape renderer.
4
+ * Uses hexagon markers (⬡) at corners to indicate process node semantics.
5
+ *
6
+ * Renders as:
7
+ * ⬡─────────⬡
8
+ * │ Label │
9
+ * ⬡─────────⬡
10
+ */
11
+ export declare const hexagonRenderer: ShapeRenderer;
12
+ //# sourceMappingURL=hexagon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hexagon.d.ts","sourceRoot":"","sources":["../../../../../src/vendor/mermaid-ascii/ascii/shapes/hexagon.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAI/C;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,EAAE,aAS7B,CAAA"}
@@ -0,0 +1,22 @@
1
+ // ============================================================================
2
+ // Hexagon shape renderer — uses corner decorators instead of diagonals
3
+ // ============================================================================
4
+ import { getBoxDimensions, renderBox, getBoxAttachmentPoint } from "./rectangle.js";
5
+ import { getCorners } from "./corners.js";
6
+ /**
7
+ * Hexagon shape renderer.
8
+ * Uses hexagon markers (⬡) at corners to indicate process node semantics.
9
+ *
10
+ * Renders as:
11
+ * ⬡─────────⬡
12
+ * │ Label │
13
+ * ⬡─────────⬡
14
+ */
15
+ export const hexagonRenderer = {
16
+ getDimensions: getBoxDimensions,
17
+ render(label, dimensions, options) {
18
+ const corners = getCorners('hexagon', options.useAscii);
19
+ return renderBox(label, dimensions, corners, options.useAscii);
20
+ },
21
+ getAttachmentPoint: getBoxAttachmentPoint,
22
+ };