@diagrammo/dgmo 0.14.1 → 0.15.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 (71) hide show
  1. package/README.md +14 -1
  2. package/dist/advanced.cjs +53069 -0
  3. package/dist/advanced.d.cts +4691 -0
  4. package/dist/advanced.d.ts +4691 -0
  5. package/dist/advanced.js +52823 -0
  6. package/dist/auto.cjs +1557 -1295
  7. package/dist/auto.js +132 -713
  8. package/dist/auto.mjs +1553 -1291
  9. package/dist/cli.cjs +173 -150
  10. package/dist/editor.cjs +1 -0
  11. package/dist/editor.js +1 -0
  12. package/dist/highlight.cjs +1 -0
  13. package/dist/highlight.js +1 -0
  14. package/dist/index.cjs +2031 -4722
  15. package/dist/index.d.cts +96 -4464
  16. package/dist/index.d.ts +96 -4464
  17. package/dist/index.js +2024 -4475
  18. package/dist/internal.cjs +51930 -553
  19. package/dist/internal.d.cts +4526 -102
  20. package/dist/internal.d.ts +4526 -102
  21. package/dist/internal.js +51721 -548
  22. package/dist/pert.cjs +1 -1
  23. package/dist/pert.js +1 -1
  24. package/docs/language-reference.md +67 -17
  25. package/package.json +18 -3
  26. package/src/advanced.ts +731 -0
  27. package/src/auto/index.ts +14 -13
  28. package/src/boxes-and-lines/layout.ts +481 -445
  29. package/src/c4/parser.ts +7 -7
  30. package/src/chart-types.ts +0 -5
  31. package/src/class/parser.ts +1 -9
  32. package/src/cli.ts +9 -7
  33. package/src/completion-types.ts +28 -0
  34. package/src/completion.ts +15 -18
  35. package/src/cycle/layout.ts +2 -2
  36. package/src/d3.ts +1455 -1122
  37. package/src/echarts.ts +11 -11
  38. package/src/editor/keywords.ts +1 -0
  39. package/src/er/parser.ts +1 -9
  40. package/src/er/renderer.ts +1 -1
  41. package/src/gantt/calculator.ts +1 -11
  42. package/src/gantt/parser.ts +16 -16
  43. package/src/gantt/renderer.ts +2 -2
  44. package/src/graph/flowchart-parser.ts +1 -1
  45. package/src/graph/flowchart-renderer.ts +1 -1
  46. package/src/graph/state-renderer.ts +1 -1
  47. package/src/index.ts +213 -690
  48. package/src/infra/parser.ts +57 -25
  49. package/src/infra/renderer.ts +2 -2
  50. package/src/internal.ts +11 -17
  51. package/src/kanban/parser.ts +2 -2
  52. package/src/mindmap/layout.ts +1 -1
  53. package/src/mindmap/parser.ts +1 -1
  54. package/src/org/parser.ts +1 -1
  55. package/src/org/renderer.ts +1 -1
  56. package/src/palettes/index.ts +39 -0
  57. package/src/pert/layout.ts +1 -1
  58. package/src/pert/monte-carlo.ts +2 -2
  59. package/src/pert/parser.ts +3 -3
  60. package/src/raci/parser.ts +4 -4
  61. package/src/raci/renderer.ts +1 -1
  62. package/src/render.ts +17 -1
  63. package/src/sequence/renderer.ts +1 -4
  64. package/src/sitemap/parser.ts +1 -1
  65. package/src/tech-radar/interactive.ts +1 -1
  66. package/src/tech-radar/renderer.ts +1 -1
  67. package/src/themes.ts +22 -0
  68. package/src/utils/tag-groups.ts +11 -12
  69. package/src/wireframe/layout.ts +11 -7
  70. package/src/wireframe/parser.ts +2 -2
  71. package/src/wireframe/renderer.ts +5 -2
@@ -1,3 +1,8 @@
1
+ import { EChartsOption } from 'echarts';
2
+ import * as d3Selection from 'd3-selection';
3
+ import { Selection } from 'd3-selection';
4
+ import * as d3Scale from 'd3-scale';
5
+
1
6
  type DgmoSeverity = 'error' | 'warning';
2
7
  interface DgmoError {
3
8
  line: number;
@@ -11,7 +16,591 @@ interface DgmoError {
11
16
  */
12
17
  code?: string;
13
18
  }
19
+ declare function makeDgmoError(line: number, message: string, severity?: DgmoSeverity, code?: string): DgmoError;
20
+ declare function formatDgmoError(err: DgmoError): string;
21
+
22
+ /**
23
+ * Stable diagnostic codes for in-arrow label parsing errors.
24
+ *
25
+ * **Active codes** — emitted by the parser pipeline today:
26
+ * - `ARROW_SUBSTRING_IN_LABEL` (TD-13)
27
+ * - `CONTROL_CHAR_IN_LABEL` (TD-14)
28
+ *
29
+ * **Reserved codes** — declared but NOT currently emitted. These are
30
+ * placeholders for future tightening of the arrow-tokenization rules
31
+ * described in TD-9. Today's chart parsers catch these cases through
32
+ * their own regex machinery with different diagnostics. A follow-up
33
+ * spec that introduces a dedicated tokenizer can start emitting them
34
+ * without changing the public code shape:
35
+ * - `TRAILING_ARROW_TEXT` — extra `->`/`~>` after the primary arrow
36
+ * - `MIXED_ARROW_DELIMITERS` — opening delim type doesn't match arrow
37
+ *
38
+ * See `docs/dgmo-language-spec-decisions.md` → TD-16 for the rationale.
39
+ */
40
+ declare const ARROW_DIAGNOSTIC_CODES: {
41
+ /** Active: label contains `->` or `~>` substring (TD-13). */
42
+ readonly ARROW_SUBSTRING_IN_LABEL: "E_ARROW_SUBSTRING_IN_LABEL";
43
+ /** Active: label contains a forbidden control character (TD-14). */
44
+ readonly CONTROL_CHAR_IN_LABEL: "E_CONTROL_CHAR_IN_LABEL";
45
+ /** Reserved: not currently emitted by any parser. See JSDoc above. */
46
+ readonly TRAILING_ARROW_TEXT: "E_TRAILING_ARROW_TEXT";
47
+ /** Reserved: not currently emitted by any parser. See JSDoc above. */
48
+ readonly MIXED_ARROW_DELIMITERS: "E_MIXED_ARROW_DELIMITERS";
49
+ };
50
+ /**
51
+ * Validate an in-arrow label against the TD-13 and TD-14 character-set
52
+ * contract. Returns diagnostics (possibly empty). Does NOT mutate the label —
53
+ * callers that want a normalized label should trim before calling.
54
+ *
55
+ * TD-13: label must not contain the substrings "->" or "~>".
56
+ * TD-14: label must not contain C0 control chars other than tab, and no DEL.
57
+ */
58
+ declare function validateLabelCharacters(label: string, lineNumber: number): DgmoError[];
59
+ interface ParseInArrowLabelResult {
60
+ /** Cleaned label (trimmed; `undefined` if empty after trim per TD-10). */
61
+ label: string | undefined;
62
+ diagnostics: DgmoError[];
63
+ }
64
+ /**
65
+ * Normalize and validate a raw in-arrow label.
66
+ *
67
+ * Behavior:
68
+ * - Trims leading/trailing whitespace (TD-8: internal whitespace preserved).
69
+ * - Empty-after-trim → `{ label: undefined }` (TD-10 normalization).
70
+ * - TD-13: emits `E_ARROW_SUBSTRING_IN_LABEL` if `->` or `~>` is present.
71
+ * - TD-14: emits `E_CONTROL_CHAR_IN_LABEL` for forbidden control chars.
72
+ *
73
+ * This helper is intentionally chart-agnostic: it operates on an already
74
+ * extracted label string, leaving each chart's existing arrow-finding
75
+ * tokenization in place. TD-11 color-parens is handled inside the
76
+ * flowchart and state `parseArrowToken` functions because those are the
77
+ * only charts that interpret `-(color)->` as a colored edge; they use
78
+ * `matchColorParens()` from this module for the shared lookup.
79
+ */
80
+ declare function parseInArrowLabel(rawLabel: string, lineNumber: number): ParseInArrowLabelResult;
81
+ /**
82
+ * Test whether a string matches the TD-11 color-parens form `(colorName)`
83
+ * where `colorName` is one of the 11 recognized palette color names from
84
+ * `src/colors.ts:RECOGNIZED_COLOR_NAMES`. Returns the lowercase color name
85
+ * on a match, or `null` on fall-through (whole string becomes a label).
86
+ *
87
+ * Used by flowchart and state parsers to keep the color-parens recognition
88
+ * rule in one place — do NOT re-implement the regex in chart parsers.
89
+ */
90
+ declare function matchColorParens(content: string): string | null;
91
+
92
+ /**
93
+ * Compact view state schema (ADR-6).
94
+ * All fields optional. Only non-default values are encoded.
95
+ * `tag: null` means "user chose none"; absent `tag` means "use DSL default" (ADR-5).
96
+ */
97
+ interface CompactViewState {
98
+ tag?: string | null;
99
+ cs?: number[];
100
+ cg?: string[];
101
+ swim?: string | null;
102
+ cl?: string[];
103
+ cc?: string[];
104
+ rm?: string;
105
+ htv?: Record<string, string[]>;
106
+ ha?: string[];
107
+ sem?: boolean;
108
+ cm?: boolean;
109
+ c4l?: string;
110
+ c4s?: string;
111
+ c4c?: string;
112
+ rps?: number;
113
+ spd?: number;
114
+ io?: Record<string, number>;
115
+ hd?: boolean;
116
+ cbd?: boolean;
117
+ rq?: string;
118
+ an?: boolean;
119
+ fl?: boolean;
120
+ }
121
+ interface DecodedDiagramUrl {
122
+ dsl: string;
123
+ viewState: CompactViewState;
124
+ palette?: string;
125
+ theme?: 'light' | 'dark';
126
+ filename?: string;
127
+ }
128
+ interface EncodeDiagramUrlOptions {
129
+ baseUrl?: string;
130
+ viewState?: CompactViewState;
131
+ palette?: string;
132
+ theme?: 'light' | 'dark';
133
+ filename?: string;
134
+ }
135
+ type EncodeDiagramUrlResult = {
136
+ url: string;
137
+ error?: undefined;
138
+ } | {
139
+ url?: undefined;
140
+ error: 'too-large';
141
+ compressedSize: number;
142
+ limit: number;
143
+ };
144
+ /**
145
+ * Encode a CompactViewState to a compressed string for URL embedding.
146
+ * Returns empty string if state has no keys (ADR-4).
147
+ */
148
+ declare function encodeViewState(state: CompactViewState): string;
149
+ /**
150
+ * Decode a compressed view state string back to CompactViewState.
151
+ * Returns empty object on failure (no crash).
152
+ */
153
+ declare function decodeViewState(encoded: string): CompactViewState;
154
+ /**
155
+ * Compress a DGMO DSL string into a shareable URL.
156
+ * Returns `{ url }` on success, or `{ error: 'too-large', compressedSize, limit }` if the
157
+ * compressed payload exceeds the 8 KB limit.
158
+ */
159
+ declare function encodeDiagramUrl(dsl: string, options?: EncodeDiagramUrlOptions): EncodeDiagramUrlResult;
160
+ /**
161
+ * Decode a DGMO DSL string and view state from a URL query string or hash.
162
+ * Accepts any of:
163
+ * - `?dgmo=<payload>&vs=<state>`
164
+ * - `#dgmo=<payload>&vs=<state>` (backwards compat)
165
+ * - `dgmo=<payload>`
166
+ * - `<bare payload>`
167
+ *
168
+ * Returns `{ dsl, viewState }`. The DSL is empty string on invalid input.
169
+ */
170
+ declare function decodeDiagramUrl(hash: string): DecodedDiagramUrl;
171
+
172
+ /**
173
+ * Render DGMO source to an SVG string.
174
+ *
175
+ * Automatically detects the chart type, selects the appropriate renderer,
176
+ * and returns a complete SVG document string.
177
+ *
178
+ * @param content - DGMO source text
179
+ * @param options - Optional theme and palette settings
180
+ * @returns Object with `svg` (SVG string, empty on error) and `diagnostics` (parse errors/warnings)
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * import { render } from '@diagrammo/dgmo';
185
+ *
186
+ * const { svg, diagnostics } = await render(`pie Languages
187
+ * TypeScript: 45
188
+ * Python: 30
189
+ * Rust: 25`);
190
+ * ```
191
+ */
192
+ declare function render(content: string, options?: {
193
+ theme?: 'light' | 'dark' | 'transparent';
194
+ palette?: string;
195
+ c4Level?: 'context' | 'containers' | 'components' | 'deployment';
196
+ c4System?: string;
197
+ c4Container?: string;
198
+ tagGroup?: string;
199
+ /** Legend state for export — controls which tag group is shown in exported SVG. */
200
+ legendState?: {
201
+ activeGroup?: string;
202
+ hiddenAttributes?: string[];
203
+ };
204
+ /** View state for export — controls interactive state (collapse, swimlanes, etc.) */
205
+ viewState?: CompactViewState;
206
+ }): Promise<{
207
+ svg: string;
208
+ diagnostics: DgmoError[];
209
+ }>;
210
+
211
+ interface ChartTypeMeta {
212
+ readonly id: string;
213
+ readonly description: string;
214
+ readonly triggers: readonly string[];
215
+ readonly fallback?: true;
216
+ }
217
+ declare const chartTypes: readonly ChartTypeMeta[];
218
+
219
+ /** Normalize a string to lowercase ASCII-ish tokens for matching. */
220
+ declare function normalize(s: string): string[];
221
+ /**
222
+ * True if `triggerTokens` appears as a contiguous slice of `promptTokens`.
223
+ * Token-based (not substring) — prevents "scatter plot" matching "scattered
224
+ * the plot", "ER diagram" matching "water diagram", and similar traps.
225
+ */
226
+ declare function matchesContiguously(promptTokens: readonly string[], triggerTokens: readonly string[]): boolean;
227
+ interface ChartTypeScore {
228
+ readonly type: ChartTypeMeta;
229
+ readonly score: number;
230
+ readonly matched: string[];
231
+ }
232
+ /**
233
+ * Score a single chart type against a prompt.
234
+ *
235
+ * Primary signal: contiguous trigger-phrase matches weighted by token count
236
+ * (longer phrases beat shorter ones). Secondary signal: description-word
237
+ * overlap at 0.25× weight — a tiebreak-only hint that rescues prompts which
238
+ * miss every trigger but touch description vocabulary. Triggers always win
239
+ * over descriptions because any trigger match is ≥1.0 and descriptions
240
+ * contribute ≤0.25 per token.
241
+ */
242
+ declare function scoreChartType(prompt: string, type: ChartTypeMeta): {
243
+ score: number;
244
+ matched: string[];
245
+ };
246
+ /**
247
+ * Minimum trigger-based score for a confident match. A result below this
248
+ * floor means no actual trigger fired — only description-rescue tokens
249
+ * contributed — so the caller should drop to the fallback list instead of
250
+ * returning a confident-looking wrong answer.
251
+ *
252
+ * 1.0 is the weight of a single-token trigger. Anything less came entirely
253
+ * from 0.25× description hits.
254
+ */
255
+ declare const MIN_PRIMARY_SCORE = 1;
256
+ /**
257
+ * Minimum absolute score gap required before calling a match
258
+ * non-ambiguous. 0.5 ≈ two description-rescue tokens' worth, or half a
259
+ * trigger-token difference. Below this, the cliff between "medium" and
260
+ * "ambiguous" is effectively noise.
261
+ */
262
+ declare const AMBIGUITY_THRESHOLD = 0.5;
263
+ type Confidence = 'high' | 'medium' | 'ambiguous';
264
+ /**
265
+ * Confidence from the top two scores. Rules:
266
+ * 1. top < MIN_PRIMARY_SCORE → ambiguous (no real trigger matched)
267
+ * 2. second === 0 → high (nothing competes)
268
+ * 3. top ≥ 2 × second → high (top dominates)
269
+ * 4. top − second < AMBIGUITY_THRESHOLD → ambiguous (gap is noise)
270
+ * 5. otherwise → medium
271
+ */
272
+ declare function confidence(top: number, second: number): Confidence;
273
+ interface SuggestionResult {
274
+ readonly ranked: readonly ChartTypeScore[];
275
+ readonly fallback: readonly ChartTypeMeta[];
276
+ readonly confidence: Confidence;
277
+ readonly fellBack: boolean;
278
+ }
279
+ /**
280
+ * Score every chart type against `prompt` and return a ranked suggestion
281
+ * bundle. Types with score 0 are filtered out. When the top score is below
282
+ * `MIN_PRIMARY_SCORE` (no real trigger fired), the caller should present
283
+ * the fallback list — `fellBack` is set to true in that case.
284
+ *
285
+ * Array order is preserved: scoring iterates `chartTypes` in source order
286
+ * and `.sort` is stable in V8, so ties go to the earlier entry — specialized
287
+ * types beat generic catch-alls by construction.
288
+ */
289
+ declare function suggestChartTypes(prompt: string): SuggestionResult;
290
+
291
+ /**
292
+ * Extracts the chart type from raw file content.
293
+ * First tries the first non-empty, non-comment line as a bare chart type name
294
+ * (e.g., `gantt Product Launch`).
295
+ * Falls back to inference when no explicit chart type is found.
296
+ */
297
+ declare function parseDgmoChartType(content: string): string | null;
298
+ /** User-visible rendering category for dispatch and routing. */
299
+ type RenderCategory = 'data-chart' | 'visualization' | 'diagram';
300
+ /**
301
+ * Returns the render category for a given chart type, or `null` if unknown.
302
+ * Use this instead of the internal framework map for dispatch in consumers.
303
+ */
304
+ declare function getRenderCategory(chartType: string): RenderCategory | null;
305
+ /**
306
+ * Returns true if the chart type is an extended chart type
307
+ * handled by parseExtendedChart (scatter, sankey, chord, function, heatmap, funnel).
308
+ * Returns false for standard chart types and all other types.
309
+ */
310
+ declare function isExtendedChartType(chartType: string): boolean;
311
+ /**
312
+ * Returns all supported chart type identifiers in canonical (tier) order,
313
+ * derived from `chartTypes`. Consumers that need alphabetical order should
314
+ * call `.sort()` explicitly.
315
+ */
316
+ declare function getAllChartTypes(): string[];
317
+ /**
318
+ * Canonical descriptions for every supported chart type. Derived from
319
+ * `chartTypes` so there is exactly one place to update when adding a new
320
+ * type. Consumed by the CLI `--chart-types` flag, the editor autocomplete
321
+ * popup, and the MCP `list_chart_types` tool.
322
+ */
323
+ declare const CHART_TYPE_DESCRIPTIONS: Record<string, string>;
324
+ type ParseResult = {
325
+ diagnostics: DgmoError[];
326
+ };
327
+ type ParseFn = (content: string) => ParseResult;
328
+ /**
329
+ * Maps every chart-type id to the parser that handles it. Adding a new
330
+ * chart type means:
331
+ * 1. Add an entry here.
332
+ * 2. Add an entry to `chartTypes` in `chart-types.ts`.
333
+ *
334
+ * The `chart-types.test.ts` cross-check asserts both sets are identical;
335
+ * forgetting either side trips the test.
336
+ */
337
+ declare const chartTypeParsers: ReadonlyArray<readonly [string, ParseFn]>;
338
+ /** Ids in the same order as `chartTypeParsers`; used for cross-checks. */
339
+ declare const knownChartTypeIds: readonly string[];
340
+ /**
341
+ * Parse DGMO content and return diagnostics without rendering.
342
+ * Useful for the CLI and editor to surface all errors before attempting render.
343
+ */
344
+ declare function parseDgmo(content: string): {
345
+ diagnostics: DgmoError[];
346
+ chartType: string | null;
347
+ };
348
+
349
+ /**
350
+ * Color definitions for a single mode (light or dark).
351
+ * 10 semantic UI colors + 9 named accent colors = 19 total.
352
+ */
353
+ interface PaletteColors {
354
+ /** Main background (#eceff4 light / #2e3440 dark for Nord) */
355
+ bg: string;
356
+ /** Cards, panels (#e5e9f0 / #3b4252) */
357
+ surface: string;
358
+ /** Popovers, dropdowns (#e5e9f0 / #434c5e) */
359
+ overlay: string;
360
+ /** Borders, dividers, muted (#d8dee9 / #4c566a) */
361
+ border: string;
362
+ /** Primary text (#2e3440 / #eceff4) */
363
+ text: string;
364
+ /** Secondary/diminished text (#4c566a / #d8dee9) */
365
+ textMuted: string;
366
+ /**
367
+ * Light-mode arg for `contrastText()` when text is rendered on a
368
+ * tinted shape fill (e.g. `shapeFill()` output). Must guarantee
369
+ * ≥ 4.5:1 WCAG AA against any `shapeFill()` the palette can produce.
370
+ * Distinct from `colors.white` because palette-aesthetic anchors don't
371
+ * always meet contrast requirements (TD-5).
372
+ */
373
+ textOnFillLight: string;
374
+ /** Dark-mode counterpart to `textOnFillLight`. */
375
+ textOnFillDark: string;
376
+ /** Primary accent — buttons, links */
377
+ primary: string;
378
+ /** Secondary accent */
379
+ secondary: string;
380
+ /** Tertiary accent */
381
+ accent: string;
382
+ /** Error/danger */
383
+ destructive: string;
384
+ /**
385
+ * Used for: inline annotations (red), pie charts, cScale,
386
+ * series rotation, journey actors, Gantt tasks.
387
+ */
388
+ colors: {
389
+ red: string;
390
+ orange: string;
391
+ yellow: string;
392
+ green: string;
393
+ blue: string;
394
+ purple: string;
395
+ teal: string;
396
+ cyan: string;
397
+ gray: string;
398
+ black: string;
399
+ white: string;
400
+ };
401
+ }
402
+ /**
403
+ * Complete palette definition. One object per color scheme.
404
+ * This is what palette authors create — the single artifact for NFR1.
405
+ */
406
+ interface PaletteConfig {
407
+ /** Registry key: 'nord', 'solarized', 'catppuccin' */
408
+ id: string;
409
+ /** Display name: 'Nord', 'Solarized', 'Catppuccin' */
410
+ name: string;
411
+ /** Light mode color definitions */
412
+ light: PaletteColors;
413
+ /** Dark mode color definitions */
414
+ dark: PaletteColors;
415
+ }
416
+
417
+ /** Validate that a hex string is well-formed (#RGB or #RRGGBB). */
418
+ declare function isValidHex(value: string): boolean;
419
+ /**
420
+ * Register a palette. Called at module initialization.
421
+ * Validates that all 19 color fields per mode are present and valid hex.
422
+ * Throws on malformed palettes to catch errors at startup, not at render time.
423
+ */
424
+ declare function registerPalette(palette: PaletteConfig): void;
425
+ /** Get palette by id. Returns Nord if id is unrecognized (FR10). */
426
+ declare function getPalette(id: string): PaletteConfig;
427
+ /** List all registered palettes alphabetically (for the selector UI). */
428
+ declare function getAvailablePalettes(): PaletteConfig[];
429
+
430
+ /** Convert hex (#RRGGBB or #RGB) to { h, s, l } with h in degrees, s/l as percentages. */
431
+ declare function hexToHSL(hex: string): {
432
+ h: number;
433
+ s: number;
434
+ l: number;
435
+ };
436
+ /** Convert { h (degrees), s (%), l (%) } back to #RRGGBB hex string. */
437
+ declare function hslToHex(h: number, s: number, l: number): string;
438
+ /** Convert hex to "H S% L%" string for CSS custom properties. */
439
+ declare function hexToHSLString(hex: string): string;
440
+ /**
441
+ * Blend a color toward white (light mode quadrant fills).
442
+ * amount: 0 = original, 1 = white
443
+ */
444
+ declare function tint(hex: string, amount: number): string;
445
+ /**
446
+ * Blend a color toward a dark base (dark mode quadrant fills).
447
+ * amount: 0 = original, 1 = base
448
+ */
449
+ declare function shade(hex: string, base: string, amount: number): string;
450
+ /**
451
+ * Blend two hex colors by percentage.
452
+ * `pct` = 0 → 100% of `b`, `pct` = 100 → 100% of `a`.
453
+ *
454
+ * Used by all renderers for tinted fills and strokes.
455
+ */
456
+ declare function mix(a: string, b: string, pct: number): string;
457
+ /**
458
+ * Pick `lightText` or `darkText` for placement on top of `bg`.
459
+ *
460
+ * Three-tier decision:
461
+ * 1. **High-luminance fill (luminance > 0.55)** → `darkText`. Yellows, peaches,
462
+ * light cyans — dark text reads better and a light cream on light yellow is
463
+ * unreadable.
464
+ * 2. **Pastel fill (min RGB channel ≥ 100, luminance ≤ 0.55)** → defer to WCAG
465
+ * ratio. Pastels have no near-zero channel and tend to read as "soft" —
466
+ * dark text usually wins by ratio (catppuccin dark mauve `#cba6f7` min 166,
467
+ * ratio 9.35:1; tokyo-night dark red `#f7768e` min 118, ratio 7.86:1; and
468
+ * tokyo-night green `#9ece6a` min 106, ratio 11.4:1 all correctly pick dark).
469
+ * 3. **Saturated fill (min RGB < 100, luminance ≤ 0.55)** → `lightText`. At least
470
+ * one channel near zero signals true saturation — gruvbox dark green
471
+ * `#b8bb26` (min 38), one-dark blue `#4078f2` (min 64), bold red/blue
472
+ * (min 0), solarized blue `#268bd2` (min 38). The user consistently
473
+ * prefers light text on these for visual punch.
474
+ *
475
+ * `min RGB` discriminates pastel-vs-saturated more reliably than `max-min`
476
+ * (vibrance): tokyo-night and catppuccin dark are pastels with high max RGB,
477
+ * so vibrance alone misclassifies them as "saturated."
478
+ *
479
+ * Tinted fills (luminance ~0.7+ in light themes / ~0.02–0.14 in dark themes)
480
+ * are unambiguous in either branch; only solid-fill output shifts here.
481
+ */
482
+ declare function contrastText(bg: string, lightText: string, darkText: string): string;
483
+ /**
484
+ * Canonical tinted shape fill: 25% intent color + 75% surface.
485
+ * Use for any "tinted intent shape" — graph nodes, kanban cards,
486
+ * journey-map shapes, infra severity, ECharts pie/funnel/bar/etc.
487
+ *
488
+ * NOT for subtle-neutral shapes (use the existing 5-10% inline formula
489
+ * for "recede when no intent" cases — infra normal-state, untagged
490
+ * boxes, no-color sequence participants).
491
+ *
492
+ * Sankey is the only documented exception (75/45% custom desaturation).
493
+ *
494
+ * `opts.solid` (per `option solid-fill`): bypass the 25% tint and return
495
+ * the raw intent. Opt-in only; default behavior unchanged.
496
+ */
497
+ declare function shapeFill(palette: PaletteColors, intent: string, isDark: boolean, opts?: {
498
+ solid?: boolean;
499
+ }): string;
500
+ /** Derive the 8-color series rotation from a palette's named colors. */
501
+ declare function getSeriesColors(palette: PaletteColors): string[];
502
+
503
+ declare const boldPalette: PaletteConfig;
504
+
505
+ declare const catppuccinPalette: PaletteConfig;
506
+
507
+ declare const gruvboxPalette: PaletteConfig;
508
+
509
+ declare const nordPalette: PaletteConfig;
510
+
511
+ declare const oneDarkPalette: PaletteConfig;
512
+
513
+ declare const rosePinePalette: PaletteConfig;
514
+
515
+ declare const solarizedPalette: PaletteConfig;
516
+
517
+ declare const tokyoNightPalette: PaletteConfig;
518
+
519
+ declare const draculaPalette: PaletteConfig;
520
+
521
+ declare const monokaiPalette: PaletteConfig;
522
+
523
+ /**
524
+ * All built-in palettes, keyed by camelCase id. Use directly with render():
525
+ *
526
+ * await render(text, { palette: palettes.catppuccin });
527
+ *
528
+ * For preference/settings storage, the `.id` field of each entry is the
529
+ * canonical string (e.g. `'tokyo-night'`, `'nord'`) — that's the wire format
530
+ * used by share URLs and the CLI `--palette` flag.
531
+ */
532
+ declare const palettes: {
533
+ readonly nord: PaletteConfig;
534
+ readonly catppuccin: PaletteConfig;
535
+ readonly solarized: PaletteConfig;
536
+ readonly gruvbox: PaletteConfig;
537
+ readonly tokyoNight: PaletteConfig;
538
+ readonly oneDark: PaletteConfig;
539
+ readonly rosePine: PaletteConfig;
540
+ readonly dracula: PaletteConfig;
541
+ readonly monokai: PaletteConfig;
542
+ readonly bold: PaletteConfig;
543
+ };
544
+
545
+ type ChartType$1 = 'bar' | 'line' | 'pie' | 'doughnut' | 'area' | 'polar-area' | 'radar' | 'bar-stacked';
546
+ interface ChartDataPoint {
547
+ label: string;
548
+ value: number;
549
+ extraValues?: number[];
550
+ color?: string;
551
+ lineNumber: number;
552
+ }
553
+ interface ChartEra {
554
+ start: string;
555
+ end: string;
556
+ label: string;
557
+ color: string | null;
558
+ lineNumber: number;
559
+ }
560
+
561
+ interface ParsedChart {
562
+ type: ChartType$1;
563
+ title?: string;
564
+ titleLineNumber?: number;
565
+ series?: string;
566
+ seriesLineNumber?: number;
567
+ xlabel?: string;
568
+ xlabelLineNumber?: number;
569
+ ylabel?: string;
570
+ ylabelLineNumber?: number;
571
+ seriesNames?: string[];
572
+ seriesNameLineNumbers?: number[];
573
+ seriesNameColors?: (string | undefined)[];
574
+ orientation?: 'horizontal' | 'vertical';
575
+ color?: string;
576
+ label?: string;
577
+ noName?: boolean;
578
+ noValue?: boolean;
579
+ noPercent?: boolean;
580
+ /** Render with full intent saturation instead of the canonical 25% tint. */
581
+ solidFill?: boolean;
582
+ /** Cross-chart-type: when true, the renderer suppresses the chart title. */
583
+ noTitle?: boolean;
584
+ data: ChartDataPoint[];
585
+ eras?: ChartEra[];
586
+ diagnostics: DgmoError[];
587
+ error: string | null;
588
+ }
14
589
 
590
+ /**
591
+ * Parses the simple chart text format into a structured object.
592
+ *
593
+ * Format (colon-free):
594
+ * ```
595
+ * bar My Chart
596
+ * series Revenue
597
+ *
598
+ * Jan 120
599
+ * Feb 200
600
+ * Mar 150
601
+ * ```
602
+ */
603
+ declare function parseChart(content: string, palette?: PaletteColors): ParsedChart;
15
604
  /**
16
605
  * Parse a data row line: everything before the last numeric token(s) is the label,
17
606
  * numeric tokens at the end are the values. Supports comma-separated multi-values,
@@ -35,6 +624,352 @@ declare function parseDataRowValues(line: string, options?: {
35
624
  values: number[];
36
625
  } | null;
37
626
 
627
+ interface LegendState {
628
+ activeGroup: string | null;
629
+ hiddenAttributes?: Set<string>;
630
+ controlsExpanded?: boolean;
631
+ }
632
+ interface LegendCallbacks {
633
+ onGroupToggle?: (groupName: string) => void;
634
+ onVisibilityToggle?: (attribute: string) => void;
635
+ onStateChange?: (newState: LegendState) => void;
636
+ /** Called when an entry is hovered. Chart renderers can use this for cross-element highlighting. */
637
+ onEntryHover?: (groupName: string, entryValue: string | null) => void;
638
+ /** Called after each group <g> is rendered — lets chart renderers inject custom elements (swimlane icons, etc.) */
639
+ onGroupRendered?: (groupName: string, groupEl: D3Sel, isActive: boolean) => void;
640
+ /** Called when the controls group gear pill is clicked (expand/collapse) */
641
+ onControlsExpand?: () => void;
642
+ /** Called when a controls group toggle entry is clicked */
643
+ onControlsToggle?: (toggleId: string, active: boolean) => void;
644
+ }
645
+ interface LegendPosition {
646
+ placement: 'top-center';
647
+ titleRelation: 'below-title' | 'inline-with-title';
648
+ }
649
+ type LegendMode = 'fixed' | 'inline';
650
+ type LegendControlExportBehavior = 'include' | 'strip' | 'static';
651
+ interface LegendControl {
652
+ id: string;
653
+ /** SVG markup for the control icon, or a string label */
654
+ icon: string;
655
+ label?: string;
656
+ exportBehavior: LegendControlExportBehavior;
657
+ onClick?: () => void;
658
+ children?: LegendControlEntry[];
659
+ }
660
+ interface LegendControlEntry {
661
+ id: string;
662
+ label: string;
663
+ isActive?: boolean;
664
+ onClick?: () => void;
665
+ }
666
+ interface ControlsGroupToggle {
667
+ id: string;
668
+ /** Only 'toggle' is implemented in v1. 'select' and 'action' future-proof for Infra playback etc. */
669
+ type: 'toggle' | 'select' | 'action';
670
+ label: string;
671
+ active: boolean;
672
+ onToggle: (active: boolean) => void;
673
+ }
674
+ interface ControlsGroupConfig {
675
+ toggles: ControlsGroupToggle[];
676
+ }
677
+ interface LegendConfig {
678
+ groups: LegendGroupData[];
679
+ position: LegendPosition;
680
+ controls?: LegendControl[];
681
+ controlsGroup?: ControlsGroupConfig;
682
+ mode: LegendMode;
683
+ /** Title width in pixels — used for inline-with-title computation */
684
+ titleWidth?: number;
685
+ /** Extra width (px) reserved after the pill inside an active capsule (e.g. for eye icon addon). Entries start after this offset. */
686
+ capsulePillAddonWidth?: number;
687
+ /** When true, groups with no entries are still rendered as collapsed pills. Default: false (empty groups hidden). */
688
+ showEmptyGroups?: boolean;
689
+ }
690
+ interface LegendPalette {
691
+ bg: string;
692
+ surface: string;
693
+ text: string;
694
+ textMuted: string;
695
+ primary?: string;
696
+ }
697
+ interface LegendPillLayout {
698
+ groupName: string;
699
+ x: number;
700
+ y: number;
701
+ width: number;
702
+ height: number;
703
+ isActive: boolean;
704
+ }
705
+ interface LegendEntryLayout {
706
+ value: string;
707
+ color: string;
708
+ x: number;
709
+ y: number;
710
+ dotCx: number;
711
+ dotCy: number;
712
+ textX: number;
713
+ textY: number;
714
+ }
715
+ interface LegendCapsuleLayout {
716
+ groupName: string;
717
+ x: number;
718
+ y: number;
719
+ width: number;
720
+ height: number;
721
+ pill: LegendPillLayout;
722
+ entries: LegendEntryLayout[];
723
+ /** Overflow indicator when entries exceed max rows */
724
+ moreCount?: number;
725
+ /** X offset where addon content (e.g. eye icon) can be placed — after pill, before entries */
726
+ addonX?: number;
727
+ }
728
+ interface LegendControlLayout {
729
+ id: string;
730
+ x: number;
731
+ y: number;
732
+ width: number;
733
+ height: number;
734
+ icon: string;
735
+ label?: string;
736
+ exportBehavior: LegendControlExportBehavior;
737
+ children?: Array<{
738
+ id: string;
739
+ label: string;
740
+ x: number;
741
+ y: number;
742
+ width: number;
743
+ isActive?: boolean;
744
+ }>;
745
+ }
746
+ interface ControlsGroupToggleLayout {
747
+ id: string;
748
+ label: string;
749
+ active: boolean;
750
+ dotCx: number;
751
+ dotCy: number;
752
+ textX: number;
753
+ textY: number;
754
+ }
755
+ interface ControlsGroupLayout {
756
+ x: number;
757
+ y: number;
758
+ width: number;
759
+ height: number;
760
+ expanded: boolean;
761
+ /** The gear pill layout (collapsed or inside capsule) */
762
+ pill: {
763
+ x: number;
764
+ y: number;
765
+ width: number;
766
+ height: number;
767
+ };
768
+ /** Toggle entries (only present when expanded) */
769
+ toggles: ControlsGroupToggleLayout[];
770
+ }
771
+ interface LegendRowLayout {
772
+ y: number;
773
+ items: Array<LegendPillLayout | LegendCapsuleLayout | LegendControlLayout>;
774
+ }
775
+ interface LegendLayout {
776
+ /** Total computed height including all rows */
777
+ height: number;
778
+ /** Total computed width */
779
+ width: number;
780
+ /** Rows of legend elements (pills wrap to new rows on overflow) */
781
+ rows: LegendRowLayout[];
782
+ /** Active capsule layout (if any group is active) */
783
+ activeCapsule?: LegendCapsuleLayout;
784
+ /** Control layouts (right-aligned) */
785
+ controls: LegendControlLayout[];
786
+ /** All pill layouts (collapsed groups) */
787
+ pills: LegendPillLayout[];
788
+ /** Controls group layout (gear pill / capsule) */
789
+ controlsGroup?: ControlsGroupLayout;
790
+ }
791
+ interface LegendHandle {
792
+ setState: (state: LegendState) => void;
793
+ destroy: () => void;
794
+ getHeight: () => number;
795
+ getLayout: () => LegendLayout;
796
+ }
797
+ type D3Sel = Selection<any, unknown, any, unknown>;
798
+
799
+ interface LegendGroupData {
800
+ name: string;
801
+ entries: Array<{
802
+ value: string;
803
+ color: string;
804
+ }>;
805
+ }
806
+ interface LegendRenderOptions {
807
+ palette: {
808
+ bg: string;
809
+ surface: string;
810
+ text: string;
811
+ textMuted: string;
812
+ };
813
+ isDark: boolean;
814
+ containerWidth: number;
815
+ /** Grid left offset as percentage (e.g. 12 for '12%'). Centers legend over plot area. */
816
+ gridLeftPct?: number;
817
+ /** Grid right offset as percentage (e.g. 4 for '4%'). Centers legend over plot area. */
818
+ gridRightPct?: number;
819
+ activeGroup?: string | null;
820
+ className?: string;
821
+ }
822
+ interface LegendRenderResult {
823
+ svg: string;
824
+ height: number;
825
+ /** Natural content width (px). Callers can use this for CSS-based centering. */
826
+ width: number;
827
+ }
828
+ declare function renderLegendSvg(groups: LegendGroupData[], options: LegendRenderOptions): LegendRenderResult;
829
+ declare function renderLegendSvgFromConfig(config: LegendConfig, state: LegendState, palette: LegendPalette & {
830
+ isDark: boolean;
831
+ }, containerWidth: number): LegendRenderResult;
832
+
833
+ type ExtendedChartType = 'sankey' | 'chord' | 'function' | 'scatter' | 'heatmap' | 'funnel';
834
+ interface ExtendedChartDataPoint {
835
+ label: string;
836
+ value: number;
837
+ color?: string;
838
+ lineNumber: number;
839
+ }
840
+ interface ParsedSankeyLink {
841
+ source: string;
842
+ target: string;
843
+ value: number;
844
+ color?: string;
845
+ directed?: boolean;
846
+ lineNumber: number;
847
+ }
848
+ interface ParsedFunction {
849
+ name: string;
850
+ expression: string;
851
+ color?: string;
852
+ lineNumber: number;
853
+ }
854
+ interface ParsedScatterPoint {
855
+ name: string;
856
+ x: number;
857
+ y: number;
858
+ size?: number;
859
+ color?: string;
860
+ category?: string;
861
+ lineNumber: number;
862
+ }
863
+ interface ParsedHeatmapRow {
864
+ label: string;
865
+ values: number[];
866
+ lineNumber: number;
867
+ }
868
+
869
+ interface ParsedExtendedChart {
870
+ type: ExtendedChartType;
871
+ title?: string;
872
+ titleLineNumber?: number;
873
+ series?: string;
874
+ seriesLineNumber?: number;
875
+ seriesNames?: string[];
876
+ seriesNameLineNumbers?: number[];
877
+ seriesNameColors?: (string | undefined)[];
878
+ data: ExtendedChartDataPoint[];
879
+ links?: ParsedSankeyLink[];
880
+ functions?: ParsedFunction[];
881
+ scatterPoints?: ParsedScatterPoint[];
882
+ heatmapRows?: ParsedHeatmapRow[];
883
+ columns?: string[];
884
+ rows?: string[];
885
+ xRange?: {
886
+ min: number;
887
+ max: number;
888
+ };
889
+ xlabel?: string;
890
+ xlabelLineNumber?: number;
891
+ ylabel?: string;
892
+ ylabelLineNumber?: number;
893
+ sizelabel?: string;
894
+ noName?: boolean;
895
+ noValue?: boolean;
896
+ noPercent?: boolean;
897
+ shade?: boolean;
898
+ /** Render with full intent saturation instead of the canonical 25% tint. */
899
+ solidFill?: boolean;
900
+ /** Cross-chart-type: when true, the renderer suppresses the chart title. */
901
+ noTitle?: boolean;
902
+ categoryColors?: Record<string, string>;
903
+ categoryLineNumbers?: Record<string, number>;
904
+ nodeColors?: Record<string, string>;
905
+ diagnostics: DgmoError[];
906
+ error: string | null;
907
+ }
908
+
909
+ /**
910
+ * Parses extended chart content into a structured object.
911
+ *
912
+ * Format (colon-free):
913
+ * ```
914
+ * scatter My Chart
915
+ * xlabel Weight
916
+ *
917
+ * Alice 165, 60
918
+ * Bob 180, 85
919
+ * ```
920
+ */
921
+ declare function parseExtendedChart(content: string, palette?: PaletteColors): ParsedExtendedChart;
922
+ /**
923
+ * Converts a ParsedExtendedChart into an EChartsOption.
924
+ * Handles extended chart types: scatter, sankey, chord, function, heatmap, funnel.
925
+ * @param parsed - Result of parseExtendedChart()
926
+ */
927
+ declare function buildExtendedChartOption(parsed: ParsedExtendedChart, palette: PaletteColors, isDark: boolean): EChartsOption;
928
+ /**
929
+ * Extracts legend group data from standard chart types (multi-line, bar-stacked).
930
+ * Returns empty array if chart has no multi-series legend.
931
+ */
932
+ declare function getSimpleChartLegendGroups(parsed: ParsedChart, colors: string[]): LegendGroupData[];
933
+ /**
934
+ * Extracts legend group data from extended chart types.
935
+ * Supports scatter (categories), chord (nodes), and function (series).
936
+ */
937
+ declare function getExtendedChartLegendGroups(parsed: ParsedExtendedChart, colors: string[]): LegendGroupData[];
938
+ interface ScatterLabelPoint {
939
+ name: string;
940
+ px: number;
941
+ py: number;
942
+ color: string;
943
+ size?: number;
944
+ }
945
+ /**
946
+ * Greedy label placement for scatter charts.
947
+ * Returns ECharts `graphic` elements (text + background rects + optional connector lines).
948
+ * Pure function — no ECharts instance dependency.
949
+ *
950
+ * @param bg - chart background color, used for label background rects that mask connector lines
951
+ */
952
+ declare function computeScatterLabelGraphics(points: ScatterLabelPoint[], chartBounds: {
953
+ top: number;
954
+ bottom: number;
955
+ }, fontSize: number, symbolSize: number, bg?: string): Record<string, unknown>[];
956
+ /**
957
+ * Converts a ParsedChart into an EChartsOption.
958
+ * Handles standard chart types: bar, line, area, pie, doughnut, radar, polar-area, bar-stacked, multi-line.
959
+ * @param parsed - Result of parseChart()
960
+ */
961
+ declare function buildSimpleChartOption(parsed: ParsedChart, palette: PaletteColors, isDark: boolean, chartWidth?: number): EChartsOption;
962
+ /**
963
+ * Renders an extended chart (scatter, sankey, chord, function, heatmap, funnel) to SVG using server-side rendering.
964
+ * Mirrors the `renderForExport` API — returns an SVG string or empty string on failure.
965
+ */
966
+ declare function renderExtendedChartForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette?: PaletteColors): Promise<string>;
967
+
968
+ interface D3ExportDimensions {
969
+ width?: number;
970
+ height?: number;
971
+ }
972
+
38
973
  /** A single entry inside a tag group: `Value(color)` */
39
974
  interface TagEntry {
40
975
  value: string;
@@ -51,146 +986,3464 @@ interface TagGroup {
51
986
  lineNumber: number;
52
987
  }
53
988
 
54
- /** @deprecated Use `TagGroup` from `utils/tag-groups` */
55
- type KanbanTagGroup = TagGroup;
56
- interface KanbanCard {
989
+ type VisualizationType = 'slope' | 'wordcloud' | 'arc' | 'timeline' | 'venn' | 'quadrant' | 'sequence' | 'tech-radar' | 'cycle' | 'pyramid' | 'ring';
990
+ interface D3DataItem {
991
+ label: string;
992
+ values: number[];
993
+ color: string | null;
994
+ lineNumber: number;
995
+ }
996
+ interface WordCloudWord {
997
+ text: string;
998
+ weight: number;
999
+ lineNumber: number;
1000
+ }
1001
+ type WordCloudRotate = 'none' | 'mixed' | 'angled';
1002
+ interface WordCloudOptions {
1003
+ rotate: WordCloudRotate;
1004
+ max: number;
1005
+ minSize: number;
1006
+ maxSize: number;
1007
+ }
1008
+ interface ArcLink {
1009
+ source: string;
1010
+ target: string;
1011
+ value: number;
1012
+ color: string | null;
1013
+ lineNumber: number;
1014
+ }
1015
+ type ArcOrder = 'appearance' | 'name' | 'group' | 'degree';
1016
+ interface ArcNodeGroup {
1017
+ name: string;
1018
+ nodes: string[];
1019
+ color: string | null;
1020
+ lineNumber: number;
1021
+ }
1022
+ type TimelineSort = 'time' | 'group' | 'tag';
1023
+ interface TimelineEvent {
1024
+ date: string;
1025
+ endDate: string | null;
1026
+ label: string;
1027
+ group: string | null;
1028
+ metadata: Record<string, string>;
1029
+ lineNumber: number;
1030
+ uncertain?: boolean;
1031
+ }
1032
+ interface TimelineGroup {
1033
+ name: string;
1034
+ color: string | null;
1035
+ lineNumber: number;
1036
+ }
1037
+ interface TimelineEra {
1038
+ startDate: string;
1039
+ endDate: string;
1040
+ label: string;
1041
+ color: string | null;
1042
+ lineNumber: number;
1043
+ }
1044
+ interface TimelineMarker {
1045
+ date: string;
1046
+ label: string;
1047
+ color: string | null;
1048
+ lineNumber: number;
1049
+ }
1050
+ interface VennSet {
1051
+ name: string;
1052
+ alias: string | null;
1053
+ color: string | null;
1054
+ lineNumber: number;
1055
+ }
1056
+ interface VennOverlap {
1057
+ sets: string[];
1058
+ label: string | null;
1059
+ lineNumber: number;
1060
+ }
1061
+ interface QuadrantLabel {
1062
+ text: string;
1063
+ color: string | null;
1064
+ lineNumber: number;
1065
+ }
1066
+ interface QuadrantPoint {
1067
+ label: string;
1068
+ x: number;
1069
+ y: number;
1070
+ lineNumber: number;
1071
+ }
1072
+ interface QuadrantLabels {
1073
+ topRight: QuadrantLabel | null;
1074
+ topLeft: QuadrantLabel | null;
1075
+ bottomLeft: QuadrantLabel | null;
1076
+ bottomRight: QuadrantLabel | null;
1077
+ }
1078
+
1079
+ interface ParsedVisualization {
1080
+ type: VisualizationType | null;
1081
+ title: string | null;
1082
+ titleLineNumber: number | null;
1083
+ orientation: 'horizontal' | 'vertical';
1084
+ periods: string[];
1085
+ data: D3DataItem[];
1086
+ words: WordCloudWord[];
1087
+ cloudOptions: WordCloudOptions;
1088
+ links: ArcLink[];
1089
+ arcOrder: ArcOrder;
1090
+ arcNodeGroups: ArcNodeGroup[];
1091
+ timelineEvents: TimelineEvent[];
1092
+ timelineGroups: TimelineGroup[];
1093
+ timelineEras: TimelineEra[];
1094
+ timelineMarkers: TimelineMarker[];
1095
+ timelineTagGroups: TagGroup[];
1096
+ timelineSort: TimelineSort;
1097
+ timelineDefaultSwimlaneTG?: string;
1098
+ timelineScale: boolean;
1099
+ timelineSwimlanes: boolean;
1100
+ vennSets: VennSet[];
1101
+ vennOverlaps: VennOverlap[];
1102
+ quadrantLabels: QuadrantLabels;
1103
+ quadrantPoints: QuadrantPoint[];
1104
+ quadrantXAxis: [string, string] | null;
1105
+ quadrantXAxisLineNumber: number | null;
1106
+ quadrantYAxis: [string, string] | null;
1107
+ quadrantYAxisLineNumber: number | null;
1108
+ quadrantTitleLineNumber: number | null;
1109
+ noName?: boolean;
1110
+ noValue?: boolean;
1111
+ noPercent?: boolean;
1112
+ /** Render with full intent saturation instead of the canonical 25% tint. */
1113
+ solidFill?: boolean;
1114
+ /** Cross-chart-type: when true, the renderer suppresses the chart title. */
1115
+ noTitle?: boolean;
1116
+ diagnostics: DgmoError[];
1117
+ error: string | null;
1118
+ }
1119
+
1120
+ /**
1121
+ * Converts a date string (YYYY, YYYY-MM, YYYY-MM-DD, or YYYY-MM-DD HH:MM) to a fractional year number.
1122
+ */
1123
+ declare function parseTimelineDate(s: string): number;
1124
+ /**
1125
+ * Adds a duration to a date string and returns the resulting date string.
1126
+ * Supports: d (days), w (weeks), m (months), y (years), h (hours), min (minutes)
1127
+ * Supports decimals up to 2 places (e.g., 1.25y = 1 year 3 months)
1128
+ * Preserves the precision of the input date (YYYY, YYYY-MM, YYYY-MM-DD, or YYYY-MM-DD HH:MM).
1129
+ */
1130
+ declare function addDurationToDate(startDate: string, amount: number, unit: 'd' | 'w' | 'm' | 'y' | 'h' | 'min'): string;
1131
+ /**
1132
+ * Parses D3 chart text format into structured data.
1133
+ */
1134
+ declare function parseVisualization(content: string, palette?: PaletteColors): ParsedVisualization;
1135
+ /**
1136
+ * Renders a slope chart into the given container using D3.
1137
+ */
1138
+ declare function renderSlopeChart(container: HTMLDivElement, parsed: ParsedVisualization, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: D3ExportDimensions): void;
1139
+ /**
1140
+ * Orders arc diagram nodes based on the selected ordering strategy.
1141
+ */
1142
+ declare function orderArcNodes(links: ArcLink[], order: ArcOrder, groups: ArcNodeGroup[]): string[];
1143
+ /**
1144
+ * Renders an arc diagram into the given container using D3.
1145
+ */
1146
+ declare function renderArcDiagram(container: HTMLDivElement, parsed: ParsedVisualization, palette: PaletteColors, _isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: D3ExportDimensions): void;
1147
+ /**
1148
+ * Converts a DSL date string (YYYY, YYYY-MM, YYYY-MM-DD, or YYYY-MM-DD HH:MM) to a human-readable label.
1149
+ * '1718' → '1718'
1150
+ * '1718-05' → 'May 1718'
1151
+ * '1718-05-22' → 'May 22, 1718'
1152
+ * '2024-06-15 14:30' → 'Jun 15, 2024 14:30'
1153
+ */
1154
+ declare function formatDateLabel(dateStr: string): string;
1155
+ /**
1156
+ * Renders a timeline chart into the given container using D3.
1157
+ * Supports horizontal (default) and vertical orientation.
1158
+ */
1159
+ declare function renderTimeline(container: HTMLDivElement, parsed: ParsedVisualization, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: D3ExportDimensions, activeTagGroup?: string | null, swimlaneTagGroup?: string | null, onTagStateChange?: (activeTagGroup: string | null, swimlaneTagGroup: string | null) => void, viewMode?: boolean): void;
1160
+ /**
1161
+ * Renders a word cloud into the given container using d3-cloud.
1162
+ */
1163
+ declare function renderWordCloud(container: HTMLDivElement, parsed: ParsedVisualization, palette: PaletteColors, _isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: D3ExportDimensions): void;
1164
+ declare function renderVenn(container: HTMLDivElement, parsed: ParsedVisualization, palette: PaletteColors, _isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: D3ExportDimensions): void;
1165
+ /**
1166
+ * Renders a quadrant chart using D3.
1167
+ * Displays 4 colored quadrant regions, axis labels, quadrant labels, and data points.
1168
+ */
1169
+ declare function renderQuadrant(container: HTMLDivElement, parsed: ParsedVisualization, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: D3ExportDimensions): void;
1170
+ /**
1171
+ * Renders a D3 chart to an SVG string for export.
1172
+ * Creates a detached DOM element, renders into it, extracts the SVG, then cleans up.
1173
+ */
1174
+ declare function renderForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette?: PaletteColors, viewState?: CompactViewState, options?: {
1175
+ c4Level?: 'context' | 'containers' | 'components' | 'deployment';
1176
+ c4System?: string;
1177
+ c4Container?: string;
1178
+ tagGroup?: string;
1179
+ }): Promise<string>;
1180
+
1181
+ /**
1182
+ * Generates adaptive tick marks along a time axis.
1183
+ * Picks the right granularity (years, months, weeks, days, hours, minutes)
1184
+ * based on the domain span.
1185
+ *
1186
+ * Optional boundary parameters add ticks at exact data start/end:
1187
+ * - boundaryStart/boundaryEnd: numeric date values
1188
+ * - boundaryStartLabel/boundaryEndLabel: formatted labels for those dates
1189
+ */
1190
+ declare function computeTimeTicks(domainMin: number, domainMax: number, scale: d3Scale.ScaleLinear<number, number>, boundaryStart?: number, boundaryEnd?: number, boundaryStartLabel?: string, boundaryEndLabel?: string): {
1191
+ pos: number;
1192
+ label: string;
1193
+ }[];
1194
+
1195
+ /**
1196
+ * Participant types that can be declared via "Name is a type" syntax.
1197
+ */
1198
+ type ParticipantType = 'default' | 'service' | 'database' | 'actor' | 'queue' | 'cache' | 'gateway' | 'external' | 'networking' | 'frontend';
1199
+ /**
1200
+ * A declared or inferred participant in the sequence diagram.
1201
+ */
1202
+ interface SequenceParticipant {
1203
+ /** Internal identifier (e.g. "AuthService") */
1204
+ id: string;
1205
+ /** Display label — first-seen casing/spacing of the name */
1206
+ label: string;
1207
+ /** Participant shape type */
1208
+ type: ParticipantType;
1209
+ /** Source line number (1-based) */
1210
+ lineNumber: number;
1211
+ /** Explicit layout position override (0-based from left, negative from right) */
1212
+ position?: number;
1213
+ /** Pipe-delimited tag metadata (e.g. `| role: Gateway`) */
1214
+ metadata?: Record<string, string>;
1215
+ }
1216
+ /**
1217
+ * A message between two participants.
1218
+ */
1219
+ interface SequenceMessage {
1220
+ from: string;
1221
+ to: string;
1222
+ label: string;
1223
+ lineNumber: number;
1224
+ async?: boolean;
1225
+ /** Pipe-delimited tag metadata (e.g. `| c: Caching`) */
1226
+ metadata?: Record<string, string>;
1227
+ }
1228
+ /**
1229
+ * A conditional or loop block in the sequence diagram.
1230
+ */
1231
+ interface ElseIfBranch {
1232
+ label: string;
1233
+ children: SequenceElement[];
1234
+ lineNumber: number;
1235
+ }
1236
+ interface SequenceBlock {
1237
+ kind: 'block';
1238
+ type: 'if' | 'loop' | 'parallel';
1239
+ label: string;
1240
+ children: SequenceElement[];
1241
+ elseChildren: SequenceElement[];
1242
+ elseIfBranches?: ElseIfBranch[];
1243
+ elseLineNumber?: number;
1244
+ lineNumber: number;
1245
+ }
1246
+ /**
1247
+ * A labeled horizontal divider between message phases.
1248
+ */
1249
+ interface SequenceSection {
1250
+ kind: 'section';
1251
+ label: string;
1252
+ lineNumber: number;
1253
+ }
1254
+ /**
1255
+ * An annotation attached to a message, rendered as a folded-corner box.
1256
+ */
1257
+ interface SequenceNote {
1258
+ kind: 'note';
1259
+ text: string;
1260
+ position: 'right' | 'left';
1261
+ participantId: string;
1262
+ lineNumber: number;
1263
+ endLineNumber: number;
1264
+ }
1265
+ type SequenceElement = SequenceMessage | SequenceBlock | SequenceSection | SequenceNote;
1266
+ declare function isSequenceBlock(el: SequenceElement): el is SequenceBlock;
1267
+ declare function isSequenceNote(el: SequenceElement): el is SequenceNote;
1268
+ /**
1269
+ * A named group of participants rendered as a labeled box.
1270
+ */
1271
+ interface SequenceGroup {
1272
+ name: string;
1273
+ participantIds: string[];
1274
+ lineNumber: number;
1275
+ /** Pipe-delimited tag metadata (e.g. `[Backend | t: Product]`) */
1276
+ metadata?: Record<string, string>;
1277
+ /** Whether this group is collapsed by default */
1278
+ collapsed?: boolean;
1279
+ }
1280
+ /**
1281
+ * Parsed result from a .dgmo sequence diagram.
1282
+ */
1283
+ interface ParsedSequenceDgmo {
1284
+ title: string | null;
1285
+ titleLineNumber: number | null;
1286
+ participants: SequenceParticipant[];
1287
+ messages: SequenceMessage[];
1288
+ elements: SequenceElement[];
1289
+ groups: SequenceGroup[];
1290
+ sections: SequenceSection[];
1291
+ tagGroups: TagGroup[];
1292
+ options: Record<string, string>;
1293
+ diagnostics: DgmoError[];
1294
+ error: string | null;
1295
+ }
1296
+ /**
1297
+ * Parse a .dgmo file with `chart: sequence` into a structured representation.
1298
+ */
1299
+ declare function parseSequenceDgmo(content: string): ParsedSequenceDgmo;
1300
+ /**
1301
+ * Detect whether raw content looks like a sequence diagram.
1302
+ * Used by the chart type inference logic.
1303
+ */
1304
+ declare function looksLikeSequence(content: string): boolean;
1305
+
1306
+ /**
1307
+ * Infer participant type from a name using the ordered rules table.
1308
+ * Returns 'default' if no rule matches.
1309
+ */
1310
+ declare function inferParticipantType(name: string): ParticipantType;
1311
+ /**
1312
+ * Number of rules in the table. Exported for test assertions.
1313
+ */
1314
+ declare const RULE_COUNT: number;
1315
+
1316
+ type GraphShape = 'terminal' | 'process' | 'decision' | 'io' | 'subroutine' | 'document' | 'state' | 'pseudostate';
1317
+ type GraphDirection = 'TB' | 'LR';
1318
+ interface GraphNode {
1319
+ id: string;
1320
+ label: string;
1321
+ shape: GraphShape;
1322
+ color?: string;
1323
+ group?: string;
1324
+ lineNumber: number;
1325
+ }
1326
+ interface GraphEdge {
1327
+ source: string;
1328
+ target: string;
1329
+ label?: string;
1330
+ color?: string;
1331
+ lineNumber: number;
1332
+ }
1333
+ interface GraphGroup {
1334
+ id: string;
1335
+ label: string;
1336
+ color?: string;
1337
+ nodeIds: string[];
1338
+ lineNumber: number;
1339
+ }
1340
+
1341
+ interface ParsedGraph {
1342
+ type: 'flowchart' | 'state';
1343
+ title?: string;
1344
+ titleLineNumber?: number;
1345
+ direction: GraphDirection;
1346
+ nodes: GraphNode[];
1347
+ edges: GraphEdge[];
1348
+ groups?: GraphGroup[];
1349
+ options: Record<string, string>;
1350
+ diagnostics: DgmoError[];
1351
+ error: string | null;
1352
+ }
1353
+
1354
+ type ChartType = string;
1355
+ interface DiagramSymbols {
1356
+ kind: ChartType;
1357
+ entities: string[];
1358
+ keywords: string[];
1359
+ /**
1360
+ * Map of alias-literal → canonical entity name, collected from
1361
+ * `Name as <alias>` declarations in the document. Editor surfaces
1362
+ * both forms in autocomplete; selecting an alias inserts the alias
1363
+ * literal (the alias is input convenience, not a display name).
1364
+ */
1365
+ aliases?: Record<string, string>;
1366
+ }
1367
+ type ExtractFn = (docText: string) => DiagramSymbols;
1368
+
1369
+ declare function parseFlowchart(content: string, palette?: PaletteColors): ParsedGraph;
1370
+ /**
1371
+ * Detect if content looks like a flowchart (without explicit `chart: flowchart` header).
1372
+ * Checks for shape delimiters combined with `->` arrows.
1373
+ * Avoids false-positives on sequence diagrams (which use bare names with `->`)
1374
+ */
1375
+ declare function looksLikeFlowchart(content: string): boolean;
1376
+
1377
+ declare function parseState(content: string, palette?: PaletteColors): ParsedGraph;
1378
+ /**
1379
+ * Detect if content looks like a state diagram (without explicit `chart: state` header).
1380
+ * Only matches if `[*]` token is present — too ambiguous to infer from bare names alone.
1381
+ */
1382
+ declare function looksLikeState(content: string): boolean;
1383
+
1384
+ interface LayoutNode {
1385
+ id: string;
1386
+ label: string;
1387
+ shape: GraphShape;
1388
+ color?: string;
1389
+ group?: string;
1390
+ lineNumber: number;
1391
+ x: number;
1392
+ y: number;
1393
+ width: number;
1394
+ height: number;
1395
+ }
1396
+ interface LayoutEdge {
1397
+ source: string;
1398
+ target: string;
1399
+ points: {
1400
+ x: number;
1401
+ y: number;
1402
+ }[];
1403
+ label?: string;
1404
+ color?: string;
1405
+ lineNumber: number;
1406
+ }
1407
+ interface LayoutGroup {
1408
+ id: string;
1409
+ label: string;
1410
+ color?: string;
1411
+ lineNumber: number;
1412
+ collapsed?: boolean;
1413
+ x: number;
1414
+ y: number;
1415
+ width: number;
1416
+ height: number;
1417
+ }
1418
+ interface LayoutOptions {
1419
+ /** Map of group ID → number of child nodes (for collapsed groups) */
1420
+ collapsedChildCounts?: Map<string, number>;
1421
+ /** Original groups before collapse (includes collapsed ones) */
1422
+ originalGroups?: GraphGroup[];
1423
+ }
1424
+ interface LayoutResult$1 {
1425
+ nodes: LayoutNode[];
1426
+ edges: LayoutEdge[];
1427
+ groups: LayoutGroup[];
1428
+ width: number;
1429
+ height: number;
1430
+ }
1431
+ declare function layoutGraph(graph: ParsedGraph, options?: LayoutOptions): LayoutResult$1;
1432
+
1433
+ declare function renderState(container: HTMLDivElement, graph: ParsedGraph, layout: LayoutResult$1, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
1434
+ width?: number;
1435
+ height?: number;
1436
+ }): void;
1437
+ declare function renderStateForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
1438
+
1439
+ interface StateCollapseResult {
1440
+ parsed: ParsedGraph;
1441
+ collapsedChildCounts: Map<string, number>;
1442
+ originalGroups: GraphGroup[];
1443
+ }
1444
+ /**
1445
+ * Pure transform: returns a new ParsedGraph with collapsed groups
1446
+ * removed from the diagram content.
1447
+ *
1448
+ * - Children of collapsed groups removed from nodes
1449
+ * - Edges redirected: endpoints in collapsed groups → group ID
1450
+ * - Internal edges (both in same collapsed group) dropped
1451
+ * - Duplicate edges (same source, target, label) deduplicated
1452
+ * - Collapsed groups removed from groups[] (layout handles as nodes)
1453
+ */
1454
+ declare function collapseStateGroups(parsed: ParsedGraph, collapsedGroups: Set<string>): StateCollapseResult;
1455
+
1456
+ type ClassModifier = 'abstract' | 'interface' | 'enum';
1457
+ type MemberVisibility = 'public' | 'private' | 'protected';
1458
+ type RelationshipType = 'extends' | 'implements' | 'composes' | 'aggregates' | 'depends' | 'associates';
1459
+ interface ClassMember {
1460
+ name: string;
1461
+ type?: string;
1462
+ params?: string;
1463
+ visibility: MemberVisibility;
1464
+ isStatic: boolean;
1465
+ isMethod: boolean;
1466
+ lineNumber: number;
1467
+ }
1468
+ interface ClassNode {
1469
+ id: string;
1470
+ name: string;
1471
+ modifier?: ClassModifier;
1472
+ color?: string;
1473
+ members: ClassMember[];
1474
+ lineNumber: number;
1475
+ }
1476
+ interface ClassRelationship {
1477
+ source: string;
1478
+ target: string;
1479
+ type: RelationshipType;
1480
+ label?: string;
1481
+ lineNumber: number;
1482
+ }
1483
+
1484
+ interface ParsedClassDiagram {
1485
+ type: 'class';
1486
+ title?: string;
1487
+ titleLineNumber?: number;
1488
+ classes: ClassNode[];
1489
+ relationships: ClassRelationship[];
1490
+ options: Record<string, string>;
1491
+ diagnostics: DgmoError[];
1492
+ error: string | null;
1493
+ }
1494
+
1495
+ declare function parseClassDiagram(content: string, palette?: PaletteColors): ParsedClassDiagram;
1496
+ /**
1497
+ * Detect if content looks like a class diagram without explicit `chart: class`.
1498
+ * Requires class-like patterns (capitalized names with modifiers or UML relationships).
1499
+ * Must not false-positive on flowcharts.
1500
+ */
1501
+ declare function looksLikeClassDiagram(content: string): boolean;
1502
+
1503
+ interface ClassLayoutNode extends ClassNode {
1504
+ x: number;
1505
+ y: number;
1506
+ width: number;
1507
+ height: number;
1508
+ headerHeight: number;
1509
+ fieldsHeight: number;
1510
+ methodsHeight: number;
1511
+ }
1512
+ interface ClassLayoutEdge {
1513
+ source: string;
1514
+ target: string;
1515
+ type: RelationshipType;
1516
+ points: {
1517
+ x: number;
1518
+ y: number;
1519
+ }[];
1520
+ label?: string;
1521
+ lineNumber: number;
1522
+ }
1523
+ interface ClassLayoutResult {
1524
+ nodes: ClassLayoutNode[];
1525
+ edges: ClassLayoutEdge[];
1526
+ width: number;
1527
+ height: number;
1528
+ }
1529
+ declare function layoutClassDiagram(parsed: ParsedClassDiagram): ClassLayoutResult;
1530
+
1531
+ declare function renderClassDiagram(container: HTMLDivElement, parsed: ParsedClassDiagram, layout: ClassLayoutResult, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
1532
+ width?: number;
1533
+ height?: number;
1534
+ }, legendActive?: boolean | null): void;
1535
+ declare function renderClassDiagramForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
1536
+
1537
+ type ERConstraint = 'pk' | 'fk' | 'unique' | 'nullable';
1538
+ type ERCardinality = '1' | '*' | '?';
1539
+ interface ERColumn {
1540
+ name: string;
1541
+ type?: string;
1542
+ constraints: ERConstraint[];
1543
+ lineNumber: number;
1544
+ }
1545
+ interface ERTable {
1546
+ id: string;
1547
+ name: string;
1548
+ color?: string;
1549
+ columns: ERColumn[];
1550
+ metadata: Record<string, string>;
1551
+ lineNumber: number;
1552
+ }
1553
+ interface ERRelationship {
1554
+ source: string;
1555
+ target: string;
1556
+ cardinality: {
1557
+ from: ERCardinality;
1558
+ to: ERCardinality;
1559
+ };
1560
+ label?: string;
1561
+ lineNumber: number;
1562
+ }
1563
+
1564
+ interface ParsedERDiagram {
1565
+ type: 'er';
1566
+ title?: string;
1567
+ titleLineNumber?: number;
1568
+ options: Record<string, string>;
1569
+ tables: ERTable[];
1570
+ relationships: ERRelationship[];
1571
+ tagGroups: TagGroup[];
1572
+ diagnostics: DgmoError[];
1573
+ error: string | null;
1574
+ }
1575
+
1576
+ declare function parseERDiagram(content: string, palette?: PaletteColors): ParsedERDiagram;
1577
+ /**
1578
+ * Detect if content looks like an ER diagram without explicit `er` first line.
1579
+ * Looks for indented lines with pk or fk constraint keywords.
1580
+ */
1581
+ declare function looksLikeERDiagram(content: string): boolean;
1582
+
1583
+ interface ERLayoutNode extends ERTable {
1584
+ x: number;
1585
+ y: number;
1586
+ width: number;
1587
+ height: number;
1588
+ headerHeight: number;
1589
+ columnsHeight: number;
1590
+ }
1591
+ interface ERLayoutEdge {
1592
+ source: string;
1593
+ target: string;
1594
+ cardinality: {
1595
+ from: string;
1596
+ to: string;
1597
+ };
1598
+ points: {
1599
+ x: number;
1600
+ y: number;
1601
+ }[];
1602
+ label?: string;
1603
+ lineNumber: number;
1604
+ }
1605
+ interface ERLayoutResult {
1606
+ nodes: ERLayoutNode[];
1607
+ edges: ERLayoutEdge[];
1608
+ width: number;
1609
+ height: number;
1610
+ }
1611
+ declare function layoutERDiagram(parsed: ParsedERDiagram): ERLayoutResult;
1612
+
1613
+ declare function renderERDiagram(container: HTMLDivElement, parsed: ParsedERDiagram, layout: ERLayoutResult, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
1614
+ width?: number;
1615
+ height?: number;
1616
+ }, activeTagGroup?: string | null,
1617
+ /** When false, semantic role colors are suppressed and entities use a neutral color. */
1618
+ semanticColorsActive?: boolean): void;
1619
+ declare function renderERDiagramForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
1620
+
1621
+ interface InlineSpan {
1622
+ text: string;
1623
+ bold?: boolean;
1624
+ italic?: boolean;
1625
+ code?: boolean;
1626
+ href?: string;
1627
+ }
1628
+ declare function parseInlineMarkdown(text: string): InlineSpan[];
1629
+ declare function truncateBareUrl(url: string): string;
1630
+
1631
+ /**
1632
+ * Reduce a name to its canonical key for equality comparison.
1633
+ *
1634
+ * Idempotent: `normalizeName(normalizeName(x)) === normalizeName(x)`.
1635
+ *
1636
+ * The returned key is for equality only — never display it. Callers
1637
+ * that need to render a name should use the `displayLabel` field of
1638
+ * the `NameEntry` returned by `getOrCreateName`.
1639
+ */
1640
+ declare function normalizeName(input: string): string;
1641
+ /**
1642
+ * Reduce a name to its display form: NFC normalize and trim only.
1643
+ *
1644
+ * Casing AND internal whitespace are preserved verbatim — the spec
1645
+ * says "first-seen casing/spacing wins for display" (ADR-002), so a
1646
+ * double space typed by the user survives into the rendered label.
1647
+ * Renderers may collapse it for layout, but the source-of-truth is
1648
+ * what the user typed.
1649
+ *
1650
+ * Two inputs that share the same `normalizeName(...)` key but have
1651
+ * different `displayName(...)` values are a "merge" — surfaced via
1652
+ * the `NAME_MERGED` diagnostic.
1653
+ */
1654
+ declare function displayName(input: string): string;
1655
+ /**
1656
+ * One entity, identified by its normalized key.
1657
+ *
1658
+ * Parsers either use this shape directly in their entity Map or
1659
+ * compose it into a richer per-chart node type. Equality MUST use
1660
+ * only `normalizedKey`; rendering MUST use only `displayLabel`.
1661
+ */
1662
+ interface NameEntry {
1663
+ /** Output of `normalizeName(input)` — the lookup key. */
1664
+ normalizedKey: string;
1665
+ /** First-seen casing/spacing — what gets rendered. */
1666
+ displayLabel: string;
1667
+ /** 1-based source line where the name was first declared. */
1668
+ declaredLine: number;
1669
+ }
1670
+ /**
1671
+ * Result of an entity insertion attempt.
1672
+ *
1673
+ * `created` is true on first sighting. `merged` is present iff the
1674
+ * input collided with an existing entry AND the displayed forms
1675
+ * differ — that is the case worth reporting via `NAME_MERGED`.
1676
+ * Identical re-declarations produce neither `created` nor `merged`.
1677
+ */
1678
+ interface GetOrCreateNameResult {
1679
+ entry: NameEntry;
1680
+ created: boolean;
1681
+ merged?: {
1682
+ existingLine: number;
1683
+ existingDisplay: string;
1684
+ incomingDisplay: string;
1685
+ };
1686
+ }
1687
+ /**
1688
+ * Insert-or-fetch helper for `Map<normalizedKey, NameEntry>` stores.
1689
+ *
1690
+ * Parsers that need a richer node type (e.g. flowchart's `Node`
1691
+ * carries shape + edges) should wrap this helper: call it for the
1692
+ * normalization + merge-detection bookkeeping, then store the result
1693
+ * in their own `Map<normalizedKey, RichNode>`.
1694
+ *
1695
+ * When an `aliasStore` is provided, alias resolution runs FIRST: an
1696
+ * exact-match (case-sensitive) hit returns the bound canonical entry
1697
+ * untouched (the alias literal does NOT contribute to display or
1698
+ * merge bookkeeping). Misses fall through to UNH normalization.
1699
+ */
1700
+ declare function getOrCreateName(input: string, store: Map<string, NameEntry>, lineNumber: number, aliasStore?: AliasMap): GetOrCreateNameResult;
1701
+ /** alias literal → bound canonical entry. Exact-match, case-sensitive. */
1702
+ type AliasMap = Map<string, NameEntry>;
1703
+
1704
+ interface OrgNode {
1705
+ id: string;
1706
+ label: string;
1707
+ metadata: Record<string, string>;
1708
+ children: OrgNode[];
1709
+ parentId: string | null;
1710
+ isContainer: boolean;
1711
+ lineNumber: number;
1712
+ color?: string;
1713
+ }
1714
+ interface ParsedOrg {
1715
+ title: string | null;
1716
+ titleLineNumber: number | null;
1717
+ roots: OrgNode[];
1718
+ tagGroups: TagGroup[];
1719
+ options: Record<string, string>;
1720
+ diagnostics: DgmoError[];
1721
+ error: string | null;
1722
+ }
1723
+ declare function parseOrg(content: string, palette?: PaletteColors): ParsedOrg;
1724
+
1725
+ interface OrgLayoutNode {
1726
+ id: string;
1727
+ label: string;
1728
+ metadata: Record<string, string>;
1729
+ /** Original (unfiltered) metadata — used for tag-based hover dimming even when the group is hidden */
1730
+ tagMetadata: Record<string, string>;
1731
+ isContainer: boolean;
1732
+ lineNumber: number;
1733
+ color?: string;
1734
+ x: number;
1735
+ y: number;
1736
+ width: number;
1737
+ height: number;
1738
+ /** Count of hidden descendants when this node is collapsed */
1739
+ hiddenCount?: number;
1740
+ /** True if node has children (expanded or collapsed) — drives toggle UI */
1741
+ hasChildren?: boolean;
1742
+ }
1743
+ interface OrgLayoutEdge {
1744
+ sourceId: string;
1745
+ targetId: string;
1746
+ points: {
1747
+ x: number;
1748
+ y: number;
1749
+ }[];
1750
+ }
1751
+ interface OrgContainerBounds {
1752
+ nodeId: string;
1753
+ label: string;
1754
+ lineNumber: number;
1755
+ color?: string;
1756
+ metadata: Record<string, string>;
1757
+ /** Original (unfiltered) metadata — used for tag-based hover dimming even when the group is hidden */
1758
+ tagMetadata: Record<string, string>;
1759
+ x: number;
1760
+ y: number;
1761
+ width: number;
1762
+ height: number;
1763
+ labelHeight: number;
1764
+ /** Count of hidden descendants when this container is collapsed */
1765
+ hiddenCount?: number;
1766
+ /** True if container has children (expanded or collapsed) — drives toggle UI */
1767
+ hasChildren?: boolean;
1768
+ }
1769
+ interface OrgLegendEntry {
1770
+ value: string;
1771
+ color: string;
1772
+ }
1773
+ interface OrgLegendGroup {
1774
+ name: string;
1775
+ alias?: string;
1776
+ entries: OrgLegendEntry[];
1777
+ x: number;
1778
+ y: number;
1779
+ width: number;
1780
+ height: number;
1781
+ minifiedWidth: number;
1782
+ minifiedHeight: number;
1783
+ }
1784
+ interface OrgLayoutResult {
1785
+ nodes: OrgLayoutNode[];
1786
+ edges: OrgLayoutEdge[];
1787
+ containers: OrgContainerBounds[];
1788
+ legend: OrgLegendGroup[];
1789
+ width: number;
1790
+ height: number;
1791
+ }
1792
+ declare function layoutOrg(parsed: ParsedOrg, hiddenCounts?: Map<string, number>, activeTagGroup?: string | null, hiddenAttributes?: Set<string>, expandAllLegend?: boolean): OrgLayoutResult;
1793
+
1794
+ interface CollapsedOrgResult {
1795
+ /** ParsedOrg with collapsed subtrees pruned (deep-cloned, never mutates original) */
1796
+ parsed: ParsedOrg;
1797
+ /** nodeId → count of hidden descendants */
1798
+ hiddenCounts: Map<string, number>;
1799
+ }
1800
+ interface AncestorInfo {
1801
+ id: string;
1802
+ label: string;
1803
+ lineNumber: number;
1804
+ color?: string;
1805
+ metadata: Record<string, string>;
1806
+ isContainer: boolean;
1807
+ }
1808
+ interface FocusOrgResult {
1809
+ /** ParsedOrg with only the focused subtree as the single root */
1810
+ parsed: ParsedOrg;
1811
+ /** Ancestor path from original root → parent of focused node (top-down order) */
1812
+ ancestorPath: AncestorInfo[];
1813
+ }
1814
+ declare function collapseOrgTree(original: ParsedOrg, collapsedIds: Set<string>): CollapsedOrgResult;
1815
+ /**
1816
+ * Extract a subtree rooted at `focusNodeId`, returning the focused tree
1817
+ * and the ancestor breadcrumb path. Returns null if the node is not found.
1818
+ */
1819
+ declare function focusOrgTree(original: ParsedOrg, focusNodeId: string): FocusOrgResult | null;
1820
+
1821
+ declare function renderOrg(container: HTMLDivElement, parsed: ParsedOrg, layout: OrgLayoutResult, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
1822
+ width?: number;
1823
+ height?: number;
1824
+ }, activeTagGroup?: string | null, hiddenAttributes?: Set<string>, ancestorPath?: AncestorInfo[]): void;
1825
+ declare function renderOrgForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
1826
+
1827
+ /** @deprecated Use `TagEntry` from `utils/tag-groups` */
1828
+ type KanbanTagEntry = TagEntry;
1829
+ /** @deprecated Use `TagGroup` from `utils/tag-groups` */
1830
+ type KanbanTagGroup = TagGroup;
1831
+ interface KanbanCard {
1832
+ id: string;
1833
+ title: string;
1834
+ tags: Record<string, string>;
1835
+ details: string[];
1836
+ lineNumber: number;
1837
+ endLineNumber: number;
1838
+ color?: string;
1839
+ }
1840
+ interface KanbanColumn {
1841
+ id: string;
1842
+ name: string;
1843
+ wipLimit?: number;
1844
+ color?: string;
1845
+ metadata?: Record<string, string>;
1846
+ cards: KanbanCard[];
1847
+ lineNumber: number;
1848
+ }
1849
+ interface ParsedKanban {
1850
+ type: 'kanban';
1851
+ title?: string;
1852
+ titleLineNumber?: number;
1853
+ columns: KanbanColumn[];
1854
+ tagGroups: KanbanTagGroup[];
1855
+ options: Record<string, string>;
1856
+ diagnostics: DgmoError[];
1857
+ error: string | null;
1858
+ }
1859
+
1860
+ declare function parseKanban(content: string, palette?: PaletteColors): ParsedKanban;
1861
+
1862
+ /**
1863
+ * Compute new file content after moving a card to a different position.
1864
+ *
1865
+ * @param content - original file content string
1866
+ * @param parsed - parsed kanban board
1867
+ * @param cardId - id of the card to move
1868
+ * @param targetColumnId - id of the destination column
1869
+ * @param targetIndex - position within target column (0 = first card)
1870
+ * @returns new content string, or null if move is invalid
1871
+ */
1872
+ declare function computeCardMove(content: string, parsed: ParsedKanban, cardId: string, targetColumnId: string, targetIndex: number): string | null;
1873
+ /**
1874
+ * Move a card to the Archive section at the end of the file.
1875
+ * Creates `== Archive ==` if it doesn't exist.
1876
+ *
1877
+ * @returns new content string, or null if the card is not found
1878
+ */
1879
+ declare function computeCardArchive(content: string, parsed: ParsedKanban, cardId: string): string | null;
1880
+ /** Check if a column name is the archive column (case-insensitive). */
1881
+ declare function isArchiveColumn(name: string): boolean;
1882
+
1883
+ interface KanbanInteractiveOptions {
1884
+ onNavigateToLine?: (line: number) => void;
1885
+ exportDims?: {
1886
+ width: number;
1887
+ height: number;
1888
+ };
1889
+ activeTagGroup?: string | null;
1890
+ currentSwimlaneGroup?: string | null;
1891
+ onSwimlaneChange?: (group: string | null) => void;
1892
+ collapsedLanes?: Set<string>;
1893
+ collapsedColumns?: Set<string>;
1894
+ compactMeta?: boolean;
1895
+ }
1896
+ declare function renderKanban(container: HTMLElement, parsed: ParsedKanban, palette: PaletteColors, isDark: boolean, options?: KanbanInteractiveOptions): void;
1897
+ declare function renderKanbanForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
1898
+
1899
+ /** @deprecated Use `TagEntry` from `utils/tag-groups` */
1900
+ type C4TagEntry = TagEntry;
1901
+ /** @deprecated Use `TagGroup` from `utils/tag-groups` */
1902
+ type C4TagGroup = TagGroup;
1903
+ type C4ElementType = 'person' | 'system' | 'container' | 'component';
1904
+ type C4Shape = 'default' | 'database' | 'cache' | 'queue' | 'cloud' | 'external';
1905
+ type C4ArrowType = 'sync' | 'async' | 'bidirectional' | 'bidirectional-async';
1906
+ interface C4Relationship {
1907
+ target: string;
1908
+ label?: string;
1909
+ technology?: string;
1910
+ arrowType: C4ArrowType;
1911
+ lineNumber: number;
1912
+ }
1913
+ interface C4Group {
1914
+ name: string;
1915
+ children: C4Element[];
1916
+ lineNumber: number;
1917
+ }
1918
+ interface C4Element {
1919
+ name: string;
1920
+ type: C4ElementType;
1921
+ shape: C4Shape;
1922
+ metadata: Record<string, string>;
1923
+ description?: string[];
1924
+ children: C4Element[];
1925
+ groups: C4Group[];
1926
+ relationships: C4Relationship[];
1927
+ importPath?: string;
1928
+ lineNumber: number;
1929
+ sectionHeader?: 'containers' | 'components';
1930
+ sectionHeaderLineNumber?: number;
1931
+ }
1932
+ interface C4DeploymentNode {
1933
+ name: string;
1934
+ metadata: Record<string, string>;
1935
+ shape: C4Shape;
1936
+ children: C4DeploymentNode[];
1937
+ containerRefs: string[];
1938
+ lineNumber: number;
1939
+ }
1940
+ interface ParsedC4 {
1941
+ title: string | null;
1942
+ titleLineNumber: number | null;
1943
+ options: Record<string, string>;
1944
+ tagGroups: TagGroup[];
1945
+ elements: C4Element[];
1946
+ relationships: C4Relationship[];
1947
+ deployment: C4DeploymentNode[];
1948
+ diagnostics: DgmoError[];
1949
+ error: string | null;
1950
+ }
1951
+
1952
+ declare function parseC4(content: string, palette?: PaletteColors): ParsedC4;
1953
+
1954
+ interface C4LayoutNode {
1955
+ id: string;
1956
+ name: string;
1957
+ type: 'person' | 'system' | 'container' | 'component';
1958
+ description?: string;
1959
+ metadata: Record<string, string>;
1960
+ lineNumber: number;
1961
+ color?: string;
1962
+ shape?: C4Shape;
1963
+ technology?: string;
1964
+ drillable?: boolean;
1965
+ importPath?: string;
1966
+ x: number;
1967
+ y: number;
1968
+ width: number;
1969
+ height: number;
1970
+ }
1971
+ interface C4LayoutEdge {
1972
+ source: string;
1973
+ target: string;
1974
+ arrowType: C4ArrowType;
1975
+ label?: string;
1976
+ technology?: string;
1977
+ lineNumber: number;
1978
+ points: {
1979
+ x: number;
1980
+ y: number;
1981
+ }[];
1982
+ }
1983
+ interface C4LegendEntry {
1984
+ value: string;
1985
+ color: string;
1986
+ }
1987
+ interface C4LegendGroup {
1988
+ name: string;
1989
+ entries: C4LegendEntry[];
1990
+ x: number;
1991
+ y: number;
1992
+ width: number;
1993
+ height: number;
1994
+ }
1995
+ interface C4LayoutBoundary {
1996
+ label: string;
1997
+ typeLabel: string;
1998
+ lineNumber: number;
1999
+ x: number;
2000
+ y: number;
2001
+ width: number;
2002
+ height: number;
2003
+ }
2004
+ interface C4LayoutResult {
2005
+ nodes: C4LayoutNode[];
2006
+ edges: C4LayoutEdge[];
2007
+ legend: C4LegendGroup[];
2008
+ boundary?: C4LayoutBoundary;
2009
+ groupBoundaries: C4LayoutBoundary[];
2010
+ width: number;
2011
+ height: number;
2012
+ }
2013
+ interface ContextRelationship {
2014
+ sourceName: string;
2015
+ targetName: string;
2016
+ label?: string;
2017
+ technology?: string;
2018
+ arrowType: C4ArrowType;
2019
+ lineNumber: number;
2020
+ }
2021
+ /**
2022
+ * Roll up container/component-level relationships to system-to-system edges.
2023
+ * - Skips internal relationships (same top-level ancestor).
2024
+ * - Deduplicates: same source→target pair keeps only one (first seen).
2025
+ * - Explicit system-level relationships override rolled-up ones.
2026
+ */
2027
+ declare function rollUpContextRelationships(parsed: ParsedC4): ContextRelationship[];
2028
+ declare function layoutC4Context(parsed: ParsedC4, activeTagGroup?: string | null): C4LayoutResult;
2029
+ /**
2030
+ * Layout containers within a specific system, plus external elements
2031
+ * that have relationships with those containers.
2032
+ */
2033
+ declare function layoutC4Containers(parsed: ParsedC4, systemName: string, activeTagGroup?: string | null): C4LayoutResult;
2034
+ /**
2035
+ * Layout components within a specific container, plus external elements
2036
+ * that have relationships with those components.
2037
+ */
2038
+ declare function layoutC4Components(parsed: ParsedC4, systemName: string, containerName: string, activeTagGroup?: string | null): C4LayoutResult;
2039
+ /**
2040
+ * Layout a C4 deployment diagram.
2041
+ *
2042
+ * Infrastructure nodes become boundary boxes (nested).
2043
+ * Container refs inside them become cards.
2044
+ * Edges are drawn between referenced containers that have relationships.
2045
+ */
2046
+ declare function layoutC4Deployment(parsed: ParsedC4, activeTagGroup?: string | null): C4LayoutResult;
2047
+
2048
+ declare function renderC4Context(container: HTMLDivElement, parsed: ParsedC4, layout: C4LayoutResult, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
2049
+ width?: number;
2050
+ height?: number;
2051
+ }, activeTagGroup?: string | null): void;
2052
+ declare function renderC4ContextForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
2053
+ /**
2054
+ * Render a C4 container-level diagram showing containers inside a system boundary
2055
+ * with external elements outside.
2056
+ */
2057
+ declare function renderC4Containers(container: HTMLDivElement, parsed: ParsedC4, layout: C4LayoutResult, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
2058
+ width?: number;
2059
+ height?: number;
2060
+ }, activeTagGroup?: string | null): void;
2061
+ declare function renderC4ContainersForExport(content: string, systemName: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
2062
+ declare function renderC4ComponentsForExport(content: string, systemName: string, containerName: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
2063
+ /**
2064
+ * Render a C4 deployment diagram interactively.
2065
+ * Reuses the container renderer — infrastructure boundaries are rendered
2066
+ * as group boundaries and container refs as cards (same visual pattern).
2067
+ */
2068
+ declare function renderC4Deployment(container: HTMLDivElement, parsed: ParsedC4, layout: C4LayoutResult, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
2069
+ width?: number;
2070
+ height?: number;
2071
+ }, activeTagGroup?: string | null): void;
2072
+ /**
2073
+ * Export convenience function for deployment diagrams.
2074
+ */
2075
+ declare function renderC4DeploymentForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
2076
+
2077
+ interface BLNode {
2078
+ label: string;
2079
+ lineNumber: number;
2080
+ metadata: Record<string, string>;
2081
+ description?: string[];
2082
+ }
2083
+ interface BLEdge {
2084
+ source: string;
2085
+ target: string;
2086
+ label?: string;
2087
+ bidirectional: boolean;
2088
+ lineNumber: number;
2089
+ metadata: Record<string, string>;
2090
+ }
2091
+ interface BLGroup {
2092
+ label: string;
2093
+ children: string[];
2094
+ lineNumber: number;
2095
+ metadata: Record<string, string>;
2096
+ parentGroup?: string;
2097
+ }
2098
+ interface ParsedBoxesAndLines {
2099
+ type: 'boxes-and-lines';
2100
+ title: string | null;
2101
+ titleLineNumber: number | null;
2102
+ nodes: BLNode[];
2103
+ edges: BLEdge[];
2104
+ groups: BLGroup[];
2105
+ tagGroups: TagGroup[];
2106
+ options: Record<string, string>;
2107
+ initialHiddenTagValues: Map<string, Set<string>>;
2108
+ direction: 'LR' | 'TB';
2109
+ diagnostics: DgmoError[];
2110
+ error: string | null;
2111
+ }
2112
+
2113
+ declare function parseBoxesAndLines(content: string): ParsedBoxesAndLines;
2114
+
2115
+ interface BLLayoutNode {
2116
+ label: string;
2117
+ x: number;
2118
+ y: number;
2119
+ width: number;
2120
+ height: number;
2121
+ }
2122
+ interface BLLayoutEdge {
2123
+ source: string;
2124
+ target: string;
2125
+ label?: string;
2126
+ bidirectional: boolean;
2127
+ lineNumber: number;
2128
+ points: {
2129
+ x: number;
2130
+ y: number;
2131
+ }[];
2132
+ labelX?: number;
2133
+ labelY?: number;
2134
+ yOffset: number;
2135
+ parallelCount: number;
2136
+ metadata: Record<string, string>;
2137
+ /** Marker for renderer: draw with linear curve, not curveBasis (ELK gives
2138
+ * us orthogonal polylines and curveBasis would smooth corners into waves) */
2139
+ deferred?: boolean;
2140
+ }
2141
+ interface BLLayoutGroup {
2142
+ label: string;
2143
+ lineNumber: number;
2144
+ x: number;
2145
+ y: number;
2146
+ width: number;
2147
+ height: number;
2148
+ collapsed: boolean;
2149
+ childCount?: number;
2150
+ }
2151
+ interface BLLayoutResult {
2152
+ nodes: BLLayoutNode[];
2153
+ edges: BLLayoutEdge[];
2154
+ groups: BLLayoutGroup[];
2155
+ width: number;
2156
+ height: number;
2157
+ }
2158
+ declare function layoutBoxesAndLines(parsed: ParsedBoxesAndLines, collapseInfo?: {
2159
+ collapsedChildCounts: Map<string, number>;
2160
+ originalGroups: BLGroup[];
2161
+ }, layoutOptions?: {
2162
+ hideDescriptions?: boolean;
2163
+ }): Promise<BLLayoutResult>;
2164
+
2165
+ interface BLRenderOptions {
2166
+ onClickItem?: (lineNumber: number) => void;
2167
+ exportDims?: {
2168
+ width?: number;
2169
+ height?: number;
2170
+ };
2171
+ activeTagGroup?: string | null;
2172
+ hiddenTagValues?: Map<string, Set<string>>;
2173
+ hideDescriptions?: boolean;
2174
+ controlsExpanded?: boolean;
2175
+ onToggleDescriptions?: (active: boolean) => void;
2176
+ onToggleControlsExpand?: () => void;
2177
+ }
2178
+ declare function renderBoxesAndLines(container: HTMLDivElement, parsed: ParsedBoxesAndLines, layout: BLLayoutResult, palette: PaletteColors, isDark: boolean, options?: BLRenderOptions): void;
2179
+ declare function renderBoxesAndLinesForExport(container: HTMLDivElement, parsed: ParsedBoxesAndLines, layout: BLLayoutResult, palette: PaletteColors, isDark: boolean, options?: {
2180
+ exportDims?: {
2181
+ width: number;
2182
+ height: number;
2183
+ };
2184
+ activeTagGroup?: string | null;
2185
+ hiddenTagValues?: Map<string, Set<string>>;
2186
+ }): void;
2187
+
2188
+ interface BLCollapseResult {
2189
+ parsed: ParsedBoxesAndLines;
2190
+ collapsedChildCounts: Map<string, number>;
2191
+ originalGroups: BLGroup[];
2192
+ }
2193
+ /**
2194
+ * Pure transform: returns a new ParsedBoxesAndLines with collapsed groups
2195
+ * removed from the diagram content.
2196
+ *
2197
+ * - Children of collapsed groups removed from nodes
2198
+ * - Edges redirected: endpoints in collapsed groups → group ID
2199
+ * - Internal edges (both in same collapsed group) dropped
2200
+ * - Duplicate edges (same source, target, label) deduplicated
2201
+ * - Collapsed groups removed from groups[] (layout handles as nodes)
2202
+ */
2203
+ declare function collapseBoxesAndLines(parsed: ParsedBoxesAndLines, collapsedGroups: Set<string>): BLCollapseResult;
2204
+
2205
+ interface SitemapNode {
2206
+ id: string;
2207
+ label: string;
2208
+ metadata: Record<string, string>;
2209
+ children: SitemapNode[];
2210
+ parentId: string | null;
2211
+ description?: string[];
2212
+ /** True for [Group Name] container nodes */
2213
+ isContainer: boolean;
2214
+ lineNumber: number;
2215
+ color?: string;
2216
+ }
2217
+ interface SitemapEdge {
2218
+ sourceId: string;
2219
+ targetId: string;
2220
+ label?: string;
2221
+ color?: string;
2222
+ lineNumber: number;
2223
+ }
2224
+ type SitemapDirection = 'TB' | 'LR';
2225
+ interface ParsedSitemap {
2226
+ title: string | null;
2227
+ titleLineNumber: number | null;
2228
+ direction: SitemapDirection;
2229
+ /** Top-level nodes (roots of the hierarchy) */
2230
+ roots: SitemapNode[];
2231
+ /** All cross-link edges */
2232
+ edges: SitemapEdge[];
2233
+ tagGroups: TagGroup[];
2234
+ options: Record<string, string>;
2235
+ diagnostics: DgmoError[];
2236
+ error: string | null;
2237
+ }
2238
+
2239
+ /**
2240
+ * Returns true if content looks like a sitemap diagram.
2241
+ * Heuristic: has `->` arrows AND `[Group]` containers but does NOT have
2242
+ * flowchart shape delimiters ((...), <...>, /.../) adjacent to arrows.
2243
+ */
2244
+ declare function looksLikeSitemap(content: string): boolean;
2245
+ declare function parseSitemap(content: string, palette?: PaletteColors): ParsedSitemap;
2246
+
2247
+ interface SitemapLayoutNode {
2248
+ id: string;
2249
+ label: string;
2250
+ metadata: Record<string, string>;
2251
+ /** Original (unfiltered) metadata for tag-based coloring and hover dimming */
2252
+ tagMetadata: Record<string, string>;
2253
+ description?: string[];
2254
+ isContainer: boolean;
2255
+ lineNumber: number;
2256
+ color?: string;
2257
+ x: number;
2258
+ y: number;
2259
+ width: number;
2260
+ height: number;
2261
+ /** Count of hidden descendants when collapsed */
2262
+ hiddenCount?: number;
2263
+ /** True if node has children (expanded or collapsed) — drives toggle UI */
2264
+ hasChildren?: boolean;
2265
+ }
2266
+ interface SitemapLayoutEdge {
2267
+ sourceId: string;
2268
+ targetId: string;
2269
+ points: {
2270
+ x: number;
2271
+ y: number;
2272
+ }[];
2273
+ label?: string;
2274
+ color?: string;
2275
+ lineNumber: number;
2276
+ /** True for edges deferred from dagre (container endpoints) — use linear curve */
2277
+ deferred?: boolean;
2278
+ }
2279
+ interface SitemapContainerBounds {
2280
+ nodeId: string;
2281
+ label: string;
2282
+ lineNumber: number;
2283
+ color?: string;
2284
+ metadata: Record<string, string>;
2285
+ /** Original (unfiltered) metadata for tag-based coloring and hover dimming */
2286
+ tagMetadata: Record<string, string>;
2287
+ x: number;
2288
+ y: number;
2289
+ width: number;
2290
+ height: number;
2291
+ labelHeight: number;
2292
+ /** Count of hidden descendants when collapsed */
2293
+ hiddenCount?: number;
2294
+ /** True if container has children (expanded or collapsed) */
2295
+ hasChildren?: boolean;
2296
+ }
2297
+ interface SitemapLegendEntry {
2298
+ value: string;
2299
+ color: string;
2300
+ }
2301
+ interface SitemapLegendGroup {
2302
+ name: string;
2303
+ alias?: string;
2304
+ entries: SitemapLegendEntry[];
2305
+ x: number;
2306
+ y: number;
2307
+ width: number;
2308
+ height: number;
2309
+ minifiedWidth: number;
2310
+ minifiedHeight: number;
2311
+ }
2312
+ interface SitemapLayoutResult {
2313
+ nodes: SitemapLayoutNode[];
2314
+ edges: SitemapLayoutEdge[];
2315
+ containers: SitemapContainerBounds[];
2316
+ legend: SitemapLegendGroup[];
2317
+ width: number;
2318
+ height: number;
2319
+ }
2320
+ declare function layoutSitemap(parsed: ParsedSitemap, hiddenCounts?: Map<string, number>, activeTagGroup?: string | null, hiddenAttributes?: Set<string>, expandAllLegend?: boolean): SitemapLayoutResult;
2321
+
2322
+ declare function renderSitemap(container: HTMLDivElement, parsed: ParsedSitemap, layout: SitemapLayoutResult, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
2323
+ width?: number;
2324
+ height?: number;
2325
+ }, activeTagGroup?: string | null, hiddenAttributes?: Set<string>): void;
2326
+ declare function renderSitemapForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette?: PaletteColors): Promise<string>;
2327
+
2328
+ interface CollapsedSitemapResult {
2329
+ /** ParsedSitemap with collapsed subtrees pruned (deep-cloned, never mutates original) */
2330
+ parsed: ParsedSitemap;
2331
+ /** nodeId → count of hidden descendants */
2332
+ hiddenCounts: Map<string, number>;
2333
+ }
2334
+ declare function collapseSitemapTree(original: ParsedSitemap, collapsedIds: Set<string>): CollapsedSitemapResult;
2335
+
2336
+ /** Namespaced behavior property keys recognized by the parser. */
2337
+ type InfraBehaviorKey = 'cache-hit' | 'firewall-block' | 'ratelimit-rps' | 'latency-ms' | 'uptime' | 'instances' | 'max-rps' | 'cb-error-threshold' | 'cb-latency-threshold-ms' | 'concurrency' | 'duration-ms' | 'cold-start-ms' | 'buffer' | 'drain-rate' | 'retention-hours' | 'partitions';
2338
+ /** All recognized property keys (behavior + structural). */
2339
+ declare const INFRA_BEHAVIOR_KEYS: Set<string>;
2340
+ interface InfraProperty {
2341
+ key: string;
2342
+ value: string | number;
2343
+ lineNumber: number;
2344
+ }
2345
+ interface InfraNode {
2346
+ id: string;
2347
+ label: string;
2348
+ properties: InfraProperty[];
2349
+ groupId: string | null;
2350
+ tags: Record<string, string>;
2351
+ isEdge: boolean;
2352
+ description?: string[];
2353
+ lineNumber: number;
2354
+ }
2355
+ interface InfraEdge {
2356
+ sourceId: string;
2357
+ targetId: string;
2358
+ label: string;
2359
+ async: boolean;
2360
+ split: number | null;
2361
+ fanout: number | null;
2362
+ lineNumber: number;
2363
+ }
2364
+ interface InfraGroup {
2365
+ id: string;
2366
+ label: string;
2367
+ /** Number of instances (or auto-scaling range "N-M") of this group as a unit. */
2368
+ instances?: number | string;
2369
+ /** Whether this group should be collapsed by default in the source. */
2370
+ collapsed?: boolean;
2371
+ /** Pipe metadata on the group header, cascaded to children. */
2372
+ metadata?: Record<string, string>;
2373
+ lineNumber: number;
2374
+ }
2375
+ interface InfraTagValue {
2376
+ name: string;
2377
+ color?: string;
2378
+ }
2379
+ interface InfraTagGroup {
2380
+ name: string;
2381
+ alias: string | null;
2382
+ values: InfraTagValue[];
2383
+ /** Value of the entry marked `default` (nodes without this tag get it automatically). */
2384
+ defaultValue?: string;
2385
+ lineNumber: number;
2386
+ }
2387
+ interface ParsedInfra {
2388
+ type: 'infra';
2389
+ title: string | null;
2390
+ titleLineNumber: number | null;
2391
+ direction: 'LR' | 'TB';
2392
+ nodes: InfraNode[];
2393
+ edges: InfraEdge[];
2394
+ groups: InfraGroup[];
2395
+ tagGroups: InfraTagGroup[];
2396
+ options: Record<string, string>;
2397
+ diagnostics: DgmoError[];
2398
+ error: string | null;
2399
+ }
2400
+ interface InfraComputeParams {
2401
+ rps?: number;
2402
+ instanceOverrides?: Record<string, number>;
2403
+ /** Per-node property overrides: nodeId -> { propertyKey: numericValue }. */
2404
+ propertyOverrides?: Record<string, Record<string, number>>;
2405
+ /** Set of group IDs that should be treated as collapsed (virtual nodes). */
2406
+ collapsedGroups?: Set<string>;
2407
+ }
2408
+ type InfraCbState = 'closed' | 'open' | 'half-open';
2409
+ interface ComputedInfraNode {
2410
+ id: string;
2411
+ label: string;
2412
+ groupId: string | null;
2413
+ isEdge: boolean;
2414
+ computedRps: number;
2415
+ overloaded: boolean;
2416
+ /** True when inbound RPS exceeds the node's ratelimit-rps and traffic is being shed. */
2417
+ rateLimited: boolean;
2418
+ /** Cumulative latency from edge to this node (ms). */
2419
+ computedLatencyMs: number;
2420
+ /** Latency percentiles from this node through all downstream paths (ms). */
2421
+ computedLatencyPercentiles: InfraLatencyPercentiles;
2422
+ /** Component uptime (product of uptimes along path, 0-1). */
2423
+ computedUptime: number;
2424
+ /** Local availability at this node (0-1), factoring in uptime, overload shed, and rate-limit reject. */
2425
+ computedAvailability: number;
2426
+ /** Availability percentiles through all downstream paths from this node (0-1 fractions). */
2427
+ computedAvailabilityPercentiles: InfraAvailabilityPercentiles;
2428
+ /** Circuit breaker state. */
2429
+ computedCbState: InfraCbState;
2430
+ /** Computed instance count for auto-scaling (min-max) ranges. */
2431
+ computedInstances: number;
2432
+ /** For serverless nodes: estimated concurrent invocations (Little's Law: RPS × duration_ms / 1000). */
2433
+ computedConcurrentInvocations: number;
2434
+ /** For collapsed group virtual nodes: worst health state of any child.
2435
+ * 'overloaded' > 'warning' > 'normal'. Undefined for regular nodes. */
2436
+ childHealthState?: 'normal' | 'warning' | 'overloaded';
2437
+ /** Queue metrics — only present when buffer property exists. */
2438
+ queueMetrics?: {
2439
+ /** Messages per second filling the buffer (inbound - drain-rate, clamped to 0). */
2440
+ fillRate: number;
2441
+ /** Seconds until buffer overflow at sustained fill rate. Infinity if not filling. */
2442
+ timeToOverflow: number;
2443
+ /** Queue wait time in ms (pending_messages / drain_rate * 1000). */
2444
+ waitTimeMs: number;
2445
+ };
2446
+ properties: InfraProperty[];
2447
+ tags: Record<string, string>;
2448
+ description?: string[];
2449
+ lineNumber: number;
2450
+ }
2451
+ interface ComputedInfraEdge {
2452
+ sourceId: string;
2453
+ targetId: string;
2454
+ label: string;
2455
+ async: boolean;
2456
+ computedRps: number;
2457
+ split: number;
2458
+ fanout: number | null;
2459
+ lineNumber: number;
2460
+ }
2461
+ interface InfraDiagnostic {
2462
+ type: 'SPLIT_SUM' | 'CYCLE' | 'OVERLOAD' | 'RATE_LIMITED' | 'ORPHAN' | 'SYNTAX' | 'UPTIME';
2463
+ line: number;
2464
+ message: string;
2465
+ }
2466
+ interface InfraLatencyPercentiles {
2467
+ p50: number;
2468
+ p90: number;
2469
+ p99: number;
2470
+ }
2471
+ interface InfraAvailabilityPercentiles {
2472
+ p50: number;
2473
+ p90: number;
2474
+ p99: number;
2475
+ }
2476
+ interface ComputedInfraModel {
2477
+ nodes: ComputedInfraNode[];
2478
+ edges: ComputedInfraEdge[];
2479
+ groups: InfraGroup[];
2480
+ tagGroups: InfraTagGroup[];
2481
+ title: string | null;
2482
+ direction: 'LR' | 'TB';
2483
+ /** Diagram-level options (e.g., default-latency-ms, default-uptime). */
2484
+ options: Record<string, string>;
2485
+ /** Latency percentiles at the edge entry point (weighted by traffic probability). */
2486
+ edgeLatency: InfraLatencyPercentiles;
2487
+ /** System uptime at edge (weighted average across all paths). */
2488
+ systemUptime: number;
2489
+ /** System availability at edge (weighted average of compound availability across all paths). */
2490
+ systemAvailability: number;
2491
+ diagnostics: InfraDiagnostic[];
2492
+ }
2493
+
2494
+ declare function parseInfra(content: string): ParsedInfra;
2495
+
2496
+ declare function computeInfra(parsed: ParsedInfra, params?: InfraComputeParams): ComputedInfraModel;
2497
+
2498
+ declare function validateInfra(parsed: ParsedInfra): InfraDiagnostic[];
2499
+ /**
2500
+ * Validate computed model (post-computation warnings).
2501
+ * Call after computeInfra() to get uptime/SLA warnings.
2502
+ */
2503
+ declare function validateComputed(computed: ComputedInfraModel): InfraDiagnostic[];
2504
+
2505
+ interface InfraLayoutNode {
2506
+ id: string;
2507
+ label: string;
2508
+ x: number;
2509
+ y: number;
2510
+ width: number;
2511
+ height: number;
2512
+ computedRps: number;
2513
+ overloaded: boolean;
2514
+ rateLimited: boolean;
2515
+ isEdge: boolean;
2516
+ groupId: string | null;
2517
+ computedLatencyMs: number;
2518
+ computedLatencyPercentiles: ComputedInfraNode['computedLatencyPercentiles'];
2519
+ computedUptime: number;
2520
+ computedAvailability: number;
2521
+ computedAvailabilityPercentiles: ComputedInfraNode['computedAvailabilityPercentiles'];
2522
+ computedInstances: number;
2523
+ computedConcurrentInvocations: number;
2524
+ computedCbState: ComputedInfraNode['computedCbState'];
2525
+ childHealthState?: ComputedInfraNode['childHealthState'];
2526
+ properties: ComputedInfraNode['properties'];
2527
+ queueMetrics?: ComputedInfraNode['queueMetrics'];
2528
+ tags: Record<string, string>;
2529
+ description?: string[];
2530
+ lineNumber: number;
2531
+ }
2532
+ interface InfraLayoutEdge {
2533
+ sourceId: string;
2534
+ targetId: string;
2535
+ label: string;
2536
+ async: boolean;
2537
+ computedRps: number;
2538
+ split: number;
2539
+ fanout: number | null;
2540
+ points: {
2541
+ x: number;
2542
+ y: number;
2543
+ }[];
2544
+ lineNumber: number;
2545
+ }
2546
+ interface InfraLayoutGroup {
2547
+ id: string;
2548
+ label: string;
2549
+ x: number;
2550
+ y: number;
2551
+ width: number;
2552
+ height: number;
2553
+ instances?: number | string;
2554
+ lineNumber: number;
2555
+ }
2556
+ interface InfraLayoutResult {
2557
+ nodes: InfraLayoutNode[];
2558
+ edges: InfraLayoutEdge[];
2559
+ groups: InfraLayoutGroup[];
2560
+ /** Diagram-level options (e.g., default-latency-ms, default-uptime). */
2561
+ options: Record<string, string>;
2562
+ direction: 'LR' | 'TB';
2563
+ width: number;
2564
+ height: number;
2565
+ }
2566
+ declare function layoutInfra(computed: ComputedInfraModel, expandedNodeIds?: Set<string> | null, collapsedNodes?: Set<string> | null): InfraLayoutResult;
2567
+
2568
+ interface InfraRole {
2569
+ name: string;
2570
+ color: string;
2571
+ }
2572
+ /**
2573
+ * Infer roles from a component's properties.
2574
+ * A component can have multiple roles (e.g., Cache + Rate Limiter).
2575
+ */
2576
+ declare function inferRoles(properties: InfraProperty[]): InfraRole[];
2577
+ /**
2578
+ * Collect all unique roles present in the diagram (for legend).
2579
+ */
2580
+ declare function collectDiagramRoles(allProperties: InfraProperty[][]): InfraRole[];
2581
+
2582
+ interface InfraLegendEntry {
2583
+ value: string;
2584
+ color: string;
2585
+ /** For role: kebab-case role name. For tag: lowercase tag value. */
2586
+ key: string;
2587
+ }
2588
+ interface InfraLegendGroup {
2589
+ name: string;
2590
+ type: 'role' | 'tag';
2591
+ /** For tag groups: the key used in data-tag-* attributes (alias or name). */
2592
+ tagKey?: string;
2593
+ entries: InfraLegendEntry[];
2594
+ width: number;
2595
+ minifiedWidth: number;
2596
+ }
2597
+ /** Build legend groups from roles + tags. */
2598
+ declare function computeInfraLegendGroups(nodes: InfraLayoutNode[], tagGroups: InfraTagGroup[], palette: PaletteColors, edges?: InfraLayoutEdge[]): InfraLegendGroup[];
2599
+ interface InfraPlaybackState {
2600
+ expanded: boolean;
2601
+ paused: boolean;
2602
+ speed: number;
2603
+ speedOptions: readonly number[];
2604
+ }
2605
+ declare function renderInfra(container: HTMLDivElement, layout: InfraLayoutResult, palette: PaletteColors, isDark: boolean, title: string | null, titleLineNumber: number | null, tagGroups?: InfraTagGroup[], activeGroup?: string | null, animate?: boolean, playback?: InfraPlaybackState | null, expandedNodeIds?: Set<string> | null, exportMode?: boolean, collapsedNodes?: Set<string> | null): void;
2606
+ declare function parseAndLayoutInfra(content: string): {
2607
+ parsed: ParsedInfra;
2608
+ computed: null;
2609
+ layout: null;
2610
+ } | {
2611
+ parsed: ParsedInfra;
2612
+ computed: ComputedInfraModel;
2613
+ layout: InfraLayoutResult;
2614
+ };
2615
+
2616
+ /** Calendar units: d (days), w (weeks), m (months), q (quarters), y (years), h (hours), min (minutes). bd = business days. s = sprints. */
2617
+ type DurationUnit = 'd' | 'bd' | 'w' | 'm' | 'q' | 'y' | 'h' | 'min' | 's';
2618
+ interface Duration {
2619
+ amount: number;
2620
+ unit: DurationUnit;
2621
+ }
2622
+ interface Offset {
2623
+ duration: Duration;
2624
+ direction: 1 | -1;
2625
+ }
2626
+ interface GanttDependency {
2627
+ targetName: string;
2628
+ label?: string;
2629
+ offset?: Offset;
2630
+ lineNumber: number;
2631
+ }
2632
+ interface GanttTask {
2633
+ id: string;
2634
+ label: string;
2635
+ duration: Duration | null;
2636
+ explicitStart?: string;
2637
+ uncertain: boolean;
2638
+ progress: number | null;
2639
+ offset?: Offset;
2640
+ dependencies: GanttDependency[];
2641
+ metadata: Record<string, string>;
2642
+ lineNumber: number;
2643
+ groupPath: string[];
2644
+ comment?: string;
2645
+ }
2646
+ interface GanttGroup {
2647
+ name: string;
2648
+ color: string | null;
2649
+ metadata: Record<string, string>;
2650
+ lineNumber: number;
2651
+ children: GanttNode[];
2652
+ }
2653
+ interface GanttParallelBlock {
2654
+ kind: 'parallel';
2655
+ lineNumber: number;
2656
+ children: GanttNode[];
2657
+ }
2658
+ /** A node in the gantt tree: either a task, group, or parallel block. */
2659
+ type GanttNode = ({
2660
+ kind: 'task';
2661
+ } & GanttTask) | ({
2662
+ kind: 'group';
2663
+ } & GanttGroup) | GanttParallelBlock;
2664
+ type Weekday = 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat' | 'sun';
2665
+ interface HolidayDate {
2666
+ date: string;
2667
+ label: string;
2668
+ lineNumber: number;
2669
+ }
2670
+ interface HolidayRange {
2671
+ startDate: string;
2672
+ endDate: string;
2673
+ label: string;
2674
+ lineNumber: number;
2675
+ }
2676
+ interface GanttHolidays {
2677
+ dates: HolidayDate[];
2678
+ ranges: HolidayRange[];
2679
+ workweek: Weekday[];
2680
+ }
2681
+ interface GanttEra {
2682
+ startDate: string;
2683
+ endDate: string;
2684
+ label: string;
2685
+ color: string | null;
2686
+ lineNumber: number;
2687
+ }
2688
+ interface GanttMarker {
2689
+ date: string;
2690
+ label: string;
2691
+ color: string | null;
2692
+ lineNumber: number;
2693
+ }
2694
+ interface GanttOptions {
2695
+ start: string | null;
2696
+ title: string | null;
2697
+ titleLineNumber: number | null;
2698
+ todayMarker: 'off' | 'on' | string;
2699
+ criticalPath: boolean;
2700
+ dependencies: boolean;
2701
+ sort: 'default' | 'tag';
2702
+ defaultSwimlaneGroup: string | null;
2703
+ activeTag: string | null;
2704
+ /** Line numbers for option/block keywords — maps key to source line */
2705
+ optionLineNumbers: Record<string, number>;
2706
+ holidaysLineNumber: number | null;
2707
+ sprintLength: Duration | null;
2708
+ sprintNumber: number | null;
2709
+ sprintStart: string | null;
2710
+ sprintMode: 'auto' | 'explicit' | null;
2711
+ /** When true, render bars at full intent saturation instead of the canonical 25% tint. */
2712
+ solidFill: boolean;
2713
+ /** When true, the renderer suppresses the chart banner title. */
2714
+ noTitle: boolean;
2715
+ }
2716
+ interface ParsedGantt {
2717
+ nodes: GanttNode[];
2718
+ holidays: GanttHolidays;
2719
+ tagGroups: TagGroup[];
2720
+ eras: GanttEra[];
2721
+ markers: GanttMarker[];
2722
+ options: GanttOptions;
2723
+ diagnostics: DgmoError[];
2724
+ error: string | null;
2725
+ }
2726
+ interface ResolvedTask {
2727
+ task: GanttTask;
2728
+ startDate: Date;
2729
+ endDate: Date;
2730
+ isCriticalPath: boolean;
2731
+ isUncertain: boolean;
2732
+ isMilestone: boolean;
2733
+ groupPath: string[];
2734
+ effectiveMetadata: Record<string, string>;
2735
+ }
2736
+ interface ResolvedGroup$1 {
2737
+ name: string;
2738
+ color: string | null;
2739
+ metadata: Record<string, string>;
2740
+ startDate: Date;
2741
+ endDate: Date;
2742
+ progress: number | null;
2743
+ lineNumber: number;
2744
+ depth: number;
2745
+ }
2746
+ interface ResolvedSprint {
2747
+ number: number;
2748
+ startDate: Date;
2749
+ endDate: Date;
2750
+ }
2751
+ interface ResolvedSchedule {
2752
+ tasks: ResolvedTask[];
2753
+ groups: ResolvedGroup$1[];
2754
+ startDate: Date;
2755
+ endDate: Date;
2756
+ holidays: GanttHolidays;
2757
+ tagGroups: TagGroup[];
2758
+ eras: GanttEra[];
2759
+ markers: GanttMarker[];
2760
+ sprints: ResolvedSprint[];
2761
+ options: GanttOptions;
2762
+ diagnostics: DgmoError[];
2763
+ error: string | null;
2764
+ }
2765
+
2766
+ declare function parseGantt(content: string, palette?: PaletteColors): ParsedGantt;
2767
+
2768
+ declare function calculateSchedule(parsed: ParsedGantt): ResolvedSchedule;
2769
+
2770
+ interface GanttInteractiveOptions {
2771
+ onClickItem?: (lineNumber: number) => void;
2772
+ collapsedGroups?: Set<string>;
2773
+ onToggleGroup?: (groupName: string) => void;
2774
+ currentSwimlaneGroup?: string | null;
2775
+ onSwimlaneChange?: (group: string | null) => void;
2776
+ currentActiveGroup?: string | null;
2777
+ onActiveGroupChange?: (group: string | null) => void;
2778
+ collapsedLanes?: Set<string>;
2779
+ onToggleLane?: (laneName: string) => void;
2780
+ viewMode?: boolean;
2781
+ }
2782
+ declare function renderGantt(container: HTMLDivElement, resolved: ResolvedSchedule, palette: PaletteColors, isDark: boolean, options?: GanttInteractiveOptions, exportDims?: D3ExportDimensions): void;
2783
+ type GroupRow = {
2784
+ type: 'group';
2785
+ group: ResolvedGroup$1;
2786
+ };
2787
+ type TaskRow = {
2788
+ type: 'task';
2789
+ task: ResolvedTask;
2790
+ };
2791
+ type LaneHeaderRow = {
2792
+ type: 'lane-header';
2793
+ laneName: string;
2794
+ laneColor: string;
2795
+ aggregateProgress: number | null;
2796
+ tagKey: string;
2797
+ isCollapsed: boolean;
2798
+ laneStartDate: Date | null;
2799
+ laneEndDate: Date | null;
2800
+ };
2801
+ type Row = GroupRow | TaskRow | LaneHeaderRow;
2802
+
2803
+ declare function buildTagLaneRowList(resolved: ResolvedSchedule, swimlaneGroup: string, collapsedLanes?: Set<string>): Row[] | null;
2804
+
2805
+ interface ResolverMatch {
2806
+ task: GanttTask;
2807
+ }
2808
+ interface ResolverError {
2809
+ kind: 'not_found' | 'ambiguous';
2810
+ message: string;
2811
+ }
2812
+ type ResolverResult = ResolverMatch | ResolverError;
2813
+ /**
2814
+ * Collect all tasks from a tree of GanttNodes, annotating each with its
2815
+ * fully qualified group path (e.g., ["Backend", "API"]).
2816
+ */
2817
+ declare function collectTasks(nodes: GanttNode[]): GanttTask[];
2818
+ /**
2819
+ * Resolve a dependency target name to a task.
2820
+ *
2821
+ * Resolution strategy (greedy right-to-left):
2822
+ * 1. Try the full string as an exact task label match
2823
+ * 2. If no match, split at the last dot → group prefix + task label
2824
+ * 3. Recurse for deeper paths
2825
+ *
2826
+ * Returns a match or an error with helpful suggestions.
2827
+ */
2828
+ declare function resolveTaskName(name: string, allTasks: GanttTask[]): ResolverResult;
2829
+
2830
+ /**
2831
+ * A three-point duration estimate. Each component is a parsed
2832
+ * `Duration { amount, unit }` so mixed units (`1w 2w 3m`) are
2833
+ * preserved; the analyzer normalizes to `options.timeUnit` for
2834
+ * arithmetic.
2835
+ */
2836
+ interface DurationEstimate {
2837
+ o: Duration;
2838
+ m: Duration;
2839
+ p: Duration;
2840
+ /**
2841
+ * When true, only an M token was given on the source line and the
2842
+ * analyzer must expand O/P from confidence factors. When false, the
2843
+ * user wrote an explicit O M P triple (even when all three values
2844
+ * are equal — zero-variance is a valid, deterministic estimate).
2845
+ */
2846
+ mOnly: boolean;
2847
+ }
2848
+ /**
2849
+ * Per-activity layout-overrides shape — the diagrammo-app holds expansion
2850
+ * state in its own store and passes overrides to `relayoutPert`.
2851
+ */
2852
+ type LayoutOverrides = Record<string, {
2853
+ width: number;
2854
+ height: number;
2855
+ }>;
2856
+
2857
+ /** Layout direction. `LR` is the default; `TB` for tall chains. */
2858
+ type PertDirection = 'LR' | 'TB';
2859
+ /** `node-detail` directive value. */
2860
+ type NodeDetail = 'compact' | 'full';
2861
+ /**
2862
+ * Project schedule anchor. Mutually-exclusive at parse time:
2863
+ * - `forward` — `start-date YYYY-MM-DD` anchors source-activity ES.
2864
+ * - `backward` — `end-date YYYY-MM-DD` anchors sink-activity LF.
2865
+ * - `null` — no anchor; ES/EF/LS/LF render as numeric offsets.
2866
+ */
2867
+ type Anchor = {
2868
+ kind: 'forward';
2869
+ date: string;
2870
+ } | {
2871
+ kind: 'backward';
2872
+ date: string;
2873
+ } | null;
2874
+ /**
2875
+ * One row of the project-stats caption. Replaces the previous
2876
+ * `\n`-joined `summaryText` string with a structured shape so the
2877
+ * renderer doesn't have to recover bullet structure by splitting on
2878
+ * `\n` / `. ` and tests can assert on `isPast` directly instead of
2879
+ * matching the trailing `(latest-safe start has passed)` suffix.
2880
+ */
2881
+ interface CaptionRow {
2882
+ /** Pre-formatted caption text for this row (no leading bullet glyph). */
2883
+ text: string;
2884
+ /** 0 = top-level row; 1 = sub-row (indented under the previous level-0 row). */
2885
+ level: 0 | 1;
2886
+ /** When true, renderer paints the text italic. */
2887
+ italic?: boolean;
2888
+ /**
2889
+ * Backward-mode flag — true when the row reports a latest-safe-start
2890
+ * date that precedes `options.today`. The text already carries a
2891
+ * `(latest-safe start has passed)` suffix; the flag is for downstream
2892
+ * styling/test assertions.
2893
+ */
2894
+ isPast?: boolean;
2895
+ }
2896
+ /** Diagram-level options collected by the parser. */
2897
+ interface PertOptions {
2898
+ /** Time unit for μ/σ/ES/EF formatting and M-only heuristics. */
2899
+ timeUnit: Duration['unit'];
2900
+ /** `direction` directive. Defaults to `LR`. */
2901
+ direction: PertDirection;
2902
+ /** `node-detail` directive. Defaults to `compact`. */
2903
+ nodeDetail: NodeDetail;
2904
+ /**
2905
+ * Global confidence used to fill O/P from M-only durations.
2906
+ * Stored verbatim — analyzer applies `resolveConfidence()` to expand
2907
+ * named levels (`high`/`medium`/`low`) or `O/P` factor pairs.
2908
+ */
2909
+ confidence: string;
2910
+ /** Monte-Carlo trials for the canonical run (default 10000). */
2911
+ trials: number;
2912
+ /** Monte-Carlo seed; deterministic across machines via mulberry32. */
2913
+ seed: number;
2914
+ /** Fast-MC trials for the live duration scrubber (default 300, floor 100). */
2915
+ scrubberTrials: number;
2916
+ /**
2917
+ * Date anchor — discriminated union enforces mutual exclusion.
2918
+ * `null` when no `start-date`/`end-date` directive was authored.
2919
+ */
2920
+ anchor: Anchor;
2921
+ /** When true, the renderer suppresses the diagram banner title. */
2922
+ noTitle?: boolean;
2923
+ /**
2924
+ * `active-tag <name>` directive — selects which declared tag group
2925
+ * drives node fill via `resolveTagColor()`. `'none'` (case-insensitive)
2926
+ * suppresses tag coloring; `undefined` lets `resolveActiveTagGroup()`
2927
+ * auto-activate the first declared group.
2928
+ */
2929
+ activeTag?: string;
2930
+ /**
2931
+ * Sprint mode (mirrors Gantt's surface). Activated automatically when
2932
+ * `time-unit s` is set, or explicitly when any `sprint-*` directive
2933
+ * appears. Schedule cells render as `S<n>` instead of numeric offsets
2934
+ * or ISO dates.
2935
+ */
2936
+ sprintLength: Duration | null;
2937
+ sprintNumber: number | null;
2938
+ sprintStart: string | null;
2939
+ sprintMode: 'auto' | 'explicit' | null;
2940
+ /**
2941
+ * "Today" baked in at parse time (ISO YYYY-MM-DD). Same source as
2942
+ * `start-date now`, captured for every parse regardless of whether
2943
+ * `now` was authored. Analyzer reads this to flag past latest-safe
2944
+ * starts in backward mode; renderer surfaces it in the
2945
+ * `(as of YYYY-MM-DD)` anchor annotation. Empty string when the
2946
+ * parser was given no `now` and no `start-date now` directive (legacy
2947
+ * fixtures pre-dating this field) — consumers treat empty as
2948
+ * "no today known" and skip past-flagging.
2949
+ */
2950
+ today: string;
2951
+ }
2952
+ /**
2953
+ * A PERT activity (node). Activities have either a three-point estimate,
2954
+ * an M-only estimate (parser fills O/P from confidence factors), or no
2955
+ * estimate at all (TBD — analyzer null-poisons descendants).
2956
+ */
2957
+ interface PertActivity {
2958
+ /** Stable id — alias if `as` was given, otherwise normalized name. */
2959
+ id: string;
2960
+ /** Human-readable label as written in source. */
2961
+ name: string;
2962
+ /** Optional alias from `<name> <durs> as <id>`. */
2963
+ alias?: string;
2964
+ /**
2965
+ * Activity duration estimate.
2966
+ * - `null` → TBD (no estimate); analyzer poisons descendants with `null`.
2967
+ */
2968
+ duration: DurationEstimate | null;
2969
+ /**
2970
+ * Per-activity confidence override from pipe metadata (`| confidence: low`).
2971
+ * When unset, analyzer uses `options.confidence`.
2972
+ */
2973
+ confidence?: string;
2974
+ /** Group id this activity belongs to (post-resolve). */
2975
+ groupId?: string;
2976
+ /** Source line of the declaration site (1-based). */
2977
+ lineNumber: number;
2978
+ /** True for `milestone <name>` primitives (zero-duration, diamond shape). */
2979
+ isMilestone: boolean;
2980
+ /**
2981
+ * Resolved tag-group metadata from pipe-metadata aliases. Keys are
2982
+ * lowercased tag-group names (e.g. `priority`, `team`); values are the
2983
+ * authored tag entry names. Drives node fill via `resolveTagColor()`
2984
+ * when an `active-tag` group is set. Empty when no tag groups are
2985
+ * declared or the activity carried no tag metadata.
2986
+ */
2987
+ tags?: Record<string, string>;
2988
+ }
2989
+ /**
2990
+ * Forward-style milestone shorthand. Stored as a `PertActivity` with
2991
+ * `isMilestone: true` and a zero-duration estimate, but kept here as a
2992
+ * distinct exported alias for callers that want to filter by kind.
2993
+ */
2994
+ type PertMilestone = PertActivity & {
2995
+ isMilestone: true;
2996
+ };
2997
+ /**
2998
+ * Dependency type — defaults to FS (Finish-to-Start), the dominant case.
2999
+ * - FS: `B.ES ≥ A.EF + lag` (most edges)
3000
+ * - SS: `B.ES ≥ A.ES + lag` (parallel start)
3001
+ * - FF: `B.EF ≥ A.EF + lag` (synchronized finish)
3002
+ * - SF: `B.EF ≥ A.ES + lag` (rare; included for completeness)
3003
+ */
3004
+ type EdgeType = 'FS' | 'SS' | 'FF' | 'SF';
3005
+ /**
3006
+ * Directed dependency edge from `source` activity to `target`.
3007
+ * `type` defaults to FS, `lag` to null (zero offset). Lag amount may be
3008
+ * negative (a lead — predecessor and successor overlap).
3009
+ */
3010
+ interface PertEdge {
3011
+ source: string;
3012
+ target: string;
3013
+ lineNumber: number;
3014
+ type: EdgeType;
3015
+ lag: Duration | null;
3016
+ }
3017
+ /** Group declared via `[group-name] | metadata`. */
3018
+ interface PertGroup {
3019
+ id: string;
3020
+ name: string;
3021
+ /** Activity ids belonging to this group, populated in Pass 2. */
3022
+ activityIds: string[];
3023
+ /** Whether the user authored `| collapsed: true`. */
3024
+ collapsed: boolean;
3025
+ /** Source line of the `[group-name]` header (1-based). */
3026
+ lineNumber: number;
3027
+ /**
3028
+ * Resolved tag-group metadata for the cluster header — same shape as
3029
+ * `PertActivity.tags`. Currently informational; default-tag injection
3030
+ * skips groups (containers) so they appear "untagged" unless the user
3031
+ * authors an explicit value via pipe metadata.
3032
+ */
3033
+ tags?: Record<string, string>;
3034
+ /**
3035
+ * Auto-detected group topology (Pass 2 result).
3036
+ * - `hammock`: single entry + single exit — collapses to a super-edge.
3037
+ * - `cluster`: multi-entry or multi-exit — collapses to a bounding rect.
3038
+ */
3039
+ classification?: 'hammock' | 'cluster';
3040
+ }
3041
+ /** Output of `parsePert(content)`. */
3042
+ interface ParsedPert {
3043
+ /** Optional title parsed from `pert <title>`. */
3044
+ title: string | null;
3045
+ options: PertOptions;
3046
+ activities: PertActivity[];
3047
+ edges: PertEdge[];
3048
+ groups: PertGroup[];
3049
+ /**
3050
+ * Tag groups declared at the top of the diagram (`tag Priority as p
3051
+ * High(red), Low(green)`). Drive node fill via `resolveTagColor()`.
3052
+ * Empty when no `tag` blocks are declared.
3053
+ */
3054
+ tagGroups: TagGroup[];
3055
+ /**
3056
+ * Map alias-or-name → canonical activity id. Useful for the analyzer
3057
+ * and for editor autocomplete; also populated in Pass 2.
3058
+ */
3059
+ idMap: Record<string, string>;
3060
+ diagnostics: DgmoError[];
3061
+ /** First fatal error message; `null` when parse succeeded. */
3062
+ error: string | null;
3063
+ }
3064
+ /**
3065
+ * Fully-resolved per-activity analysis output. ES/EF/LS/LF/slack are
3066
+ * `null` for any activity downstream of a TBD (poison-propagation per
3067
+ * AC2.3).
3068
+ */
3069
+ interface ResolvedActivity {
3070
+ activity: PertActivity;
3071
+ /** Earliest start (forward pass). `null` if upstream TBD. */
3072
+ es: number | null;
3073
+ /** Earliest finish. */
3074
+ ef: number | null;
3075
+ /** Latest start (backward pass). */
3076
+ ls: number | null;
3077
+ /** Latest finish. */
3078
+ lf: number | null;
3079
+ /** Slack = LS − ES (or LF − EF). 0 = on critical path. `null` if poisoned. */
3080
+ slack: number | null;
3081
+ /** True iff the M-world critical path passes through this activity. */
3082
+ isCriticalPath: boolean;
3083
+ /** Resolved μ in `options.timeUnit` (numeric mean of o/m/p). */
3084
+ mu: number | null;
3085
+ /** Resolved σ in `options.timeUnit` (Beta-PERT std dev). */
3086
+ sigma: number | null;
3087
+ /**
3088
+ * Criticality index from Monte Carlo (0–1). `null` when MC is off or
3089
+ * when this activity is downstream of a TBD.
3090
+ */
3091
+ criticality: number | null;
3092
+ /**
3093
+ * True iff the source declared an explicit O/M/P triple. M-only,
3094
+ * TBD, and milestone activities all report `false`.
3095
+ */
3096
+ isAuthored: boolean;
3097
+ }
3098
+ /** Resolved hammock/cluster group. */
3099
+ interface ResolvedGroup {
3100
+ group: PertGroup;
3101
+ /** Aggregate μ/σ along the group's internal critical path. */
3102
+ rolledMu: number | null;
3103
+ rolledSigma: number | null;
3104
+ /** Group entry/exit ids derived in Pass 2. */
3105
+ entries: string[];
3106
+ exits: string[];
3107
+ /**
3108
+ * Rolled-up schedule envelope across member activities.
3109
+ * ES = min member.es
3110
+ * EF = max member.ef
3111
+ * LS = min member.ls
3112
+ * LF = max member.lf
3113
+ * slack = LS − ES
3114
+ * criticality = max member.criticality (when MC is on)
3115
+ * Each is `null` when no member has a non-null value (e.g. all-TBD group).
3116
+ */
3117
+ es: number | null;
3118
+ ef: number | null;
3119
+ ls: number | null;
3120
+ lf: number | null;
3121
+ slack: number | null;
3122
+ criticality: number | null;
3123
+ }
3124
+ /**
3125
+ * Bare shape for a Monte-Carlo simulation result; Phase 2 fills it.
3126
+ * Keeping the shape exported in v1 means analyzer consumers don't break
3127
+ * when MC support lands.
3128
+ */
3129
+ interface MonteCarloResult {
3130
+ /** Trials run (canonical or fast). */
3131
+ trials: number;
3132
+ /** Seed used for deterministic reproduction. */
3133
+ seed: number;
3134
+ /** Project-completion percentiles. */
3135
+ p50: number;
3136
+ p80: number;
3137
+ p95: number;
3138
+ /**
3139
+ * Central ~68% band — empirical equivalent of a ±1σ window. Used by
3140
+ * the S-curve to draw a "where the project most likely lands" shaded
3141
+ * region without assuming the finish-time distribution is normal.
3142
+ */
3143
+ p16: number;
3144
+ p84: number;
3145
+ /**
3146
+ * Empirical lower bound — minimum trial duration in canonical days.
3147
+ * Used by the S-curve to anchor its x-axis at the actually-observed
3148
+ * span rather than an analytical extrapolation. Backward-mode reads
3149
+ * this through `end_date − max` to land the left edge of the
3150
+ * candidate-start axis.
3151
+ */
3152
+ minDurationDays: number;
3153
+ /**
3154
+ * Empirical upper bound — maximum trial duration in canonical days.
3155
+ * Symmetric counterpart to `minDurationDays`. Backward-mode reads
3156
+ * this as the latest candidate start that still has a chance of
3157
+ * hitting the deadline.
3158
+ */
3159
+ maxDurationDays: number;
3160
+ /** Per-activity criticality index, keyed by activity id. */
3161
+ criticalityByActivity: Record<string, number>;
3162
+ /** Modal-longest-path tuple (activity ids). */
3163
+ modalCriticalPath: string[];
3164
+ /**
3165
+ * Per-activity tornado swings — how much the project end-date
3166
+ * moves when this activity comes in at its optimistic (O) or
3167
+ * pessimistic (P) extreme while every other activity stays at
3168
+ * its mean (μ). Sorted descending by total swing.
3169
+ *
3170
+ * `lowSwing` and `highSwing` are in canonical days (≥ 0).
3171
+ * Renderer converts to display unit.
3172
+ */
3173
+ tornadoSwings: TornadoSwing[];
3174
+ }
3175
+ /**
3176
+ * One row of a true two-sided tornado: the project end-date moves
3177
+ * lowSwing days earlier when the activity is at its optimistic
3178
+ * extreme, and highSwing days later when at its pessimistic extreme.
3179
+ * All other activities held at their μ.
3180
+ */
3181
+ interface TornadoSwing {
3182
+ id: string;
3183
+ name: string;
3184
+ /** Days the project finishes EARLIER when this activity ≈ O. */
3185
+ lowSwing: number;
3186
+ /** Days the project finishes LATER when this activity ≈ P. */
3187
+ highSwing: number;
3188
+ /** Per-activity MC criticality index, used by the renderer for bar color. */
3189
+ criticality: number | null;
3190
+ }
3191
+ /**
3192
+ * Per-activity (O, M, P) in canonical days — the analyzer's
3193
+ * expanded-estimate cache, populated for every activity that has an
3194
+ * estimate (TBDs are omitted). Workers re-running Monte Carlo on an
3195
+ * already-resolved PERT can read this directly instead of re-parsing
3196
+ * + re-expanding from source.
3197
+ */
3198
+ interface PertExpandedActivity {
3199
+ id: string;
3200
+ o: number;
3201
+ m: number;
3202
+ p: number;
3203
+ }
3204
+ interface ResolvedPert {
3205
+ options: PertOptions;
3206
+ activities: ResolvedActivity[];
3207
+ edges: PertEdge[];
3208
+ groups: ResolvedGroup[];
3209
+ /**
3210
+ * Tag groups copied from the parsed source. The renderer reads this
3211
+ * + `options.activeTag` to drive node fill via `resolveTagColor()`
3212
+ * and to render the legend.
3213
+ */
3214
+ tagGroups: TagGroup[];
3215
+ /**
3216
+ * Analysis mode auto-derived from data: `monte-carlo` when at least
3217
+ * one non-milestone activity carries an O/M/P triple AND `trials >= 100`,
3218
+ * otherwise `analytical`.
3219
+ */
3220
+ mode: 'monte-carlo' | 'analytical';
3221
+ /**
3222
+ * Project-stats caption rows. Each row is one bullet in the rendered
3223
+ * caption box; level-1 rows render indented under the preceding
3224
+ * level-0 row. Null only when analysis bails out before producing
3225
+ * any output (e.g. cycle detection); non-null in every successful
3226
+ * analyze() run.
3227
+ */
3228
+ summaryRows: CaptionRow[] | null;
3229
+ /**
3230
+ * One-line project summary rendered as a subtitle under the diagram title.
3231
+ * Shape per mode (see §13A.7):
3232
+ * - Forward: `Expected finish: <date> · ≈ <μ> <unit> of work (± <σ>)`
3233
+ * - Backward: `Expected start: <date> · ≈ <μ> <unit> lead time (± <σ>)`
3234
+ * - Unanchored: `≈ <μ> <unit> (± <σ>)`
3235
+ * Null when analysis bails out before producing any output.
3236
+ */
3237
+ projectSubtitle: string | null;
3238
+ /** μ along the M-world critical path (max EF over all activities). */
3239
+ projectMu: number | null;
3240
+ /** σ along the M-world critical path (sqrt of variance sum). */
3241
+ projectSigma: number | null;
3242
+ /** Critical-path activity ids in topological order. */
3243
+ criticalPath: string[];
3244
+ /**
3245
+ * Anchored mode: the date all four schedule labels (ES/EF/LS/LF) are
3246
+ * computed off. Forward = start-date; backward = end-date − projectMu;
3247
+ * null otherwise (no anchor, or backward + TBD upstream).
3248
+ */
3249
+ projectStart: string | null;
3250
+ /** Populated when `mode === 'monte-carlo'`. */
3251
+ monteCarloResult: MonteCarloResult | null;
3252
+ /**
3253
+ * Per-activity (O, M, P) in canonical days. Always populated; used
3254
+ * by Phase 3b Worker / scrubber so the simulator can re-run on a
3255
+ * postMessage-cloned ResolvedPert without needing the original
3256
+ * ParsedPert or analyzer state.
3257
+ */
3258
+ expandedActivities: PertExpandedActivity[];
3259
+ diagnostics: DgmoError[];
3260
+ error: string | null;
3261
+ }
3262
+ interface PertLayoutNode {
3263
+ id: string;
3264
+ x: number;
3265
+ y: number;
3266
+ width: number;
3267
+ height: number;
3268
+ }
3269
+ interface PertLayoutEdge {
3270
+ source: string;
3271
+ target: string;
3272
+ points: {
3273
+ x: number;
3274
+ y: number;
3275
+ }[];
3276
+ }
3277
+ interface PertLayoutGroup {
3278
+ id: string;
3279
+ x: number;
3280
+ y: number;
3281
+ width: number;
3282
+ height: number;
3283
+ classification: 'hammock' | 'cluster';
3284
+ /**
3285
+ * True when the group is currently collapsed. Layout sized this rect
3286
+ * as a single rolled-up node and hid the group's member activities
3287
+ * from `nodes` / re-routed external edges to land on this rect.
3288
+ */
3289
+ collapsed?: boolean;
3290
+ }
3291
+ interface LayoutResult {
3292
+ nodes: PertLayoutNode[];
3293
+ edges: PertLayoutEdge[];
3294
+ groups: PertLayoutGroup[];
3295
+ width: number;
3296
+ height: number;
3297
+ }
3298
+
3299
+ interface ParsePertOptions {
3300
+ /**
3301
+ * "Today" reference for `start-date now` and `options.today`. Defaults
3302
+ * to `new Date()` at call time; tests inject a fixed date for
3303
+ * deterministic snapshots and past-row assertions.
3304
+ */
3305
+ now?: Date;
3306
+ /**
3307
+ * Active palette — used when resolving color names on `tag` entries
3308
+ * (e.g. `High(red)` → palette.colors.red). Optional; when omitted the
3309
+ * universal default color map is used.
3310
+ */
3311
+ palette?: PaletteColors;
3312
+ }
3313
+ declare function parsePert(content: string, parseOpts?: ParsePertOptions): ParsedPert;
3314
+ declare function extractPertSymbols(docText: string): DiagramSymbols;
3315
+ /**
3316
+ * Returns true when content lacks an explicit chart type but reads as a
3317
+ * PERT diagram. Per spec § Implementation Decisions: drop the
3318
+ * "three-number durations" heuristic (too generic) — require any of:
3319
+ * (a) literal `pert` chart-type line (already handled by parseFirstLine)
3320
+ * (b) an `analysis monte-carlo` directive
3321
+ *
3322
+ * This function is for case (b) inference — case (a) is handled upstream.
3323
+ */
3324
+ declare function looksLikePert(content: string): boolean;
3325
+
3326
+ declare function analyzePert(parsed: ParsedPert): ResolvedPert;
3327
+
3328
+ declare function layoutPert(resolved: ResolvedPert): LayoutResult;
3329
+ declare function relayoutPert(resolved: ResolvedPert, overrides: LayoutOverrides, collapsedGroupIds?: ReadonlySet<string>): LayoutResult;
3330
+
3331
+ /**
3332
+ * Substitute `start-date now` with the host-local resolved date.
3333
+ * Pass the result to `encodeDiagramUrl` so the share-link captures
3334
+ * the resolved date, not the literal token.
3335
+ *
3336
+ * Lines without `start-date now` (explicit-date lines, comments,
3337
+ * other directives, activity lines containing the word "now") pass
3338
+ * through verbatim.
3339
+ */
3340
+ declare function normalizePertSourceForShare(dsl: string): string;
3341
+
3342
+ /**
3343
+ * mulberry32: 32-bit seedable PRNG. Portable, deterministic, ~10 lines.
3344
+ * Returns a function that yields [0, 1).
3345
+ */
3346
+ declare function mulberry32(seed: number): () => number;
3347
+ /**
3348
+ * Sample one duration from a Beta-PERT distribution defined by (O, M, P).
3349
+ * Zero-variance case (O = M = P) bypasses sampling deterministically.
3350
+ */
3351
+ declare function sampleBetaPert(o: number, m: number, p: number, rng: () => number): number;
3352
+ interface ExpandedActivity {
3353
+ id: string;
3354
+ o: number;
3355
+ m: number;
3356
+ p: number;
3357
+ }
3358
+ interface SimulateOptions {
3359
+ trials: number;
3360
+ seed: number;
3361
+ }
3362
+ /**
3363
+ * Build a runnable simulation context from a `ResolvedPert`. The
3364
+ * analyzer will call this then invoke `simulateCanonical` /
3365
+ * `simulateFast` on the result.
3366
+ */
3367
+ declare function buildSimulationContext(resolved: ResolvedPert): {
3368
+ predecessors: Map<string, string[]>;
3369
+ successors: Map<string, string[]>;
3370
+ topo: string[];
3371
+ terminals: string[];
3372
+ poisoned: Set<string>;
3373
+ };
3374
+ /**
3375
+ * Canonical simulation — N=10000 by default. Used for static export
3376
+ * and the "computing…" Worker job in the app.
3377
+ */
3378
+ declare function simulateCanonical(resolved: ResolvedPert, expanded: ExpandedActivity[], opts: SimulateOptions): MonteCarloResult;
3379
+ /**
3380
+ * Fast simulation — N=300 by default. Used by the duration scrubber for
3381
+ * sub-100ms re-analysis on each rAF tick.
3382
+ */
3383
+ declare function simulateFast(resolved: ResolvedPert, expanded: ExpandedActivity[], opts: SimulateOptions): MonteCarloResult;
3384
+
3385
+ interface PertRenderOptions {
3386
+ /** Optional title rendered above the diagram. */
3387
+ title?: string | null;
3388
+ /**
3389
+ * Optional one-line project subtitle rendered under the title (or in
3390
+ * the title slot when the title is suppressed via `no-title`). Carries
3391
+ * the project-level μ ± σ + anchor-derived date(s) so the duration
3392
+ * stays visible even when the Analysis row is toggled off. Pass `null`
3393
+ * to suppress (the desktop preview does this — it draws an HTML
3394
+ * subtitle below the React `<h1>` instead). Typically wired from
3395
+ * `resolved.projectSubtitle`.
3396
+ */
3397
+ subtitle?: string | null;
3398
+ /** Optional callback for click → editor sync. */
3399
+ onClickItem?: (lineNumber: number) => void;
3400
+ /**
3401
+ * Override container dimensions during export. Treated as a hint:
3402
+ * the renderer will expand height/width if needed to fit chrome
3403
+ * (title + backward-anchor annotation + diagram body + caption
3404
+ * block) so the diagram never clips. Pass `undefined` (or omit) to
3405
+ * use the auto-computed natural size.
3406
+ */
3407
+ exportDims?: {
3408
+ width?: number;
3409
+ height?: number;
3410
+ };
3411
+ /**
3412
+ * Group ids that should render as a single collapsed surface.
3413
+ * When set, the renderer:
3414
+ * - draws the group rect with a solid fill and the rolled-up
3415
+ * attribute body (μ / σ / slack / ES·EF / LS·LF / criticality)
3416
+ * - skips every activity node whose `groupId` is in this set
3417
+ * - skips every edge whose source AND target are both inside a
3418
+ * collapsed group (i.e. internal-only edges)
3419
+ */
3420
+ collapsedGroupIds?: readonly string[];
3421
+ /**
3422
+ * Render the 3×2 field-reference mini-card to the right of the
3423
+ * Summary box. Helps presenters explain what each schedule cell
3424
+ * (ES / dur / EF / LS / slack / LF) means while reviewing the
3425
+ * diagram. Off by default; the desktop app turns it on with the
3426
+ * "Field labels" toggle.
3427
+ */
3428
+ showFieldLegend?: boolean;
3429
+ /**
3430
+ * Render the top legend (Critical Path / Anchor / Milestone pills)
3431
+ * inside the SVG, between the title and the diagram. Defaults to
3432
+ * true so CLI exports and share-link images include the legend; the
3433
+ * desktop preview flips it off and renders the legend in a sibling
3434
+ * native-pixel SVG instead, so the pill text stays at intended size
3435
+ * even when the diagram SVG gets scale-to-fit'd into the panel.
3436
+ */
3437
+ showTopLegend?: boolean;
3438
+ /**
3439
+ * Render the project-stats Summary box below the diagram. Defaults
3440
+ * to true so CLI exports / share-link images keep showing it; the
3441
+ * desktop app's cog has a "Summary" toggle that flips this off when
3442
+ * readers want a cleaner chart.
3443
+ */
3444
+ showSummary?: boolean;
3445
+ /**
3446
+ * Render the Tornado sensitivity chart below the diagram. Reads
3447
+ * existing Monte-Carlo output (criticality + per-activity sigma)
3448
+ * and ranks activities by Schedule Sensitivity Index. Off by
3449
+ * default; the desktop app exposes it as a cog toggle.
3450
+ * When MC didn't run (analytical mode), the widget renders nothing.
3451
+ */
3452
+ showTornado?: boolean;
3453
+ /**
3454
+ * Render the S-curve (cumulative completion probability) below the
3455
+ * diagram. Reads the empirical CDF of Monte-Carlo trial finish times
3456
+ * — gives readers the full distribution shape, not just three
3457
+ * percentile dates. Off by default. Silently omits when MC didn't
3458
+ * run.
3459
+ */
3460
+ showScurve?: boolean;
3461
+ /**
3462
+ * Programmatic override for the active tag group — wins over
3463
+ * `options.activeTag` from the parsed source. Used by the desktop
3464
+ * preview when the user clicks a tag-legend pill: that interaction
3465
+ * sets the override (without mutating the parsed source) and
3466
+ * triggers a re-render with the new coloring. Pass `null` (or
3467
+ * `'none'`) to explicitly suppress tag coloring; omit to fall
3468
+ * through to the parsed `active-tag` directive.
3469
+ */
3470
+ activeTagOverride?: string | null;
3471
+ }
3472
+ declare function renderPert(container: HTMLDivElement, resolved: ResolvedPert, layout: LayoutResult, palette: PaletteColors, isDark: boolean, options?: PertRenderOptions): void;
3473
+ declare function renderPertForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors,
3474
+ /**
3475
+ * Optional parse-time "today" override. Threads through to
3476
+ * `parsePert({ now })` so the analyzer's backward-mode past-date
3477
+ * check + the anchor annotation's "(as of YYYY-MM-DD)" suffix stay
3478
+ * deterministic. Test snapshots pin this; production code omits it.
3479
+ */
3480
+ now?: Date): string;
3481
+ /**
3482
+ * Measure (without painting) the natural dimensions the analysis layer
3483
+ * would consume at the given width. Used by callers that need to lay
3484
+ * out the analysis SVG alongside other content — most importantly the
3485
+ * desktop preview, which fits diagram + analysis into a fixed panel
3486
+ * height by scaling proportionally when natural sizes overflow.
3487
+ */
3488
+ declare function measurePertAnalysisBlock(resolved: ResolvedPert, width: number, options: {
3489
+ showSummary?: boolean;
3490
+ showTornado?: boolean;
3491
+ showScurve?: boolean;
3492
+ showFieldLegend?: boolean;
3493
+ }): {
3494
+ width: number;
3495
+ height: number;
3496
+ };
3497
+ /**
3498
+ * Render the PERT analysis layer (Summary + Tornado + S-curve + Field
3499
+ * labels) into its own sibling SVG at native pixel size. Used by the
3500
+ * desktop preview so the analysis text stays at intended size even when
3501
+ * the main diagram SVG is scale-to-fit'd into the panel.
3502
+ */
3503
+ declare function renderPertAnalysisBlock(container: HTMLDivElement, resolved: ResolvedPert, palette: PaletteColors, isDark: boolean, options: {
3504
+ width: number;
3505
+ showSummary?: boolean;
3506
+ showTornado?: boolean;
3507
+ showScurve?: boolean;
3508
+ showFieldLegend?: boolean;
3509
+ }): void;
3510
+ /**
3511
+ * Fade everything in the diagram that doesn't belong to the given
3512
+ * legend set (`'critical'`, `'anchor'`, or `'milestone'`). Auto-detects
3513
+ * MC vs analytical mode for the critical-path rule.
3514
+ *
3515
+ * No-op when nothing qualifies (e.g. hovering Anchor on a diagram with
3516
+ * no anchor — shouldn't happen because the pill wouldn't render, but
3517
+ * defensive). The React layer is responsible for resetting via
3518
+ * `resetPertHighlight` when hover/click goes away.
3519
+ */
3520
+ declare function highlightPertSet(container: Element, kind: LegendKind): void;
3521
+ /**
3522
+ * Critical-path-specific shorthand for `highlightPertSet(container,
3523
+ * 'critical')`. Kept for backwards compatibility with existing callers.
3524
+ */
3525
+ declare function highlightPertCriticalPath(container: Element): void;
3526
+ /**
3527
+ * Reset opacities applied by `highlightPertSet`. Safe to call when no
3528
+ * highlight is active.
3529
+ */
3530
+ declare function resetPertHighlight(container: Element): void;
3531
+ /**
3532
+ * Backwards-compatible alias for `resetPertHighlight`.
3533
+ */
3534
+ declare function resetPertCriticalPath(container: Element): void;
3535
+ /**
3536
+ * Render the 3×2 PERT-field reference card. A neutral-tinted rounded
3537
+ * rect with a "Activity card fields" header band on top (mirroring the
3538
+ * Summary's typographic idiom) and a 3×2 grid of labeled definitions
3539
+ * below — so the cells map 1-to-1 to the schedule cells of every
3540
+ * activity card without pretending to be a node themselves.
3541
+ *
3542
+ * The cell content is vertically centered inside each row, so the
3543
+ * legend looks balanced whether it's sized to a tall Summary (lots of
3544
+ * bullets) or its compact default height.
3545
+ *
3546
+ * Cell order follows `drawTextbookCard`:
3547
+ * top: [ Early Start | Duration | Early Finish ]
3548
+ * bottom: [ Late Start | Slack | Late Finish ]
3549
+ */
3550
+ type LegendKind = 'critical' | 'anchor' | 'milestone';
3551
+ interface LegendEntry {
3552
+ kind: LegendKind;
3553
+ label: string;
3554
+ }
3555
+ /**
3556
+ * Returns the PERT-specific legend entries (Critical Path / Anchor /
3557
+ * Milestone). Tag groups are rendered separately via the shared
3558
+ * `renderLegendD3` helper so they get the standard collapsible-capsule
3559
+ * treatment used by org / kanban / gantt.
3560
+ */
3561
+ declare function pertLegendEntries(resolved: ResolvedPert): LegendEntry[];
3562
+ interface LegendBlockArgs {
3563
+ x: number;
3564
+ y: number;
3565
+ width: number;
3566
+ palette: PaletteColors;
3567
+ isDark: boolean;
3568
+ }
3569
+ /**
3570
+ * Render the top-legend pill row. Each pill carries
3571
+ * `data-legend-entry="critical|anchor|milestone"` so the React layer
3572
+ * can attach hover/click wiring to fade the matching set.
3573
+ *
3574
+ * Visual style mirrors the shared `renderLegendD3` pill convention so
3575
+ * PERT looks consistent with Cycle / Mindmap / BoxesAndLines: 28px tall,
3576
+ * fully-rounded rx, mix-fill against surface, no stroke, 11pt label.
3577
+ */
3578
+ declare const PERT_LEGEND_PILL_HEIGHT = 28;
3579
+ declare function pertLegendBlockWidth(entries: LegendEntry[]): number;
3580
+ declare function renderLegendBlock(svg: d3Selection.Selection<SVGSVGElement, unknown, null, undefined>, entries: LegendEntry[], args: LegendBlockArgs): void;
3581
+
3582
+ interface MindmapNode {
3583
+ id: string;
3584
+ label: string;
3585
+ description?: string[];
3586
+ metadata: Record<string, string>;
3587
+ children: MindmapNode[];
3588
+ parentId: string | null;
3589
+ lineNumber: number;
3590
+ color?: string;
3591
+ collapsed?: boolean;
3592
+ }
3593
+ interface ParsedMindmap {
3594
+ title: string | null;
3595
+ titleLineNumber: number | null;
3596
+ roots: MindmapNode[];
3597
+ tagGroups: TagGroup[];
3598
+ options: Record<string, string>;
3599
+ diagnostics: DgmoError[];
3600
+ error: string | null;
3601
+ }
3602
+ interface MindmapLayoutNode {
3603
+ id: string;
3604
+ label: string;
3605
+ description?: string[];
3606
+ metadata: Record<string, string>;
3607
+ lineNumber: number;
3608
+ color?: string;
3609
+ x: number;
3610
+ y: number;
3611
+ width: number;
3612
+ height: number;
3613
+ depth: number;
3614
+ angle: number;
3615
+ radius: number;
3616
+ hiddenCount?: number;
3617
+ hasChildren?: boolean;
3618
+ }
3619
+ interface MindmapLayoutEdge {
3620
+ sourceId: string;
3621
+ targetId: string;
3622
+ path: string;
3623
+ }
3624
+ interface MindmapLayoutResult {
3625
+ nodes: MindmapLayoutNode[];
3626
+ edges: MindmapLayoutEdge[];
3627
+ width: number;
3628
+ height: number;
3629
+ }
3630
+
3631
+ declare function parseMindmap(content: string, palette?: PaletteColors): ParsedMindmap;
3632
+
3633
+ declare function layoutMindmap(parsed: ParsedMindmap, _palette: PaletteColors, options?: {
3634
+ interactive?: boolean;
3635
+ hiddenCounts?: Map<string, number>;
3636
+ activeTagGroup?: string | null;
3637
+ hideDescriptions?: boolean;
3638
+ }): MindmapLayoutResult;
3639
+
3640
+ declare function renderMindmap(container: HTMLDivElement, parsed: ParsedMindmap, layout: MindmapLayoutResult, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
3641
+ width?: number;
3642
+ height?: number;
3643
+ }, onToggleNode?: (nodeId: string) => void, hideDescriptions?: boolean, activeTagGroup?: string | null, options?: {
3644
+ colorByDepth?: boolean;
3645
+ onToggleColorByDepth?: (active: boolean) => void;
3646
+ onToggleDescriptions?: (active: boolean) => void;
3647
+ controlsExpanded?: boolean;
3648
+ onToggleControlsExpand?: () => void;
3649
+ }): void;
3650
+ declare function renderMindmapForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
3651
+
3652
+ interface CollapsedMindmapResult {
3653
+ /** Roots with collapsed subtrees pruned (deep-cloned, never mutates original) */
3654
+ roots: MindmapNode[];
3655
+ /** nodeId → count of hidden descendants */
3656
+ hiddenCounts: Map<string, number>;
3657
+ }
3658
+ declare function collapseMindmapTree(roots: MindmapNode[], collapsedIds: Set<string>): CollapsedMindmapResult;
3659
+
3660
+ /**
3661
+ * All wireframe element types.
3662
+ * Visual-mnemonic elements are inferred from bracket syntax;
3663
+ * keyword elements use a small vocabulary (9 keywords).
3664
+ */
3665
+ type WireframeElementType = 'group' | 'textInput' | 'button' | 'dropdown' | 'checkbox' | 'radio' | 'heading' | 'divider' | 'text' | 'listItem' | 'nav' | 'tabs' | 'table' | 'image' | 'modal' | 'skeleton' | 'alert' | 'progress' | 'chart';
3666
+ /**
3667
+ * Single flat interface for all wireframe elements (ADR-8).
3668
+ * No separate WireframeGroup — all elements carry group fields
3669
+ * with sensible defaults (isContainer=false, orientation='vertical', isSkeleton=false).
3670
+ */
3671
+ interface WireframeElement {
3672
+ id: string;
3673
+ type: WireframeElementType;
3674
+ /** Display label / placeholder text / heading text */
3675
+ label: string;
3676
+ /** Child elements (non-empty only when isContainer=true) */
3677
+ children: WireframeElement[];
3678
+ /** Pipe metadata key-value pairs */
3679
+ metadata: Record<string, string>;
3680
+ /** State keywords: disabled, active, ghost, destructive, etc. */
3681
+ states: string[];
3682
+ /** Free-text annotations from pipe metadata */
3683
+ annotations: string[];
3684
+ /** 1-based line number in source */
3685
+ lineNumber: number;
3686
+ /** Measured indentation (column) */
3687
+ indent: number;
3688
+ /** True when element has children (set during parse via indent stack) */
3689
+ isContainer: boolean;
3690
+ /** Stacking direction for group children */
3691
+ orientation: 'vertical' | 'horizontal';
3692
+ /** True when inside a skeleton block */
3693
+ isSkeleton: boolean;
3694
+ /** Heading level: 1 for `#`, 2 for `##` */
3695
+ headingLevel?: number;
3696
+ /** Dropdown options (for type='dropdown') */
3697
+ options?: string[];
3698
+ /** Checked state (for type='checkbox') */
3699
+ checked?: boolean;
3700
+ /** Selected state (for type='radio') */
3701
+ selected?: boolean;
3702
+ /** Image hint: 'default' | 'round' | 'wide' */
3703
+ imageHint?: 'default' | 'round' | 'wide';
3704
+ /** Progress value 0-100 (for type='progress') */
3705
+ progressValue?: number;
3706
+ /** Chart hint: 'line' | 'bar' | 'pie' */
3707
+ chartHint?: 'line' | 'bar' | 'pie';
3708
+ /** Table dimensions for skeleton shorthand (for type='table') */
3709
+ tableRows?: number;
3710
+ tableCols?: number;
3711
+ /** Table header row labels (for type='table') */
3712
+ tableHeaders?: string[];
3713
+ /** Table data rows — each row is an array of cell content strings (for type='table') */
3714
+ tableData?: string[][];
3715
+ /** Inline elements on the same line (multi-element line) */
3716
+ inlineElements?: WireframeElement[];
3717
+ /** Label element for label-field pairing */
3718
+ labelFor?: WireframeElement;
3719
+ /** Color from tag system */
3720
+ color?: string;
3721
+ /** Field variant: password, textarea */
3722
+ fieldVariant?: 'password' | 'textarea';
3723
+ }
3724
+ /** Form factor / layout mode */
3725
+ type WireframeFormFactor = 'desktop' | 'mobile';
3726
+ interface ParsedWireframe {
3727
+ title: string | null;
3728
+ titleLineNumber: number | null;
3729
+ formFactor: WireframeFormFactor;
3730
+ /** Top-level elements (roots of the hierarchy) */
3731
+ roots: WireframeElement[];
3732
+ /** Modal elements (rendered separately below main) */
3733
+ modals: WireframeElement[];
3734
+ tagGroups: TagGroup[];
3735
+ options: Record<string, string>;
3736
+ diagnostics: DgmoError[];
3737
+ error: string | null;
3738
+ }
3739
+
3740
+ declare function parseWireframe(content: string): ParsedWireframe;
3741
+
3742
+ interface WireframeLayoutNode {
3743
+ id: string;
3744
+ x: number;
3745
+ y: number;
3746
+ width: number;
3747
+ height: number;
3748
+ element: WireframeElement;
3749
+ children: WireframeLayoutNode[];
3750
+ /** For label-field pairs: the x offset where fields align */
3751
+ fieldAlignX?: number;
3752
+ }
3753
+ interface WireframeLayout {
3754
+ width: number;
3755
+ height: number;
3756
+ titleHeight: number;
3757
+ nodes: WireframeLayoutNode[];
3758
+ modalNodes: WireframeLayoutNode[];
3759
+ }
3760
+ declare function layoutWireframe(parsed: ParsedWireframe, _options?: Record<string, string>, overrideWidth?: number, showGroupLabels?: boolean): WireframeLayout;
3761
+
3762
+ interface WireframeRenderOptions {
3763
+ exportDims?: {
3764
+ width?: number;
3765
+ height?: number;
3766
+ };
3767
+ theme?: string;
3768
+ onClickItem?: (lineNumber: number) => void;
3769
+ /** Controls group state */
3770
+ controlsExpanded?: boolean;
3771
+ fitWidth?: boolean;
3772
+ showGroupLabels?: boolean;
3773
+ onControlsExpand?: () => void;
3774
+ onControlsToggle?: (id: string, active: boolean) => void;
3775
+ }
3776
+ declare function renderWireframe(container: HTMLDivElement, parsed: ParsedWireframe, layout: WireframeLayout, palette: PaletteColors, isDark: boolean, _onClickItem?: (lineNumber: number) => void, exportDims?: {
3777
+ width?: number;
3778
+ height?: number;
3779
+ }, theme?: string, options?: WireframeRenderOptions): void;
3780
+
3781
+ type QuadrantPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
3782
+ type BlipTrend = 'new' | 'up' | 'down' | 'stable';
3783
+ interface TechRadarRing {
3784
+ name: string;
3785
+ alias: string | null;
3786
+ lineNumber: number;
3787
+ }
3788
+ interface TechRadarBlip {
3789
+ name: string;
3790
+ ring: string;
3791
+ trend: BlipTrend | null;
3792
+ description: string[];
3793
+ lineNumber: number;
3794
+ /** Assigned after parsing — global numbering across all quadrants. */
3795
+ globalNumber: number;
3796
+ }
3797
+ interface TechRadarQuadrant {
3798
+ name: string;
3799
+ position: QuadrantPosition;
3800
+ color: string | null;
3801
+ lineNumber: number;
3802
+ blips: TechRadarBlip[];
3803
+ }
3804
+ interface ParsedTechRadar {
3805
+ type: 'tech-radar';
3806
+ title: string;
3807
+ titleLineNumber: number;
3808
+ rings: TechRadarRing[];
3809
+ quadrants: TechRadarQuadrant[];
3810
+ options: Record<string, string>;
3811
+ diagnostics: DgmoError[];
3812
+ error: string | null;
3813
+ }
3814
+ interface TechRadarLayoutPoint {
3815
+ blip: TechRadarBlip;
3816
+ x: number;
3817
+ y: number;
3818
+ quadrantIndex: number;
3819
+ ringIndex: number;
3820
+ }
3821
+ interface TechRadarRenderOptions {
3822
+ /** Whether the blip listing is visible. Default: true for export, false for interactive. */
3823
+ showListing?: boolean;
3824
+ /** Callback when the listing toggle is clicked. */
3825
+ onToggleListing?: (show: boolean) => void;
3826
+ /** Whether the controls legend capsule is expanded. */
3827
+ controlsExpanded?: boolean;
3828
+ /** Callback when the controls gear pill is clicked (expand/collapse). */
3829
+ onToggleControlsExpand?: () => void;
3830
+ /** Active legend group name (e.g. 'Trends'). */
3831
+ activeLegendGroup?: string | null;
3832
+ /** Callback when a legend group pill is toggled. */
3833
+ onLegendGroupToggle?: (groupName: string) => void;
3834
+ /** Active line from the editor cursor — triggers popover/expansion for that blip. */
3835
+ activeLine?: number | null;
3836
+ }
3837
+
3838
+ declare function parseTechRadar(content: string): ParsedTechRadar;
3839
+
3840
+ /**
3841
+ * Compute deterministic, non-overlapping blip positions for a tech radar.
3842
+ *
3843
+ * Each blip is positioned within its ring+quadrant slice using polar coordinates,
3844
+ * then converted to cartesian. The algorithm is:
3845
+ * - Stable: changes in one slice don't affect other slices
3846
+ * - Deterministic: same input always produces same output
3847
+ * - Collision-avoiding: nudges overlapping blips radially within their ring band
3848
+ */
3849
+ declare function computeRadarLayout(parsed: ParsedTechRadar, width: number, height: number): TechRadarLayoutPoint[];
3850
+ /**
3851
+ * Get the center and max radius for a radar at the given dimensions.
3852
+ * Useful for renderers that need these values independently.
3853
+ */
3854
+ declare function getRadarGeometry(width: number, height: number, ringCount: number): {
3855
+ cx: number;
3856
+ cy: number;
3857
+ maxRadius: number;
3858
+ ringBandWidth: number;
3859
+ };
3860
+
3861
+ declare function renderTechRadar(container: HTMLDivElement, parsed: ParsedTechRadar, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: D3ExportDimensions, viewState?: CompactViewState, options?: TechRadarRenderOptions): void;
3862
+ declare function renderTechRadarForExport(container: HTMLDivElement, parsed: ParsedTechRadar, palette: PaletteColors, isDark: boolean, exportDims?: D3ExportDimensions, viewState?: CompactViewState): void;
3863
+
3864
+ declare function renderQuadrantFocus(container: HTMLDivElement, parsed: ParsedTechRadar, quadrantPosition: QuadrantPosition, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: D3ExportDimensions, _options?: TechRadarRenderOptions): void;
3865
+ declare function renderQuadrantFocusForExport(container: HTMLDivElement, parsed: ParsedTechRadar, quadrantPosition: QuadrantPosition, palette: PaletteColors, isDark: boolean, exportDims: {
3866
+ width: number;
3867
+ height: number;
3868
+ }): void;
3869
+
3870
+ /**
3871
+ * One rendered description line. `kind` controls horizontal placement and
3872
+ * whether the renderer draws a bullet glyph:
3873
+ * - `plain` — flush left at the description's left edge
3874
+ * - `bullet-first` — "•" drawn at the left edge, body text at the bullet column
3875
+ * - `bullet-cont` — body continuation at the bullet column (no glyph)
3876
+ *
3877
+ * Splitting first-line bullet rendering into separate text elements lets
3878
+ * continuation lines align exactly under the first word past the bullet,
3879
+ * regardless of font-width estimation drift.
3880
+ */
3881
+ interface WrappedDescLine {
3882
+ text: string;
3883
+ kind: 'plain' | 'bullet-first' | 'bullet-cont';
3884
+ }
3885
+
3886
+ interface CycleNode {
3887
+ label: string;
3888
+ lineNumber: number;
3889
+ color?: string;
3890
+ span: number;
3891
+ description: string[];
3892
+ metadata: Record<string, string>;
3893
+ }
3894
+ interface CycleEdge {
3895
+ sourceIndex: number;
3896
+ targetIndex: number;
3897
+ label?: string;
3898
+ color?: string;
3899
+ width?: number;
3900
+ description: string[];
3901
+ lineNumber?: number;
3902
+ metadata: Record<string, string>;
3903
+ }
3904
+ interface ParsedCycle {
3905
+ type: 'cycle';
3906
+ title: string;
3907
+ titleLineNumber: number;
3908
+ nodes: CycleNode[];
3909
+ edges: CycleEdge[];
3910
+ direction: 'clockwise' | 'counterclockwise';
3911
+ options: Record<string, string>;
3912
+ diagnostics: DgmoError[];
3913
+ error: string | null;
3914
+ }
3915
+
3916
+ interface CycleLayoutNode {
3917
+ label: string;
3918
+ x: number;
3919
+ y: number;
3920
+ angle: number;
3921
+ width: number;
3922
+ height: number;
3923
+ /** Pre-wrapped description lines (fit to node width). Empty if no descriptions. */
3924
+ wrappedDesc: WrappedDescLine[];
3925
+ /** Whether this node should be rendered as a circle. */
3926
+ isCircle: boolean;
3927
+ }
3928
+ interface CycleLayoutEdge {
3929
+ sourceIndex: number;
3930
+ targetIndex: number;
3931
+ path: string;
3932
+ labelX: number;
3933
+ labelY: number;
3934
+ /** Angle of the label position on the circle (radians), for text-anchor. */
3935
+ labelAngle: number;
3936
+ label?: string;
3937
+ }
3938
+ interface CycleLayoutResult {
3939
+ nodes: CycleLayoutNode[];
3940
+ edges: CycleLayoutEdge[];
3941
+ cx: number;
3942
+ cy: number;
3943
+ radius: number;
3944
+ width: number;
3945
+ height: number;
3946
+ /** Scale factor applied to nodes (1 = no scaling, <1 = shrunk to fit). */
3947
+ scale: number;
3948
+ }
3949
+
3950
+ /**
3951
+ * Parse a `.dgmo` cycle diagram document.
3952
+ *
3953
+ * Syntax:
3954
+ * ```
3955
+ * cycle Title
3956
+ *
3957
+ * direction-counterclockwise
3958
+ *
3959
+ * NodeLabel | color: blue, span: 3
3960
+ * Description line (indented under node)
3961
+ * -Label-> | color: red, width: 6
3962
+ * Edge description (indented under edge)
3963
+ * ```
3964
+ */
3965
+ declare function parseCycle(content: string): ParsedCycle;
3966
+
3967
+ /**
3968
+ * Compute cycle diagram layout: positions nodes equidistant (or span-weighted)
3969
+ * on a circle, and generates curved edge paths between consecutive nodes.
3970
+ */
3971
+ declare function computeCycleLayout(parsed: ParsedCycle, options?: {
3972
+ width?: number;
3973
+ height?: number;
3974
+ hideDescriptions?: boolean;
3975
+ }): CycleLayoutResult;
3976
+
3977
+ interface CycleRenderOptions {
3978
+ onClickItem?: (lineNumber: number) => void;
3979
+ exportDims?: D3ExportDimensions;
3980
+ viewState?: CompactViewState;
3981
+ hideDescriptions?: boolean;
3982
+ controlsExpanded?: boolean;
3983
+ onToggleDescriptions?: (active: boolean) => void;
3984
+ onToggleControlsExpand?: () => void;
3985
+ }
3986
+ /**
3987
+ * Render a cycle diagram into the given container.
3988
+ */
3989
+ declare function renderCycle(container: HTMLDivElement, parsed: ParsedCycle, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: D3ExportDimensions, viewState?: CompactViewState, renderOptions?: CycleRenderOptions): void;
3990
+ /**
3991
+ * Render for CLI/export (no click handlers).
3992
+ */
3993
+ declare function renderCycleForExport(container: HTMLDivElement, parsed: ParsedCycle, palette: PaletteColors, isDark: boolean, exportDims?: D3ExportDimensions, viewState?: CompactViewState): void;
3994
+
3995
+ interface JourneyMapAnnotation {
3996
+ type: 'pain' | 'opportunity' | 'thought';
3997
+ text: string;
3998
+ }
3999
+ interface JourneyMapStep {
57
4000
  id: string;
58
4001
  title: string;
4002
+ score?: number;
4003
+ emotionLabel?: string;
59
4004
  tags: Record<string, string>;
60
- details: string[];
4005
+ annotations: JourneyMapAnnotation[];
4006
+ description?: string;
61
4007
  lineNumber: number;
62
4008
  endLineNumber: number;
63
- color?: string;
64
4009
  }
65
- interface KanbanColumn {
4010
+ interface JourneyMapPhase {
66
4011
  id: string;
67
4012
  name: string;
68
- wipLimit?: number;
4013
+ steps: JourneyMapStep[];
4014
+ lineNumber: number;
4015
+ }
4016
+ interface JourneyMapPersona {
4017
+ name: string;
4018
+ description?: string;
69
4019
  color?: string;
70
- metadata?: Record<string, string>;
71
- cards: KanbanCard[];
72
4020
  lineNumber: number;
73
4021
  }
74
- interface ParsedKanban {
75
- type: 'kanban';
4022
+ interface ParsedJourneyMap {
4023
+ type: 'journey-map';
76
4024
  title?: string;
77
4025
  titleLineNumber?: number;
78
- columns: KanbanColumn[];
79
- tagGroups: KanbanTagGroup[];
4026
+ persona?: JourneyMapPersona;
4027
+ phases: JourneyMapPhase[];
4028
+ /** Flat-mode steps (not inside any phase) */
4029
+ steps: JourneyMapStep[];
4030
+ tagGroups: TagGroup[];
4031
+ options: Record<string, string>;
4032
+ diagnostics: DgmoError[];
4033
+ error: string | null;
4034
+ }
4035
+
4036
+ declare function parseJourneyMap(content: string, palette?: PaletteColors): ParsedJourneyMap;
4037
+
4038
+ interface CurvePoint {
4039
+ x: number;
4040
+ y: number;
4041
+ score: number;
4042
+ emotionLabel?: string;
4043
+ stepIndex: number;
4044
+ }
4045
+ interface StepLayout {
4046
+ x: number;
4047
+ y: number;
4048
+ width: number;
4049
+ height: number;
4050
+ step: JourneyMapStep;
4051
+ color: string;
4052
+ }
4053
+ interface PhaseLayout {
4054
+ x: number;
4055
+ y: number;
4056
+ width: number;
4057
+ height: number;
4058
+ phase: JourneyMapPhase;
4059
+ headerColor: string;
4060
+ stepLayouts: StepLayout[];
4061
+ }
4062
+ interface JourneyMapLayout {
4063
+ phases: PhaseLayout[];
4064
+ flatStepLayouts: StepLayout[];
4065
+ curvePoints: CurvePoint[];
4066
+ totalWidth: number;
4067
+ totalHeight: number;
4068
+ curveAreaTop: number;
4069
+ curveAreaBottom: number;
4070
+ cardAreaTop: number;
4071
+ personaHeight: number;
4072
+ titleHeight: number;
4073
+ /** Whether any step has thought annotations */
4074
+ hasThoughts: boolean;
4075
+ }
4076
+ declare function layoutJourneyMap(parsed: ParsedJourneyMap, palette: PaletteColors, options?: {
4077
+ exportDims?: {
4078
+ width: number;
4079
+ height: number;
4080
+ };
4081
+ collapsedPhases?: Set<string>;
4082
+ isDark?: boolean;
4083
+ }): JourneyMapLayout;
4084
+
4085
+ interface JourneyMapInteractiveOptions {
4086
+ onNavigateToLine?: (line: number) => void;
4087
+ exportDims?: {
4088
+ width: number;
4089
+ height: number;
4090
+ };
4091
+ activeTagGroup?: string | null;
4092
+ onActiveTagGroupChange?: (group: string | null) => void;
4093
+ /** Current editor cursor line — highlights the matching face + card, dims the rest */
4094
+ currentLine?: number | null;
4095
+ /** Set of collapsed phase names */
4096
+ collapsedPhases?: Set<string>;
4097
+ /** Called when a phase is toggled */
4098
+ onPhaseToggle?: (phaseName: string) => void;
4099
+ }
4100
+ declare function renderJourneyMap(container: HTMLElement, parsed: ParsedJourneyMap, palette: PaletteColors, isDark: boolean, options?: JourneyMapInteractiveOptions): void;
4101
+ declare function renderJourneyMapForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
4102
+
4103
+ interface PyramidLayer {
4104
+ label: string;
4105
+ lineNumber: number;
4106
+ /** Optional palette color name (red/green/blue/…). */
4107
+ color?: string;
4108
+ /** Description lines — from bare pipe shorthand or indented body. */
4109
+ description: string[];
4110
+ /** Unconsumed pipe metadata (reserved for future use). */
4111
+ metadata: Record<string, string>;
4112
+ }
4113
+ interface ParsedPyramid {
4114
+ type: 'pyramid';
4115
+ title: string;
4116
+ titleLineNumber: number;
4117
+ layers: PyramidLayer[];
4118
+ /** When true, apex points down instead of up. */
4119
+ inverted: boolean;
80
4120
  options: Record<string, string>;
81
4121
  diagnostics: DgmoError[];
82
4122
  error: string | null;
83
4123
  }
84
4124
 
85
4125
  /**
86
- * Compute new file content after moving a card to a different position.
4126
+ * Parse a `.dgmo` pyramid diagram document.
87
4127
  *
88
- * @param content - original file content string
89
- * @param parsed - parsed kanban board
90
- * @param cardId - id of the card to move
91
- * @param targetColumnId - id of the destination column
92
- * @param targetIndex - position within target column (0 = first card)
93
- * @returns new content string, or null if move is invalid
94
- */
95
- declare function computeCardMove(content: string, parsed: ParsedKanban, cardId: string, targetColumnId: string, targetIndex: number): string | null;
96
- /**
97
- * Move a card to the Archive section at the end of the file.
98
- * Creates `== Archive ==` if it doesn't exist.
4128
+ * Top of file = apex of pyramid (reads top-down).
99
4129
  *
100
- * @returns new content string, or null if the card is not found
4130
+ * Syntax:
4131
+ * ```
4132
+ * pyramid Maslow's Hierarchy of Needs
4133
+ *
4134
+ * inverted // optional — flips apex to bottom
4135
+ *
4136
+ * Self-Actualization // indented body = description
4137
+ * Achieving one's full potential.
4138
+ *
4139
+ * Esteem | Respect, recognition // bare pipe shorthand = description
4140
+ *
4141
+ * Love & Belonging | color: blue // structured metadata
4142
+ * Friendship, intimacy, family.
4143
+ *
4144
+ * Physiological | Food, water, rest
4145
+ * ```
101
4146
  */
102
- declare function computeCardArchive(content: string, parsed: ParsedKanban, cardId: string): string | null;
103
- /** Check if a column name is the archive column (case-insensitive). */
104
- declare function isArchiveColumn(name: string): boolean;
4147
+ declare function parsePyramid(content: string): ParsedPyramid;
105
4148
 
106
4149
  /**
107
- * Participant types that can be declared via "Name is a type" syntax.
4150
+ * Render a pyramid diagram into the given container.
108
4151
  */
109
- type ParticipantType = 'default' | 'service' | 'database' | 'actor' | 'queue' | 'cache' | 'gateway' | 'external' | 'networking' | 'frontend';
4152
+ declare function renderPyramid(container: HTMLDivElement, parsed: ParsedPyramid, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: D3ExportDimensions): void;
110
4153
  /**
111
- * A declared or inferred participant in the sequence diagram.
4154
+ * Render for CLI/export (no click handlers).
112
4155
  */
113
- interface SequenceParticipant {
114
- /** Internal identifier (e.g. "AuthService") */
115
- id: string;
116
- /** Display label — first-seen casing/spacing of the name */
4156
+ declare function renderPyramidForExport(container: HTMLDivElement, parsed: ParsedPyramid, palette: PaletteColors, isDark: boolean, exportDims?: D3ExportDimensions): void;
4157
+
4158
+ interface RingLayer {
117
4159
  label: string;
118
- /** Participant shape type */
119
- type: ParticipantType;
120
- /** Source line number (1-based) */
121
4160
  lineNumber: number;
122
- /** Explicit layout position override (0-based from left, negative from right) */
123
- position?: number;
124
- /** Pipe-delimited tag metadata (e.g. `| role: Gateway`) */
125
- metadata?: Record<string, string>;
4161
+ /** Optional palette color name (red/green/blue/…). */
4162
+ color?: string;
4163
+ /** Description lines from bare pipe shorthand or indented body. */
4164
+ description: string[];
4165
+ /** Unconsumed pipe metadata (reserved for future use). */
4166
+ metadata: Record<string, string>;
4167
+ }
4168
+ interface ParsedRing {
4169
+ type: 'ring';
4170
+ title: string;
4171
+ titleLineNumber: number;
4172
+ /** Source order: layers[0] = innermost (filled disc); last = outermost ring. */
4173
+ layers: RingLayer[];
4174
+ options: Record<string, string>;
4175
+ diagnostics: DgmoError[];
4176
+ error: string | null;
126
4177
  }
4178
+
127
4179
  /**
128
- * A message between two participants.
4180
+ * Parse a `.dgmo` ring diagram document.
4181
+ *
4182
+ * Top of file = innermost ring (rendered as a filled disc).
4183
+ * Last layer in source = outermost ring.
129
4184
  */
130
- interface SequenceMessage {
131
- from: string;
132
- to: string;
133
- label: string;
134
- lineNumber: number;
135
- async?: boolean;
136
- /** Pipe-delimited tag metadata (e.g. `| c: Caching`) */
137
- metadata?: Record<string, string>;
138
- }
4185
+ declare function parseRing(content: string): ParsedRing;
4186
+
139
4187
  /**
140
- * A conditional or loop block in the sequence diagram.
4188
+ * Render a ring diagram into the given container.
141
4189
  */
142
- interface ElseIfBranch {
143
- label: string;
144
- children: SequenceElement[];
4190
+ declare function renderRing(container: HTMLDivElement, parsed: ParsedRing, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: D3ExportDimensions): void;
4191
+ /**
4192
+ * Render for CLI/export (no click handlers).
4193
+ */
4194
+ declare function renderRingForExport(container: HTMLDivElement, parsed: ParsedRing, palette: PaletteColors, isDark: boolean, exportDims?: D3ExportDimensions): void;
4195
+
4196
+ /** Marker alphabet member for any variant. */
4197
+ type RaciMarker = 'R' | 'A' | 'S' | 'C' | 'I' | 'D';
4198
+ /** Variant identifier — selects alphabet + constraint rule set. */
4199
+ type RaciVariant = 'raci' | 'rasci' | 'daci';
4200
+ /**
4201
+ * One `Role: <markers>` line under a task.
4202
+ *
4203
+ * `id` is the normalized role key — used by mutations to look up the
4204
+ * cell and by validation to detect unknown roles. `displayName` is the
4205
+ * first-seen casing/spacing for rendering.
4206
+ */
4207
+ interface RaciRoleAssignment {
4208
+ id: string;
4209
+ displayName: string;
4210
+ markers: RaciMarker[];
145
4211
  lineNumber: number;
4212
+ endLineNumber: number;
146
4213
  }
147
- interface SequenceBlock {
148
- kind: 'block';
149
- type: 'if' | 'loop' | 'parallel';
150
- label: string;
151
- children: SequenceElement[];
152
- elseChildren: SequenceElement[];
153
- elseIfBranches?: ElseIfBranch[];
154
- elseLineNumber?: number;
4214
+ /** One task — flush-left under a phase or directly under the chart. */
4215
+ interface RaciTask {
4216
+ id: string;
4217
+ displayName: string;
4218
+ description: string;
4219
+ roleAssignments: RaciRoleAssignment[];
155
4220
  lineNumber: number;
4221
+ endLineNumber: number;
4222
+ }
4223
+ /** Optional `[Phase Label]` group header — one level deep. */
4224
+ interface RaciPhase {
4225
+ id: string;
4226
+ displayName: string;
4227
+ /** Optional palette color from a `[Label](color)` suffix on the bracket. */
4228
+ color?: string;
4229
+ tasks: RaciTask[];
4230
+ lineNumber: number;
4231
+ endLineNumber: number;
4232
+ }
4233
+ /** Top-level parse result. */
4234
+ interface ParsedRaci {
4235
+ type: 'raci';
4236
+ /** Optional title from the chart-type header line. */
4237
+ title?: string;
4238
+ titleLineNumber?: number;
4239
+ /** Variant selected by directive, or by chart-type id when absent. */
4240
+ variant: RaciVariant;
4241
+ /**
4242
+ * Canonical column order. Populated either from an explicit
4243
+ * `roles:` directive or, when absent, from first-seen role usage.
4244
+ */
4245
+ roles: string[];
4246
+ /** Display name for each role (parallel to `roles`). */
4247
+ roleDisplayNames: string[];
4248
+ /**
4249
+ * Optional per-role palette color from `Cap(blue)` suffix in the
4250
+ * roles block. Parallel to `roles`; entries default to `undefined`
4251
+ * (renderer falls back to the neutral column tint).
4252
+ */
4253
+ roleColors: Array<string | undefined>;
4254
+ phases: RaciPhase[];
4255
+ /** Tasks declared without a parent phase. */
4256
+ tasksWithoutPhase: RaciTask[];
4257
+ options: Record<string, string>;
4258
+ diagnostics: DgmoError[];
4259
+ error: string | null;
156
4260
  }
4261
+
157
4262
  /**
158
- * A labeled horizontal divider between message phases.
4263
+ * Parse RACI/RASCI/DACI source. The leading chart-type id (if a
4264
+ * recognized variant id) acts as a hint for default variant when the
4265
+ * `variant` directive is absent.
159
4266
  */
160
- interface SequenceSection {
161
- kind: 'section';
162
- label: string;
163
- lineNumber: number;
4267
+ declare function parseRaci(content: string, palette?: PaletteColors): ParsedRaci;
4268
+
4269
+ /** Drag-source identity passed to `onMarkerDragStart`. */
4270
+ type RaciDragSource = {
4271
+ kind: 'legend';
4272
+ marker: RaciMarker;
4273
+ } | {
4274
+ kind: 'cell';
4275
+ marker: RaciMarker;
4276
+ taskId: string;
4277
+ roleId: string;
4278
+ };
4279
+ interface RaciInteractionHandlers {
4280
+ onClickLine?: (lineNumber: number) => void;
4281
+ /** Fires on `pointerdown` of a legend chip OR an in-cell marker slice. */
4282
+ onMarkerDragStart?: (source: RaciDragSource, event: PointerEvent) => void;
4283
+ /**
4284
+ * Suppress the in-SVG legend strip. The app overlays an HTML legend
4285
+ * for native HTML5 drag — SVG `<g> draggable=true` is unreliable.
4286
+ * PNG/SVG export keeps the legend by default.
4287
+ */
4288
+ hideLegend?: boolean;
4289
+ /**
4290
+ * Phase ids whose tasks should be hidden. The phase header still
4291
+ * renders with a "collapsed" chevron so the user can re-expand.
4292
+ */
4293
+ collapsedPhases?: ReadonlySet<string>;
4294
+ /**
4295
+ * Suppress the in-SVG title. The app paints its own HTML title
4296
+ * above the HTML legend bar so the visual order is title → legend
4297
+ * → matrix. PNG/SVG export keeps the title by default.
4298
+ */
4299
+ hideTitle?: boolean;
164
4300
  }
165
4301
  /**
166
- * An annotation attached to a message, rendered as a folded-corner box.
4302
+ * Render a RACI / RASCI / DACI matrix into the given DOM container.
4303
+ * Layout is computed once and laid out as SVG; no animation.
167
4304
  */
168
- interface SequenceNote {
169
- kind: 'note';
170
- text: string;
171
- position: 'right' | 'left';
172
- participantId: string;
173
- lineNumber: number;
174
- endLineNumber: number;
4305
+ declare function renderRaci(container: HTMLDivElement, parsed: ParsedRaci, palette: PaletteColors, isDark: boolean, handlers?: RaciInteractionHandlers | ((lineNumber: number) => void), exportDims?: D3ExportDimensions): void;
4306
+ declare function renderRaciForExport(container: HTMLDivElement, parsed: ParsedRaci, palette: PaletteColors, isDark: boolean, exportDims?: D3ExportDimensions): void;
4307
+
4308
+ /**
4309
+ * Set the markers on a cell to exactly `[marker]`, replacing whatever
4310
+ * was there. If `marker` is `null`, the cell is cleared (the role
4311
+ * assignment line is removed if it was the only marker; otherwise the
4312
+ * line stays with its other markers untouched — see `cellRemove` for
4313
+ * specific-marker removal semantics).
4314
+ *
4315
+ * Insertion point when the role assignment doesn't exist:
4316
+ * - After the last existing role assignment under the task, OR
4317
+ * - After the task's description block, OR
4318
+ * - Immediately after the task line.
4319
+ *
4320
+ * Returns `null` for no-ops (the cell already contains `[marker]`).
4321
+ */
4322
+ declare function cellReplace(content: string, parsed: ParsedRaci, taskId: string, roleId: string, marker: RaciMarker | null): string | null;
4323
+ /**
4324
+ * Append `marker` to the cell, producing a combined-marker string
4325
+ * like `A R`. Idempotent — if `marker` is already present, returns
4326
+ * `null`. If the cell is empty (no existing role assignment line),
4327
+ * behaves like `cellReplace(content, ..., marker)`.
4328
+ */
4329
+ declare function cellAppendMarker(content: string, parsed: ParsedRaci, taskId: string, roleId: string, marker: RaciMarker): string | null;
4330
+ /**
4331
+ * Remove a single `marker` from the cell, OR all markers when
4332
+ * `marker` is `undefined`. If the cell becomes empty as a result,
4333
+ * the entire role-assignment line is dropped.
4334
+ *
4335
+ * Returns `null` for no-ops (e.g. removing a marker that wasn't
4336
+ * there).
4337
+ */
4338
+ declare function cellRemove(content: string, parsed: ParsedRaci, taskId: string, roleId: string, marker?: RaciMarker): string | null;
4339
+ /**
4340
+ * Cycle the cell's marker through the variant alphabet. Used by the
4341
+ * click-to-cycle interaction in `RACIPreview`. Cycle order:
4342
+ *
4343
+ * blank → alphabet[0] → alphabet[1] → … → alphabet[n-1] → blank → …
4344
+ *
4345
+ * If the cell currently has multiple markers (e.g. `A R`), cycling
4346
+ * collapses to a single marker chosen as the *next* one after the
4347
+ * first existing marker — interpretation: "cycle from the dominant
4348
+ * marker." This keeps the affordance simple; combined-markers stay
4349
+ * the territory of drag-from-palette (per TD #10).
4350
+ */
4351
+ declare function cellCycle(content: string, parsed: ParsedRaci, taskId: string, roleId: string, alphabet: ReadonlyArray<RaciMarker>): string | null;
4352
+
4353
+ /** Codes for variant-defining structural errors (always fire). */
4354
+ declare const RACI_ERROR_CODES: {
4355
+ readonly MULTI_ACCOUNTABLE: "E_RACI_MULTI_ACCOUNTABLE";
4356
+ readonly DACI_MULTI_DRIVER: "E_DACI_MULTI_DRIVER";
4357
+ readonly DACI_MULTI_ACCOUNTABLE: "E_DACI_MULTI_ACCOUNTABLE";
4358
+ readonly INVALID_MARKER: "E_RACI_INVALID_MARKER";
4359
+ readonly UNEXPECTED_LINE: "E_RACI_UNEXPECTED_LINE";
4360
+ readonly MIXED_VARIANTS: "E_RACI_MIXED_VARIANTS";
4361
+ readonly DUPLICATE_VARIANT: "E_RACI_DUPLICATE_VARIANT";
4362
+ };
4363
+ /** Codes for warnings (suppressible chart-wide by the `no-rule-enforcement` directive). */
4364
+ declare const RACI_WARNING_CODES: {
4365
+ readonly MISSING_ACCOUNTABLE: "W_RACI_MISSING_ACCOUNTABLE";
4366
+ readonly MISSING_RESPONSIBLE: "W_RACI_MISSING_RESPONSIBLE";
4367
+ readonly DACI_MISSING_DRIVER: "W_DACI_MISSING_DRIVER";
4368
+ readonly DACI_MISSING_ACCOUNTABLE: "W_DACI_MISSING_ACCOUNTABLE";
4369
+ readonly UNKNOWN_ROLE: "W_RACI_UNKNOWN_ROLE";
4370
+ readonly EMPTY_TASK: "W_RACI_EMPTY_TASK";
4371
+ readonly CONFLICTING_MARKERS: "W_RACI_CONFLICTING_MARKERS";
4372
+ readonly TOO_MANY_RESPONSIBLE: "W_RACI_TOO_MANY_RESPONSIBLE";
4373
+ readonly ORPHAN_ROLE: "W_RACI_ORPHAN_ROLE";
4374
+ };
4375
+ /** A constraint rule produces zero or more diagnostics for a single task. */
4376
+ type ConstraintRule = (task: RaciTask) => DgmoError[];
4377
+ interface VariantRuleSet {
4378
+ alphabet: ReadonlyArray<RaciMarker>;
4379
+ /**
4380
+ * Structural errors. Fire whenever `no-rule-enforcement` is off, like
4381
+ * the warning rules — kept as a separate bucket so callers (e.g. the
4382
+ * editor diagnostics panel) can style them with error severity.
4383
+ */
4384
+ errorRules: ConstraintRule[];
4385
+ /** Hygiene warnings — same suppression as errors. */
4386
+ warningRules: ConstraintRule[];
175
4387
  }
176
- type SequenceElement = SequenceMessage | SequenceBlock | SequenceSection | SequenceNote;
4388
+ declare const VARIANTS: Readonly<Record<RaciVariant, VariantRuleSet>>;
4389
+
177
4390
  /**
178
- * A named group of participants rendered as a labeled box.
4391
+ * Async or sync file reader. Receives an absolute path, returns content.
4392
+ * Throwing means "file not found".
179
4393
  */
180
- interface SequenceGroup {
181
- name: string;
182
- participantIds: string[];
183
- lineNumber: number;
184
- /** Pipe-delimited tag metadata (e.g. `[Backend | t: Product]`) */
185
- metadata?: Record<string, string>;
186
- /** Whether this group is collapsed by default */
187
- collapsed?: boolean;
4394
+ type ReadFileFn = (path: string) => string | Promise<string>;
4395
+ /** Tracks the original source file and line for an imported line. */
4396
+ interface ImportSource {
4397
+ /** Absolute path of the file this line originates from */
4398
+ filePath: string;
4399
+ /** 1-based line number in the original (pre-resolution) source file */
4400
+ sourceLine: number;
4401
+ }
4402
+ interface ResolveImportsResult {
4403
+ content: string;
4404
+ diagnostics: DgmoError[];
4405
+ /** resolvedLine (1-based index) → originalLine (1-based) or null for inserted lines */
4406
+ lineMap: (number | null)[];
4407
+ /** resolvedLine (1-based index) → import source info or null for non-imported lines */
4408
+ importSourceMap: (ImportSource | null)[];
188
4409
  }
4410
+ /**
4411
+ * Pre-processes org chart content, resolving `tags` and `import` directives.
4412
+ *
4413
+ * @param content - Raw .dgmo file content
4414
+ * @param filePath - Absolute path of the file (for relative path resolution)
4415
+ * @param readFileFn - Function to read files (sync or async)
4416
+ * @returns Merged content with all imports resolved + diagnostics
4417
+ */
4418
+ declare function resolveOrgImports(content: string, filePath: string, readFileFn: ReadFileFn): Promise<ResolveImportsResult>;
4419
+
4420
+ declare function renderFlowchart(container: HTMLDivElement, graph: ParsedGraph, layout: LayoutResult$1, palette: PaletteColors, isDark: boolean, onClickItem?: (lineNumber: number) => void, exportDims?: {
4421
+ width?: number;
4422
+ height?: number;
4423
+ }): void;
4424
+ declare function renderFlowchartForExport(content: string, theme: 'light' | 'dark' | 'transparent', palette: PaletteColors): string;
4425
+
4426
+ declare const LEGEND_HEIGHT = 28;
4427
+ declare const LEGEND_GEAR_PILL_W: number;
4428
+
4429
+ declare function renderLegendD3(container: D3Sel, config: LegendConfig, state: LegendState, palette: LegendPalette, isDark: boolean, callbacks?: LegendCallbacks, containerWidth?: number): LegendHandle;
4430
+
4431
+ declare function controlsGroupCapsuleWidth(toggles: Array<{
4432
+ label: string;
4433
+ }>): number;
4434
+ declare function computeLegendLayout(config: LegendConfig, state: LegendState, containerWidth: number): LegendLayout;
4435
+ declare function getLegendReservedHeight(config: LegendConfig, state: LegendState, containerWidth: number): number;
189
4436
 
190
4437
  interface SectionMessageGroup {
191
4438
  section: SequenceSection;
192
4439
  messageIndices: number[];
193
4440
  }
4441
+ interface SequenceRenderOptions {
4442
+ collapsedSections?: Set<number>;
4443
+ collapsedGroups?: Set<number>;
4444
+ exportWidth?: number;
4445
+ activeTagGroup?: string | null;
4446
+ }
194
4447
  /**
195
4448
  * Group messages by the top-level section that precedes them.
196
4449
  * Messages before the first section are ungrouped (always visible).
@@ -238,6 +4491,10 @@ declare function applyPositionOverrides(participants: SequenceParticipant[]): Se
238
4491
  * Explicit `position` overrides are handled separately by `applyPositionOverrides`.
239
4492
  */
240
4493
  declare function applyGroupOrdering(participants: SequenceParticipant[], groups: SequenceGroup[], messages?: SequenceMessage[]): SequenceParticipant[];
4494
+ /**
4495
+ * Render a sequence diagram into the given container element.
4496
+ */
4497
+ declare function renderSequenceDiagram(container: HTMLDivElement, parsed: ParsedSequenceDgmo, palette: PaletteColors, isDark: boolean, _onNavigateToLine?: (line: number) => void, options?: SequenceRenderOptions): void;
241
4498
  /**
242
4499
  * Build a mapping from each note's lineNumber to the lineNumber of its
243
4500
  * associated message (the last message before the note in document order).
@@ -245,23 +4502,190 @@ declare function applyGroupOrdering(participants: SequenceParticipant[], groups:
245
4502
  */
246
4503
  declare function buildNoteMessageMap(elements: SequenceElement[]): Map<number, number>;
247
4504
 
248
- interface ArcLink {
249
- source: string;
250
- target: string;
251
- value: number;
252
- color: string | null;
253
- lineNumber: number;
4505
+ interface CollapsedView {
4506
+ participants: SequenceParticipant[];
4507
+ messages: SequenceMessage[];
4508
+ elements: SequenceElement[];
4509
+ groups: SequenceGroup[];
4510
+ /** Maps member participant ID → collapsed group name */
4511
+ collapsedGroupIds: Map<string, string>;
254
4512
  }
255
- type ArcOrder = 'appearance' | 'name' | 'group' | 'degree';
256
- interface ArcNodeGroup {
4513
+ /**
4514
+ * Project a parsed sequence diagram into a collapsed view.
4515
+ *
4516
+ * @param parsed - The immutable parsed sequence diagram
4517
+ * @param collapsedGroups - Set of group lineNumbers that should be collapsed
4518
+ * @returns A new CollapsedView with remapped participants, messages, elements, and groups
4519
+ */
4520
+ declare function applyCollapseProjection(parsed: ParsedSequenceDgmo, collapsedGroups: Set<number>): CollapsedView;
4521
+
4522
+ /** Complete 16-entry Nord palette. */
4523
+ declare const nord: {
4524
+ nord0: string;
4525
+ nord1: string;
4526
+ nord2: string;
4527
+ nord3: string;
4528
+ nord4: string;
4529
+ nord5: string;
4530
+ nord6: string;
4531
+ nord7: string;
4532
+ nord8: string;
4533
+ nord9: string;
4534
+ nord10: string;
4535
+ nord11: string;
4536
+ nord12: string;
4537
+ nord13: string;
4538
+ nord14: string;
4539
+ nord15: string;
4540
+ };
4541
+ /** Color name → Nord hex for inline `(color)` annotations. */
4542
+ declare const colorNames: Record<string, string>;
4543
+ /**
4544
+ * The canonical, closed set of color names accepted by the DGMO language.
4545
+ * See `docs/dgmo-language-spec.md` §1.5. Users cannot extend this list —
4546
+ * palettes only provide the per-theme hex values for these names.
4547
+ */
4548
+ declare const RECOGNIZED_COLOR_NAMES: readonly ["red", "orange", "yellow", "green", "blue", "purple", "teal", "cyan", "gray", "black", "white"];
4549
+ /**
4550
+ * Returns true iff `name` is one of the 11 recognized DGMO color names.
4551
+ */
4552
+ declare function isRecognizedColorName(name: string): boolean;
4553
+ /**
4554
+ * Resolves a recognized color name to its hex value for the active palette
4555
+ * (falling back to the built-in Nord defaults). Returns `null` for any
4556
+ * unrecognized input — including hex codes, CSS keywords like `pink`,
4557
+ * and typos. Callers MUST treat `null` as a parse error and emit a
4558
+ * diagnostic; do not silently fall back to the raw input.
4559
+ */
4560
+ declare function resolveColor(color: string, palette?: {
4561
+ colors: Record<string, string>;
4562
+ }): string | null;
4563
+
4564
+ /**
4565
+ * Resolves a color name and pushes a warning diagnostic on failure.
4566
+ * Returns the hex string for valid names, or `undefined` for unknown
4567
+ * input (after pushing a diagnostic). Use this from parsers that have
4568
+ * a diagnostics array and a line number in scope.
4569
+ */
4570
+ declare function resolveColorWithDiagnostic(color: string, line: number, diagnostics: DgmoError[], palette?: {
4571
+ colors: Record<string, string>;
4572
+ }): string | undefined;
4573
+ /** @deprecated Use getSeriesColors(palette) from '@/lib/palettes' instead. */
4574
+ declare const seriesColors: string[];
4575
+
4576
+ /**
4577
+ * Diagram symbol extraction API + completion registry.
4578
+ *
4579
+ * Provides:
4580
+ * - DiagramSymbols interface + extractDiagramSymbols() dispatch
4581
+ * - COMPLETION_REGISTRY: chart-type → directives map (for editor autocomplete)
4582
+ * - CHART_TYPES: array of { name, description } for chart type completion
4583
+ * - METADATA_KEY_SET: derived set of all known directive keys
4584
+ *
4585
+ * Each diagram type registers its own extractor via registerExtractor().
4586
+ * All built-in extractors are registered at module init below.
4587
+ */
4588
+
4589
+ declare function registerExtractor(kind: ChartType, fn: ExtractFn): void;
4590
+ /**
4591
+ * Extract diagram symbols from document text.
4592
+ * Returns null if the chart type is unknown or has no registered extractor.
4593
+ */
4594
+ declare function extractDiagramSymbols(docText: string): DiagramSymbols | null;
4595
+ /** Specification for a single directive: description + optional enumerated values. */
4596
+ interface DirectiveValueSpec {
4597
+ description: string;
4598
+ values?: string[];
4599
+ }
4600
+ /** Specification for a chart type's directives. */
4601
+ interface DirectiveSpec {
4602
+ directives: Record<string, DirectiveValueSpec>;
4603
+ }
4604
+ /** Chart-type → directive specifications. Every chart type has at least palette + theme. */
4605
+ declare const COMPLETION_REGISTRY: Map<string, DirectiveSpec>;
4606
+ declare const CHART_TYPES: ReadonlyArray<{
257
4607
  name: string;
258
- nodes: string[];
259
- color: string | null;
260
- lineNumber: number;
4608
+ description: string;
4609
+ }>;
4610
+ /**
4611
+ * Entity types for `Name is a <type>` declarations, keyed by chart type.
4612
+ * Values are sourced from parser constants (VALID_PARTICIPANT_TYPES,
4613
+ * C4_IS_A_RE).
4614
+ */
4615
+ declare const ENTITY_TYPES: Map<string, string[]>;
4616
+ /** Specification for a single pipe metadata key. */
4617
+ interface PipeKeySpec {
4618
+ description: string;
4619
+ values?: string[];
261
4620
  }
262
4621
  /**
263
- * Orders arc diagram nodes based on the selected ordering strategy.
4622
+ * Pipe metadata keys for inline `| key value` on data lines.
4623
+ * Keyed by chart type → { context-name: keys }.
4624
+ *
4625
+ * Contexts are open-ended. The two universal ones are:
4626
+ * - `node` — the default for any non-arrow line
4627
+ * - `edge` — lines containing an arrow (`->`, `--`)
4628
+ *
4629
+ * Charts with richer line types declare additional contexts:
4630
+ * - raci: `role`, `phase`, `assignment`
4631
+ * - ring / pyramid: `layer`
4632
+ * - tech-radar: `quadrant`, `blip`
4633
+ * - journey-map: `step`
4634
+ *
4635
+ * IMPORTANT: NEVER add 'sequence' here. The `|` character in sequence
4636
+ * diagrams separates display names from identifiers and tag metadata.
4637
+ * Adding sequence would trigger false pipe-metadata completions on every `|`.
264
4638
  */
265
- declare function orderArcNodes(links: ArcLink[], order: ArcOrder, groups: ArcNodeGroup[]): string[];
4639
+ type PipeContextMap = Record<string, Record<string, PipeKeySpec>>;
4640
+ declare const PIPE_METADATA: Map<string, PipeContextMap>;
4641
+ /** All known directive keys, derived from COMPLETION_REGISTRY. Includes implicit keys. */
4642
+ declare const METADATA_KEY_SET: ReadonlySet<string>;
4643
+ /**
4644
+ * Extract tag declarations from document text.
4645
+ * Returns a map of alias (or full name) → array of tag values.
4646
+ * Keys preserve original case for display; use case-insensitive lookup.
4647
+ */
4648
+ declare function extractTagDeclarations(docText: string): Map<string, string[]>;
4649
+
4650
+ /**
4651
+ * Shared parser utilities — extracted from individual parsers to eliminate
4652
+ * duplication of measureIndent, extractColor, header regexes, and
4653
+ * pipe-metadata parsing.
4654
+ */
4655
+
4656
+ /** Complete set of recognized chart type identifiers. */
4657
+ declare const ALL_CHART_TYPES: Set<string>;
4658
+ /**
4659
+ * Parse the first non-empty, non-comment line to extract chart type and optional title.
4660
+ * The first token is matched against `ALL_CHART_TYPES`; the remainder is the title.
4661
+ *
4662
+ * Returns `null` if the first token is not a recognized chart type.
4663
+ */
4664
+ declare function parseFirstLine(line: string): {
4665
+ chartType: string;
4666
+ title: string | undefined;
4667
+ } | null;
4668
+
4669
+ /**
4670
+ * Theme — render mode flag. Selects which palette variant the renderer uses
4671
+ * for background and text:
4672
+ * - 'light' → palette.light colors
4673
+ * - 'dark' → palette.dark colors
4674
+ * - 'transparent' → no background fill (for embedding in colored containers)
4675
+ */
4676
+ type Theme = 'light' | 'dark' | 'transparent';
4677
+ /**
4678
+ * `themes` namespace — use with render() options for a typed handle:
4679
+ *
4680
+ * await render(text, { theme: themes.dark });
4681
+ *
4682
+ * Passing the raw string `'dark'` also works (the underlying type is the
4683
+ * string-literal union); the namespace is the conventional path.
4684
+ */
4685
+ declare const themes: {
4686
+ readonly light: "light";
4687
+ readonly dark: "dark";
4688
+ readonly transparent: "transparent";
4689
+ };
266
4690
 
267
- export { applyGroupOrdering, applyPositionOverrides, buildNoteMessageMap, buildRenderSequence, computeActivations, computeCardArchive, computeCardMove, groupMessagesBySection, isArchiveColumn, orderArcNodes, parseDataRowValues };
4691
+ export { ALL_CHART_TYPES, AMBIGUITY_THRESHOLD, ARROW_DIAGNOSTIC_CODES, type Activation, type AncestorInfo, type ArcLink, type ArcNodeGroup, type BLCollapseResult, type BLEdge, type BLGroup, type BLLayoutEdge, type BLLayoutGroup, type BLLayoutNode, type BLLayoutResult, type BLNode, type BlipTrend, type C4ArrowType, type C4DeploymentNode, type C4Element, type C4ElementType, type C4Group, type C4LayoutBoundary, type C4LayoutEdge, type C4LayoutNode, type C4LayoutResult, type C4LegendEntry, type C4LegendGroup, type C4Relationship, type C4Shape, type C4TagEntry, type C4TagGroup, CHART_TYPES, CHART_TYPE_DESCRIPTIONS, COMPLETION_REGISTRY, type ChartDataPoint, type ChartEra, type ChartType$1 as ChartType, type Confidence as ChartTypeConfidence, type ChartTypeMeta, type ChartTypeScore, type SuggestionResult as ChartTypeSuggestionResult, type ClassLayoutEdge, type ClassLayoutNode, type ClassLayoutResult, type ClassMember, type ClassModifier, type ClassNode, type ClassRelationship, type CollapsedMindmapResult, type CollapsedOrgResult, type CollapsedSitemapResult, type CollapsedView, type CompactViewState, type ComputedInfraEdge, type ComputedInfraModel, type ComputedInfraNode, type ContextRelationship, type CycleEdge, type CycleLayoutEdge, type CycleLayoutNode, type CycleLayoutResult, type CycleNode, type CycleRenderOptions, type D3ExportDimensions, type DecodedDiagramUrl, type DgmoError, type DgmoSeverity, type DiagramSymbols, type DirectiveSpec, type DirectiveValueSpec, type Duration, type DurationUnit, ENTITY_TYPES, type ERCardinality, type ERColumn, type ERConstraint, type ERLayoutEdge, type ERLayoutNode, type ERLayoutResult, type ERRelationship, type ERTable, type ElseIfBranch, type EncodeDiagramUrlOptions, type EncodeDiagramUrlResult, type ExpandedActivity, type ExtendedChartType, type ExtractFn, type FocusOrgResult, type GanttDependency, type GanttEra, type GanttGroup, type GroupRow as GanttGroupRow, type GanttHolidays, type GanttInteractiveOptions, type LaneHeaderRow as GanttLaneHeaderRow, type GanttMarker, type GanttNode, type GanttOptions, type GanttParallelBlock, type Row as GanttRow, type GanttTask, type TaskRow as GanttTaskRow, type GetOrCreateNameResult, type GraphDirection, type GraphEdge, type GraphGroup, type GraphNode, type GraphShape, INFRA_BEHAVIOR_KEYS, type ImportSource, type InfraAvailabilityPercentiles, type InfraBehaviorKey, type InfraCbState, type InfraComputeParams, type InfraDiagnostic, type InfraEdge, type InfraGroup, type InfraLatencyPercentiles, type InfraLayoutEdge, type InfraLayoutGroup, type InfraLayoutNode, type InfraLayoutResult, type InfraLegendGroup, type InfraNode, type InfraPlaybackState, type InfraProperty, type InfraRole, type InfraTagGroup, type InlineSpan, type JourneyMapAnnotation, type JourneyMapInteractiveOptions, type JourneyMapLayout, type JourneyMapPersona, type JourneyMapPhase, type JourneyMapStep, type KanbanCard, type KanbanColumn, type KanbanTagEntry, type KanbanTagGroup, LEGEND_GEAR_PILL_W, LEGEND_HEIGHT, type LayoutEdge, type LayoutGroup, type LayoutNode, type LayoutOptions, type LayoutResult$1 as LayoutResult, type LegendCallbacks, type LegendConfig, type LegendControl, type LegendGroupData, type LegendHandle, type LegendLayout, type LegendMode, type LegendPalette, type LegendPosition, type LegendState, METADATA_KEY_SET, MIN_PRIMARY_SCORE, type MemberVisibility, type MindmapLayoutEdge, type MindmapLayoutNode, type MindmapLayoutResult, type MindmapNode, type MonteCarloResult, type NameEntry, type NodeDetail, type OrgContainerBounds, type OrgLayoutEdge, type OrgLayoutNode, type OrgLayoutResult, type OrgNode, PERT_LEGEND_PILL_HEIGHT, PIPE_METADATA, type PaletteColors, type PaletteConfig, type ParseInArrowLabelResult, type ParsedBoxesAndLines, type ParsedC4, type ParsedChart, type ParsedClassDiagram, type ParsedCycle, type ParsedERDiagram, type ParsedExtendedChart, type ParsedGantt, type ParsedGraph, type ParsedInfra, type ParsedJourneyMap, type ParsedKanban, type ParsedMindmap, type ParsedOrg, type ParsedPert, type ParsedPyramid, type ParsedRaci, type ParsedRing, type ParsedSequenceDgmo, type ParsedSitemap, type ParsedTechRadar, type ParsedVisualization, type ParsedWireframe, type ParticipantType, type PertActivity, type Anchor as PertAnchor, type PertDirection, type PertEdge, type PertGroup, type PertLayoutEdge, type PertLayoutGroup, type PertLayoutNode, type LayoutOverrides as PertLayoutOverrides, type LayoutResult as PertLayoutResult, type PertMilestone, type PertOptions, type PertRenderOptions, type PipeKeySpec, type PyramidLayer, type QuadrantPosition, RACI_ERROR_CODES, VARIANTS as RACI_VARIANTS, RACI_WARNING_CODES, RECOGNIZED_COLOR_NAMES, RULE_COUNT, type RaciDragSource, type RaciInteractionHandlers, type RaciMarker, type RaciPhase, type RaciRoleAssignment, type RaciTask, type RaciVariant, type ReadFileFn, type RelationshipType, type RenderCategory, type RenderStep, type ResolveImportsResult, type ResolvedActivity, type ResolvedGroup$1 as ResolvedGroup, type ResolvedPert, type ResolvedGroup as ResolvedPertGroup, type ResolvedSchedule, type ResolvedTask, type RingLayer, type ScatterLabelPoint, type SectionMessageGroup, type SequenceBlock, type SequenceElement, type SequenceGroup, type SequenceMessage, type SequenceNote, type SequenceParticipant, type SequenceRenderOptions, type SequenceSection, type SimulateOptions, type SitemapContainerBounds, type SitemapDirection, type SitemapEdge, type SitemapLayoutEdge, type SitemapLayoutNode, type SitemapLayoutResult, type SitemapLegendEntry, type SitemapLegendGroup, type SitemapNode, type StateCollapseResult, type TagEntry, type TagGroup, type TechRadarBlip, type TechRadarLayoutPoint, type TechRadarQuadrant, type TechRadarRing, type Theme, type VisualizationType, type WireframeElement, type WireframeElementType, type WireframeFormFactor, type WireframeLayout, type WireframeLayoutNode, addDurationToDate, analyzePert, applyCollapseProjection, applyGroupOrdering, applyPositionOverrides, boldPalette, buildExtendedChartOption, buildNoteMessageMap, buildRenderSequence, buildSimpleChartOption, buildSimulationContext, buildTagLaneRowList, calculateSchedule, catppuccinPalette, confidence as chartTypeConfidence, chartTypeParsers, chartTypes, collapseBoxesAndLines, collapseMindmapTree, collapseOrgTree, collapseSitemapTree, collapseStateGroups, collectDiagramRoles, collectTasks, colorNames, computeActivations, computeCardArchive, computeCardMove, computeCycleLayout, computeInfra, computeInfraLegendGroups, computeLegendLayout, computeRadarLayout, computeScatterLabelGraphics, computeTimeTicks, contrastText, controlsGroupCapsuleWidth, decodeDiagramUrl, decodeViewState, displayName, draculaPalette, encodeDiagramUrl, encodeViewState, extractDiagramSymbols, extractPertSymbols, extractTagDeclarations, focusOrgTree, formatDateLabel, formatDgmoError, getAllChartTypes, getAvailablePalettes, getExtendedChartLegendGroups, getLegendReservedHeight, getOrCreateName, getPalette, getRadarGeometry, getRenderCategory, getSeriesColors, getSimpleChartLegendGroups, groupMessagesBySection, gruvboxPalette, hexToHSL, hexToHSLString, highlightPertCriticalPath, highlightPertSet, hslToHex, inferParticipantType, inferRoles, isArchiveColumn, isExtendedChartType, isRecognizedColorName, isSequenceBlock, isSequenceNote, isValidHex, knownChartTypeIds, layoutBoxesAndLines, layoutC4Components, layoutC4Containers, layoutC4Context, layoutC4Deployment, layoutClassDiagram, layoutERDiagram, layoutGraph, layoutInfra, layoutJourneyMap, layoutMindmap, layoutOrg, layoutPert, layoutSitemap, layoutWireframe, looksLikeClassDiagram, looksLikeERDiagram, looksLikeFlowchart, looksLikePert, looksLikeSequence, looksLikeSitemap, looksLikeState, makeDgmoError, matchColorParens, matchesContiguously, measurePertAnalysisBlock, mix, monokaiPalette, mulberry32, nord, nordPalette, normalize as normalizeChartTypePrompt, normalizeName, normalizePertSourceForShare, oneDarkPalette, orderArcNodes, palettes, parseAndLayoutInfra, parseBoxesAndLines, parseC4, parseChart, parseClassDiagram, parseCycle, parseDataRowValues, parseDgmo, parseDgmoChartType, parseERDiagram, parseExtendedChart, parseFirstLine, parseFlowchart, parseGantt, parseInArrowLabel, parseInfra, parseInlineMarkdown, parseJourneyMap, parseKanban, parseMindmap, parseOrg, parsePert, parsePyramid, parseRaci, parseRing, parseSequenceDgmo, parseSequenceDgmo as parseSequenceDiagram, parseSitemap, parseState, parseTechRadar, parseTimelineDate, parseVisualization, parseWireframe, pertLegendBlockWidth, pertLegendEntries, cellAppendMarker as raciCellAppendMarker, cellCycle as raciCellCycle, cellRemove as raciCellRemove, cellReplace as raciCellReplace, registerExtractor, registerPalette, relayoutPert, render, renderArcDiagram, renderBoxesAndLines, renderBoxesAndLinesForExport, renderC4ComponentsForExport, renderC4Containers, renderC4ContainersForExport, renderC4Context, renderC4ContextForExport, renderC4Deployment, renderC4DeploymentForExport, renderClassDiagram, renderClassDiagramForExport, renderCycle, renderCycleForExport, renderERDiagram, renderERDiagramForExport, renderExtendedChartForExport, renderFlowchart, renderFlowchartForExport, renderForExport, renderGantt, renderInfra, renderJourneyMap, renderJourneyMapForExport, renderKanban, renderKanbanForExport, renderLegendD3, renderLegendSvg, renderLegendSvgFromConfig, renderMindmap, renderMindmapForExport, renderOrg, renderOrgForExport, renderPert, renderPertAnalysisBlock, renderPertForExport, renderLegendBlock as renderPertLegendBlock, renderPyramid, renderPyramidForExport, renderQuadrant, renderQuadrantFocus, renderQuadrantFocusForExport, renderRaci, renderRaciForExport, renderRing, renderRingForExport, renderSequenceDiagram, renderSitemap, renderSitemapForExport, renderSlopeChart, renderState, renderStateForExport, renderTechRadar, renderTechRadarForExport, renderTimeline, renderVenn, renderWireframe, renderWordCloud, resetPertCriticalPath, resetPertHighlight, resolveColor, resolveColorWithDiagnostic, resolveOrgImports, resolveTaskName, rollUpContextRelationships, rosePinePalette, sampleBetaPert, scoreChartType, seriesColors, shade, shapeFill, simulateCanonical, simulateFast, solarizedPalette, suggestChartTypes, themes, tint, tokyoNightPalette, truncateBareUrl, parseDgmo as validate, validateComputed, validateInfra, validateLabelCharacters };