agentic-mermaid 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/AGENT_NATIVE.md +671 -0
  2. package/CHANGELOG.md +19 -0
  3. package/Instructions_for_agents.md +89 -0
  4. package/README.md +8 -8
  5. package/assets/hero.png +0 -0
  6. package/dist/agent-core.d.ts +2 -2
  7. package/dist/agent-core.js +2 -2
  8. package/dist/agent.d.ts +2 -2
  9. package/dist/agent.js +4 -4
  10. package/dist/agentic-mermaid-mcp.js +5 -5
  11. package/dist/am.js +8 -15
  12. package/dist/{chunk-QKDLMOJJ.js → chunk-2P5FKUQC.js} +7 -9
  13. package/dist/{chunk-WN3YDOBG.js → chunk-2S3VSS6I.js} +4 -4
  14. package/dist/{chunk-CDPKJ2BQ.js → chunk-2SILJDW2.js} +2 -2
  15. package/dist/{chunk-ZYMMKQ3I.js → chunk-BJYMBT4I.js} +299 -973
  16. package/dist/{chunk-WI35L7IR.js → chunk-FDM43XU7.js} +2 -2
  17. package/dist/{chunk-4QECACIA.js → chunk-MYPDVZCO.js} +19 -19
  18. package/dist/{index-D54dqSdC.d.ts → index-DWPa2MJs.d.ts} +7 -4
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.js +1 -1
  21. package/dist/mcp-cli-5J47WEY3.js +17 -0
  22. package/docs/README.md +34 -34
  23. package/docs/agent-api-cookbook.md +317 -0
  24. package/docs/agent-mutation-policy.md +104 -0
  25. package/docs/agent-workflow-examples.md +46 -0
  26. package/docs/api.md +418 -0
  27. package/docs/ascii.md +113 -0
  28. package/docs/code-mode-impact.md +214 -0
  29. package/docs/comparison.md +106 -0
  30. package/docs/computational-aesthetics-prototype-plan.md +252 -0
  31. package/docs/config.md +121 -0
  32. package/docs/custom-fonts.md +265 -0
  33. package/docs/custom-style-cookbook.md +275 -0
  34. package/docs/diagram-families.md +218 -0
  35. package/docs/features.md +154 -0
  36. package/docs/fork-differences.md +133 -0
  37. package/docs/getting-started.md +182 -0
  38. package/docs/issue-derived-test-cases.md +163 -0
  39. package/docs/mcp-code-mode-rationale.md +108 -0
  40. package/docs/mcp-http-transport.md +230 -0
  41. package/docs/mermaid-layout-complaints.md +851 -0
  42. package/docs/mutation-testing.md +285 -0
  43. package/docs/quality.md +224 -0
  44. package/docs/react.md +97 -0
  45. package/docs/style-authoring.md +336 -0
  46. package/docs/svg-semantic-contract.md +49 -0
  47. package/docs/testing-strategy.md +443 -0
  48. package/docs/theming.md +149 -0
  49. package/package.json +21 -6
  50. package/server.json +2 -2
  51. package/skills/agentic-mermaid-live-editor/SKILL.md +1 -1
  52. package/dist/mcp-cli-SBQSTJFC.js +0 -17
@@ -1,242 +1,3 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __commonJS = (cb, mod) => function __require() {
8
- try {
9
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
- } catch (e2) {
11
- throw mod = 0, e2;
12
- }
13
- };
14
- var __copyProps = (to, from, except, desc) => {
15
- if (from && typeof from === "object" || typeof from === "function") {
16
- for (let key of __getOwnPropNames(from))
17
- if (!__hasOwnProp.call(to, key) && key !== except)
18
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
- }
20
- return to;
21
- };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
- // If the importer is in node compatibility mode or this is not an ESM
24
- // file that has been converted to a CommonJS file using a Babel-
25
- // compatible transform (i.e. "__esModule" has not been set), then set
26
- // "default" to the CommonJS "module.exports" for node compatibility.
27
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
- mod
29
- ));
30
-
31
- // package.json
32
- var require_package = __commonJS({
33
- "package.json"(exports, module) {
34
- module.exports = {
35
- name: "agentic-mermaid",
36
- mcpName: "io.github.adewale/agentic-mermaid",
37
- version: "0.1.2",
38
- license: "MIT",
39
- description: "Agentic Mermaid: render, verify, and safely edit Mermaid diagrams as ASCII, PNG, SVG, or structured agent workflows \u2014 with composable styles (hand-drawn, excalidraw, watercolor, or your own as JSON).",
40
- type: "module",
41
- main: "dist/index.js",
42
- types: "dist/index.d.ts",
43
- exports: {
44
- ".": {
45
- types: "./dist/index.d.ts",
46
- import: "./dist/index.js",
47
- default: "./dist/index.js"
48
- },
49
- "./agent": {
50
- types: "./dist/agent.d.ts",
51
- import: "./dist/agent.js",
52
- default: "./dist/agent.js"
53
- },
54
- "./agent/core": {
55
- types: "./dist/agent-core.d.ts",
56
- import: "./dist/agent-core.js",
57
- default: "./dist/agent-core.js"
58
- },
59
- "./style-spec.schema.json": "./docs/schemas/style-spec.schema.json",
60
- "./package.json": "./package.json"
61
- },
62
- bin: {
63
- am: "dist/am.js",
64
- "agentic-mermaid": "dist/am.js",
65
- "agentic-mermaid-mcp": "dist/agentic-mermaid-mcp.js"
66
- },
67
- engines: {
68
- node: ">=18"
69
- },
70
- publishConfig: {
71
- access: "public",
72
- provenance: true
73
- },
74
- repository: {
75
- type: "git",
76
- url: "git+https://github.com/adewale/agentic-mermaid.git"
77
- },
78
- homepage: "https://agentic-mermaid.dev/",
79
- bugs: {
80
- url: "https://github.com/adewale/agentic-mermaid/issues"
81
- },
82
- keywords: [
83
- "mermaid",
84
- "agentic-mermaid",
85
- "agent",
86
- "ai",
87
- "mcp",
88
- "cli",
89
- "diagram",
90
- "svg",
91
- "png",
92
- "ascii",
93
- "flowchart",
94
- "sequence-diagram",
95
- "class-diagram",
96
- "er-diagram",
97
- "timeline-diagram",
98
- "journey-diagram",
99
- "architecture-diagram",
100
- "xychart",
101
- "pie-chart",
102
- "quadrant-chart",
103
- "gantt-chart",
104
- "state-diagram",
105
- "mindmap",
106
- "git-graph",
107
- "radar-chart",
108
- "visualization",
109
- "theming",
110
- "styles",
111
- "hand-drawn",
112
- "sketch",
113
- "excalidraw",
114
- "watercolor",
115
- "llms-txt"
116
- ],
117
- author: "Adewale",
118
- files: [
119
- "dist/",
120
- "assets/fonts/",
121
- "docs/schemas/style-spec.schema.json",
122
- "examples/styles/",
123
- "skills/",
124
- "server.json",
125
- "CHANGELOG.md",
126
- "SECURITY.md",
127
- "LICENSE",
128
- "LICENSES/",
129
- "THIRD_PARTY_NOTICES.md",
130
- "README.md",
131
- "!dist/**/*.map"
132
- ],
133
- scripts: {
134
- test: "bun test --coverage --timeout 30000 src/__tests__/",
135
- typecheck: "bun run website/build.ts && tsc --noEmit",
136
- "test:browser": "bun run e2e/run-browser-contracts.ts",
137
- editor: "bun run scripts/site/editor.ts",
138
- dev: "bun run website:dev",
139
- bench: "bun run eval/benchmark/sample-bench.ts",
140
- "benchmark:palette": "bun run eval/palette-performance/run.ts --record",
141
- "benchmark:palette:check": "bun run eval/palette-performance/run.ts --check",
142
- "harvest:upstream": "bun run eval/mermaid-upstream-suite-bench/harvest.ts",
143
- "harvest:upstream:refresh-check": "bun run eval/mermaid-upstream-suite-bench/refresh-check.ts",
144
- build: "tsup",
145
- "build:binary": "bun build ./bin/am.ts --compile --outfile dist/am",
146
- website: "bun run website/build.ts",
147
- "website:check": "bun run website/build.ts --check",
148
- "website:dev": "cd website && WRANGLER_SEND_METRICS=false npx --yes wrangler@latest dev --port 9095 --ip 127.0.0.1",
149
- deploy: "bun run website && cd website && WRANGLER_SEND_METRICS=false npx --yes wrangler@latest deploy",
150
- prepublishOnly: "npm run build",
151
- "goldens:ascii": "bun run scripts/update-ascii-goldens.ts",
152
- "goldens:ascii:check": "bun run scripts/update-ascii-goldens.ts --check",
153
- hero: "bun run scripts/site/hero.ts",
154
- "hero:check": "bun run scripts/site/hero.ts --check",
155
- site: "bun run website",
156
- "site:check": "bun run website:check",
157
- "style:audit": "bun test src/__tests__/style-role-audit.test.ts",
158
- "sketch:check": "bun test scripts/sketch-prototype/styles.test.ts && bun run scripts/sketch-prototype/contrast-audit.ts",
159
- "characterization:check": "bun run scripts/characterization/contact-sheet.ts --check && bun run scripts/characterization/contact-sheet-families.ts --check && bun run scripts/characterization/visual-quality.ts --check",
160
- "agent-doc-artifacts": "bun run scripts/generate-agent-doc-artifacts.ts",
161
- "agent-doc-artifacts:check": "bun run scripts/generate-agent-doc-artifacts.ts --check",
162
- "section-a-report": "bun run scripts/generate-section-a-capability-report.ts",
163
- "section-a-report:check": "bun run scripts/generate-section-a-capability-report.ts --check",
164
- "section-b-report": "bun run scripts/generate-section-b-capability-report.ts",
165
- "section-b-report:check": "bun run scripts/generate-section-b-capability-report.ts --check",
166
- "render-options-docs": "bun run scripts/generate-render-options-docs.ts",
167
- "render-options-docs:check": "bun run scripts/generate-render-options-docs.ts --check",
168
- "style-spec-artifacts": "bun run scripts/generate-style-spec-artifacts.ts",
169
- "style-spec-artifacts:check": "bun run scripts/generate-style-spec-artifacts.ts --check",
170
- "upstream-manifest": "bun run scripts/generate-upstream-mermaid-manifest.ts",
171
- "upstream-manifest:check": "bun run scripts/generate-upstream-mermaid-manifest.ts --check",
172
- "mutation-test": "bun run scripts/quality/mutation-profile.ts",
173
- "sabotage:routes": "bun run eval/sabotage/route-regressions.ts",
174
- "test:family-elevation-reverts": "bun run scripts/quality/family-elevation-revert-probes.ts",
175
- lint: "bun test src/__tests__/agent-substrate-lint.test.ts src/__tests__/test-quality-lint.test.ts",
176
- "eval:agent-live": "bun run eval/agent-usage/live.ts",
177
- "eval:agent-subagent": "bun run eval/agent-usage/capture-subagent-prompt-eval.ts",
178
- "rubric:visual": "bun run eval/visual-rubric/run.ts",
179
- "contact:sheet": "bun run eval/visual-rubric/contact-sheet.ts",
180
- "contact:sheet:test-portfolio": "bun run scripts/pr-assets/test-portfolio-contact-sheet.ts",
181
- "contact:sheet:test-portfolio:review": "bun run scripts/ci/test-portfolio-visual-review.ts",
182
- "gallery:custom-styles": "bun run scripts/docs/custom-style-cookbook.ts",
183
- "gallery:custom-styles:check": "bun run scripts/docs/custom-style-cookbook.ts --check",
184
- "gallery:linkrank-feedback-packing": "bun run scripts/pr-assets/linkrank-feedback-packing-evidence.ts",
185
- "gallery:linkrank-feedback-packing:check": "bun run scripts/pr-assets/linkrank-feedback-packing-evidence.ts --check",
186
- "gallery:mindmap-gitgraph": "bun run scripts/pr-assets/mindmap-gitgraph-content-gallery.ts",
187
- "gallery:mindmap-gitgraph:check": "bun run scripts/pr-assets/mindmap-gitgraph-content-gallery.ts --check",
188
- "gallery:mermaid-docs": "bun run scripts/pr-assets/mermaid-doc-showcase-gallery.ts",
189
- "gallery:mermaid-docs:check": "bun run scripts/pr-assets/mermaid-doc-showcase-gallery.ts --check",
190
- "gallery:style-switch": "bun run scripts/pr-assets/style-switch-contact-sheet.ts",
191
- "gallery:style-switch:check": "bun run scripts/pr-assets/style-switch-contact-sheet.ts --check",
192
- "gallery:pie-highlight": "bun run scripts/pr-assets/pie-highlightslice-evidence.ts",
193
- "gallery:pie-highlight:check": "bun run scripts/pr-assets/pie-highlightslice-evidence.ts --check",
194
- "gallery:palette-rollout:baseline": "bun run scripts/pr-assets/palette-rollout-evidence.ts --record-baseline",
195
- "gallery:palette-rollout": "bun run scripts/pr-assets/palette-rollout-evidence.ts",
196
- "gallery:palette-rollout:check": "bun run scripts/pr-assets/palette-rollout-evidence.ts --check",
197
- "gallery:palette-harmony": "bun run scripts/pr-assets/palette-harmony-experiment.ts",
198
- "gallery:palette-harmony:check": "bun run scripts/pr-assets/palette-harmony-experiment.ts --check",
199
- "gallery:section-b": "bun run scripts/pr-assets/section-b-brand-evidence.ts",
200
- "gallery:section-b:check": "bun run scripts/pr-assets/section-b-brand-evidence.ts --check",
201
- track: "bun run eval/heuristic-tracker/run.ts",
202
- "audit:ugly": "bun run eval/ugly-detector/audit.ts",
203
- "audit:dependencies": "bun audit --audit-level=high"
204
- },
205
- dependencies: {
206
- "@resvg/resvg-js": "2.6.2",
207
- acorn: "8.16.0",
208
- elkjs: "^0.11.0",
209
- entities: "^7.0.1",
210
- yaml: "^2.8.3"
211
- },
212
- overrides: {
213
- "brace-expansion": "5.0.7",
214
- esbuild: "0.28.1",
215
- "lodash-es": "4.18.1",
216
- picomatch: "4.0.5",
217
- qs: "6.15.3"
218
- },
219
- devDependencies: {
220
- "@modelcontextprotocol/sdk": "1.29.0",
221
- "@resvg/resvg-wasm": "2.6.2",
222
- "@stryker-mutator/core": "^9.6.1",
223
- "@types/bun": "^1.3.9",
224
- "beautiful-mermaid": "1.1.3",
225
- "fast-check": "^4.6.0",
226
- mermaid: "11.16.0",
227
- "mermaid-ast": "0.8.2",
228
- playwright: "^1.58.2",
229
- "perfect-freehand": "1.2.3",
230
- roughjs: "4.6.6",
231
- shiki: "^3.19.0",
232
- tsup: "^8.5.1",
233
- typescript: "^5.9.3",
234
- "upng-js": "^2.1.0"
235
- }
236
- };
237
- }
238
- });
239
-
240
1
  // src/svg-structure.ts
241
2
  import { decodeXML } from "entities";
242
3
  function isNameChar(char) {
@@ -1356,8 +1117,10 @@ function negotiateRenderCapabilityTuple(output, tuple) {
1356
1117
  );
1357
1118
  }
1358
1119
 
1120
+ // src/version.ts
1121
+ var PACKAGE_VERSION = "0.2.0";
1122
+
1359
1123
  // src/shared/extension-identity.ts
1360
- var import_package = __toESM(require_package(), 1);
1361
1124
  function sameExtensionIdentity(left, right2) {
1362
1125
  if (left === void 0 || right2 === void 0) return false;
1363
1126
  if (left.id !== right2.id || left.kind !== right2.kind || left.version !== right2.version) return false;
@@ -1371,7 +1134,7 @@ function sameExtensionIdentity(left, right2) {
1371
1134
  return left.provenance.owner === right2.provenance.owner && left.provenance.source === right2.provenance.source && left.provenance.reference === right2.provenance.reference;
1372
1135
  }
1373
1136
  var KNOWN_EXTENSION_CONTRACT_VERSIONS = Object.freeze({
1374
- core: import_package.default.version,
1137
+ core: PACKAGE_VERSION,
1375
1138
  scene: SCENE_CONTRACT_SEMVER
1376
1139
  });
1377
1140
  function requireExtensionContractCompatibility(identity, contract) {
@@ -1705,7 +1468,7 @@ var SCENE_ROLE_DESCRIPTORS = Object.freeze(
1705
1468
  id: `role:${role}`,
1706
1469
  kind: "role",
1707
1470
  version: "1.0.0",
1708
- compatibility: { core: "^0.1.1", scene: "^2.0.0" },
1471
+ compatibility: { core: "^0.2.0", scene: "^2.0.0" },
1709
1472
  provenance: { owner: "agentic-mermaid", source: "built-in", reference: "src/scene/roles.ts" }
1710
1473
  }),
1711
1474
  role,
@@ -2581,6 +2344,116 @@ function labelOverflowWarning(target, text3, cap) {
2581
2344
  return charCount > cap ? { code: "LABEL_OVERFLOW", target, charCount, limit: cap } : null;
2582
2345
  }
2583
2346
 
2347
+ // src/agent/body-utils.ts
2348
+ function indexedIdAllocator(existing, prefix) {
2349
+ const seen = new Set(existing);
2350
+ let index = 0;
2351
+ return () => {
2352
+ while (seen.has(`${prefix}-${index}`)) index++;
2353
+ const id = `${prefix}-${index}`;
2354
+ seen.add(id);
2355
+ index++;
2356
+ return id;
2357
+ };
2358
+ }
2359
+ function labelOverflowCollector(warnings, opts, cap = opts.labelCharCap ?? DEFAULT_LABEL_CHAR_CAP) {
2360
+ return (target, text3) => {
2361
+ const warning = labelOverflowWarning(target, text3, cap);
2362
+ if (warning) warnings.push(warning);
2363
+ };
2364
+ }
2365
+
2366
+ // src/shared/accessibility-directives.ts
2367
+ var ACC_TITLE_RE = /^\s*accTitle(?:\s*:\s*|\s+)(.+)$/i;
2368
+ var ACC_DESCR_INLINE_RE = /^\s*accDescr(?:\s*:\s*|\s+)(.+)$/i;
2369
+ var ACC_DESCR_BLOCK_RE = /^\s*accDescr\s*:?\s*\{(.*)$/i;
2370
+ function parseAccessibilityDirective(lines, startIndex) {
2371
+ const line2 = lines[startIndex];
2372
+ if (line2 === void 0) return null;
2373
+ const block = line2.match(ACC_DESCR_BLOCK_RE);
2374
+ if (block) {
2375
+ const parts = [];
2376
+ for (let index = startIndex; index < lines.length; index++) {
2377
+ const content = index === startIndex ? block[1] : lines[index];
2378
+ const closing = content.indexOf("}");
2379
+ if (closing < 0) {
2380
+ if (content.trim()) parts.push(content.trim());
2381
+ continue;
2382
+ }
2383
+ const beforeClosing = content.slice(0, closing).trim();
2384
+ if (beforeClosing) parts.push(beforeClosing);
2385
+ const suffix = content.slice(closing + 1);
2386
+ const indent = lines[index].match(/^\s*/)?.[0] ?? "";
2387
+ return {
2388
+ title: false,
2389
+ form: "block",
2390
+ value: parts.join("\n").trim(),
2391
+ endIndex: index,
2392
+ ...suffix.trim() ? { suffixLine: indent + suffix.trimStart() } : {}
2393
+ };
2394
+ }
2395
+ return void 0;
2396
+ }
2397
+ const title = line2.match(ACC_TITLE_RE);
2398
+ if (title) return { title: true, form: "inline", value: title[1].trim(), endIndex: startIndex };
2399
+ const description = line2.match(ACC_DESCR_INLINE_RE);
2400
+ if (description) return { title: false, form: "inline", value: description[1].trim(), endIndex: startIndex };
2401
+ return null;
2402
+ }
2403
+ function scanAccessibilityDirectives(lines) {
2404
+ const accessibility = {};
2405
+ const familyLines = [];
2406
+ let unclosedIndex;
2407
+ for (let index = 0; index < lines.length; index++) {
2408
+ const directive = parseAccessibilityDirective(lines, index);
2409
+ if (directive === void 0) {
2410
+ unclosedIndex = index;
2411
+ familyLines.push(...lines.slice(index));
2412
+ break;
2413
+ }
2414
+ if (directive === null) {
2415
+ familyLines.push(lines[index]);
2416
+ continue;
2417
+ }
2418
+ if (directive.title) accessibility.title = directive.value;
2419
+ else accessibility.descr = directive.value;
2420
+ if (directive.suffixLine) familyLines.push(directive.suffixLine);
2421
+ index = directive.endIndex;
2422
+ }
2423
+ return {
2424
+ accessibility,
2425
+ familyLines,
2426
+ ...unclosedIndex !== void 0 ? { unclosedIndex } : {}
2427
+ };
2428
+ }
2429
+ function requireClosedAccessibility(scan) {
2430
+ if (scan.unclosedIndex !== void 0) throw new Error("Unclosed accDescr block");
2431
+ }
2432
+ function accessibilityFields(accessibility) {
2433
+ return {
2434
+ ...accessibility.title !== void 0 ? { accessibilityTitle: accessibility.title } : {},
2435
+ ...accessibility.descr !== void 0 ? { accessibilityDescription: accessibility.descr } : {}
2436
+ };
2437
+ }
2438
+ function withAccessibilityFields(value, accessibility) {
2439
+ if (accessibility.title === void 0 && accessibility.descr === void 0) {
2440
+ return value;
2441
+ }
2442
+ return { ...value, ...accessibilityFields(accessibility) };
2443
+ }
2444
+ function withAccessibilityObject(value, accessibility) {
2445
+ if (accessibility.title === void 0 && accessibility.descr === void 0) {
2446
+ return value;
2447
+ }
2448
+ return {
2449
+ ...value,
2450
+ accessibility: {
2451
+ ...accessibility.title !== void 0 ? { title: accessibility.title } : {},
2452
+ ...accessibility.descr !== void 0 ? { description: accessibility.descr } : {}
2453
+ }
2454
+ };
2455
+ }
2456
+
2584
2457
  // src/shared/direction-statement.ts
2585
2458
  var DIRECTION_RE = /^direction\s+(TB|TD|BT|LR|RL)\s*$/i;
2586
2459
  function parseDirectionStatement(line2) {
@@ -2680,13 +2553,17 @@ function parseClassInteraction(line2) {
2680
2553
  return ref && /^(?:https?:|mailto:)/i.test(href) ? { ...ref, href } : null;
2681
2554
  }
2682
2555
  function parseClassDiagram(lines) {
2683
- lines = lines.flatMap(expandInlineNamespaceStatement);
2556
+ const accessibility = scanAccessibilityDirectives(lines);
2557
+ requireClosedAccessibility(accessibility);
2558
+ lines = accessibility.familyLines.flatMap(expandInlineNamespaceStatement);
2684
2559
  const diagram = {
2685
2560
  classes: [],
2686
2561
  classDefs: /* @__PURE__ */ new Map(),
2687
2562
  relationships: [],
2688
2563
  notes: [],
2689
- namespaces: []
2564
+ namespaces: [],
2565
+ ...accessibility.accessibility.title !== void 0 ? { accessibilityTitle: normalizeBrTags(accessibility.accessibility.title) } : {},
2566
+ ...accessibility.accessibility.descr !== void 0 ? { accessibilityDescription: normalizeBrTags(accessibility.accessibility.descr) } : {}
2690
2567
  };
2691
2568
  const classMap = /* @__PURE__ */ new Map();
2692
2569
  const namespaceByPath = /* @__PURE__ */ new Map();
@@ -2723,23 +2600,6 @@ function parseClassDiagram(lines) {
2723
2600
  const namespaceFrameSizes = [];
2724
2601
  for (let i2 = 1; i2 < lines.length; i2++) {
2725
2602
  const line2 = lines[i2];
2726
- const accTitle = parseAccessibilityLine(line2, "accTitle");
2727
- if (accTitle !== void 0) {
2728
- diagram.accessibilityTitle = accTitle;
2729
- continue;
2730
- }
2731
- const accDescrStart = line2.match(/^accDescr\s*:?\s*\{\s*(.*)$/i);
2732
- if (accDescrStart) {
2733
- const parsed = collectAccessibilityBlock(accDescrStart[1] ?? "", lines, i2);
2734
- diagram.accessibilityDescription = normalizeBrTags(parsed.text);
2735
- i2 = parsed.nextIndex;
2736
- continue;
2737
- }
2738
- const accDescr = parseAccessibilityLine(line2, "accDescr");
2739
- if (accDescr !== void 0) {
2740
- diagram.accessibilityDescription = accDescr;
2741
- continue;
2742
- }
2743
2603
  if (currentClass && braceDepth > 0) {
2744
2604
  if (line2 === "}") {
2745
2605
  braceDepth--;
@@ -2883,26 +2743,6 @@ function parseClassDiagram(lines) {
2883
2743
  diagram.classes = [...classMap.values()];
2884
2744
  return diagram;
2885
2745
  }
2886
- function parseAccessibilityLine(line2, directive) {
2887
- const match = line2.match(new RegExp(`^${directive}\\s*:?[ \\t]+(.+)$`, "i"));
2888
- return match ? normalizeBrTags(match[1].trim()) : void 0;
2889
- }
2890
- function collectAccessibilityBlock(initial, lines, startIndex) {
2891
- const initialEnd = initial.indexOf("}");
2892
- if (initialEnd !== -1) return { text: initial.slice(0, initialEnd).trim(), nextIndex: startIndex };
2893
- const parts = [initial.trim()].filter(Boolean);
2894
- for (let i2 = startIndex + 1; i2 < lines.length; i2++) {
2895
- const line2 = lines[i2];
2896
- const end = line2.indexOf("}");
2897
- if (end !== -1) {
2898
- const beforeBrace = line2.slice(0, end).trim();
2899
- if (beforeBrace) parts.push(beforeBrace);
2900
- return { text: parts.join("\n"), nextIndex: i2 };
2901
- }
2902
- parts.push(line2);
2903
- }
2904
- throw new Error('Class accDescr block is missing a closing "}"');
2905
- }
2906
2746
  function ensureClass(classMap, id, generic) {
2907
2747
  let cls = classMap.get(id);
2908
2748
  if (!cls) {
@@ -3536,15 +3376,11 @@ function mutateClass(body, op) {
3536
3376
  }
3537
3377
  function verifyClass(body, opts) {
3538
3378
  const warnings = [];
3539
- const cap = opts.labelCharCap ?? DEFAULT_LABEL_CHAR_CAP;
3540
3379
  if (body.classes.length === 0 && body.title === void 0) {
3541
3380
  warnings.push({ code: "EMPTY_DIAGRAM" });
3542
3381
  return warnings;
3543
3382
  }
3544
- const overflow = (target, text3) => {
3545
- const w2 = labelOverflowWarning(target, text3, cap);
3546
- if (w2) warnings.push(w2);
3547
- };
3383
+ const overflow = labelOverflowCollector(warnings, opts);
3548
3384
  if (body.title) overflow("title", body.title);
3549
3385
  const ids = new Set(body.classes.map((c2) => c2.id));
3550
3386
  for (const c2 of body.classes) {
@@ -3613,11 +3449,16 @@ function parseErGroupHeader(line2) {
3613
3449
  return { id, label: formatErMarkdown(explicit[2]?.trim() || id) };
3614
3450
  }
3615
3451
  function parseErDiagram(lines) {
3452
+ const accessibility = scanAccessibilityDirectives(lines);
3453
+ requireClosedAccessibility(accessibility);
3454
+ lines = accessibility.familyLines;
3616
3455
  const diagram = {
3617
3456
  entities: [],
3618
3457
  classDefs: /* @__PURE__ */ new Map(),
3619
3458
  relationships: [],
3620
- groups: []
3459
+ groups: [],
3460
+ ...accessibility.accessibility.title !== void 0 ? { accessibilityTitle: normalizeBrTags(accessibility.accessibility.title) } : {},
3461
+ ...accessibility.accessibility.descr !== void 0 ? { accessibilityDescription: normalizeBrTags(accessibility.accessibility.descr) } : {}
3621
3462
  };
3622
3463
  const entityMap = /* @__PURE__ */ new Map();
3623
3464
  let currentEntity = null;
@@ -3626,23 +3467,6 @@ function parseErDiagram(lines) {
3626
3467
  const currentGroup = () => groupStack.at(-1);
3627
3468
  for (let i2 = 1; i2 < lines.length; i2++) {
3628
3469
  const line2 = lines[i2];
3629
- const accTitle = parseAccessibilityLine2(line2, "accTitle");
3630
- if (accTitle !== void 0) {
3631
- diagram.accessibilityTitle = accTitle;
3632
- continue;
3633
- }
3634
- const accDescrStart = line2.match(/^accDescr\s*:?\s*\{\s*(.*)$/i);
3635
- if (accDescrStart) {
3636
- const parsed = collectAccessibilityBlock2(accDescrStart[1] ?? "", lines, i2);
3637
- diagram.accessibilityDescription = normalizeBrTags(parsed.text);
3638
- i2 = parsed.nextIndex;
3639
- continue;
3640
- }
3641
- const accDescr = parseAccessibilityLine2(line2, "accDescr");
3642
- if (accDescr !== void 0) {
3643
- diagram.accessibilityDescription = accDescr;
3644
- continue;
3645
- }
3646
3470
  if (currentEntity) {
3647
3471
  if (line2 === "}") {
3648
3472
  currentEntity = null;
@@ -3721,26 +3545,6 @@ function parseErDiagram(lines) {
3721
3545
  diagram.entities = [...entityMap.values()];
3722
3546
  return diagram;
3723
3547
  }
3724
- function parseAccessibilityLine2(line2, directive) {
3725
- const match = line2.match(new RegExp(`^${directive}\\s*:?[ \\t]+(.+)$`, "i"));
3726
- return match ? normalizeBrTags(match[1].trim()) : void 0;
3727
- }
3728
- function collectAccessibilityBlock2(initial, lines, startIndex) {
3729
- const initialEnd = initial.indexOf("}");
3730
- if (initialEnd !== -1) return { text: initial.slice(0, initialEnd).trim(), nextIndex: startIndex };
3731
- const parts = [initial.trim()].filter(Boolean);
3732
- for (let i2 = startIndex + 1; i2 < lines.length; i2++) {
3733
- const line2 = lines[i2];
3734
- const end = line2.indexOf("}");
3735
- if (end !== -1) {
3736
- const beforeBrace = line2.slice(0, end).trim();
3737
- if (beforeBrace) parts.push(beforeBrace);
3738
- return { text: parts.join("\n"), nextIndex: i2 };
3739
- }
3740
- parts.push(line2);
3741
- }
3742
- throw new Error('ER accDescr block is missing a closing "}"');
3743
- }
3744
3548
  function ensureEntity(entityMap, id, label, className, groupId) {
3745
3549
  let entity = entityMap.get(id);
3746
3550
  if (!entity) {
@@ -4274,16 +4078,12 @@ function mutateEr(body, op) {
4274
4078
  }
4275
4079
  function verifyErBody(body, opts) {
4276
4080
  const warnings = [];
4277
- const cap = opts.labelCharCap ?? DEFAULT_LABEL_CHAR_CAP;
4278
4081
  if (body.entities.length === 0 && body.relations.length === 0 && (body.groups?.length ?? 0) === 0) {
4279
4082
  warnings.push({ code: "EMPTY_DIAGRAM" });
4280
4083
  return warnings;
4281
4084
  }
4282
4085
  const ids = /* @__PURE__ */ new Set([...body.entities.map((e2) => e2.id), ...(body.groups ?? []).map((group2) => group2.id)]);
4283
- const overflow = (target, text3) => {
4284
- const w2 = labelOverflowWarning(target, text3, cap);
4285
- if (w2) warnings.push(w2);
4286
- };
4086
+ const overflow = labelOverflowCollector(warnings, opts);
4287
4087
  for (const group2 of body.groups ?? []) overflow(group2.id, group2.label);
4288
4088
  for (const e2 of body.entities) {
4289
4089
  if (e2.label) overflow(e2.id, e2.label);
@@ -4343,13 +4143,17 @@ function parseSequenceMessageLine(line2) {
4343
4143
  };
4344
4144
  }
4345
4145
  function parseSequenceDiagram(lines, opts = {}) {
4146
+ const accessibility = scanAccessibilityDirectives(lines);
4147
+ lines = accessibility.familyLines;
4346
4148
  const diagram = {
4347
4149
  actors: [],
4348
4150
  messages: [],
4349
4151
  blocks: [],
4350
4152
  notes: [],
4351
4153
  activationEvents: [],
4352
- boxes: []
4154
+ boxes: [],
4155
+ ...accessibility.accessibility.title !== void 0 ? { accessibilityTitle: normalizeBrTags(accessibility.accessibility.title) } : {},
4156
+ ...accessibility.accessibility.descr !== void 0 ? { accessibilityDescription: normalizeBrTags(accessibility.accessibility.descr) } : {}
4353
4157
  };
4354
4158
  const actorIds = /* @__PURE__ */ new Set();
4355
4159
  const blockStack = [];
@@ -4387,25 +4191,6 @@ function parseSequenceDiagram(lines, opts = {}) {
4387
4191
  };
4388
4192
  for (let i2 = 1; i2 < lines.length; i2++) {
4389
4193
  const line2 = lines[i2];
4390
- const accTitle = parseAccessibilityLine3(line2, "accTitle");
4391
- if (accTitle !== void 0) {
4392
- diagram.accessibilityTitle = accTitle;
4393
- continue;
4394
- }
4395
- const accDescrStart = line2.match(/^accDescr\s*:?\s*\{\s*(.*)$/i);
4396
- if (accDescrStart) {
4397
- const parsed = collectAccessibilityBlock3(accDescrStart[1] ?? "", lines, i2);
4398
- if (parsed) {
4399
- diagram.accessibilityDescription = normalizeBrTags(parsed.text);
4400
- i2 = parsed.nextIndex;
4401
- }
4402
- continue;
4403
- }
4404
- const accDescr = parseAccessibilityLine3(line2, "accDescr");
4405
- if (accDescr !== void 0) {
4406
- diagram.accessibilityDescription = accDescr;
4407
- continue;
4408
- }
4409
4194
  const actorDeclaration = parseActorDeclaration(line2);
4410
4195
  if (actorDeclaration) {
4411
4196
  const { id, label, type } = actorDeclaration;
@@ -4615,26 +4400,6 @@ function parseMessageArrow(arrow) {
4615
4400
  }
4616
4401
  return { lineStyle, startHead: "none", endHead: "open" };
4617
4402
  }
4618
- function parseAccessibilityLine3(line2, directive) {
4619
- const match = line2.match(new RegExp(`^${directive}\\s*:?[ \\t]+(.+)$`, "i"));
4620
- return match ? normalizeBrTags(match[1].trim()) : void 0;
4621
- }
4622
- function collectAccessibilityBlock3(initial, lines, startIndex) {
4623
- const initialEnd = initial.indexOf("}");
4624
- if (initialEnd !== -1) return { text: initial.slice(0, initialEnd).trim(), nextIndex: startIndex };
4625
- const parts = [initial.trim()].filter(Boolean);
4626
- for (let i2 = startIndex + 1; i2 < lines.length; i2++) {
4627
- const line2 = lines[i2];
4628
- const end = line2.indexOf("}");
4629
- if (end !== -1) {
4630
- const beforeBrace = line2.slice(0, end).trim();
4631
- if (beforeBrace) parts.push(beforeBrace);
4632
- return { text: parts.join("\n"), nextIndex: i2 };
4633
- }
4634
- parts.push(line2);
4635
- }
4636
- return null;
4637
- }
4638
4403
  function ensureActor(diagram, actorIds, id) {
4639
4404
  if (!actorIds.has(id)) {
4640
4405
  actorIds.add(id);
@@ -5195,9 +4960,6 @@ function syntaxError(detail) {
5195
4960
  var TIMELINE_HEADER_DIRECTION_RE = /^timeline\s+(LR|TD)\s*$/i;
5196
4961
  var TIMELINE_TITLE_RE = /^title\s+(.+)$/i;
5197
4962
  var TIMELINE_SECTION_RE = /^section\s+([^:]+)$/i;
5198
- var TIMELINE_ACCESSIBILITY_TITLE_RE = /^accTitle\s*:\s*(.+)$/i;
5199
- var TIMELINE_ACCESSIBILITY_DESCRIPTION_RE = /^accDescr\s*:\s*(.+)$/i;
5200
- var TIMELINE_ACCESSIBILITY_DESCRIPTION_BLOCK_RE = /^accDescr\s*\{\s*$/i;
5201
4963
  var TIMELINE_CONTINUATION_RE = /^:\s+(.+)$/;
5202
4964
  var TIMELINE_PERIOD_RE = /^([^:#\n]+?)(\s*:\s+.+)$/;
5203
4965
  function splitTimelineEvents(raw) {
@@ -5243,11 +5005,16 @@ function parseTimelineEventSegments(raw) {
5243
5005
  }
5244
5006
  }
5245
5007
  function parseTimelineBody(lines, accessibility = {}) {
5008
+ const scanned = scanAccessibilityDirectives(lines);
5009
+ if (scanned.unclosedIndex !== void 0) return null;
5010
+ lines = scanned.familyLines;
5011
+ const accessibilityTitle = scanned.accessibility.title ?? accessibility.title;
5012
+ const accessibilityDescription = scanned.accessibility.descr ?? accessibility.descr;
5246
5013
  const body = {
5247
5014
  kind: "timeline",
5248
5015
  sections: [],
5249
- ...accessibility.title !== void 0 ? { accessibilityTitle: accessibility.title } : {},
5250
- ...accessibility.descr !== void 0 ? { accessibilityDescription: accessibility.descr } : {}
5016
+ ...accessibilityTitle !== void 0 ? { accessibilityTitle } : {},
5017
+ ...accessibilityDescription !== void 0 ? { accessibilityDescription } : {}
5251
5018
  };
5252
5019
  let currentSection;
5253
5020
  let currentPeriod;
@@ -5270,31 +5037,6 @@ function parseTimelineBody(lines, accessibility = {}) {
5270
5037
  body.title = title;
5271
5038
  continue;
5272
5039
  }
5273
- const at = line2.match(TIMELINE_ACCESSIBILITY_TITLE_RE);
5274
- if (at) {
5275
- body.accessibilityTitle = normalizeTimelineText(at[1]);
5276
- continue;
5277
- }
5278
- const ad = line2.match(TIMELINE_ACCESSIBILITY_DESCRIPTION_RE);
5279
- if (ad) {
5280
- body.accessibilityDescription = normalizeTimelineText(ad[1]);
5281
- continue;
5282
- }
5283
- if (TIMELINE_ACCESSIBILITY_DESCRIPTION_BLOCK_RE.test(line2)) {
5284
- const descriptionLines = [];
5285
- let closed = false;
5286
- while (++i2 < lines.length) {
5287
- const blockLine = lines[i2].trim();
5288
- if (blockLine === "}") {
5289
- closed = true;
5290
- break;
5291
- }
5292
- descriptionLines.push(blockLine);
5293
- }
5294
- if (!closed) return null;
5295
- body.accessibilityDescription = descriptionLines.join("\n").trim();
5296
- continue;
5297
- }
5298
5040
  const sm = line2.match(TIMELINE_SECTION_RE);
5299
5041
  if (sm) {
5300
5042
  const label = normalizeTimelineText(sm[1]);
@@ -5384,21 +5126,16 @@ function cloneTimeline(b2) {
5384
5126
  };
5385
5127
  }
5386
5128
  function makeTimelineIdAllocator(body) {
5387
- const seen = /* @__PURE__ */ new Set();
5388
- for (const s2 of body.sections) {
5389
- seen.add(s2.id);
5390
- for (const p2 of s2.periods) {
5391
- seen.add(p2.id);
5392
- for (const e2 of p2.events) seen.add(e2.id);
5393
- }
5394
- }
5395
- return (prefix) => {
5396
- let n2 = 0;
5397
- while (seen.has(`${prefix}-${n2}`)) n2++;
5398
- const id = `${prefix}-${n2}`;
5399
- seen.add(id);
5400
- return id;
5129
+ const ids = body.sections.flatMap((section2) => [
5130
+ section2.id,
5131
+ ...section2.periods.flatMap((period) => [period.id, ...period.events.map((event) => event.id)])
5132
+ ]);
5133
+ const allocators = {
5134
+ section: indexedIdAllocator(ids, "section"),
5135
+ period: indexedIdAllocator(ids, "period"),
5136
+ event: indexedIdAllocator(ids, "event")
5401
5137
  };
5138
+ return (prefix) => allocators[prefix]();
5402
5139
  }
5403
5140
  function normalizeTimelineOpText(value, opts) {
5404
5141
  if (typeof value !== "string") return err({ code: "INVALID_OP", message: `Timeline ${opts.field} must be a string` });
@@ -5600,8 +5337,6 @@ var JOURNEY_TITLE_RE = /^title\s+(.+)$/i;
5600
5337
  var JOURNEY_SECTION_RE = /^section\s+(.+)$/i;
5601
5338
  var JOURNEY_TASK_RE = /^([^:]+?)\s*:\s*([0-9]+)\s*(?::\s*(.*))?$/;
5602
5339
  var TASK_LIKE_RE = /^([^:]+?)\s*:\s*([^:]+?)(?:\s*:\s*.*)?$/;
5603
- var ACC_LINE_RE = (directive) => new RegExp(`^${directive}\\s*:[ \\t]*(.+)$`, "i");
5604
- var ACC_DESCR_BLOCK_START_RE = /^accDescr\s*:?\s*\{\s*(.*)$/i;
5605
5340
  function normalizeJourneyLabel(label) {
5606
5341
  return label.replace(/<br\s*\/?>/gi, "\n").replace(/\\n/g, "\n").replace(/<\/?(?:sub|sup|small|mark)\s*>/gi, "").replace(/\*\*(.+?)\*\*/g, "<b>$1</b>").replace(/(?<!\*)\*([^\s*](?:[^*]*[^\s*])?)\*(?!\*)/g, "<i>$1</i>").replace(/~~(.+?)~~/g, "<s>$1</s>");
5607
5342
  }
@@ -5622,23 +5357,22 @@ function walkJourneyLines(lines, startIndex, events) {
5622
5357
  const line2 = lines[i2].trim();
5623
5358
  if (!line2) continue;
5624
5359
  if (isJourneyComment(line2)) continue;
5625
- const accDescrStart = line2.match(ACC_DESCR_BLOCK_START_RE);
5626
- if (accDescrStart) {
5627
- const collected = collectJourneyAccessibilityBlock(accDescrStart[1] ?? "", lines, i2);
5628
- if (!collected) {
5629
- const outcome2 = events.issue?.({
5630
- code: "unclosed_accdescr",
5631
- lineIndex: i2,
5632
- statement: line2,
5633
- detail: 'Journey accDescr block is missing a closing "}"'
5634
- });
5635
- if (outcome2 === "stop") return;
5636
- return;
5637
- }
5638
- events.accDescr?.(normalizeJourneyText(collected.text), i2);
5639
- i2 = collected.nextIndex;
5640
- for (const statement of splitJourneyStatements(collected.suffix)) {
5641
- const outcome2 = classifyStatement(statement, collected.nextIndex, events);
5360
+ const accessibility = parseAccessibilityDirective(lines, i2);
5361
+ if (accessibility === void 0) {
5362
+ const outcome2 = events.issue?.({
5363
+ code: "unclosed_accdescr",
5364
+ lineIndex: i2,
5365
+ statement: line2,
5366
+ detail: 'Journey accDescr block is missing a closing "}"'
5367
+ });
5368
+ if (outcome2 === "stop") return;
5369
+ return;
5370
+ }
5371
+ if (accessibility?.form === "block") {
5372
+ events.accDescr?.(normalizeJourneyText(accessibility.value), i2);
5373
+ i2 = accessibility.endIndex;
5374
+ for (const statement of splitJourneyStatements(accessibility.suffixLine ?? "")) {
5375
+ const outcome2 = classifyStatement(statement, accessibility.endIndex, events);
5642
5376
  if (outcome2 === "stop") return;
5643
5377
  }
5644
5378
  continue;
@@ -5651,14 +5385,11 @@ function walkJourneyLines(lines, startIndex, events) {
5651
5385
  }
5652
5386
  function classifyStatement(statement, lineIndex, events) {
5653
5387
  const issue = (code, detail) => events.issue?.({ code, lineIndex, statement, detail });
5654
- const accTitle = matchAccessibilityLine(statement, "accTitle");
5655
- if (accTitle !== void 0) {
5656
- events.accTitle?.(accTitle, lineIndex);
5657
- return;
5658
- }
5659
- const accDescr = matchAccessibilityLine(statement, "accDescr");
5660
- if (accDescr !== void 0) {
5661
- events.accDescr?.(accDescr, lineIndex);
5388
+ const accessibility = parseAccessibilityDirective([statement], 0);
5389
+ if (accessibility) {
5390
+ const text3 = normalizeJourneyText(accessibility.value);
5391
+ if (accessibility.title) events.accTitle?.(text3, lineIndex);
5392
+ else events.accDescr?.(text3, lineIndex);
5662
5393
  return;
5663
5394
  }
5664
5395
  const titleMatch = statement.match(JOURNEY_TITLE_RE);
@@ -5727,36 +5458,6 @@ function splitJourneyStatements(line2) {
5727
5458
  parts.push(line2.slice(start));
5728
5459
  return parts.map((part) => part.trim()).filter((part) => part && !isJourneyComment(part));
5729
5460
  }
5730
- function matchAccessibilityLine(line2, directive) {
5731
- const match = line2.match(ACC_LINE_RE(directive));
5732
- return match ? normalizeJourneyText(match[1]) : void 0;
5733
- }
5734
- function collectJourneyAccessibilityBlock(initial, lines, startIndex) {
5735
- const initialEnd = initial.indexOf("}");
5736
- if (initialEnd !== -1) {
5737
- return {
5738
- text: initial.slice(0, initialEnd).trim(),
5739
- nextIndex: startIndex,
5740
- suffix: initial.slice(initialEnd + 1).trim()
5741
- };
5742
- }
5743
- const parts = [initial.trim()].filter(Boolean);
5744
- for (let i2 = startIndex + 1; i2 < lines.length; i2++) {
5745
- const line2 = lines[i2];
5746
- const end = line2.indexOf("}");
5747
- if (end !== -1) {
5748
- const beforeBrace = line2.slice(0, end).trim();
5749
- if (beforeBrace) parts.push(beforeBrace);
5750
- return {
5751
- text: parts.join("\n"),
5752
- nextIndex: i2,
5753
- suffix: line2.slice(end + 1).trim()
5754
- };
5755
- }
5756
- parts.push(line2);
5757
- }
5758
- return null;
5759
- }
5760
5461
 
5761
5462
  // src/agent/journey-body.ts
5762
5463
  function formatJourneyInline(value) {
@@ -5848,18 +5549,10 @@ function cloneJourney(b2) {
5848
5549
  };
5849
5550
  }
5850
5551
  function makeIdAllocator(body) {
5851
- const seen = /* @__PURE__ */ new Set();
5852
- for (const s2 of body.sections) {
5853
- seen.add(s2.id);
5854
- for (const t2 of s2.tasks) seen.add(t2.id);
5855
- }
5856
- return (prefix) => {
5857
- let n2 = 0;
5858
- while (seen.has(`${prefix}-${n2}`)) n2++;
5859
- const id = `${prefix}-${n2}`;
5860
- seen.add(id);
5861
- return id;
5862
- };
5552
+ const ids = body.sections.flatMap((section3) => [section3.id, ...section3.tasks.map((task2) => task2.id)]);
5553
+ const section2 = indexedIdAllocator(ids, "section");
5554
+ const task = indexedIdAllocator(ids, "task");
5555
+ return (prefix) => prefix === "section" ? section2() : task();
5863
5556
  }
5864
5557
  function normalizeOpText(value, field, opts = {}) {
5865
5558
  if (typeof value !== "string") return err({ code: "INVALID_OP", message: `Journey ${field} must be a string` });
@@ -6070,16 +5763,12 @@ function journeySemantics(body) {
6070
5763
  function verifyJourney(body, opts) {
6071
5764
  const cap = opts.labelCharCap ?? DEFAULT_LABEL_CHAR_CAP;
6072
5765
  const warnings = [];
6073
- const overflow = (target, text3) => {
6074
- const w2 = labelOverflowWarning(target, text3, cap);
6075
- if (w2) warnings.push(w2);
6076
- };
5766
+ const overflow = labelOverflowCollector(warnings, opts, cap);
6077
5767
  const hasTask = body.sections.some((s2) => s2.tasks.length > 0);
6078
5768
  const hasHeaderFurniture = body.title !== void 0 || body.accessibilityTitle !== void 0 || body.accessibilityDescription !== void 0 || body.sections.length > 0;
6079
5769
  if (!hasTask && !hasHeaderFurniture) warnings.push({ code: "EMPTY_DIAGRAM" });
6080
5770
  if (body.title !== void 0) {
6081
- const w2 = labelOverflowWarning("title", body.title, Math.max(cap, 80));
6082
- if (w2) warnings.push(w2);
5771
+ labelOverflowCollector(warnings, opts, Math.max(cap, 80))("title", body.title);
6083
5772
  }
6084
5773
  const actors = new Set(body.sections.flatMap((section2) => section2.tasks.flatMap((task) => task.actors)));
6085
5774
  if (actors.size > JOURNEY_ACTOR_COLOR_LIMIT) {
@@ -6260,9 +5949,12 @@ function parseEdge(line2) {
6260
5949
  };
6261
5950
  }
6262
5951
  function parseArchitectureBody(lines, accessibility = {}) {
5952
+ const scanned = scanAccessibilityDirectives(lines);
5953
+ if (scanned.unclosedIndex !== void 0) return null;
5954
+ lines = scanned.familyLines;
6263
5955
  let title;
6264
- let accessibilityTitle = accessibility.title;
6265
- let accessibilityDescription = accessibility.descr;
5956
+ const accessibilityTitle = scanned.accessibility.title ?? accessibility.title;
5957
+ const accessibilityDescription = scanned.accessibility.descr ?? accessibility.descr;
6266
5958
  const groups = [];
6267
5959
  const services = [];
6268
5960
  const junctions = [];
@@ -6283,43 +5975,6 @@ function parseArchitectureBody(lines, accessibility = {}) {
6283
5975
  if (!title) return null;
6284
5976
  continue;
6285
5977
  }
6286
- const accessibilityTitleMatch = line2.match(/^accTitle\s*:\s*(.+)$/i);
6287
- if (accessibilityTitleMatch) {
6288
- accessibilityTitle = normalizeText(accessibilityTitleMatch[1]);
6289
- if (!accessibilityTitle) return null;
6290
- continue;
6291
- }
6292
- const accessibilityDescriptionMatch = line2.match(/^accDescr\s*:\s*(?!\{)(.+)$/i);
6293
- if (accessibilityDescriptionMatch) {
6294
- accessibilityDescription = normalizeText(accessibilityDescriptionMatch[1]);
6295
- if (!accessibilityDescription) return null;
6296
- continue;
6297
- }
6298
- const accessibilityDescriptionBlock = line2.match(/^accDescr\s*:?\s*\{\s*(.*)$/i);
6299
- if (accessibilityDescriptionBlock) {
6300
- const blockLines = [];
6301
- let remainder = accessibilityDescriptionBlock[1];
6302
- let closed = false;
6303
- if (remainder.includes("}")) {
6304
- blockLines.push(remainder.slice(0, remainder.indexOf("}")).trim());
6305
- closed = true;
6306
- } else {
6307
- if (remainder.trim()) blockLines.push(remainder.trim());
6308
- while (++lineIndex < lines.length) {
6309
- const blockLine = lines[lineIndex];
6310
- if (blockLine.includes("}")) {
6311
- const before = blockLine.slice(0, blockLine.indexOf("}")).trim();
6312
- if (before) blockLines.push(before);
6313
- closed = true;
6314
- break;
6315
- }
6316
- blockLines.push(blockLine.trim());
6317
- }
6318
- }
6319
- if (!closed) return null;
6320
- accessibilityDescription = blockLines.filter(Boolean).join("\n");
6321
- continue;
6322
- }
6323
5978
  const gm = line2.match(GROUP_RE);
6324
5979
  if (gm) {
6325
5980
  const id = gm[1];
@@ -6846,12 +6501,8 @@ function verifyOpaqueArchitectureIcons(source) {
6846
6501
  return warnings;
6847
6502
  }
6848
6503
  function verifyArchitecture(body, opts) {
6849
- const cap = opts.labelCharCap ?? DEFAULT_LABEL_CHAR_CAP;
6850
6504
  const warnings = [];
6851
- const overflow = (target, text3) => {
6852
- const w2 = labelOverflowWarning(target, text3, cap);
6853
- if (w2) warnings.push(w2);
6854
- };
6505
+ const overflow = labelOverflowCollector(warnings, opts);
6855
6506
  if (body.groups.length === 0 && body.services.length === 0 && body.junctions.length === 0 && body.title === void 0 && body.accessibilityTitle === void 0 && body.accessibilityDescription === void 0) {
6856
6507
  warnings.push({ code: "EMPTY_DIAGRAM" });
6857
6508
  }
@@ -7168,16 +6819,6 @@ function cloneXyChart(b2) {
7168
6819
  series: b2.series.map((s2) => ({ id: s2.id, kind: s2.kind, name: s2.name, values: [...s2.values], ...s2.pointLabels ? { pointLabels: [...s2.pointLabels] } : {} }))
7169
6820
  };
7170
6821
  }
7171
- function makeSeriesIdAllocator(body) {
7172
- const seen = new Set(body.series.map((s2) => s2.id));
7173
- return () => {
7174
- let n2 = 0;
7175
- while (seen.has(`series-${n2}`)) n2++;
7176
- const id = `series-${n2}`;
7177
- seen.add(id);
7178
- return id;
7179
- };
7180
- }
7181
6822
  function validBareText(value, field) {
7182
6823
  if (typeof value !== "string") return err({ code: "INVALID_OP", message: `XY chart ${field} must be a string` });
7183
6824
  const normalized = normalizeText2(value);
@@ -7234,7 +6875,7 @@ function buildAxis(spec, axisName) {
7234
6875
  }
7235
6876
  function mutateXyChart(body, op) {
7236
6877
  const next = cloneXyChart(body);
7237
- const nextId = makeSeriesIdAllocator(next);
6878
+ const nextId = indexedIdAllocator(next.series.map((series) => series.id), "series");
7238
6879
  switch (op.kind) {
7239
6880
  case "set_title": {
7240
6881
  if (op.title === null) {
@@ -7352,12 +6993,8 @@ function mutateXyChart(body, op) {
7352
6993
  return ok(next);
7353
6994
  }
7354
6995
  function verifyXyChart(body, opts) {
7355
- const cap = opts.labelCharCap ?? DEFAULT_LABEL_CHAR_CAP;
7356
6996
  const warnings = [];
7357
- const overflow = (target, text3) => {
7358
- const w2 = labelOverflowWarning(target, text3, cap);
7359
- if (w2) warnings.push(w2);
7360
- };
6997
+ const overflow = labelOverflowCollector(warnings, opts);
7361
6998
  if (body.series.length === 0) warnings.push({ code: "EMPTY_DIAGRAM" });
7362
6999
  if (body.title !== void 0) overflow("title", body.title);
7363
7000
  if (body.xAxis?.name !== void 0) overflow("x-axis", body.xAxis.name);
@@ -7377,46 +7014,11 @@ function verifyXyChart(body, opts) {
7377
7014
  return warnings;
7378
7015
  }
7379
7016
 
7380
- // src/shared/accessibility-directives.ts
7381
- function accessibilityFields(accessibility) {
7382
- return {
7383
- ...accessibility.title !== void 0 ? { accessibilityTitle: accessibility.title } : {},
7384
- ...accessibility.descr !== void 0 ? { accessibilityDescription: accessibility.descr } : {}
7385
- };
7386
- }
7387
- function withAccessibilityFields(value, accessibility) {
7388
- if (accessibility.title === void 0 && accessibility.descr === void 0) {
7389
- return value;
7390
- }
7391
- return { ...value, ...accessibilityFields(accessibility) };
7392
- }
7393
- function withAccessibilityObject(value, accessibility) {
7394
- if (accessibility.title === void 0 && accessibility.descr === void 0) {
7395
- return value;
7396
- }
7397
- return {
7398
- ...value,
7399
- accessibility: {
7400
- ...accessibility.title !== void 0 ? { title: accessibility.title } : {},
7401
- ...accessibility.descr !== void 0 ? { description: accessibility.descr } : {}
7402
- }
7403
- };
7404
- }
7405
- function accessibilityDirectiveEnd(lines, i2) {
7406
- const line2 = lines[i2].trim();
7407
- if (/^acc(Title|Descr)\s*:/i.test(line2)) return i2;
7408
- if (/^accDescr\s*\{/i.test(line2)) {
7409
- let end = i2;
7410
- while (end < lines.length && !lines[end].includes("}")) end++;
7411
- return end;
7412
- }
7413
- return -1;
7414
- }
7415
-
7416
7017
  // src/pie/parser.ts
7417
7018
  var ENTRY_RE = /^"((?:[^"\\]|\\.)*)"\s*:\s*(.+)$/;
7418
7019
  var NUMBER_RE = /^\+?(?:\d+(?:\.\d+)?|\.\d+)$/;
7419
7020
  function parsePieChart(lines) {
7021
+ lines = scanAccessibilityDirectives(lines).familyLines;
7420
7022
  if (lines.length === 0) {
7421
7023
  throw new Error("Pie chart is empty");
7422
7024
  }
@@ -7443,11 +7045,6 @@ function parsePieChart(lines) {
7443
7045
  for (let i2 = 1; i2 < lines.length; i2++) {
7444
7046
  const line2 = lines[i2].trim();
7445
7047
  if (line2.length === 0 || line2.startsWith("%%")) continue;
7446
- const accEnd = accessibilityDirectiveEnd(lines, i2);
7447
- if (accEnd !== -1) {
7448
- i2 = accEnd;
7449
- continue;
7450
- }
7451
7048
  if (/^showData\s*$/i.test(line2)) {
7452
7049
  showData = true;
7453
7050
  continue;
@@ -7543,16 +7140,6 @@ function clonePie(b2) {
7543
7140
  slices: b2.slices.map((s2) => ({ id: s2.id, label: s2.label, value: s2.value }))
7544
7141
  };
7545
7142
  }
7546
- function makeSliceIdAllocator(body) {
7547
- const seen = new Set(body.slices.map((s2) => s2.id));
7548
- return () => {
7549
- let n2 = 0;
7550
- while (seen.has(`slice-${n2}`)) n2++;
7551
- const id = `slice-${n2}`;
7552
- seen.add(id);
7553
- return id;
7554
- };
7555
- }
7556
7143
  function validLabel(value, field) {
7557
7144
  if (typeof value !== "string") return err({ code: "INVALID_OP", message: `Pie ${field} must be a string` });
7558
7145
  const trimmed = value.trim();
@@ -7572,7 +7159,7 @@ function findSlice(body, label) {
7572
7159
  }
7573
7160
  function mutatePie(body, op) {
7574
7161
  const next = clonePie(body);
7575
- const nextId = makeSliceIdAllocator(next);
7162
+ const nextId = indexedIdAllocator(next.slices.map((slice) => slice.id), "slice");
7576
7163
  switch (op.kind) {
7577
7164
  case "set_title": {
7578
7165
  if (op.title === null) {
@@ -7653,12 +7240,8 @@ function mutatePie(body, op) {
7653
7240
  return ok(next);
7654
7241
  }
7655
7242
  function verifyPie(body, opts) {
7656
- const cap = opts.labelCharCap ?? DEFAULT_LABEL_CHAR_CAP;
7657
7243
  const warnings = [];
7658
- const overflow = (target, text3) => {
7659
- const w2 = labelOverflowWarning(target, text3, cap);
7660
- if (w2) warnings.push(w2);
7661
- };
7244
+ const overflow = labelOverflowCollector(warnings, opts);
7662
7245
  if (body.slices.length === 0) warnings.push({ code: "EMPTY_DIAGRAM" });
7663
7246
  if (body.title !== void 0) overflow("title", body.title);
7664
7247
  for (const s2 of body.slices) overflow(s2.id, s2.label);
@@ -7779,10 +7362,10 @@ var AXIS_RE = /^([xy])-axis\s+(.+)$/i;
7779
7362
  var QUADRANT_RE = /^quadrant-([1-4])\s+(.+)$/i;
7780
7363
  var POINT_RE = /^(.+?)\s*:\s*\[\s*([^,\]]+)\s*,\s*([^,\]]+)\s*\]\s*(.*)$/;
7781
7364
  var CLASSDEF_RE = /^classDef\s+(.+)$/i;
7782
- var ACC_TITLE_RE = /^accTitle\s*:\s*(.+)$/i;
7783
- var ACC_DESCR_RE = /^accDescr\s*:\s*(?!\{)(.+)$/i;
7784
- var ACC_DESCR_BLOCK_RE = /^accDescr\s*:?\s*\{\s*(.*)$/i;
7785
7365
  function parseQuadrantChart(lines) {
7366
+ const scanned = scanAccessibilityDirectives(lines);
7367
+ requireClosedAccessibility(scanned);
7368
+ lines = scanned.familyLines;
7786
7369
  if (lines.length === 0) {
7787
7370
  throw new Error("Quadrant chart is empty");
7788
7371
  }
@@ -7791,7 +7374,10 @@ function parseQuadrantChart(lines) {
7791
7374
  throw new Error(`Quadrant chart must start with "quadrant" or "quadrantChart", got: "${header}"`);
7792
7375
  }
7793
7376
  let title;
7794
- const accessibility = {};
7377
+ const accessibility = {
7378
+ ...scanned.accessibility.title !== void 0 ? { title: normalizeBrTags(scanned.accessibility.title) } : {},
7379
+ ...scanned.accessibility.descr !== void 0 ? { description: normalizeBrTags(scanned.accessibility.descr) } : {}
7380
+ };
7795
7381
  let xAxis;
7796
7382
  let yAxis;
7797
7383
  const quadrants = [void 0, void 0, void 0, void 0];
@@ -7810,38 +7396,6 @@ function parseQuadrantChart(lines) {
7810
7396
  classDefs[parsed.name] = parsed.style;
7811
7397
  continue;
7812
7398
  }
7813
- if (m2 = line2.match(ACC_TITLE_RE)) {
7814
- accessibility.title = normalizeBrTags(m2[1].trim());
7815
- continue;
7816
- }
7817
- if (m2 = line2.match(ACC_DESCR_RE)) {
7818
- accessibility.description = normalizeBrTags(m2[1].trim());
7819
- continue;
7820
- }
7821
- if (m2 = line2.match(ACC_DESCR_BLOCK_RE)) {
7822
- const parts = [];
7823
- let rest = m2[1];
7824
- let closed = false;
7825
- for (; ; ) {
7826
- const end = rest.indexOf("}");
7827
- if (end !== -1) {
7828
- const text3 = rest.slice(0, end).trim();
7829
- if (text3) parts.push(text3);
7830
- if (rest.slice(end + 1).trim()) {
7831
- throw new Error(`Unrecognized text after quadrant accDescr block: "${rest.slice(end + 1).trim()}"`);
7832
- }
7833
- closed = true;
7834
- break;
7835
- }
7836
- if (rest.trim()) parts.push(rest.trim());
7837
- i2++;
7838
- if (i2 >= lines.length) break;
7839
- rest = lines[i2];
7840
- }
7841
- if (!closed) throw new Error('Quadrant accDescr block is missing a closing "}"');
7842
- accessibility.description = normalizeBrTags(parts.join("\n"));
7843
- continue;
7844
- }
7845
7399
  if (m2 = line2.match(TITLE_RE2)) {
7846
7400
  title = normalizeBrTags(m2[1].trim());
7847
7401
  continue;
@@ -8152,12 +7706,8 @@ function mutateQuadrant(body, op) {
8152
7706
  return ok(next);
8153
7707
  }
8154
7708
  function verifyQuadrant(body, opts) {
8155
- const cap = opts.labelCharCap ?? DEFAULT_LABEL_CHAR_CAP;
8156
7709
  const warnings = [];
8157
- const overflow = (target, text3) => {
8158
- const w2 = labelOverflowWarning(target, text3, cap);
8159
- if (w2) warnings.push(w2);
8160
- };
7710
+ const overflow = labelOverflowCollector(warnings, opts);
8161
7711
  const empty = body.title === void 0 && !body.xAxis && !body.yAxis && body.quadrants.every((q) => q === void 0) && body.points.length === 0;
8162
7712
  if (empty) warnings.push({ code: "EMPTY_DIAGRAM" });
8163
7713
  if (body.title !== void 0) overflow("title", body.title);
@@ -11687,15 +11237,11 @@ function renameInTransitions(body, from, to) {
11687
11237
  walk(body.states, body.transitions);
11688
11238
  }
11689
11239
  function verifyState(body, opts) {
11690
- const cap = opts.labelCharCap ?? DEFAULT_LABEL_CHAR_CAP;
11691
11240
  const warnings = [];
11692
11241
  if (body.states.length === 0 && body.transitions.length === 0 && (body.notes ?? []).length === 0) {
11693
11242
  return [{ code: "EMPTY_DIAGRAM" }];
11694
11243
  }
11695
- const overflow = (target, text3) => {
11696
- const w2 = labelOverflowWarning(target, text3, cap);
11697
- if (w2) warnings.push(w2);
11698
- };
11244
+ const overflow = labelOverflowCollector(warnings, opts);
11699
11245
  const known = /* @__PURE__ */ new Set([PSEUDO]);
11700
11246
  collectIds(body.states, known);
11701
11247
  const anchors = (endpoint) => {
@@ -11841,12 +11387,14 @@ var DIRECTIVE_RES = {
11841
11387
  weekday: /^weekday\s+(.+)$/i,
11842
11388
  weekend: /^weekend\s+(.+)$/i,
11843
11389
  section: /^section\s+(.+)$/i,
11844
- click: /^click\s+([\w-]+)\s+(href|call)\s+(.+)$/i,
11845
- accTitle: /^accTitle\s*:\s*(.+)$/i,
11846
- accDescrInline: /^accDescr\s*:\s*(.+)$/i,
11847
- accDescrBlock: /^accDescr\s*\{\s*$/i
11390
+ click: /^click\s+([\w-]+)\s+(href|call)\s+(.+)$/i
11848
11391
  };
11849
11392
  function parseGanttModel(lines) {
11393
+ const accessibility = scanAccessibilityDirectives(lines);
11394
+ if (accessibility.unclosedIndex !== void 0) {
11395
+ throw new GanttError("GANTT_BAD_DIRECTIVE", "Unclosed accDescr block", accessibility.unclosedIndex + 1);
11396
+ }
11397
+ lines = accessibility.familyLines;
11850
11398
  const header = (lines[0] ?? "").trim();
11851
11399
  if (!/^gantt\s*$/i.test(header)) {
11852
11400
  throw new GanttError("GANTT_BAD_DIRECTIVE", `Expected "gantt" header, got "${header}"`, 1);
@@ -11861,25 +11409,16 @@ function parseGanttModel(lines) {
11861
11409
  weekStart: "sunday",
11862
11410
  sections: [{ taskIndexes: [] }],
11863
11411
  tasks: [],
11864
- clicks: []
11412
+ clicks: [],
11413
+ ...accessibility.accessibility.title !== void 0 ? { accTitle: accessibility.accessibility.title } : {},
11414
+ ...accessibility.accessibility.descr !== void 0 ? { accDescr: accessibility.accessibility.descr.replace(/\s*\n\s*/g, " ") } : {}
11865
11415
  };
11866
11416
  const seenIds = /* @__PURE__ */ new Set();
11867
11417
  let currentSection = 0;
11868
- let inAccDescr = false;
11869
- const accDescrBuf = [];
11870
11418
  for (let i2 = 1; i2 < lines.length; i2++) {
11871
11419
  const line2 = lines[i2].trim();
11872
11420
  const lineNo = i2 + 1;
11873
11421
  if (!line2 || line2.startsWith("%%")) continue;
11874
- if (inAccDescr) {
11875
- if (/^\}\s*$/.test(line2)) {
11876
- model.accDescr = accDescrBuf.join(" ").trim();
11877
- inAccDescr = false;
11878
- } else {
11879
- accDescrBuf.push(line2);
11880
- }
11881
- continue;
11882
- }
11883
11422
  let m2;
11884
11423
  if (m2 = line2.match(DIRECTIVE_RES.title)) {
11885
11424
  model.title = m2[1].trim();
@@ -11939,18 +11478,6 @@ function parseGanttModel(lines) {
11939
11478
  model.clicks.push({ taskId: m2[1], action: m2[2].toLowerCase(), rest: m2[3].trim(), line: lineNo });
11940
11479
  continue;
11941
11480
  }
11942
- if (m2 = line2.match(DIRECTIVE_RES.accTitle)) {
11943
- model.accTitle = m2[1].trim();
11944
- continue;
11945
- }
11946
- if (DIRECTIVE_RES.accDescrBlock.test(line2)) {
11947
- inAccDescr = true;
11948
- continue;
11949
- }
11950
- if (m2 = line2.match(DIRECTIVE_RES.accDescrInline)) {
11951
- model.accDescr = m2[1].trim();
11952
- continue;
11953
- }
11954
11481
  if (m2 = line2.match(DIRECTIVE_RES.section)) {
11955
11482
  model.sections.push({ label: m2[1].trim(), taskIndexes: [], line: lineNo });
11956
11483
  currentSection = model.sections.length - 1;
@@ -11983,7 +11510,6 @@ function parseGanttModel(lines) {
11983
11510
  }
11984
11511
  throw new GanttError("GANTT_BAD_DIRECTIVE", `Unrecognized gantt line "${line2}"`, lineNo);
11985
11512
  }
11986
- if (inAccDescr) throw new GanttError("GANTT_BAD_DIRECTIVE", "Unclosed accDescr block");
11987
11513
  return model;
11988
11514
  }
11989
11515
  function applyGanttFrontmatterConfig(model, frontmatter) {
@@ -12020,8 +11546,7 @@ function applyResolvedGanttFrontmatterConfig(model, resolved) {
12020
11546
  }
12021
11547
 
12022
11548
  // src/agent/gantt-body.ts
12023
- var DIRECTIVE_LINE_RE = /^(dateFormat|axisFormat|tickInterval|inclusiveEndDates|topAxis|excludes|includes|todayMarker|weekday|weekend|click|accTitle|accDescr)\b/i;
12024
- var ACC_DESCR_BLOCK_OPEN_RE = /^accDescr\s*\{\s*$/i;
11549
+ var DIRECTIVE_LINE_RE = /^(dateFormat|axisFormat|tickInterval|inclusiveEndDates|topAxis|excludes|includes|todayMarker|weekday|weekend|click)\b/i;
12025
11550
  var TITLE_RE3 = /^title\s+(.+)$/i;
12026
11551
  var SECTION_RE = /^section\s+(.+)$/i;
12027
11552
  var TASK_ID_RE = /^[\w-]+$/;
@@ -12049,21 +11574,11 @@ function parseGanttBody(trimmedLines, rawLines) {
12049
11574
  i2++;
12050
11575
  continue;
12051
11576
  }
12052
- if (ACC_DESCR_BLOCK_OPEN_RE.test(line2)) {
12053
- const blockLines = [rawLine];
12054
- i2++;
12055
- let closed = false;
12056
- while (i2 < raw.length) {
12057
- const inner = raw[i2];
12058
- blockLines.push(inner);
12059
- i2++;
12060
- if (/^\}\s*$/.test(inner.trim())) {
12061
- closed = true;
12062
- break;
12063
- }
12064
- }
12065
- if (!closed) return null;
12066
- appendOpaqueSegment(statements, blockLines, ganttOpaqueBlock);
11577
+ const accessibility = parseAccessibilityDirective(raw, i2);
11578
+ if (accessibility === void 0) return null;
11579
+ if (accessibility !== null) {
11580
+ appendOpaqueSegment(statements, raw.slice(i2, accessibility.endIndex + 1), ganttOpaqueBlock);
11581
+ i2 = accessibility.endIndex + 1;
12067
11582
  continue;
12068
11583
  }
12069
11584
  if (DIRECTIVE_LINE_RE.test(line2)) {
@@ -12176,18 +11691,10 @@ function deriveStatements(b2) {
12176
11691
  return out;
12177
11692
  }
12178
11693
  function makeIdAllocator2(body, prefix) {
12179
- const seen = /* @__PURE__ */ new Set();
12180
- for (const s2 of body.sections) {
12181
- seen.add(s2.id);
12182
- for (const t2 of s2.tasks) seen.add(t2.id);
12183
- }
12184
- return () => {
12185
- let n2 = 0;
12186
- while (seen.has(`${prefix}-${n2}`)) n2++;
12187
- const id = `${prefix}-${n2}`;
12188
- seen.add(id);
12189
- return id;
12190
- };
11694
+ return indexedIdAllocator(
11695
+ body.sections.flatMap((section2) => [section2.id, ...section2.tasks.map((task) => task.id)]),
11696
+ prefix
11697
+ );
12191
11698
  }
12192
11699
  function validateTask(task) {
12193
11700
  if (!task.label || /[:\r\n]/.test(task.label)) {
@@ -12610,10 +12117,7 @@ function verifyGantt(body, opts) {
12610
12117
  if (tasks.length === 0 && body.title === void 0 && opaqueLines.length === 0) {
12611
12118
  return [{ code: "EMPTY_DIAGRAM" }];
12612
12119
  }
12613
- const overflow = (target, text3) => {
12614
- const w2 = labelOverflowWarning(target, text3, cap);
12615
- if (w2) warnings.push(w2);
12616
- };
12120
+ const overflow = labelOverflowCollector(warnings, opts, cap);
12617
12121
  if (body.title !== void 0) overflow("title", body.title);
12618
12122
  for (const s2 of body.sections) {
12619
12123
  if (s2.label !== void 0) overflow(s2.id, s2.label);
@@ -13920,15 +13424,21 @@ var MindmapDuplicateIdError = class extends MindmapParseError {
13920
13424
  code = "MINDMAP_DUPLICATE_ID";
13921
13425
  };
13922
13426
  function parseMindmap(source) {
13923
- const rawLines = source.replace(/^\uFEFF/, "").split(/\r?\n/);
13427
+ const sourceLines = source.replace(/^\uFEFF/, "").split(/\r?\n/);
13428
+ const accessibilityLines = sourceLines.map((line2) => parseAccessibilityDirective([line2], 0)?.form === "inline" ? stripInlineComment(line2) : line2);
13429
+ const scanned = scanAccessibilityDirectives(accessibilityLines);
13430
+ if (scanned.unclosedIndex !== void 0) {
13431
+ throw new MindmapParseError("Unclosed accDescr block", scanned.unclosedIndex + 1);
13432
+ }
13433
+ const rawLines = scanned.familyLines;
13924
13434
  const headerIndex = rawLines.findIndex((line2) => /^\s*mindmap\s*$/i.test(line2));
13925
13435
  if (headerIndex < 0) throw new MindmapParseError("Mindmap source must start with the mindmap header");
13926
13436
  const stack = [];
13927
13437
  const ids = /* @__PURE__ */ new Set();
13928
13438
  let root;
13929
13439
  let lastNode;
13930
- let accessibilityTitle;
13931
- let accessibilityDescription;
13440
+ const accessibilityTitle = scanned.accessibility.title !== void 0 ? normalizeBrTags(scanned.accessibility.title) : void 0;
13441
+ const accessibilityDescription = scanned.accessibility.descr !== void 0 ? normalizeBrTags(scanned.accessibility.descr) : void 0;
13932
13442
  for (let index = headerIndex + 1; index < rawLines.length; index++) {
13933
13443
  let raw = rawLines[index];
13934
13444
  if (raw.includes('["`') && !raw.includes('`"]')) {
@@ -13947,38 +13457,9 @@ function parseMindmap(source) {
13947
13457
  raw = stripInlineComment(raw);
13948
13458
  const trimmed = raw.trim();
13949
13459
  if (!trimmed || trimmed.startsWith("%%")) continue;
13950
- const accTitle = trimmed.match(/^accTitle\s*:\s*(.+)$/i);
13951
- if (accTitle) {
13952
- accessibilityTitle = normalizeBrTags(accTitle[1].trim());
13953
- continue;
13954
- }
13955
- if (/^accTitle\s*:/i.test(trimmed)) throw new MindmapParseError("Mindmap accTitle must contain a non-empty value", index + 1);
13956
- const accDescr = trimmed.match(/^accDescr\s*:\s*(.+)$/i);
13957
- if (accDescr) {
13958
- accessibilityDescription = normalizeBrTags(accDescr[1].trim());
13959
- continue;
13960
- }
13961
- if (/^accDescr\s*:/i.test(trimmed)) throw new MindmapParseError("Mindmap accDescr must contain a non-empty value", index + 1);
13962
- const accDescrBlock = trimmed.match(/^accDescr\s*\{\s*(.*)$/i);
13963
- if (accDescrBlock) {
13964
- const parts = [];
13965
- let rest = accDescrBlock[1];
13966
- let closed = false;
13967
- while (true) {
13968
- const close = rest.indexOf("}");
13969
- if (close >= 0) {
13970
- if (rest.slice(0, close).trim()) parts.push(rest.slice(0, close).trim());
13971
- closed = true;
13972
- break;
13973
- }
13974
- if (rest.trim()) parts.push(rest.trim());
13975
- index++;
13976
- if (index >= rawLines.length) break;
13977
- rest = rawLines[index].trim();
13978
- }
13979
- if (!closed) throw new MindmapParseError("Unclosed accDescr block", index + 1);
13980
- accessibilityDescription = normalizeBrTags(parts.join("\n").trim());
13981
- continue;
13460
+ if (/^acc(?:Title|Descr)\b/i.test(trimmed)) {
13461
+ const kind = /^accTitle\b/i.test(trimmed) ? "accTitle" : "accDescr";
13462
+ throw new MindmapParseError(`Mindmap ${kind} must contain a non-empty value`, index + 1);
13982
13463
  }
13983
13464
  if (/^::icon\b/i.test(trimmed)) {
13984
13465
  const icon = trimmed.match(/^::icon\(([^)]*)\)$/i);
@@ -14307,10 +13788,9 @@ function mutateMindmap(body, op) {
14307
13788
  }
14308
13789
  function verifyMindmap(body, opts) {
14309
13790
  const warnings = [];
14310
- const cap = opts.labelCharCap ?? DEFAULT_LABEL_CHAR_CAP;
13791
+ const overflow = labelOverflowCollector(warnings, opts);
14311
13792
  const visit2 = (node2) => {
14312
- const overflow = labelOverflowWarning(node2.id, node2.label, cap);
14313
- if (overflow) warnings.push(overflow);
13793
+ overflow(node2.id, node2.label);
14314
13794
  node2.children.forEach(visit2);
14315
13795
  };
14316
13796
  visit2(body.root);
@@ -14335,7 +13815,11 @@ var GitGraphDuplicateCommitError = class extends GitGraphParseError {
14335
13815
  code = "GITGRAPH_DUPLICATE_COMMIT_ID";
14336
13816
  };
14337
13817
  function parseGitGraph(source, options = {}) {
14338
- const lines = source.replace(/^\uFEFF/, "").split(/\r?\n/);
13818
+ const scanned = scanAccessibilityDirectives(source.replace(/^\uFEFF/, "").split(/\r?\n/));
13819
+ if (scanned.unclosedIndex !== void 0) {
13820
+ throw new GitGraphParseError("Unclosed accDescr block", scanned.unclosedIndex + 1);
13821
+ }
13822
+ const lines = scanned.familyLines;
14339
13823
  const headerIndex = lines.findIndex((line2) => /^\s*gitgraph\b/i.test(line2));
14340
13824
  if (headerIndex < 0) throw new GitGraphParseError("gitGraph source must start with a gitGraph header");
14341
13825
  const header = lines[headerIndex].trim().match(/^gitGraph(?:\s+(LR|TB|BT))?\s*:?[ \t]*$/i);
@@ -14350,8 +13834,8 @@ function parseGitGraph(source, options = {}) {
14350
13834
  const commitById = /* @__PURE__ */ new Map();
14351
13835
  let currentBranch = mainBranchName;
14352
13836
  let sequence = 0;
14353
- let accessibilityTitle;
14354
- let accessibilityDescription;
13837
+ const accessibilityTitle = scanned.accessibility.title;
13838
+ const accessibilityDescription = scanned.accessibility.descr;
14355
13839
  const addCommit = (attrs, sourceKind, line2, extra = {}, parents) => {
14356
13840
  const customId = attrs.id !== void 0;
14357
13841
  const id = attrs.id ?? `c${sequence}`;
@@ -14378,37 +13862,6 @@ function parseGitGraph(source, options = {}) {
14378
13862
  for (let index = headerIndex + 1; index < lines.length; index++) {
14379
13863
  const text3 = lines[index].trim();
14380
13864
  if (!text3 || text3.startsWith("%%")) continue;
14381
- const accTitle = text3.match(/^accTitle\s*:\s*(.+)$/i);
14382
- if (accTitle) {
14383
- accessibilityTitle = accTitle[1].trim();
14384
- continue;
14385
- }
14386
- const accDescr = text3.match(/^accDescr\s*:\s*(.+)$/i);
14387
- if (accDescr) {
14388
- accessibilityDescription = accDescr[1].trim();
14389
- continue;
14390
- }
14391
- const accDescrBlock = text3.match(/^accDescr\s*\{\s*(.*)$/i);
14392
- if (accDescrBlock) {
14393
- const parts = [];
14394
- let rest = accDescrBlock[1];
14395
- let closed = false;
14396
- while (true) {
14397
- const close = rest.indexOf("}");
14398
- if (close >= 0) {
14399
- if (rest.slice(0, close).trim()) parts.push(rest.slice(0, close).trim());
14400
- closed = true;
14401
- break;
14402
- }
14403
- if (rest.trim()) parts.push(rest.trim());
14404
- index++;
14405
- if (index >= lines.length) break;
14406
- rest = lines[index].trim();
14407
- }
14408
- if (!closed) throw new GitGraphParseError("Unclosed accDescr block", index + 1);
14409
- accessibilityDescription = parts.join("\n").trim();
14410
- continue;
14411
- }
14412
13865
  const commitLine = text3.match(/^commit(?:\s+(.*))?$/i);
14413
13866
  if (commitLine) {
14414
13867
  const payload = commitLine[1] ?? "";
@@ -14725,10 +14178,9 @@ function mutateGitGraph(body, op) {
14725
14178
  function verifyGitGraph(body, opts) {
14726
14179
  const warnings = [];
14727
14180
  const ids = new Set(body.commits.map((commit) => commit.id));
14728
- const cap = opts.labelCharCap ?? DEFAULT_LABEL_CHAR_CAP;
14181
+ const overflow = labelOverflowCollector(warnings, opts);
14729
14182
  for (const commit of body.commits) {
14730
- const overflow = labelOverflowWarning(commit.id, commit.message || commit.id, cap);
14731
- if (overflow) warnings.push(overflow);
14183
+ overflow(commit.id, commit.message || commit.id);
14732
14184
  for (const parent of commit.parents) if (!ids.has(parent)) warnings.push({ code: "EDGE_MISANCHORED", edge: `${parent}->${commit.id}`, to: commit.id });
14733
14185
  }
14734
14186
  return warnings;
@@ -14739,9 +14191,6 @@ var MAX_RADAR_TICKS = 64;
14739
14191
  var MAX_RADAR_AXES = 256;
14740
14192
  var HEADER_RE = /^radar-beta(?:[\t ]*:)?(?=$|\s)/i;
14741
14193
  var TITLE_RE4 = /^title(?:[\t ]+(.*))?$/i;
14742
- var ACC_TITLE_RE2 = /^accTitle[\t ]*:[\t ]*(.*)$/i;
14743
- var ACC_DESCR_RE2 = /^accDescr[\t ]*:[\t ]*(.*)$/i;
14744
- var ACC_DESCR_BLOCK_RE2 = /^accDescr\s*:?\s*\{/i;
14745
14194
  var AXIS_RE2 = /^axis\s+(.+)$/i;
14746
14195
  var CURVE_RE = /^curve\s+([\s\S]+)$/i;
14747
14196
  var OPTION_RE = /^(showLegend|ticks|max|min|graticule)\b(.*)$/i;
@@ -15013,13 +14462,18 @@ function parseCurveItem(item, axes) {
15013
14462
  return { id, label, values };
15014
14463
  }
15015
14464
  function parseRadarChart(lines, options = {}) {
15016
- const source = stripComments(lines.join("\n")).trimStart();
14465
+ const scanned = scanAccessibilityDirectives(stripComments(lines.join("\n")).split(/\r?\n/));
14466
+ requireClosedAccessibility(scanned);
14467
+ const source = scanned.familyLines.join("\n").trimStart();
15017
14468
  if (!source) throw new Error("Radar chart is empty");
15018
14469
  const header = source.match(HEADER_RE);
15019
14470
  if (!header) throw new Error(`Radar chart must start with "radar-beta", got: "${source.split(/\r?\n/, 1)[0]}"`);
15020
14471
  const statements = bodyStatements(source.slice(header[0].length));
15021
14472
  let title = options.title;
15022
- const accessibility = {};
14473
+ const accessibility = {
14474
+ ...scanned.accessibility.title !== void 0 ? { title: normalizeBrTags(scanned.accessibility.title) } : {},
14475
+ ...scanned.accessibility.descr !== void 0 ? { description: normalizeBrTags(scanned.accessibility.descr) } : {}
14476
+ };
15023
14477
  const axes = [];
15024
14478
  const pendingCurves = [];
15025
14479
  let min = 0;
@@ -15030,20 +14484,11 @@ function parseRadarChart(lines, options = {}) {
15030
14484
  for (let i2 = 0; i2 < statements.length; i2++) {
15031
14485
  const line2 = statements[i2];
15032
14486
  let match;
15033
- if (match = line2.match(ACC_TITLE_RE2)) {
15034
- accessibility.title = normalizeBrTags(match[1].trim());
15035
- continue;
15036
- }
15037
- if (ACC_DESCR_BLOCK_RE2.test(line2)) {
15038
- const open = line2.indexOf("{");
15039
- const close = line2.lastIndexOf("}");
15040
- if (open < 0 || close <= open) throw new Error('Radar accDescr block is missing a closing "}"');
15041
- if (line2.slice(close + 1).trim()) throw new Error(`Unrecognized text after radar accDescr block: "${line2.slice(close + 1).trim()}"`);
15042
- accessibility.description = normalizeBrTags(line2.slice(open + 1, close).trim().split("\n").map((part) => part.trim()).filter(Boolean).join("\n"));
15043
- continue;
15044
- }
15045
- if (match = line2.match(ACC_DESCR_RE2)) {
15046
- accessibility.description = normalizeBrTags(match[1].trim());
14487
+ const accessibilityDirective = parseAccessibilityDirective([line2], 0);
14488
+ if (accessibilityDirective === void 0) throw new Error('Radar accDescr block is missing a closing "}"');
14489
+ if (accessibilityDirective !== null) {
14490
+ if (accessibilityDirective.title) accessibility.title = normalizeBrTags(accessibilityDirective.value);
14491
+ else accessibility.description = normalizeBrTags(accessibilityDirective.value);
15047
14492
  continue;
15048
14493
  }
15049
14494
  if (match = line2.match(TITLE_RE4)) {
@@ -15492,12 +14937,8 @@ function reorder(len, from, to, what) {
15492
14937
  return ok({ from, to });
15493
14938
  }
15494
14939
  function verifyRadar(body, opts) {
15495
- const cap = opts.labelCharCap ?? DEFAULT_LABEL_CHAR_CAP;
15496
14940
  const warnings = [];
15497
- const overflow = (target, text3) => {
15498
- const w2 = labelOverflowWarning(target, text3, cap);
15499
- if (w2) warnings.push(w2);
15500
- };
14941
+ const overflow = labelOverflowCollector(warnings, opts);
15501
14942
  if (body.axes.length === 0 && body.curves.length === 0) warnings.push({ code: "EMPTY_DIAGRAM" });
15502
14943
  if (body.title !== void 0) overflow("title", body.title);
15503
14944
  for (const a2 of body.axes) overflow(a2.id, a2.label);
@@ -28425,7 +27866,7 @@ ${pageRect}` : sceneNodeSerialization(part)).join("\n");
28425
27866
  }
28426
27867
  };
28427
27868
  var CORE_BACKEND_VERSION = "1.0.0";
28428
- var CORE_BACKEND_COMPATIBILITY = Object.freeze({ core: "^0.1.1", scene: "^2.0.0" });
27869
+ var CORE_BACKEND_COMPATIBILITY = Object.freeze({ core: "^0.2.0", scene: "^2.0.0" });
28429
27870
  var CORE_BACKEND_PROVENANCE = Object.freeze({
28430
27871
  owner: "agentic-mermaid",
28431
27872
  source: "built-in",
@@ -30652,7 +30093,7 @@ var INTERNAL_STYLE_FACE_PROJECTION = Object.freeze({
30652
30093
  group: Object.freeze({ sourceRole: "group", fields: Object.freeze([...INTERNAL_TEXT_FACE_FIELDS, ...INTERNAL_BOX_FACE_FIELDS, "fontFamily", "headerFillColor"]) })
30653
30094
  });
30654
30095
  var CORE_STYLE_VERSION = "1.0.0";
30655
- var CORE_STYLE_COMPATIBILITY = Object.freeze({ core: "^0.1.1" });
30096
+ var CORE_STYLE_COMPATIBILITY = Object.freeze({ core: "^0.2.0" });
30656
30097
  var CORE_STYLE_PROVENANCE = Object.freeze({
30657
30098
  owner: "agentic-mermaid",
30658
30099
  source: "built-in",
@@ -34360,7 +33801,13 @@ var escapeXml4 = escapeXml;
34360
33801
 
34361
33802
  // src/timeline/parser.ts
34362
33803
  function parseTimelineDiagram(lines, accessibility = {}) {
34363
- const diagram = { sections: [], ...accessibilityFields(accessibility) };
33804
+ const scanned = scanAccessibilityDirectives(lines);
33805
+ requireClosedAccessibility(scanned);
33806
+ lines = scanned.familyLines;
33807
+ const diagram = {
33808
+ sections: [],
33809
+ ...accessibilityFields({ ...accessibility, ...scanned.accessibility })
33810
+ };
34364
33811
  const headerDirection = lines[0]?.trim().match(TIMELINE_HEADER_DIRECTION_RE);
34365
33812
  if (headerDirection) {
34366
33813
  diagram.direction = headerDirection[1].toUpperCase();
@@ -34399,33 +33846,6 @@ function parseTimelineDiagram(lines, accessibility = {}) {
34399
33846
  diagram.title = normalizeBrTags(titleMatch[1].trim());
34400
33847
  continue;
34401
33848
  }
34402
- const accTitleMatch = line2.match(TIMELINE_ACCESSIBILITY_TITLE_RE);
34403
- if (accTitleMatch) {
34404
- diagram.accessibilityTitle = normalizeBrTags(accTitleMatch[1].trim());
34405
- continue;
34406
- }
34407
- const accDescrMatch = line2.match(TIMELINE_ACCESSIBILITY_DESCRIPTION_RE);
34408
- if (accDescrMatch) {
34409
- diagram.accessibilityDescription = normalizeBrTags(accDescrMatch[1].trim());
34410
- continue;
34411
- }
34412
- if (TIMELINE_ACCESSIBILITY_DESCRIPTION_BLOCK_RE.test(line2)) {
34413
- const descriptionLines = [];
34414
- let foundClosingBrace = false;
34415
- while (++i2 < lines.length) {
34416
- const blockLine = lines[i2];
34417
- if (blockLine === "}") {
34418
- foundClosingBrace = true;
34419
- break;
34420
- }
34421
- descriptionLines.push(blockLine);
34422
- }
34423
- if (!foundClosingBrace) {
34424
- throw new Error('Timeline accDescr block was not closed with "}"');
34425
- }
34426
- diagram.accessibilityDescription = normalizeBrTags(descriptionLines.join("\n").trim());
34427
- continue;
34428
- }
34429
33849
  const sectionMatch = line2.match(TIMELINE_SECTION_RE);
34430
33850
  if (sectionMatch) {
34431
33851
  currentSection = {
@@ -36862,13 +36282,19 @@ function letterAttr5(value) {
36862
36282
 
36863
36283
  // src/xychart/parser.ts
36864
36284
  function parseXYChart(lines) {
36285
+ const expandedStatements = expandXYChartStatements(lines);
36286
+ const accessibility = scanAccessibilityDirectives(expandedStatements);
36287
+ const accessibilityMetadata = accessibility.accessibility;
36288
+ const unclosed = accessibility.unclosedIndex;
36289
+ const familyLines = unclosed === void 0 ? accessibility.familyLines : accessibility.familyLines.slice(0, unclosed - expandedStatements.length);
36290
+ if (unclosed !== void 0) {
36291
+ accessibilityMetadata.descr = expandedStatements.slice(unclosed).join("\n").replace(/^[^{]*\{/, "").trim() || void 0;
36292
+ }
36865
36293
  const xAxis = {};
36866
36294
  const yAxis = {};
36867
36295
  const series = [];
36868
- const statements = expandXYChartStatements(lines);
36296
+ const statements = expandXYChartStatements(familyLines);
36869
36297
  let title;
36870
- let accTitle;
36871
- let accDescription;
36872
36298
  let horizontal = false;
36873
36299
  let headerOrientation;
36874
36300
  for (let index = 0; index < statements.length; index++) {
@@ -36883,27 +36309,6 @@ function parseXYChart(lines) {
36883
36309
  }
36884
36310
  continue;
36885
36311
  }
36886
- const accTitleMatch = line2.match(/^accTitle\s*:?\s*(.+)$/i);
36887
- if (accTitleMatch) {
36888
- accTitle = parseDirectiveText(accTitleMatch[1]);
36889
- continue;
36890
- }
36891
- const accDescrBlockMatch = line2.match(/^accDescr\s*:?\s*\{\s*$/i);
36892
- if (accDescrBlockMatch) {
36893
- const block = [];
36894
- for (index += 1; index < statements.length; index++) {
36895
- const blockLine = statements[index];
36896
- if (blockLine === "}") break;
36897
- block.push(blockLine);
36898
- }
36899
- accDescription = block.join("\n").trim() || void 0;
36900
- continue;
36901
- }
36902
- const accDescrMatch = line2.match(/^accDescr\s*:?\s*(.+)$/i);
36903
- if (accDescrMatch) {
36904
- accDescription = parseDirectiveText(accDescrMatch[1]);
36905
- continue;
36906
- }
36907
36312
  const titleMatch = line2.match(/^title\s+(.+)$/);
36908
36313
  if (titleMatch) {
36909
36314
  title = parseDirectiveText(titleMatch[1]);
@@ -36957,7 +36362,10 @@ function parseXYChart(lines) {
36957
36362
  }
36958
36363
  return {
36959
36364
  title,
36960
- accessibility: accTitle || accDescription ? { title: accTitle, description: accDescription } : void 0,
36365
+ accessibility: accessibilityMetadata.title || accessibilityMetadata.descr ? {
36366
+ title: accessibilityMetadata.title,
36367
+ description: accessibilityMetadata.descr
36368
+ } : void 0,
36961
36369
  horizontal,
36962
36370
  headerOrientation,
36963
36371
  xAxis,
@@ -37201,13 +36609,14 @@ function expandXYChartStatements(lines) {
37201
36609
  if (!line2) continue;
37202
36610
  if (inAccDescrBlock) {
37203
36611
  statements.push(line2);
37204
- if (line2 === "}") inAccDescrBlock = false;
36612
+ if (line2.includes("}")) inAccDescrBlock = false;
37205
36613
  continue;
37206
36614
  }
37207
36615
  const parts = splitSemicolonStatements(line2);
37208
36616
  for (const part of parts) {
37209
36617
  statements.push(part);
37210
- if (/^accDescr\s*:?\s*\{\s*$/i.test(part)) inAccDescrBlock = true;
36618
+ const block = part.match(/^accDescr\s*:?\s*\{(.*)$/i);
36619
+ if (block && !block[1].includes("}")) inAccDescrBlock = true;
37211
36620
  }
37212
36621
  }
37213
36622
  return statements;
@@ -43054,6 +42463,9 @@ var JUNCTION_RE2 = new RegExp(`^junction\\s+(${IDENT2})(?:\\s+in\\s+(${IDENT2}))
43054
42463
  var SOURCE_RE2 = new RegExp(`^(${IDENT2})(\\{group\\})?:(L|R|T|B)$`);
43055
42464
  var TARGET_RE2 = new RegExp(`^(L|R|T|B):(${IDENT2})(\\{group\\})?$`);
43056
42465
  function parseArchitectureDiagram(lines) {
42466
+ const accessibility = scanAccessibilityDirectives(lines);
42467
+ requireClosedAccessibility(accessibility);
42468
+ lines = accessibility.familyLines;
43057
42469
  if (lines.length === 0) {
43058
42470
  throw new Error("Empty mermaid diagram");
43059
42471
  }
@@ -43067,8 +42479,8 @@ function parseArchitectureDiagram(lines) {
43067
42479
  const edges = [];
43068
42480
  const alignments = [];
43069
42481
  let title;
43070
- let accessibilityTitle;
43071
- let accessibilityDescription;
42482
+ const accessibilityTitle = accessibility.accessibility.title === void 0 ? void 0 : normalizeBrTags(accessibility.accessibility.title);
42483
+ const accessibilityDescription = accessibility.accessibility.descr === void 0 ? void 0 : normalizeBrTags(accessibility.accessibility.descr);
43072
42484
  for (let i2 = 1; i2 < lines.length; i2++) {
43073
42485
  const line2 = lines[i2];
43074
42486
  const titleMatch = line2.match(/^title\s+(.+)$/i);
@@ -43076,35 +42488,6 @@ function parseArchitectureDiagram(lines) {
43076
42488
  title = normalizeBrTags(titleMatch[1].trim());
43077
42489
  continue;
43078
42490
  }
43079
- const accTitleMatch = line2.match(/^accTitle\s*:\s*(.+)$/i);
43080
- if (accTitleMatch) {
43081
- accessibilityTitle = normalizeBrTags(accTitleMatch[1].trim());
43082
- continue;
43083
- }
43084
- const accDescrBlockMatch = line2.match(/^accDescr\s*:?\s*\{\s*(.*)$/i);
43085
- if (accDescrBlockMatch) {
43086
- const blockLines = [];
43087
- if (accDescrBlockMatch[1].trim()) blockLines.push(accDescrBlockMatch[1].trim());
43088
- let closed = false;
43089
- for (i2++; i2 < lines.length; i2++) {
43090
- const blockLine = lines[i2];
43091
- if (blockLine.includes("}")) {
43092
- const before = blockLine.slice(0, blockLine.indexOf("}")).trim();
43093
- if (before) blockLines.push(before);
43094
- closed = true;
43095
- break;
43096
- }
43097
- blockLines.push(blockLine);
43098
- }
43099
- if (!closed) throw new Error('Unterminated accDescr block \u2014 missing closing "}"');
43100
- accessibilityDescription = normalizeBrTags(blockLines.join("\n").trim());
43101
- continue;
43102
- }
43103
- const accDescrMatch = line2.match(/^accDescr\s*:\s*(.+)$/i);
43104
- if (accDescrMatch) {
43105
- accessibilityDescription = normalizeBrTags(accDescrMatch[1].trim());
43106
- continue;
43107
- }
43108
42491
  const groupMatch = line2.match(GROUP_RE2);
43109
42492
  if (groupMatch) {
43110
42493
  const id = groupMatch[1];
@@ -52068,7 +51451,7 @@ function renderBody(body, kind, meta, parsedDescriptorIdentity) {
52068
51451
  const descriptorMatches = body.kind !== "extension" || sameExtensionIdentity(parsedDescriptorIdentity, plugin?.identity);
52069
51452
  if (plugin?.serialize && descriptorMatches) {
52070
51453
  const rendered2 = plugin.serialize(body);
52071
- return body.kind === "extension" ? rendered2 : ensureAccessibilityLines(rendered2, meta.accessibility);
51454
+ return ensureAccessibilityLines(rendered2, meta.accessibility);
52072
51455
  }
52073
51456
  if (body.kind === "extension") return body.source.endsWith("\n") ? body.source : body.source + "\n";
52074
51457
  throw new Error(`No serializer registered for diagram kind "${kind}"`);
@@ -52555,7 +51938,7 @@ var HOSTED_FONT_RESOURCES = Object.freeze(
52555
51938
  id: `resource:${fontResourceLocalId(face)}`,
52556
51939
  kind: "resource",
52557
51940
  version: "1.0.0",
52558
- compatibility: { core: "^0.1.1" },
51941
+ compatibility: { core: "^0.2.0" },
52559
51942
  provenance: { owner: "agentic-mermaid", source: "bundled", reference: `assets/fonts/${face.file}` }
52560
51943
  })
52561
51944
  }))
@@ -55889,7 +55272,7 @@ var RADAR_RENDER_HOOKS = {
55889
55272
  ), { injectAccessibility: false }),
55890
55273
  projectPositioned: positionedView(projectRadarPositioned),
55891
55274
  lowerScene: scene(lowerRadarScene),
55892
- renderAscii: (ctx) => renderRadarAscii(ctx.source.lines, ctx.config, ctx.colorMode, ctx.theme, ctx.source.frontmatter, ctx.options.targetWidth, ctx.styleFace)
55275
+ renderAscii: (ctx) => renderRadarAscii(ctx.source.familyLines, ctx.config, ctx.colorMode, ctx.theme, ctx.source.frontmatter, ctx.options.targetWidth, ctx.styleFace)
55893
55276
  };
55894
55277
  var GANTT_RENDER_HOOKS = {
55895
55278
  normalizeRequest: (ctx) => ({
@@ -56530,7 +55913,7 @@ function completeBuiltinDescriptor(seed) {
56530
55913
  id: `family:${seed.id}`,
56531
55914
  kind: "family",
56532
55915
  version: "1.0.0",
56533
- compatibility: { core: "^0.1.1" },
55916
+ compatibility: { core: "^0.2.0" },
56534
55917
  provenance: { owner: "agentic-mermaid", source: "built-in" }
56535
55918
  }),
56536
55919
  collisionPriority: 100,
@@ -57127,36 +56510,11 @@ function detectRegisteredFamilyFromFirstLine(firstLine, mode = "strict") {
57127
56510
  var FRONTMATTER_REGEX = /^\uFEFF?\s*---\s*\r?\n([\s\S]*?)\r?\n\s*---\s*(?:\r?\n|$)/;
57128
56511
  var INIT_DIRECTIVE_REGEX = /^\s*%%\{\s*(?:init|initialize)\s*:\s*([\s\S]*?)\}\s*%%\s*(?:\r?\n|$)?/gm;
57129
56512
  var COMMENT_LINE_REGEX = /^\s*%%(?!\{)\s*(.*)$/;
57130
- var ACC_TITLE_REGEX = /^\s*accTitle(?:\s*:\s*|\s+)(.+)$/i;
57131
- var ACC_DESCR_INLINE_REGEX = /^\s*accDescr(?:\s*:\s*|\s+)(.+)$/i;
57132
- var ACC_DESCR_BLOCK_START = /^\s*accDescr\s*:?\s*\{(.*)$/i;
57133
- function accessibilityDescriptionBlockAt(lines, startIndex) {
57134
- const opening = lines[startIndex].match(ACC_DESCR_BLOCK_START);
57135
- if (!opening) return void 0;
57136
- const parts = [];
57137
- for (let index = startIndex; index < lines.length; index++) {
57138
- const content = index === startIndex ? opening[1] : lines[index];
57139
- const closing = content.indexOf("}");
57140
- if (closing < 0) {
57141
- if (content.trim()) parts.push(content.trim());
57142
- continue;
57143
- }
57144
- const beforeClosing = content.slice(0, closing).trim();
57145
- if (beforeClosing) parts.push(beforeClosing);
57146
- const suffix = content.slice(closing + 1);
57147
- const indent = lines[index].match(/^\s*/)?.[0] ?? "";
57148
- return {
57149
- description: parts.join("\n").trim(),
57150
- endIndex: index,
57151
- ...suffix.trim() ? { suffixLine: indent + suffix.trimStart() } : {}
57152
- };
57153
- }
57154
- return null;
57155
- }
57156
56513
  function normalizeMermaidSource(text3, baseConfig = {}) {
57157
56514
  const processed = preprocessMermaidSource(text3, runtimeConfigToFrontmatterMap(baseConfig));
57158
- const envelope = sourceEnvelopeMetadata(text3);
57159
- const familyBody = withoutUniversalAccessibilityBody(processed.body);
56515
+ const accessibilityScan = scanAccessibilityDirectives(processed.body.split(/\r?\n/));
56516
+ const envelope = sourceEnvelopeMetadata(text3, accessibilityScan.accessibility);
56517
+ const familyBody = accessibilityScan.familyLines.join("\n");
57160
56518
  const familyLines = toMermaidLines(familyBody);
57161
56519
  return {
57162
56520
  originalText: text3,
@@ -57175,26 +56533,6 @@ function normalizeMermaidSource(text3, baseConfig = {}) {
57175
56533
  accessibility: envelope.accessibility
57176
56534
  };
57177
56535
  }
57178
- function withoutUniversalAccessibilityBody(body) {
57179
- const kept = [];
57180
- const lines = body.split(/\r?\n/);
57181
- for (let index = 0; index < lines.length; index++) {
57182
- const line2 = lines[index];
57183
- const block = accessibilityDescriptionBlockAt(lines, index);
57184
- if (block !== void 0) {
57185
- if (block === null) {
57186
- kept.push(...lines.slice(index));
57187
- break;
57188
- }
57189
- if (block.suffixLine) kept.push(block.suffixLine);
57190
- index = block.endIndex;
57191
- continue;
57192
- }
57193
- if (ACC_TITLE_REGEX.test(line2) || ACC_DESCR_INLINE_REGEX.test(line2)) continue;
57194
- kept.push(line2);
57195
- }
57196
- return kept.join("\n");
57197
- }
57198
56536
  function normalizeMermaidSourceWithOverrides(text3, overrides = {}) {
57199
56537
  const source = normalizeMermaidSource(text3);
57200
56538
  if (Object.keys(overrides).length === 0) return source;
@@ -57205,7 +56543,7 @@ function normalizeMermaidSourceWithOverrides(text3, overrides = {}) {
57205
56543
  config: normalizeMermaidRuntimeConfig(frontmatter)
57206
56544
  };
57207
56545
  }
57208
- function sourceEnvelopeMetadata(text3) {
56546
+ function sourceEnvelopeMetadata(text3, accessibility) {
57209
56547
  const frontmatter = text3.match(FRONTMATTER_REGEX);
57210
56548
  const frontmatterEnd = frontmatter?.[0].length ?? 0;
57211
56549
  const initDirectives = [];
@@ -57220,27 +56558,15 @@ function sourceEnvelopeMetadata(text3) {
57220
56558
  }
57221
56559
  const withoutUniversalConfig = text3.replace(FRONTMATTER_REGEX, "").replace(new RegExp(INIT_DIRECTIVE_REGEX.source, "gm"), "");
57222
56560
  const comments = [];
57223
- const accessibility = {};
57224
56561
  const lines = withoutUniversalConfig.split(/\r?\n/);
57225
56562
  for (let index = 0; index < lines.length; index++) {
57226
- const line2 = lines[index];
57227
- const block = accessibilityDescriptionBlockAt(lines, index);
57228
- if (block !== void 0) {
57229
- if (block === null) break;
57230
- accessibility.descr = block.description;
57231
- index = block.endIndex;
57232
- continue;
57233
- }
57234
- const title = line2.match(ACC_TITLE_REGEX);
57235
- if (title) {
57236
- accessibility.title = title[1].trim();
57237
- continue;
57238
- }
57239
- const description = line2.match(ACC_DESCR_INLINE_REGEX);
57240
- if (description) {
57241
- accessibility.descr = description[1].trim();
56563
+ const accessibility2 = parseAccessibilityDirective(lines, index);
56564
+ if (accessibility2 === void 0) break;
56565
+ if (accessibility2 !== null) {
56566
+ index = accessibility2.endIndex;
57242
56567
  continue;
57243
56568
  }
56569
+ const line2 = lines[index];
57244
56570
  const comment = line2.match(COMMENT_LINE_REGEX);
57245
56571
  if (comment) comments.push({ text: comment[1], line: index + 1 });
57246
56572
  }
@@ -62324,7 +61650,6 @@ async function renderMermaidSVGAsync(text3, options = {}) {
62324
61650
  }
62325
61651
 
62326
61652
  export {
62327
- __toESM,
62328
61653
  scanSvgStartTags,
62329
61654
  decodedSvgAttributeValue,
62330
61655
  toHex,
@@ -62348,7 +61673,7 @@ export {
62348
61673
  negotiateCapabilities,
62349
61674
  CORE_CAPABILITY_OFFERS,
62350
61675
  negotiateRenderCapabilities,
62351
- require_package,
61676
+ PACKAGE_VERSION,
62352
61677
  sameExtensionIdentity,
62353
61678
  KNOWN_EXTENSION_CONTRACT_VERSIONS,
62354
61679
  evaluateExtensionCompatibility,
@@ -62411,6 +61736,7 @@ export {
62411
61736
  measureMultilineText,
62412
61737
  normalizeBrTags,
62413
61738
  labelOverflowWarning,
61739
+ parseAccessibilityDirective,
62414
61740
  expandInlineNamespaceStatement,
62415
61741
  parseClassDeclaration,
62416
61742
  parseClassReference,
@@ -62634,4 +61960,4 @@ export {
62634
61960
  renderMermaidSVGWithReceipt,
62635
61961
  renderMermaidSVGAsync
62636
61962
  };
62637
- //# sourceMappingURL=chunk-ZYMMKQ3I.js.map
61963
+ //# sourceMappingURL=chunk-BJYMBT4I.js.map