@diagrammo/dgmo 0.8.23 → 0.8.26

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 (78) hide show
  1. package/.claude/commands/dgmo.md +43 -431
  2. package/.cursorrules +2 -2
  3. package/.windsurfrules +2 -2
  4. package/AGENTS.md +8 -5
  5. package/dist/cli.cjs +119 -114
  6. package/dist/editor.cjs +0 -2
  7. package/dist/editor.cjs.map +1 -1
  8. package/dist/editor.js +0 -2
  9. package/dist/editor.js.map +1 -1
  10. package/dist/highlight.cjs +0 -2
  11. package/dist/highlight.cjs.map +1 -1
  12. package/dist/highlight.js +0 -2
  13. package/dist/highlight.js.map +1 -1
  14. package/dist/index.cjs +719 -281
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +105 -18
  17. package/dist/index.d.ts +105 -18
  18. package/dist/index.js +709 -280
  19. package/dist/index.js.map +1 -1
  20. package/dist/internal.cjs +348 -51
  21. package/dist/internal.cjs.map +1 -1
  22. package/dist/internal.d.cts +93 -5
  23. package/dist/internal.d.ts +93 -5
  24. package/dist/internal.js +334 -38
  25. package/dist/internal.js.map +1 -1
  26. package/docs/guide/chart-area.md +17 -17
  27. package/docs/guide/chart-bar-stacked.md +12 -12
  28. package/docs/guide/chart-doughnut.md +10 -10
  29. package/docs/guide/chart-funnel.md +9 -9
  30. package/docs/guide/chart-heatmap.md +10 -10
  31. package/docs/guide/chart-kanban.md +2 -0
  32. package/docs/guide/chart-line.md +19 -19
  33. package/docs/guide/chart-multi-line.md +16 -16
  34. package/docs/guide/chart-pie.md +11 -11
  35. package/docs/guide/chart-polar-area.md +10 -10
  36. package/docs/guide/chart-radar.md +9 -9
  37. package/docs/guide/chart-scatter.md +24 -27
  38. package/docs/guide/index.md +3 -3
  39. package/docs/language-reference.md +46 -25
  40. package/fonts/Inter-Bold.ttf +0 -0
  41. package/fonts/Inter-Regular.ttf +0 -0
  42. package/fonts/LICENSE-Inter.txt +92 -0
  43. package/gallery/fixtures/bar-stacked.dgmo +12 -6
  44. package/gallery/fixtures/heatmap.dgmo +12 -6
  45. package/gallery/fixtures/multi-line.dgmo +11 -7
  46. package/gallery/fixtures/quadrant.dgmo +8 -8
  47. package/gallery/fixtures/scatter.dgmo +12 -12
  48. package/package.json +10 -3
  49. package/src/boxes-and-lines/parser.ts +13 -2
  50. package/src/boxes-and-lines/renderer.ts +22 -13
  51. package/src/chart-type-scoring.ts +162 -0
  52. package/src/chart-types.ts +437 -0
  53. package/src/cli.ts +147 -66
  54. package/src/completion.ts +0 -4
  55. package/src/d3.ts +40 -2
  56. package/src/dgmo-router.ts +85 -130
  57. package/src/editor/keywords.ts +0 -2
  58. package/src/fonts.ts +3 -2
  59. package/src/gantt/parser.ts +5 -1
  60. package/src/index.ts +24 -1
  61. package/src/infra/parser.ts +1 -1
  62. package/src/internal.ts +6 -2
  63. package/src/journey-map/layout.ts +8 -6
  64. package/src/journey-map/parser.ts +5 -1
  65. package/src/kanban/parser.ts +5 -1
  66. package/src/org/collapse.ts +1 -4
  67. package/src/org/parser.ts +1 -1
  68. package/src/org/renderer.ts +26 -17
  69. package/src/sequence/parser.ts +2 -2
  70. package/src/sequence/participant-inference.ts +0 -1
  71. package/src/sequence/renderer.ts +95 -263
  72. package/src/sharing.ts +0 -1
  73. package/src/sitemap/parser.ts +1 -1
  74. package/src/tech-radar/layout.ts +1 -2
  75. package/src/tech-radar/shared.ts +1 -37
  76. package/src/utils/tag-groups.ts +35 -5
  77. package/src/wireframe/parser.ts +3 -1
  78. package/src/tech-radar/index.ts +0 -14
package/dist/index.cjs CHANGED
@@ -2086,7 +2086,8 @@ function validateTagValues(entities, tagGroups, pushWarning, suggestFn) {
2086
2086
  }
2087
2087
  }
2088
2088
  }
2089
- function validateTagGroupNames(tagGroups, pushWarning) {
2089
+ function validateTagGroupNames(tagGroups, pushWarning, pushError) {
2090
+ const report = pushError ?? pushWarning;
2090
2091
  for (const group of tagGroups) {
2091
2092
  if (group.name.toLowerCase() === "none") {
2092
2093
  pushWarning(
@@ -2094,6 +2095,18 @@ function validateTagGroupNames(tagGroups, pushWarning) {
2094
2095
  `'none' is a reserved keyword and cannot be used as a tag group name`
2095
2096
  );
2096
2097
  }
2098
+ if (!VALID_TAG_IDENT_RE.test(group.name)) {
2099
+ report(
2100
+ group.lineNumber,
2101
+ `Tag group name "${group.name}" contains invalid characters \u2014 use a single identifier (letters, digits, underscore, hyphen)`
2102
+ );
2103
+ }
2104
+ if (group.alias != null && !VALID_TAG_IDENT_RE.test(group.alias)) {
2105
+ report(
2106
+ group.lineNumber,
2107
+ `Tag group alias "${group.alias}" contains invalid characters \u2014 use a single identifier (letters, digits, underscore, hyphen)`
2108
+ );
2109
+ }
2097
2110
  }
2098
2111
  }
2099
2112
  function injectDefaultTagMetadata(entities, tagGroups, skip) {
@@ -2132,12 +2145,13 @@ function resolveActiveTagGroup(tagGroups, explicitActiveTag, programmaticOverrid
2132
2145
  function matchTagBlockHeading(trimmed) {
2133
2146
  return parseTagDeclaration(trimmed);
2134
2147
  }
2135
- var TAG_BLOCK_NOCOLON_RE;
2148
+ var TAG_BLOCK_NOCOLON_RE, VALID_TAG_IDENT_RE;
2136
2149
  var init_tag_groups = __esm({
2137
2150
  "src/utils/tag-groups.ts"() {
2138
2151
  "use strict";
2139
2152
  init_parsing();
2140
2153
  TAG_BLOCK_NOCOLON_RE = /^tag\s+/i;
2154
+ VALID_TAG_IDENT_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
2141
2155
  }
2142
2156
  });
2143
2157
 
@@ -3073,7 +3087,6 @@ var init_participant_inference = __esm({
3073
3087
  { pattern: /^Admin$/i, type: "actor" },
3074
3088
  { pattern: /^User$/i, type: "actor" },
3075
3089
  { pattern: /^Customer$/i, type: "actor" },
3076
- { pattern: /^Client$/i, type: "actor" },
3077
3090
  { pattern: /^Agent$/i, type: "actor" },
3078
3091
  { pattern: /^Person$/i, type: "actor" },
3079
3092
  { pattern: /^Buyer$/i, type: "actor" },
@@ -4071,7 +4084,7 @@ function parseSequenceDgmo(content) {
4071
4084
  entities.push({ metadata: g.metadata, lineNumber: g.lineNumber });
4072
4085
  }
4073
4086
  validateTagValues(entities, result.tagGroups, pushWarning, suggest);
4074
- validateTagGroupNames(result.tagGroups, pushWarning);
4087
+ validateTagGroupNames(result.tagGroups, pushWarning, pushError);
4075
4088
  }
4076
4089
  return result;
4077
4090
  }
@@ -4094,7 +4107,7 @@ var init_parser = __esm({
4094
4107
  init_parsing();
4095
4108
  init_tag_groups();
4096
4109
  KNOWN_SEQ_OPTIONS = /* @__PURE__ */ new Set(["active-tag"]);
4097
- KNOWN_SEQ_BOOLEANS = /* @__PURE__ */ new Set(["activations", "collapse-notes"]);
4110
+ KNOWN_SEQ_BOOLEANS = /* @__PURE__ */ new Set(["activations"]);
4098
4111
  VALID_PARTICIPANT_TYPES = /* @__PURE__ */ new Set([
4099
4112
  "service",
4100
4113
  "database",
@@ -8452,7 +8465,7 @@ function parseOrg(content, palette) {
8452
8465
  };
8453
8466
  collectAll(result.roots);
8454
8467
  validateTagValues(allNodes, result.tagGroups, pushWarning, suggest);
8455
- validateTagGroupNames(result.tagGroups, pushWarning);
8468
+ validateTagGroupNames(result.tagGroups, pushWarning, pushError);
8456
8469
  }
8457
8470
  if (result.roots.length === 0 && result.tagGroups.length === 0 && !result.error) {
8458
8471
  const diag = makeDgmoError(1, "No nodes found in org chart");
@@ -8785,7 +8798,11 @@ function parseKanban(content, palette) {
8785
8798
  if (result.columns.length === 0 && !result.error) {
8786
8799
  return fail(1, "No columns found. Use [Column Name] to define columns");
8787
8800
  }
8788
- validateTagGroupNames(result.tagGroups, warn);
8801
+ validateTagGroupNames(result.tagGroups, warn, (line11, msg) => {
8802
+ const diag = makeDgmoError(line11, msg);
8803
+ result.diagnostics.push(diag);
8804
+ if (!result.error) result.error = formatDgmoError(diag);
8805
+ });
8789
8806
  return result;
8790
8807
  }
8791
8808
  function parseCardLine(trimmed, lineNumber, counter, aliasMap, _palette, _diagnostics) {
@@ -9911,7 +9928,7 @@ function parseSitemap(content, palette) {
9911
9928
  };
9912
9929
  collectAll(result.roots);
9913
9930
  validateTagValues(allNodes, result.tagGroups, pushWarning, suggest);
9914
- validateTagGroupNames(result.tagGroups, pushWarning);
9931
+ validateTagGroupNames(result.tagGroups, pushWarning, pushError);
9915
9932
  }
9916
9933
  if (result.roots.length === 0 && result.tagGroups.length === 0 && !result.error) {
9917
9934
  const diag = makeDgmoError(1, "No pages found in sitemap");
@@ -10548,7 +10565,7 @@ function parseInfra(content) {
10548
10565
  }
10549
10566
  }
10550
10567
  }
10551
- validateTagGroupNames(result.tagGroups, warn);
10568
+ validateTagGroupNames(result.tagGroups, warn, setError);
10552
10569
  return result;
10553
10570
  }
10554
10571
  function extractSymbols4(docText) {
@@ -11489,7 +11506,11 @@ function parseGantt(content, palette) {
11489
11506
  warn(0, "sort tag has no effect \u2014 no tag groups defined.");
11490
11507
  result.options.sort = "default";
11491
11508
  }
11492
- validateTagGroupNames(result.tagGroups, warn);
11509
+ validateTagGroupNames(result.tagGroups, warn, (line11, msg) => {
11510
+ const diag = makeDgmoError(line11, msg);
11511
+ diagnostics.push(diag);
11512
+ if (!result.error) result.error = formatDgmoError(diag);
11513
+ });
11493
11514
  const hasSprintOption = result.options.sprintLength !== null || result.options.sprintNumber !== null || result.options.sprintStart !== null;
11494
11515
  const hasSprintUnit = hasSprintDurationUnit(result.nodes);
11495
11516
  if (hasSprintOption) {
@@ -11753,6 +11774,7 @@ function parseBoxesAndLines(content) {
11753
11774
  const groupLabels = /* @__PURE__ */ new Set();
11754
11775
  let lastNodeLabel = null;
11755
11776
  let lastSourceIsGroup = false;
11777
+ let lastNodeIndent = 0;
11756
11778
  let descState = null;
11757
11779
  function flushDescription() {
11758
11780
  if (descState && descState.lines.length > 0) {
@@ -12050,7 +12072,8 @@ function parseBoxesAndLines(content) {
12050
12072
  if (trimmed.startsWith("->") || /^-[^>].*->/.test(trimmed)) {
12051
12073
  const gs2 = currentGroupState();
12052
12074
  const inGroup = gs2 && indent > gs2.indent;
12053
- if (inGroup) {
12075
+ const indentedUnderNode = lastNodeLabel && !lastSourceIsGroup && indent > lastNodeIndent;
12076
+ if (inGroup && !indentedUnderNode) {
12054
12077
  const sourcePrefix = `[${gs2.group.label}]`;
12055
12078
  edgeText = `${sourcePrefix} ${trimmed}`;
12056
12079
  } else if (lastNodeLabel) {
@@ -12090,6 +12113,7 @@ function parseBoxesAndLines(content) {
12090
12113
  }
12091
12114
  lastNodeLabel = node.label;
12092
12115
  lastSourceIsGroup = false;
12116
+ lastNodeIndent = indent;
12093
12117
  const gs = currentGroupState();
12094
12118
  const isGroupChild = gs && indent > gs.indent;
12095
12119
  if (nodeLabels.has(node.label)) {
@@ -12158,7 +12182,11 @@ function parseBoxesAndLines(content) {
12158
12182
  if (result.tagGroups.length > 0) {
12159
12183
  injectDefaultTagMetadata(result.nodes, result.tagGroups);
12160
12184
  validateTagValues(result.nodes, result.tagGroups, pushWarning, suggest);
12161
- validateTagGroupNames(result.tagGroups, pushWarning);
12185
+ validateTagGroupNames(result.tagGroups, pushWarning, (line11, msg) => {
12186
+ const diag = makeDgmoError(line11, msg);
12187
+ result.diagnostics.push(diag);
12188
+ if (!result.error) result.error = diag.message;
12189
+ });
12162
12190
  }
12163
12191
  return result;
12164
12192
  }
@@ -13134,7 +13162,9 @@ function parseWireframe(content) {
13134
13162
  }
13135
13163
  }
13136
13164
  }
13137
- validateTagGroupNames(tagGroups, pushWarning);
13165
+ validateTagGroupNames(tagGroups, pushWarning, (line11, msg) => {
13166
+ diagnostics.push(makeDgmoError(line11, msg));
13167
+ });
13138
13168
  const error = diagnostics.find((d) => d.severity === "error") ? formatDgmoError(diagnostics.find((d) => d.severity === "error")) : null;
13139
13169
  return {
13140
13170
  title,
@@ -14062,7 +14092,11 @@ function parseJourneyMap(content, palette) {
14062
14092
  if (result.phases.length === 0 && result.steps.length === 0 && !result.error) {
14063
14093
  return fail(1, "No phases or steps found");
14064
14094
  }
14065
- validateTagGroupNames(result.tagGroups, warn);
14095
+ validateTagGroupNames(result.tagGroups, warn, (line11, msg) => {
14096
+ const diag = makeDgmoError(line11, msg);
14097
+ result.diagnostics.push(diag);
14098
+ if (!result.error) result.error = formatDgmoError(diag);
14099
+ });
14066
14100
  return result;
14067
14101
  }
14068
14102
  function parseStepLine(trimmed, lineNumber, counter, aliasMap, warn) {
@@ -14292,13 +14326,425 @@ var init_parser16 = __esm({
14292
14326
  }
14293
14327
  });
14294
14328
 
14329
+ // src/chart-types.ts
14330
+ var chartTypes;
14331
+ var init_chart_types = __esm({
14332
+ "src/chart-types.ts"() {
14333
+ "use strict";
14334
+ chartTypes = [
14335
+ // ── Tier 1 — Narrative / architecture diagrams ────────────
14336
+ {
14337
+ id: "journey-map",
14338
+ description: "User experience flow with emotion scores, phases, and annotations",
14339
+ triggers: [
14340
+ "user journey",
14341
+ "customer journey",
14342
+ "customer experience",
14343
+ "customer goes through",
14344
+ "user goes through",
14345
+ "customer path",
14346
+ "customer touchpoints",
14347
+ "cx flow",
14348
+ "ux journey",
14349
+ "onboarding flow",
14350
+ "persona journey",
14351
+ "empathy map",
14352
+ "service blueprint"
14353
+ ]
14354
+ },
14355
+ {
14356
+ id: "c4",
14357
+ description: "System architecture (context, container, component, deployment)",
14358
+ triggers: [
14359
+ "c4 diagram",
14360
+ "system context",
14361
+ "container diagram",
14362
+ "component diagram",
14363
+ "architecture overview",
14364
+ "software architecture"
14365
+ ]
14366
+ },
14367
+ {
14368
+ id: "er",
14369
+ description: "Database schemas and relationships",
14370
+ triggers: [
14371
+ "database schema",
14372
+ "er diagram",
14373
+ "entity relationship",
14374
+ "data model",
14375
+ "tables and relationships",
14376
+ "foreign keys"
14377
+ ]
14378
+ },
14379
+ {
14380
+ id: "class",
14381
+ description: "UML class hierarchies",
14382
+ triggers: [
14383
+ "uml class",
14384
+ "class hierarchy",
14385
+ "class diagram",
14386
+ "inheritance tree",
14387
+ "oop structure"
14388
+ ]
14389
+ },
14390
+ {
14391
+ id: "sequence",
14392
+ description: "Message / interaction flows",
14393
+ triggers: [
14394
+ "sequence diagram",
14395
+ "message flow",
14396
+ "api call flow",
14397
+ "request lifecycle",
14398
+ "interaction diagram",
14399
+ "call sequence"
14400
+ ],
14401
+ fallback: true
14402
+ },
14403
+ {
14404
+ id: "state",
14405
+ description: "State machine / lifecycle transitions",
14406
+ triggers: [
14407
+ "state diagram",
14408
+ "state machine",
14409
+ "state transitions",
14410
+ "lifecycle diagram",
14411
+ "status transitions"
14412
+ ]
14413
+ },
14414
+ {
14415
+ id: "infra",
14416
+ description: "Infrastructure traffic flow with RPS computation",
14417
+ triggers: [
14418
+ "infrastructure diagram",
14419
+ "traffic flow",
14420
+ "request path",
14421
+ "rps",
14422
+ "capacity planning",
14423
+ "network topology"
14424
+ ]
14425
+ },
14426
+ {
14427
+ id: "gantt",
14428
+ description: "Project scheduling with task dependencies and milestones",
14429
+ triggers: [
14430
+ "gantt chart",
14431
+ "project schedule",
14432
+ "sprint plan",
14433
+ "project timeline",
14434
+ "task dependencies",
14435
+ "project milestones"
14436
+ ]
14437
+ },
14438
+ // ── Tier 2 — Specialized structural diagrams ──────────────
14439
+ {
14440
+ id: "timeline",
14441
+ description: "Events, eras, and date ranges",
14442
+ triggers: [
14443
+ "event timeline",
14444
+ "historical timeline",
14445
+ "era chart",
14446
+ "period chart",
14447
+ "project history"
14448
+ ]
14449
+ },
14450
+ {
14451
+ id: "org",
14452
+ description: "Reporting hierarchy",
14453
+ triggers: [
14454
+ "org chart",
14455
+ "organization chart",
14456
+ "reporting structure",
14457
+ "hierarchy chart",
14458
+ "team structure"
14459
+ ]
14460
+ },
14461
+ {
14462
+ id: "sitemap",
14463
+ description: "Site / app navigation structure",
14464
+ triggers: [
14465
+ "sitemap",
14466
+ "site structure",
14467
+ "page hierarchy",
14468
+ "navigation structure",
14469
+ "app navigation"
14470
+ ]
14471
+ },
14472
+ {
14473
+ id: "kanban",
14474
+ description: "Task board columns",
14475
+ triggers: [
14476
+ "kanban board",
14477
+ "task board",
14478
+ "workflow columns",
14479
+ "todo doing done",
14480
+ "agile board"
14481
+ ]
14482
+ },
14483
+ {
14484
+ id: "tech-radar",
14485
+ description: "Technology adoption quadrants (adopt/trial/assess/hold)",
14486
+ triggers: [
14487
+ "tech radar",
14488
+ "technology radar",
14489
+ "tech adoption",
14490
+ "adopt trial assess hold",
14491
+ "tech choices"
14492
+ ]
14493
+ },
14494
+ {
14495
+ id: "mindmap",
14496
+ description: "Radial hierarchy of ideas branching from a central topic",
14497
+ triggers: [
14498
+ "mind map",
14499
+ "brainstorm diagram",
14500
+ "concept map",
14501
+ "idea tree",
14502
+ "radial ideas"
14503
+ ]
14504
+ },
14505
+ {
14506
+ id: "wireframe",
14507
+ description: "Low-fidelity UI layout with panels, controls, and annotations",
14508
+ triggers: [
14509
+ "wireframe",
14510
+ "ui mockup",
14511
+ "screen layout",
14512
+ "page layout",
14513
+ "low-fidelity mockup"
14514
+ ]
14515
+ },
14516
+ {
14517
+ id: "cycle",
14518
+ description: "Cyclical process visualization (PDCA, OODA, DevOps loops)",
14519
+ triggers: [
14520
+ "pdca cycle",
14521
+ "ooda loop",
14522
+ "feedback loop",
14523
+ "cyclical process",
14524
+ "devops loop",
14525
+ "continuous loop"
14526
+ ]
14527
+ },
14528
+ {
14529
+ id: "pyramid",
14530
+ description: "Stacked hierarchy of layers with descriptions (Maslow, DIKW)",
14531
+ triggers: [
14532
+ "pyramid diagram",
14533
+ "layered hierarchy",
14534
+ "maslow hierarchy",
14535
+ "dikw pyramid",
14536
+ "layered model"
14537
+ ]
14538
+ },
14539
+ // ── Tier 3 — Specialized analytical charts ────────────────
14540
+ {
14541
+ id: "quadrant",
14542
+ description: "2x2 positioning matrix",
14543
+ triggers: [
14544
+ "2x2 matrix",
14545
+ "priority matrix",
14546
+ "quadrant chart",
14547
+ "impact effort matrix",
14548
+ "positioning matrix"
14549
+ ]
14550
+ },
14551
+ {
14552
+ id: "venn",
14553
+ description: "Set overlaps",
14554
+ triggers: [
14555
+ "venn diagram",
14556
+ "set overlap",
14557
+ "intersection of",
14558
+ "shared traits",
14559
+ "overlapping circles"
14560
+ ]
14561
+ },
14562
+ {
14563
+ id: "funnel",
14564
+ description: "Conversion pipeline",
14565
+ triggers: [
14566
+ "conversion funnel",
14567
+ "sales funnel",
14568
+ "user funnel",
14569
+ "pipeline stages",
14570
+ "drop-off funnel"
14571
+ ]
14572
+ },
14573
+ {
14574
+ id: "slope",
14575
+ description: "Change between two periods",
14576
+ triggers: [
14577
+ "slope chart",
14578
+ "before and after",
14579
+ "two-period change",
14580
+ "delta chart",
14581
+ "shift comparison"
14582
+ ]
14583
+ },
14584
+ {
14585
+ id: "sankey",
14586
+ description: "Flow / allocation visualization",
14587
+ triggers: [
14588
+ "sankey diagram",
14589
+ "flow allocation",
14590
+ "budget flow",
14591
+ "energy flow",
14592
+ "traffic allocation"
14593
+ ]
14594
+ },
14595
+ {
14596
+ id: "chord",
14597
+ description: "Circular flow relationships",
14598
+ triggers: [
14599
+ "chord diagram",
14600
+ "circular flow",
14601
+ "relationship wheel",
14602
+ "team connections"
14603
+ ]
14604
+ },
14605
+ {
14606
+ id: "arc",
14607
+ description: "Network relationships",
14608
+ triggers: [
14609
+ "arc diagram",
14610
+ "relationship chart",
14611
+ "connection arcs",
14612
+ "network arcs"
14613
+ ]
14614
+ },
14615
+ {
14616
+ id: "wordcloud",
14617
+ description: "Term frequency visualization",
14618
+ triggers: [
14619
+ "word cloud",
14620
+ "tag cloud",
14621
+ "term frequency",
14622
+ "keyword frequency"
14623
+ ]
14624
+ },
14625
+ {
14626
+ id: "heatmap",
14627
+ description: "Matrix intensity visualization",
14628
+ triggers: [
14629
+ "heatmap",
14630
+ "intensity matrix",
14631
+ "activity heatmap",
14632
+ "correlation matrix"
14633
+ ]
14634
+ },
14635
+ {
14636
+ id: "function",
14637
+ description: "Mathematical expressions",
14638
+ triggers: [
14639
+ "function plot",
14640
+ "mathematical plot",
14641
+ "equation chart",
14642
+ "graph y=f(x)"
14643
+ ]
14644
+ },
14645
+ // ── Tier 4 — General-purpose data charts ──────────────────
14646
+ {
14647
+ id: "bar",
14648
+ description: "Categorical comparisons",
14649
+ triggers: ["bar chart", "categorical comparison", "bar graph"],
14650
+ fallback: true
14651
+ },
14652
+ {
14653
+ id: "line",
14654
+ description: "Trends over time",
14655
+ triggers: ["line chart", "trend over time", "time series"],
14656
+ fallback: true
14657
+ },
14658
+ {
14659
+ id: "multi-line",
14660
+ description: "Multiple series trends over time",
14661
+ triggers: [
14662
+ "multi-line chart",
14663
+ "multiple trends",
14664
+ "multiple series over time"
14665
+ ]
14666
+ },
14667
+ {
14668
+ id: "area",
14669
+ description: "Filled line chart",
14670
+ triggers: ["area chart", "filled line", "cumulative trend"]
14671
+ },
14672
+ {
14673
+ id: "pie",
14674
+ description: "Part-to-whole proportions",
14675
+ triggers: ["pie chart", "part to whole", "percentage breakdown"]
14676
+ },
14677
+ {
14678
+ id: "doughnut",
14679
+ description: "Ring-style pie chart",
14680
+ triggers: ["doughnut chart", "donut chart", "ring chart"]
14681
+ },
14682
+ {
14683
+ id: "radar",
14684
+ description: "Multi-dimensional metrics",
14685
+ triggers: ["radar chart", "spider chart", "multi-dimensional metrics"]
14686
+ },
14687
+ {
14688
+ id: "polar-area",
14689
+ description: "Radial bar chart",
14690
+ triggers: ["polar area", "radial bar chart"]
14691
+ },
14692
+ {
14693
+ id: "bar-stacked",
14694
+ description: "Multi-series categorical",
14695
+ triggers: [
14696
+ "stacked bar",
14697
+ "stacked bar chart",
14698
+ "multi-series bar",
14699
+ "composite bar"
14700
+ ]
14701
+ },
14702
+ {
14703
+ id: "scatter",
14704
+ description: "2D data points or bubble chart",
14705
+ triggers: [
14706
+ "scatter plot",
14707
+ "correlation plot",
14708
+ "bubble chart",
14709
+ "2d data points"
14710
+ ]
14711
+ },
14712
+ // ── Tier 5 — Generic catch-alls (listed last on purpose) ──
14713
+ {
14714
+ id: "flowchart",
14715
+ description: "Decision trees and process flows",
14716
+ triggers: [
14717
+ "flowchart",
14718
+ "decision tree",
14719
+ "if-then diagram",
14720
+ "process flow with decisions"
14721
+ ],
14722
+ fallback: true
14723
+ },
14724
+ {
14725
+ id: "boxes-and-lines",
14726
+ description: "General-purpose node-edge diagrams with groups and tags",
14727
+ triggers: [
14728
+ "boxes and lines",
14729
+ "nodes and edges",
14730
+ "generic diagram",
14731
+ "general-purpose network"
14732
+ ],
14733
+ fallback: true
14734
+ }
14735
+ ];
14736
+ }
14737
+ });
14738
+
14295
14739
  // src/dgmo-router.ts
14296
14740
  var dgmo_router_exports = {};
14297
14741
  __export(dgmo_router_exports, {
14298
14742
  CHART_TYPE_DESCRIPTIONS: () => CHART_TYPE_DESCRIPTIONS,
14743
+ chartTypeParsers: () => chartTypeParsers,
14299
14744
  getAllChartTypes: () => getAllChartTypes,
14300
14745
  getRenderCategory: () => getRenderCategory,
14301
14746
  isExtendedChartType: () => isExtendedChartType,
14747
+ knownChartTypeIds: () => knownChartTypeIds,
14302
14748
  looksLikeC4: () => looksLikeC4,
14303
14749
  looksLikeGantt: () => looksLikeGantt,
14304
14750
  parseDgmo: () => parseDgmo,
@@ -14357,7 +14803,7 @@ function isExtendedChartType(chartType) {
14357
14803
  return EXTENDED_CHART_TYPES.has(chartType.toLowerCase());
14358
14804
  }
14359
14805
  function getAllChartTypes() {
14360
- return [...DATA_CHART_TYPES, ...VISUALIZATION_TYPES, ...DIAGRAM_TYPES];
14806
+ return chartTypes.map((c) => c.id);
14361
14807
  }
14362
14808
  function parseDgmo(content) {
14363
14809
  const chartType = parseDgmoChartType(content);
@@ -14372,23 +14818,9 @@ function parseDgmo(content) {
14372
14818
  chartType: null
14373
14819
  };
14374
14820
  }
14375
- const directParser = PARSE_DISPATCH.get(chartType);
14376
- if (directParser) {
14377
- const result2 = directParser(content);
14378
- return {
14379
- diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)],
14380
- chartType
14381
- };
14382
- }
14383
- if (STANDARD_CHART_TYPES2.has(chartType)) {
14384
- const result2 = parseChart(content);
14385
- return {
14386
- diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)],
14387
- chartType
14388
- };
14389
- }
14390
- if (ECHART_TYPES.has(chartType)) {
14391
- const result2 = parseExtendedChart(content);
14821
+ const parser = PARSER_BY_ID.get(chartType);
14822
+ if (parser) {
14823
+ const result2 = parser(content);
14392
14824
  return {
14393
14825
  diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)],
14394
14826
  chartType
@@ -14440,7 +14872,7 @@ function detectEmptyContent(content) {
14440
14872
  }
14441
14873
  return [];
14442
14874
  }
14443
- var GANTT_DURATION_RE, GANTT_DATE_RE, C4_TYPE_RE, DATA_CHART_TYPES, VISUALIZATION_TYPES, DIAGRAM_TYPES, EXTENDED_CHART_TYPES, STANDARD_CHART_TYPES2, CHART_TYPE_DESCRIPTIONS, ECHART_TYPES, PARSE_DISPATCH, ALL_KNOWN_TYPES;
14875
+ var GANTT_DURATION_RE, GANTT_DATE_RE, C4_TYPE_RE, DATA_CHART_TYPES, VISUALIZATION_TYPES, DIAGRAM_TYPES, EXTENDED_CHART_TYPES, CHART_TYPE_DESCRIPTIONS, chartTypeParsers, knownChartTypeIds, PARSER_BY_ID, ALL_KNOWN_TYPES;
14444
14876
  var init_dgmo_router = __esm({
14445
14877
  "src/dgmo-router.ts"() {
14446
14878
  "use strict";
@@ -14467,6 +14899,7 @@ var init_dgmo_router = __esm({
14467
14899
  init_parser16();
14468
14900
  init_parsing();
14469
14901
  init_diagnostics();
14902
+ init_chart_types();
14470
14903
  GANTT_DURATION_RE = /^\d+(?:\.\d+)?(?:min|bd|d|w|m|q|y|h)(?:\?)?\s+/;
14471
14904
  GANTT_DATE_RE = /^\d{4}-\d{2}-\d{2}(?:\s\d{2}:\d{2})?\s+/;
14472
14905
  C4_TYPE_RE = /\bis\s+an?\s+(person|system|container|component)\b/i;
@@ -14523,91 +14956,57 @@ var init_dgmo_router = __esm({
14523
14956
  "heatmap",
14524
14957
  "funnel"
14525
14958
  ]);
14526
- STANDARD_CHART_TYPES2 = /* @__PURE__ */ new Set([
14527
- "bar",
14528
- "line",
14529
- "multi-line",
14530
- "area",
14531
- "pie",
14532
- "doughnut",
14533
- "radar",
14534
- "polar-area",
14535
- "bar-stacked"
14536
- ]);
14537
- CHART_TYPE_DESCRIPTIONS = {
14538
- bar: "Bar chart \u2014 categorical comparisons",
14539
- line: "Line chart \u2014 trends over time; supports era bands (era start -> end Label (color)) for annotating named periods",
14540
- "multi-line": "Multi-line chart \u2014 multiple series trends over time; supports era bands",
14541
- area: "Area chart \u2014 filled line chart; supports era bands",
14542
- pie: "Pie chart \u2014 part-to-whole proportions",
14543
- doughnut: "Doughnut chart \u2014 ring-style pie chart",
14544
- radar: "Radar chart \u2014 multi-dimensional metrics",
14545
- "polar-area": "Polar area chart \u2014 radial bar chart",
14546
- "bar-stacked": "Stacked bar chart \u2014 multi-series categorical",
14547
- scatter: "Scatter plot \u2014 2D data points or bubble chart",
14548
- sankey: "Sankey diagram \u2014 flow/allocation visualization",
14549
- chord: "Chord diagram \u2014 circular flow relationships",
14550
- function: "Function plot \u2014 mathematical expressions",
14551
- heatmap: "Heatmap \u2014 matrix intensity visualization",
14552
- funnel: "Funnel chart \u2014 conversion pipeline",
14553
- slope: "Slope chart \u2014 change between two periods",
14554
- wordcloud: "Word cloud \u2014 term frequency visualization",
14555
- arc: "Arc diagram \u2014 network relationships",
14556
- timeline: "Timeline \u2014 events, eras, and date ranges",
14557
- venn: "Venn diagram \u2014 set overlaps",
14558
- quadrant: "Quadrant chart \u2014 2x2 positioning matrix",
14559
- "tech-radar": "Tech radar \u2014 technology adoption quadrants (adopt/trial/assess/hold)",
14560
- cycle: "Cycle diagram \u2014 cyclical process visualization (PDCA, OODA, DevOps loops)",
14561
- sequence: "Sequence diagram \u2014 message/interaction flows",
14562
- flowchart: "Flowchart \u2014 decision trees and process flows",
14563
- class: "Class diagram \u2014 UML class hierarchies",
14564
- er: "ER diagram \u2014 database schemas and relationships",
14565
- org: "Org chart \u2014 hierarchical tree structures",
14566
- kanban: "Kanban board \u2014 task/workflow columns",
14567
- c4: "C4 diagram \u2014 system architecture (context, container, component, deployment)",
14568
- state: "State diagram \u2014 state machine / lifecycle transitions",
14569
- sitemap: "Sitemap \u2014 navigable UI structure with pages, groups, and cross-link arrows",
14570
- infra: "Infrastructure diagram \u2014 traffic flow with RPS computation, capacity modeling, and latency analysis",
14571
- gantt: "Gantt chart \u2014 project scheduling with task dependencies and milestones",
14572
- "boxes-and-lines": "Boxes and lines \u2014 general-purpose node-edge diagrams with nested groups, tags, and shape inference",
14573
- mindmap: "Mindmap \u2014 radial hierarchy of ideas branching from a central topic",
14574
- wireframe: "Wireframe \u2014 low-fidelity UI layout with panels, controls, and annotations",
14575
- "journey-map": "Journey map \u2014 user experience flow with emotion scores, phases, and annotations",
14576
- pyramid: "Pyramid \u2014 hierarchical layered pyramid (Maslow, DIKW, learning pyramid); inverted for funnel-of-learning style"
14577
- };
14578
- ECHART_TYPES = /* @__PURE__ */ new Set([
14579
- "scatter",
14580
- "sankey",
14581
- "chord",
14582
- "function",
14583
- "heatmap",
14584
- "funnel"
14585
- ]);
14586
- PARSE_DISPATCH = /* @__PURE__ */ new Map([
14587
- ["sequence", (c) => parseSequenceDgmo(c)],
14588
- ["flowchart", (c) => parseFlowchart(c)],
14589
- ["class", (c) => parseClassDiagram(c)],
14590
- ["er", (c) => parseERDiagram(c)],
14591
- ["org", (c) => parseOrg(c)],
14592
- ["kanban", (c) => parseKanban(c)],
14593
- ["c4", (c) => parseC4(c)],
14594
- ["state", (c) => parseState(c)],
14595
- ["sitemap", (c) => parseSitemap(c)],
14596
- ["infra", (c) => parseInfra(c)],
14597
- ["gantt", (c) => parseGantt(c)],
14598
- ["boxes-and-lines", (c) => parseBoxesAndLines(c)],
14599
- ["mindmap", (c) => parseMindmap(c)],
14600
- ["wireframe", (c) => parseWireframe(c)],
14601
- ["tech-radar", (c) => parseTechRadar(c)],
14602
- ["cycle", (c) => parseCycle(c)],
14603
- ["journey-map", (c) => parseJourneyMap(c)],
14604
- ["pyramid", (c) => parsePyramid(c)]
14605
- ]);
14606
- ALL_KNOWN_TYPES = /* @__PURE__ */ new Set([
14607
- ...DATA_CHART_TYPES,
14608
- ...VISUALIZATION_TYPES,
14609
- ...DIAGRAM_TYPES
14610
- ]);
14959
+ CHART_TYPE_DESCRIPTIONS = Object.fromEntries(chartTypes.map((c) => [c.id, c.description]));
14960
+ chartTypeParsers = [
14961
+ // Structured diagrams (direct parsers)
14962
+ ["sequence", parseSequenceDgmo],
14963
+ ["flowchart", parseFlowchart],
14964
+ ["class", parseClassDiagram],
14965
+ ["er", parseERDiagram],
14966
+ ["state", parseState],
14967
+ ["org", parseOrg],
14968
+ ["kanban", parseKanban],
14969
+ ["c4", parseC4],
14970
+ ["sitemap", parseSitemap],
14971
+ ["infra", parseInfra],
14972
+ ["gantt", parseGantt],
14973
+ ["boxes-and-lines", parseBoxesAndLines],
14974
+ ["mindmap", parseMindmap],
14975
+ ["wireframe", parseWireframe],
14976
+ ["tech-radar", parseTechRadar],
14977
+ ["cycle", parseCycle],
14978
+ ["journey-map", parseJourneyMap],
14979
+ ["pyramid", parsePyramid],
14980
+ // Standard ECharts charts (parseChart)
14981
+ ["bar", parseChart],
14982
+ ["line", parseChart],
14983
+ ["multi-line", parseChart],
14984
+ ["area", parseChart],
14985
+ ["pie", parseChart],
14986
+ ["doughnut", parseChart],
14987
+ ["radar", parseChart],
14988
+ ["polar-area", parseChart],
14989
+ ["bar-stacked", parseChart],
14990
+ // Extended ECharts charts (parseExtendedChart)
14991
+ ["scatter", parseExtendedChart],
14992
+ ["sankey", parseExtendedChart],
14993
+ ["chord", parseExtendedChart],
14994
+ ["function", parseExtendedChart],
14995
+ ["heatmap", parseExtendedChart],
14996
+ ["funnel", parseExtendedChart],
14997
+ // D3 visualizations (parseVisualization)
14998
+ ["slope", parseVisualization],
14999
+ ["wordcloud", parseVisualization],
15000
+ ["arc", parseVisualization],
15001
+ ["timeline", parseVisualization],
15002
+ ["venn", parseVisualization],
15003
+ ["quadrant", parseVisualization]
15004
+ ];
15005
+ knownChartTypeIds = chartTypeParsers.map(
15006
+ ([id]) => id
15007
+ );
15008
+ PARSER_BY_ID = new Map(chartTypeParsers);
15009
+ ALL_KNOWN_TYPES = new Set(knownChartTypeIds);
14611
15010
  }
14612
15011
  });
14613
15012
 
@@ -19643,7 +20042,16 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
19643
20042
  const clipId = `bl-clip-${group.label.replace(/[[\]\s]/g, "")}`;
19644
20043
  groupG.append("clipPath").attr("id", clipId).append("rect").attr("x", gx).attr("y", gy).attr("width", group.width).attr("height", group.height).attr("rx", NODE_RX);
19645
20044
  groupG.append("rect").attr("x", gx).attr("y", gy + group.height - COLLAPSE_BAR_HEIGHT3).attr("width", group.width).attr("height", COLLAPSE_BAR_HEIGHT3).attr("fill", strokeColor).attr("clip-path", `url(#${clipId})`).attr("class", "bl-collapse-bar");
19646
- groupG.append("text").attr("class", "bl-group-label").attr("x", group.x).attr("y", group.y).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-family", FONT_FAMILY).attr("font-size", GROUP_LABEL_FONT_SIZE).attr("font-weight", "600").attr("fill", palette.text).text(group.label);
20045
+ const maxLabelLines = Math.max(
20046
+ 2,
20047
+ Math.floor((group.height - 16) / (MIN_NODE_FONT_SIZE * 1.3))
20048
+ );
20049
+ const fitted = fitLabelToHeader(group.label, group.width, maxLabelLines);
20050
+ const lineH = fitted.fontSize * 1.3;
20051
+ const totalH = fitted.lines.length * lineH;
20052
+ for (let li = 0; li < fitted.lines.length; li++) {
20053
+ groupG.append("text").attr("class", "bl-group-label").attr("x", group.x).attr("y", group.y - totalH / 2 + lineH / 2 + li * lineH).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-family", FONT_FAMILY).attr("font-size", fitted.fontSize).attr("font-weight", "600").attr("fill", palette.text).text(fitted.lines[li]);
20054
+ }
19647
20055
  } else {
19648
20056
  groupG.append("rect").attr("x", gx).attr("y", gy).attr("width", group.width).attr("height", groupHeight).attr("rx", GROUP_RX).attr("ry", GROUP_RX).attr("fill", mix(palette.surface, palette.bg, 40)).attr("stroke", palette.textMuted).attr("stroke-width", 1).attr("stroke-opacity", 0.35);
19649
20057
  groupG.append("text").attr("class", "bl-group-label").attr("x", gx + group.width / 2).attr("y", gy + 18).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", GROUP_LABEL_FONT_SIZE).attr("font-weight", "600").attr("fill", palette.text).text(group.label);
@@ -32128,7 +32536,6 @@ var init_renderer12 = __esm({
32128
32536
  // src/journey-map/layout.ts
32129
32537
  var layout_exports11 = {};
32130
32538
  __export(layout_exports11, {
32131
- COLLAPSED_PHASE_WIDTH: () => COLLAPSED_PHASE_WIDTH,
32132
32539
  TAG_STRIP_HEIGHT: () => TAG_STRIP_HEIGHT,
32133
32540
  layoutJourneyMap: () => layoutJourneyMap,
32134
32541
  scoreToColor: () => scoreToColor
@@ -32154,7 +32561,8 @@ function layoutJourneyMap(parsed, palette, options) {
32154
32561
  const annoIconIndent = ANNO_ICON_SIZE + ANNO_ICON_GAP;
32155
32562
  const annoTextW = STEP_CARD_WIDTH - CARD_PADDING_X2 * 2 - annoIconIndent;
32156
32563
  const descTextWidth = STEP_CARD_WIDTH - CARD_PADDING_X2 * 2;
32157
- const charWidth = 4.8;
32564
+ const FONT_SIZE_META2 = 10;
32565
+ const charWidth = FONT_SIZE_META2 * 0.6;
32158
32566
  const titleTextWidth = STEP_CARD_WIDTH - CARD_PADDING_X2 * 2;
32159
32567
  const titleCharWidth = 6.5;
32160
32568
  const TITLE_LINE_HEIGHT2 = 16;
@@ -32321,7 +32729,7 @@ function wrapLineCount(text, maxWidth, charWidth) {
32321
32729
  }
32322
32730
  return lines;
32323
32731
  }
32324
- var PADDING, TITLE_HEIGHT7, PERSONA_HEIGHT, CURVE_AREA_HEIGHT, CARD_GAP2, STEP_CARD_WIDTH, CARD_HEADER_HEIGHT2, CARD_META_LINE_HEIGHT2, PHASE_HEADER_HEIGHT, CARD_PADDING_X2, CARD_PADDING_Y2, ANNO_ICON_SIZE, ANNO_ICON_GAP, TAG_STRIP_HEIGHT, PHASE_GAP, COLUMN_PADDING2, FACE_ICON_SIZE, COLLAPSED_PHASE_WIDTH;
32732
+ var PADDING, TITLE_HEIGHT7, PERSONA_HEIGHT, CURVE_AREA_HEIGHT, CARD_GAP2, STEP_CARD_WIDTH, CARD_HEADER_HEIGHT2, CARD_META_LINE_HEIGHT2, PHASE_HEADER_HEIGHT, CARD_PADDING_X2, CARD_PADDING_Y2, ANNO_ICON_SIZE, ANNO_ICON_GAP, TAG_STRIP_HEIGHT, PHASE_GAP, COLUMN_PADDING2, FACE_ICON_SIZE;
32325
32733
  var init_layout12 = __esm({
32326
32734
  "src/journey-map/layout.ts"() {
32327
32735
  "use strict";
@@ -32343,7 +32751,6 @@ var init_layout12 = __esm({
32343
32751
  PHASE_GAP = 16;
32344
32752
  COLUMN_PADDING2 = 12;
32345
32753
  FACE_ICON_SIZE = 20;
32346
- COLLAPSED_PHASE_WIDTH = 60;
32347
32754
  }
32348
32755
  });
32349
32756
 
@@ -34537,7 +34944,6 @@ __export(renderer_exports16, {
34537
34944
  applyPositionOverrides: () => applyPositionOverrides,
34538
34945
  buildNoteMessageMap: () => buildNoteMessageMap,
34539
34946
  buildRenderSequence: () => buildRenderSequence,
34540
- collectNoteLineNumbers: () => collectNoteLineNumbers,
34541
34947
  computeActivations: () => computeActivations,
34542
34948
  groupMessagesBySection: () => groupMessagesBySection,
34543
34949
  parseInlineMarkdown: () => parseInlineMarkdown,
@@ -34920,9 +35326,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
34920
35326
  const groups = collapsed ? collapsed.groups : parsed.groups;
34921
35327
  const collapsedGroupIds = collapsed?.collapsedGroupIds ?? /* @__PURE__ */ new Map();
34922
35328
  const collapsedSections = options?.collapsedSections;
34923
- const expandedNoteLines = options?.expandedNoteLines;
34924
- const collapseNotesDisabled = parsedOptions["collapse-notes"]?.toLowerCase() === "no";
34925
- const isNoteExpanded = (note) => expandedNoteLines === void 0 || collapseNotesDisabled || expandedNoteLines.has(note.lineNumber);
34926
35329
  const sourceParticipants = collapsed ? collapsed.participants : parsed.participants;
34927
35330
  const participants = applyPositionOverrides(
34928
35331
  applyGroupOrdering(sourceParticipants, groups, messages)
@@ -35091,7 +35494,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35091
35494
  const note = els[j];
35092
35495
  const sc = isNoteAfterSelfCall(note);
35093
35496
  const maxW = noteEffectiveMaxW(note.participantId, note.position, sc);
35094
- const noteH = isNoteExpanded(note) ? computeNoteHeight(note.text, charsForWidth(maxW)) : COLLAPSED_NOTE_H;
35497
+ const noteH = computeNoteHeight(note.text, charsForWidth(maxW));
35095
35498
  totalExtent += noteH + NOTE_OFFSET_BELOW;
35096
35499
  j++;
35097
35500
  }
@@ -35287,7 +35690,10 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35287
35690
  prevNote.position,
35288
35691
  isNoteAfterSelfCall(prevNote)
35289
35692
  );
35290
- const prevNoteH = isNoteExpanded(prevNote) ? computeNoteHeight(prevNote.text, charsForWidth(prevMaxW)) : COLLAPSED_NOTE_H;
35693
+ const prevNoteH = computeNoteHeight(
35694
+ prevNote.text,
35695
+ charsForWidth(prevMaxW)
35696
+ );
35291
35697
  noteTopY = prevNoteY + prevNoteH + NOTE_OFFSET_BELOW;
35292
35698
  } else {
35293
35699
  noteTopY = stepY(si) + noteOffsetBelow(el);
@@ -35318,7 +35724,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35318
35724
  note.position,
35319
35725
  isNoteAfterSelfCall(note)
35320
35726
  );
35321
- const noteH = isNoteExpanded(note) ? computeNoteHeight(note.text, charsForWidth(maxW)) : COLLAPSED_NOTE_H;
35727
+ const noteH = computeNoteHeight(note.text, charsForWidth(maxW));
35322
35728
  contentBottomY = Math.max(
35323
35729
  contentBottomY,
35324
35730
  noteTopY + noteH + NOTE_TRAILING_GAP
@@ -35388,24 +35794,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35388
35794
  titleEl.attr("data-line-number", parsed.titleLineNumber);
35389
35795
  }
35390
35796
  }
35391
- const allNoteLineNumbers = [];
35392
- const collectNoteLines = (els) => {
35393
- for (const el of els) {
35394
- if (isSequenceNote(el)) {
35395
- allNoteLineNumbers.push(el.lineNumber);
35396
- } else if (isSequenceBlock(el)) {
35397
- collectNoteLines(el.children);
35398
- if ("elseChildren" in el) collectNoteLines(el.elseChildren);
35399
- if ("branches" in el && Array.isArray(el.branches)) {
35400
- for (const branch of el.branches) {
35401
- collectNoteLines(branch.children);
35402
- }
35403
- }
35404
- }
35405
- }
35406
- };
35407
- collectNoteLines(elements);
35408
- const showNotesControl = allNoteLineNumbers.length > 0 && !collapseNotesDisabled && expandedNoteLines !== void 0;
35409
35797
  const hasTagGroups = parsed.tagGroups.length > 0;
35410
35798
  const collapsedGroupNames = /* @__PURE__ */ new Set();
35411
35799
  const collapsedGroupMeta = /* @__PURE__ */ new Map();
@@ -35817,7 +36205,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35817
36205
  }
35818
36206
  });
35819
36207
  const noteFill = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.bg, palette.surface, 15);
35820
- const collapsedNoteFill = mix(palette.textMuted, palette.bg, 15);
35821
36208
  const renderNoteElements = (els) => {
35822
36209
  for (const el of els) {
35823
36210
  if (isSequenceNote(el)) {
@@ -35825,83 +36212,54 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35825
36212
  if (px === void 0) continue;
35826
36213
  const noteTopY = noteYMap.get(el);
35827
36214
  if (noteTopY === void 0) continue;
35828
- const expanded = isNoteExpanded(el);
35829
36215
  const isRight = el.position === "right";
35830
- if (expanded) {
35831
- const afterSelfCall = isNoteAfterSelfCall(el);
35832
- const maxW = noteEffectiveMaxW(
35833
- el.participantId,
35834
- el.position,
35835
- afterSelfCall
35836
- );
35837
- const maxChars = charsForWidth(maxW);
35838
- const wrappedLines = wrapTextLines(el.text, maxChars);
35839
- const noteH = wrappedLines.length * NOTE_LINE_H + NOTE_PAD_V * 2;
35840
- const maxLineLen = Math.max(...wrappedLines.map((l) => l.length));
35841
- const noteW = Math.min(
35842
- maxW,
35843
- Math.max(80, maxLineLen * NOTE_CHAR_W + NOTE_PAD_H * 2 + NOTE_FOLD)
35844
- );
35845
- const rightOffset = afterSelfCall && isRight ? ACTIVATION_WIDTH / 2 + SELF_CALL_WIDTH + NOTE_GAP : ACTIVATION_WIDTH + NOTE_GAP;
35846
- const noteX = isRight ? px + rightOffset : px - ACTIVATION_WIDTH - NOTE_GAP - noteW;
35847
- const noteG = svg.append("g").attr("class", "note").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber)).attr("data-line-end", String(el.endLineNumber));
35848
- noteG.append("path").attr(
35849
- "d",
35850
- [
35851
- `M ${noteX} ${noteTopY}`,
35852
- `L ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,
35853
- `L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`,
35854
- `L ${noteX + noteW} ${noteTopY + noteH}`,
35855
- `L ${noteX} ${noteTopY + noteH}`,
35856
- "Z"
35857
- ].join(" ")
35858
- ).attr("fill", noteFill).attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-box");
35859
- noteG.append("path").attr(
35860
- "d",
35861
- [
35862
- `M ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,
35863
- `L ${noteX + noteW - NOTE_FOLD} ${noteTopY + NOTE_FOLD}`,
35864
- `L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`
35865
- ].join(" ")
35866
- ).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-fold");
35867
- wrappedLines.forEach((line11, li) => {
35868
- const textY = noteTopY + NOTE_PAD_V + (li + 1) * NOTE_LINE_H - 3;
35869
- const isBullet = line11.startsWith("- ");
35870
- const bulletIndent = isBullet ? 10 : 0;
35871
- const displayLine = isBullet ? line11.slice(2) : line11;
35872
- const textEl = noteG.append("text").attr("x", noteX + NOTE_PAD_H + bulletIndent).attr("y", textY).attr("fill", palette.text).attr("font-size", NOTE_FONT_SIZE).attr("class", "note-text");
35873
- if (isBullet) {
35874
- noteG.append("text").attr("x", noteX + NOTE_PAD_H).attr("y", textY).attr("fill", palette.text).attr("font-size", NOTE_FONT_SIZE).text("\u2022");
35875
- }
35876
- renderInlineText(textEl, displayLine, palette, NOTE_FONT_SIZE);
35877
- });
35878
- } else {
35879
- const cFold = 6;
35880
- const afterSelfCallC = isNoteAfterSelfCall(el);
35881
- const rightOffsetC = afterSelfCallC && isRight ? ACTIVATION_WIDTH / 2 + SELF_CALL_WIDTH + NOTE_GAP : ACTIVATION_WIDTH + NOTE_GAP;
35882
- const noteX = isRight ? px + rightOffsetC : px - ACTIVATION_WIDTH - NOTE_GAP - COLLAPSED_NOTE_W;
35883
- const noteG = svg.append("g").attr("class", "note note-collapsed").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber)).attr("data-line-end", String(el.endLineNumber)).style("cursor", "pointer");
35884
- noteG.append("path").attr(
35885
- "d",
35886
- [
35887
- `M ${noteX} ${noteTopY}`,
35888
- `L ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY}`,
35889
- `L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + cFold}`,
35890
- `L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + COLLAPSED_NOTE_H}`,
35891
- `L ${noteX} ${noteTopY + COLLAPSED_NOTE_H}`,
35892
- "Z"
35893
- ].join(" ")
35894
- ).attr("fill", collapsedNoteFill).attr("stroke", palette.border).attr("stroke-width", 0.75).attr("class", "note-box");
35895
- noteG.append("path").attr(
35896
- "d",
35897
- [
35898
- `M ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY}`,
35899
- `L ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY + cFold}`,
35900
- `L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + cFold}`
35901
- ].join(" ")
35902
- ).attr("fill", "none").attr("stroke", palette.border).attr("stroke-width", 0.75).attr("class", "note-fold");
35903
- noteG.append("text").attr("x", noteX + COLLAPSED_NOTE_W / 2).attr("y", noteTopY + COLLAPSED_NOTE_H / 2 + 3).attr("text-anchor", "middle").attr("fill", palette.textMuted).attr("font-size", 9).attr("class", "note-text").text("\u2026");
35904
- }
36216
+ const afterSelfCall = isNoteAfterSelfCall(el);
36217
+ const maxW = noteEffectiveMaxW(
36218
+ el.participantId,
36219
+ el.position,
36220
+ afterSelfCall
36221
+ );
36222
+ const maxChars = charsForWidth(maxW);
36223
+ const wrappedLines = wrapTextLines(el.text, maxChars);
36224
+ const noteH = wrappedLines.length * NOTE_LINE_H + NOTE_PAD_V * 2;
36225
+ const maxLineLen = Math.max(...wrappedLines.map((l) => l.length));
36226
+ const noteW = Math.min(
36227
+ maxW,
36228
+ Math.max(80, maxLineLen * NOTE_CHAR_W + NOTE_PAD_H * 2 + NOTE_FOLD)
36229
+ );
36230
+ const rightOffset = afterSelfCall && isRight ? ACTIVATION_WIDTH / 2 + SELF_CALL_WIDTH + NOTE_GAP : ACTIVATION_WIDTH + NOTE_GAP;
36231
+ const noteX = isRight ? px + rightOffset : px - ACTIVATION_WIDTH - NOTE_GAP - noteW;
36232
+ const noteG = svg.append("g").attr("class", "note").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber)).attr("data-line-end", String(el.endLineNumber));
36233
+ noteG.append("path").attr(
36234
+ "d",
36235
+ [
36236
+ `M ${noteX} ${noteTopY}`,
36237
+ `L ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,
36238
+ `L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`,
36239
+ `L ${noteX + noteW} ${noteTopY + noteH}`,
36240
+ `L ${noteX} ${noteTopY + noteH}`,
36241
+ "Z"
36242
+ ].join(" ")
36243
+ ).attr("fill", noteFill).attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-box");
36244
+ noteG.append("path").attr(
36245
+ "d",
36246
+ [
36247
+ `M ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,
36248
+ `L ${noteX + noteW - NOTE_FOLD} ${noteTopY + NOTE_FOLD}`,
36249
+ `L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`
36250
+ ].join(" ")
36251
+ ).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-fold");
36252
+ wrappedLines.forEach((line11, li) => {
36253
+ const textY = noteTopY + NOTE_PAD_V + (li + 1) * NOTE_LINE_H - 3;
36254
+ const isBullet = line11.startsWith("- ");
36255
+ const bulletIndent = isBullet ? 10 : 0;
36256
+ const displayLine = isBullet ? line11.slice(2) : line11;
36257
+ const textEl = noteG.append("text").attr("x", noteX + NOTE_PAD_H + bulletIndent).attr("y", textY).attr("fill", palette.text).attr("font-size", NOTE_FONT_SIZE).attr("class", "note-text");
36258
+ if (isBullet) {
36259
+ noteG.append("text").attr("x", noteX + NOTE_PAD_H).attr("y", textY).attr("fill", palette.text).attr("font-size", NOTE_FONT_SIZE).text("\u2022");
36260
+ }
36261
+ renderInlineText(textEl, displayLine, palette, NOTE_FONT_SIZE);
36262
+ });
35905
36263
  } else if (isSequenceBlock(el)) {
35906
36264
  renderNoteElements(el.children);
35907
36265
  if (el.elseIfBranches) {
@@ -35916,8 +36274,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35916
36274
  if (elements && elements.length > 0) {
35917
36275
  renderNoteElements(elements);
35918
36276
  }
35919
- if (hasTagGroups || showNotesControl) {
35920
- const controlsExpanded = options?.controlsExpanded ?? false;
36277
+ if (hasTagGroups) {
35921
36278
  const legendY = TOP_MARGIN + titleOffset;
35922
36279
  const resolvedGroups = parsed.tagGroups.filter((tg) => tg.entries.length > 0).map((tg) => ({
35923
36280
  name: tg.name,
@@ -35926,37 +36283,16 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
35926
36283
  color: e.color
35927
36284
  }))
35928
36285
  }));
35929
- const allExpanded = showNotesControl && (options?.expandAllNotes ?? false);
35930
- const controlsGroup = showNotesControl ? {
35931
- toggles: [
35932
- {
35933
- id: "expand-all-notes",
35934
- type: "toggle",
35935
- label: "Expand Notes",
35936
- active: allExpanded,
35937
- onToggle: () => {
35938
- }
35939
- }
35940
- ]
35941
- } : void 0;
35942
36286
  const legendConfig = {
35943
36287
  groups: resolvedGroups,
35944
36288
  position: { placement: "top-center", titleRelation: "below-title" },
35945
- mode: "fixed",
35946
- controlsGroup
36289
+ mode: "fixed"
35947
36290
  };
35948
36291
  const legendState = {
35949
36292
  activeGroup: activeTagGroup ?? null,
35950
- controlsExpanded
35951
- };
35952
- const legendCallbacks = {
35953
- onControlsExpand: () => {
35954
- options?.onToggleControlsExpand?.();
35955
- },
35956
- onControlsToggle: (_toggleId, active) => {
35957
- options?.onExpandAllNotes?.(active);
35958
- }
36293
+ controlsExpanded: false
35959
36294
  };
36295
+ const legendCallbacks = {};
35960
36296
  const legendG = svg.append("g").attr("class", "sequence-legend").attr("transform", `translate(0,${legendY})`);
35961
36297
  renderLegendD3(
35962
36298
  legendG,
@@ -35995,26 +36331,6 @@ function buildNoteMessageMap(elements) {
35995
36331
  walk(elements);
35996
36332
  return map;
35997
36333
  }
35998
- function collectNoteLineNumbers(elements) {
35999
- const result = [];
36000
- const walk = (els) => {
36001
- for (const el of els) {
36002
- if (isSequenceNote(el)) {
36003
- result.push(el.lineNumber);
36004
- } else if (isSequenceBlock(el)) {
36005
- walk(el.children);
36006
- if (el.elseIfBranches) {
36007
- for (const branch of el.elseIfBranches) {
36008
- walk(branch.children);
36009
- }
36010
- }
36011
- walk(el.elseChildren);
36012
- }
36013
- }
36014
- };
36015
- walk(elements);
36016
- return result;
36017
- }
36018
36334
  function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr) {
36019
36335
  const g = svg.append("g").attr("transform", `translate(${cx}, ${cy})`).attr("class", "participant").attr("data-participant-id", participant.id);
36020
36336
  if (tagAttr) {
@@ -36070,7 +36386,7 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
36070
36386
  });
36071
36387
  }
36072
36388
  }
36073
- var d3Selection18, PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, COLLAPSED_NOTE_H, COLLAPSED_NOTE_W, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, NOTE_LANE_MAX, LABEL_CHAR_WIDTH, LABEL_MAX_CHARS, fill, stroke, SW, W, H;
36389
+ var d3Selection18, PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, NOTE_LANE_MAX, LABEL_CHAR_WIDTH, LABEL_MAX_CHARS, fill, stroke, SW, W, H;
36074
36390
  var init_renderer16 = __esm({
36075
36391
  "src/sequence/renderer.ts"() {
36076
36392
  "use strict";
@@ -36106,8 +36422,6 @@ var init_renderer16 = __esm({
36106
36422
  NOTE_CHARS_PER_LINE = Math.floor(
36107
36423
  (NOTE_MAX_W - NOTE_PAD_H * 2 - NOTE_FOLD) / NOTE_CHAR_W
36108
36424
  );
36109
- COLLAPSED_NOTE_H = 20;
36110
- COLLAPSED_NOTE_W = 40;
36111
36425
  ACTIVATION_WIDTH = 10;
36112
36426
  SELF_CALL_HEIGHT = 25;
36113
36427
  SELF_CALL_WIDTH = 30;
@@ -37073,7 +37387,12 @@ function parseVisualization(content, palette) {
37073
37387
  );
37074
37388
  validateTagGroupNames(
37075
37389
  result.timelineTagGroups,
37076
- (line11, msg) => result.diagnostics.push(makeDgmoError(line11, msg, "warning"))
37390
+ (line11, msg) => result.diagnostics.push(makeDgmoError(line11, msg, "warning")),
37391
+ (line11, msg) => {
37392
+ const diag = makeDgmoError(line11, msg);
37393
+ result.diagnostics.push(diag);
37394
+ if (!result.error) result.error = formatDgmoError(diag);
37395
+ }
37077
37396
  );
37078
37397
  for (const group of result.timelineTagGroups) {
37079
37398
  if (!group.defaultValue) continue;
@@ -37655,8 +37974,10 @@ function renderEras(g, eras, scale, isVertical, innerWidth, innerHeight, onEnter
37655
37974
  eras.forEach((era, i) => {
37656
37975
  const startVal = parseTimelineDate(era.startDate);
37657
37976
  const endVal = parseTimelineDate(era.endDate);
37977
+ if (!Number.isFinite(startVal) || !Number.isFinite(endVal)) return;
37658
37978
  const start = scale(startVal);
37659
37979
  const end = scale(endVal);
37980
+ if (!Number.isFinite(start) || !Number.isFinite(end)) return;
37660
37981
  const color = era.color || eraColors[i % eraColors.length];
37661
37982
  const eraG = g.append("g").attr("class", "tl-era").attr("data-line-number", String(era.lineNumber)).attr("data-era-start", String(startVal)).attr("data-era-end", String(endVal)).style("cursor", "pointer").on("mouseenter", function(event) {
37662
37983
  onEnter(startVal, endVal);
@@ -37685,7 +38006,9 @@ function renderMarkers(g, markers, scale, isVertical, innerWidth, innerHeight, _
37685
38006
  const defaultColor = palette?.accent || "#d08770";
37686
38007
  markers.forEach((marker) => {
37687
38008
  const dateVal = parseTimelineDate(marker.date);
38009
+ if (!Number.isFinite(dateVal)) return;
37688
38010
  const pos = scale(dateVal);
38011
+ if (!Number.isFinite(pos)) return;
37689
38012
  const color = marker.color || defaultColor;
37690
38013
  const lineOpacity = 0.5;
37691
38014
  const diamondSize = 5;
@@ -37969,6 +38292,30 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
37969
38292
  latestEndDateStr = ev.endDate ?? ev.date;
37970
38293
  }
37971
38294
  }
38295
+ for (const era of timelineEras) {
38296
+ const eraStartNum = parseTimelineDate(era.startDate);
38297
+ const eraEndNum = parseTimelineDate(era.endDate);
38298
+ if (Number.isFinite(eraStartNum) && eraStartNum < minDate) {
38299
+ minDate = eraStartNum;
38300
+ earliestStartDateStr = era.startDate;
38301
+ }
38302
+ if (Number.isFinite(eraEndNum) && eraEndNum > maxDate) {
38303
+ maxDate = eraEndNum;
38304
+ latestEndDateStr = era.endDate;
38305
+ }
38306
+ }
38307
+ for (const marker of timelineMarkers) {
38308
+ const markerNum = parseTimelineDate(marker.date);
38309
+ if (!Number.isFinite(markerNum)) continue;
38310
+ if (markerNum < minDate) {
38311
+ minDate = markerNum;
38312
+ earliestStartDateStr = marker.date;
38313
+ }
38314
+ if (markerNum > maxDate) {
38315
+ maxDate = markerNum;
38316
+ latestEndDateStr = marker.date;
38317
+ }
38318
+ }
37972
38319
  const datePadding = (maxDate - minDate) * 0.05 || 0.5;
37973
38320
  const FADE_OPACITY2 = 0.1;
37974
38321
  function fadeToGroup(g, groupName) {
@@ -40883,6 +41230,7 @@ var require_lz_string = __commonJS({
40883
41230
  var index_exports = {};
40884
41231
  __export(index_exports, {
40885
41232
  ALL_CHART_TYPES: () => ALL_CHART_TYPES,
41233
+ AMBIGUITY_THRESHOLD: () => AMBIGUITY_THRESHOLD,
40886
41234
  ARROW_DIAGNOSTIC_CODES: () => ARROW_DIAGNOSTIC_CODES,
40887
41235
  CHART_TYPES: () => CHART_TYPES,
40888
41236
  CHART_TYPE_DESCRIPTIONS: () => CHART_TYPE_DESCRIPTIONS,
@@ -40891,6 +41239,7 @@ __export(index_exports, {
40891
41239
  INFRA_BEHAVIOR_KEYS: () => INFRA_BEHAVIOR_KEYS,
40892
41240
  LEGEND_HEIGHT: () => LEGEND_HEIGHT,
40893
41241
  METADATA_KEY_SET: () => METADATA_KEY_SET,
41242
+ MIN_PRIMARY_SCORE: () => MIN_PRIMARY_SCORE,
40894
41243
  PIPE_METADATA: () => PIPE_METADATA,
40895
41244
  RECOGNIZED_COLOR_NAMES: () => RECOGNIZED_COLOR_NAMES,
40896
41245
  RULE_COUNT: () => RULE_COUNT,
@@ -40906,13 +41255,15 @@ __export(index_exports, {
40906
41255
  buildTagLaneRowList: () => buildTagLaneRowList,
40907
41256
  calculateSchedule: () => calculateSchedule,
40908
41257
  catppuccinPalette: () => catppuccinPalette,
41258
+ chartTypeConfidence: () => confidence,
41259
+ chartTypeParsers: () => chartTypeParsers,
41260
+ chartTypes: () => chartTypes,
40909
41261
  collapseBoxesAndLines: () => collapseBoxesAndLines,
40910
41262
  collapseMindmapTree: () => collapseMindmapTree,
40911
41263
  collapseOrgTree: () => collapseOrgTree,
40912
41264
  collapseSitemapTree: () => collapseSitemapTree,
40913
41265
  collapseStateGroups: () => collapseStateGroups,
40914
41266
  collectDiagramRoles: () => collectDiagramRoles,
40915
- collectNoteLineNumbers: () => collectNoteLineNumbers,
40916
41267
  collectTasks: () => collectTasks,
40917
41268
  colorNames: () => colorNames,
40918
41269
  computeActivations: () => computeActivations,
@@ -40958,6 +41309,7 @@ __export(index_exports, {
40958
41309
  isSequenceBlock: () => isSequenceBlock,
40959
41310
  isSequenceNote: () => isSequenceNote,
40960
41311
  isValidHex: () => isValidHex,
41312
+ knownChartTypeIds: () => knownChartTypeIds,
40961
41313
  layoutBoxesAndLines: () => layoutBoxesAndLines,
40962
41314
  layoutC4Components: () => layoutC4Components,
40963
41315
  layoutC4Containers: () => layoutC4Containers,
@@ -40980,10 +41332,12 @@ __export(index_exports, {
40980
41332
  looksLikeState: () => looksLikeState,
40981
41333
  makeDgmoError: () => makeDgmoError,
40982
41334
  matchColorParens: () => matchColorParens,
41335
+ matchesContiguously: () => matchesContiguously,
40983
41336
  mix: () => mix,
40984
41337
  monokaiPalette: () => monokaiPalette,
40985
41338
  nord: () => nord,
40986
41339
  nordPalette: () => nordPalette,
41340
+ normalizeChartTypePrompt: () => normalize,
40987
41341
  oneDarkPalette: () => oneDarkPalette,
40988
41342
  orderArcNodes: () => orderArcNodes,
40989
41343
  parseAndLayoutInfra: () => parseAndLayoutInfra,
@@ -41075,9 +41429,11 @@ __export(index_exports, {
41075
41429
  resolveTaskName: () => resolveTaskName,
41076
41430
  rollUpContextRelationships: () => rollUpContextRelationships,
41077
41431
  rosePinePalette: () => rosePinePalette,
41432
+ scoreChartType: () => scoreChartType,
41078
41433
  seriesColors: () => seriesColors,
41079
41434
  shade: () => shade,
41080
41435
  solarizedPalette: () => solarizedPalette,
41436
+ suggestChartTypes: () => suggestChartTypes,
41081
41437
  tint: () => tint,
41082
41438
  tokyoNightPalette: () => tokyoNightPalette,
41083
41439
  truncateBareUrl: () => truncateBareUrl,
@@ -41148,6 +41504,83 @@ async function render(content, options) {
41148
41504
  return { svg, diagnostics };
41149
41505
  }
41150
41506
 
41507
+ // src/index.ts
41508
+ init_chart_types();
41509
+
41510
+ // src/chart-type-scoring.ts
41511
+ init_chart_types();
41512
+ var TYPOGRAPHIC_REPLACEMENTS = [
41513
+ [/[‘’]/g, "'"],
41514
+ // curly single quotes
41515
+ [/[“”]/g, '"'],
41516
+ // curly double quotes
41517
+ [/[–—]/g, "-"],
41518
+ // en/em dash
41519
+ [/×/g, "x"]
41520
+ // unicode multiplication → ASCII (for "2×2" vs "2x2")
41521
+ ];
41522
+ function normalize(s) {
41523
+ let out = s.normalize("NFKD").toLowerCase();
41524
+ for (const [re, repl] of TYPOGRAPHIC_REPLACEMENTS)
41525
+ out = out.replace(re, repl);
41526
+ return out.split(/[^a-z0-9]+/).filter(Boolean);
41527
+ }
41528
+ function matchesContiguously(promptTokens, triggerTokens) {
41529
+ if (triggerTokens.length === 0 || triggerTokens.length > promptTokens.length)
41530
+ return false;
41531
+ outer: for (let i = 0; i <= promptTokens.length - triggerTokens.length; i++) {
41532
+ for (let j = 0; j < triggerTokens.length; j++) {
41533
+ if (promptTokens[i + j] !== triggerTokens[j]) continue outer;
41534
+ }
41535
+ return true;
41536
+ }
41537
+ return false;
41538
+ }
41539
+ function scoreChartType(prompt, type) {
41540
+ const promptTokens = normalize(prompt);
41541
+ const matched = [];
41542
+ let score = 0;
41543
+ for (const trigger of type.triggers) {
41544
+ const triggerTokens = normalize(trigger);
41545
+ if (matchesContiguously(promptTokens, triggerTokens)) {
41546
+ matched.push(trigger);
41547
+ score += triggerTokens.length;
41548
+ }
41549
+ }
41550
+ const descTokens = new Set(normalize(type.description));
41551
+ let descHits = 0;
41552
+ for (const t of promptTokens) if (descTokens.has(t)) descHits++;
41553
+ score += descHits * 0.25;
41554
+ return { score, matched };
41555
+ }
41556
+ var MIN_PRIMARY_SCORE = 1;
41557
+ var AMBIGUITY_THRESHOLD = 0.5;
41558
+ function confidence(top, second) {
41559
+ if (top < MIN_PRIMARY_SCORE) return "ambiguous";
41560
+ if (second === 0) return "high";
41561
+ if (top >= second * 2) return "high";
41562
+ if (top - second < AMBIGUITY_THRESHOLD) return "ambiguous";
41563
+ return "medium";
41564
+ }
41565
+ function suggestChartTypes(prompt) {
41566
+ const scored = [];
41567
+ for (const type of chartTypes) {
41568
+ const { score, matched } = scoreChartType(prompt, type);
41569
+ if (score > 0) scored.push({ type, score, matched });
41570
+ }
41571
+ scored.sort((a, b) => b.score - a.score);
41572
+ const fallback = chartTypes.filter((c) => c.fallback);
41573
+ const topScore = scored[0]?.score ?? 0;
41574
+ const secondScore = scored[1]?.score ?? 0;
41575
+ const fellBack = topScore < MIN_PRIMARY_SCORE;
41576
+ return {
41577
+ ranked: scored,
41578
+ fallback,
41579
+ confidence: confidence(topScore, secondScore),
41580
+ fellBack
41581
+ };
41582
+ }
41583
+
41151
41584
  // src/index.ts
41152
41585
  init_dgmo_router();
41153
41586
  init_chart();
@@ -42059,10 +42492,6 @@ var COMPLETION_REGISTRY = /* @__PURE__ */ new Map([
42059
42492
  description: "Show activation bars",
42060
42493
  values: ["on", "off"]
42061
42494
  },
42062
- "collapse-notes": {
42063
- description: "Collapse note blocks",
42064
- values: ["yes", "no"]
42065
- },
42066
42495
  "active-tag": { description: "Active tag group name" }
42067
42496
  })
42068
42497
  ],
@@ -42800,6 +43229,7 @@ init_parsing();
42800
43229
  // Annotate the CommonJS export names for ESM import in node:
42801
43230
  0 && (module.exports = {
42802
43231
  ALL_CHART_TYPES,
43232
+ AMBIGUITY_THRESHOLD,
42803
43233
  ARROW_DIAGNOSTIC_CODES,
42804
43234
  CHART_TYPES,
42805
43235
  CHART_TYPE_DESCRIPTIONS,
@@ -42808,6 +43238,7 @@ init_parsing();
42808
43238
  INFRA_BEHAVIOR_KEYS,
42809
43239
  LEGEND_HEIGHT,
42810
43240
  METADATA_KEY_SET,
43241
+ MIN_PRIMARY_SCORE,
42811
43242
  PIPE_METADATA,
42812
43243
  RECOGNIZED_COLOR_NAMES,
42813
43244
  RULE_COUNT,
@@ -42823,13 +43254,15 @@ init_parsing();
42823
43254
  buildTagLaneRowList,
42824
43255
  calculateSchedule,
42825
43256
  catppuccinPalette,
43257
+ chartTypeConfidence,
43258
+ chartTypeParsers,
43259
+ chartTypes,
42826
43260
  collapseBoxesAndLines,
42827
43261
  collapseMindmapTree,
42828
43262
  collapseOrgTree,
42829
43263
  collapseSitemapTree,
42830
43264
  collapseStateGroups,
42831
43265
  collectDiagramRoles,
42832
- collectNoteLineNumbers,
42833
43266
  collectTasks,
42834
43267
  colorNames,
42835
43268
  computeActivations,
@@ -42875,6 +43308,7 @@ init_parsing();
42875
43308
  isSequenceBlock,
42876
43309
  isSequenceNote,
42877
43310
  isValidHex,
43311
+ knownChartTypeIds,
42878
43312
  layoutBoxesAndLines,
42879
43313
  layoutC4Components,
42880
43314
  layoutC4Containers,
@@ -42897,10 +43331,12 @@ init_parsing();
42897
43331
  looksLikeState,
42898
43332
  makeDgmoError,
42899
43333
  matchColorParens,
43334
+ matchesContiguously,
42900
43335
  mix,
42901
43336
  monokaiPalette,
42902
43337
  nord,
42903
43338
  nordPalette,
43339
+ normalizeChartTypePrompt,
42904
43340
  oneDarkPalette,
42905
43341
  orderArcNodes,
42906
43342
  parseAndLayoutInfra,
@@ -42992,9 +43428,11 @@ init_parsing();
42992
43428
  resolveTaskName,
42993
43429
  rollUpContextRelationships,
42994
43430
  rosePinePalette,
43431
+ scoreChartType,
42995
43432
  seriesColors,
42996
43433
  shade,
42997
43434
  solarizedPalette,
43435
+ suggestChartTypes,
42998
43436
  tint,
42999
43437
  tokyoNightPalette,
43000
43438
  truncateBareUrl,