schematex 0.9.4 → 0.9.6

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 (82) hide show
  1. package/README.md +45 -0
  2. package/dist/ai/ai-sdk.cjs +8 -8
  3. package/dist/ai/ai-sdk.d.cts +3 -3
  4. package/dist/ai/ai-sdk.d.ts +3 -3
  5. package/dist/ai/ai-sdk.js +3 -3
  6. package/dist/ai/index.cjs +17 -17
  7. package/dist/ai/index.d.cts +4 -4
  8. package/dist/ai/index.d.ts +4 -4
  9. package/dist/ai/index.js +4 -4
  10. package/dist/{api-1xoGiseb.d.cts → api-BOJJlNb1.d.ts} +2 -2
  11. package/dist/{api-CgXRSnCn.d.ts → api-v9t1T1v6.d.cts} +2 -2
  12. package/dist/browser.cjs +9 -9
  13. package/dist/browser.d.cts +3 -3
  14. package/dist/browser.d.ts +3 -3
  15. package/dist/browser.js +3 -3
  16. package/dist/{chunk-UFXDAIDD.js → chunk-4W75FGWO.js} +1714 -658
  17. package/dist/chunk-4W75FGWO.js.map +1 -0
  18. package/dist/{chunk-NIYB6CHH.js → chunk-CVTHUOAM.js} +265 -15
  19. package/dist/chunk-CVTHUOAM.js.map +1 -0
  20. package/dist/{chunk-TX3YWZZX.cjs → chunk-HX64QWB6.cjs} +267 -17
  21. package/dist/chunk-HX64QWB6.cjs.map +1 -0
  22. package/dist/{chunk-PFZKW3HE.js → chunk-II4GLKGF.js} +2 -2
  23. package/dist/chunk-II4GLKGF.js.map +1 -0
  24. package/dist/{chunk-GTCAJPQR.cjs → chunk-KH5GRKUM.cjs} +1715 -658
  25. package/dist/chunk-KH5GRKUM.cjs.map +1 -0
  26. package/dist/{chunk-WJXLF42K.cjs → chunk-N3HU635X.cjs} +2 -2
  27. package/dist/chunk-N3HU635X.cjs.map +1 -0
  28. package/dist/{diagnostics-CDwnQ65n.d.cts → diagnostics-5bVLlGNj.d.cts} +1 -1
  29. package/dist/{diagnostics-CDwnQ65n.d.ts → diagnostics-5bVLlGNj.d.ts} +1 -1
  30. package/dist/diagrams/blockdiagram/index.d.cts +1 -1
  31. package/dist/diagrams/blockdiagram/index.d.ts +1 -1
  32. package/dist/diagrams/circuit/index.d.cts +1 -1
  33. package/dist/diagrams/circuit/index.d.ts +1 -1
  34. package/dist/diagrams/ecomap/index.d.cts +1 -1
  35. package/dist/diagrams/ecomap/index.d.ts +1 -1
  36. package/dist/diagrams/entity/index.d.cts +1 -1
  37. package/dist/diagrams/entity/index.d.ts +1 -1
  38. package/dist/diagrams/fishbone/index.d.cts +1 -1
  39. package/dist/diagrams/fishbone/index.d.ts +1 -1
  40. package/dist/diagrams/flowchart/index.d.cts +2 -2
  41. package/dist/diagrams/flowchart/index.d.ts +2 -2
  42. package/dist/diagrams/genogram/index.d.cts +1 -1
  43. package/dist/diagrams/genogram/index.d.ts +1 -1
  44. package/dist/diagrams/ladder/index.d.cts +1 -1
  45. package/dist/diagrams/ladder/index.d.ts +1 -1
  46. package/dist/diagrams/logic/index.d.cts +1 -1
  47. package/dist/diagrams/logic/index.d.ts +1 -1
  48. package/dist/diagrams/orgchart/index.d.cts +1 -1
  49. package/dist/diagrams/orgchart/index.d.ts +1 -1
  50. package/dist/diagrams/pedigree/index.d.cts +1 -1
  51. package/dist/diagrams/pedigree/index.d.ts +1 -1
  52. package/dist/diagrams/phylo/index.d.cts +1 -1
  53. package/dist/diagrams/phylo/index.d.ts +1 -1
  54. package/dist/diagrams/sld/index.cjs +7 -7
  55. package/dist/diagrams/sld/index.d.cts +1 -1
  56. package/dist/diagrams/sld/index.d.ts +1 -1
  57. package/dist/diagrams/sld/index.js +1 -1
  58. package/dist/diagrams/sociogram/index.d.cts +1 -1
  59. package/dist/diagrams/sociogram/index.d.ts +1 -1
  60. package/dist/diagrams/timing/index.d.cts +1 -1
  61. package/dist/diagrams/timing/index.d.ts +1 -1
  62. package/dist/diagrams/venn/index.d.cts +1 -1
  63. package/dist/diagrams/venn/index.d.ts +1 -1
  64. package/dist/{index-DNOoLmYX.d.cts → index-Cmf4Rcve.d.cts} +1 -1
  65. package/dist/{index-CYSH3_ca.d.ts → index-syc0E5Ss.d.ts} +1 -1
  66. package/dist/index.cjs +41 -37
  67. package/dist/index.d.cts +7 -5
  68. package/dist/index.d.ts +7 -5
  69. package/dist/index.js +4 -4
  70. package/dist/react.cjs +3 -3
  71. package/dist/react.d.cts +2 -2
  72. package/dist/react.d.ts +2 -2
  73. package/dist/react.js +2 -2
  74. package/dist/{tools-CbYmQ3hH.d.cts → tools-B98iarLm.d.cts} +2 -2
  75. package/dist/{tools-BhTti-oG.d.ts → tools-CCZ1IcIN.d.ts} +2 -2
  76. package/package.json +1 -1
  77. package/dist/chunk-GTCAJPQR.cjs.map +0 -1
  78. package/dist/chunk-NIYB6CHH.js.map +0 -1
  79. package/dist/chunk-PFZKW3HE.js.map +0 -1
  80. package/dist/chunk-TX3YWZZX.cjs.map +0 -1
  81. package/dist/chunk-UFXDAIDD.js.map +0 -1
  82. package/dist/chunk-WJXLF42K.cjs.map +0 -1
@@ -2,7 +2,7 @@ import { orgchart } from './chunk-3J4DZPZC.js';
2
2
  import { circuit } from './chunk-RDYACU2G.js';
3
3
  import { blockdiagram } from './chunk-3PH2MQGN.js';
4
4
  import { ladder } from './chunk-B4CMWA6Y.js';
5
- import { sld } from './chunk-PFZKW3HE.js';
5
+ import { sld } from './chunk-II4GLKGF.js';
6
6
  import { entity } from './chunk-JEMAOC2D.js';
7
7
  import { fishbone } from './chunk-GYYYULBL.js';
8
8
  import { venn } from './chunk-SXOAAQNY.js';
@@ -2754,8 +2754,8 @@ function renderEras(layout, theme) {
2754
2754
  layout.eras.forEach((e, i) => {
2755
2755
  const l = leftmostOnRow.get(e.bandRow);
2756
2756
  if (l === void 0 || e.x < layout.eras[l].x) leftmostOnRow.set(e.bandRow, i);
2757
- const r6 = rightmostOnRow.get(e.bandRow);
2758
- if (r6 === void 0 || e.x + e.width > layout.eras[r6].x + layout.eras[r6].width) rightmostOnRow.set(e.bandRow, i);
2757
+ const r7 = rightmostOnRow.get(e.bandRow);
2758
+ if (r7 === void 0 || e.x + e.width > layout.eras[r7].x + layout.eras[r7].width) rightmostOnRow.set(e.bandRow, i);
2759
2759
  });
2760
2760
  const plotEnd = layout.plotX + layout.plotW;
2761
2761
  const items = layout.eras.map((e, i) => {
@@ -2881,20 +2881,20 @@ function renderSwimlanePoints(layout, theme) {
2881
2881
  function renderMarker(ev, color, shape, isMilestone) {
2882
2882
  const x = ev.x;
2883
2883
  const y = ev.y;
2884
- const r6 = isMilestone ? 8 : 5;
2884
+ const r7 = isMilestone ? 8 : 5;
2885
2885
  const klass = isMilestone ? "st-milestone" : "st-event-dot";
2886
2886
  switch (shape) {
2887
2887
  case "square":
2888
- return rect({ x: x - r6, y: y - r6, width: r6 * 2, height: r6 * 2, fill: color, class: klass, "data-event-id": ev.event.id });
2888
+ return rect({ x: x - r7, y: y - r7, width: r7 * 2, height: r7 * 2, fill: color, class: klass, "data-event-id": ev.event.id });
2889
2889
  case "diamond":
2890
- return path({ d: `M ${x},${y - r6} L ${x + r6},${y} L ${x},${y + r6} L ${x - r6},${y} Z`, fill: color, class: klass, "data-event-id": ev.event.id });
2890
+ return path({ d: `M ${x},${y - r7} L ${x + r7},${y} L ${x},${y + r7} L ${x - r7},${y} Z`, fill: color, class: klass, "data-event-id": ev.event.id });
2891
2891
  case "star":
2892
- return path({ d: starPath(x, y, r6 + 2, (r6 + 2) / 2.5, 5), fill: color, class: klass, "data-event-id": ev.event.id });
2892
+ return path({ d: starPath(x, y, r7 + 2, (r7 + 2) / 2.5, 5), fill: color, class: klass, "data-event-id": ev.event.id });
2893
2893
  case "flag":
2894
- return path({ d: `M ${x - r6},${y + r6} L ${x - r6},${y - r6 - 4} L ${x + r6 + 4},${y - r6 - 1} L ${x - r6},${y + 2}`, fill: color, class: klass, "data-event-id": ev.event.id });
2894
+ return path({ d: `M ${x - r7},${y + r7} L ${x - r7},${y - r7 - 4} L ${x + r7 + 4},${y - r7 - 1} L ${x - r7},${y + 2}`, fill: color, class: klass, "data-event-id": ev.event.id });
2895
2895
  case "circle":
2896
2896
  default:
2897
- return circle({ cx: x, cy: y, r: r6, fill: color, class: klass, "data-event-id": ev.event.id });
2897
+ return circle({ cx: x, cy: y, r: r7, fill: color, class: klass, "data-event-id": ev.event.id });
2898
2898
  }
2899
2899
  }
2900
2900
  function renderLabels(layout) {
@@ -3150,10 +3150,10 @@ function starPath(cx, cy, rOuter, rInner, points) {
3150
3150
  const step = Math.PI / points;
3151
3151
  let d = "";
3152
3152
  for (let i = 0; i < points * 2; i++) {
3153
- const r6 = i % 2 === 0 ? rOuter : rInner;
3153
+ const r7 = i % 2 === 0 ? rOuter : rInner;
3154
3154
  const a = i * step - Math.PI / 2;
3155
- const x = cx + r6 * Math.cos(a);
3156
- const y = cy + r6 * Math.sin(a);
3155
+ const x = cx + r7 * Math.cos(a);
3156
+ const y = cy + r7 * Math.sin(a);
3157
3157
  d += (i === 0 ? "M" : "L") + x.toFixed(2) + "," + y.toFixed(2) + " ";
3158
3158
  }
3159
3159
  return d + "Z";
@@ -3424,7 +3424,7 @@ function parseStateDiagram(src) {
3424
3424
  }
3425
3425
  ctxTop.regionMode = true;
3426
3426
  if (!parent.regions) parent.regions = [];
3427
- const lastIdx = parent.regions.reduce((s, r6) => s + r6.length, 0);
3427
+ const lastIdx = parent.regions.reduce((s, r7) => s + r7.length, 0);
3428
3428
  const slice = parent.children.slice(lastIdx);
3429
3429
  parent.regions.push(slice);
3430
3430
  i++;
@@ -3628,7 +3628,7 @@ function parseStateDiagram(src) {
3628
3628
  }
3629
3629
  function finalizeRegions(node) {
3630
3630
  if (node.regions) {
3631
- const consumed = node.regions.reduce((s, r6) => s + r6.length, 0);
3631
+ const consumed = node.regions.reduce((s, r7) => s + r7.length, 0);
3632
3632
  if (node.children.length > consumed) {
3633
3633
  node.regions.push(node.children.slice(consumed));
3634
3634
  }
@@ -4073,33 +4073,33 @@ function pointsToPath(pts) {
4073
4073
  const rest = pts.slice(1).map((p) => `L ${p.x} ${p.y}`).join(" ");
4074
4074
  return rest ? `${head} ${rest}` : head;
4075
4075
  }
4076
- function trimPathStart(d, cx, cy, r6) {
4076
+ function trimPathStart(d, cx, cy, r7) {
4077
4077
  const pts = parsePathPoints(d);
4078
4078
  if (!pts || pts.length < 2) return d;
4079
4079
  const p0 = pts[0];
4080
4080
  const p1 = pts[1];
4081
- const newP0 = projectOnPerimeter(p0, p1, cx, cy, r6);
4081
+ const newP0 = projectOnPerimeter(p0, p1, cx, cy, r7);
4082
4082
  pts[0] = newP0;
4083
4083
  return pointsToPath(pts);
4084
4084
  }
4085
- function trimPathEnd(d, cx, cy, r6) {
4085
+ function trimPathEnd(d, cx, cy, r7) {
4086
4086
  const pts = parsePathPoints(d);
4087
4087
  if (!pts || pts.length < 2) return d;
4088
4088
  const last = pts[pts.length - 1];
4089
4089
  const prev = pts[pts.length - 2];
4090
- const newLast = projectOnPerimeter(last, prev, cx, cy, r6);
4090
+ const newLast = projectOnPerimeter(last, prev, cx, cy, r7);
4091
4091
  pts[pts.length - 1] = newLast;
4092
4092
  return pointsToPath(pts);
4093
4093
  }
4094
- function projectOnPerimeter(endpoint, neighbor, cx, cy, r6) {
4094
+ function projectOnPerimeter(endpoint, neighbor, cx, cy, r7) {
4095
4095
  const dx = endpoint.x - neighbor.x;
4096
4096
  const dy = endpoint.y - neighbor.y;
4097
4097
  if (Math.abs(dx) > Math.abs(dy)) {
4098
4098
  const sign2 = dx >= 0 ? 1 : -1;
4099
- return { x: cx - sign2 * r6, y: cy };
4099
+ return { x: cx - sign2 * r7, y: cy };
4100
4100
  }
4101
4101
  const sign = dy >= 0 ? 1 : -1;
4102
- return { x: cx, y: cy - sign * r6 };
4102
+ return { x: cx, y: cy - sign * r7 };
4103
4103
  }
4104
4104
  function shiftPathX(d, dx) {
4105
4105
  return d.replace(/([MLCQ])\s*((?:-?\d+(?:\.\d+)?\s+){1,5}-?\d+(?:\.\d+)?)/g, (_, cmd, args) => {
@@ -4277,12 +4277,12 @@ function renderPseudo(node) {
4277
4277
  ]
4278
4278
  );
4279
4279
  case "choice": {
4280
- const r6 = 14;
4280
+ const r7 = 14;
4281
4281
  return group(
4282
4282
  { class: "lt-state lt-pseudo", "data-id": node.id, "data-kind": "choice" },
4283
4283
  [
4284
4284
  polygon({
4285
- points: `${cx},${cy - r6} ${cx + r6},${cy} ${cx},${cy + r6} ${cx - r6},${cy}`,
4285
+ points: `${cx},${cy - r7} ${cx + r7},${cy} ${cx},${cy + r7} ${cx - r7},${cy}`,
4286
4286
  class: "lt-ps-choice"
4287
4287
  })
4288
4288
  ]
@@ -5280,27 +5280,27 @@ function renderEquip(type, label, rawType) {
5280
5280
  ]);
5281
5281
  }
5282
5282
  case "pump_centrifugal": {
5283
- const r6 = 22;
5283
+ const r7 = 22;
5284
5284
  return group({}, [
5285
- circle({ cx: 0, cy: 0, r: r6, class: "lt-pid-equip" }),
5285
+ circle({ cx: 0, cy: 0, r: r7, class: "lt-pid-equip" }),
5286
5286
  polygon({
5287
- points: `${r6 * 0.4},${-r6 * 0.9} ${r6 + 6},${-r6 * 0.9} ${r6 * 0.4},${0}`,
5287
+ points: `${r7 * 0.4},${-r7 * 0.9} ${r7 + 6},${-r7 * 0.9} ${r7 * 0.4},${0}`,
5288
5288
  class: "lt-pid-equip"
5289
5289
  }),
5290
5290
  text(
5291
- { x: 0, y: r6 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" },
5291
+ { x: 0, y: r7 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" },
5292
5292
  label
5293
5293
  )
5294
5294
  ]);
5295
5295
  }
5296
5296
  case "pump_pd": {
5297
- const r6 = 22;
5297
+ const r7 = 22;
5298
5298
  return group({}, [
5299
- circle({ cx: 0, cy: 0, r: r6, class: "lt-pid-equip" }),
5299
+ circle({ cx: 0, cy: 0, r: r7, class: "lt-pid-equip" }),
5300
5300
  circle({ cx: -8, cy: 0, r: 6, class: "lt-pid-tray-line", fill: "none" }),
5301
5301
  circle({ cx: 8, cy: 0, r: 6, class: "lt-pid-tray-line", fill: "none" }),
5302
5302
  text(
5303
- { x: 0, y: r6 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" },
5303
+ { x: 0, y: r7 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" },
5304
5304
  label
5305
5305
  )
5306
5306
  ]);
@@ -5315,14 +5315,14 @@ function renderEquip(type, label, rawType) {
5315
5315
  ]);
5316
5316
  }
5317
5317
  case "blower": {
5318
- const r6 = 22;
5318
+ const r7 = 22;
5319
5319
  return group({}, [
5320
- circle({ cx: 0, cy: 0, r: r6, class: "lt-pid-equip" }),
5320
+ circle({ cx: 0, cy: 0, r: r7, class: "lt-pid-equip" }),
5321
5321
  path({
5322
- d: `M 0 0 L ${r6 * 0.8} ${-r6 * 0.5} M 0 0 L ${-r6 * 0.6} ${-r6 * 0.6} M 0 0 L 0 ${r6 * 0.8}`,
5322
+ d: `M 0 0 L ${r7 * 0.8} ${-r7 * 0.5} M 0 0 L ${-r7 * 0.6} ${-r7 * 0.6} M 0 0 L 0 ${r7 * 0.8}`,
5323
5323
  class: "lt-pid-tray-line"
5324
5324
  }),
5325
- text({ x: 0, y: r6 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" }, label)
5325
+ text({ x: 0, y: r7 + 14, "text-anchor": "middle", class: "lt-pid-equip-tag" }, label)
5326
5326
  ]);
5327
5327
  }
5328
5328
  case "reactor_cstr": {
@@ -5498,7 +5498,7 @@ function renderEquip(type, label, rawType) {
5498
5498
  }
5499
5499
  }
5500
5500
  function renderInstrument(category, letterCode, loopNumber) {
5501
- const r6 = 14;
5501
+ const r7 = 14;
5502
5502
  const isComputer = category.endsWith("computer");
5503
5503
  const isPlc = category.endsWith("plc");
5504
5504
  const isShared = category.endsWith("shared");
@@ -5506,17 +5506,17 @@ function renderInstrument(category, letterCode, loopNumber) {
5506
5506
  const isLocal = category.startsWith("local_");
5507
5507
  const parts = [];
5508
5508
  if (isComputer) {
5509
- parts.push(circle({ cx: 0, cy: 0, r: r6, class: "lt-inst-body" }));
5509
+ parts.push(circle({ cx: 0, cy: 0, r: r7, class: "lt-inst-body" }));
5510
5510
  parts.push(
5511
5511
  polygon({
5512
- points: `0,${-r6 + 1} ${r6 - 1},0 0,${r6 - 1} ${ -13},0`,
5512
+ points: `0,${-r7 + 1} ${r7 - 1},0 0,${r7 - 1} ${ -13},0`,
5513
5513
  class: "lt-inst-body",
5514
5514
  fill: "none"
5515
5515
  })
5516
5516
  );
5517
5517
  } else if (isPlc) {
5518
- parts.push(circle({ cx: 0, cy: 0, r: r6, class: "lt-inst-body" }));
5519
- const side = r6 * Math.SQRT1_2 * 2 - 2;
5518
+ parts.push(circle({ cx: 0, cy: 0, r: r7, class: "lt-inst-body" }));
5519
+ const side = r7 * Math.SQRT1_2 * 2 - 2;
5520
5520
  parts.push(
5521
5521
  rect({
5522
5522
  x: -side / 2,
@@ -5528,11 +5528,11 @@ function renderInstrument(category, letterCode, loopNumber) {
5528
5528
  })
5529
5529
  );
5530
5530
  } else if (isShared) {
5531
- parts.push(circle({ cx: 0, cy: 0, r: r6, class: "lt-inst-body" }));
5531
+ parts.push(circle({ cx: 0, cy: 0, r: r7, class: "lt-inst-body" }));
5532
5532
  const hex = [];
5533
5533
  for (let i = 0; i < 6; i++) {
5534
5534
  const a = Math.PI / 3 * i - Math.PI / 2;
5535
- hex.push(`${(r6 - 2) * Math.cos(a)},${(r6 - 2) * Math.sin(a)}`);
5535
+ hex.push(`${(r7 - 2) * Math.cos(a)},${(r7 - 2) * Math.sin(a)}`);
5536
5536
  }
5537
5537
  parts.push(
5538
5538
  polygon({
@@ -5542,12 +5542,12 @@ function renderInstrument(category, letterCode, loopNumber) {
5542
5542
  })
5543
5543
  );
5544
5544
  } else {
5545
- parts.push(circle({ cx: 0, cy: 0, r: r6, class: "lt-inst-body" }));
5545
+ parts.push(circle({ cx: 0, cy: 0, r: r7, class: "lt-inst-body" }));
5546
5546
  }
5547
5547
  if (isControlRoom) {
5548
- parts.push(line({ x1: -r6, y1: 0, x2: r6, y2: 0, class: "lt-inst-cr-line" }));
5548
+ parts.push(line({ x1: -r7, y1: 0, x2: r7, y2: 0, class: "lt-inst-cr-line" }));
5549
5549
  } else if (isLocal) {
5550
- parts.push(line({ x1: -r6, y1: 0, x2: r6, y2: 0, class: "lt-inst-local-line" }));
5550
+ parts.push(line({ x1: -r7, y1: 0, x2: r7, y2: 0, class: "lt-inst-local-line" }));
5551
5551
  }
5552
5552
  parts.push(
5553
5553
  text(
@@ -6299,19 +6299,19 @@ function readScalar(map, key) {
6299
6299
  return { value, line: entry.header.line };
6300
6300
  }
6301
6301
  function readInt(map, key) {
6302
- const r6 = readScalar(map, key);
6303
- if (r6 === void 0) return void 0;
6304
- return parseInt10(r6.value, r6.line);
6302
+ const r7 = readScalar(map, key);
6303
+ if (r7 === void 0) return void 0;
6304
+ return parseInt10(r7.value, r7.line);
6305
6305
  }
6306
6306
  function readSources(map, key) {
6307
- const r6 = readScalar(map, key);
6308
- if (r6 === void 0) return void 0;
6309
- return parsePairs(r6.value, r6.line);
6307
+ const r7 = readScalar(map, key);
6308
+ if (r7 === void 0) return void 0;
6309
+ return parsePairs(r7.value, r7.line);
6310
6310
  }
6311
6311
  function readReasons(map, key) {
6312
- const r6 = readScalar(map, key);
6313
- if (r6 === void 0) return void 0;
6314
- return parsePairs(r6.value, r6.line);
6312
+ const r7 = readScalar(map, key);
6313
+ if (r7 === void 0) return void 0;
6314
+ return parsePairs(r7.value, r7.line);
6315
6315
  }
6316
6316
  function readBlock(map, key) {
6317
6317
  const entry = map.get(key);
@@ -6639,7 +6639,7 @@ function runArithmeticValidation(ast) {
6639
6639
  }
6640
6640
  }
6641
6641
  if (ast.screening.excluded.reasons && ast.screening.excluded.reasons.length > 0) {
6642
- const sum = ast.screening.excluded.reasons.reduce((a, r6) => a + r6.count, 0);
6642
+ const sum = ast.screening.excluded.reasons.reduce((a, r7) => a + r7.count, 0);
6643
6643
  if (sum !== screenedExcluded) {
6644
6644
  issues.push(
6645
6645
  `screening.excluded reasons sum to ${formatN(sum)} but n = ${formatN(screenedExcluded)}`
@@ -6647,7 +6647,7 @@ function runArithmeticValidation(ast) {
6647
6647
  }
6648
6648
  }
6649
6649
  if (ast.eligibility.excluded.reasons && ast.eligibility.excluded.reasons.length > 0) {
6650
- const sum = ast.eligibility.excluded.reasons.reduce((a, r6) => a + r6.count, 0);
6650
+ const sum = ast.eligibility.excluded.reasons.reduce((a, r7) => a + r7.count, 0);
6651
6651
  if (sum !== eligExcluded) {
6652
6652
  issues.push(
6653
6653
  `eligibility.excluded reasons sum to ${formatN(sum)} but n = ${formatN(eligExcluded)}`
@@ -6740,7 +6740,7 @@ function aggregateReasons(reasons) {
6740
6740
  const sorted = [...reasons].sort((a, b) => b.count - a.count);
6741
6741
  const head = sorted.slice(0, PRISMA_CONST.MAX_REASON_LINES - 1);
6742
6742
  const tail = sorted.slice(PRISMA_CONST.MAX_REASON_LINES - 1);
6743
- const otherSum = tail.reduce((a, r6) => a + r6.count, 0);
6743
+ const otherSum = tail.reduce((a, r7) => a + r7.count, 0);
6744
6744
  return {
6745
6745
  lines: [...head, { name: `Other (${tail.length} reasons)`, count: otherSum }],
6746
6746
  truncated: tail.length
@@ -6797,8 +6797,8 @@ function buildIdentificationRemovedBox(id, kind) {
6797
6797
  }
6798
6798
  if (removed.length === 0) return null;
6799
6799
  const lines = [{ text: v.recordsRemovedLabel, style: "label" }];
6800
- for (const r6 of removed) {
6801
- lines.push({ text: r6, style: "reason", indent: 1 });
6800
+ for (const r7 of removed) {
6801
+ lines.push({ text: r7, style: "reason", indent: 1 });
6802
6802
  }
6803
6803
  return {
6804
6804
  role: "id-removed",
@@ -6854,8 +6854,8 @@ function buildScreeningExcludedBox(n, reasons, kind) {
6854
6854
  { text: v.recordsExcluded, style: "label" },
6855
6855
  { text: `n = ${nFmt(n)}`, style: "count" }
6856
6856
  ];
6857
- for (const r6 of items) {
6858
- out.push({ text: `${r6.name} (n = ${nFmt(r6.count)})`, style: "reason", indent: 1 });
6857
+ for (const r7 of items) {
6858
+ out.push({ text: `${r7.name} (n = ${nFmt(r7.count)})`, style: "reason", indent: 1 });
6859
6859
  }
6860
6860
  return {
6861
6861
  role: "screening-excluded",
@@ -6885,8 +6885,8 @@ function buildEligibilityExcludedBox(n, reasons, kind) {
6885
6885
  { text: v.reportsExcluded, style: "label" },
6886
6886
  { text: `n = ${nFmt(n)}`, style: "count" }
6887
6887
  ];
6888
- for (const r6 of items) {
6889
- out.push({ text: `${r6.name} (n = ${nFmt(r6.count)})`, style: "reason", indent: 1 });
6888
+ for (const r7 of items) {
6889
+ out.push({ text: `${r7.name} (n = ${nFmt(r7.count)})`, style: "reason", indent: 1 });
6890
6890
  }
6891
6891
  return {
6892
6892
  role: "eligibility-excluded",
@@ -7487,7 +7487,7 @@ function classForEdge(kind) {
7487
7487
  }
7488
7488
  }
7489
7489
  function renderBand(band) {
7490
- const r6 = rect({
7490
+ const r7 = rect({
7491
7491
  x: band.x,
7492
7492
  y: band.y,
7493
7493
  width: band.width,
@@ -7510,10 +7510,10 @@ function renderBand(band) {
7510
7510
  },
7511
7511
  band.label
7512
7512
  );
7513
- return group({ "data-band": band.stage }, [r6, txt]);
7513
+ return group({ "data-band": band.stage }, [r7, txt]);
7514
7514
  }
7515
7515
  function renderHeader(h) {
7516
- const r6 = rect({
7516
+ const r7 = rect({
7517
7517
  x: h.x,
7518
7518
  y: h.y,
7519
7519
  width: h.width,
@@ -7538,10 +7538,10 @@ function renderHeader(h) {
7538
7538
  ln
7539
7539
  )
7540
7540
  );
7541
- return group({ "data-header": h.column }, [r6, ...lines]);
7541
+ return group({ "data-header": h.column }, [r7, ...lines]);
7542
7542
  }
7543
7543
  function renderBox(box2) {
7544
- const r6 = rect({
7544
+ const r7 = rect({
7545
7545
  x: box2.x,
7546
7546
  y: box2.y,
7547
7547
  width: box2.width,
@@ -7599,7 +7599,7 @@ function renderBox(box2) {
7599
7599
  "data-prisma-variant": box2.variant,
7600
7600
  "data-prisma-stage": box2.stage
7601
7601
  },
7602
- [r6, ...textEls]
7602
+ [r7, ...textEls]
7603
7603
  );
7604
7604
  }
7605
7605
  function approxLineWidth(line2) {
@@ -8308,14 +8308,14 @@ function sizeEllipse(uc) {
8308
8308
  }
8309
8309
  function buildDeepEdges(ast, ucIds) {
8310
8310
  const edges = [];
8311
- for (const r6 of ast.relations) {
8312
- if (!ucIds.has(r6.source) || !ucIds.has(r6.target)) continue;
8313
- if (r6.kind === "include") {
8314
- edges.push({ from: r6.source, to: r6.target });
8315
- } else if (r6.kind === "extend") {
8316
- edges.push({ from: r6.target, to: r6.source });
8317
- } else if (r6.kind === "generalization") {
8318
- edges.push({ from: r6.source, to: r6.target });
8311
+ for (const r7 of ast.relations) {
8312
+ if (!ucIds.has(r7.source) || !ucIds.has(r7.target)) continue;
8313
+ if (r7.kind === "include") {
8314
+ edges.push({ from: r7.source, to: r7.target });
8315
+ } else if (r7.kind === "extend") {
8316
+ edges.push({ from: r7.target, to: r7.source });
8317
+ } else if (r7.kind === "generalization") {
8318
+ edges.push({ from: r7.source, to: r7.target });
8319
8319
  }
8320
8320
  }
8321
8321
  return edges;
@@ -8343,15 +8343,15 @@ function classifyActorSides(ast) {
8343
8343
  ast.actors.forEach((a, i) => idx.set(a.id, i));
8344
8344
  const parent = /* @__PURE__ */ new Map();
8345
8345
  const find = (x) => {
8346
- let r6 = x;
8347
- while ((parent.get(r6) ?? r6) !== r6) r6 = parent.get(r6) ?? r6;
8346
+ let r7 = x;
8347
+ while ((parent.get(r7) ?? r7) !== r7) r7 = parent.get(r7) ?? r7;
8348
8348
  let c = x;
8349
8349
  while ((parent.get(c) ?? c) !== c) {
8350
8350
  const next = parent.get(c) ?? c;
8351
- parent.set(c, r6);
8351
+ parent.set(c, r7);
8352
8352
  c = next;
8353
8353
  }
8354
- return r6;
8354
+ return r7;
8355
8355
  };
8356
8356
  const union = (a, b) => {
8357
8357
  const ra = find(a);
@@ -8361,9 +8361,9 @@ function classifyActorSides(ast) {
8361
8361
  else parent.set(ra, rb);
8362
8362
  };
8363
8363
  for (const a of ast.actors) parent.set(a.id, a.id);
8364
- for (const r6 of ast.relations) {
8365
- if (r6.kind === "generalization" && actorIds.has(r6.source) && actorIds.has(r6.target)) {
8366
- union(r6.source, r6.target);
8364
+ for (const r7 of ast.relations) {
8365
+ if (r7.kind === "generalization" && actorIds.has(r7.source) && actorIds.has(r7.target)) {
8366
+ union(r7.source, r7.target);
8367
8367
  }
8368
8368
  }
8369
8369
  const baseSide = (a, i) => a.side === "left" ? "left" : a.side === "right" ? "right" : i === 0 ? "left" : "right";
@@ -8398,10 +8398,10 @@ function layoutUsecase(ast) {
8398
8398
  const sides = classifyActorSides(ast);
8399
8399
  const connectedActors = /* @__PURE__ */ new Map();
8400
8400
  for (const u of ast.usecases) connectedActors.set(u.id, []);
8401
- for (const r6 of ast.relations) {
8402
- if (r6.kind !== "association" && r6.kind !== "directed") continue;
8403
- const aId = actorById.has(r6.source) ? r6.source : actorById.has(r6.target) ? r6.target : null;
8404
- const uId = ucIds.has(r6.source) ? r6.source : ucIds.has(r6.target) ? r6.target : null;
8401
+ for (const r7 of ast.relations) {
8402
+ if (r7.kind !== "association" && r7.kind !== "directed") continue;
8403
+ const aId = actorById.has(r7.source) ? r7.source : actorById.has(r7.target) ? r7.target : null;
8404
+ const uId = ucIds.has(r7.source) ? r7.source : ucIds.has(r7.target) ? r7.target : null;
8405
8405
  if (aId && uId) connectedActors.get(uId).push(aId);
8406
8406
  }
8407
8407
  const columns = [];
@@ -8440,10 +8440,10 @@ function layoutUsecase(ast) {
8440
8440
  });
8441
8441
  let prev = -Infinity;
8442
8442
  for (const u of col) {
8443
- let r6 = rowPos.get(u.id);
8444
- if (r6 <= prev) r6 = prev + 1;
8445
- rowPos.set(u.id, r6);
8446
- prev = r6;
8443
+ let r7 = rowPos.get(u.id);
8444
+ if (r7 <= prev) r7 = prev + 1;
8445
+ rowPos.set(u.id, r7);
8446
+ prev = r7;
8447
8447
  }
8448
8448
  }
8449
8449
  const colMaxRx = columns.map(
@@ -8589,10 +8589,10 @@ function layoutUsecase(ast) {
8589
8589
  const edges = [];
8590
8590
  const trees = [];
8591
8591
  const genByParent = /* @__PURE__ */ new Map();
8592
- for (const r6 of ast.relations) {
8593
- if (r6.kind !== "generalization") continue;
8594
- if (!genByParent.has(r6.target)) genByParent.set(r6.target, []);
8595
- genByParent.get(r6.target).push(r6);
8592
+ for (const r7 of ast.relations) {
8593
+ if (r7.kind !== "generalization") continue;
8594
+ if (!genByParent.has(r7.target)) genByParent.set(r7.target, []);
8595
+ genByParent.get(r7.target).push(r7);
8596
8596
  }
8597
8597
  const handledGen = /* @__PURE__ */ new Set();
8598
8598
  function nodeCenter(id) {
@@ -8626,11 +8626,11 @@ function layoutUsecase(ast) {
8626
8626
  }
8627
8627
  for (const [parentId, rels] of genByParent) {
8628
8628
  const useTree = ast.generalizationTree && rels.length >= C2.GEN_TREE_THRESHOLD;
8629
- const allActors = actorById2.has(parentId) && rels.every((r6) => actorById2.has(r6.source));
8629
+ const allActors = actorById2.has(parentId) && rels.every((r7) => actorById2.has(r7.source));
8630
8630
  if (allActors) {
8631
8631
  const side = sides.get(parentId) ?? "left";
8632
8632
  const pAnchor = actorGenAnchor(parentId, side);
8633
- const childAnchors = rels.map((r6) => ({ r: r6, p: actorGenAnchor(r6.source, side) }));
8633
+ const childAnchors = rels.map((r7) => ({ r: r7, p: actorGenAnchor(r7.source, side) }));
8634
8634
  const xs = [pAnchor.x, ...childAnchors.map((c) => c.p.x)];
8635
8635
  const ys = [pAnchor.y, ...childAnchors.map((c) => c.p.y)];
8636
8636
  const busX = side === "left" ? Math.min(...xs) - 20 : Math.max(...xs) + 20;
@@ -8646,7 +8646,7 @@ function layoutUsecase(ast) {
8646
8646
  }
8647
8647
  trees.push({
8648
8648
  parentId,
8649
- childIds: rels.map((r6) => r6.source),
8649
+ childIds: rels.map((r7) => r7.source),
8650
8650
  stemX: busX,
8651
8651
  stemTop: minY2,
8652
8652
  stemBottom: maxY2,
@@ -8669,7 +8669,7 @@ function layoutUsecase(ast) {
8669
8669
  if (!useTree) continue;
8670
8670
  const parent = nodeCenter(parentId);
8671
8671
  if (!parent) continue;
8672
- const childCenters = rels.map((r6) => nodeCenter(r6.source)).filter((c) => c !== null);
8672
+ const childCenters = rels.map((r7) => nodeCenter(r7.source)).filter((c) => c !== null);
8673
8673
  if (childCenters.length === 0) continue;
8674
8674
  const avgX = childCenters.reduce((s, c) => s + c.cx, 0) / childCenters.length;
8675
8675
  const avgY = childCenters.reduce((s, c) => s + c.cy, 0) / childCenters.length;
@@ -8680,14 +8680,14 @@ function layoutUsecase(ast) {
8680
8680
  const jx = pPt.x + dirX / len * C2.GEN_JUNCTION_OFFSET;
8681
8681
  const jy = pPt.y + dirY / len * C2.GEN_JUNCTION_OFFSET;
8682
8682
  const legPaths = [];
8683
- for (const r6 of rels) {
8684
- const cPt = perimeter(r6.source, jx, jy);
8683
+ for (const r7 of rels) {
8684
+ const cPt = perimeter(r7.source, jx, jy);
8685
8685
  legPaths.push(`M ${round3(cPt.x)} ${round3(cPt.y)} L ${round3(jx)} ${round3(jy)}`);
8686
- handledGen.add(r6);
8686
+ handledGen.add(r7);
8687
8687
  }
8688
8688
  trees.push({
8689
8689
  parentId,
8690
- childIds: rels.map((r6) => r6.source),
8690
+ childIds: rels.map((r7) => r7.source),
8691
8691
  stemX: jx,
8692
8692
  stemTop: jy,
8693
8693
  stemBottom: jy,
@@ -8695,72 +8695,72 @@ function layoutUsecase(ast) {
8695
8695
  legPaths
8696
8696
  });
8697
8697
  }
8698
- for (const r6 of ast.relations) {
8699
- if (handledGen.has(r6)) continue;
8700
- const a = nodeCenter(r6.source);
8701
- const b = nodeCenter(r6.target);
8698
+ for (const r7 of ast.relations) {
8699
+ if (handledGen.has(r7)) continue;
8700
+ const a = nodeCenter(r7.source);
8701
+ const b = nodeCenter(r7.target);
8702
8702
  if (!a || !b) continue;
8703
- if (r6.kind === "generalization" && actorById2.has(r6.source) && actorById2.has(r6.target)) {
8704
- const side = sides.get(r6.target) ?? "left";
8705
- const pAnchor = actorGenAnchor(r6.target, side);
8706
- const cAnchor = actorGenAnchor(r6.source, side);
8703
+ if (r7.kind === "generalization" && actorById2.has(r7.source) && actorById2.has(r7.target)) {
8704
+ const side = sides.get(r7.target) ?? "left";
8705
+ const pAnchor = actorGenAnchor(r7.target, side);
8706
+ const cAnchor = actorGenAnchor(r7.source, side);
8707
8707
  const busX = side === "left" ? Math.min(pAnchor.x, cAnchor.x) - 20 : Math.max(pAnchor.x, cAnchor.x) + 20;
8708
8708
  edges.push({
8709
- relation: r6,
8709
+ relation: r7,
8710
8710
  d: `M ${round3(cAnchor.x)} ${round3(cAnchor.y)} L ${round3(busX)} ${round3(cAnchor.y)} L ${round3(busX)} ${round3(pAnchor.y)} L ${round3(pAnchor.x)} ${round3(pAnchor.y)}`,
8711
8711
  arrowKind: "hollow",
8712
8712
  dashed: false
8713
8713
  });
8714
8714
  continue;
8715
8715
  }
8716
- const srcActor = actorById2.get(r6.source);
8717
- const tgtActor = actorById2.get(r6.target);
8716
+ const srcActor = actorById2.get(r7.source);
8717
+ const tgtActor = actorById2.get(r7.target);
8718
8718
  let pa;
8719
8719
  let pb;
8720
8720
  if (srcActor && !tgtActor) {
8721
8721
  pa = { x: srcActor.anchorX, y: srcActor.anchorY };
8722
- pb = perimeter(r6.target, pa.x, pa.y);
8722
+ pb = perimeter(r7.target, pa.x, pa.y);
8723
8723
  } else if (tgtActor && !srcActor) {
8724
8724
  pb = { x: tgtActor.anchorX, y: tgtActor.anchorY };
8725
- pa = perimeter(r6.source, pb.x, pb.y);
8725
+ pa = perimeter(r7.source, pb.x, pb.y);
8726
8726
  } else {
8727
- pa = perimeter(r6.source, b.cx, b.cy);
8728
- pb = perimeter(r6.target, a.cx, a.cy);
8727
+ pa = perimeter(r7.source, b.cx, b.cy);
8728
+ pb = perimeter(r7.target, a.cx, a.cy);
8729
8729
  }
8730
- const dashed = r6.kind === "include" || r6.kind === "extend";
8730
+ const dashed = r7.kind === "include" || r7.kind === "extend";
8731
8731
  let arrowKind2 = "none";
8732
- if (r6.kind === "directed" || r6.kind === "include" || r6.kind === "extend") arrowKind2 = "open";
8733
- else if (r6.kind === "generalization") arrowKind2 = "hollow";
8732
+ if (r7.kind === "directed" || r7.kind === "include" || r7.kind === "extend") arrowKind2 = "open";
8733
+ else if (r7.kind === "generalization") arrowKind2 = "hollow";
8734
8734
  const edge = {
8735
- relation: r6,
8735
+ relation: r7,
8736
8736
  d: `M ${round3(pa.x)} ${round3(pa.y)} L ${round3(pb.x)} ${round3(pb.y)}`,
8737
8737
  arrowKind: arrowKind2,
8738
8738
  dashed
8739
8739
  };
8740
- if (r6.kind === "include" || r6.kind === "extend") {
8740
+ if (r7.kind === "include" || r7.kind === "extend") {
8741
8741
  const rows = [];
8742
- const keyword = r6.kind === "include" ? "include" : "extend";
8743
- rows.push(`\xAB${r6.stereotype ?? keyword}\xBB`);
8744
- if (r6.condition) rows.push(`[${r6.condition}]`);
8745
- if (r6.extensionPointRef) rows.push(`(extension point: ${r6.extensionPointRef})`);
8742
+ const keyword = r7.kind === "include" ? "include" : "extend";
8743
+ rows.push(`\xAB${r7.stereotype ?? keyword}\xBB`);
8744
+ if (r7.condition) rows.push(`[${r7.condition}]`);
8745
+ if (r7.extensionPointRef) rows.push(`(extension point: ${r7.extensionPointRef})`);
8746
8746
  const label = {
8747
8747
  rows,
8748
8748
  cx: (pa.x + pb.x) / 2,
8749
8749
  cy: (pa.y + pb.y) / 2
8750
8750
  };
8751
8751
  edge.label = label;
8752
- } else if ((r6.kind === "association" || r6.kind === "directed") && r6.stereotype) {
8752
+ } else if ((r7.kind === "association" || r7.kind === "directed") && r7.stereotype) {
8753
8753
  edge.label = {
8754
- rows: [`\xAB${r6.stereotype}\xBB`],
8754
+ rows: [`\xAB${r7.stereotype}\xBB`],
8755
8755
  cx: (pa.x + pb.x) / 2,
8756
8756
  cy: (pa.y + pb.y) / 2
8757
8757
  };
8758
8758
  }
8759
- if (r6.sourceMultiplicity) {
8760
- edge.multiplicityFrom = placeMultiplicity(pa, pb, r6.sourceMultiplicity);
8759
+ if (r7.sourceMultiplicity) {
8760
+ edge.multiplicityFrom = placeMultiplicity(pa, pb, r7.sourceMultiplicity);
8761
8761
  }
8762
- if (r6.targetMultiplicity) {
8763
- edge.multiplicityTo = placeMultiplicity(pb, pa, r6.targetMultiplicity);
8762
+ if (r7.targetMultiplicity) {
8763
+ edge.multiplicityTo = placeMultiplicity(pb, pa, r7.targetMultiplicity);
8764
8764
  }
8765
8765
  edges.push(edge);
8766
8766
  }
@@ -9015,7 +9015,7 @@ function renderEdgeLabel(e) {
9015
9015
  const rows = e.label.rows;
9016
9016
  const lineH = 12;
9017
9017
  const totalH = rows.length * lineH;
9018
- const widest = rows.reduce((m, r6) => Math.max(m, r6.length), 0);
9018
+ const widest = rows.reduce((m, r7) => Math.max(m, r7.length), 0);
9019
9019
  const pillW = widest * 6 + 8;
9020
9020
  const pillH = totalH + 4;
9021
9021
  const startY = e.label.cy - totalH / 2 + 9;
@@ -9031,7 +9031,7 @@ function renderEdgeLabel(e) {
9031
9031
  ry: 4
9032
9032
  })
9033
9033
  ];
9034
- rows.forEach((r6, i) => {
9034
+ rows.forEach((r7, i) => {
9035
9035
  parts.push(
9036
9036
  text(
9037
9037
  {
@@ -9040,7 +9040,7 @@ function renderEdgeLabel(e) {
9040
9040
  y: startY + i * lineH,
9041
9041
  "text-anchor": "middle"
9042
9042
  },
9043
- r6
9043
+ r7
9044
9044
  )
9045
9045
  );
9046
9046
  });
@@ -9080,8 +9080,8 @@ function renderTree(tr) {
9080
9080
  function renderUsecaseLayout(layout, config) {
9081
9081
  const t = resolveBaseTheme(config?.theme ?? "default");
9082
9082
  const children = [];
9083
- const nInclude = layout.ast.relations.filter((r6) => r6.kind === "include").length;
9084
- const nExtend = layout.ast.relations.filter((r6) => r6.kind === "extend").length;
9083
+ const nInclude = layout.ast.relations.filter((r7) => r7.kind === "include").length;
9084
+ const nExtend = layout.ast.relations.filter((r7) => r7.kind === "extend").length;
9085
9085
  children.push(title(`Use Case Diagram${layout.title ? " \u2014 " + layout.title : ""}`));
9086
9086
  children.push(
9087
9087
  desc(
@@ -9258,8 +9258,8 @@ function parseHeaderLine(ln, ast) {
9258
9258
  }
9259
9259
  case "layout": {
9260
9260
  const l = value.toLowerCase();
9261
- if (l !== "network" && l !== "timescaled" && l !== "aoa") {
9262
- throw new PertParseError(`layout must be network, timescaled, or aoa (got '${value}')`, ln.line);
9261
+ if (l !== "network" && l !== "timescaled" && l !== "aoa" && l !== "gantt") {
9262
+ throw new PertParseError(`layout must be network, timescaled, aoa, or gantt (got '${value}')`, ln.line);
9263
9263
  }
9264
9264
  ast.layout = l;
9265
9265
  return true;
@@ -9270,6 +9270,26 @@ function parseHeaderLine(ln, ast) {
9270
9270
  case "show-sentinels":
9271
9271
  ast.showSentinels = /^(true|yes|on)$/i.test(value);
9272
9272
  return true;
9273
+ case "start":
9274
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
9275
+ throw new PertParseError(`start must be a date 'YYYY-MM-DD' (got '${value}')`, ln.line);
9276
+ }
9277
+ ast.start = value;
9278
+ return true;
9279
+ case "calendar": {
9280
+ const c = value.toLowerCase();
9281
+ if (c !== "continuous" && c !== "5day" && c !== "7day") {
9282
+ throw new PertParseError(`calendar must be continuous, 7day, or 5day (got '${value}')`, ln.line);
9283
+ }
9284
+ ast.calendar = c === "5day" ? "5day" : "continuous";
9285
+ return true;
9286
+ }
9287
+ case "today":
9288
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
9289
+ throw new PertParseError(`today must be a date 'YYYY-MM-DD' (got '${value}')`, ln.line);
9290
+ }
9291
+ ast.today = value;
9292
+ return true;
9273
9293
  default:
9274
9294
  return false;
9275
9295
  }
@@ -9334,7 +9354,7 @@ function parseDepRef(raw, unit, lineNo) {
9334
9354
  }
9335
9355
  throw new PertParseError(`cannot parse predecessor reference '${ref}'`, lineNo);
9336
9356
  }
9337
- var KEY_RE = /\b(duration|after|tags|class|lane)\s*:/gi;
9357
+ var KEY_RE = /\b(duration|after|tags|class|lane|progress|done)\s*:/gi;
9338
9358
  function parseTaskLine(ln, ast) {
9339
9359
  const head = ln.text.match(/^task\s+(\S+)\s*(.*)$/i);
9340
9360
  if (!head) {
@@ -9409,6 +9429,13 @@ function parseTaskLine(ln, ast) {
9409
9429
  const tags = values.tags ? values.tags.split(",").map((t) => t.trim()).filter(Boolean) : [];
9410
9430
  const className = values.class ? values.class.trim() : void 0;
9411
9431
  const lane = values.lane ? stripQuotes3(values.lane) : void 0;
9432
+ const progressRaw = values.progress ?? values.done;
9433
+ let progress;
9434
+ if (progressRaw !== void 0 && progressRaw !== "") {
9435
+ const pct = progressRaw.trim().replace(/%$/, "");
9436
+ const n = parseNumber(pct, ln.line, "progress");
9437
+ progress = Math.max(0, Math.min(100, n));
9438
+ }
9412
9439
  const task = {
9413
9440
  id,
9414
9441
  label,
@@ -9422,6 +9449,7 @@ function parseTaskLine(ln, ast) {
9422
9449
  if (variance !== void 0) task.variance = variance;
9423
9450
  if (className) task.className = className;
9424
9451
  if (lane) task.lane = lane;
9452
+ if (progress !== void 0) task.progress = progress;
9425
9453
  ast.tasks.push(task);
9426
9454
  }
9427
9455
  function parsePert(src) {
@@ -9432,18 +9460,21 @@ function parsePert(src) {
9432
9460
  layout: "network",
9433
9461
  criticalTolerance: 0,
9434
9462
  showSentinels: false,
9463
+ calendar: "continuous",
9435
9464
  tasks: [],
9436
9465
  warnings: []
9437
9466
  };
9438
9467
  const lines = preprocess8(src);
9439
9468
  if (lines.length === 0) {
9440
- throw new PertParseError("empty document \u2014 expected 'pert' header", 1);
9469
+ throw new PertParseError("empty document \u2014 expected 'pert' or 'gantt' header", 1);
9441
9470
  }
9442
9471
  const first = lines[0];
9443
- if (!/^pert\b/i.test(first.text)) {
9444
- throw new PertParseError(`first non-comment line must start with 'pert' (got: ${first.text})`, first.line);
9472
+ if (!/^(pert|gantt)\b/i.test(first.text)) {
9473
+ throw new PertParseError(`first non-comment line must start with 'pert' or 'gantt' (got: ${first.text})`, first.line);
9445
9474
  }
9446
- const inlineTitle = first.text.replace(/^pert\b/i, "").trim();
9475
+ const isGanttHeader = /^gantt\b/i.test(first.text);
9476
+ if (isGanttHeader) ast.layout = "gantt";
9477
+ const inlineTitle = first.text.replace(/^(pert|gantt)\b/i, "").trim();
9447
9478
  if (inlineTitle) {
9448
9479
  const m = inlineTitle.match(/^"([^"]+)"$/) || inlineTitle.match(/^'([^']+)'$/);
9449
9480
  if (m) ast.title = m[1];
@@ -9829,12 +9860,12 @@ function layoutAoa(ast, schedule) {
9829
9860
  const predEvents = (e) => inAdj[e].map((ai) => arcs[ai].from);
9830
9861
  const succEvents = (e) => outAdj[e].map((ai) => arcs[ai].to);
9831
9862
  for (let iter = 0; iter < 4; iter++) {
9832
- for (let r6 = 1; r6 <= maxRank; r6++) {
9833
- layers[r6] = sortByBary(layers[r6], predEvents, pos);
9863
+ for (let r7 = 1; r7 <= maxRank; r7++) {
9864
+ layers[r7] = sortByBary(layers[r7], predEvents, pos);
9834
9865
  refresh(layers, pos);
9835
9866
  }
9836
- for (let r6 = maxRank - 1; r6 >= 0; r6--) {
9837
- layers[r6] = sortByBary(layers[r6], succEvents, pos);
9867
+ for (let r7 = maxRank - 1; r7 >= 0; r7--) {
9868
+ layers[r7] = sortByBary(layers[r7], succEvents, pos);
9838
9869
  refresh(layers, pos);
9839
9870
  }
9840
9871
  }
@@ -9844,12 +9875,12 @@ function layoutAoa(ast, schedule) {
9844
9875
  const contentH = (maxRows - 1) * AOA.VGAP + 2 * AOA.R;
9845
9876
  const cx = new Array(nEvents).fill(0);
9846
9877
  const cy = new Array(nEvents).fill(0);
9847
- for (let r6 = 0; r6 <= maxRank; r6++) {
9848
- const layer = layers[r6];
9878
+ for (let r7 = 0; r7 <= maxRank; r7++) {
9879
+ const layer = layers[r7];
9849
9880
  const colH = (layer.length - 1) * AOA.VGAP;
9850
9881
  const y0 = topY + AOA.R + (contentH - 2 * AOA.R - colH) / 2;
9851
9882
  layer.forEach((e, i) => {
9852
- cx[e] = AOA.PAD + AOA.R + r6 * AOA.COL;
9883
+ cx[e] = AOA.PAD + AOA.R + r7 * AOA.COL;
9853
9884
  cy[e] = y0 + i * AOA.VGAP;
9854
9885
  });
9855
9886
  }
@@ -9911,16 +9942,16 @@ function sortByBary(layer, neighbors, pos) {
9911
9942
  return { e, i, bary };
9912
9943
  }).sort((a, b) => a.bary !== b.bary ? a.bary - b.bary : a.i - b.i).map((x) => x.e);
9913
9944
  }
9914
- function arcGeometry(tx, ty, hx, hy, r6) {
9945
+ function arcGeometry(tx, ty, hx, hy, r7) {
9915
9946
  const dx = hx - tx;
9916
9947
  const dy = hy - ty;
9917
9948
  const len = Math.hypot(dx, dy) || 1;
9918
9949
  const ux = dx / len;
9919
9950
  const uy = dy / len;
9920
- const sx = tx + ux * r6;
9921
- const sy = ty + uy * r6;
9922
- const ex = hx - ux * r6;
9923
- const ey = hy - uy * r6;
9951
+ const sx = tx + ux * r7;
9952
+ const sy = ty + uy * r7;
9953
+ const ex = hx - ux * r7;
9954
+ const ey = hy - uy * r7;
9924
9955
  return { d: `M ${round5(sx)} ${round5(sy)} L ${round5(ex)} ${round5(ey)}`, mx: (sx + ex) / 2, my: (sy + ey) / 2 };
9925
9956
  }
9926
9957
  function buildAoaSummary(ast, sched) {
@@ -9993,11 +10024,11 @@ function assignRanks(ast) {
9993
10024
  if (visiting.has(id)) return 0;
9994
10025
  visiting.add(id);
9995
10026
  const t = byId.get(id);
9996
- let r6 = 0;
9997
- for (const dep of t.deps) r6 = Math.max(r6, compute(dep.pred) + 1);
10027
+ let r7 = 0;
10028
+ for (const dep of t.deps) r7 = Math.max(r7, compute(dep.pred) + 1);
9998
10029
  visiting.delete(id);
9999
- rank.set(id, r6);
10000
- return r6;
10030
+ rank.set(id, r7);
10031
+ return r7;
10001
10032
  };
10002
10033
  let maxRank = 0;
10003
10034
  for (const t of ast.tasks) maxRank = Math.max(maxRank, compute(t.id));
@@ -10043,15 +10074,15 @@ function orderLayers(ast, schedule, rank, maxRank) {
10043
10074
  return s / neighbors.length;
10044
10075
  };
10045
10076
  for (let iter = 0; iter < 4; iter++) {
10046
- for (let r6 = 1; r6 <= maxRank; r6++) {
10047
- layers[r6] = stableSortByKey(layers[r6], (id) => {
10077
+ for (let r7 = 1; r7 <= maxRank; r7++) {
10078
+ layers[r7] = stableSortByKey(layers[r7], (id) => {
10048
10079
  const bc = barycenter(id, pred.get(id));
10049
10080
  return crit(id) ? bc - 0.4 : bc;
10050
10081
  });
10051
10082
  refreshPos();
10052
10083
  }
10053
- for (let r6 = maxRank - 1; r6 >= 0; r6--) {
10054
- layers[r6] = stableSortByKey(layers[r6], (id) => {
10084
+ for (let r7 = maxRank - 1; r7 >= 0; r7--) {
10085
+ layers[r7] = stableSortByKey(layers[r7], (id) => {
10055
10086
  const bc = barycenter(id, succ.get(id));
10056
10087
  return crit(id) ? bc - 0.4 : bc;
10057
10088
  });
@@ -10103,9 +10134,9 @@ function layoutNetwork(ast, schedule) {
10103
10134
  const originCross = dir === "TB" ? C2.PAD : C2.PAD + titleH;
10104
10135
  const boxes = [];
10105
10136
  const boxById = /* @__PURE__ */ new Map();
10106
- for (let r6 = 0; r6 <= maxRank; r6++) {
10107
- const layer = layers[r6];
10108
- const extent = colExtent[r6];
10137
+ for (let r7 = 0; r7 <= maxRank; r7++) {
10138
+ const layer = layers[r7];
10139
+ const extent = colExtent[r7];
10109
10140
  const crossStart = originCross + (maxExtent - extent) / 2;
10110
10141
  let cursor = crossStart;
10111
10142
  for (const id of layer) {
@@ -10116,12 +10147,12 @@ function layoutNetwork(ast, schedule) {
10116
10147
  let x;
10117
10148
  let y;
10118
10149
  if (dir === "TB") {
10119
- const rankPos = originPrimary + r6 * (C2.BOX_H + C2.H_GAP);
10150
+ const rankPos = originPrimary + r7 * (C2.BOX_H + C2.H_GAP);
10120
10151
  x = cursor + (C2.BOX_W - w) / 2;
10121
10152
  y = rankPos;
10122
10153
  cursor += C2.BOX_W + C2.H_GAP;
10123
10154
  } else {
10124
- const rankPos = originPrimary + r6 * (C2.BOX_W + C2.H_GAP);
10155
+ const rankPos = originPrimary + r7 * (C2.BOX_W + C2.H_GAP);
10125
10156
  x = rankPos + (C2.BOX_W - w) / 2;
10126
10157
  y = cursor;
10127
10158
  cursor += C2.BOX_H + C2.V_GAP;
@@ -10135,7 +10166,7 @@ function layoutNetwork(ast, schedule) {
10135
10166
  width: w,
10136
10167
  height: h,
10137
10168
  milestone: t.milestone,
10138
- rank: r6
10169
+ rank: r7
10139
10170
  };
10140
10171
  boxes.push(box2);
10141
10172
  boxById.set(id, box2);
@@ -10295,7 +10326,7 @@ function layoutSwimlane2(ast, schedule) {
10295
10326
  const crit = (id) => schedule.computed.get(id).critical;
10296
10327
  const es = (id) => schedule.computed.get(id).es;
10297
10328
  const cell = /* @__PURE__ */ new Map();
10298
- const key = (lane, r6) => `${lane}\0${r6}`;
10329
+ const key = (lane, r7) => `${lane}\0${r7}`;
10299
10330
  for (const t of ast.tasks) {
10300
10331
  const k = key(laneOf.get(t.id), rank.get(t.id));
10301
10332
  if (!cell.has(k)) cell.set(k, []);
@@ -10312,15 +10343,15 @@ function layoutSwimlane2(ast, schedule) {
10312
10343
  }
10313
10344
  const titleH = ast.title ? C2.TITLE_H : 0;
10314
10345
  const topY = C2.PAD + titleH;
10315
- const colX = (r6) => C2.LANE_LABEL_W + C2.PAD + r6 * (C2.BOX_W + C2.H_GAP);
10346
+ const colX = (r7) => C2.LANE_LABEL_W + C2.PAD + r7 * (C2.BOX_W + C2.H_GAP);
10316
10347
  const lanes = [];
10317
10348
  const laneY = /* @__PURE__ */ new Map();
10318
10349
  const laneH = /* @__PURE__ */ new Map();
10319
10350
  let cursor = topY;
10320
10351
  laneOrder.forEach((lane, i) => {
10321
10352
  let stack = 1;
10322
- for (let r6 = 0; r6 <= maxRank; r6++) {
10323
- const arr = cell.get(key(lane, r6));
10353
+ for (let r7 = 0; r7 <= maxRank; r7++) {
10354
+ const arr = cell.get(key(lane, r7));
10324
10355
  if (arr) stack = Math.max(stack, arr.length);
10325
10356
  }
10326
10357
  const bandH = stack * C2.BOX_H + (stack - 1) * C2.V_GAP + 2 * C2.LANE_PAD;
@@ -10335,15 +10366,15 @@ function layoutSwimlane2(ast, schedule) {
10335
10366
  for (const lane of laneOrder) {
10336
10367
  const bandTop = laneY.get(lane);
10337
10368
  const bandH = laneH.get(lane);
10338
- for (let r6 = 0; r6 <= maxRank; r6++) {
10339
- const arr = cell.get(key(lane, r6));
10369
+ for (let r7 = 0; r7 <= maxRank; r7++) {
10370
+ const arr = cell.get(key(lane, r7));
10340
10371
  if (!arr) continue;
10341
10372
  const colInnerH = arr.length * C2.BOX_H + (arr.length - 1) * C2.V_GAP;
10342
10373
  const y0 = bandTop + (bandH - colInnerH) / 2;
10343
10374
  arr.forEach((id, idx) => {
10344
10375
  const t = byId.get(id);
10345
10376
  const w = t.milestone ? C2.MS_W : C2.BOX_W;
10346
- const x = colX(r6) + (C2.BOX_W - w) / 2;
10377
+ const x = colX(r7) + (C2.BOX_W - w) / 2;
10347
10378
  const y = y0 + idx * (C2.BOX_H + C2.V_GAP);
10348
10379
  const box2 = {
10349
10380
  id,
@@ -10354,7 +10385,7 @@ function layoutSwimlane2(ast, schedule) {
10354
10385
  width: w,
10355
10386
  height: C2.BOX_H,
10356
10387
  milestone: t.milestone,
10357
- rank: r6
10388
+ rank: r7
10358
10389
  };
10359
10390
  boxes.push(box2);
10360
10391
  boxById.set(id, box2);
@@ -10523,10 +10554,381 @@ function layoutPert(ast, schedule) {
10523
10554
  return layoutNetwork(ast, sched);
10524
10555
  }
10525
10556
 
10526
- // src/diagrams/pert/renderer.ts
10557
+ // src/diagrams/pert/gantt.ts
10558
+ var PALETTES = {
10559
+ default: {
10560
+ bar: "#cfe0f5",
10561
+ barStroke: "#5b85c0",
10562
+ barDone: "#5b85c0",
10563
+ critBar: "#fbe6e0",
10564
+ critStroke: "#d2604f",
10565
+ critDone: "#d2604f",
10566
+ milestone: "#3c5a80",
10567
+ text: "#234567",
10568
+ subtext: "#728198",
10569
+ axis: "#8497ad",
10570
+ grid: "#e3eaf3",
10571
+ sectionBand: "#eef3fa",
10572
+ sectionText: "#41597a",
10573
+ dep: "#9fb0c6",
10574
+ today: "#d2604f"
10575
+ },
10576
+ monochrome: {
10577
+ bar: "#ffffff",
10578
+ barStroke: "#000000",
10579
+ barDone: "#9a9a9a",
10580
+ critBar: "#ffffff",
10581
+ critStroke: "#000000",
10582
+ critDone: "#000000",
10583
+ milestone: "#000000",
10584
+ text: "#000000",
10585
+ subtext: "#555555",
10586
+ axis: "#000000",
10587
+ grid: "#dddddd",
10588
+ sectionBand: "#f2f2f2",
10589
+ sectionText: "#000000",
10590
+ dep: "#888888",
10591
+ today: "#000000"
10592
+ },
10593
+ dark: {
10594
+ bar: "#37506e",
10595
+ barStroke: "#89b4fa",
10596
+ barDone: "#89b4fa",
10597
+ critBar: "#5a3540",
10598
+ critStroke: "#f38ba8",
10599
+ critDone: "#f38ba8",
10600
+ milestone: "#bac2de",
10601
+ text: "#cdd6f4",
10602
+ subtext: "#9399b2",
10603
+ axis: "#7f849c",
10604
+ grid: "#313244",
10605
+ sectionBand: "#272838",
10606
+ sectionText: "#bac2de",
10607
+ dep: "#6c7086",
10608
+ today: "#f38ba8"
10609
+ }
10610
+ };
10611
+ function ymdToDays(y, m, d) {
10612
+ const yy = m <= 2 ? y - 1 : y;
10613
+ const era = Math.floor((yy >= 0 ? yy : yy - 399) / 400);
10614
+ const yoe = yy - era * 400;
10615
+ const doy = Math.floor((153 * (m > 2 ? m - 3 : m + 9) + 2) / 5) + d - 1;
10616
+ const doe = yoe * 365 + Math.floor(yoe / 4) - Math.floor(yoe / 100) + doy;
10617
+ return era * 146097 + doe - 719468;
10618
+ }
10619
+ function daysToYmd(z) {
10620
+ const zz = z + 719468;
10621
+ const era = Math.floor((zz >= 0 ? zz : zz - 146096) / 146097);
10622
+ const doe = zz - era * 146097;
10623
+ const yoe = Math.floor((doe - Math.floor(doe / 1460) + Math.floor(doe / 36524) - Math.floor(doe / 146096)) / 365);
10624
+ const y = yoe + era * 400;
10625
+ const doy = doe - (365 * yoe + Math.floor(yoe / 4) - Math.floor(yoe / 100));
10626
+ const mp = Math.floor((5 * doy + 2) / 153);
10627
+ const d = doy - Math.floor((153 * mp + 2) / 5) + 1;
10628
+ const m = mp < 10 ? mp + 3 : mp - 9;
10629
+ return { y: m <= 2 ? y + 1 : y, m, d };
10630
+ }
10631
+ function parseISODays(s) {
10632
+ const [y, m, d] = s.split("-").map(Number);
10633
+ return ymdToDays(y, m, d);
10634
+ }
10635
+ function dow(days) {
10636
+ return (days % 7 + 4 + 7e3) % 7;
10637
+ }
10638
+ function isWeekend(days) {
10639
+ const w = dow(days);
10640
+ return w === 0 || w === 6;
10641
+ }
10642
+ function advanceWorking(startDays, n) {
10643
+ let cur = startDays;
10644
+ let left = Math.round(n);
10645
+ const step = left >= 0 ? 1 : -1;
10646
+ left = Math.abs(left);
10647
+ while (left > 0) {
10648
+ cur += step;
10649
+ if (!isWeekend(cur)) left--;
10650
+ }
10651
+ return cur;
10652
+ }
10653
+ var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
10654
+ function fmtDate(days) {
10655
+ const { m, d } = daysToYmd(days);
10656
+ return `${MONTHS[m - 1]} ${d}`;
10657
+ }
10658
+ var G = {
10659
+ PAD: 20,
10660
+ TITLE_H: 30,
10661
+ AXIS_H: 26,
10662
+ ROW_H: 28,
10663
+ BAR_H: 15,
10664
+ SECTION_H: 24,
10665
+ LABEL_MIN: 120,
10666
+ LABEL_MAX: 250,
10667
+ CHAR_W: 6.6,
10668
+ LABEL_PAD: 12,
10669
+ TARGET_CHART_W: 740,
10670
+ MIN_PX_UNIT: 5,
10671
+ MAX_PX_UNIT: 56,
10672
+ FOOTER_H: 28
10673
+ };
10674
+ function renderGantt2(ast, schedule, config) {
10675
+ const base = resolveBaseTheme(config?.theme ?? "default");
10676
+ const themeName = (config?.theme ?? "default") in PALETTES ? config.theme : "default";
10677
+ const P = PALETTES[themeName];
10678
+ const tasks = ast.tasks;
10679
+ const span = Math.max(schedule.projectDuration, 1);
10680
+ const unitToDay = ast.unit === "weeks" ? 7 : 1;
10681
+ const unitToWork = ast.unit === "weeks" ? 5 : 1;
10682
+ const pxUnit = Math.max(G.MIN_PX_UNIT, Math.min(G.MAX_PX_UNIT, G.TARGET_CHART_W / span));
10683
+ const longest = tasks.reduce((mx, t) => Math.max(mx, (t.label ?? t.id).length), 4);
10684
+ const labelW = Math.max(G.LABEL_MIN, Math.min(G.LABEL_MAX, Math.ceil(longest * G.CHAR_W) + 2 * G.LABEL_PAD));
10685
+ const chartX = G.PAD + labelW + 8;
10686
+ const chartW = Math.ceil(span * pxUnit);
10687
+ const hasTitle = !!ast.title;
10688
+ const topY = G.PAD + (hasTitle ? G.TITLE_H : 0);
10689
+ const axisBottom = topY + G.AXIS_H;
10690
+ const rows = [];
10691
+ let cursorY = axisBottom + 6;
10692
+ let lastLane = "\0";
10693
+ for (const t of tasks) {
10694
+ const lane = t.lane;
10695
+ if (lane !== lastLane && lane !== void 0) {
10696
+ rows.push({ kind: "section", y: cursorY, h: G.SECTION_H, label: lane });
10697
+ cursorY += G.SECTION_H;
10698
+ lastLane = lane;
10699
+ } else if (lane === void 0) {
10700
+ lastLane = void 0;
10701
+ }
10702
+ rows.push({ kind: "task", y: cursorY, h: G.ROW_H, task: t });
10703
+ cursorY += G.ROW_H;
10704
+ }
10705
+ const chartBottom = cursorY;
10706
+ const totalH = chartBottom + G.FOOTER_H + G.PAD;
10707
+ const totalW = chartX + chartW + G.PAD;
10708
+ const startDays = ast.start ? parseISODays(ast.start) : void 0;
10709
+ const xAt = (unitOffset) => chartX + unitOffset * pxUnit;
10710
+ const offsetToDate = (u) => {
10711
+ if (startDays === void 0) return void 0;
10712
+ return ast.calendar === "5day" ? advanceWorking(startDays, u * unitToWork) : startDays + Math.round(u * unitToDay);
10713
+ };
10714
+ const niceStep2 = (s) => {
10715
+ const raw = s / 9;
10716
+ const candidates = [1, 2, 5, 7, 10, 14, 20, 25, 50, 100];
10717
+ for (const c of candidates) if (c >= raw) return c;
10718
+ return Math.ceil(raw / 50) * 50;
10719
+ };
10720
+ const step = niceStep2(span);
10721
+ const styleBlock = el("style", {}, `
10722
+ .sx-gantt-bg { fill: ${base.bg}; }
10723
+ .sx-gantt-title { fill: ${P.text}; font-size: 15px; font-weight: 700; }
10724
+ .sx-gantt-grid { stroke: ${P.grid}; stroke-width: 1; }
10725
+ .sx-gantt-axis-tick { stroke: ${P.axis}; stroke-width: 1; }
10726
+ .sx-gantt-axis-text { fill: ${P.subtext}; font-size: 9.5px; }
10727
+ .sx-gantt-axis-base { stroke: ${P.axis}; stroke-width: 1.2; }
10728
+ .sx-gantt-section { fill: ${P.sectionBand}; }
10729
+ .sx-gantt-section-text { fill: ${P.sectionText}; font-size: 11px; font-weight: 700; }
10730
+ .sx-gantt-rowlabel { fill: ${P.text}; font-size: 11.5px; }
10731
+ .sx-gantt-rowlabel.crit { fill: ${P.critStroke}; font-weight: 600; }
10732
+ .sx-gantt-bar { fill: ${P.bar}; stroke: ${P.barStroke}; stroke-width: 1; }
10733
+ .sx-gantt-bar[data-critical="true"] { fill: ${P.critBar}; stroke: ${P.critStroke}; stroke-width: 1.4; }
10734
+ .sx-gantt-done { fill: ${P.barDone}; }
10735
+ .sx-gantt-done[data-critical="true"] { fill: ${P.critDone}; }
10736
+ .sx-gantt-ms { fill: ${P.milestone}; stroke: ${P.milestone}; }
10737
+ .sx-gantt-ms[data-critical="true"] { fill: ${P.critStroke}; stroke: ${P.critStroke}; }
10738
+ .sx-gantt-dep { fill: none; stroke: ${P.dep}; stroke-width: 1; }
10739
+ .sx-gantt-barlabel { fill: ${P.subtext}; font-size: 9.5px; }
10740
+ .sx-gantt-today { stroke: ${P.today}; stroke-width: 1.3; stroke-dasharray: 4 3; }
10741
+ .sx-gantt-today-text { fill: ${P.today}; font-size: 9.5px; font-weight: 700; }
10742
+ .sx-gantt-footer { fill: ${P.subtext}; font-size: 10px; }
10743
+ `.trim());
10744
+ const children = [
10745
+ title(`Gantt chart${ast.title ? " \u2014 " + ast.title : ""}`),
10746
+ desc(summarise(ast, schedule)),
10747
+ styleBlock,
10748
+ rect({ x: 0, y: 0, width: totalW, height: totalH, class: "sx-gantt-bg" })
10749
+ ];
10750
+ if (hasTitle) {
10751
+ children.push(text({ x: G.PAD, y: G.PAD + 18, class: "sx-gantt-title" }, ast.title));
10752
+ }
10753
+ const bandEls = [];
10754
+ for (const r7 of rows) {
10755
+ if (r7.kind === "section") {
10756
+ bandEls.push(rect({ x: G.PAD, y: r7.y, width: totalW - 2 * G.PAD, height: r7.h, class: "sx-gantt-section" }));
10757
+ bandEls.push(text({ x: G.PAD + 8, y: r7.y + r7.h / 2 + 4, class: "sx-gantt-section-text" }, r7.label));
10758
+ }
10759
+ }
10760
+ children.push(group({ class: "sx-gantt-sections" }, bandEls));
10761
+ const axisEls = [];
10762
+ for (let u = 0; u <= span + 1e-4; u += step) {
10763
+ const x = xAt(u);
10764
+ axisEls.push(line({ class: "sx-gantt-grid", x1: x, y1: axisBottom, x2: x, y2: chartBottom }));
10765
+ axisEls.push(line({ class: "sx-gantt-axis-tick", x1: x, y1: axisBottom - 5, x2: x, y2: axisBottom }));
10766
+ const cal = offsetToDate(u);
10767
+ const label = cal !== void 0 ? fmtDate(cal) : fmtVal(u);
10768
+ axisEls.push(text({ x, y: axisBottom - 9, class: "sx-gantt-axis-text", "text-anchor": "middle" }, label));
10769
+ }
10770
+ axisEls.push(line({ class: "sx-gantt-axis-base", x1: chartX, y1: axisBottom, x2: chartX + chartW, y2: axisBottom }));
10771
+ children.push(group({ class: "sx-gantt-axis" }, axisEls));
10772
+ const labelEls = [];
10773
+ for (const r7 of rows) {
10774
+ if (r7.kind !== "task" || !r7.task) continue;
10775
+ const c = schedule.computed.get(r7.task.id);
10776
+ const crit = c?.critical ?? false;
10777
+ labelEls.push(
10778
+ text(
10779
+ { x: G.PAD + 4, y: r7.y + r7.h / 2 + 4, class: `sx-gantt-rowlabel${crit ? " crit" : ""}` },
10780
+ clip(r7.task.label ?? r7.task.id, Math.floor(labelW / G.CHAR_W))
10781
+ )
10782
+ );
10783
+ }
10784
+ children.push(group({ class: "sx-gantt-rowlabels" }, labelEls));
10785
+ const rowOf = /* @__PURE__ */ new Map();
10786
+ for (const r7 of rows) if (r7.kind === "task" && r7.task) rowOf.set(r7.task.id, r7);
10787
+ const depEls = [];
10788
+ for (const t of tasks) {
10789
+ const tr = rowOf.get(t.id);
10790
+ const tc = schedule.computed.get(t.id);
10791
+ if (!tr || !tc) continue;
10792
+ const succMidY = tr.y + tr.h / 2;
10793
+ const succX = xAt(tc.es);
10794
+ for (const dep of t.deps) {
10795
+ const pr = rowOf.get(dep.pred);
10796
+ const pc2 = schedule.computed.get(dep.pred);
10797
+ if (!pr || !pc2) continue;
10798
+ const predMidY = pr.y + pr.h / 2;
10799
+ const predX = xAt(pc2.ef);
10800
+ const midX = Math.max(predX + 8, succX - 10);
10801
+ depEls.push(path({
10802
+ class: "sx-gantt-dep",
10803
+ d: `M ${r1(predX)} ${r1(predMidY)} H ${r1(midX)} V ${r1(succMidY)} H ${r1(succX - 3)}`
10804
+ }));
10805
+ }
10806
+ }
10807
+ children.push(group({ class: "sx-gantt-deps" }, depEls));
10808
+ const barEls = [];
10809
+ for (const r7 of rows) {
10810
+ if (r7.kind !== "task" || !r7.task) continue;
10811
+ const t = r7.task;
10812
+ const c = schedule.computed.get(t.id);
10813
+ if (!c) continue;
10814
+ const crit = c.critical;
10815
+ const cy = r7.y + r7.h / 2;
10816
+ if (t.milestone || t.duration === 0) {
10817
+ const x2 = xAt(c.es);
10818
+ const s = 7;
10819
+ barEls.push(group(
10820
+ { class: "sx-gantt-task", "data-id": t.id, "data-critical": String(crit), "data-es": String(c.es) },
10821
+ [polygon({
10822
+ class: "sx-gantt-ms",
10823
+ "data-critical": String(crit),
10824
+ points: `${r1(x2)},${r1(cy - s)} ${r1(x2 + s)},${r1(cy)} ${r1(x2)},${r1(cy + s)} ${r1(x2 - s)},${r1(cy)}`
10825
+ })]
10826
+ ));
10827
+ continue;
10828
+ }
10829
+ const x = xAt(c.es);
10830
+ const w = Math.max(2, (c.ef - c.es) * pxUnit);
10831
+ const by = cy - G.BAR_H / 2;
10832
+ const parts = [
10833
+ rect({ x: r1(x), y: r1(by), width: r1(w), height: G.BAR_H, rx: 3, class: "sx-gantt-bar", "data-critical": String(crit) })
10834
+ ];
10835
+ if (t.progress !== void 0 && t.progress > 0) {
10836
+ parts.push(rect({
10837
+ x: r1(x),
10838
+ y: r1(by),
10839
+ width: r1(Math.max(2, w * t.progress / 100)),
10840
+ height: G.BAR_H,
10841
+ rx: 3,
10842
+ class: "sx-gantt-done",
10843
+ "data-critical": String(crit)
10844
+ }));
10845
+ }
10846
+ const cap2 = c.slack > 0 ? `${fmtVal(c.ef - c.es)}${unitSuffix2(ast.unit)} \xB7 slack ${fmtVal(c.slack)}` : `${fmtVal(c.ef - c.es)}${unitSuffix2(ast.unit)}`;
10847
+ parts.push(text({ x: r1(x + w + 5), y: r1(cy + 3.5), class: "sx-gantt-barlabel" }, cap2));
10848
+ barEls.push(group(
10849
+ {
10850
+ class: "sx-gantt-task",
10851
+ "data-id": t.id,
10852
+ "data-critical": String(crit),
10853
+ "data-es": String(c.es),
10854
+ "data-ef": String(c.ef),
10855
+ "data-slack": String(c.slack),
10856
+ ...t.progress !== void 0 ? { "data-progress": String(t.progress) } : {}
10857
+ },
10858
+ parts
10859
+ ));
10860
+ }
10861
+ children.push(group({ class: "sx-gantt-bars" }, barEls));
10862
+ if (ast.today && startDays !== void 0) {
10863
+ const todayDays = parseISODays(ast.today);
10864
+ let u;
10865
+ if (ast.calendar === "5day") {
10866
+ u = workingDaysBetween(startDays, todayDays) / unitToWork;
10867
+ } else {
10868
+ u = (todayDays - startDays) / unitToDay;
10869
+ }
10870
+ if (u >= 0 && u <= span) {
10871
+ const x = xAt(u);
10872
+ children.push(group({ class: "sx-gantt-today-g" }, [
10873
+ line({ class: "sx-gantt-today", x1: x, y1: axisBottom, x2: x, y2: chartBottom }),
10874
+ text({ x, y: chartBottom + 12, class: "sx-gantt-today-text", "text-anchor": "middle" }, "today")
10875
+ ]));
10876
+ }
10877
+ }
10878
+ const footer = `${schedule.order.length} tasks \xB7 duration ${fmtVal(schedule.projectDuration)}${unitSuffix2(ast.unit)} \xB7 critical path: ${schedule.criticalPath.join(" \u2192 ") || "\u2014"}`;
10879
+ children.push(text({ x: G.PAD, y: totalH - 10, class: "sx-gantt-footer" }, clip(footer, Math.floor((totalW - 2 * G.PAD) / 5.4))));
10880
+ return svgRoot(
10881
+ {
10882
+ class: "sx-gantt",
10883
+ role: "img",
10884
+ "aria-label": escapeXml(ast.title ?? "Gantt chart"),
10885
+ width: totalW,
10886
+ height: totalH,
10887
+ viewBox: `0 0 ${totalW} ${totalH}`,
10888
+ "data-diagram-type": "pert",
10889
+ "data-layout": "gantt"
10890
+ },
10891
+ children
10892
+ );
10893
+ }
10894
+ function workingDaysBetween(a, b) {
10895
+ if (b < a) return -workingDaysBetween(b, a);
10896
+ let n = 0;
10897
+ for (let d = a; d < b; d++) if (!isWeekend(d)) n++;
10898
+ return n;
10899
+ }
10900
+ function unitSuffix2(unit) {
10901
+ switch (unit) {
10902
+ case "days":
10903
+ return "d";
10904
+ case "weeks":
10905
+ return "w";
10906
+ case "hours":
10907
+ return "h";
10908
+ default:
10909
+ return "";
10910
+ }
10911
+ }
10527
10912
  function fmtVal(n) {
10528
10913
  return String(parseFloat(n.toFixed(2)));
10529
10914
  }
10915
+ function r1(n) {
10916
+ return Math.round(n * 10) / 10;
10917
+ }
10918
+ function clip(s, n) {
10919
+ return s.length <= n ? s : s.slice(0, Math.max(1, n - 1)) + "\u2026";
10920
+ }
10921
+ function summarise(ast, s) {
10922
+ const parts = [`Gantt chart: ${s.order.length} tasks, project duration ${fmtVal(s.projectDuration)}${unitSuffix2(ast.unit)}.`];
10923
+ if (ast.start) parts.push(`Starts ${ast.start} (${ast.calendar === "5day" ? "weekdays only" : "continuous"}).`);
10924
+ if (s.criticalPath.length) parts.push(`Critical path: ${s.criticalPath.join(" \u2192 ")}.`);
10925
+ return parts.join(" ");
10926
+ }
10927
+
10928
+ // src/diagrams/pert/renderer.ts
10929
+ function fmtVal2(n) {
10930
+ return String(parseFloat(n.toFixed(2)));
10931
+ }
10530
10932
  function unitWord(unit) {
10531
10933
  return unit === "abstract" ? "" : unit;
10532
10934
  }
@@ -10630,19 +11032,19 @@ function dataAttrs(b) {
10630
11032
  const attrs = {
10631
11033
  class: `sx-pert-task${c.critical ? " critical" : ""}${b.task.className ? " " + b.task.className : ""}`,
10632
11034
  "data-id": b.id,
10633
- "data-es": fmtVal(c.es),
10634
- "data-ef": fmtVal(c.ef),
10635
- "data-ls": fmtVal(c.ls),
10636
- "data-lf": fmtVal(c.lf),
10637
- "data-slack": fmtVal(c.slack),
10638
- "data-duration": fmtVal(b.task.duration),
11035
+ "data-es": fmtVal2(c.es),
11036
+ "data-ef": fmtVal2(c.ef),
11037
+ "data-ls": fmtVal2(c.ls),
11038
+ "data-lf": fmtVal2(c.lf),
11039
+ "data-slack": fmtVal2(c.slack),
11040
+ "data-duration": fmtVal2(b.task.duration),
10639
11041
  "data-critical": String(c.critical)
10640
11042
  };
10641
11043
  if (b.task.tags.length) attrs["data-tag"] = b.task.tags.join(" ");
10642
11044
  if (b.task.threePoint) {
10643
11045
  const tp = b.task.threePoint;
10644
- attrs["data-pert-triple"] = `${fmtVal(tp.o)}/${fmtVal(tp.m)}/${fmtVal(tp.p)}`;
10645
- if (b.task.variance !== void 0) attrs["data-pert-variance"] = fmtVal(b.task.variance);
11046
+ attrs["data-pert-triple"] = `${fmtVal2(tp.o)}/${fmtVal2(tp.m)}/${fmtVal2(tp.p)}`;
11047
+ if (b.task.variance !== void 0) attrs["data-pert-variance"] = fmtVal2(b.task.variance);
10646
11048
  }
10647
11049
  return attrs;
10648
11050
  }
@@ -10669,16 +11071,16 @@ function renderSixField(b) {
10669
11071
  text({ class: "sx-pert-field-label", x: fx, y: y + 9, "text-anchor": "middle" }, label),
10670
11072
  text({ class: cls, x: fx, y: y + 19, "text-anchor": "middle" }, value)
10671
11073
  ]);
10672
- parts.push(field(x + col / 2, "ES", fmtVal(c.es)));
10673
- parts.push(field(x + col * 1.5, "DUR", fmtVal(b.task.duration)));
10674
- parts.push(field(x + col * 2.5, "EF", fmtVal(c.ef)));
11074
+ parts.push(field(x + col / 2, "ES", fmtVal2(c.es)));
11075
+ parts.push(field(x + col * 1.5, "DUR", fmtVal2(b.task.duration)));
11076
+ parts.push(field(x + col * 2.5, "EF", fmtVal2(c.ef)));
10675
11077
  const fieldBot = (fx, label, value, cls = "sx-pert-field") => group({}, [
10676
11078
  text({ class: cls, x: fx, y: yBot + 13, "text-anchor": "middle" }, value),
10677
11079
  text({ class: "sx-pert-field-label", x: fx, y: yBot + 21, "text-anchor": "middle" }, label)
10678
11080
  ]);
10679
- parts.push(fieldBot(x + col / 2, "LS", fmtVal(c.ls)));
10680
- parts.push(fieldBot(x + col * 1.5, "SLACK", fmtVal(c.slack), "sx-pert-field slack"));
10681
- parts.push(fieldBot(x + col * 2.5, "LF", fmtVal(c.lf)));
11081
+ parts.push(fieldBot(x + col / 2, "LS", fmtVal2(c.ls)));
11082
+ parts.push(fieldBot(x + col * 1.5, "SLACK", fmtVal2(c.slack), "sx-pert-field slack"));
11083
+ parts.push(fieldBot(x + col * 2.5, "LF", fmtVal2(c.lf)));
10682
11084
  const hasSigma = b.task.variance !== void 0;
10683
11085
  const nameY = hasSigma ? y + topH + 18 : y + topH + 19;
10684
11086
  parts.push(text({ class: "sx-pert-name", x: cx, y: nameY, "text-anchor": "middle" }, b.task.label));
@@ -10687,7 +11089,7 @@ function renderSixField(b) {
10687
11089
  parts.push(
10688
11090
  text(
10689
11091
  { class: "sx-pert-sigma", x: cx, y: nameY + 27, "text-anchor": "middle" },
10690
- `\u03C3=${fmtVal(Math.sqrt(b.task.variance))}`
11092
+ `\u03C3=${fmtVal2(Math.sqrt(b.task.variance))}`
10691
11093
  )
10692
11094
  );
10693
11095
  }
@@ -10701,7 +11103,7 @@ function renderMilestone(b) {
10701
11103
  const parts = [
10702
11104
  polygon({ class: "sx-pert-ms", points: pts }),
10703
11105
  text({ class: "sx-pert-name", x: cx, y: cy - 2, "text-anchor": "middle" }, b.task.label),
10704
- text({ class: "sx-pert-id", x: cx, y: cy + 12, "text-anchor": "middle" }, `@ ${fmtVal(b.computed.es)}`)
11106
+ text({ class: "sx-pert-id", x: cx, y: cy + 12, "text-anchor": "middle" }, `@ ${fmtVal2(b.computed.es)}`)
10705
11107
  ];
10706
11108
  return group(dataAttrs(b), parts);
10707
11109
  }
@@ -10714,12 +11116,12 @@ function renderTimescaledBar(b) {
10714
11116
  parts.push(text({ class: "sx-pert-id", x: cx, y: y + h / 2 + 4, "text-anchor": "middle" }, b.id));
10715
11117
  const wide = w >= 104;
10716
11118
  if (wide) {
10717
- parts.push(text({ class: "sx-pert-field-label", x: x + 7, y: y + 15, "text-anchor": "start" }, `ES ${fmtVal(c.es)}`));
10718
- parts.push(text({ class: "sx-pert-field-label", x: x + w - 7, y: y + 15, "text-anchor": "end" }, `EF ${fmtVal(c.ef)}`));
11119
+ parts.push(text({ class: "sx-pert-field-label", x: x + 7, y: y + 15, "text-anchor": "start" }, `ES ${fmtVal2(c.es)}`));
11120
+ parts.push(text({ class: "sx-pert-field-label", x: x + w - 7, y: y + 15, "text-anchor": "end" }, `EF ${fmtVal2(c.ef)}`));
10719
11121
  parts.push(
10720
11122
  text(
10721
11123
  { class: `sx-pert-field-label${c.critical ? " slack" : ""}`, x: cx, y: y + h - 8, "text-anchor": "middle" },
10722
- `slack ${fmtVal(c.slack)}`
11124
+ `slack ${fmtVal2(c.slack)}`
10723
11125
  )
10724
11126
  );
10725
11127
  }
@@ -10804,7 +11206,7 @@ function renderAxis2(axis, gridTop) {
10804
11206
  parts.push(line({ x1: tk.pos, y1: axis.baseline, x2: tk.pos, y2: axis.baseline + len }));
10805
11207
  if (tk.major) {
10806
11208
  parts.push(
10807
- text({ x: tk.pos, y: axis.baseline + 18, "text-anchor": "middle" }, fmtVal(tk.value))
11209
+ text({ x: tk.pos, y: axis.baseline + 18, "text-anchor": "middle" }, fmtVal2(tk.value))
10808
11210
  );
10809
11211
  }
10810
11212
  }
@@ -10830,7 +11232,7 @@ function renderAoa(aoa) {
10830
11232
  );
10831
11233
  if (!a.dummy && a.label) {
10832
11234
  const critCls = a.critical ? " critical" : "";
10833
- const durStr = fmtVal(a.duration ?? 0);
11235
+ const durStr = fmtVal2(a.duration ?? 0);
10834
11236
  const w = Math.max(a.label.length * 6.2, durStr.length * 6) + 8;
10835
11237
  labelEls.push(
10836
11238
  rect({ class: "sx-pert-edge-halo", x: a.labelX - w / 2, y: a.labelY - 16, width: w, height: 31, rx: 3, ry: 3 })
@@ -10860,8 +11262,8 @@ function renderAoa(aoa) {
10860
11262
  }
10861
11263
  function summaryText(summary) {
10862
11264
  const u = unitWord(summary.unit);
10863
- const dur = `${fmtVal(summary.projectDuration)}${u ? " " + u : ""}`;
10864
- const sigma = summary.projectStdDev !== void 0 ? ` \xB7 \u03C3 \u2248 ${fmtVal(summary.projectStdDev)}` : "";
11265
+ const dur = `${fmtVal2(summary.projectDuration)}${u ? " " + u : ""}`;
11266
+ const sigma = summary.projectStdDev !== void 0 ? ` \xB7 \u03C3 \u2248 ${fmtVal2(summary.projectStdDev)}` : "";
10865
11267
  const plain = `Project duration ${dur} \xB7 ${summary.taskCount} tasks \xB7 ${summary.depCount} dependencies \xB7 ${summary.criticalCount} critical${sigma}`;
10866
11268
  const critPath = summary.criticalPath.map((id) => id).join(" \u2192 ");
10867
11269
  return { plain, critPath };
@@ -10873,7 +11275,7 @@ function renderPertLayout(layout, config) {
10873
11275
  children.push(title(`PERT network${layout.title ? " \u2014 " + layout.title : ""}`));
10874
11276
  children.push(
10875
11277
  desc(
10876
- `${layout.summary.taskCount} activities, project duration ${fmtVal(layout.summary.projectDuration)} ${unitWord(layout.unit)}` + (cp.length ? `, critical path ${cp.join(" \u2192 ")}` : "") + "."
11278
+ `${layout.summary.taskCount} activities, project duration ${fmtVal2(layout.summary.projectDuration)} ${unitWord(layout.unit)}` + (cp.length ? `, critical path ${cp.join(" \u2192 ")}` : "") + "."
10877
11279
  )
10878
11280
  );
10879
11281
  children.push(el("style", {}, buildCss5(t)));
@@ -10941,6 +11343,7 @@ var PERT_PAD = 24;
10941
11343
  function renderPert(textOrAst, config) {
10942
11344
  const ast = typeof textOrAst === "string" ? parsePert(textOrAst) : textOrAst;
10943
11345
  const schedule = schedulePert(ast);
11346
+ if (ast.layout === "gantt") return renderGantt2(ast, schedule, config);
10944
11347
  const layout = layoutPert(ast, schedule);
10945
11348
  return renderPertLayout(layout, config);
10946
11349
  }
@@ -10953,7 +11356,7 @@ var pert = {
10953
11356
  const t = raw.trim();
10954
11357
  if (!t) continue;
10955
11358
  if (t.startsWith("#") || t.startsWith("//")) continue;
10956
- return /^pert\b/i.test(t);
11359
+ return /^(pert|gantt)\b/i.test(t);
10957
11360
  }
10958
11361
  return false;
10959
11362
  },
@@ -12021,18 +12424,18 @@ function renderFragmentTab(f) {
12021
12424
  });
12022
12425
  return group({ class: "sx-seq-fragment-tab-g", "data-op": f.op }, parts);
12023
12426
  }
12024
- function renderRef(r6) {
12427
+ function renderRef(r7) {
12025
12428
  const tabW = 40;
12026
12429
  const tabH = 18;
12027
12430
  const fold = 6;
12028
- const tab = `M ${r6.x} ${r6.y} H ${r6.x + tabW} V ${r6.y + tabH - fold} L ${r6.x + tabW - fold} ${r6.y + tabH} H ${r6.x} Z`;
12431
+ const tab = `M ${r7.x} ${r7.y} H ${r7.x + tabW} V ${r7.y + tabH - fold} L ${r7.x + tabW - fold} ${r7.y + tabH} H ${r7.x} Z`;
12029
12432
  return group({ class: "sx-seq-fragment", "data-op": "ref" }, [
12030
- rect({ class: "sx-seq-frame", x: r6.x, y: r6.y, width: r6.width, height: r6.height, rx: 2, ry: 2 }),
12433
+ rect({ class: "sx-seq-frame", x: r7.x, y: r7.y, width: r7.width, height: r7.height, rx: 2, ry: 2 }),
12031
12434
  path({ class: "sx-seq-frame-tab", d: tab }),
12032
- text({ class: "sx-seq-frame-op", x: r6.x + 8, y: r6.y + 13 }, "ref"),
12435
+ text({ class: "sx-seq-frame-op", x: r7.x + 8, y: r7.y + 13 }, "ref"),
12033
12436
  text(
12034
- { class: "sx-seq-ref-name", x: r6.x + r6.width / 2, y: r6.y + r6.height / 2 + 8, "text-anchor": "middle" },
12035
- r6.text
12437
+ { class: "sx-seq-ref-name", x: r7.x + r7.width / 2, y: r7.y + r7.height / 2 + 8, "text-anchor": "middle" },
12438
+ r7.text
12036
12439
  )
12037
12440
  ]);
12038
12441
  }
@@ -12069,10 +12472,10 @@ function renderInvariant(iv) {
12069
12472
  ]);
12070
12473
  }
12071
12474
  function renderDestroy(d) {
12072
- const r6 = 7;
12475
+ const r7 = 7;
12073
12476
  return group({ class: "sx-seq-destroy-g" }, [
12074
- line({ class: "sx-seq-destroy", x1: d.x - r6, y1: d.y - r6, x2: d.x + r6, y2: d.y + r6 }),
12075
- line({ class: "sx-seq-destroy", x1: d.x - r6, y1: d.y + r6, x2: d.x + r6, y2: d.y - r6 })
12477
+ line({ class: "sx-seq-destroy", x1: d.x - r7, y1: d.y - r7, x2: d.x + r7, y2: d.y + r7 }),
12478
+ line({ class: "sx-seq-destroy", x1: d.x - r7, y1: d.y + r7, x2: d.x + r7, y2: d.y - r7 })
12076
12479
  ]);
12077
12480
  }
12078
12481
  function renderSequenceLayout(layout, config) {
@@ -12915,10 +13318,10 @@ function renderArc2(ag) {
12915
13318
  const dx = last.x - prev.x;
12916
13319
  const dy = last.y - prev.y;
12917
13320
  const len = Math.hypot(dx, dy) || 1;
12918
- const r6 = 4;
12919
- const cx = last.x - dx / len * r6;
12920
- const cy = last.y - dy / len * r6;
12921
- parts.push(circle({ class: "sx-petri-inhibitor-dot", cx, cy, r: r6 }));
13321
+ const r7 = 4;
13322
+ const cx = last.x - dx / len * r7;
13323
+ const cy = last.y - dy / len * r7;
13324
+ parts.push(circle({ class: "sx-petri-inhibitor-dot", cx, cy, r: r7 }));
12922
13325
  }
12923
13326
  if (ag.weight > 1) {
12924
13327
  parts.push(
@@ -13316,10 +13719,10 @@ function parseNetwork(text2) {
13316
13719
  if (rest[0]) ast.title = rest[0].value;
13317
13720
  break;
13318
13721
  case "spines":
13319
- ast.spines.push(...rest.filter((r6) => !r6.str).map((r6) => r6.value));
13722
+ ast.spines.push(...rest.filter((r7) => !r7.str).map((r7) => r7.value));
13320
13723
  break;
13321
13724
  case "leaves":
13322
- ast.leaves.push(...rest.filter((r6) => !r6.str).map((r6) => r6.value));
13725
+ ast.leaves.push(...rest.filter((r7) => !r7.str).map((r7) => r7.value));
13323
13726
  break;
13324
13727
  case "legend":
13325
13728
  break;
@@ -13889,29 +14292,29 @@ function placeBanded(ast, ranks) {
13889
14292
  const lr = ast.direction === "lr";
13890
14293
  const byRank = /* @__PURE__ */ new Map();
13891
14294
  for (const d of ast.devices) {
13892
- const r6 = ranks.get(d.id) ?? 0;
13893
- if (!byRank.has(r6)) byRank.set(r6, []);
13894
- byRank.get(r6).push(d);
14295
+ const r7 = ranks.get(d.id) ?? 0;
14296
+ if (!byRank.has(r7)) byRank.set(r7, []);
14297
+ byRank.get(r7).push(d);
13895
14298
  }
13896
14299
  const rankValues = [...byRank.keys()].sort((a, b) => a - b);
13897
14300
  const pos = /* @__PURE__ */ new Map();
13898
14301
  let maxRowSpan = 0;
13899
14302
  const rowSpans = /* @__PURE__ */ new Map();
13900
- for (const r6 of rankValues) {
13901
- const devs = byRank.get(r6);
14303
+ for (const r7 of rankValues) {
14304
+ const devs = byRank.get(r7);
13902
14305
  let span = 0;
13903
14306
  devs.forEach((d, i) => {
13904
14307
  const fp = deviceFootprint(d);
13905
14308
  const cross = lr ? fp.h + labelExtra(d) : Math.max(fp.w, labelText(d).length * NET_CONST.CHAR_W + 6);
13906
14309
  span += cross + (i > 0 ? NET_CONST.SIBLING_GAP : 0);
13907
14310
  });
13908
- rowSpans.set(r6, span);
14311
+ rowSpans.set(r7, span);
13909
14312
  maxRowSpan = Math.max(maxRowSpan, span);
13910
14313
  }
13911
- rankValues.forEach((r6, rowIdx) => {
13912
- const devs = byRank.get(r6);
14314
+ rankValues.forEach((r7, rowIdx) => {
14315
+ const devs = byRank.get(r7);
13913
14316
  const along = rowIdx * NET_CONST.TIER_BAND_GAP;
13914
- let cursor = (maxRowSpan - rowSpans.get(r6)) / 2;
14317
+ let cursor = (maxRowSpan - rowSpans.get(r7)) / 2;
13915
14318
  for (const d of devs) {
13916
14319
  const fp = deviceFootprint(d);
13917
14320
  const cross = lr ? fp.h + labelExtra(d) : Math.max(fp.w, labelText(d).length * NET_CONST.CHAR_W + 6);
@@ -13946,8 +14349,8 @@ function tieredRanks(ast, links) {
13946
14349
  if (rank.has(d.id)) continue;
13947
14350
  const known = [];
13948
14351
  for (const n of adj.get(d.id) ?? []) {
13949
- const r6 = rank.get(n);
13950
- if (r6 !== void 0) known.push(r6);
14352
+ const r7 = rank.get(n);
14353
+ if (r7 !== void 0) known.push(r7);
13951
14354
  }
13952
14355
  if (known.length === 0) continue;
13953
14356
  const next = ENDPOINT_KINDS.has(d.kind) ? Math.max(...known) + 1 : Math.min(...known) + 1;
@@ -13981,10 +14384,10 @@ function treeRanks(ast, links) {
13981
14384
  rank.set(root.id, 0);
13982
14385
  while (queue.length) {
13983
14386
  const id = queue.shift();
13984
- const r6 = rank.get(id);
14387
+ const r7 = rank.get(id);
13985
14388
  for (const n of adj.get(id) ?? []) {
13986
14389
  if (!rank.has(n)) {
13987
- rank.set(n, r6 + 1);
14390
+ rank.set(n, r7 + 1);
13988
14391
  queue.push(n);
13989
14392
  }
13990
14393
  }
@@ -14168,11 +14571,11 @@ function layoutNetwork2(ast) {
14168
14571
  };
14169
14572
  const groupsByDepth = [...ast.groups].sort((a, b) => depthOf(b.id) - depthOf(a.id));
14170
14573
  for (const g of groupsByDepth) {
14171
- let l = Infinity, t = Infinity, r6 = -Infinity, bm = -Infinity;
14574
+ let l = Infinity, t = Infinity, r7 = -Infinity, bm = -Infinity;
14172
14575
  const addBox = (e) => {
14173
14576
  l = Math.min(l, e.left);
14174
14577
  t = Math.min(t, e.top);
14175
- r6 = Math.max(r6, e.right);
14578
+ r7 = Math.max(r7, e.right);
14176
14579
  bm = Math.max(bm, e.bottom);
14177
14580
  };
14178
14581
  for (const mid of g.members) {
@@ -14189,7 +14592,7 @@ function layoutNetwork2(ast) {
14189
14592
  groupBoxesRaw.set(g.id, {
14190
14593
  left: l - pad,
14191
14594
  top: t - pad - NET_CONST.GROUP_HEADER,
14192
- right: r6 + pad,
14595
+ right: r7 + pad,
14193
14596
  bottom: bm + pad,
14194
14597
  depth
14195
14598
  });
@@ -14648,10 +15051,10 @@ function parseUmlClass(text2) {
14648
15051
  }
14649
15052
  const rels = tryParseRelationship(t, i + 1);
14650
15053
  if (rels) {
14651
- for (const r6 of rels) {
14652
- ast.relationships.push(r6);
14653
- ensureClassifier(ast, r6.from);
14654
- ensureClassifier(ast, r6.to);
15054
+ for (const r7 of rels) {
15055
+ ast.relationships.push(r7);
15056
+ ensureClassifier(ast, r7.from);
15057
+ ensureClassifier(ast, r7.to);
14655
15058
  }
14656
15059
  i++;
14657
15060
  continue;
@@ -15206,11 +15609,11 @@ function findConnector(line2, glyph) {
15206
15609
  }
15207
15610
  function validateGeneralizationAcyclicity(ast) {
15208
15611
  const adj = /* @__PURE__ */ new Map();
15209
- for (const r6 of ast.relationships) {
15210
- if (r6.kind === "generalization" || r6.kind === "realization") {
15211
- const list = adj.get(r6.from) ?? [];
15212
- list.push(r6.to);
15213
- adj.set(r6.from, list);
15612
+ for (const r7 of ast.relationships) {
15613
+ if (r7.kind === "generalization" || r7.kind === "realization") {
15614
+ const list = adj.get(r7.from) ?? [];
15615
+ list.push(r7.to);
15616
+ adj.set(r7.from, list);
15214
15617
  }
15215
15618
  }
15216
15619
  const WHITE = 0, GREY = 1, BLACK = 2;
@@ -15243,12 +15646,12 @@ function validateGeneralizationAcyclicity(ast) {
15243
15646
  }
15244
15647
  }
15245
15648
  function validateRealizationTargets(ast) {
15246
- for (const r6 of ast.relationships) {
15247
- if (r6.kind !== "realization") continue;
15248
- const target = ast.classifiers.find((c) => c.id === r6.to);
15649
+ for (const r7 of ast.relationships) {
15650
+ if (r7.kind !== "realization") continue;
15651
+ const target = ast.classifiers.find((c) => c.id === r7.to);
15249
15652
  if (target && target.kind !== "interface") {
15250
15653
  ast.warnings.push(
15251
- `Realization target "${r6.to}" is not an \xABinterface\xBB \u2014 consider marking it so.`
15654
+ `Realization target "${r7.to}" is not an \xABinterface\xBB \u2014 consider marking it so.`
15252
15655
  );
15253
15656
  }
15254
15657
  }
@@ -15726,16 +16129,16 @@ function memberLineText(m) {
15726
16129
  const props = m.properties && m.properties.length > 0 ? ` {${m.properties.join(", ")}}` : "";
15727
16130
  return `${v}${m.name}(${params})${ret}${props}`;
15728
16131
  }
15729
- function rankEnds(r6) {
15730
- switch (r6.kind) {
16132
+ function rankEnds(r7) {
16133
+ switch (r7.kind) {
15731
16134
  case "generalization":
15732
16135
  case "realization":
15733
- return { parent: r6.to, child: r6.from };
16136
+ return { parent: r7.to, child: r7.from };
15734
16137
  case "composition":
15735
16138
  case "aggregation":
15736
16139
  case "directed":
15737
16140
  case "dependency":
15738
- return { parent: r6.from, child: r6.to };
16141
+ return { parent: r7.from, child: r7.to };
15739
16142
  case "association":
15740
16143
  return null;
15741
16144
  }
@@ -15743,8 +16146,8 @@ function rankEnds(r6) {
15743
16146
  function computeRanks(ast, boxes) {
15744
16147
  const parentsOf = /* @__PURE__ */ new Map();
15745
16148
  for (const b of boxes) parentsOf.set(b.classifier.id, /* @__PURE__ */ new Set());
15746
- for (const r6 of ast.relationships) {
15747
- const ends = rankEnds(r6);
16149
+ for (const r7 of ast.relationships) {
16150
+ const ends = rankEnds(r7);
15748
16151
  if (ends) parentsOf.get(ends.child)?.add(ends.parent);
15749
16152
  }
15750
16153
  const rank = /* @__PURE__ */ new Map();
@@ -15786,19 +16189,19 @@ function buildLayeredGraph(rels, boxes, rankByID) {
15786
16189
  byID.set(n.id, n);
15787
16190
  }
15788
16191
  const chains = [];
15789
- for (const r6 of rels) {
15790
- const a = byID.get(r6.from);
15791
- const b = byID.get(r6.to);
16192
+ for (const r7 of rels) {
16193
+ const a = byID.get(r7.from);
16194
+ const b = byID.get(r7.to);
15792
16195
  if (!a || !b) continue;
15793
16196
  if (a.rank === b.rank) {
15794
- chains.push({ rel: r6, chain: [a.id, b.id], sameRank: true });
16197
+ chains.push({ rel: r7, chain: [a.id, b.id], sameRank: true });
15795
16198
  continue;
15796
16199
  }
15797
16200
  const lo = a.rank < b.rank ? a : b;
15798
16201
  const hi = a.rank < b.rank ? b : a;
15799
16202
  const diff = hi.rank - lo.rank;
15800
16203
  if (diff === 1) {
15801
- chains.push({ rel: r6, chain: [r6.from, r6.to], sameRank: false });
16204
+ chains.push({ rel: r7, chain: [r7.from, r7.to], sameRank: false });
15802
16205
  continue;
15803
16206
  }
15804
16207
  const innerDummies = [];
@@ -15819,7 +16222,7 @@ function buildLayeredGraph(rels, boxes, rankByID) {
15819
16222
  }
15820
16223
  const lowToHigh = [lo.id, ...innerDummies, hi.id];
15821
16224
  const chain = a.rank < b.rank ? lowToHigh : [...lowToHigh].reverse();
15822
- chains.push({ rel: r6, chain, sameRank: false });
16225
+ chains.push({ rel: r7, chain, sameRank: false });
15823
16226
  }
15824
16227
  return { nodes, chains };
15825
16228
  }
@@ -15859,12 +16262,12 @@ function orderRanks(ranks, chains) {
15859
16262
  for (let iter = 0; iter < UMLCLASS_CONST.ORDER_ITERATIONS; iter++) {
15860
16263
  const downward = iter % 2 === 0;
15861
16264
  if (downward) {
15862
- for (let r6 = 1; r6 < ranks.length; r6++) {
15863
- applyBarycenter(ranks[r6], ranks[r6 - 1], up);
16265
+ for (let r7 = 1; r7 < ranks.length; r7++) {
16266
+ applyBarycenter(ranks[r7], ranks[r7 - 1], up);
15864
16267
  }
15865
16268
  } else {
15866
- for (let r6 = ranks.length - 2; r6 >= 0; r6--) {
15867
- applyBarycenter(ranks[r6], ranks[r6 + 1], down);
16269
+ for (let r7 = ranks.length - 2; r7 >= 0; r7--) {
16270
+ applyBarycenter(ranks[r7], ranks[r7 + 1], down);
15868
16271
  }
15869
16272
  }
15870
16273
  }
@@ -16003,22 +16406,22 @@ function routeEdges(chains, nodes, boxByID, vertical) {
16003
16406
  const handled = /* @__PURE__ */ new Set();
16004
16407
  const groups = /* @__PURE__ */ new Map();
16005
16408
  for (const c of chains) {
16006
- const r6 = c.rel;
16007
- if (r6.kind !== "generalization" && r6.kind !== "realization") continue;
16008
- const k = `${r6.kind}::${r6.to}`;
16009
- if (!groups.has(k)) groups.set(k, { kind: r6.kind, parentId: r6.to, rels: [] });
16010
- groups.get(k).rels.push(r6);
16409
+ const r7 = c.rel;
16410
+ if (r7.kind !== "generalization" && r7.kind !== "realization") continue;
16411
+ const k = `${r7.kind}::${r7.to}`;
16412
+ if (!groups.has(k)) groups.set(k, { kind: r7.kind, parentId: r7.to, rels: [] });
16413
+ groups.get(k).rels.push(r7);
16011
16414
  }
16012
16415
  for (const [, group2] of groups) {
16013
16416
  if (group2.rels.length < UMLCLASS_CONST.TREE_MERGE_THRESHOLD) continue;
16014
16417
  const parent = boxByID.get(group2.parentId);
16015
16418
  if (!parent) continue;
16016
- const children = group2.rels.map((r6) => ({ r: r6, box: boxByID.get(r6.from) })).filter((c) => !!c.box);
16419
+ const children = group2.rels.map((r7) => ({ r: r7, box: boxByID.get(r7.from) })).filter((c) => !!c.box);
16017
16420
  if (children.length < UMLCLASS_CONST.TREE_MERGE_THRESHOLD) continue;
16018
16421
  const tree = buildTree2(group2.kind, parent, children, vertical);
16019
16422
  if (tree) {
16020
16423
  trees.push(tree);
16021
- for (const r6 of group2.rels) handled.add(r6);
16424
+ for (const r7 of group2.rels) handled.add(r7);
16022
16425
  }
16023
16426
  }
16024
16427
  const liftLanes = /* @__PURE__ */ new Map();
@@ -16471,8 +16874,8 @@ function escapeXmlText(s) {
16471
16874
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
16472
16875
  }
16473
16876
  function renderEdge4(e) {
16474
- const r6 = e.rel;
16475
- const dashed = r6.kind === "realization" || r6.kind === "dependency";
16877
+ const r7 = e.rel;
16878
+ const dashed = r7.kind === "realization" || r7.kind === "dependency";
16476
16879
  const parts = [];
16477
16880
  parts.push(
16478
16881
  path({
@@ -16481,15 +16884,15 @@ function renderEdge4(e) {
16481
16884
  "data-dashed": dashed ? "true" : void 0
16482
16885
  })
16483
16886
  );
16484
- parts.push(renderTargetAdornment(r6.kind, e.targetEnd));
16485
- if (r6.kind === "composition" || r6.kind === "aggregation") {
16486
- parts.push(renderSourceDiamond(r6.kind, e.sourceEnd));
16487
- }
16488
- if (r6.sourceMult) parts.push(renderEndLabel(e.sourceEnd, r6.sourceMult, false));
16489
- if (r6.targetMult) parts.push(renderEndLabel(e.targetEnd, r6.targetMult, false));
16490
- if (r6.sourceRole) parts.push(renderEndLabel(e.sourceEnd, r6.sourceRole, true));
16491
- if (r6.targetRole) parts.push(renderEndLabel(e.targetEnd, r6.targetRole, true));
16492
- if (r6.label && e.labelAnchor) {
16887
+ parts.push(renderTargetAdornment(r7.kind, e.targetEnd));
16888
+ if (r7.kind === "composition" || r7.kind === "aggregation") {
16889
+ parts.push(renderSourceDiamond(r7.kind, e.sourceEnd));
16890
+ }
16891
+ if (r7.sourceMult) parts.push(renderEndLabel(e.sourceEnd, r7.sourceMult, false));
16892
+ if (r7.targetMult) parts.push(renderEndLabel(e.targetEnd, r7.targetMult, false));
16893
+ if (r7.sourceRole) parts.push(renderEndLabel(e.sourceEnd, r7.sourceRole, true));
16894
+ if (r7.targetRole) parts.push(renderEndLabel(e.targetEnd, r7.targetRole, true));
16895
+ if (r7.label && e.labelAnchor) {
16493
16896
  parts.push(
16494
16897
  text(
16495
16898
  {
@@ -16498,7 +16901,7 @@ function renderEdge4(e) {
16498
16901
  class: "sx-umlclass-edge-name sx-umlclass-edge-name-halo",
16499
16902
  "text-anchor": "middle"
16500
16903
  },
16501
- r6.label
16904
+ r7.label
16502
16905
  )
16503
16906
  );
16504
16907
  parts.push(
@@ -16509,19 +16912,19 @@ function renderEdge4(e) {
16509
16912
  class: "sx-umlclass-edge-name",
16510
16913
  "text-anchor": "middle"
16511
16914
  },
16512
- r6.label
16915
+ r7.label
16513
16916
  )
16514
16917
  );
16515
16918
  }
16516
16919
  return group(
16517
16920
  {
16518
16921
  class: "sx-umlclass-rel",
16519
- "data-from": r6.from,
16520
- "data-to": r6.to,
16521
- "data-kind": r6.kind,
16522
- "data-source-mult": r6.sourceMult,
16523
- "data-target-mult": r6.targetMult,
16524
- "data-name": r6.label
16922
+ "data-from": r7.from,
16923
+ "data-to": r7.to,
16924
+ "data-kind": r7.kind,
16925
+ "data-source-mult": r7.sourceMult,
16926
+ "data-target-mult": r7.targetMult,
16927
+ "data-name": r7.label
16525
16928
  },
16526
16929
  parts
16527
16930
  );
@@ -16676,8 +17079,8 @@ function summariseDiagram(ast, treeCount) {
16676
17079
  byKind[k] = (byKind[k] ?? 0) + 1;
16677
17080
  }
16678
17081
  const relsByKind = {};
16679
- for (const r6 of ast.relationships) {
16680
- relsByKind[r6.kind] = (relsByKind[r6.kind] ?? 0) + 1;
17082
+ for (const r7 of ast.relationships) {
17083
+ relsByKind[r7.kind] = (relsByKind[r7.kind] ?? 0) + 1;
16681
17084
  }
16682
17085
  const classifierStr = Object.entries(byKind).map(([k, n]) => `${n} ${k}`).join(", ");
16683
17086
  const relStr = Object.entries(relsByKind).map(([k, n]) => `${n} ${k}`).join(", ");
@@ -16909,9 +17312,9 @@ function validate(ast) {
16909
17312
  if (!e.gate) continue;
16910
17313
  const refs = [...e.gate.inputs];
16911
17314
  if (e.gate.condition && isId(e.gate.condition)) refs.push(e.gate.condition);
16912
- for (const r6 of refs) {
16913
- if (!byId.has(r6)) {
16914
- throw new FaultTreeParseError(`gate ${e.id} references undefined event '${r6}'`);
17315
+ for (const r7 of refs) {
17316
+ if (!byId.has(r7)) {
17317
+ throw new FaultTreeParseError(`gate ${e.id} references undefined event '${r7}'`);
16915
17318
  }
16916
17319
  }
16917
17320
  if (e.gate.kind === "voting") {
@@ -16983,9 +17386,9 @@ function parseProb(s, lineNo) {
16983
17386
  return n;
16984
17387
  }
16985
17388
  function splitRefs(s, lineNo) {
16986
- const refs = s.split(",").map((r6) => r6.trim()).filter(Boolean);
16987
- for (const r6 of refs) {
16988
- if (!isId(r6)) throw new FaultTreeParseError(`invalid event reference "${r6}"`, lineNo);
17389
+ const refs = s.split(",").map((r7) => r7.trim()).filter(Boolean);
17390
+ for (const r7 of refs) {
17391
+ if (!isId(r7)) throw new FaultTreeParseError(`invalid event reference "${r7}"`, lineNo);
16989
17392
  }
16990
17393
  if (refs.length === 0) throw new FaultTreeParseError(`empty input list`, lineNo);
16991
17394
  return refs;
@@ -17627,7 +18030,7 @@ function renderFaultTreeLayout(layout, config) {
17627
18030
  const instById = new Map(layout.events.map((e) => [e.instanceId, e]));
17628
18031
  const children = [
17629
18032
  title(a11y),
17630
- desc(summarise(layout)),
18033
+ desc(summarise2(layout)),
17631
18034
  styleBlock,
17632
18035
  rect({ x: 0, y: 0, width, height, class: "sx-ft-bg" })
17633
18036
  ];
@@ -17703,10 +18106,10 @@ function renderEvent(e, showProb) {
17703
18106
  parts.push(text({ x: e.cx, y: cy + 3, class: "sx-ft-id", "text-anchor": "middle" }, e.event.id));
17704
18107
  parts.push(...leafCaption(e, cy + FAULTTREE_CONST.BASIC_R, label, showProb));
17705
18108
  } else if (e.role === "undeveloped") {
17706
- const r6 = FAULTTREE_CONST.DIAMOND_W / 2;
17707
- parts.push(path({ d: `M ${e.cx} ${cy - r6} L ${e.cx + r6} ${cy} L ${e.cx} ${cy + r6} L ${e.cx - r6} ${cy} Z`, class: "sx-ft-undeveloped" }));
18109
+ const r7 = FAULTTREE_CONST.DIAMOND_W / 2;
18110
+ parts.push(path({ d: `M ${e.cx} ${cy - r7} L ${e.cx + r7} ${cy} L ${e.cx} ${cy + r7} L ${e.cx - r7} ${cy} Z`, class: "sx-ft-undeveloped" }));
17708
18111
  parts.push(text({ x: e.cx, y: cy + 3, class: "sx-ft-id", "text-anchor": "middle" }, e.event.id));
17709
- parts.push(...leafCaption(e, cy + r6, label, showProb));
18112
+ parts.push(...leafCaption(e, cy + r7, label, showProb));
17710
18113
  } else if (e.role === "house") {
17711
18114
  const w = FAULTTREE_CONST.HOUSE_W, h = FAULTTREE_CONST.HOUSE_H, roofH = h * 0.34;
17712
18115
  const top = cy - h / 2, bottom = cy + h / 2, L = e.cx - w / 2, R = e.cx + w / 2;
@@ -17730,7 +18133,7 @@ function leafCaption(e, shapeBottom, label, showProb) {
17730
18133
  const out = [];
17731
18134
  const hasOwnLabel = !!e.event.label && e.event.label !== e.event.id;
17732
18135
  if (hasOwnLabel) {
17733
- out.push(text({ x: e.cx, y: shapeBottom + FAULTTREE_CONST.CAP_GAP, class: "sx-ft-cap", "text-anchor": "middle" }, clip(label, 20)));
18136
+ out.push(text({ x: e.cx, y: shapeBottom + FAULTTREE_CONST.CAP_GAP, class: "sx-ft-cap", "text-anchor": "middle" }, clip2(label, 20)));
17734
18137
  }
17735
18138
  if (showProb && e.event.prob !== void 0) {
17736
18139
  const y = shapeBottom + (hasOwnLabel ? FAULTTREE_CONST.CAP_GAP + FAULTTREE_CONST.CAP_LINE_H : FAULTTREE_CONST.CAP_GAP);
@@ -17788,7 +18191,7 @@ function topProbLabel(analysis) {
17788
18191
  if (analysis.topProb === void 0) return "P(top) = n/a (missing p)";
17789
18192
  return `P(top) = ${fmtProb(analysis.topProb)} (${analysis.method})`;
17790
18193
  }
17791
- function summarise(layout) {
18194
+ function summarise2(layout) {
17792
18195
  const { ast, analysis } = layout;
17793
18196
  const counts = {};
17794
18197
  for (const e of ast.events) counts[e.kind] = (counts[e.kind] ?? 0) + 1;
@@ -17818,7 +18221,7 @@ function fmtProb(n) {
17818
18221
  if (n >= 1e-3) return String(parseFloat(n.toPrecision(3)));
17819
18222
  return n.toExponential(2);
17820
18223
  }
17821
- function clip(s, n) {
18224
+ function clip2(s, n) {
17822
18225
  return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
17823
18226
  }
17824
18227
  function wrap2(s, perLine) {
@@ -17836,7 +18239,7 @@ function wrap2(s, perLine) {
17836
18239
  if (cur) lines.push(cur);
17837
18240
  if (lines.length > 2) {
17838
18241
  lines.length = 2;
17839
- lines[1] = clip(lines[1], perLine);
18242
+ lines[1] = clip2(lines[1], perLine);
17840
18243
  }
17841
18244
  return lines.join("<br/>");
17842
18245
  }
@@ -18325,7 +18728,7 @@ function renderBowtieLayout(layout, config) {
18325
18728
  );
18326
18729
  const children = [
18327
18730
  title(a11y),
18328
- desc(summarise2(layout)),
18731
+ desc(summarise3(layout)),
18329
18732
  styleBlock,
18330
18733
  rect({ x: 0, y: 0, width, height, class: "sx-bowtie-bg" })
18331
18734
  ];
@@ -18415,7 +18818,7 @@ function renderLegend2(layout, fontFamily) {
18415
18818
  }
18416
18819
  return group({ class: "sx-bowtie-legend", "data-role": "legend" }, parts);
18417
18820
  }
18418
- function summarise2(layout) {
18821
+ function summarise3(layout) {
18419
18822
  const { ast } = layout;
18420
18823
  const barrierCount = layout.boxes.filter((b) => b.role === "barrier").length;
18421
18824
  const escCount = layout.boxes.filter((b) => b.role === "escalation").length;
@@ -18443,11 +18846,11 @@ function wrap3(s, perLine, maxLines) {
18443
18846
  }
18444
18847
  }
18445
18848
  if (cur && lines.length < maxLines) lines.push(cur);
18446
- else if (cur && lines.length === maxLines) lines[maxLines - 1] = clip2(`${lines[maxLines - 1]} ${cur}`, perLine);
18849
+ else if (cur && lines.length === maxLines) lines[maxLines - 1] = clip3(`${lines[maxLines - 1]} ${cur}`, perLine);
18447
18850
  if (lines.length === 0) lines.push(s);
18448
18851
  return lines;
18449
18852
  }
18450
- function clip2(s, n) {
18853
+ function clip3(s, n) {
18451
18854
  return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
18452
18855
  }
18453
18856
  function r4(n) {
@@ -18953,7 +19356,7 @@ function renderEventTreeLayout(layout, config) {
18953
19356
  );
18954
19357
  const children = [
18955
19358
  title(a11y),
18956
- desc(summarise3(layout)),
19359
+ desc(summarise4(layout)),
18957
19360
  styleBlock,
18958
19361
  rect({ x: 0, y: 0, width, height, class: "sx-et-bg" })
18959
19362
  ];
@@ -19024,7 +19427,7 @@ function renderEventTreeLayout(layout, config) {
19024
19427
  el("circle", { cx: leaf.x, cy: leaf.y, r: 3, class: "sx-et-dot", ...dom }),
19025
19428
  text(
19026
19429
  { x: leaf.x + 10, y: leaf.y - 4, class: "sx-et-outcome", ...dom },
19027
- clip3(seq.outcome, 30)
19430
+ clip4(seq.outcome, 30)
19028
19431
  ),
19029
19432
  text(
19030
19433
  { x: leaf.x + 10, y: leaf.y + EVENTTREE_CONST.LEAF_LINE_H - 2, class: "sx-et-freq", ...dom },
@@ -19049,7 +19452,7 @@ function renderEventTreeLayout(layout, config) {
19049
19452
  children
19050
19453
  );
19051
19454
  }
19052
- function summarise3(layout) {
19455
+ function summarise4(layout) {
19053
19456
  const { ast, analysis } = layout;
19054
19457
  const parts = [
19055
19458
  `Event tree for "${ast.initiating.label ?? ast.initiating.id}" (f\u2080 = ${fmtFreq(ast.initiating.freq)}): ${ast.functions.length} function${ast.functions.length === 1 ? "" : "s"}, ${analysis.sequences.length} sequence${analysis.sequences.length === 1 ? "" : "s"}.`
@@ -19082,7 +19485,7 @@ function fmtProb2(n) {
19082
19485
  if (n >= 1e-3) return String(parseFloat(n.toPrecision(3)));
19083
19486
  return n.toExponential(2);
19084
19487
  }
19085
- function clip3(s, n) {
19488
+ function clip4(s, n) {
19086
19489
  return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
19087
19490
  }
19088
19491
 
@@ -19528,7 +19931,7 @@ function analyseFmea(ast) {
19528
19931
  }
19529
19932
  for (const act of ast.actions) {
19530
19933
  const target = flat.find(
19531
- (r6) => r6.mode === act.mode && (act.cause === void 0 || r6.cause === act.cause)
19934
+ (r7) => r7.mode === act.mode && (act.cause === void 0 || r7.cause === act.cause)
19532
19935
  );
19533
19936
  if (!target) {
19534
19937
  notes.push(`Action references unknown mode/cause "${act.mode}"${act.cause ? ` / "${act.cause}"` : ""}.`);
@@ -19551,41 +19954,41 @@ function analyseFmea(ast) {
19551
19954
  rpnDelta: rpn(target.sev, target.occ, target.det) - afterRpn
19552
19955
  };
19553
19956
  }
19554
- const rows = flat.map((r6) => {
19555
- const r0 = rpn(r6.sev, r6.occ, r6.det);
19556
- const ap = actionPriority(r6.sev, r6.occ, r6.det);
19957
+ const rows = flat.map((r7) => {
19958
+ const r0 = rpn(r7.sev, r7.occ, r7.det);
19959
+ const ap = actionPriority(r7.sev, r7.occ, r7.det);
19557
19960
  const flagged = ast.flag ? meetsThreshold(ast.flag, r0, ap) : false;
19558
19961
  return {
19559
19962
  index: 0,
19560
- item: r6.item,
19561
- fn: r6.fn,
19562
- mode: r6.mode,
19563
- effect: r6.effect,
19564
- effects: r6.effects,
19565
- sev: r6.sev,
19566
- cause: r6.cause,
19567
- occ: r6.occ,
19568
- det: r6.det,
19569
- controls: r6.controls,
19963
+ item: r7.item,
19964
+ fn: r7.fn,
19965
+ mode: r7.mode,
19966
+ effect: r7.effect,
19967
+ effects: r7.effects,
19968
+ sev: r7.sev,
19969
+ cause: r7.cause,
19970
+ occ: r7.occ,
19971
+ det: r7.det,
19972
+ controls: r7.controls,
19570
19973
  rpn: r0,
19571
19974
  ap,
19572
19975
  flagged,
19573
- action: r6.action,
19976
+ action: r7.action,
19574
19977
  itemFirst: false,
19575
19978
  itemSpan: 1,
19576
19979
  modeFirst: false,
19577
19980
  modeSpan: 1
19578
19981
  };
19579
19982
  });
19580
- const orig = new Map(rows.map((r6, i) => [r6, i]));
19983
+ const orig = new Map(rows.map((r7, i) => [r7, i]));
19581
19984
  rows.sort((a, b) => compareRows(a, b, ast.rank, orig));
19582
- rows.forEach((r6, i) => {
19583
- r6.index = i + 1;
19985
+ rows.forEach((r7, i) => {
19986
+ r7.index = i + 1;
19584
19987
  });
19585
19988
  computeSpans(rows);
19586
- const flaggedCount = rows.filter((r6) => r6.flagged).length;
19587
- const maxRpn = rows.reduce((m, r6) => Math.max(m, r6.rpn), 0);
19588
- const hasActions = rows.some((r6) => r6.action !== void 0);
19989
+ const flaggedCount = rows.filter((r7) => r7.flagged).length;
19990
+ const maxRpn = rows.reduce((m, r7) => Math.max(m, r7.rpn), 0);
19991
+ const hasActions = rows.some((r7) => r7.action !== void 0);
19589
19992
  return { rank: ast.rank, rows, flaggedCount, maxRpn, hasActions, notes };
19590
19993
  }
19591
19994
  function compareRows(a, b, rank, orig) {
@@ -19649,39 +20052,39 @@ var FMEA_CONST = {
19649
20052
  function buildColumnSpecs(hasActions, rank) {
19650
20053
  const C2 = FMEA_CONST;
19651
20054
  const specs = [
19652
- { key: "no", label: "#", width: 28, align: "middle", numeric: true, field: (r6) => String(r6.index) },
20055
+ { key: "no", label: "#", width: 28, align: "middle", numeric: true, field: (r7) => String(r7.index) },
19653
20056
  {
19654
20057
  key: "item",
19655
20058
  label: "Item / Function",
19656
20059
  width: 130,
19657
20060
  align: "start",
19658
20061
  numeric: false,
19659
- field: (r6) => r6.fn ? `${r6.item}
19660
- \u2014 ${r6.fn}` : r6.item
20062
+ field: (r7) => r7.fn ? `${r7.item}
20063
+ \u2014 ${r7.fn}` : r7.item
19661
20064
  },
19662
- { key: "mode", label: "Failure Mode", width: 120, align: "start", numeric: false, field: (r6) => r6.mode },
20065
+ { key: "mode", label: "Failure Mode", width: 120, align: "start", numeric: false, field: (r7) => r7.mode },
19663
20066
  {
19664
20067
  key: "effect",
19665
20068
  label: "Effect(s)",
19666
20069
  width: 120,
19667
20070
  align: "start",
19668
20071
  numeric: false,
19669
- field: (r6) => r6.effects.length > 1 ? r6.effects.join("; ") : r6.effect
20072
+ field: (r7) => r7.effects.length > 1 ? r7.effects.join("; ") : r7.effect
19670
20073
  },
19671
- { key: "sev", label: "S", width: C2.NUM_COL_W, align: "middle", band: "before", numeric: true, field: (r6) => String(r6.sev) },
19672
- { key: "cause", label: "Cause(s)", width: 120, align: "start", numeric: false, field: (r6) => r6.cause },
19673
- { key: "occ", label: "O", width: C2.NUM_COL_W, align: "middle", band: "before", numeric: true, field: (r6) => String(r6.occ) },
20074
+ { key: "sev", label: "S", width: C2.NUM_COL_W, align: "middle", band: "before", numeric: true, field: (r7) => String(r7.sev) },
20075
+ { key: "cause", label: "Cause(s)", width: 120, align: "start", numeric: false, field: (r7) => r7.cause },
20076
+ { key: "occ", label: "O", width: C2.NUM_COL_W, align: "middle", band: "before", numeric: true, field: (r7) => String(r7.occ) },
19674
20077
  {
19675
20078
  key: "controls",
19676
20079
  label: "Current Controls",
19677
20080
  width: 120,
19678
20081
  align: "start",
19679
20082
  numeric: false,
19680
- field: (r6) => controlsText(r6)
20083
+ field: (r7) => controlsText(r7)
19681
20084
  },
19682
- { key: "det", label: "D", width: C2.NUM_COL_W, align: "middle", band: "before", numeric: true, field: (r6) => String(r6.det) },
19683
- { key: "rpn", label: "RPN", width: C2.RPN_COL_W, align: "middle", band: "before", numeric: true, field: (r6) => String(r6.rpn) },
19684
- { key: "ap", label: "AP", width: C2.AP_COL_W, align: "middle", band: "before", numeric: true, field: (r6) => r6.ap }
20085
+ { key: "det", label: "D", width: C2.NUM_COL_W, align: "middle", band: "before", numeric: true, field: (r7) => String(r7.det) },
20086
+ { key: "rpn", label: "RPN", width: C2.RPN_COL_W, align: "middle", band: "before", numeric: true, field: (r7) => String(r7.rpn) },
20087
+ { key: "ap", label: "AP", width: C2.AP_COL_W, align: "middle", band: "before", numeric: true, field: (r7) => r7.ap }
19685
20088
  ];
19686
20089
  if (hasActions) {
19687
20090
  specs.push(
@@ -19692,7 +20095,7 @@ function buildColumnSpecs(hasActions, rank) {
19692
20095
  align: "start",
19693
20096
  numeric: false,
19694
20097
  afterOnly: true,
19695
- field: (r6) => actionText(r6)
20098
+ field: (r7) => actionText(r7)
19696
20099
  },
19697
20100
  {
19698
20101
  key: "rsev",
@@ -19702,7 +20105,7 @@ function buildColumnSpecs(hasActions, rank) {
19702
20105
  band: "after",
19703
20106
  numeric: true,
19704
20107
  afterOnly: true,
19705
- field: (r6) => r6.action ? String(r6.action.sev) : ""
20108
+ field: (r7) => r7.action ? String(r7.action.sev) : ""
19706
20109
  },
19707
20110
  {
19708
20111
  key: "rocc",
@@ -19712,7 +20115,7 @@ function buildColumnSpecs(hasActions, rank) {
19712
20115
  band: "after",
19713
20116
  numeric: true,
19714
20117
  afterOnly: true,
19715
- field: (r6) => r6.action ? String(r6.action.occ) : ""
20118
+ field: (r7) => r7.action ? String(r7.action.occ) : ""
19716
20119
  },
19717
20120
  {
19718
20121
  key: "rdet",
@@ -19722,7 +20125,7 @@ function buildColumnSpecs(hasActions, rank) {
19722
20125
  band: "after",
19723
20126
  numeric: true,
19724
20127
  afterOnly: true,
19725
- field: (r6) => r6.action ? String(r6.action.det) : ""
20128
+ field: (r7) => r7.action ? String(r7.action.det) : ""
19726
20129
  },
19727
20130
  {
19728
20131
  key: "rrpn",
@@ -19732,7 +20135,7 @@ function buildColumnSpecs(hasActions, rank) {
19732
20135
  band: "after",
19733
20136
  numeric: true,
19734
20137
  afterOnly: true,
19735
- field: (r6) => r6.action ? String(r6.action.rpn) : ""
20138
+ field: (r7) => r7.action ? String(r7.action.rpn) : ""
19736
20139
  },
19737
20140
  {
19738
20141
  key: "rap",
@@ -19742,26 +20145,26 @@ function buildColumnSpecs(hasActions, rank) {
19742
20145
  band: "after",
19743
20146
  numeric: true,
19744
20147
  afterOnly: true,
19745
- field: (r6) => r6.action ? r6.action.ap : ""
20148
+ field: (r7) => r7.action ? r7.action.ap : ""
19746
20149
  }
19747
20150
  );
19748
20151
  }
19749
20152
  return specs;
19750
20153
  }
19751
- function controlsText(r6) {
20154
+ function controlsText(r7) {
19752
20155
  const parts = [];
19753
- if (r6.controls?.prevention) parts.push(`P: ${r6.controls.prevention}`);
19754
- if (r6.controls?.detection) parts.push(`D: ${r6.controls.detection}`);
20156
+ if (r7.controls?.prevention) parts.push(`P: ${r7.controls.prevention}`);
20157
+ if (r7.controls?.detection) parts.push(`D: ${r7.controls.detection}`);
19755
20158
  return parts.join("\n");
19756
20159
  }
19757
- function actionText(r6) {
19758
- if (!r6.action) return "";
20160
+ function actionText(r7) {
20161
+ if (!r7.action) return "";
19759
20162
  const parts = [];
19760
- if (r6.action.recommendation) parts.push(r6.action.recommendation);
20163
+ if (r7.action.recommendation) parts.push(r7.action.recommendation);
19761
20164
  const meta = [];
19762
- if (r6.action.owner) meta.push(r6.action.owner);
19763
- if (r6.action.target) meta.push(r6.action.target);
19764
- if (r6.action.status) meta.push(`[${r6.action.status}]`);
20165
+ if (r7.action.owner) meta.push(r7.action.owner);
20166
+ if (r7.action.target) meta.push(r7.action.target);
20167
+ if (r7.action.status) meta.push(`[${r7.action.status}]`);
19765
20168
  if (meta.length) parts.push(meta.join(" \xB7 "));
19766
20169
  return parts.join("\n");
19767
20170
  }
@@ -20031,7 +20434,7 @@ function renderFmeaLayout(layout, config) {
20031
20434
  const style = el("style", {}, buildCss9(p));
20032
20435
  const children = [
20033
20436
  title(a11y),
20034
- desc(summarise4(layout)),
20437
+ desc(summarise5(layout)),
20035
20438
  style,
20036
20439
  rect({ x: 0, y: 0, width, height, class: "sx-fmea-bg" })
20037
20440
  ];
@@ -20183,7 +20586,7 @@ function renderHeaderBlock(layout) {
20183
20586
  function capitalise(s) {
20184
20587
  return s.charAt(0).toUpperCase() + s.slice(1);
20185
20588
  }
20186
- function summarise4(layout) {
20589
+ function summarise5(layout) {
20187
20590
  const { ast, analysis } = layout;
20188
20591
  const top = analysis.rows[0];
20189
20592
  const parts = [
@@ -20235,6 +20638,658 @@ var fmea = {
20235
20638
  }
20236
20639
  };
20237
20640
 
20641
+ // src/diagrams/rbd/parser.ts
20642
+ function normalizeQuotes2(text2) {
20643
+ return text2.replace(/[“”„«»「」『』"]/g, '"').replace(/[‘’‚']/g, "'");
20644
+ }
20645
+ var RbdParseError = class extends Error {
20646
+ constructor(message) {
20647
+ super(message);
20648
+ this.name = "RbdParseError";
20649
+ }
20650
+ };
20651
+ var HEADER_RE = /^\s*(rbd|reliability(?:blockdiagram)?|reliability-block-diagram)\b/i;
20652
+ var GROUP_KW = /* @__PURE__ */ new Set(["series", "parallel", "kofn", "k-of-n", "voting"]);
20653
+ function parseRbd(text2) {
20654
+ const normalized = normalizeQuotes2(text2);
20655
+ const lines = normalized.split("\n");
20656
+ let headerIdx = -1;
20657
+ for (let i = 0; i < lines.length; i++) {
20658
+ if (lines[i].trim() === "") continue;
20659
+ if (!HEADER_RE.test(lines[i])) {
20660
+ throw new RbdParseError(
20661
+ `RBD must start with 'rbd' (or 'reliability'). Example: rbd "My System"`
20662
+ );
20663
+ }
20664
+ headerIdx = i;
20665
+ break;
20666
+ }
20667
+ if (headerIdx < 0) throw new RbdParseError("Empty RBD input.");
20668
+ const warnings = [];
20669
+ const metadata = {};
20670
+ const headerRest = lines[headerIdx].replace(HEADER_RE, "").trim();
20671
+ const title2 = extractQuoted(headerRest);
20672
+ const body = lines.slice(headerIdx + 1).join("\n");
20673
+ const tokens = tokenize6(stripBodyDirectives(body, metadata));
20674
+ const seenIds = /* @__PURE__ */ new Set();
20675
+ let pos = 0;
20676
+ const peek = () => tokens[pos];
20677
+ const parseBlock = () => {
20678
+ const idTok = tokens[pos++];
20679
+ if (idTok.t !== "word") throw new RbdParseError("Expected a block id.");
20680
+ const id = idTok.v;
20681
+ if (seenIds.has(id)) warnings.push(`Duplicate block id "${id}" \u2014 later definition rendered, ids should be unique.`);
20682
+ seenIds.add(id);
20683
+ let label;
20684
+ let R;
20685
+ if (peek()?.t === "string") {
20686
+ label = tokens[pos++].v;
20687
+ }
20688
+ while (peek()?.t === "word") {
20689
+ const w = peek().v;
20690
+ const attr = parseAttr(w);
20691
+ if (!attr) break;
20692
+ pos++;
20693
+ if (attr.key === "p") R = clamp01(1 - attr.value, w, warnings);
20694
+ else R = clamp01(attr.value, w, warnings);
20695
+ }
20696
+ return { kind: "block", id, ...label !== void 0 ? { label } : {}, ...R !== void 0 ? { R } : {} };
20697
+ };
20698
+ const parseGroup = (kwRaw) => {
20699
+ const kw = kwRaw.toLowerCase();
20700
+ let k;
20701
+ let n;
20702
+ if (kw === "kofn" || kw === "k-of-n" || kw === "voting") {
20703
+ const spec = peek();
20704
+ if (spec?.t === "word" && /^\d+\s*\/\s*\d+$/.test(spec.v)) {
20705
+ pos++;
20706
+ const [ks, ns] = spec.v.split("/");
20707
+ k = parseInt(ks, 10);
20708
+ n = parseInt(ns, 10);
20709
+ } else {
20710
+ throw new RbdParseError(`'${kwRaw}' needs a k/n threshold, e.g. 'kofn 2/3 { \u2026 }'.`);
20711
+ }
20712
+ }
20713
+ if (peek()?.t !== "lbrace") throw new RbdParseError(`Expected '{' after '${kwRaw}'.`);
20714
+ pos++;
20715
+ const children = parseList();
20716
+ if (peek()?.t !== "rbrace") throw new RbdParseError(`Unclosed '${kwRaw}' group \u2014 missing '}'.`);
20717
+ pos++;
20718
+ if (children.length === 0) warnings.push(`Empty '${kwRaw}' group ignored.`);
20719
+ const kind = kw === "series" ? "series" : "parallel";
20720
+ const isKofn = kw === "kofn" || kw === "k-of-n" || kw === "voting";
20721
+ if (isKofn) {
20722
+ const total = n ?? children.length;
20723
+ let thr = k ?? total;
20724
+ if (thr > total) {
20725
+ warnings.push(`k-of-n threshold k=${thr} exceeds n=${total} \u2014 clamped to ${total}.`);
20726
+ thr = total;
20727
+ }
20728
+ if (thr < 1) {
20729
+ warnings.push(`k-of-n threshold k=${thr} < 1 \u2014 clamped to 1.`);
20730
+ thr = 1;
20731
+ }
20732
+ return { kind: "kofn", k: thr, n: total, children };
20733
+ }
20734
+ return { kind, children };
20735
+ };
20736
+ const parseStructure = () => {
20737
+ const tok = peek();
20738
+ if (!tok) throw new RbdParseError("Unexpected end of input.");
20739
+ if (tok.t === "rbrace") throw new RbdParseError("Unexpected '}'.");
20740
+ if (tok.t === "string") throw new RbdParseError(`Unexpected quoted text "${tok.v}" \u2014 labels attach to a block.`);
20741
+ if (tok.t === "lbrace") throw new RbdParseError("Unexpected '{' \u2014 a group keyword (series/parallel/kofn) must precede it.");
20742
+ const w = tok.v;
20743
+ if (GROUP_KW.has(w.toLowerCase())) {
20744
+ pos++;
20745
+ return parseGroup(w);
20746
+ }
20747
+ if (w.toLowerCase() === "block") {
20748
+ pos++;
20749
+ return parseBlock();
20750
+ }
20751
+ return parseBlock();
20752
+ };
20753
+ function parseList() {
20754
+ const items = [];
20755
+ while (pos < tokens.length && peek()?.t !== "rbrace") {
20756
+ items.push(parseStructure());
20757
+ }
20758
+ return items;
20759
+ }
20760
+ const top = parseList();
20761
+ if (pos < tokens.length) throw new RbdParseError("Unbalanced '}' in RBD body.");
20762
+ let root;
20763
+ if (top.length === 0) {
20764
+ throw new RbdParseError("RBD has no blocks. Add at least one `block ID R=\u2026`.");
20765
+ } else if (top.length === 1 && top[0].kind !== "block") {
20766
+ root = top[0];
20767
+ } else {
20768
+ root = { kind: "series", children: top };
20769
+ }
20770
+ return {
20771
+ type: "rbd",
20772
+ ...title2 ? { title: title2 } : {},
20773
+ root,
20774
+ warnings,
20775
+ ...Object.keys(metadata).length > 0 ? { metadata } : {}
20776
+ };
20777
+ }
20778
+ function tokenize6(src) {
20779
+ const out = [];
20780
+ let i = 0;
20781
+ const n = src.length;
20782
+ const isQuote2 = (c) => c === '"' || c === "'";
20783
+ while (i < n) {
20784
+ const c = src[i];
20785
+ if (c === "#") {
20786
+ while (i < n && src[i] !== "\n") i++;
20787
+ continue;
20788
+ }
20789
+ if (/\s/.test(c)) {
20790
+ i++;
20791
+ continue;
20792
+ }
20793
+ if (c === "{") {
20794
+ out.push({ t: "lbrace" });
20795
+ i++;
20796
+ continue;
20797
+ }
20798
+ if (c === "}") {
20799
+ out.push({ t: "rbrace" });
20800
+ i++;
20801
+ continue;
20802
+ }
20803
+ if (isQuote2(c)) {
20804
+ const close = c;
20805
+ let v2 = "";
20806
+ i++;
20807
+ while (i < n && src[i] !== close) {
20808
+ v2 += src[i];
20809
+ i++;
20810
+ }
20811
+ i++;
20812
+ out.push({ t: "string", v: v2.trim() });
20813
+ continue;
20814
+ }
20815
+ let v = "";
20816
+ while (i < n && !/\s/.test(src[i]) && src[i] !== "{" && src[i] !== "}" && !isQuote2(src[i])) {
20817
+ v += src[i];
20818
+ i++;
20819
+ }
20820
+ out.push({ t: "word", v });
20821
+ }
20822
+ return out;
20823
+ }
20824
+ function stripBodyDirectives(body, metadata) {
20825
+ return body.split("\n").filter((line2) => {
20826
+ const m = line2.match(/^\s*(title|standard|note)\s*:\s*(.+)$/i);
20827
+ if (m) {
20828
+ const key = m[1].toLowerCase();
20829
+ if (key !== "title") metadata[key] = m[2].trim();
20830
+ else metadata.title = m[2].trim();
20831
+ return false;
20832
+ }
20833
+ return true;
20834
+ }).join("\n");
20835
+ }
20836
+ function extractQuoted(s) {
20837
+ const m = s.match(/^["']([^"']*)["']/);
20838
+ if (m) return m[1].trim();
20839
+ return s.length > 0 ? s.trim() : void 0;
20840
+ }
20841
+ function parseAttr(w) {
20842
+ const m = w.match(/^(R|r|p|prob|q)\s*[=:]\s*(.+)$/);
20843
+ if (m) {
20844
+ const key = m[1].toLowerCase();
20845
+ const value = parseNum(m[2]);
20846
+ if (value === void 0) return null;
20847
+ return { key: key === "p" || key === "q" ? "p" : "R", value };
20848
+ }
20849
+ const bare = parseNum(w);
20850
+ if (bare !== void 0) return { key: "R", value: bare };
20851
+ return null;
20852
+ }
20853
+ function parseNum(s) {
20854
+ const t = s.trim();
20855
+ if (/%$/.test(t)) {
20856
+ const v2 = parseFloat(t.slice(0, -1));
20857
+ return Number.isFinite(v2) ? v2 / 100 : void 0;
20858
+ }
20859
+ const v = parseFloat(t);
20860
+ return Number.isFinite(v) ? v : void 0;
20861
+ }
20862
+ function clamp01(v, raw, warnings) {
20863
+ if (v < 0) {
20864
+ warnings.push(`Reliability ${raw} < 0 \u2014 clamped to 0.`);
20865
+ return 0;
20866
+ }
20867
+ if (v > 1) {
20868
+ warnings.push(`Reliability ${raw} > 1 \u2014 clamped to 1.`);
20869
+ return 1;
20870
+ }
20871
+ return v;
20872
+ }
20873
+
20874
+ // src/diagrams/rbd/analysis.ts
20875
+ var KOFN_ENUM_CAP = 18;
20876
+ function analyseRbd(ast) {
20877
+ const notes = [];
20878
+ const warnings = [...ast.warnings];
20879
+ const blocks = [];
20880
+ collectBlocks(ast.root, blocks);
20881
+ const missing = blocks.filter((b) => b.R === void 0).map((b) => b.id);
20882
+ const baseEnv = new Map(blocks.map((b) => [b.id, b.R]));
20883
+ const systemReliability = evalStructure(ast.root, baseEnv, notes);
20884
+ const results = blocks.map((b) => {
20885
+ if (systemReliability === void 0) {
20886
+ return { id: b.id, ...b.R !== void 0 ? { R: b.R } : {}, isSpof: false };
20887
+ }
20888
+ const up = new Map(baseEnv);
20889
+ up.set(b.id, 1);
20890
+ const down = new Map(baseEnv);
20891
+ down.set(b.id, 0);
20892
+ const rUp = evalStructure(ast.root, up, notes);
20893
+ const rDown = evalStructure(ast.root, down, notes);
20894
+ const importance = rUp !== void 0 && rDown !== void 0 ? rUp - rDown : void 0;
20895
+ const isSpof = rDown === 0;
20896
+ return {
20897
+ id: b.id,
20898
+ ...b.R !== void 0 ? { R: b.R } : {},
20899
+ ...importance !== void 0 ? { importance } : {},
20900
+ isSpof
20901
+ };
20902
+ });
20903
+ let criticalBlock;
20904
+ let best = -Infinity;
20905
+ for (const r7 of results) {
20906
+ if (r7.importance !== void 0 && r7.importance > best) {
20907
+ best = r7.importance;
20908
+ criticalBlock = r7.id;
20909
+ }
20910
+ }
20911
+ if (systemReliability !== void 0) {
20912
+ const spofs = results.filter((r7) => r7.isSpof).map((r7) => r7.id);
20913
+ if (spofs.length === 0) notes.push("No single point of failure \u2014 every block has redundancy in the success path.");
20914
+ }
20915
+ return {
20916
+ ...systemReliability !== void 0 ? { systemReliability } : {},
20917
+ blocks: results,
20918
+ missing,
20919
+ ...criticalBlock ? { criticalBlock } : {},
20920
+ warnings,
20921
+ notes
20922
+ };
20923
+ }
20924
+ function collectBlocks(s, out) {
20925
+ if (s.kind === "block") {
20926
+ out.push({ id: s.id, ...s.R !== void 0 ? { R: s.R } : {} });
20927
+ return;
20928
+ }
20929
+ for (const c of s.children) collectBlocks(c, out);
20930
+ }
20931
+ function evalStructure(s, env, notes) {
20932
+ if (s.kind === "block") return env.get(s.id);
20933
+ const childR = s.children.map((c) => evalStructure(c, env, notes));
20934
+ if (childR.some((r7) => r7 === void 0)) return void 0;
20935
+ const rs = childR;
20936
+ if (rs.length === 0) return 1;
20937
+ if (s.kind === "series") {
20938
+ return rs.reduce((p, r7) => p * r7, 1);
20939
+ }
20940
+ if (s.kind === "parallel") {
20941
+ return 1 - rs.reduce((p, r7) => p * (1 - r7), 1);
20942
+ }
20943
+ const n = rs.length;
20944
+ const k = Math.min(Math.max(s.k ?? n, 1), n);
20945
+ if (n > KOFN_ENUM_CAP) {
20946
+ notes.push(`k-of-n group with n=${n} exceeds the exact-enumeration cap (${KOFN_ENUM_CAP}); reported as a parallel bound.`);
20947
+ return 1 - rs.reduce((p, r7) => p * (1 - r7), 1);
20948
+ }
20949
+ return kofnReliability(rs, k);
20950
+ }
20951
+ function kofnReliability(rs, k) {
20952
+ const n = rs.length;
20953
+ let total = 0;
20954
+ for (let mask = 0; mask < 1 << n; mask++) {
20955
+ let working = 0;
20956
+ let prob = 1;
20957
+ for (let i = 0; i < n; i++) {
20958
+ if (mask & 1 << i) {
20959
+ working++;
20960
+ prob *= rs[i];
20961
+ } else prob *= 1 - rs[i];
20962
+ }
20963
+ if (working >= k) total += prob;
20964
+ }
20965
+ return total;
20966
+ }
20967
+
20968
+ // src/diagrams/rbd/layout.ts
20969
+ var RBD_CONST = {
20970
+ BLOCK_H: 46,
20971
+ BLOCK_MIN_W: 96,
20972
+ BLOCK_MAX_W: 200,
20973
+ BLOCK_RX: 5,
20974
+ CHAR_W: 6.9,
20975
+ PAD_X: 14,
20976
+ /** Horizontal wire length between series members. */
20977
+ H_GAP: 44,
20978
+ /** Vertical gap between parallel rails. */
20979
+ V_GAP: 26,
20980
+ /** Fan-out / merge horizontal stub flanking a parallel group. */
20981
+ SPLIT_STUB: 30,
20982
+ NODE_R: 3.5,
20983
+ /** Input/output terminal stub at the network ends. */
20984
+ TERM_STUB: 30,
20985
+ CAP_GAP: 15,
20986
+ CAP_LINE_H: 13,
20987
+ CANVAS_PAD: 28,
20988
+ TITLE_H: 32,
20989
+ HEADER_H: 26
20990
+ };
20991
+ function blockWidth(label) {
20992
+ const C2 = RBD_CONST;
20993
+ return Math.min(C2.BLOCK_MAX_W, Math.max(C2.BLOCK_MIN_W, Math.ceil(label.length * C2.CHAR_W) + 2 * C2.PAD_X));
20994
+ }
20995
+ function layoutRbd(ast) {
20996
+ const C2 = RBD_CONST;
20997
+ const analysis = analyseRbd(ast);
20998
+ const spof = new Set(analysis.blocks.filter((b) => b.isSpof).map((b) => b.id));
20999
+ const rById = new Map(analysis.blocks.map((b) => [b.id, b.R]));
21000
+ const blocks = [];
21001
+ const nodes = [];
21002
+ const wires = [];
21003
+ const marks = [];
21004
+ const measure = (s) => {
21005
+ if (s.kind === "block") {
21006
+ return { s, w: blockWidth(s.label ?? s.id), h: C2.BLOCK_H, children: [] };
21007
+ }
21008
+ const children = s.children.map(measure);
21009
+ if (children.length === 0) return { s, w: C2.BLOCK_MIN_W, h: C2.BLOCK_H, children };
21010
+ if (s.kind === "series") {
21011
+ const w2 = children.reduce((acc, c) => acc + c.w, 0) + C2.H_GAP * (children.length - 1);
21012
+ const h2 = Math.max(...children.map((c) => c.h));
21013
+ return { s, w: w2, h: h2, children };
21014
+ }
21015
+ const innerW = Math.max(...children.map((c) => c.w));
21016
+ const w = innerW + 2 * C2.SPLIT_STUB;
21017
+ const h = children.reduce((acc, c) => acc + c.h, 0) + C2.V_GAP * (children.length - 1);
21018
+ return { s, w, h, children };
21019
+ };
21020
+ const place = (m, x, yc2) => {
21021
+ const s = m.s;
21022
+ if (s.kind === "block") {
21023
+ const r7 = rById.get(s.id);
21024
+ blocks.push({
21025
+ block: s,
21026
+ x,
21027
+ y: yc2 - C2.BLOCK_H / 2,
21028
+ width: m.w,
21029
+ height: C2.BLOCK_H,
21030
+ ...r7 !== void 0 ? { R: r7 } : {},
21031
+ isSpof: spof.has(s.id),
21032
+ critical: analysis.criticalBlock === s.id
21033
+ });
21034
+ return { entryX: x, exitX: x + m.w };
21035
+ }
21036
+ if (s.kind === "series") {
21037
+ let cursor = x;
21038
+ let prevExit = null;
21039
+ let firstEntry = x;
21040
+ let lastExit = x;
21041
+ m.children.forEach((cm, i) => {
21042
+ const ep2 = place(cm, cursor, yc2);
21043
+ if (i === 0) firstEntry = ep2.entryX;
21044
+ if (prevExit !== null) wires.push({ path: `M ${r6(prevExit)} ${r6(yc2)} L ${r6(ep2.entryX)} ${r6(yc2)}` });
21045
+ prevExit = ep2.exitX;
21046
+ lastExit = ep2.exitX;
21047
+ cursor = ep2.exitX + C2.H_GAP;
21048
+ });
21049
+ return { entryX: firstEntry, exitX: lastExit };
21050
+ }
21051
+ const innerW = Math.max(...m.children.map((c) => c.w));
21052
+ const splitX = x + C2.NODE_R;
21053
+ const mergeX = x + m.w - C2.NODE_R;
21054
+ const childBandX = x + C2.SPLIT_STUB;
21055
+ nodes.push({ kind: "split", x: splitX, y: yc2 });
21056
+ nodes.push({ kind: "join", x: mergeX, y: yc2 });
21057
+ let runY = yc2 - m.h / 2;
21058
+ for (const cm of m.children) {
21059
+ const childYc = runY + cm.h / 2;
21060
+ const childStartX = childBandX + (innerW - cm.w) / 2;
21061
+ const ep2 = place(cm, childStartX, childYc);
21062
+ wires.push({ path: `M ${r6(splitX)} ${r6(yc2)} L ${r6(splitX)} ${r6(childYc)} L ${r6(ep2.entryX)} ${r6(childYc)}` });
21063
+ wires.push({ path: `M ${r6(ep2.exitX)} ${r6(childYc)} L ${r6(mergeX)} ${r6(childYc)} L ${r6(mergeX)} ${r6(yc2)}` });
21064
+ runY += cm.h + C2.V_GAP;
21065
+ }
21066
+ if (s.kind === "kofn") {
21067
+ marks.push({ x: mergeX + 6, y: yc2 - m.h / 2 - 6, text: `${s.k}/${s.n ?? m.children.length}` });
21068
+ }
21069
+ return { entryX: splitX, exitX: mergeX };
21070
+ };
21071
+ const rootM = measure(ast.root);
21072
+ const headerH = (ast.title ? C2.TITLE_H : 0) + C2.HEADER_H;
21073
+ const yc = C2.CANVAS_PAD + headerH + rootM.h / 2;
21074
+ const originX = C2.CANVAS_PAD + C2.TERM_STUB;
21075
+ const ep = place(rootM, originX, yc);
21076
+ const inX = C2.CANVAS_PAD;
21077
+ const outX = ep.exitX + C2.TERM_STUB;
21078
+ nodes.push({ kind: "in", x: inX, y: yc });
21079
+ nodes.push({ kind: "out", x: outX, y: yc });
21080
+ wires.push({ path: `M ${r6(inX)} ${r6(yc)} L ${r6(ep.entryX)} ${r6(yc)}` });
21081
+ wires.push({ path: `M ${r6(ep.exitX)} ${r6(yc)} L ${r6(outX)} ${r6(yc)}` });
21082
+ let maxX = outX;
21083
+ let maxY = yc + rootM.h / 2;
21084
+ for (const b of blocks) {
21085
+ maxX = Math.max(maxX, b.x + b.width);
21086
+ const capLines = (b.R !== void 0 ? 1 : 0) + (b.block.label && b.block.label !== b.block.id ? 1 : 0);
21087
+ maxY = Math.max(maxY, b.y + b.height + (capLines > 0 ? C2.CAP_GAP + capLines * C2.CAP_LINE_H : 0));
21088
+ }
21089
+ for (const mk of marks) maxX = Math.max(maxX, mk.x + 24);
21090
+ return {
21091
+ ast,
21092
+ analysis,
21093
+ blocks,
21094
+ nodes,
21095
+ wires,
21096
+ marks,
21097
+ width: Math.ceil(maxX + C2.CANVAS_PAD),
21098
+ height: Math.ceil(maxY + C2.CANVAS_PAD)
21099
+ };
21100
+ }
21101
+ function r6(n) {
21102
+ return Math.round(n * 10) / 10;
21103
+ }
21104
+
21105
+ // src/diagrams/rbd/renderer.ts
21106
+ function renderRbd(text2, config) {
21107
+ const ast = parseRbd(text2);
21108
+ const layout = layoutRbd(ast);
21109
+ return renderRbdLayout(layout, config);
21110
+ }
21111
+ function renderRbdLayout(layout, config) {
21112
+ const theme = resolveReliabilityTheme(config?.theme ?? "default");
21113
+ const fontFamily = config?.fontFamily ?? DEFAULT_FONT_FAMILY;
21114
+ const pad = config?.padding ?? 0;
21115
+ const { ast, analysis } = layout;
21116
+ const width = layout.width + pad * 2;
21117
+ const height = layout.height + pad * 2;
21118
+ const a11y = ast.title ?? "Reliability block diagram";
21119
+ const styleBlock = el(
21120
+ "style",
21121
+ {},
21122
+ `
21123
+ .sx-rbd-bg { fill: ${theme.bg}; }
21124
+ .sx-rbd-wire { fill: none; stroke: ${theme.edgeStroke}; stroke-width: ${STROKE_WIDTH.normal}; }
21125
+ .sx-rbd-node { fill: ${theme.edgeStroke}; stroke: none; }
21126
+ .sx-rbd-term { fill: ${theme.eventFill}; stroke: ${theme.eventStroke}; stroke-width: ${STROKE_WIDTH.normal}; }
21127
+ .sx-rbd-block { fill: ${theme.eventFill}; stroke: ${theme.eventStroke}; stroke-width: ${STROKE_WIDTH.normal}; }
21128
+ .sx-rbd-block[data-spof="true"] { stroke: ${theme.spofStroke}; stroke-width: ${STROKE_WIDTH.thick}; }
21129
+ .sx-rbd-block[data-critical="true"] { stroke: ${theme.gateStroke}; stroke-width: 2.25; }
21130
+ .sx-rbd-label { fill: ${theme.eventStroke}; font-size: ${FONT_SIZE.label}px; font-weight: 600; }
21131
+ .sx-rbd-r { fill: ${theme.probText}; font-size: ${FONT_SIZE.small}px; font-weight: 600; }
21132
+ .sx-rbd-mark { fill: ${theme.gateStroke}; font-size: ${FONT_SIZE.small}px; font-weight: 700; }
21133
+ .sx-rbd-rsys { fill: ${theme.probText}; font-size: ${FONT_SIZE.label + 1}px; font-weight: 700; }
21134
+ .sx-rbd-title { fill: ${theme.eventStroke}; font-size: ${FONT_SIZE.title}px; font-weight: 700; }
21135
+ `.trim()
21136
+ );
21137
+ const children = [
21138
+ title(a11y),
21139
+ desc(summarise6(layout)),
21140
+ styleBlock,
21141
+ rect({ x: 0, y: 0, width, height, class: "sx-rbd-bg" })
21142
+ ];
21143
+ const inner = [];
21144
+ if (ast.title) {
21145
+ inner.push(
21146
+ text(
21147
+ { x: RBD_CONST.CANVAS_PAD, y: 22, class: "sx-rbd-title", "font-family": fontFamily },
21148
+ ast.title
21149
+ )
21150
+ );
21151
+ }
21152
+ inner.push(
21153
+ text(
21154
+ {
21155
+ x: layout.width / 2,
21156
+ y: (ast.title ? RBD_CONST.TITLE_H : 0) + 18,
21157
+ class: "sx-rbd-rsys",
21158
+ "text-anchor": "middle"
21159
+ },
21160
+ systemLabel(analysis)
21161
+ )
21162
+ );
21163
+ for (const w of layout.wires) inner.push(path({ d: w.path, class: "sx-rbd-wire" }));
21164
+ for (const n of layout.nodes) {
21165
+ if (n.kind === "in" || n.kind === "out") {
21166
+ inner.push(circle({ cx: n.x, cy: n.y, r: 6, class: "sx-rbd-term", "data-node": n.kind }));
21167
+ } else {
21168
+ inner.push(circle({ cx: n.x, cy: n.y, r: RBD_CONST.NODE_R, class: "sx-rbd-node", "data-node": n.kind }));
21169
+ }
21170
+ }
21171
+ for (const mk of layout.marks) {
21172
+ inner.push(text({ x: mk.x, y: mk.y, class: "sx-rbd-mark" }, mk.text));
21173
+ }
21174
+ for (const b of layout.blocks) inner.push(renderBlock(b));
21175
+ children.push(
21176
+ group({ transform: pad ? `translate(${pad}, ${pad})` : void 0, "font-family": fontFamily }, inner)
21177
+ );
21178
+ return svgRoot(
21179
+ {
21180
+ width,
21181
+ height,
21182
+ viewBox: `0 0 ${width} ${height}`,
21183
+ role: "img",
21184
+ "aria-label": a11y,
21185
+ "data-diagram-type": "rbd"
21186
+ },
21187
+ children
21188
+ );
21189
+ }
21190
+ function renderBlock(b) {
21191
+ const cx = b.x + b.width / 2;
21192
+ const cy = b.y + b.height / 2;
21193
+ const label = b.block.label ?? b.block.id;
21194
+ const parts = [
21195
+ rect({
21196
+ x: b.x,
21197
+ y: b.y,
21198
+ width: b.width,
21199
+ height: b.height,
21200
+ rx: RBD_CONST.BLOCK_RX,
21201
+ class: "sx-rbd-block",
21202
+ ...b.isSpof ? { "data-spof": "true" } : {},
21203
+ ...b.critical && !b.isSpof ? { "data-critical": "true" } : {}
21204
+ }),
21205
+ multilineText(
21206
+ { x: cx, y: cy, class: "sx-rbd-label", "text-anchor": "middle", "dominant-baseline": "middle" },
21207
+ wrap4(label, 18),
21208
+ 13
21209
+ )
21210
+ ];
21211
+ if (b.R !== void 0) {
21212
+ parts.push(
21213
+ text(
21214
+ { x: cx, y: b.y + b.height + RBD_CONST.CAP_GAP, class: "sx-rbd-r", "text-anchor": "middle" },
21215
+ `R=${fmtR(b.R)}`
21216
+ )
21217
+ );
21218
+ }
21219
+ return group(
21220
+ {
21221
+ class: "sx-rbd-block-g",
21222
+ "data-id": b.block.id,
21223
+ ...b.R !== void 0 ? { "data-r": String(b.R) } : {},
21224
+ ...b.isSpof ? { "data-spof": "true" } : {},
21225
+ ...b.critical ? { "data-critical": "true" } : {}
21226
+ },
21227
+ parts
21228
+ );
21229
+ }
21230
+ function systemLabel(analysis) {
21231
+ if (analysis.systemReliability === void 0) {
21232
+ const miss = analysis.missing.length > 0 ? ` \u2014 missing R on ${analysis.missing.join(", ")}` : "";
21233
+ return `System reliability: n/a${miss}`;
21234
+ }
21235
+ return `System reliability R = ${fmtR(analysis.systemReliability)}`;
21236
+ }
21237
+ function fmtR(n) {
21238
+ if (n >= 1) return "1";
21239
+ if (n <= 0) return "0";
21240
+ for (let p = 5; p <= 9; p++) {
21241
+ const s = parseFloat(n.toPrecision(p));
21242
+ if (s < 1) return String(s);
21243
+ }
21244
+ return String(parseFloat(n.toPrecision(9)));
21245
+ }
21246
+ function summarise6(layout) {
21247
+ const { analysis } = layout;
21248
+ const n = layout.blocks.length;
21249
+ const parts = [`Reliability block diagram: ${n} block${n === 1 ? "" : "s"}.`];
21250
+ if (analysis.systemReliability !== void 0) {
21251
+ parts.push(`System reliability R = ${fmtR(analysis.systemReliability)}.`);
21252
+ } else if (analysis.missing.length > 0) {
21253
+ parts.push(`System reliability n/a \u2014 missing R on ${analysis.missing.join(", ")}.`);
21254
+ }
21255
+ const spofs = analysis.blocks.filter((b) => b.isSpof).map((b) => b.id);
21256
+ if (spofs.length > 0) parts.push(`Single point${spofs.length > 1 ? "s" : ""} of failure: ${spofs.join(", ")}.`);
21257
+ if (analysis.criticalBlock) parts.push(`Highest reliability-importance block: ${analysis.criticalBlock}.`);
21258
+ for (const note of analysis.notes) parts.push(note);
21259
+ for (const w of analysis.warnings) parts.push(w);
21260
+ return parts.join(" ");
21261
+ }
21262
+ function wrap4(s, perLine) {
21263
+ if (s.length <= perLine) return s;
21264
+ const words = s.split(/\s+/);
21265
+ const lines = [];
21266
+ let cur = "";
21267
+ for (const w of words) {
21268
+ if (cur && cur.length + 1 + w.length > perLine) {
21269
+ lines.push(cur);
21270
+ cur = w;
21271
+ } else cur = cur ? `${cur} ${w}` : w;
21272
+ }
21273
+ if (cur) lines.push(cur);
21274
+ if (lines.length > 2) {
21275
+ lines.length = 2;
21276
+ lines[1] = lines[1].slice(0, perLine - 1) + "\u2026";
21277
+ }
21278
+ return lines.join("<br/>");
21279
+ }
21280
+
21281
+ // src/diagrams/rbd/index.ts
21282
+ var rbd = {
21283
+ type: "rbd",
21284
+ detect(text2) {
21285
+ return /^\s*(rbd|reliability(?:blockdiagram)?|reliability-block-diagram)\b/i.test(text2);
21286
+ },
21287
+ parse: parseRbd,
21288
+ render(text2, config) {
21289
+ return renderRbd(text2, config);
21290
+ }
21291
+ };
21292
+
20238
21293
  // src/diagrams/causalloop/parser.ts
20239
21294
  var CausalLoopParseError = class extends Error {
20240
21295
  constructor(message, line2) {
@@ -20928,7 +21983,7 @@ function renderCausalLoopLayout(layout, config) {
20928
21983
  );
20929
21984
  const children = [
20930
21985
  title(a11y),
20931
- desc(summarise5(layout)),
21986
+ desc(summarise7(layout)),
20932
21987
  styleBlock,
20933
21988
  el("rect", { x: 0, y: 0, width, height, class: "sx-cld-bg" })
20934
21989
  ];
@@ -21042,17 +22097,17 @@ function arrowhead(x, y, tx, ty) {
21042
22097
  return polygon({ points: `${tip} ${p1} ${p2}`, class: "sx-cld-arrow" });
21043
22098
  }
21044
22099
  function renderGlyph(g) {
21045
- const r6 = g.r;
22100
+ const r7 = g.r;
21046
22101
  const startAng = -Math.PI / 2;
21047
22102
  const sweep = 300 * Math.PI / 180;
21048
22103
  const endAng = g.clockwise ? startAng + sweep : startAng - sweep;
21049
- const sx = g.cx + r6 * Math.cos(startAng);
21050
- const sy = g.cy + r6 * Math.sin(startAng);
21051
- const ex = g.cx + r6 * Math.cos(endAng);
21052
- const ey = g.cy + r6 * Math.sin(endAng);
22104
+ const sx = g.cx + r7 * Math.cos(startAng);
22105
+ const sy = g.cy + r7 * Math.sin(startAng);
22106
+ const ex = g.cx + r7 * Math.cos(endAng);
22107
+ const ey = g.cy + r7 * Math.sin(endAng);
21053
22108
  const largeArc = 1;
21054
22109
  const sweepFlag = g.clockwise ? 1 : 0;
21055
- const arc = `M ${fmt4(sx)} ${fmt4(sy)} A ${r6} ${r6} 0 ${largeArc} ${sweepFlag} ${fmt4(ex)} ${fmt4(ey)}`;
22110
+ const arc = `M ${fmt4(sx)} ${fmt4(sy)} A ${r7} ${r7} 0 ${largeArc} ${sweepFlag} ${fmt4(ex)} ${fmt4(ey)}`;
21056
22111
  const dir = g.clockwise ? 1 : -1;
21057
22112
  const tx = -Math.sin(endAng) * dir;
21058
22113
  const ty = Math.cos(endAng) * dir;
@@ -21097,7 +22152,7 @@ function glyphArrow(x, y, tx, ty) {
21097
22152
  const p2 = `${fmt4(bx - px * wide)},${fmt4(by - py * wide)}`;
21098
22153
  return polygon({ points: `${fmt4(x)},${fmt4(y)} ${p1} ${p2}`, class: "sx-cld-glyph-head" });
21099
22154
  }
21100
- function summarise5(layout) {
22155
+ function summarise7(layout) {
21101
22156
  const { ast, analysis } = layout;
21102
22157
  const parts = [
21103
22158
  `Causal loop diagram${ast.title ? ` "${ast.title}"` : ""}: ${ast.variables.length} variable${ast.variables.length === 1 ? "" : "s"}, ${ast.links.length} causal link${ast.links.length === 1 ? "" : "s"}.`
@@ -21146,7 +22201,7 @@ var MarkovParseError = class extends Error {
21146
22201
  };
21147
22202
  var OPENERS2 = ['"', "\u201C", "\u300C", "\u300E", "\xAB"];
21148
22203
  var CLOSERS2 = ['"', "\u201D", "\u300D", "\u300F", "\xBB"];
21149
- function tokenize6(s) {
22204
+ function tokenize7(s) {
21150
22205
  const out = [];
21151
22206
  let i = 0;
21152
22207
  while (i < s.length) {
@@ -21231,7 +22286,7 @@ function parseMarkov(text2) {
21231
22286
  if (trimmed.startsWith("#") || trimmed.startsWith("//")) continue;
21232
22287
  if (!sawHeader && /^(markov|markovchain)\b/i.test(trimmed)) {
21233
22288
  sawHeader = true;
21234
- const toks = tokenize6(trimmed);
22289
+ const toks = tokenize7(trimmed);
21235
22290
  const titleTok = toks.find((t, idx) => idx > 0 && t.quoted);
21236
22291
  if (titleTok) ast.title = titleTok.text;
21237
22292
  else if (toks[1] && !toks[1].quoted) ast.title = toks.slice(1).map((t) => t.text).join(" ");
@@ -21289,7 +22344,7 @@ function parseMarkov(text2) {
21289
22344
  return ast;
21290
22345
  }
21291
22346
  function parseStateDecl(line2, lineNo, ensureState) {
21292
- const toks = tokenize6(normalizeKeyNums2(line2));
22347
+ const toks = tokenize7(normalizeKeyNums2(line2));
21293
22348
  const idTok = toks[1];
21294
22349
  if (!idTok || idTok.quoted) throw new MarkovParseError(`state is missing an id`, lineNo);
21295
22350
  const id = idTok.text;
@@ -21563,22 +22618,22 @@ function computeAbsorbing(P, order, classification) {
21563
22618
  const absorbing = order.filter((id) => absorbingSet.has(id));
21564
22619
  const pos = new Map(order.map((id, i) => [id, i]));
21565
22620
  const t = transient.length;
21566
- const r6 = absorbing.length;
22621
+ const r7 = absorbing.length;
21567
22622
  const Q = Array.from({ length: t }, () => new Array(t).fill(0));
21568
- const R = Array.from({ length: t }, () => new Array(r6).fill(0));
22623
+ const R = Array.from({ length: t }, () => new Array(r7).fill(0));
21569
22624
  for (let a = 0; a < t; a++) {
21570
22625
  const fi = pos.get(transient[a]);
21571
22626
  for (let b = 0; b < t; b++) Q[a][b] = P[fi][pos.get(transient[b])];
21572
- for (let b = 0; b < r6; b++) R[a][b] = P[fi][pos.get(absorbing[b])];
22627
+ for (let b = 0; b < r7; b++) R[a][b] = P[fi][pos.get(absorbing[b])];
21573
22628
  }
21574
22629
  const ImQ = Array.from(
21575
22630
  { length: t },
21576
22631
  (_, a) => Array.from({ length: t }, (_2, b) => (a === b ? 1 : 0) - Q[a][b])
21577
22632
  );
21578
22633
  const N = invert(ImQ);
21579
- const B = Array.from({ length: t }, () => new Array(r6).fill(0));
22634
+ const B = Array.from({ length: t }, () => new Array(r7).fill(0));
21580
22635
  for (let a = 0; a < t; a++) {
21581
- for (let b = 0; b < r6; b++) {
22636
+ for (let b = 0; b < r7; b++) {
21582
22637
  let s = 0;
21583
22638
  for (let c = 0; c < t; c++) s += N[a][c] * R[c][b];
21584
22639
  B[a][b] = s;
@@ -21850,11 +22905,11 @@ function curvedArcGeom(tr, a, b, bow, C2) {
21850
22905
  labelY: mid.y
21851
22906
  };
21852
22907
  }
21853
- function aimToBoundary(centre, target, r6) {
22908
+ function aimToBoundary(centre, target, r7) {
21854
22909
  const dx = target.x - centre.x;
21855
22910
  const dy = target.y - centre.y;
21856
22911
  const len = Math.hypot(dx, dy) || 1;
21857
- return { x: centre.x + dx / len * r6, y: centre.y + dy / len * r6 };
22912
+ return { x: centre.x + dx / len * r7, y: centre.y + dy / len * r7 };
21858
22913
  }
21859
22914
  function selfLoopGeom(tr, c, ringCenter, layout, C2) {
21860
22915
  let ox = c.x - ringCenter.x;
@@ -22088,8 +23143,8 @@ function renderMarkov(textOrAst, config) {
22088
23143
  }
22089
23144
  function fmt5(x) {
22090
23145
  if (!Number.isFinite(x)) return String(x);
22091
- const r6 = Math.round(x * 1e3) / 1e3;
22092
- return String(r6);
23146
+ const r7 = Math.round(x * 1e3) / 1e3;
23147
+ return String(r7);
22093
23148
  }
22094
23149
  function num(x) {
22095
23150
  return Math.round(x * 100) / 100;
@@ -22766,7 +23821,7 @@ function renderGitGraphLayout(layout, config) {
22766
23821
  const styleBlock = buildStyle2(pal, ast.showBranches);
22767
23822
  const children = [
22768
23823
  title(a11y),
22769
- desc(summarise6(layout)),
23824
+ desc(summarise8(layout)),
22770
23825
  styleBlock,
22771
23826
  rect({ x: 0, y: 0, width, height, class: "sx-gg-bg" })
22772
23827
  ];
@@ -22889,13 +23944,13 @@ function renderCommit(lc, ast, pal, fontFamily) {
22889
23944
  if (node.commitType !== "NORMAL") dataAttrs2["data-type"] = node.commitType;
22890
23945
  if (node.tag) dataAttrs2["data-tag"] = node.tag;
22891
23946
  if (node.commitType === "HIGHLIGHT") {
22892
- const r6 = GITGRAPH_CONST.SQUARE_R;
23947
+ const r7 = GITGRAPH_CONST.SQUARE_R;
22893
23948
  parts.push(
22894
23949
  rect({
22895
- x: x - r6,
22896
- y: y - r6,
22897
- width: r6 * 2,
22898
- height: r6 * 2,
23950
+ x: x - r7,
23951
+ y: y - r7,
23952
+ width: r7 * 2,
23953
+ height: r7 * 2,
22899
23954
  rx: 2,
22900
23955
  class: `sx-gg-node sx-gg-highlight sx-gg-stroke-c${ci}`
22901
23956
  })
@@ -23016,7 +24071,7 @@ ${laneRules}
23016
24071
  function num2(n) {
23017
24072
  return Number.isInteger(n) ? String(n) : n.toFixed(2);
23018
24073
  }
23019
- function summarise6(layout) {
24074
+ function summarise8(layout) {
23020
24075
  const c = layout.replay.commits.length;
23021
24076
  const b = layout.replay.branches.length;
23022
24077
  const merges = layout.replay.commits.filter((n) => n.isMerge).length;
@@ -23573,33 +24628,33 @@ function layoutEpc(ast) {
23573
24628
  const isLR = ast.direction === "lr";
23574
24629
  const layerCenter = [];
23575
24630
  let primary = EPC_CONST.CANVAS_PAD + (ast.title ? EPC_CONST.TITLE_H : 0);
23576
- for (let r6 = 0; r6 <= maxLayer; r6++) {
24631
+ for (let r7 = 0; r7 <= maxLayer; r7++) {
23577
24632
  const bandThickness = Math.max(
23578
24633
  0,
23579
- ...ranks[r6].map((id) => isLR ? sized.get(id).w : sized.get(id).h)
24634
+ ...ranks[r7].map((id) => isLR ? sized.get(id).w : sized.get(id).h)
23580
24635
  );
23581
- layerCenter[r6] = primary + bandThickness / 2;
24636
+ layerCenter[r7] = primary + bandThickness / 2;
23582
24637
  primary += bandThickness + EPC_CONST.LAYER_GAP;
23583
24638
  }
23584
24639
  const primaryExtent = primary - EPC_CONST.LAYER_GAP + EPC_CONST.CANVAS_PAD;
23585
24640
  const crossPos = /* @__PURE__ */ new Map();
23586
24641
  let maxCrossExtent = 0;
23587
24642
  const rankWidths = [];
23588
- for (let r6 = 0; r6 <= maxLayer; r6++) {
24643
+ for (let r7 = 0; r7 <= maxLayer; r7++) {
23589
24644
  let cursor = 0;
23590
- for (const id of ranks[r6]) {
24645
+ for (const id of ranks[r7]) {
23591
24646
  const s = sized.get(id);
23592
24647
  const span = isLR ? s.h : s.w;
23593
24648
  crossPos.set(id, cursor + span / 2);
23594
24649
  cursor += span + EPC_CONST.NODE_GAP;
23595
24650
  }
23596
24651
  const total = Math.max(0, cursor - EPC_CONST.NODE_GAP);
23597
- rankWidths[r6] = total;
24652
+ rankWidths[r7] = total;
23598
24653
  maxCrossExtent = Math.max(maxCrossExtent, total);
23599
24654
  }
23600
- for (let r6 = 0; r6 <= maxLayer; r6++) {
23601
- const shift = (maxCrossExtent - rankWidths[r6]) / 2 + EPC_CONST.CANVAS_PAD;
23602
- for (const id of ranks[r6]) crossPos.set(id, crossPos.get(id) + shift);
24655
+ for (let r7 = 0; r7 <= maxLayer; r7++) {
24656
+ const shift = (maxCrossExtent - rankWidths[r7]) / 2 + EPC_CONST.CANVAS_PAD;
24657
+ for (const id of ranks[r7]) crossPos.set(id, crossPos.get(id) + shift);
23603
24658
  }
23604
24659
  const backMargin = backSet.size > 0 ? EPC_CONST.BACK_MARGIN : 0;
23605
24660
  const crossExtent = maxCrossExtent + EPC_CONST.CANVAS_PAD * 2 + backMargin;
@@ -23677,15 +24732,15 @@ function longestPathLayers(ast, dagOut, dagIn) {
23677
24732
  }
23678
24733
  function orderRanks2(ranks, dagIn, ast) {
23679
24734
  const declIndex = new Map(ast.nodes.map((n, i) => [n.id, i]));
23680
- for (let r6 = 1; r6 < ranks.length; r6++) {
24735
+ for (let r7 = 1; r7 < ranks.length; r7++) {
23681
24736
  const prevIndex = /* @__PURE__ */ new Map();
23682
- ranks[r6 - 1].forEach((id, i) => prevIndex.set(id, i));
24737
+ ranks[r7 - 1].forEach((id, i) => prevIndex.set(id, i));
23683
24738
  const bary = /* @__PURE__ */ new Map();
23684
- for (const id of ranks[r6]) {
24739
+ for (const id of ranks[r7]) {
23685
24740
  const preds = (dagIn.get(id) ?? []).map((p) => prevIndex.get(p)).filter((v) => v !== void 0);
23686
24741
  bary.set(id, preds.length ? preds.reduce((a, b) => a + b, 0) / preds.length : declIndex.get(id) ?? 0);
23687
24742
  }
23688
- ranks[r6].sort((a, b) => {
24743
+ ranks[r7].sort((a, b) => {
23689
24744
  const d = (bary.get(a) ?? 0) - (bary.get(b) ?? 0);
23690
24745
  if (Math.abs(d) > 1e-9) return d;
23691
24746
  return (declIndex.get(a) ?? 0) - (declIndex.get(b) ?? 0);
@@ -23716,7 +24771,7 @@ function detectBackEdges(ast, out) {
23716
24771
  }
23717
24772
  colour.set(id, BLACK);
23718
24773
  };
23719
- for (const r6 of visitOrder) if ((colour.get(r6) ?? WHITE) === WHITE) dfs(r6);
24774
+ for (const r7 of visitOrder) if ((colour.get(r7) ?? WHITE) === WHITE) dfs(r7);
23720
24775
  return back;
23721
24776
  }
23722
24777
  function routeEdge3(e, nodePos, crossExtent, back, isLR) {
@@ -23753,9 +24808,9 @@ function borderPoint(from, to, _isLR) {
23753
24808
  const dx = to.cx - from.cx;
23754
24809
  const dy = to.cy - from.cy;
23755
24810
  if (from.node.kind === "connector") {
23756
- const r6 = EPC_CONST.CONN_R;
24811
+ const r7 = EPC_CONST.CONN_R;
23757
24812
  const len = Math.hypot(dx, dy) || 1;
23758
- return { x: from.cx + dx / len * r6, y: from.cy + dy / len * r6 };
24813
+ return { x: from.cx + dx / len * r7, y: from.cy + dy / len * r7 };
23759
24814
  }
23760
24815
  const hw = from.width / 2;
23761
24816
  const hh = from.height / 2;
@@ -23857,7 +24912,7 @@ function renderEpcLayout(layout, config) {
23857
24912
  );
23858
24913
  const children = [
23859
24914
  title(a11y),
23860
- desc(summarise7(layout)),
24915
+ desc(summarise9(layout)),
23861
24916
  styleBlock,
23862
24917
  defs([
23863
24918
  el("marker", {
@@ -23910,7 +24965,7 @@ function renderNode3(n) {
23910
24965
  parts.push(hexagon(n.cx, n.cy, n.width, n.height, "sx-epc-event"));
23911
24966
  parts.push(multilineText(
23912
24967
  { x: n.cx, y: n.cy, class: "sx-epc-label", "text-anchor": "middle", "dominant-baseline": "middle" },
23913
- wrap4(label, 18),
24968
+ wrap5(label, 18),
23914
24969
  14
23915
24970
  ));
23916
24971
  } else if (node.kind === "function") {
@@ -23925,7 +24980,7 @@ function renderNode3(n) {
23925
24980
  }));
23926
24981
  parts.push(multilineText(
23927
24982
  { x: n.cx, y: n.cy, class: "sx-epc-label", "text-anchor": "middle", "dominant-baseline": "middle" },
23928
- wrap4(label, 18),
24983
+ wrap5(label, 18),
23929
24984
  14
23930
24985
  ));
23931
24986
  } else {
@@ -23936,9 +24991,9 @@ function renderNode3(n) {
23936
24991
  ));
23937
24992
  }
23938
24993
  if (n.flagged) {
23939
- const r6 = node.kind === "connector" ? EPC_CONST.CONN_R + 5 : 0;
24994
+ const r7 = node.kind === "connector" ? EPC_CONST.CONN_R + 5 : 0;
23940
24995
  if (node.kind === "connector") {
23941
- parts.push(circle({ cx: n.cx, cy: n.cy, r: r6, class: "sx-epc-flagring" }));
24996
+ parts.push(circle({ cx: n.cx, cy: n.cy, r: r7, class: "sx-epc-flagring" }));
23942
24997
  } else {
23943
24998
  parts.push(rect({
23944
24999
  x: n.cx - n.width / 2 - 5,
@@ -23993,7 +25048,7 @@ function renderEdge6(e) {
23993
25048
  if (e.edge.label) {
23994
25049
  parts.push(text(
23995
25050
  { x: e.mid.x, y: e.mid.y - 4, class: "sx-epc-edge-label", "text-anchor": "middle" },
23996
- clip4(e.edge.label, 24)
25051
+ clip5(e.edge.label, 24)
23997
25052
  ));
23998
25053
  }
23999
25054
  return group(
@@ -24001,7 +25056,7 @@ function renderEdge6(e) {
24001
25056
  parts
24002
25057
  );
24003
25058
  }
24004
- function summarise7(layout) {
25059
+ function summarise9(layout) {
24005
25060
  const { ast, analysis } = layout;
24006
25061
  const counts = { event: 0, function: 0, connector: 0 };
24007
25062
  for (const n of ast.nodes) counts[n.kind]++;
@@ -24021,10 +25076,10 @@ function describeWellFormed(analysis) {
24021
25076
  if (warns) bits.push(`${warns} warning${warns > 1 ? "s" : ""}`);
24022
25077
  return `${bits.join(", ")}.`;
24023
25078
  }
24024
- function clip4(s, n) {
25079
+ function clip5(s, n) {
24025
25080
  return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
24026
25081
  }
24027
- function wrap4(s, perLine) {
25082
+ function wrap5(s, perLine) {
24028
25083
  if (s.length <= perLine) return s;
24029
25084
  const words = s.split(/\s+/);
24030
25085
  const lines = [];
@@ -24038,7 +25093,7 @@ function wrap4(s, perLine) {
24038
25093
  if (cur) lines.push(cur);
24039
25094
  if (lines.length > 3) {
24040
25095
  lines.length = 3;
24041
- lines[2] = clip4(lines[2], perLine);
25096
+ lines[2] = clip5(lines[2], perLine);
24042
25097
  }
24043
25098
  return lines.join("<br/>");
24044
25099
  }
@@ -24614,7 +25669,7 @@ function renderIdef0Layout(layout, config) {
24614
25669
  );
24615
25670
  const children = [
24616
25671
  title(a11y),
24617
- desc(summarise8(layout)),
25672
+ desc(summarise10(layout)),
24618
25673
  styleBlock,
24619
25674
  rect({ x: 0, y: 0, width, height, class: "sx-idef0-bg" })
24620
25675
  ];
@@ -24665,7 +25720,7 @@ function renderBox5(b) {
24665
25720
  "text-anchor": "middle",
24666
25721
  "dominant-baseline": "middle"
24667
25722
  },
24668
- wrap5(b.box.name, 18),
25723
+ wrap6(b.box.name, 18),
24669
25724
  14
24670
25725
  ),
24671
25726
  // Box number in the lower-right interior corner.
@@ -24768,11 +25823,11 @@ function renderTitleBlock(width, height, node, title2) {
24768
25823
  text({ x: x0 + 6, y: y + 13, class: "sx-idef0-tb-key" }, "NODE"),
24769
25824
  text({ x: x0 + 6, y: y + 27, class: "sx-idef0-tb-text" }, node),
24770
25825
  text({ x: c1 + 6, y: y + 13, class: "sx-idef0-tb-key" }, "TITLE"),
24771
- text({ x: c1 + 6, y: y + 27, class: "sx-idef0-tb-text" }, clip5(title2 || "\u2014", 60)),
25826
+ text({ x: c1 + 6, y: y + 27, class: "sx-idef0-tb-text" }, clip6(title2 || "\u2014", 60)),
24772
25827
  text({ x: c2 + 6, y: y + 13, class: "sx-idef0-tb-key" }, "NUMBER")
24773
25828
  ]);
24774
25829
  }
24775
- function summarise8(layout) {
25830
+ function summarise10(layout) {
24776
25831
  const { ast } = layout;
24777
25832
  const counts = {};
24778
25833
  for (const a of ast.arrows) counts[a.role] = (counts[a.role] ?? 0) + 1;
@@ -24787,10 +25842,10 @@ function summarise8(layout) {
24787
25842
  for (const w of ast.warnings) parts.push(w);
24788
25843
  return parts.join(" ");
24789
25844
  }
24790
- function clip5(s, n) {
25845
+ function clip6(s, n) {
24791
25846
  return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
24792
25847
  }
24793
- function wrap5(s, perLine) {
25848
+ function wrap6(s, perLine) {
24794
25849
  if (s.length <= perLine) return s;
24795
25850
  const words = s.split(/\s+/);
24796
25851
  const lines = [];
@@ -24806,7 +25861,7 @@ function wrap5(s, perLine) {
24806
25861
  if (cur) lines.push(cur);
24807
25862
  if (lines.length > 3) {
24808
25863
  lines.length = 3;
24809
- lines[2] = clip5(lines[2], perLine);
25864
+ lines[2] = clip6(lines[2], perLine);
24810
25865
  }
24811
25866
  return lines.join("<br/>");
24812
25867
  }
@@ -24837,7 +25892,7 @@ for (const [open, close] of Object.entries(QUOTE_PAIRS)) {
24837
25892
  QUOTE_FOLD.set(close, '"');
24838
25893
  }
24839
25894
  }
24840
- function normalizeQuotes2(text2) {
25895
+ function normalizeQuotes3(text2) {
24841
25896
  let out = "";
24842
25897
  for (const ch of text2) out += QUOTE_FOLD.get(ch) ?? ch;
24843
25898
  return out;
@@ -24868,7 +25923,7 @@ function parseThreatModel(text2) {
24868
25923
  flows: [],
24869
25924
  boundaries: []
24870
25925
  };
24871
- const rawLines = normalizeQuotes2(text2).split(/\r?\n/);
25926
+ const rawLines = normalizeQuotes3(text2).split(/\r?\n/);
24872
25927
  const byId = /* @__PURE__ */ new Map();
24873
25928
  const declareNode = (id, kind, label, lineNo, logStore) => {
24874
25929
  if (byId.has(id)) {
@@ -25327,13 +26382,13 @@ function layoutThreatModel(ast) {
25327
26382
  }
25328
26383
  const boundaries = [];
25329
26384
  for (const b of ast.boundaries) {
25330
- let l = Infinity, t = Infinity, r6 = -Infinity, bm = -Infinity;
26385
+ let l = Infinity, t = Infinity, r7 = -Infinity, bm = -Infinity;
25331
26386
  for (const m of b.members) {
25332
26387
  const mn = nodeMap.get(m);
25333
26388
  if (!mn) continue;
25334
26389
  l = Math.min(l, mn.x);
25335
26390
  t = Math.min(t, mn.y);
25336
- r6 = Math.max(r6, mn.x + mn.w);
26391
+ r7 = Math.max(r7, mn.x + mn.w);
25337
26392
  bm = Math.max(bm, mn.y + mn.h);
25338
26393
  }
25339
26394
  if (!Number.isFinite(l)) continue;
@@ -25342,7 +26397,7 @@ function layoutThreatModel(ast) {
25342
26397
  name: b.name,
25343
26398
  x: l - p,
25344
26399
  y: t - p - TM_CONST.BOUNDARY_HEADER,
25345
- w: r6 - l + p * 2,
26400
+ w: r7 - l + p * 2,
25346
26401
  h: bm - t + p * 2 + TM_CONST.BOUNDARY_HEADER
25347
26402
  });
25348
26403
  }
@@ -25376,9 +26431,9 @@ function edgePoint2(n, tx, ty) {
25376
26431
  const dy = ty - n.cy;
25377
26432
  if (dx === 0 && dy === 0) return { x: n.cx, y: n.cy };
25378
26433
  if (n.kind === "process") {
25379
- const r6 = TM_CONST.PROCESS_R;
26434
+ const r7 = TM_CONST.PROCESS_R;
25380
26435
  const len = Math.hypot(dx, dy);
25381
- return { x: n.cx + dx / len * r6, y: n.cy + dy / len * r6 };
26436
+ return { x: n.cx + dx / len * r7, y: n.cy + dy / len * r7 };
25382
26437
  }
25383
26438
  const hw = n.w / 2;
25384
26439
  const hh = n.h / 2;
@@ -25433,7 +26488,7 @@ function renderThreatModelLayout(layout, config) {
25433
26488
  ]);
25434
26489
  const children = [
25435
26490
  title(a11y),
25436
- desc(summarise9(layout)),
26491
+ desc(summarise11(layout)),
25437
26492
  styleBlock,
25438
26493
  markerDefs,
25439
26494
  rect({ x: 0, y: 0, width, height, class: "sx-tm-bg" })
@@ -25650,7 +26705,7 @@ function arrowMarker2(id, cls, crossing) {
25650
26705
  function round8(n) {
25651
26706
  return Math.round(n * 100) / 100;
25652
26707
  }
25653
- function summarise9(layout) {
26708
+ function summarise11(layout) {
25654
26709
  const a = layout.analysis;
25655
26710
  const counts = {
25656
26711
  external: layout.nodes.filter((n) => n.kind === "external").length,
@@ -26028,9 +27083,9 @@ function weldGlyph(type, cx, y, dir, cls) {
26028
27083
  return [path({ d: `M ${round9(cx - rr)} ${round9(y)} A ${round9(rr)} ${round9(rr)} 0 0 ${sweep} ${round9(cx + rr)} ${round9(y)}`, class: cls, fill: "none" })];
26029
27084
  }
26030
27085
  case "surfacing": {
26031
- const r6 = W / 4;
27086
+ const r7 = W / 4;
26032
27087
  const yy = y + dir * 3;
26033
- const bump = (off) => path({ d: `M ${round9(cx - W / 2)} ${round9(off)} a ${round9(r6)} ${round9(r6)} 0 0 ${dir > 0 ? 1 : 0} ${round9(W / 2)} 0 a ${round9(r6)} ${round9(r6)} 0 0 ${dir > 0 ? 1 : 0} ${round9(W / 2)} 0`, class: cls, fill: "none" });
27088
+ const bump = (off) => path({ d: `M ${round9(cx - W / 2)} ${round9(off)} a ${round9(r7)} ${round9(r7)} 0 0 ${dir > 0 ? 1 : 0} ${round9(W / 2)} 0 a ${round9(r7)} ${round9(r7)} 0 0 ${dir > 0 ? 1 : 0} ${round9(W / 2)} 0`, class: cls, fill: "none" });
26034
27089
  return [bump(y), bump(yy)];
26035
27090
  }
26036
27091
  case "edge":
@@ -26902,7 +27957,7 @@ function computeMaxLW(subtreeRoots, maxLabelWidth) {
26902
27957
  if (maxLW[n.depth] === void 0 || m.width > maxLW[n.depth]) maxLW[n.depth] = m.width;
26903
27958
  for (const c of n.children) walk(c);
26904
27959
  };
26905
- for (const r6 of subtreeRoots) walk(r6);
27960
+ for (const r7 of subtreeRoots) walk(r7);
26906
27961
  return maxLW;
26907
27962
  }
26908
27963
  function buildColumns(maxLW, firstColStartX, rootDepth) {
@@ -27269,9 +28324,9 @@ function renderNode5(n, color, theme, fontFamily, orderClass) {
27269
28324
  for (let i = 0; i < lineCount; i++) {
27270
28325
  const line2 = n.lines[i];
27271
28326
  const cy = topY + (i + 0.5) * lh;
27272
- const r6 = renderLine2(line2, textLeft, cy, fs, fontFamily, weight, theme);
27273
- decorations.push(...r6.decorations);
27274
- children.push(r6.textElement);
28327
+ const r7 = renderLine2(line2, textLeft, cy, fs, fontFamily, weight, theme);
28328
+ decorations.push(...r7.decorations);
28329
+ children.push(r7.textElement);
27275
28330
  }
27276
28331
  const ux1 = n.x - n.labelWidth / 2;
27277
28332
  const ux2 = n.x + n.labelWidth / 2;
@@ -27995,11 +29050,11 @@ function parseMatrix(text2) {
27995
29050
  const gm = v.match(/^(\d+)\s*x\s*(\d+)$/);
27996
29051
  if (gm) {
27997
29052
  const c = Number(gm[1]);
27998
- const r6 = Number(gm[2]);
29053
+ const r7 = Number(gm[2]);
27999
29054
  st.ast.cols = c;
28000
- st.ast.rows = r6;
28001
- if (c === 2 && r6 === 2) st.ast.grid = "2x2";
28002
- else if (c === 3 && r6 === 3) st.ast.grid = "3x3";
29055
+ st.ast.rows = r7;
29056
+ if (c === 2 && r7 === 2) st.ast.grid = "2x2";
29057
+ else if (c === 3 && r7 === 3) st.ast.grid = "3x3";
28003
29058
  else st.ast.grid = "NxM";
28004
29059
  }
28005
29060
  continue;
@@ -28212,11 +29267,11 @@ function punnettFooter(result) {
28212
29267
  }
28213
29268
  function computeQfdImportance(qfd) {
28214
29269
  const raw = qfd.hows.map(() => 0);
28215
- for (const r6 of qfd.relationships) {
28216
- if (r6.how < 0 || r6.how >= qfd.hows.length) continue;
28217
- if (r6.what < 0 || r6.what >= qfd.whats.length) continue;
28218
- const w = qfd.whats[r6.what].weight;
28219
- raw[r6.how] += w * r6.strength;
29270
+ for (const r7 of qfd.relationships) {
29271
+ if (r7.how < 0 || r7.how >= qfd.hows.length) continue;
29272
+ if (r7.what < 0 || r7.what >= qfd.whats.length) continue;
29273
+ const w = qfd.whats[r7.what].weight;
29274
+ raw[r7.how] += w * r7.strength;
28220
29275
  }
28221
29276
  const total = raw.reduce((acc, v) => acc + v, 0);
28222
29277
  return raw.map((importance, how) => ({
@@ -28237,12 +29292,12 @@ function estimateWidth(text2) {
28237
29292
  const cjk = (text2.match(/[\u3000-\u9fff]/g) ?? []).length;
28238
29293
  return (text2.length - cjk) * CHAR_W2 + cjk * 12 + 8;
28239
29294
  }
28240
- function clamp01(v) {
29295
+ function clamp012(v) {
28241
29296
  return Math.max(0.02, Math.min(0.98, v));
28242
29297
  }
28243
29298
  function placePoint(p, plot) {
28244
- const nx = clamp01(p.x);
28245
- const ny = clamp01(p.y);
29299
+ const nx = clamp012(p.x);
29300
+ const ny = clamp012(p.y);
28246
29301
  const px = plot.x0 + nx * plot.w;
28247
29302
  const py = plot.y0 + (1 - ny) * plot.h;
28248
29303
  return { px, py };
@@ -28258,8 +29313,8 @@ function computeRadius(p, maxSize, plot, scale) {
28258
29313
  }
28259
29314
  const maxArea = Math.PI * maxRadius * maxRadius;
28260
29315
  const area = ratio * maxArea;
28261
- const r6 = Math.sqrt(area / Math.PI);
28262
- return Math.max(minRadius, r6);
29316
+ const r7 = Math.sqrt(area / Math.PI);
29317
+ return Math.max(minRadius, r7);
28263
29318
  }
28264
29319
  function resolveLabelCollisions(points, plot, mode) {
28265
29320
  if (mode === "off") {
@@ -28460,20 +29515,20 @@ function layoutMatrix(ast) {
28460
29515
  }
28461
29516
  for (const p of ast.points) {
28462
29517
  const { px, py } = placePoint(p, plot);
28463
- const r6 = computeRadius(p, maxSize, plot, ast.config.bubbleScale);
29518
+ const r7 = computeRadius(p, maxSize, plot, ast.config.bubbleScale);
28464
29519
  const width = estimateWidth(p.label);
28465
29520
  const label = {
28466
29521
  text: p.label,
28467
29522
  ax: px,
28468
29523
  ay: py,
28469
- lx: px + r6 + 4 + width / 2,
28470
- ly: py - r6 - 4,
29524
+ lx: px + r7 + 4 + width / 2,
29525
+ ly: py - r7 - 4,
28471
29526
  width,
28472
29527
  height: LABEL_H,
28473
29528
  external: false,
28474
29529
  textAnchor: "middle"
28475
29530
  };
28476
- points.push({ point: p, px, py, r: r6, label });
29531
+ points.push({ point: p, px, py, r: r7, label });
28477
29532
  if (p.category) categoriesSet.add(p.category);
28478
29533
  }
28479
29534
  resolveLabelCollisions(points, plot, ast.config.labelCollision);
@@ -28623,7 +29678,7 @@ function renderQuadrantBackground(ast, lay) {
28623
29678
  return group(
28624
29679
  { id: "sx-matrix-quad-bg" },
28625
29680
  rects.map(
28626
- (r6) => rect({ x: r6.x, y: r6.y, width: r6.w, height: r6.h, fill: r6.fill, "fill-opacity": 0.55 })
29681
+ (r7) => rect({ x: r7.x, y: r7.y, width: r7.w, height: r7.h, fill: r7.fill, "fill-opacity": 0.55 })
28627
29682
  )
28628
29683
  );
28629
29684
  }
@@ -29275,9 +30330,9 @@ function renderOnePoint(pl2, categories) {
29275
30330
  class: "sx-matrix-bubble"
29276
30331
  });
29277
30332
  } else if (shape === "diamond") {
29278
- const r6 = pl2.r;
30333
+ const r7 = pl2.r;
29279
30334
  shapeEl = polygon({
29280
- points: `${pl2.px},${pl2.py - r6} ${pl2.px + r6},${pl2.py} ${pl2.px},${pl2.py + r6} ${pl2.px - r6},${pl2.py}`,
30335
+ points: `${pl2.px},${pl2.py - r7} ${pl2.px + r7},${pl2.py} ${pl2.px},${pl2.py + r7} ${pl2.px - r7},${pl2.py}`,
29281
30336
  fill: color,
29282
30337
  "fill-opacity": fillOpacity,
29283
30338
  stroke,
@@ -29285,9 +30340,9 @@ function renderOnePoint(pl2, categories) {
29285
30340
  class: "sx-matrix-bubble"
29286
30341
  });
29287
30342
  } else {
29288
- const r6 = pl2.r;
30343
+ const r7 = pl2.r;
29289
30344
  shapeEl = polygon({
29290
- points: `${pl2.px},${pl2.py - r6} ${pl2.px + r6},${pl2.py + r6 * 0.8} ${pl2.px - r6},${pl2.py + r6 * 0.8}`,
30345
+ points: `${pl2.px},${pl2.py - r7} ${pl2.px + r7},${pl2.py + r7 * 0.8} ${pl2.px - r7},${pl2.py + r7 * 0.8}`,
29291
30346
  fill: color,
29292
30347
  "fill-opacity": fillOpacity,
29293
30348
  stroke,
@@ -29419,15 +30474,15 @@ function renderSipocAST(ast, config) {
29419
30474
  const items = sipoc[def.key];
29420
30475
  const isProcess = def.key === "process";
29421
30476
  const cellNodes = [];
29422
- for (let r6 = 0; r6 < lay.rows; r6++) {
29423
- const cellY = lay.y0 + lay.headerH + r6 * lay.rowH;
29424
- const item = items[r6];
29425
- const cellClass = isProcess ? "sx-sipoc-process" : r6 % 2 === 0 ? "sx-sipoc-cell" : "sx-sipoc-cell-alt";
30477
+ for (let r7 = 0; r7 < lay.rows; r7++) {
30478
+ const cellY = lay.y0 + lay.headerH + r7 * lay.rowH;
30479
+ const item = items[r7];
30480
+ const cellClass = isProcess ? "sx-sipoc-process" : r7 % 2 === 0 ? "sx-sipoc-cell" : "sx-sipoc-cell-alt";
29426
30481
  cellNodes.push(
29427
30482
  rect({ x: colX, y: cellY, width: lay.colW, height: lay.rowH, class: cellClass })
29428
30483
  );
29429
30484
  if (item) {
29430
- const label = isProcess ? `${r6 + 1}. ${item}` : item;
30485
+ const label = isProcess ? `${r7 + 1}. ${item}` : item;
29431
30486
  const lines = wrapToLines(label, maxChars, 2);
29432
30487
  const lineH = 14;
29433
30488
  const startY = cellY + lay.rowH / 2 - (lines.length - 1) * lineH / 2;
@@ -29490,17 +30545,17 @@ var CORR_LABEL = {
29490
30545
  "-": "negative",
29491
30546
  "--": "strong negative"
29492
30547
  };
29493
- function renderQfdRelationshipSymbol(strength, cx, cy, r6) {
30548
+ function renderQfdRelationshipSymbol(strength, cx, cy, r7) {
29494
30549
  if (strength === 9) {
29495
30550
  return group({}, [
29496
- circle({ cx, cy, r: r6, fill: "none", stroke: "#2563eb", "stroke-width": 1.4 }),
29497
- circle({ cx, cy, r: r6 * 0.5, class: "sx-qfd-rel-strong" })
30551
+ circle({ cx, cy, r: r7, fill: "none", stroke: "#2563eb", "stroke-width": 1.4 }),
30552
+ circle({ cx, cy, r: r7 * 0.5, class: "sx-qfd-rel-strong" })
29498
30553
  ]);
29499
30554
  }
29500
30555
  if (strength === 3) {
29501
- return circle({ cx, cy, r: r6, class: "sx-qfd-rel-medium" });
30556
+ return circle({ cx, cy, r: r7, class: "sx-qfd-rel-medium" });
29502
30557
  }
29503
- const t = r6 * 0.95;
30558
+ const t = r7 * 0.95;
29504
30559
  return polygon({
29505
30560
  points: `${cx},${cy - t} ${cx + t},${cy + t * 0.85} ${cx - t},${cy + t * 0.85}`,
29506
30561
  class: "sx-qfd-rel-weak"
@@ -29598,15 +30653,15 @@ function renderQfdAST(ast, config) {
29598
30653
  )
29599
30654
  );
29600
30655
  const gridNodes = [];
29601
- for (let r6 = 0; r6 < lay.rows; r6++) {
29602
- const y = lay.gridY0 + r6 * lay.cellH;
30656
+ for (let r7 = 0; r7 < lay.rows; r7++) {
30657
+ const y = lay.gridY0 + r7 * lay.cellH;
29603
30658
  gridNodes.push(
29604
30659
  rect({
29605
30660
  x: lay.gridX0,
29606
30661
  y,
29607
30662
  width: lay.cols * lay.cellW,
29608
30663
  height: lay.cellH,
29609
- class: r6 % 2 === 0 ? "sx-qfd-cellbg" : "sx-qfd-cellbg-alt"
30664
+ class: r7 % 2 === 0 ? "sx-qfd-cellbg" : "sx-qfd-cellbg-alt"
29610
30665
  })
29611
30666
  );
29612
30667
  }
@@ -29784,18 +30839,18 @@ function renderPunnettAST(ast, config) {
29784
30839
  nodes.push(rect({ x: cx, y: lay.y0, width: lay.cellW, height: lay.headerH, class: "sx-punnett-header" }));
29785
30840
  nodes.push(text({ x: cx + lay.cellW / 2, y: lay.y0 + lay.headerH / 2, class: "sx-punnett-gamete" }, g));
29786
30841
  });
29787
- result.gametes2.forEach((g, r6) => {
29788
- const cy = gy0 + r6 * lay.cellH;
30842
+ result.gametes2.forEach((g, r7) => {
30843
+ const cy = gy0 + r7 * lay.cellH;
29789
30844
  nodes.push(rect({ x: lay.x0, y: cy, width: lay.headerW, height: lay.cellH, class: "sx-punnett-header" }));
29790
30845
  nodes.push(text({ x: lay.x0 + lay.headerW / 2, y: cy + lay.cellH / 2, class: "sx-punnett-gamete" }, g));
29791
30846
  });
29792
- for (let r6 = 0; r6 < result.grid.length; r6++) {
29793
- const row = result.grid[r6];
30847
+ for (let r7 = 0; r7 < result.grid.length; r7++) {
30848
+ const row = result.grid[r7];
29794
30849
  for (let c = 0; c < row.length; c++) {
29795
30850
  const cell = row[c];
29796
30851
  const color = phenoColor.get(cell.phenotypeKey);
29797
30852
  const cx = gx0 + c * lay.cellW;
29798
- const cy = gy0 + r6 * lay.cellH;
30853
+ const cy = gy0 + r7 * lay.cellH;
29799
30854
  nodes.push(rect({ x: cx, y: cy, width: lay.cellW, height: lay.cellH, fill: color.tint, class: "sx-punnett-cell" }));
29800
30855
  nodes.push(text({ x: cx + lay.cellW / 2, y: cy + lay.cellH / 2, class: "sx-punnett-genotype" }, cell.genotype));
29801
30856
  }
@@ -30348,12 +31403,12 @@ function buildColumnAssignment(ast) {
30348
31403
  const ids = ast.entities.map((e) => e.id);
30349
31404
  const idToIdx = new Map(ids.map((id, i) => [id, i]));
30350
31405
  const pairs = [];
30351
- for (const r6 of ast.refs) {
30352
- const f = parseRefSide(r6.from);
30353
- const t = parseRefSide(r6.to);
31406
+ for (const r7 of ast.refs) {
31407
+ const f = parseRefSide(r7.from);
31408
+ const t = parseRefSide(r7.to);
30354
31409
  if (idToIdx.has(f.table) && idToIdx.has(t.table)) {
30355
- const oneIsTo = isOne(r6.toCard) && !isOne(r6.fromCard);
30356
- const oneIsFrom = isOne(r6.fromCard) && !isOne(r6.toCard);
31410
+ const oneIsTo = isOne(r7.toCard) && !isOne(r7.fromCard);
31411
+ const oneIsFrom = isOne(r7.fromCard) && !isOne(r7.toCard);
30357
31412
  if (oneIsTo) pairs.push({ from: t.table, to: f.table });
30358
31413
  else if (oneIsFrom) pairs.push({ from: f.table, to: t.table });
30359
31414
  else pairs.push({ from: f.table, to: t.table });
@@ -30388,9 +31443,9 @@ function isOne(c) {
30388
31443
  function reorderByBarycenter(layerToEnts, layers, refs) {
30389
31444
  if (layers.length < 2) return;
30390
31445
  const neighbors = /* @__PURE__ */ new Map();
30391
- for (const r6 of refs) {
30392
- const a = parseRefSide(r6.from).table;
30393
- const b = parseRefSide(r6.to).table;
31446
+ for (const r7 of refs) {
31447
+ const a = parseRefSide(r7.from).table;
31448
+ const b = parseRefSide(r7.to).table;
30394
31449
  if (!neighbors.has(a)) neighbors.set(a, /* @__PURE__ */ new Set());
30395
31450
  if (!neighbors.has(b)) neighbors.set(b, /* @__PURE__ */ new Set());
30396
31451
  neighbors.get(a).add(b);
@@ -30520,9 +31575,9 @@ function layoutErd(ast) {
30520
31575
  const layers = Array.from(layerToEnts.keys()).sort((a, b) => a - b);
30521
31576
  reorderByBarycenter(layerToEnts, layers, ast.refs);
30522
31577
  const neighbors = /* @__PURE__ */ new Map();
30523
- for (const r6 of ast.refs) {
30524
- const a = parseRefSide(r6.from).table;
30525
- const b = parseRefSide(r6.to).table;
31578
+ for (const r7 of ast.refs) {
31579
+ const a = parseRefSide(r7.from).table;
31580
+ const b = parseRefSide(r7.to).table;
30526
31581
  if (!neighbors.has(a)) neighbors.set(a, /* @__PURE__ */ new Set());
30527
31582
  if (!neighbors.has(b)) neighbors.set(b, /* @__PURE__ */ new Set());
30528
31583
  neighbors.get(a).add(b);
@@ -30600,17 +31655,17 @@ function layoutErd(ast) {
30600
31655
  const placedById = new Map(placed.map((p) => [p.entity.id, p]));
30601
31656
  const edges = [];
30602
31657
  const bendBucketUses = /* @__PURE__ */ new Map();
30603
- for (const r6 of ast.refs) {
30604
- const fromTable = parseRefSide(r6.from).table;
30605
- const toTable = parseRefSide(r6.to).table;
31658
+ for (const r7 of ast.refs) {
31659
+ const fromTable = parseRefSide(r7.from).table;
31660
+ const toTable = parseRefSide(r7.to).table;
30606
31661
  const a = placedById.get(fromTable);
30607
31662
  const b = placedById.get(toTable);
30608
31663
  if (!a || !b) continue;
30609
- const fromCol = parseRefSide(r6.from).column;
30610
- const toCol = parseRefSide(r6.to).column;
31664
+ const fromCol = parseRefSide(r7.from).column;
31665
+ const toCol = parseRefSide(r7.to).column;
30611
31666
  const route = routeOrthogonal(a, b, fromCol, toCol, bendBucketUses);
30612
31667
  edges.push({
30613
- ref: r6,
31668
+ ref: r7,
30614
31669
  path: route.path,
30615
31670
  fromAnchor: route.fromAnchor,
30616
31671
  toAnchor: route.toAnchor,
@@ -30627,7 +31682,7 @@ function layoutErd(ast) {
30627
31682
  }
30628
31683
  function rowYByColumn(e, col) {
30629
31684
  if (col) {
30630
- const idx = e.rows.findIndex((r6) => r6.attribute.name.toLowerCase() === col.toLowerCase());
31685
+ const idx = e.rows.findIndex((r7) => r7.attribute.name.toLowerCase() === col.toLowerCase());
30631
31686
  if (idx >= 0) return e.y + e.rows[idx].yCenter;
30632
31687
  }
30633
31688
  return e.y + e.height / 2;
@@ -31407,8 +32462,8 @@ var PITCH = 14;
31407
32462
  function rectShape(x, y, w, h, attrs) {
31408
32463
  return el("rect", { x, y, width: w, height: h, ...attrs });
31409
32464
  }
31410
- function circShape(cx, cy, r6, attrs) {
31411
- return el("circle", { cx, cy, r: r6, ...attrs });
32465
+ function circShape(cx, cy, r7, attrs) {
32466
+ return el("circle", { cx, cy, r: r7, ...attrs });
31412
32467
  }
31413
32468
  function lineShape(x1, y1, x2, y2, attrs) {
31414
32469
  return el("line", { x1, y1, x2, y2, ...attrs });
@@ -32129,13 +33184,13 @@ function renderSubstrate(sub) {
32129
33184
  { y: sub.y + BB_CONST.BOARD_PAD_Y, type: "top" },
32130
33185
  { y: sub.y + sub.height - BB_CONST.BOARD_PAD_Y - BB_CONST.RAIL_HEIGHT, type: "bottom" }
32131
33186
  ];
32132
- for (const r6 of rails) {
33187
+ for (const r7 of rails) {
32133
33188
  elements.push(path({
32134
- d: `M ${sub.x + BB_CONST.BOARD_PAD_X} ${r6.y + 4} L ${sub.x + sub.width - BB_CONST.BOARD_PAD_X} ${r6.y + 4}`,
33189
+ d: `M ${sub.x + BB_CONST.BOARD_PAD_X} ${r7.y + 4} L ${sub.x + sub.width - BB_CONST.BOARD_PAD_X} ${r7.y + 4}`,
32135
33190
  class: "lt-bb-rail-stripe-pos"
32136
33191
  }));
32137
33192
  elements.push(path({
32138
- d: `M ${sub.x + BB_CONST.BOARD_PAD_X} ${r6.y + BB_CONST.RAIL_HEIGHT - 4} L ${sub.x + sub.width - BB_CONST.BOARD_PAD_X} ${r6.y + BB_CONST.RAIL_HEIGHT - 4}`,
33193
+ d: `M ${sub.x + BB_CONST.BOARD_PAD_X} ${r7.y + BB_CONST.RAIL_HEIGHT - 4} L ${sub.x + sub.width - BB_CONST.BOARD_PAD_X} ${r7.y + BB_CONST.RAIL_HEIGHT - 4}`,
32139
33194
  class: "lt-bb-rail-stripe-neg"
32140
33195
  }));
32141
33196
  if (sub.railsBreak) {
@@ -32143,7 +33198,7 @@ function renderSubstrate(sub) {
32143
33198
  const breakX2 = breakX1 + PITCH2;
32144
33199
  elements.push(rect({
32145
33200
  x: breakX1,
32146
- y: r6.y,
33201
+ y: r7.y,
32147
33202
  width: breakX2 - breakX1,
32148
33203
  height: BB_CONST.RAIL_HEIGHT,
32149
33204
  fill: "#e7d8b6"
@@ -32151,8 +33206,8 @@ function renderSubstrate(sub) {
32151
33206
  }
32152
33207
  for (let c = 1; c <= sub.cols; c++) {
32153
33208
  const cx = sub.x + BB_CONST.BOARD_PAD_X + BB_CONST.ROW_LABEL_W + PITCH2 / 2 + (c - 1) * PITCH2;
32154
- elements.push(circle({ cx, cy: r6.y + 4, r: 1.4, class: "lt-bb-hole-rail" }));
32155
- elements.push(circle({ cx, cy: r6.y + BB_CONST.RAIL_HEIGHT - 4, r: 1.4, class: "lt-bb-hole-rail" }));
33209
+ elements.push(circle({ cx, cy: r7.y + 4, r: 1.4, class: "lt-bb-hole-rail" }));
33210
+ elements.push(circle({ cx, cy: r7.y + BB_CONST.RAIL_HEIGHT - 4, r: 1.4, class: "lt-bb-hole-rail" }));
32156
33211
  }
32157
33212
  }
32158
33213
  }
@@ -32179,10 +33234,10 @@ function renderSubstrate(sub) {
32179
33234
  elements.push(text({ x: sub.x + sub.width - BB_CONST.BOARD_PAD_X - 4, y: yBot, class: "lt-bb-row-label" }, rowsBot[i]));
32180
33235
  }
32181
33236
  for (let c = 1; c <= sub.cols; c++) {
32182
- for (let r6 = 0; r6 < 10; r6++) {
33237
+ for (let r7 = 0; r7 < 10; r7++) {
32183
33238
  const cx = sub.x + BB_CONST.BOARD_PAD_X + BB_CONST.ROW_LABEL_W + PITCH2 / 2 + (c - 1) * PITCH2;
32184
- let cy = gridY0 + r6 * PITCH2;
32185
- if (r6 >= 5) cy += BB_CONST.TROUGH;
33239
+ let cy = gridY0 + r7 * PITCH2;
33240
+ if (r7 >= 5) cy += BB_CONST.TROUGH;
32186
33241
  elements.push(circle({ cx, cy, r: 1.6, class: "lt-bb-hole" }));
32187
33242
  }
32188
33243
  }
@@ -32684,34 +33739,34 @@ function parseFlowLine(ln, flows, objectOwner, poolByLabel) {
32684
33739
  connectorLen = 3;
32685
33740
  } else if (rest.startsWith("--?")) {
32686
33741
  kind = "conditional";
32687
- let r6 = rest.slice(3).trimStart();
32688
- const q = takeQuoted(r6);
33742
+ let r7 = rest.slice(3).trimStart();
33743
+ const q = takeQuoted(r7);
32689
33744
  if (q) {
32690
33745
  connectorLabel = q.value;
32691
- r6 = q.rest.trimStart();
33746
+ r7 = q.rest.trimStart();
32692
33747
  }
32693
- if (!r6.startsWith("-->")) {
33748
+ if (!r7.startsWith("-->")) {
32694
33749
  throw new BpmnParseError(
32695
- `conditional flow must end with --> (got '${r6.slice(0, 20)}')`,
33750
+ `conditional flow must end with --> (got '${r7.slice(0, 20)}')`,
32696
33751
  ln.no
32697
33752
  );
32698
33753
  }
32699
- connectorLen = rest.length - r6.length + 3;
33754
+ connectorLen = rest.length - r7.length + 3;
32700
33755
  } else if (rest.startsWith("--*")) {
32701
33756
  kind = "default";
32702
- let r6 = rest.slice(3).trimStart();
32703
- const q = takeQuoted(r6);
33757
+ let r7 = rest.slice(3).trimStart();
33758
+ const q = takeQuoted(r7);
32704
33759
  if (q) {
32705
33760
  connectorLabel = q.value;
32706
- r6 = q.rest.trimStart();
33761
+ r7 = q.rest.trimStart();
32707
33762
  }
32708
- if (!r6.startsWith("-->")) {
33763
+ if (!r7.startsWith("-->")) {
32709
33764
  throw new BpmnParseError(
32710
- `default flow must end with --> (got '${r6.slice(0, 20)}')`,
33765
+ `default flow must end with --> (got '${r7.slice(0, 20)}')`,
32711
33766
  ln.no
32712
33767
  );
32713
33768
  }
32714
- connectorLen = rest.length - r6.length + 3;
33769
+ connectorLen = rest.length - r7.length + 3;
32715
33770
  } else if (rest.startsWith("-->")) {
32716
33771
  kind = "sequence";
32717
33772
  connectorLen = 3;
@@ -32804,8 +33859,8 @@ function objBox(o) {
32804
33859
  if ("gatewayKind" in o) {
32805
33860
  return { w: BPMN_CONST.gatewaySize, h: BPMN_CONST.gatewaySize };
32806
33861
  }
32807
- const r6 = BPMN_CONST.eventRadius;
32808
- return { w: r6 * 2, h: r6 * 2 };
33862
+ const r7 = BPMN_CONST.eventRadius;
33863
+ return { w: r7 * 2, h: r7 * 2 };
32809
33864
  }
32810
33865
  function layoutBpmn(ast) {
32811
33866
  const allObjects = [
@@ -33416,11 +34471,11 @@ function renderGateway(ol, t) {
33416
34471
  const g = ol.obj;
33417
34472
  const cx = ol.x + ol.width / 2;
33418
34473
  const cy = ol.y + ol.height / 2;
33419
- const r6 = ol.width / 2;
33420
- const points = `${cx},${cy - r6} ${cx + r6},${cy} ${cx},${cy + r6} ${cx - r6},${cy}`;
34474
+ const r7 = ol.width / 2;
34475
+ const points = `${cx},${cy - r7} ${cx + r7},${cy} ${cx},${cy + r7} ${cx - r7},${cy}`;
33421
34476
  const inner = [];
33422
34477
  if (g.gatewayKind === "xor") {
33423
- const a = r6 * 0.42;
34478
+ const a = r7 * 0.42;
33424
34479
  inner.push(
33425
34480
  el("path", {
33426
34481
  d: `M ${cx - a} ${cy - a} L ${cx + a} ${cy + a} M ${cx + a} ${cy - a} L ${cx - a} ${cy + a}`,
@@ -33430,7 +34485,7 @@ function renderGateway(ol, t) {
33430
34485
  })
33431
34486
  );
33432
34487
  } else if (g.gatewayKind === "and") {
33433
- const a = r6 * 0.5;
34488
+ const a = r7 * 0.5;
33434
34489
  inner.push(
33435
34490
  el("path", {
33436
34491
  d: `M ${cx - a} ${cy} L ${cx + a} ${cy} M ${cx} ${cy - a} L ${cx} ${cy + a}`,
@@ -33444,7 +34499,7 @@ function renderGateway(ol, t) {
33444
34499
  el("circle", {
33445
34500
  cx,
33446
34501
  cy,
33447
- r: r6 * 0.45,
34502
+ r: r7 * 0.45,
33448
34503
  fill: "none",
33449
34504
  stroke: t.gatewayGlyph,
33450
34505
  "stroke-width": 2
@@ -33455,13 +34510,13 @@ function renderGateway(ol, t) {
33455
34510
  el("circle", {
33456
34511
  cx,
33457
34512
  cy,
33458
- r: r6 * 0.55,
34513
+ r: r7 * 0.55,
33459
34514
  fill: "none",
33460
34515
  stroke: t.gatewayGlyph,
33461
34516
  "stroke-width": 1
33462
34517
  })
33463
34518
  );
33464
- const pr = r6 * 0.32;
34519
+ const pr = r7 * 0.32;
33465
34520
  const pts = [];
33466
34521
  for (let k = 0; k < 5; k++) {
33467
34522
  const ang = -Math.PI / 2 + k * 2 * Math.PI / 5;
@@ -33503,7 +34558,7 @@ function renderEvent2(ol, t) {
33503
34558
  const e = ol.obj;
33504
34559
  const cx = ol.x + ol.width / 2;
33505
34560
  const cy = ol.y + ol.height / 2;
33506
- const r6 = ol.width / 2;
34561
+ const r7 = ol.width / 2;
33507
34562
  const isEnd = e.kind === "end";
33508
34563
  const isIntermediate = e.kind === "intermediate";
33509
34564
  const strokeW = isEnd ? 3 : 1.2;
@@ -33514,7 +34569,7 @@ function renderEvent2(ol, t) {
33514
34569
  el("circle", {
33515
34570
  cx,
33516
34571
  cy,
33517
- r: r6,
34572
+ r: r7,
33518
34573
  fill,
33519
34574
  stroke: ring,
33520
34575
  "stroke-width": strokeW
@@ -33525,7 +34580,7 @@ function renderEvent2(ol, t) {
33525
34580
  el("circle", {
33526
34581
  cx,
33527
34582
  cy,
33528
- r: r6 - 3,
34583
+ r: r7 - 3,
33529
34584
  fill: "none",
33530
34585
  stroke: ring,
33531
34586
  "stroke-width": 1.2
@@ -33534,9 +34589,9 @@ function renderEvent2(ol, t) {
33534
34589
  }
33535
34590
  const filled = e.throwCatch === "throw" && (isIntermediate || isEnd);
33536
34591
  if (e.trigger === "message") {
33537
- children.push(messageGlyph(cx, cy, r6 * 0.55, filled, t));
34592
+ children.push(messageGlyph(cx, cy, r7 * 0.55, filled, t));
33538
34593
  } else if (e.trigger === "timer") {
33539
- children.push(timerGlyph(cx, cy, r6 * 0.55, t));
34594
+ children.push(timerGlyph(cx, cy, r7 * 0.55, t));
33540
34595
  }
33541
34596
  if (e.label) {
33542
34597
  children.push(
@@ -33579,22 +34634,22 @@ function messageGlyph(cx, cy, size, filled, t) {
33579
34634
  ]);
33580
34635
  }
33581
34636
  function timerGlyph(cx, cy, size, t) {
33582
- const r6 = size / 2;
34637
+ const r7 = size / 2;
33583
34638
  const ticks = [];
33584
34639
  for (let k = 0; k < 12; k++) {
33585
34640
  const ang = k * Math.PI / 6 - Math.PI / 2;
33586
- const t1x = cx + (r6 - 1.5) * Math.cos(ang);
33587
- const t1y = cy + (r6 - 1.5) * Math.sin(ang);
33588
- const t2x = cx + r6 * Math.cos(ang);
33589
- const t2y = cy + r6 * Math.sin(ang);
34641
+ const t1x = cx + (r7 - 1.5) * Math.cos(ang);
34642
+ const t1y = cy + (r7 - 1.5) * Math.sin(ang);
34643
+ const t2x = cx + r7 * Math.cos(ang);
34644
+ const t2y = cy + r7 * Math.sin(ang);
33590
34645
  ticks.push(`M ${t1x} ${t1y} L ${t2x} ${t2y}`);
33591
34646
  }
33592
34647
  return el("g", { class: "trigger-timer" }, [
33593
- el("circle", { cx, cy, r: r6, fill: "none", stroke: t.bpmnStroke, "stroke-width": 1 }),
34648
+ el("circle", { cx, cy, r: r7, fill: "none", stroke: t.bpmnStroke, "stroke-width": 1 }),
33594
34649
  el("path", { d: ticks.join(" "), stroke: t.bpmnStroke, "stroke-width": 0.8 }),
33595
34650
  // Hands
33596
34651
  el("path", {
33597
- d: `M ${cx} ${cy} L ${cx} ${cy - r6 * 0.7} M ${cx} ${cy} L ${cx + r6 * 0.5} ${cy}`,
34652
+ d: `M ${cx} ${cy} L ${cx} ${cy - r7 * 0.7} M ${cx} ${cy} L ${cx + r7 * 0.5} ${cy}`,
33598
34653
  stroke: t.bpmnStroke,
33599
34654
  "stroke-width": 1.2,
33600
34655
  "stroke-linecap": "round"
@@ -33665,8 +34720,8 @@ function parseStart(d) {
33665
34720
  if (!m) return null;
33666
34721
  return { x: parseFloat(m[1]), y: parseFloat(m[2]) };
33667
34722
  }
33668
- function diamondPoints(cx, cy, r6) {
33669
- return `${cx - r6},${cy} ${cx},${cy - r6} ${cx + r6},${cy} ${cx},${cy + r6}`;
34723
+ function diamondPoints(cx, cy, r7) {
34724
+ return `${cx - r7},${cy} ${cx},${cy - r7} ${cx + r7},${cy} ${cx},${cy + r7}`;
33670
34725
  }
33671
34726
 
33672
34727
  // src/diagrams/bpmn/index.ts
@@ -34869,7 +35924,7 @@ function wireClass(t) {
34869
35924
  return "lt-fbd-wire-any";
34870
35925
  }
34871
35926
  }
34872
- function renderBlock(lb) {
35927
+ function renderBlock2(lb) {
34873
35928
  const { x, y, width, height, block } = lb;
34874
35929
  const headerH = FBD_CONST.block_header_h;
34875
35930
  const parts = [];
@@ -35005,7 +36060,7 @@ function renderNetwork2(ln) {
35005
36060
  for (const j of ln.junctions) {
35006
36061
  parts.push(circle({ class: "lt-fbd-junction", cx: j.x, cy: j.y, r: 3 }));
35007
36062
  }
35008
- for (const b of ln.blocks) parts.push(renderBlock(b));
36063
+ for (const b of ln.blocks) parts.push(renderBlock2(b));
35009
36064
  return group({ class: "lt-fbd-network", "data-network": ln.network.index }, parts);
35010
36065
  }
35011
36066
  function renderFbdLayout(layout) {
@@ -36075,14 +37130,14 @@ function roundTable(seats, diaM) {
36075
37130
  draw: (c) => {
36076
37131
  const half = Math.min(c.w, c.h) / 2;
36077
37132
  const ring = Math.min(RING, half * 0.37);
36078
- const r6 = half - ring;
37133
+ const r7 = half - ring;
36079
37134
  const cx = c.w / 2;
36080
37135
  const cy = c.h / 2;
36081
- const parts = [circle({ class: "sx-fp-furn", cx: c.px(cx), cy: c.px(cy), r: c.px(r6) })];
37136
+ const parts = [circle({ class: "sx-fp-furn", cx: c.px(cx), cy: c.px(cy), r: c.px(r7) })];
36082
37137
  for (let i = 0; i < seats; i++) {
36083
37138
  const a = i / seats * 2 * Math.PI - Math.PI / 2;
36084
- const px0 = cx + (r6 + ring * 0.55) * Math.cos(a);
36085
- const py0 = cy + (r6 + ring * 0.55) * Math.sin(a);
37139
+ const px0 = cx + (r7 + ring * 0.55) * Math.cos(a);
37140
+ const py0 = cy + (r7 + ring * 0.55) * Math.sin(a);
36086
37141
  parts.push(chairAt(c.px, px0, py0, a * 180 / Math.PI + 90));
36087
37142
  }
36088
37143
  return parts.join("");
@@ -36232,11 +37287,11 @@ function uStairs(c) {
36232
37287
  return parts.join("");
36233
37288
  }
36234
37289
  function spiralStairs(c) {
36235
- const r6 = Math.min(c.w, c.h) / 2 - 0.02;
37290
+ const r7 = Math.min(c.w, c.h) / 2 - 0.02;
36236
37291
  const cx = c.w / 2;
36237
37292
  const cy = c.h / 2;
36238
37293
  const parts = [
36239
- circle({ class: "sx-fp-furn", cx: c.px(cx), cy: c.px(cy), r: c.px(r6) }),
37294
+ circle({ class: "sx-fp-furn", cx: c.px(cx), cy: c.px(cy), r: c.px(r7) }),
36240
37295
  circle({ class: "sx-fp-furn-line", cx: c.px(cx), cy: c.px(cy), r: c.px(0.08) })
36241
37296
  ];
36242
37297
  for (let i = 0; i < 12; i++) {
@@ -36246,12 +37301,12 @@ function spiralStairs(c) {
36246
37301
  class: "sx-fp-furn-line",
36247
37302
  x1: c.px(cx + 0.08 * Math.cos(a)),
36248
37303
  y1: c.px(cy + 0.08 * Math.sin(a)),
36249
- x2: c.px(cx + r6 * Math.cos(a)),
36250
- y2: c.px(cy + r6 * Math.sin(a))
37304
+ x2: c.px(cx + r7 * Math.cos(a)),
37305
+ y2: c.px(cy + r7 * Math.sin(a))
36251
37306
  })
36252
37307
  );
36253
37308
  }
36254
- const wr = r6 * 0.62;
37309
+ const wr = r7 * 0.62;
36255
37310
  const a0 = Math.PI * 0.75;
36256
37311
  const a1 = Math.PI * 1.9;
36257
37312
  const steps = 5;
@@ -36323,8 +37378,8 @@ var FLOORPLAN_SYMBOLS = {
36323
37378
  w: 0.5,
36324
37379
  h: 0.5,
36325
37380
  draw: (c) => {
36326
- const r6 = Math.min(c.w, c.h) / 2;
36327
- const parts = [circle({ class: "sx-fp-furn", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(r6) })];
37381
+ const r7 = Math.min(c.w, c.h) / 2;
37382
+ const parts = [circle({ class: "sx-fp-furn", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(r7) })];
36328
37383
  for (const a of [0, 60, 120, 180, 240, 300]) {
36329
37384
  const rad = a * Math.PI / 180;
36330
37385
  parts.push(
@@ -36332,8 +37387,8 @@ var FLOORPLAN_SYMBOLS = {
36332
37387
  class: "sx-fp-furn-line",
36333
37388
  x1: c.px(c.w / 2),
36334
37389
  y1: c.px(c.h / 2),
36335
- x2: c.px(c.w / 2 + (r6 - 0.03) * Math.cos(rad)),
36336
- y2: c.px(c.h / 2 + (r6 - 0.03) * Math.sin(rad))
37390
+ x2: c.px(c.w / 2 + (r7 - 0.03) * Math.cos(rad)),
37391
+ y2: c.px(c.h / 2 + (r7 - 0.03) * Math.sin(rad))
36337
37392
  })
36338
37393
  );
36339
37394
  }
@@ -36393,11 +37448,11 @@ var FLOORPLAN_SYMBOLS = {
36393
37448
  w: 0.35,
36394
37449
  h: 0.35,
36395
37450
  draw: (c) => {
36396
- const r6 = Math.min(c.w, c.h) / 2;
37451
+ const r7 = Math.min(c.w, c.h) / 2;
36397
37452
  return [
36398
- circle({ class: "sx-fp-furn", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(r6) }),
36399
- line({ class: "sx-fp-furn-line", x1: c.px(c.w / 2 - r6), y1: c.px(c.h / 2), x2: c.px(c.w / 2 + r6), y2: c.px(c.h / 2) }),
36400
- line({ class: "sx-fp-furn-line", x1: c.px(c.w / 2), y1: c.px(c.h / 2 - r6), x2: c.px(c.w / 2), y2: c.px(c.h / 2 + r6) })
37453
+ circle({ class: "sx-fp-furn", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(r7) }),
37454
+ line({ class: "sx-fp-furn-line", x1: c.px(c.w / 2 - r7), y1: c.px(c.h / 2), x2: c.px(c.w / 2 + r7), y2: c.px(c.h / 2) }),
37455
+ line({ class: "sx-fp-furn-line", x1: c.px(c.w / 2), y1: c.px(c.h / 2 - r7), x2: c.px(c.w / 2), y2: c.px(c.h / 2 + r7) })
36401
37456
  ].join("");
36402
37457
  }
36403
37458
  },
@@ -36473,23 +37528,23 @@ var FLOORPLAN_SYMBOLS = {
36473
37528
  underlay: true,
36474
37529
  // overhead fixture — never collides with floor furniture
36475
37530
  draw: (c) => {
36476
- const r6 = Math.min(c.w, c.h) / 2;
37531
+ const r7 = Math.min(c.w, c.h) / 2;
36477
37532
  const cx = c.w / 2;
36478
37533
  const cy = c.h / 2;
36479
37534
  const parts = [
36480
- circle({ class: "sx-fp-furn-dash", cx: c.px(cx), cy: c.px(cy), r: c.px(r6) }),
36481
- circle({ class: "sx-fp-furn", cx: c.px(cx), cy: c.px(cy), r: c.px(r6 * 0.18) })
37535
+ circle({ class: "sx-fp-furn-dash", cx: c.px(cx), cy: c.px(cy), r: c.px(r7) }),
37536
+ circle({ class: "sx-fp-furn", cx: c.px(cx), cy: c.px(cy), r: c.px(r7 * 0.18) })
36482
37537
  ];
36483
37538
  for (const a of [20, 110, 200, 290]) {
36484
37539
  const rad = a * Math.PI / 180;
36485
37540
  parts.push(
36486
37541
  el("ellipse", {
36487
37542
  class: "sx-fp-furn-line",
36488
- cx: c.px(cx + r6 * 0.55 * Math.cos(rad)),
36489
- cy: c.px(cy + r6 * 0.55 * Math.sin(rad)),
36490
- rx: c.px(r6 * 0.42),
36491
- ry: c.px(r6 * 0.15),
36492
- transform: `rotate(${a} ${c.px(cx + r6 * 0.55 * Math.cos(rad))} ${c.px(cy + r6 * 0.55 * Math.sin(rad))})`
37543
+ cx: c.px(cx + r7 * 0.55 * Math.cos(rad)),
37544
+ cy: c.px(cy + r7 * 0.55 * Math.sin(rad)),
37545
+ rx: c.px(r7 * 0.42),
37546
+ ry: c.px(r7 * 0.15),
37547
+ transform: `rotate(${a} ${c.px(cx + r7 * 0.55 * Math.cos(rad))} ${c.px(cy + r7 * 0.55 * Math.sin(rad))})`
36493
37548
  })
36494
37549
  );
36495
37550
  }
@@ -36866,11 +37921,11 @@ var FLOORPLAN_SYMBOLS = {
36866
37921
  w: 1,
36867
37922
  h: 1,
36868
37923
  draw: (c) => {
36869
- const r6 = Math.min(c.w, c.h) / 2;
37924
+ const r7 = Math.min(c.w, c.h) / 2;
36870
37925
  const cx = c.w / 2;
36871
37926
  const cy = c.h / 2;
36872
37927
  const parts = [
36873
- circle({ class: "sx-fp-furn-nofill", cx: c.px(cx), cy: c.px(cy), r: c.px(r6) }),
37928
+ circle({ class: "sx-fp-furn-nofill", cx: c.px(cx), cy: c.px(cy), r: c.px(r7) }),
36874
37929
  circle({ class: "sx-fp-furn-dot", cx: c.px(cx), cy: c.px(cy), r: c.px(0.04) })
36875
37930
  ];
36876
37931
  for (const a of [0, 45, 90, 135, 180, 225, 270, 315]) {
@@ -36878,10 +37933,10 @@ var FLOORPLAN_SYMBOLS = {
36878
37933
  parts.push(
36879
37934
  line({
36880
37935
  class: "sx-fp-furn-line",
36881
- x1: c.px(cx + (r6 - 0.09) * Math.cos(rad)),
36882
- y1: c.px(cy + (r6 - 0.09) * Math.sin(rad)),
36883
- x2: c.px(cx + r6 * Math.cos(rad)),
36884
- y2: c.px(cy + r6 * Math.sin(rad))
37936
+ x1: c.px(cx + (r7 - 0.09) * Math.cos(rad)),
37937
+ y1: c.px(cy + (r7 - 0.09) * Math.sin(rad)),
37938
+ x2: c.px(cx + r7 * Math.cos(rad)),
37939
+ y2: c.px(cy + r7 * Math.sin(rad))
36885
37940
  })
36886
37941
  );
36887
37942
  }
@@ -37031,10 +38086,10 @@ var FLOORPLAN_SYMBOLS = {
37031
38086
  w: 2,
37032
38087
  h: 2,
37033
38088
  draw: (c) => {
37034
- const r6 = Math.min(c.w, c.h) / 2;
38089
+ const r7 = Math.min(c.w, c.h) / 2;
37035
38090
  return [
37036
- circle({ class: "sx-fp-furn", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(r6) }),
37037
- circle({ class: "sx-fp-furn-line", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(r6 * 0.6) }),
38091
+ circle({ class: "sx-fp-furn", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(r7) }),
38092
+ circle({ class: "sx-fp-furn-line", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(r7 * 0.6) }),
37038
38093
  circle({ class: "sx-fp-furn-dot", cx: c.px(c.w / 2), cy: c.px(c.h / 2), r: c.px(0.07) })
37039
38094
  ].join("");
37040
38095
  }
@@ -37068,10 +38123,10 @@ var FloorplanParseError = class extends Error {
37068
38123
  };
37069
38124
  var isStr = (t) => t !== void 0 && "str" in t;
37070
38125
  var isWord = (t, w) => t !== void 0 && "word" in t && (w === void 0 || t.word === w);
37071
- function normalizeQuotes3(line2) {
38126
+ function normalizeQuotes4(line2) {
37072
38127
  return line2.replace(/[“”「」『』]/g, '"').replace(/[‘’]/g, "'");
37073
38128
  }
37074
- function tokenize7(line2) {
38129
+ function tokenize8(line2) {
37075
38130
  const out = [];
37076
38131
  const re = /"([^"]*)"|(\S+)/g;
37077
38132
  let m;
@@ -37081,7 +38136,7 @@ function tokenize7(line2) {
37081
38136
  }
37082
38137
  return out;
37083
38138
  }
37084
- function parseNum(t, what, ln) {
38139
+ function parseNum2(t, what, ln) {
37085
38140
  if (!isWord(t)) throw new FloorplanParseError(`expected a number for ${what}`, ln);
37086
38141
  const v = Number(t.word);
37087
38142
  if (!Number.isFinite(v)) throw new FloorplanParseError(`expected a number for ${what}, got "${t.word}"`, ln);
@@ -37134,7 +38189,7 @@ function parseHeader3(tok, ast, ln) {
37134
38189
  }
37135
38190
  function parseRoom(tok, ast, ln) {
37136
38191
  const id = parseId(tok.shift(), "a room id", ln);
37137
- if (ast.rooms.some((r6) => r6.id === id)) {
38192
+ if (ast.rooms.some((r7) => r7.id === id)) {
37138
38193
  throw new FloorplanParseError(`duplicate room id "${id}"`, ln);
37139
38194
  }
37140
38195
  const room = { id, label: id, w: 4, h: 3, line: ln };
@@ -37151,7 +38206,7 @@ function parseRoom(tok, ast, ln) {
37151
38206
  };
37152
38207
  } else if (t.word === "offset") {
37153
38208
  if (!room.rel) throw new FloorplanParseError(`"offset" requires a relative placement (right-of/left-of/above/below)`, ln);
37154
- room.rel.offset = parseNum(tok.shift(), "offset", ln);
38209
+ room.rel.offset = parseNum2(tok.shift(), "offset", ln);
37155
38210
  } else if (t.word === "align") {
37156
38211
  if (!room.rel) throw new FloorplanParseError(`"align" requires a relative placement (right-of/left-of/above/below)`, ln);
37157
38212
  const a = parseId(tok.shift(), "align (start|center|end)", ln);
@@ -37185,7 +38240,7 @@ function parseExtend(tok, ast, ln) {
37185
38240
  };
37186
38241
  } else if (t.word === "offset") {
37187
38242
  if (!ext.rel) throw new FloorplanParseError(`"offset" requires a relative placement (right-of/left-of/above/below)`, ln);
37188
- ext.rel.offset = parseNum(tok.shift(), "offset", ln);
38243
+ ext.rel.offset = parseNum2(tok.shift(), "offset", ln);
37189
38244
  } else if (t.word === "align") {
37190
38245
  if (!ext.rel) throw new FloorplanParseError(`"align" requires a relative placement (right-of/left-of/above/below)`, ln);
37191
38246
  const a = parseId(tok.shift(), "align (start|center|end)", ln);
@@ -37230,7 +38285,7 @@ function parseOpening(kind, tok, ast, ln) {
37230
38285
  const t = tok.shift();
37231
38286
  if (!isWord(t)) throw new FloorplanParseError(`${kind}: unexpected string "${t.str}"`, ln);
37232
38287
  else if (t.word === "at") op.pct = parsePct(tok.shift(), ln);
37233
- else if (t.word === "width") op.width = parseNum(tok.shift(), "width", ln);
38288
+ else if (t.word === "width") op.width = parseNum2(tok.shift(), "width", ln);
37234
38289
  else if (t.word === "hinge") {
37235
38290
  const h = parseId(tok.shift(), "hinge (left|right)", ln);
37236
38291
  if (h !== "left" && h !== "right") throw new FloorplanParseError(`hinge must be left|right, got "${h}"`, ln);
@@ -37271,7 +38326,7 @@ function parseFurniture(tok, ast, ln) {
37271
38326
  f.x = c.x;
37272
38327
  f.y = c.y;
37273
38328
  } else if (t.word === "size") f.size = parseDims(tok.shift(), "size", ln);
37274
- else if (t.word === "rotate") f.rotate = parseNum(tok.shift(), "rotate", ln);
38329
+ else if (t.word === "rotate") f.rotate = parseNum2(tok.shift(), "rotate", ln);
37275
38330
  else throw new FloorplanParseError(`furniture: unexpected token "${t.word}"`, ln);
37276
38331
  }
37277
38332
  ast.furniture.push(f);
@@ -37291,18 +38346,18 @@ function parseArray(mode, tok, ast, ln) {
37291
38346
  const t = tok.shift();
37292
38347
  if (!isWord(t)) throw new FloorplanParseError(`${mode}: unexpected string "${t.str}"`, ln);
37293
38348
  else if (t.word === "in") a.room = parseId(tok.shift(), `a room id after "in"`, ln);
37294
- else if (t.word === "rows") a.rows = parseNum(tok.shift(), "rows", ln);
37295
- else if (t.word === "cols") a.cols = parseNum(tok.shift(), "cols", ln);
37296
- else if (t.word === "count") a.count = parseNum(tok.shift(), "count", ln);
38349
+ else if (t.word === "rows") a.rows = parseNum2(tok.shift(), "rows", ln);
38350
+ else if (t.word === "cols") a.cols = parseNum2(tok.shift(), "cols", ln);
38351
+ else if (t.word === "count") a.count = parseNum2(tok.shift(), "count", ln);
37297
38352
  else if (t.word === "area") {
37298
38353
  a.p1 = parseCoord2(tok.shift(), "area p1", ln);
37299
38354
  a.p2 = parseCoord2(tok.shift(), "area p2", ln);
37300
38355
  } else if (t.word === "itemsize") a.itemsize = parseDims(tok.shift(), "itemsize", ln);
37301
- else if (t.word === "rotate") a.rotate = parseNum(tok.shift(), "rotate", ln);
38356
+ else if (t.word === "rotate") a.rotate = parseNum2(tok.shift(), "rotate", ln);
37302
38357
  else if (t.word === "center") a.center = parseCoord2(tok.shift(), "center", ln);
37303
- else if (t.word === "radius") a.radius = parseNum(tok.shift(), "radius", ln);
37304
- else if (t.word === "from") a.fromDeg = parseNum(tok.shift(), "from", ln);
37305
- else if (t.word === "to") a.toDeg = parseNum(tok.shift(), "to", ln);
38358
+ else if (t.word === "radius") a.radius = parseNum2(tok.shift(), "radius", ln);
38359
+ else if (t.word === "from") a.fromDeg = parseNum2(tok.shift(), "from", ln);
38360
+ else if (t.word === "to") a.toDeg = parseNum2(tok.shift(), "to", ln);
37306
38361
  else throw new FloorplanParseError(`${mode}: unexpected token "${t.word}"`, ln);
37307
38362
  }
37308
38363
  ast.arrays.push(a);
@@ -37322,9 +38377,9 @@ function parseFloorplan(text2) {
37322
38377
  const lines = text2.split(/\r?\n/);
37323
38378
  for (let i = 0; i < lines.length; i++) {
37324
38379
  const ln = i + 1;
37325
- const raw = normalizeQuotes3(lines[i]).trim();
38380
+ const raw = normalizeQuotes4(lines[i]).trim();
37326
38381
  if (!raw) continue;
37327
- const all = tokenize7(raw);
38382
+ const all = tokenize8(raw);
37328
38383
  const tok = [];
37329
38384
  for (let k = 0; k < all.length; k++) {
37330
38385
  const t = all[k];
@@ -37349,7 +38404,7 @@ function parseFloorplan(text2) {
37349
38404
  throw new FloorplanParseError(`the first statement must be the "floorplan" header`, ln);
37350
38405
  } else if (kw === "room") parseRoom(tok, ast, ln);
37351
38406
  else if (kw === "north") {
37352
- ast.north = tok.length ? parseNum(tok.shift(), "north rotation (degrees)", ln) : 0;
38407
+ ast.north = tok.length ? parseNum2(tok.shift(), "north rotation (degrees)", ln) : 0;
37353
38408
  if (tok.length) throw new FloorplanParseError(`north: unexpected trailing tokens`, ln);
37354
38409
  } else if (kw === "extend") parseExtend(tok, ast, ln);
37355
38410
  else if (kw === "door" || kw === "window" || kw === "opening") parseOpening(kw, tok, ast, ln);
@@ -37612,14 +38667,14 @@ function layoutFloorplan(ast) {
37612
38667
  ].sort((a, b) => a.line - b.line);
37613
38668
  for (const stmt of stmts) {
37614
38669
  if (stmt.room) {
37615
- const r6 = stmt.room;
37616
- const w = r6.w * u;
37617
- const h = r6.h * u;
37618
- const pos = resolvePlacement(r6, w, h, byId, rooms, u, `room "${r6.id}"`, errors) ?? { x: 0, y: 0 };
38670
+ const r7 = stmt.room;
38671
+ const w = r7.w * u;
38672
+ const h = r7.h * u;
38673
+ const pos = resolvePlacement(r7, w, h, byId, rooms, u, `room "${r7.id}"`, errors) ?? { x: 0, y: 0 };
37619
38674
  const part = { x: pos.x, y: pos.y, w, h };
37620
38675
  const room = {
37621
- id: r6.id,
37622
- label: r6.label,
38676
+ id: r7.id,
38677
+ label: r7.label,
37623
38678
  x: part.x,
37624
38679
  y: part.y,
37625
38680
  w,
@@ -37627,11 +38682,11 @@ function layoutFloorplan(ast) {
37627
38682
  parts: [part],
37628
38683
  areaM2: 0,
37629
38684
  areaText: "",
37630
- fill: r6.fill,
37631
- nolabel: r6.nolabel ?? false
38685
+ fill: r7.fill,
38686
+ nolabel: r7.nolabel ?? false
37632
38687
  };
37633
38688
  refreshRoomBounds(room, ast.unit);
37634
- byId.set(r6.id, rooms.length);
38689
+ byId.set(r7.id, rooms.length);
37635
38690
  rooms.push(room);
37636
38691
  } else if (stmt.ext) {
37637
38692
  const e = stmt.ext;
@@ -37744,10 +38799,10 @@ function layoutFloorplan(ast) {
37744
38799
  const spanW = p2.x - p1.x;
37745
38800
  const spanH = p2.y - p1.y;
37746
38801
  let placed = 0;
37747
- for (let r6 = 0; r6 < nRows && placed < cap2; r6++) {
38802
+ for (let r7 = 0; r7 < nRows && placed < cap2; r7++) {
37748
38803
  for (let col = 0; col < nCols && placed < cap2; col++) {
37749
38804
  const cx = p1.x + (nCols === 1 ? spanW / 2 : col * spanW / (nCols - 1));
37750
- const cy = p1.y + (nRows === 1 ? spanH / 2 : r6 * spanH / (nRows - 1));
38805
+ const cy = p1.y + (nRows === 1 ? spanH / 2 : r7 * spanH / (nRows - 1));
37751
38806
  place(a.type, idx, cx - iw / 2, cy - ih / 2, iw, ih, a.rotate);
37752
38807
  placed++;
37753
38808
  }
@@ -37768,7 +38823,7 @@ function layoutFloorplan(ast) {
37768
38823
  }
37769
38824
  }
37770
38825
  const roomOf = /* @__PURE__ */ new Map();
37771
- for (const r6 of rooms) roomOf.set(r6.id, r6);
38826
+ for (const r7 of rooms) roomOf.set(r7.id, r7);
37772
38827
  const warnItems = /* @__PURE__ */ new Set();
37773
38828
  for (const it of items) {
37774
38829
  const room = roomOf.get(it.roomId);
@@ -37827,11 +38882,11 @@ function layoutFloorplan(ast) {
37827
38882
  let minY = Infinity;
37828
38883
  let maxX = -Infinity;
37829
38884
  let maxY = -Infinity;
37830
- for (const r6 of rooms) {
37831
- minX = Math.min(minX, r6.x);
37832
- minY = Math.min(minY, r6.y);
37833
- maxX = Math.max(maxX, r6.x + r6.w);
37834
- maxY = Math.max(maxY, r6.y + r6.h);
38885
+ for (const r7 of rooms) {
38886
+ minX = Math.min(minX, r7.x);
38887
+ minY = Math.min(minY, r7.y);
38888
+ maxX = Math.max(maxX, r7.x + r7.w);
38889
+ maxY = Math.max(maxY, r7.y + r7.h);
37835
38890
  }
37836
38891
  if (rooms.length === 0) {
37837
38892
  minX = minY = 0;
@@ -37857,8 +38912,8 @@ function layoutFloorplan(ast) {
37857
38912
  minor: false
37858
38913
  });
37859
38914
  const topSegs = [];
37860
- for (const r6 of rooms) {
37861
- for (const sg of sideSegments(r6, "north")) {
38915
+ for (const r7 of rooms) {
38916
+ for (const sg of sideSegments(r7, "north")) {
37862
38917
  if (Math.abs(sg.along - minY) < 0.01) topSegs.push({ lo: sg.lo, hi: sg.hi });
37863
38918
  }
37864
38919
  }
@@ -37875,8 +38930,8 @@ function layoutFloorplan(ast) {
37875
38930
  }
37876
38931
  }
37877
38932
  const leftSegs = [];
37878
- for (const r6 of rooms) {
37879
- for (const sg of sideSegments(r6, "west")) {
38933
+ for (const r7 of rooms) {
38934
+ for (const sg of sideSegments(r7, "west")) {
37880
38935
  if (Math.abs(sg.along - minX) < 0.01) leftSegs.push({ lo: sg.lo, hi: sg.hi });
37881
38936
  }
37882
38937
  }
@@ -37904,7 +38959,7 @@ function layoutFloorplan(ast) {
37904
38959
  dims,
37905
38960
  bounds: { minX, minY, maxX, maxY },
37906
38961
  wallT: FLOORPLAN_CONST.wallT,
37907
- totalAreaM2: rooms.reduce((s, r6) => s + r6.areaM2, 0),
38962
+ totalAreaM2: rooms.reduce((s, r7) => s + r7.areaM2, 0),
37908
38963
  errors,
37909
38964
  warnings,
37910
38965
  warnItems: [...warnItems]
@@ -37956,11 +39011,11 @@ function resolveOpening(op, rooms, byId, u, unit, errors, warnings) {
37956
39011
  return null;
37957
39012
  }
37958
39013
  owner = idx;
37959
- const r6 = rooms[idx];
39014
+ const r7 = rooms[idx];
37960
39015
  const side = op.side;
37961
- const segs = sideSegments(r6, side);
39016
+ const segs = sideSegments(r7, side);
37962
39017
  if (segs.length === 0) {
37963
- errors.push(`${op.kind} on "${r6.id}" ${side}: that side has no exterior wall segment`);
39018
+ errors.push(`${op.kind} on "${r7.id}" ${side}: that side has no exterior wall segment`);
37964
39019
  return null;
37965
39020
  }
37966
39021
  const total = segs.reduce((s, sg) => s + (sg.hi - sg.lo), 0);
@@ -38301,13 +39356,13 @@ function renderFloorplanLayout(lay, config) {
38301
39356
  const openings = [];
38302
39357
  const labels = [];
38303
39358
  const dims = [];
38304
- for (const r6 of lay.rooms) {
39359
+ for (const r7 of lay.rooms) {
38305
39360
  floors.push(
38306
39361
  group(
38307
- { class: "sx-fp-floor", "data-room": r6.id },
38308
- r6.parts.map(
39362
+ { class: "sx-fp-floor", "data-room": r7.id },
39363
+ r7.parts.map(
38309
39364
  (p) => rect({
38310
- fill: r6.fill ?? t.floorFill,
39365
+ fill: r7.fill ?? t.floorFill,
38311
39366
  x: X(p.x),
38312
39367
  y: Y(p.y),
38313
39368
  width: px(p.w),
@@ -38316,12 +39371,12 @@ function renderFloorplanLayout(lay, config) {
38316
39371
  )
38317
39372
  )
38318
39373
  );
38319
- if (!r6.nolabel) {
38320
- const main = r6.parts.reduce((a, b) => b.w * b.h > a.w * a.h ? b : a);
39374
+ if (!r7.nolabel) {
39375
+ const main = r7.parts.reduce((a, b) => b.w * b.h > a.w * a.h ? b : a);
38321
39376
  const cx = X(main.x + main.w / 2);
38322
39377
  const cy = Y(main.y + main.h / 2);
38323
- labels.push(text({ class: "sx-fp-room-name", x: cx, y: r24(cy - 3), "text-anchor": "middle" }, r6.label));
38324
- labels.push(text({ class: "sx-fp-room-area", x: cx, y: r24(cy + 13), "text-anchor": "middle" }, r6.areaText));
39378
+ labels.push(text({ class: "sx-fp-room-name", x: cx, y: r24(cy - 3), "text-anchor": "middle" }, r7.label));
39379
+ labels.push(text({ class: "sx-fp-room-area", x: cx, y: r24(cy + 13), "text-anchor": "middle" }, r7.areaText));
38325
39380
  }
38326
39381
  }
38327
39382
  const warnSet = new Set(lay.warnItems);
@@ -38351,8 +39406,8 @@ function renderFloorplanLayout(lay, config) {
38351
39406
  }
38352
39407
  });
38353
39408
  const tw = lay.wallT;
38354
- for (const r6 of lay.rooms) {
38355
- for (const p of r6.parts) {
39409
+ for (const r7 of lay.rooms) {
39410
+ for (const p of r7.parts) {
38356
39411
  walls.push(rect({ class: "sx-fp-wall", x: r24(X(p.x) - px(tw / 2)), y: r24(Y(p.y) - px(tw / 2)), width: r24(px(p.w + tw)), height: px(tw) }));
38357
39412
  walls.push(rect({ class: "sx-fp-wall", x: r24(X(p.x) - px(tw / 2)), y: r24(Y(p.y + p.h) - px(tw / 2)), width: r24(px(p.w + tw)), height: px(tw) }));
38358
39413
  walls.push(rect({ class: "sx-fp-wall", x: r24(X(p.x) - px(tw / 2)), y: r24(Y(p.y) - px(tw / 2)), width: px(tw), height: r24(px(p.h + tw)) }));
@@ -38485,8 +39540,8 @@ var PlaybookParseError = class extends Error {
38485
39540
  var isStr2 = (t) => t !== void 0 && "str" in t;
38486
39541
  var isWord2 = (t, w) => t !== void 0 && "word" in t && (w === void 0 || t.word.toLowerCase() === w);
38487
39542
  var tokDisplay = (t) => "word" in t ? t.word : `"${t.str}"`;
38488
- var normalizeQuotes4 = (s) => s.replace(/[“”「」『』]/g, '"').replace(/[‘’]/g, "'");
38489
- function tokenize8(line2) {
39543
+ var normalizeQuotes5 = (s) => s.replace(/[“”「」『』]/g, '"').replace(/[‘’]/g, "'");
39544
+ function tokenize9(line2) {
38490
39545
  const out = [];
38491
39546
  const re = /"([^"]*)"|(\S+)/g;
38492
39547
  let m;
@@ -38496,7 +39551,7 @@ function tokenize8(line2) {
38496
39551
  }
38497
39552
  return out;
38498
39553
  }
38499
- function parseNum2(t, what, ln) {
39554
+ function parseNum3(t, what, ln) {
38500
39555
  if (!isWord2(t)) throw new PlaybookParseError(`expected a number for ${what}`, ln);
38501
39556
  const v = Number(t.word);
38502
39557
  if (!Number.isFinite(v)) throw new PlaybookParseError(`expected a number for ${what}, got "${t.word}"`, ln);
@@ -38603,10 +39658,10 @@ function parseHeader4(tok, ast, ln) {
38603
39658
  function parseField(tok, ast, ln) {
38604
39659
  while (tok.length) {
38605
39660
  const t = tok.shift();
38606
- if (isWord2(t, "down")) ast.down = parseNum2(tok.shift(), "down", ln);
38607
- else if (isWord2(t, "distance") || isWord2(t, "togo")) ast.distance = parseNum2(tok.shift(), "distance", ln);
38608
- else if (isWord2(t, "los") || isWord2(t, "ball")) ast.losYard = parseNum2(tok.shift(), "los", ln);
38609
- else if (isWord2(t, "goal") || isWord2(t, "togoal")) ast.toGoal = parseNum2(tok.shift(), "goal", ln);
39661
+ if (isWord2(t, "down")) ast.down = parseNum3(tok.shift(), "down", ln);
39662
+ else if (isWord2(t, "distance") || isWord2(t, "togo")) ast.distance = parseNum3(tok.shift(), "distance", ln);
39663
+ else if (isWord2(t, "los") || isWord2(t, "ball")) ast.losYard = parseNum3(tok.shift(), "los", ln);
39664
+ else if (isWord2(t, "goal") || isWord2(t, "togoal")) ast.toGoal = parseNum3(tok.shift(), "goal", ln);
38610
39665
  else if (isWord2(t, "view")) {
38611
39666
  const v = parseId2(tok.shift(), "view (full|half)", ln).toLowerCase();
38612
39667
  if (v !== "full" && v !== "half" && v !== "auto") throw new PlaybookParseError(`view must be full|half`, ln);
@@ -38710,7 +39765,7 @@ function parseRouteRun(kind, tok, ast, ln) {
38710
39765
  const t = tok.shift();
38711
39766
  if (isWord2(t) && DIRS.includes(t.word.toLowerCase())) m.dir = t.word.toLowerCase();
38712
39767
  else if (isWord2(t) && Number.isFinite(Number(t.word))) m.depth = Number(t.word);
38713
- else if (isWord2(t, "depth")) m.depth = parseNum2(tok.shift(), "depth", ln);
39768
+ else if (isWord2(t, "depth")) m.depth = parseNum3(tok.shift(), "depth", ln);
38714
39769
  else throw new PlaybookParseError(`${kind}: unexpected token "${tokDisplay(t)}"`, ln);
38715
39770
  }
38716
39771
  ast.moves.push(m);
@@ -38815,9 +39870,9 @@ function parsePlaybook(text2) {
38815
39870
  const lines = text2.split(/\r?\n/);
38816
39871
  for (let i = 0; i < lines.length; i++) {
38817
39872
  const ln = i + 1;
38818
- const raw = normalizeQuotes4(lines[i]).trim();
39873
+ const raw = normalizeQuotes5(lines[i]).trim();
38819
39874
  if (!raw) continue;
38820
- const all = tokenize8(raw);
39875
+ const all = tokenize9(raw);
38821
39876
  const tok = [];
38822
39877
  for (const t of all) {
38823
39878
  if (isWord2(t) && (t.word.startsWith("#") || t.word.startsWith("//"))) break;
@@ -39663,12 +40718,12 @@ function resolveGeneric(m, src, byId, players, mod, sport, warnings) {
39663
40718
  let cur = { x: src.x, y: src.y };
39664
40719
  for (const p of m.points) {
39665
40720
  if (p.ref) {
39666
- const r6 = resolveRef(p.ref, byId, players, mod);
39667
- if (!r6) {
40721
+ const r7 = resolveRef(p.ref, byId, players, mod);
40722
+ if (!r7) {
39668
40723
  warnings.push(`${m.kind} ${m.player}: unknown destination "${p.ref}" \u2014 skipped`);
39669
40724
  return null;
39670
40725
  }
39671
- cur = r6;
40726
+ cur = r7;
39672
40727
  } else if (p.rel) {
39673
40728
  cur = { x: cur.x + (p.x ?? 0), y: cur.y + (p.y ?? 0) };
39674
40729
  } else {
@@ -39811,22 +40866,22 @@ function renderMove(mv, ctx) {
39811
40866
  return group({ class: "sx-pb-move-g", "data-kind": mv.kind, "data-player": mv.player }, parts);
39812
40867
  }
39813
40868
  function playerSymbol(p, ctx) {
39814
- const cx = ctx.X(p.x), cy = ctx.Y(p.y), r6 = 10;
40869
+ const cx = ctx.X(p.x), cy = ctx.Y(p.y), r7 = 10;
39815
40870
  const parts = [];
39816
40871
  if (p.side === "defense" || p.pos === "x") {
39817
- const k = r6 * 0.78;
40872
+ const k = r7 * 0.78;
39818
40873
  parts.push(line({ class: "sx-pb-x", x1: r28(cx - k), y1: r28(cy - k), x2: r28(cx + k), y2: r28(cy + k) }));
39819
40874
  parts.push(line({ class: "sx-pb-x", x1: r28(cx - k), y1: r28(cy + k), x2: r28(cx + k), y2: r28(cy - k) }));
39820
40875
  if (p.label) parts.push(text({ class: "sx-pb-x-text", x: r28(cx + k + 5), y: r28(cy - k + 2), "text-anchor": "middle" }, p.label));
39821
40876
  } else if (p.pos === "gk") {
39822
- const h = r6 * 1.15;
40877
+ const h = r7 * 1.15;
39823
40878
  parts.push(polygon({ class: "sx-pb-gk", points: `${r28(cx)},${r28(cy - h)} ${r28(cx + h)},${r28(cy + h * 0.8)} ${r28(cx - h)},${r28(cy + h * 0.8)}` }));
39824
40879
  parts.push(text({ class: "sx-pb-o-text", x: r28(cx), y: r28(cy + 6), "text-anchor": "middle" }, p.label));
39825
40880
  } else if (p.pos === "c") {
39826
- parts.push(rect({ class: "sx-pb-o", x: r28(cx - r6 * 0.82), y: r28(cy - r6 * 0.82), width: r28(r6 * 1.64), height: r28(r6 * 1.64) }));
40881
+ parts.push(rect({ class: "sx-pb-o", x: r28(cx - r7 * 0.82), y: r28(cy - r7 * 0.82), width: r28(r7 * 1.64), height: r28(r7 * 1.64) }));
39827
40882
  parts.push(text({ class: "sx-pb-o-text", x: r28(cx), y: r28(cy + 3.6), "text-anchor": "middle" }, p.label));
39828
40883
  } else {
39829
- parts.push(circle({ class: "sx-pb-o", cx: r28(cx), cy: r28(cy), r: r6 }));
40884
+ parts.push(circle({ class: "sx-pb-o", cx: r28(cx), cy: r28(cy), r: r7 }));
39830
40885
  parts.push(text({ class: "sx-pb-o-text", x: r28(cx), y: r28(cy + 3.6), "text-anchor": "middle" }, p.label));
39831
40886
  }
39832
40887
  return group({ class: "sx-pb-player", "data-side": p.side, "data-id": p.id }, parts);
@@ -39903,7 +40958,7 @@ function renderPlaybookLayout(lay, config) {
39903
40958
  const surfaceBase = rect({ class: surfaceCls, x: EDGE, y: r28(fieldTop), width: r28(fieldW), height: r28(fieldH), rx: fieldRx });
39904
40959
  const boundary = rect({ class: boundaryCls, x: EDGE, y: r28(fieldTop), width: r28(fieldW), height: r28(fieldH), rx: fieldRx });
39905
40960
  const clipId = "sx-pb-clip";
39906
- const clip6 = el("clipPath", { id: clipId }, [rect({ x: EDGE, y: r28(fieldTop), width: r28(fieldW), height: r28(fieldH), rx: fieldRx })]);
40961
+ const clip7 = el("clipPath", { id: clipId }, [rect({ x: EDGE, y: r28(fieldTop), width: r28(fieldW), height: r28(fieldH), rx: fieldRx })]);
39907
40962
  const field = group({ "clip-path": `url(#${clipId})` }, [mod.drawField(lay, ctx, t)]);
39908
40963
  const zones = [];
39909
40964
  for (const z of lay.zones) {
@@ -39931,7 +40986,7 @@ function renderPlaybookLayout(lay, config) {
39931
40986
  desc(descText),
39932
40987
  el("style", {}, buildCss14(t)),
39933
40988
  rect({ fill: t.bg, x: 0, y: 0, width: W2, height: H2 }),
39934
- el("defs", {}, [clip6]),
40989
+ el("defs", {}, [clip7]),
39935
40990
  text({ class: "sx-pb-title", x: r28(W2 / 2), y: TITLE.y, "text-anchor": "middle" }, lay.title),
39936
40991
  ...annoParts,
39937
40992
  surround,
@@ -40033,6 +41088,7 @@ var plugins = [
40033
41088
  bowtie2,
40034
41089
  eventtree,
40035
41090
  fmea,
41091
+ rbd,
40036
41092
  causalloop,
40037
41093
  markov,
40038
41094
  gitgraph,
@@ -40052,7 +41108,7 @@ function detectPlugin(text2, config) {
40052
41108
  if (plugin.detect(text2)) return plugin;
40053
41109
  }
40054
41110
  throw new Error(
40055
- "Cannot detect diagram type. Start your text with 'genogram', 'ecomap', 'pedigree', 'phylo', 'sociogram', 'timing', 'logic', 'circuit', 'blockdiagram', 'ladder', 'sld', 'entity-structure', 'fishbone', 'venn', 'flowchart', 'mindmap', 'matrix', 'orgchart', 'state', 'pid', 'erd', 'breadboard', 'bpmn', 'fbd', 'sfc', 'prisma', 'usecase', 'pert', 'sequence', 'petri', 'network', 'umlclass', 'faulttree', 'bowtie', 'floorplan', or 'playbook'."
41111
+ "Cannot detect diagram type. Start your text with 'genogram', 'ecomap', 'pedigree', 'phylo', 'sociogram', 'timing', 'logic', 'circuit', 'blockdiagram', 'ladder', 'sld', 'entity-structure', 'fishbone', 'venn', 'flowchart', 'mindmap', 'matrix', 'orgchart', 'state', 'pid', 'erd', 'breadboard', 'bpmn', 'fbd', 'sfc', 'prisma', 'usecase', 'pert', 'sequence', 'petri', 'network', 'umlclass', 'faulttree', 'bowtie', 'rbd', 'floorplan', or 'playbook'."
40056
41112
  );
40057
41113
  }
40058
41114
  function stripCodeFences(text2) {
@@ -40189,6 +41245,6 @@ function renderWithPlugin(prepared, plugin, config) {
40189
41245
  return plugin.render(prepared, renderConfig);
40190
41246
  }
40191
41247
 
40192
- export { FLOORPLAN_SYMBOLS, GEOMETRY, bowtie2 as bowtie, causalloop, decisiontree, drawDeviceIcon, epc, eventtree, faulttree, fmea, gitgraph, iconSize, idef0, markov, network, parse, parseResult, pert, petri, pid, prisma, render, renderEquip, renderPreview, renderResult, sequence, state, threatmodel, timeline, umlclass, usecase, welding };
40193
- //# sourceMappingURL=chunk-UFXDAIDD.js.map
40194
- //# sourceMappingURL=chunk-UFXDAIDD.js.map
41248
+ export { FLOORPLAN_SYMBOLS, GEOMETRY, bowtie2 as bowtie, causalloop, decisiontree, drawDeviceIcon, epc, eventtree, faulttree, fmea, gitgraph, iconSize, idef0, markov, network, parse, parseResult, pert, petri, pid, prisma, rbd, render, renderEquip, renderPreview, renderResult, sequence, state, threatmodel, timeline, umlclass, usecase, welding };
41249
+ //# sourceMappingURL=chunk-4W75FGWO.js.map
41250
+ //# sourceMappingURL=chunk-4W75FGWO.js.map