@cs-object/react 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -31,11 +31,11 @@ var __objRest = (source, exclude) => {
31
31
  };
32
32
 
33
33
  // src/formula-sheet/tokens.ts
34
- var headerTextClass = "font-['Plus_Jakarta_Sans'] text-[12px] text-black/50";
34
+ var headerTextClass = "font-['Plus_Jakarta_Sans'] text-[12px] text-slate-600";
35
35
  var valueTextClass = "font-['KaTeX_Main'] text-[16.335px]";
36
36
  var FORMULA_SHEET_SPACER_CELL_CLASS = "w-[1.5%] p-[3px]";
37
37
  var FORMULA_SHEET_DESCRIPTION_CELL_CLASS = `flex w-[37%] flex-col justify-start py-[3px] ${headerTextClass}`;
38
- var FORMULA_SHEET_COMMENT_CELL_CLASS = `flex w-[23.5%] flex-col justify-start py-[3px] text-right ${headerTextClass}`;
38
+ var FORMULA_SHEET_COMMENT_CELL_CLASS = `flex w-[23.5%] flex-col justify-start py-[3px] ${headerTextClass}`;
39
39
  var FORMULA_SHEET_SYMBOL_CELL_BASE_CLASS = "flex w-[14%] min-w-[14%] items-center justify-end overflow-visible border-r border-gray-300";
40
40
  var FORMULA_SHEET_SYMBOL_CELL_HEADER_CLASS = `p-[3px] ${headerTextClass}`;
41
41
  var FORMULA_SHEET_SYMBOL_CELL_VALUE_CLASS = `p-[3px] pr-[5px] ${valueTextClass}`;
@@ -166,11 +166,6 @@ import { parseNotation } from "@cs-object/core";
166
166
 
167
167
  // src/ascii-math/NotationMathmlView.tsx
168
168
  import { assertNever } from "@cs-object/core";
169
-
170
- // src/mathml/constants.ts
171
- var MATHML_FONT_SIZE = "15px";
172
-
173
- // src/ascii-math/NotationMathmlView.tsx
174
169
  import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
175
170
  var fenceCharacters = {
176
171
  round: ["(", ")"],
@@ -263,8 +258,8 @@ var NotationNodeMathmlView = ({
263
258
  );
264
259
  case "fraction":
265
260
  return /* @__PURE__ */ jsxs4("mfrac", { children: [
266
- /* @__PURE__ */ jsx9("mstyle", { style: { fontSize: MATHML_FONT_SIZE }, children: renderNode(node.numerator) }),
267
- /* @__PURE__ */ jsx9("mstyle", { style: { fontSize: MATHML_FONT_SIZE }, children: renderNode(node.denominator) })
261
+ /* @__PURE__ */ jsx9("mrow", { children: renderNode(node.numerator) }),
262
+ /* @__PURE__ */ jsx9("mrow", { children: renderNode(node.denominator) })
268
263
  ] });
269
264
  case "subscript":
270
265
  return /* @__PURE__ */ jsxs4("msub", { children: [
@@ -312,6 +307,9 @@ var AsciiMathView = (_a) => {
312
307
  );
313
308
  };
314
309
 
310
+ // src/mathml/constants.ts
311
+ var MATHML_FONT_SIZE = "15px";
312
+
315
313
  // src/mathml/props.ts
316
314
  var defaultMathBlockProps = {
317
315
  style: {
@@ -362,12 +360,35 @@ import {
362
360
  isSheetLiteralEmpty,
363
361
  sheetLiteralToDisplayString
364
362
  } from "@cs-object/core";
365
- import { jsx as jsx13 } from "react/jsx-runtime";
363
+
364
+ // src/formula-sheet/NumericalValue.tsx
365
+ import { formatNumerical } from "@cs-object/core";
366
+ import { jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
367
+ var NumericalValue = ({
368
+ value,
369
+ numericKind
370
+ }) => {
371
+ const formatted = Object.is(value, -0) ? "-0" : numericKind === "int" ? String(value) : formatNumerical(value);
372
+ const text = formatted.startsWith("(") ? formatted.slice(1, -1) : formatted;
373
+ const scientific = /^(-?[\d.]+)e([+-]?\d+)$/u.exec(text);
374
+ return scientific ? /* @__PURE__ */ jsx13("math", { style: { fontSize: "inherit", fontFamily: "inherit" }, children: /* @__PURE__ */ jsxs5("mrow", { children: [
375
+ /* @__PURE__ */ jsx13("mn", { children: scientific[1] }),
376
+ /* @__PURE__ */ jsx13("mo", { children: "\xD7" }),
377
+ /* @__PURE__ */ jsxs5("msup", { children: [
378
+ /* @__PURE__ */ jsx13("mn", { children: "10" }),
379
+ /* @__PURE__ */ jsx13("mn", { children: String(Number(scientific[2])) })
380
+ ] })
381
+ ] }) }) : formatted;
382
+ };
383
+
384
+ // src/formula-sheet/FormulaSheetResultCell.tsx
385
+ import { jsx as jsx14 } from "react/jsx-runtime";
366
386
  var FormulaSheetResultCell = ({
367
- literal
387
+ literal,
388
+ numericKind
368
389
  }) => {
369
- const formattedValue = sheetLiteralToDisplayString(literal);
370
- return /* @__PURE__ */ jsx13(FormulaSheetValueCell, { children: isSheetLiteralEmpty(literal) ? /* @__PURE__ */ jsx13("span", { className: "rounded-sm bg-orange-500 px-1.5 py-0 text-black opacity-70", children: "NaN" }) : formattedValue });
390
+ const formattedValue = literal.kind === "number" ? /* @__PURE__ */ jsx14(NumericalValue, { value: literal.value, numericKind }) : sheetLiteralToDisplayString(literal);
391
+ return /* @__PURE__ */ jsx14(FormulaSheetValueCell, { children: isSheetLiteralEmpty(literal) ? /* @__PURE__ */ jsx14("span", { className: "rounded-sm bg-orange-500 px-1.5 py-0 text-black opacity-70", children: "NaN" }) : formattedValue });
371
392
  };
372
393
 
373
394
  // src/formula-sheet/FormulaSheetValueTree.tsx
@@ -387,28 +408,28 @@ import {
387
408
  } from "@cs-object/core";
388
409
 
389
410
  // src/mathml/function-renderers.tsx
390
- import { jsx as jsx14, jsxs as jsxs5 } from "react/jsx-runtime";
391
- var baseStyle = { fontSize: MATHML_FONT_SIZE, textAlign: "left" };
392
- var fontSizeStyle = { fontSize: MATHML_FONT_SIZE };
411
+ import { jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
412
+ var baseStyle = { textAlign: "left" };
413
+ var branchStyle = __spreadProps(__spreadValues({}, baseStyle), { paddingBlock: "0.4em" });
393
414
  var ConditionalFunctionMathml = ({
394
415
  argCnd,
395
416
  argTrue,
396
417
  argFalse
397
418
  }) => {
398
- return /* @__PURE__ */ jsxs5("mrow", { style: baseStyle, children: [
399
- /* @__PURE__ */ jsx14("mo", { style: fontSizeStyle, children: "{" }),
400
- /* @__PURE__ */ jsxs5("mtable", { columnalign: "left", style: baseStyle, children: [
401
- /* @__PURE__ */ jsxs5("mtr", { style: fontSizeStyle, children: [
402
- /* @__PURE__ */ jsx14("mtd", { style: __spreadProps(__spreadValues({}, baseStyle), { paddingRight: "0.5em" }), children: argTrue }),
403
- /* @__PURE__ */ jsxs5("mtd", { style: baseStyle, children: [
404
- /* @__PURE__ */ jsx14("mtext", { style: fontSizeStyle, children: "if " }),
405
- /* @__PURE__ */ jsx14("mspace", { width: "5px" }),
419
+ return /* @__PURE__ */ jsxs6("mrow", { style: baseStyle, children: [
420
+ /* @__PURE__ */ jsx15("mo", { children: "{" }),
421
+ /* @__PURE__ */ jsxs6("mtable", { columnalign: "left", style: baseStyle, children: [
422
+ /* @__PURE__ */ jsxs6("mtr", { children: [
423
+ /* @__PURE__ */ jsx15("mtd", { style: __spreadProps(__spreadValues({}, branchStyle), { paddingRight: "0.5em" }), children: argTrue }),
424
+ /* @__PURE__ */ jsxs6("mtd", { style: branchStyle, children: [
425
+ /* @__PURE__ */ jsx15("mtext", { children: "if " }),
426
+ /* @__PURE__ */ jsx15("mspace", { width: "5px" }),
406
427
  argCnd
407
428
  ] })
408
429
  ] }),
409
- /* @__PURE__ */ jsxs5("mtr", { style: fontSizeStyle, children: [
410
- /* @__PURE__ */ jsx14("mtd", { style: __spreadProps(__spreadValues({}, baseStyle), { paddingRight: "0.5em" }), children: argFalse }),
411
- /* @__PURE__ */ jsx14("mtd", { style: baseStyle, children: /* @__PURE__ */ jsx14("mtext", { style: fontSizeStyle, children: "otherwise." }) })
430
+ /* @__PURE__ */ jsxs6("mtr", { children: [
431
+ /* @__PURE__ */ jsx15("mtd", { style: __spreadProps(__spreadValues({}, branchStyle), { paddingRight: "0.5em" }), children: argFalse }),
432
+ /* @__PURE__ */ jsx15("mtd", { style: branchStyle, children: /* @__PURE__ */ jsx15("mtext", { children: "otherwise." }) })
412
433
  ] })
413
434
  ] })
414
435
  ] });
@@ -417,39 +438,39 @@ var FractionFunctionMathml = ({
417
438
  numerator,
418
439
  denominator
419
440
  }) => {
420
- return /* @__PURE__ */ jsxs5("mfrac", { children: [
421
- /* @__PURE__ */ jsx14("mstyle", { style: { fontSize: MATHML_FONT_SIZE }, children: numerator }),
422
- /* @__PURE__ */ jsx14("mstyle", { style: { fontSize: MATHML_FONT_SIZE }, children: denominator })
441
+ return /* @__PURE__ */ jsxs6("mfrac", { children: [
442
+ /* @__PURE__ */ jsx15("mrow", { style: { fontSize: "1em" }, children: numerator }),
443
+ /* @__PURE__ */ jsx15("mrow", { style: { fontSize: "1em" }, children: denominator })
423
444
  ] });
424
445
  };
425
446
  var PowerFunctionMathml = ({
426
447
  base,
427
448
  exponent
428
449
  }) => {
429
- return /* @__PURE__ */ jsxs5("msup", { children: [
430
- /* @__PURE__ */ jsx14("mstyle", { style: { fontSize: MATHML_FONT_SIZE }, children: base }),
431
- /* @__PURE__ */ jsx14("mstyle", { style: { scale: "0.8" }, children: exponent })
450
+ return /* @__PURE__ */ jsxs6("msup", { children: [
451
+ /* @__PURE__ */ jsx15("mrow", { children: base }),
452
+ /* @__PURE__ */ jsx15("mrow", { children: exponent })
432
453
  ] });
433
454
  };
434
455
  var SquareRootFunctionMathml = ({
435
456
  value
436
457
  }) => {
437
- return /* @__PURE__ */ jsx14("msqrt", { children: /* @__PURE__ */ jsx14("mstyle", { style: { padding: "3px", fontSize: MATHML_FONT_SIZE }, children: value }) });
458
+ return /* @__PURE__ */ jsx15("msqrt", { children: /* @__PURE__ */ jsx15("mstyle", { style: { padding: "0.2em" }, children: value }) });
438
459
  };
439
460
  var AbsoluteValueFunctionMathml = ({
440
461
  value
441
462
  }) => {
442
- return /* @__PURE__ */ jsxs5("mrow", { style: fontSizeStyle, children: [
443
- /* @__PURE__ */ jsx14("mo", { fence: "true", stretchy: "true", children: "|" }),
463
+ return /* @__PURE__ */ jsxs6("mrow", { children: [
464
+ /* @__PURE__ */ jsx15("mo", { fence: "true", stretchy: "true", children: "|" }),
444
465
  value,
445
- /* @__PURE__ */ jsx14("mo", { fence: "true", stretchy: "true", children: "|" })
466
+ /* @__PURE__ */ jsx15("mo", { fence: "true", stretchy: "true", children: "|" })
446
467
  ] });
447
468
  };
448
469
  var UnaryMinusFunctionMathml = ({
449
470
  value
450
471
  }) => {
451
- return /* @__PURE__ */ jsxs5("mrow", { style: { fontSize: MATHML_FONT_SIZE }, children: [
452
- /* @__PURE__ */ jsx14("mo", { style: { fontSize: MATHML_FONT_SIZE }, children: "-" }),
472
+ return /* @__PURE__ */ jsxs6("mrow", { children: [
473
+ /* @__PURE__ */ jsx15("mo", { children: "-" }),
453
474
  value
454
475
  ] });
455
476
  };
@@ -457,17 +478,42 @@ var renderSpecialValueFunction = ({
457
478
  functionId,
458
479
  argReactNodes
459
480
  }) => {
481
+ if (functionId === "fg.not" && argReactNodes.length === 1) {
482
+ return /* @__PURE__ */ jsxs6("mrow", { children: [
483
+ /* @__PURE__ */ jsx15("mo", { form: "prefix", rspace: "0.3em", children: "not" }),
484
+ /* @__PURE__ */ jsxs6("mrow", { children: [
485
+ /* @__PURE__ */ jsx15("mo", { fence: "true", children: "(" }),
486
+ argReactNodes[0],
487
+ /* @__PURE__ */ jsx15("mo", { fence: "true", children: ")" })
488
+ ] })
489
+ ] });
490
+ }
491
+ if (functionId === "fg.xor" && argReactNodes.length === 2) {
492
+ return /* @__PURE__ */ jsxs6("mrow", { children: [
493
+ /* @__PURE__ */ jsxs6("mrow", { children: [
494
+ /* @__PURE__ */ jsx15("mo", { fence: "true", children: "(" }),
495
+ argReactNodes[0],
496
+ /* @__PURE__ */ jsx15("mo", { fence: "true", children: ")" })
497
+ ] }),
498
+ /* @__PURE__ */ jsx15("mo", { form: "infix", lspace: "0.3em", rspace: "0.3em", children: "xor" }),
499
+ /* @__PURE__ */ jsxs6("mrow", { children: [
500
+ /* @__PURE__ */ jsx15("mo", { fence: "true", children: "(" }),
501
+ argReactNodes[1],
502
+ /* @__PURE__ */ jsx15("mo", { fence: "true", children: ")" })
503
+ ] })
504
+ ] });
505
+ }
460
506
  if (functionId === "fg.abs" && argReactNodes.length === 1) {
461
- return /* @__PURE__ */ jsx14(AbsoluteValueFunctionMathml, { value: argReactNodes[0] });
507
+ return /* @__PURE__ */ jsx15(AbsoluteValueFunctionMathml, { value: argReactNodes[0] });
462
508
  }
463
509
  if (functionId === "fg.sqrt" && argReactNodes.length === 1) {
464
- return /* @__PURE__ */ jsx14(SquareRootFunctionMathml, { value: argReactNodes[0] });
510
+ return /* @__PURE__ */ jsx15(SquareRootFunctionMathml, { value: argReactNodes[0] });
465
511
  }
466
512
  if (functionId === "fg.uminus" && argReactNodes.length === 1) {
467
- return /* @__PURE__ */ jsx14(UnaryMinusFunctionMathml, { value: argReactNodes[0] });
513
+ return /* @__PURE__ */ jsx15(UnaryMinusFunctionMathml, { value: argReactNodes[0] });
468
514
  }
469
515
  if (functionId === "fg.cnd" && argReactNodes.length === 3) {
470
- return /* @__PURE__ */ jsx14(
516
+ return /* @__PURE__ */ jsx15(
471
517
  ConditionalFunctionMathml,
472
518
  {
473
519
  argCnd: argReactNodes[0],
@@ -477,7 +523,7 @@ var renderSpecialValueFunction = ({
477
523
  );
478
524
  }
479
525
  if (functionId === "fg.divide" && argReactNodes.length === 2) {
480
- return /* @__PURE__ */ jsx14(
526
+ return /* @__PURE__ */ jsx15(
481
527
  FractionFunctionMathml,
482
528
  {
483
529
  numerator: argReactNodes[0],
@@ -486,7 +532,7 @@ var renderSpecialValueFunction = ({
486
532
  );
487
533
  }
488
534
  if (functionId === "fg.pow" && argReactNodes.length === 2) {
489
- return /* @__PURE__ */ jsx14(
535
+ return /* @__PURE__ */ jsx15(
490
536
  PowerFunctionMathml,
491
537
  {
492
538
  base: argReactNodes[0],
@@ -498,9 +544,9 @@ var renderSpecialValueFunction = ({
498
544
  };
499
545
 
500
546
  // src/mathml/symbol-value/components.tsx
501
- import { assertNever as assertNever2, formatNumerical } from "@cs-object/core";
547
+ import { assertNever as assertNever2, formatNumerical as formatNumerical2 } from "@cs-object/core";
502
548
  import { isValidElement } from "react";
503
- import { Fragment, jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
549
+ import { Fragment, jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
504
550
  var isDraftPositionValid = ({
505
551
  draft,
506
552
  position
@@ -536,34 +582,30 @@ var stableReactNodeKey = (node) => {
536
582
  var SymbolValueRootMathmlView = ({
537
583
  children
538
584
  }) => {
539
- return /* @__PURE__ */ jsx15("math", { children: children != null ? children : "Tree Without Root" });
585
+ return /* @__PURE__ */ jsx16("math", { children: children != null ? children : "Tree Without Root" });
540
586
  };
541
587
  var SymbolValueDraftMathmlView = ({
542
588
  draft,
543
589
  position
544
590
  }) => {
545
- const textStyle = { fontSize: MATHML_FONT_SIZE };
546
- return position !== void 0 && isDraftPositionValid({ draft, position }) ? /* @__PURE__ */ jsxs6("mrow", { style: { fontSize: MATHML_FONT_SIZE }, children: [
547
- position > 0 && /* @__PURE__ */ jsx15("mtext", { style: textStyle, children: draft.substring(0, position) }),
548
- position < draft.length && /* @__PURE__ */ jsx15("mtext", { style: textStyle, children: draft.substring(position) })
549
- ] }) : /* @__PURE__ */ jsx15("mrow", { style: { fontSize: MATHML_FONT_SIZE }, children: /* @__PURE__ */ jsx15("mtext", { style: textStyle, children: draft }) });
591
+ return position !== void 0 && isDraftPositionValid({ draft, position }) ? /* @__PURE__ */ jsxs7("mrow", { children: [
592
+ position > 0 && /* @__PURE__ */ jsx16("mtext", { children: draft.substring(0, position) }),
593
+ position < draft.length && /* @__PURE__ */ jsx16("mtext", { children: draft.substring(position) })
594
+ ] }) : /* @__PURE__ */ jsx16("mrow", { children: /* @__PURE__ */ jsx16("mtext", { children: draft }) });
550
595
  };
551
596
  var SymbolValueLiteralMathmlView = ({
552
597
  literal
553
598
  }) => {
554
- const mathProps = {
555
- style: { fontSize: MATHML_FONT_SIZE }
556
- };
557
599
  switch (literal == null ? void 0 : literal.kind) {
558
600
  case void 0:
559
601
  case "empty":
560
- return /* @__PURE__ */ jsx15("mi", __spreadProps(__spreadValues({}, mathProps), { children: "\u25A2" }));
602
+ return /* @__PURE__ */ jsx16("mi", { children: "\u25A2" });
561
603
  case "boolean":
562
- return /* @__PURE__ */ jsx15("mi", __spreadProps(__spreadValues({}, mathProps), { children: literal.value ? "true" : "false" }));
604
+ return /* @__PURE__ */ jsx16("mi", { children: literal.value ? "true" : "false" });
563
605
  case "number":
564
- return /* @__PURE__ */ jsx15("mn", __spreadProps(__spreadValues({}, mathProps), { children: formatNumerical(literal.value) }));
606
+ return /* @__PURE__ */ jsx16("mn", { children: formatNumerical2(literal.value) });
565
607
  case "string":
566
- return /* @__PURE__ */ jsx15("mtext", __spreadProps(__spreadValues({}, mathProps), { children: literal.value }));
608
+ return /* @__PURE__ */ jsx16("mtext", { children: literal.value });
567
609
  default:
568
610
  return assertNever2(literal);
569
611
  }
@@ -572,7 +614,7 @@ var SymbolValueGlyphMathmlView = ({
572
614
  glyph
573
615
  }) => {
574
616
  const mathProps = {};
575
- return /* @__PURE__ */ jsx15(AsciiMathView, __spreadValues({ expression: glyph }, mathProps));
617
+ return /* @__PURE__ */ jsx16(AsciiMathView, __spreadValues({ expression: glyph }, mathProps));
576
618
  };
577
619
  var SymbolValueGroupMathmlView = ({
578
620
  prefix,
@@ -583,21 +625,21 @@ var SymbolValueGroupMathmlView = ({
583
625
  const mathProps = {
584
626
  mathbackground: cursor ? "lightgray" : void 0
585
627
  };
586
- return /* @__PURE__ */ jsxs6("mrow", __spreadProps(__spreadValues({}, mathProps), { children: [
628
+ return /* @__PURE__ */ jsxs7("mrow", __spreadProps(__spreadValues({}, mathProps), { children: [
587
629
  prefix,
588
- (children.length > 0 || empty === "fence") && /* @__PURE__ */ jsxs6(Fragment, { children: [
589
- /* @__PURE__ */ jsx15("mo", { fence: "true", children: "(" }),
630
+ (children.length > 0 || empty === "fence") && /* @__PURE__ */ jsxs7(Fragment, { children: [
631
+ /* @__PURE__ */ jsx16("mo", { fence: "true", children: "(" }),
590
632
  children.flatMap((child, argIndex, arr) => {
591
633
  const next = arr[argIndex + 1];
592
634
  const separatorKey = `sep-${stableReactNodeKey(child)}-to-${stableReactNodeKey(next)}`;
593
635
  return [
594
636
  child,
595
637
  ...argIndex < arr.length - 1 ? [
596
- /* @__PURE__ */ jsx15("mo", { separator: "true", children: "," }, separatorKey)
638
+ /* @__PURE__ */ jsx16("mo", { separator: "true", children: "," }, separatorKey)
597
639
  ] : []
598
640
  ];
599
641
  }),
600
- /* @__PURE__ */ jsx15("mo", { fence: "true", children: ")" })
642
+ /* @__PURE__ */ jsx16("mo", { fence: "true", children: ")" })
601
643
  ] })
602
644
  ] }));
603
645
  };
@@ -607,9 +649,9 @@ var SymbolValueBinaryOperatorMathmlView = ({
607
649
  argRight
608
650
  }) => {
609
651
  const spacing = operator.id === "fg.and" || operator.id === "fg.or" ? "0.3em" : void 0;
610
- return /* @__PURE__ */ jsxs6("mrow", { children: [
652
+ return /* @__PURE__ */ jsxs7("mrow", { children: [
611
653
  argLeft,
612
- /* @__PURE__ */ jsx15("mo", { lspace: spacing, rspace: spacing, children: operator.glyph }),
654
+ /* @__PURE__ */ jsx16("mo", { lspace: spacing, rspace: spacing, children: operator.glyph }),
613
655
  argRight
614
656
  ] });
615
657
  };
@@ -655,11 +697,11 @@ var requiresExplicitOperandGroup = ({
655
697
  }
656
698
  }
657
699
  const negative = draft !== void 0 ? /^\s*[-−]/u.test(draft) : (literal == null ? void 0 : literal.kind) === "number" && (literal.value < 0 || Object.is(literal.value, -0));
658
- return argumentIndex === 0 && (parentFunctionId === "fg.pow" && (node.kind === "function" || negative) || parentFunctionId === "fg.uminus" && node.kind === "function") || argumentIndex === 1 && (parentFunctionId === "fg.add" || parentFunctionId === "fg.multiply" || parentFunctionId === "fg.subtract") && (negative || node.kind === "function" && node.functionId === "fg.uminus");
700
+ return (parentFunctionId === "fg.and" || parentFunctionId === "fg.or") && node.kind === "function" && node.functionId === "fg.xor" || argumentIndex === 0 && (parentFunctionId === "fg.pow" && (node.kind === "function" || negative) || parentFunctionId === "fg.uminus" && node.kind === "function") || argumentIndex === 1 && (parentFunctionId === "fg.add" || parentFunctionId === "fg.multiply" || parentFunctionId === "fg.subtract") && (negative || node.kind === "function" && node.functionId === "fg.uminus");
659
701
  };
660
702
 
661
703
  // src/mathml/symbol-value/ValueTreeMathmlRenderer.tsx
662
- import { Fragment as Fragment2, jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
704
+ import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
663
705
  var ValueTreeMathmlRenderer = ({
664
706
  sheet,
665
707
  valueTree,
@@ -668,9 +710,9 @@ var ValueTreeMathmlRenderer = ({
668
710
  }) => {
669
711
  const rootNode = getValueNodeByKeyOrUndefined(valueTree, valueTree.rootKey);
670
712
  if (!rootNode) {
671
- return /* @__PURE__ */ jsx16(Fragment2, { children: "Empty Value" });
713
+ return /* @__PURE__ */ jsx17(Fragment2, { children: "Empty Value" });
672
714
  }
673
- const rootValue = /* @__PURE__ */ jsx16(
715
+ const rootValue = /* @__PURE__ */ jsx17(
674
716
  ValueTreeNodeMathmlView,
675
717
  {
676
718
  sheet,
@@ -679,7 +721,7 @@ var ValueTreeMathmlRenderer = ({
679
721
  viewOptions
680
722
  }
681
723
  );
682
- return noRootContainer ? rootValue : /* @__PURE__ */ jsx16(SymbolValueRootMathmlView, { children: rootValue });
724
+ return noRootContainer ? rootValue : /* @__PURE__ */ jsx17(SymbolValueRootMathmlView, { children: rootValue });
683
725
  };
684
726
  var ValueTreeNodeMathmlView = ({
685
727
  sheet,
@@ -694,16 +736,16 @@ var ValueTreeNodeMathmlView = ({
694
736
  literalsAsDrafts: viewOptions.literalsAsDrafts
695
737
  });
696
738
  if (draft !== void 0) {
697
- return /* @__PURE__ */ jsx16(SymbolValueDraftMathmlView, { draft });
739
+ return /* @__PURE__ */ jsx17(SymbolValueDraftMathmlView, { draft });
698
740
  }
699
- return /* @__PURE__ */ jsx16(SymbolValueLiteralMathmlView, { literal: node.value });
741
+ return /* @__PURE__ */ jsx17(SymbolValueLiteralMathmlView, { literal: node.value });
700
742
  }
701
743
  if (node.kind === "symbol") {
702
744
  const nodeSymbol = getSymbolById2(sheet, node.symbolId);
703
745
  if (!viewOptions.numerical) {
704
- return /* @__PURE__ */ jsx16(SymbolValueGlyphMathmlView, { glyph: (nodeSymbol == null ? void 0 : nodeSymbol.glyph) || "" });
746
+ return /* @__PURE__ */ jsx17(SymbolValueGlyphMathmlView, { glyph: (nodeSymbol == null ? void 0 : nodeSymbol.glyph) || "" });
705
747
  }
706
- return /* @__PURE__ */ jsx16(
748
+ return /* @__PURE__ */ jsx17(
707
749
  SymbolValueLiteralMathmlView,
708
750
  {
709
751
  literal: (_a = nodeSymbol == null ? void 0 : nodeSymbol.valueTree.result) != null ? _a : emptyLiteral()
@@ -711,7 +753,7 @@ var ValueTreeNodeMathmlView = ({
711
753
  );
712
754
  }
713
755
  if (node.kind === "function") {
714
- return /* @__PURE__ */ jsx16(
756
+ return /* @__PURE__ */ jsx17(
715
757
  ValueTreeFunctionMathmlView,
716
758
  {
717
759
  sheet,
@@ -721,7 +763,7 @@ var ValueTreeNodeMathmlView = ({
721
763
  }
722
764
  );
723
765
  }
724
- return /* @__PURE__ */ jsx16(Fragment2, { children: "Error (Unknown value-tree node)" });
766
+ return /* @__PURE__ */ jsx17(Fragment2, { children: "Error (Unknown value-tree node)" });
725
767
  };
726
768
  var ValueTreeFunctionMathmlView = ({
727
769
  sheet,
@@ -730,13 +772,13 @@ var ValueTreeFunctionMathmlView = ({
730
772
  viewOptions
731
773
  }) => {
732
774
  if (node.kind !== "function") {
733
- return /* @__PURE__ */ jsx16(Fragment2, { children: "Error (Expected function value-tree node)" });
775
+ return /* @__PURE__ */ jsx17(Fragment2, { children: "Error (Expected function value-tree node)" });
734
776
  }
735
777
  const argNodes = node.argKeys.map(
736
778
  (argKey) => getValueNodeByKey(valueTree, argKey)
737
779
  );
738
780
  const argReactNodes = argNodes.map((argNode, index) => {
739
- const rendered = /* @__PURE__ */ jsx16(
781
+ const rendered = /* @__PURE__ */ jsx17(
740
782
  ValueTreeNodeMathmlView,
741
783
  {
742
784
  sheet,
@@ -754,7 +796,7 @@ var ValueTreeFunctionMathmlView = ({
754
796
  parentFunctionId: node.functionId,
755
797
  argumentIndex: index
756
798
  });
757
- return grouped ? /* @__PURE__ */ jsx16(SymbolValueGroupMathmlView, { cursor: void 0, children: [rendered] }, argNode.key) : rendered;
799
+ return grouped ? /* @__PURE__ */ jsx17(SymbolValueGroupMathmlView, { cursor: void 0, children: [rendered] }, argNode.key) : rendered;
758
800
  });
759
801
  const specialFunction = renderSpecialValueFunction({
760
802
  functionId: node.functionId,
@@ -764,15 +806,15 @@ var ValueTreeFunctionMathmlView = ({
764
806
  return specialFunction;
765
807
  }
766
808
  const operator = getFunctionBinaryOperatorById(node.functionId);
767
- if (operator && argNodes.length > 2 && (node.functionId === "fg.and" || node.functionId === "fg.or")) {
768
- return /* @__PURE__ */ jsx16("mrow", { children: argReactNodes.map((argument, index) => {
809
+ if (operator && argNodes.length >= 2 && (node.functionId === "fg.and" || node.functionId === "fg.or")) {
810
+ return /* @__PURE__ */ jsx17("mtable", { columnalign: "left", "data-logical-lines": "true", children: argReactNodes.map((argument, index) => {
769
811
  const child = argNodes[index];
770
812
  const childOperator = child.kind === "function" ? getFunctionBinaryOperatorById(child.functionId) : void 0;
771
- const grouped = childOperator !== void 0 && childOperator.priority < operator.priority;
772
- return /* @__PURE__ */ jsxs7("mrow", { children: [
773
- index > 0 && /* @__PURE__ */ jsx16("mo", { form: "infix", lspace: "0.3em", rspace: "0.3em", children: operator.glyph }),
774
- grouped ? /* @__PURE__ */ jsx16(SymbolValueGroupMathmlView, { cursor: void 0, children: [argument] }) : argument
775
- ] }, child.key);
813
+ const grouped = childOperator !== void 0 && (childOperator.priority < operator.priority || index > 0 && childOperator.priority === operator.priority);
814
+ return /* @__PURE__ */ jsx17("mtr", { children: /* @__PURE__ */ jsxs8("mtd", { style: { textAlign: "left" }, children: [
815
+ index > 0 && /* @__PURE__ */ jsx17("mo", { form: "infix", lspace: "0.3em", rspace: "0.3em", children: operator.glyph }),
816
+ grouped ? /* @__PURE__ */ jsx17(SymbolValueGroupMathmlView, { cursor: void 0, children: [argument] }) : argument
817
+ ] }) }, child.key);
776
818
  }) });
777
819
  }
778
820
  if (operator && argNodes.length === 2) {
@@ -781,9 +823,9 @@ var ValueTreeFunctionMathmlView = ({
781
823
  );
782
824
  const implicitParenthesisLeft = argOperatorLeft && argOperatorLeft.priority < operator.priority;
783
825
  const implicitParenthesisRight = argOperatorRight && argOperatorRight.priority <= operator.priority;
784
- const argLeft = implicitParenthesisLeft ? /* @__PURE__ */ jsx16(SymbolValueGroupMathmlView, { cursor: void 0, children: [argReactNodes[0]] }) : argReactNodes[0];
785
- const argRight = implicitParenthesisRight ? /* @__PURE__ */ jsx16(SymbolValueGroupMathmlView, { cursor: void 0, children: [argReactNodes[1]] }) : argReactNodes[1];
786
- return /* @__PURE__ */ jsx16(
826
+ const argLeft = implicitParenthesisLeft ? /* @__PURE__ */ jsx17(SymbolValueGroupMathmlView, { cursor: void 0, children: [argReactNodes[0]] }) : argReactNodes[0];
827
+ const argRight = implicitParenthesisRight ? /* @__PURE__ */ jsx17(SymbolValueGroupMathmlView, { cursor: void 0, children: [argReactNodes[1]] }) : argReactNodes[1];
828
+ return /* @__PURE__ */ jsx17(
787
829
  SymbolValueBinaryOperatorMathmlView,
788
830
  {
789
831
  operator,
@@ -794,14 +836,14 @@ var ValueTreeFunctionMathmlView = ({
794
836
  }
795
837
  const nodeFunction = getFunctionSpec(node.functionId);
796
838
  const functionNameGlyph = (nodeFunction == null ? void 0 : nodeFunction.glyph) || "";
797
- const groupPrefix = node.functionId === "fg.noop" ? "" : node.functionId === "fg.stub" ? /* @__PURE__ */ jsx16(SymbolValueDraftMathmlView, { draft: "" }) : /* @__PURE__ */ jsx16(SymbolValueGlyphMathmlView, { glyph: functionNameGlyph });
798
- return /* @__PURE__ */ jsx16(
839
+ const groupPrefix = node.functionId === "fg.noop" ? "" : node.functionId === "fg.stub" ? /* @__PURE__ */ jsx17(SymbolValueDraftMathmlView, { draft: "" }) : /* @__PURE__ */ jsx17(SymbolValueGlyphMathmlView, { glyph: functionNameGlyph });
840
+ return /* @__PURE__ */ jsx17(
799
841
  SymbolValueGroupMathmlView,
800
842
  {
801
843
  prefix: groupPrefix,
802
844
  cursor: void 0,
803
845
  empty: node.functionId === "fg.pi" || node.functionId === "fg.noop" || node.functionId === "fg.stub" ? "omit" : "fence",
804
- children: node.argKeys.map((key) => getValueNodeByKey(valueTree, key)).map((argNode) => /* @__PURE__ */ jsx16(
846
+ children: node.argKeys.map((key) => getValueNodeByKey(valueTree, key)).map((argNode) => /* @__PURE__ */ jsx17(
805
847
  ValueTreeNodeMathmlView,
806
848
  {
807
849
  sheet,
@@ -816,14 +858,14 @@ var ValueTreeFunctionMathmlView = ({
816
858
  };
817
859
 
818
860
  // src/mathml/symbol-value/SymbolValueMathmlView.tsx
819
- import { jsx as jsx17 } from "react/jsx-runtime";
861
+ import { jsx as jsx18 } from "react/jsx-runtime";
820
862
  var SymbolValueMathmlView = ({
821
863
  sheet,
822
864
  valueTree,
823
865
  viewOptions,
824
866
  noRootContainer
825
867
  }) => {
826
- return /* @__PURE__ */ jsx17(
868
+ return /* @__PURE__ */ jsx18(
827
869
  ValueTreeMathmlRenderer,
828
870
  {
829
871
  sheet,
@@ -835,7 +877,7 @@ var SymbolValueMathmlView = ({
835
877
  };
836
878
 
837
879
  // src/mathml/SymbolValueMathBlock.tsx
838
- import { jsx as jsx18, jsxs as jsxs8 } from "react/jsx-runtime";
880
+ import { jsx as jsx19, jsxs as jsxs9 } from "react/jsx-runtime";
839
881
  var SymbolValueMathBlock = ({
840
882
  sheet,
841
883
  symbol,
@@ -863,33 +905,37 @@ var SymbolValueMathBlock = ({
863
905
  flexShrink: "0"
864
906
  }
865
907
  };
866
- return /* @__PURE__ */ jsxs8("div", { children: [
867
- showGlyph && /* @__PURE__ */ jsx18("div", __spreadProps(__spreadValues({}, divProps), { children: /* @__PURE__ */ jsx18("math", __spreadProps(__spreadValues({}, baseMathProps), { children: /* @__PURE__ */ jsx18("mrow", { children: /* @__PURE__ */ jsx18(AsciiMathView, { expression: symbol.glyph }) }) })) })),
868
- showSymbolic && showGlyph && /* @__PURE__ */ jsx18("div", __spreadProps(__spreadValues({}, divProps), { children: /* @__PURE__ */ jsx18("math", __spreadProps(__spreadValues({}, baseMathProps), { children: /* @__PURE__ */ jsx18("mrow", { children: /* @__PURE__ */ jsx18("mo", { className: "px-1 py-2", children: "=" }) }) })) })),
869
- showSymbolic && /* @__PURE__ */ jsx18("div", __spreadProps(__spreadValues({}, divProps), { children: /* @__PURE__ */ jsx18("math", __spreadProps(__spreadValues({}, baseMathProps), { children: /* @__PURE__ */ jsx18("mrow", { children: /* @__PURE__ */ jsx18(
870
- SymbolValueMathmlView,
871
- {
872
- sheet,
873
- valueTree: symbol.valueTree,
874
- noRootContainer: true,
875
- viewOptions: { literalsAsDrafts: true }
876
- }
877
- ) }) })) })),
878
- showNumeric && (showGlyph || showSymbolic) && /* @__PURE__ */ jsx18("div", __spreadProps(__spreadValues({}, divProps), { children: /* @__PURE__ */ jsx18("math", __spreadProps(__spreadValues({}, baseMathProps), { children: /* @__PURE__ */ jsx18("mrow", { children: /* @__PURE__ */ jsx18("mo", { className: "px-1 py-2", children: "=" }) }) })) })),
879
- showNumeric && /* @__PURE__ */ jsx18("div", __spreadProps(__spreadValues({}, divProps), { children: /* @__PURE__ */ jsx18("math", __spreadProps(__spreadValues({}, baseMathProps), { children: /* @__PURE__ */ jsx18("mrow", { children: /* @__PURE__ */ jsx18(
880
- SymbolValueMathmlView,
881
- {
882
- sheet,
883
- valueTree: symbol.valueTree,
884
- noRootContainer: true,
885
- viewOptions: { numerical: true, literalsAsDrafts: true }
886
- }
887
- ) }) })) }))
908
+ return /* @__PURE__ */ jsxs9("div", { children: [
909
+ showGlyph && /* @__PURE__ */ jsx19("div", __spreadProps(__spreadValues({}, divProps), { children: /* @__PURE__ */ jsx19("math", __spreadProps(__spreadValues({}, baseMathProps), { children: /* @__PURE__ */ jsx19("mrow", { children: /* @__PURE__ */ jsx19(AsciiMathView, { expression: symbol.glyph }) }) })) })),
910
+ showSymbolic && /* @__PURE__ */ jsx19("div", __spreadProps(__spreadValues({}, divProps), { children: /* @__PURE__ */ jsx19("math", __spreadProps(__spreadValues({}, baseMathProps), { children: /* @__PURE__ */ jsxs9("mrow", { children: [
911
+ showGlyph && /* @__PURE__ */ jsx19("mo", { className: "px-1 py-2", children: "=" }),
912
+ /* @__PURE__ */ jsx19(
913
+ SymbolValueMathmlView,
914
+ {
915
+ sheet,
916
+ valueTree: symbol.valueTree,
917
+ noRootContainer: true,
918
+ viewOptions: { literalsAsDrafts: true }
919
+ }
920
+ )
921
+ ] }) })) })),
922
+ showNumeric && /* @__PURE__ */ jsx19("div", __spreadProps(__spreadValues({}, divProps), { children: /* @__PURE__ */ jsx19("math", __spreadProps(__spreadValues({}, baseMathProps), { children: /* @__PURE__ */ jsxs9("mrow", { children: [
923
+ (showGlyph || showSymbolic) && /* @__PURE__ */ jsx19("mo", { className: "px-1 py-2", children: "=" }),
924
+ /* @__PURE__ */ jsx19(
925
+ SymbolValueMathmlView,
926
+ {
927
+ sheet,
928
+ valueTree: symbol.valueTree,
929
+ noRootContainer: true,
930
+ viewOptions: { numerical: true, literalsAsDrafts: true }
931
+ }
932
+ )
933
+ ] }) })) }))
888
934
  ] });
889
935
  };
890
936
 
891
937
  // src/formula-sheet/FormulaSheetValueTree.tsx
892
- import { jsx as jsx19, jsxs as jsxs9 } from "react/jsx-runtime";
938
+ import { jsx as jsx20, jsxs as jsxs10 } from "react/jsx-runtime";
893
939
  var additionTerms = (tree, key, ancestors = /* @__PURE__ */ new Set()) => {
894
940
  if (ancestors.has(key)) {
895
941
  throw new Error(`Recursive formula node '${key}'`);
@@ -920,71 +966,111 @@ var hasActiveSymbol = (tree) => {
920
966
  };
921
967
  var FormulaSheetValueTree = ({
922
968
  sheet,
923
- symbol
969
+ symbol,
970
+ symbolicOnly = false
924
971
  }) => {
925
972
  const showSymbolic = hasActiveSymbol(symbol.valueTree);
926
973
  const terms = additionTerms(symbol.valueTree, symbol.valueTree.rootKey);
927
974
  if (terms.length > 4) {
928
- return /* @__PURE__ */ jsx19("div", { className: "cso-long-formula", children: (showSymbolic ? [false, true] : [true]).map((numerical) => (
929
- // biome-ignore lint/a11y/useSemanticElements: This labels a formula group, not a fieldset of form controls.
930
- /* @__PURE__ */ jsx19(
931
- "div",
932
- {
933
- className: "cso-formula-terms",
934
- role: "group",
935
- "aria-label": numerical ? "Substitution" : "Formula",
936
- children: terms.map((rootKey, index) => {
937
- const node = symbol.valueTree.nodes.find(
938
- (node2) => node2.key === rootKey
939
- );
940
- const operator = (node == null ? void 0 : node.kind) === "function" ? getFunctionBinaryOperatorById2(node.functionId) : void 0;
941
- const grouped = operator !== void 0 && (operator.priority < SheetOperatorPriority.AddSubtract || index > 0 && operator.priority === SheetOperatorPriority.AddSubtract) || node !== void 0 && requiresExplicitOperandGroup({
942
- sheet,
943
- node,
944
- numerical,
945
- literalsAsDrafts: true,
946
- parentFunctionId: "fg.add",
947
- argumentIndex: index === 0 ? 0 : 1
948
- });
949
- return /* @__PURE__ */ jsx19("span", { className: "cso-formula-term", children: /* @__PURE__ */ jsxs9("math", { display: "inline", children: [
950
- index === 0 && /* @__PURE__ */ jsx19(AsciiMathView, { expression: symbol.glyph }),
951
- /* @__PURE__ */ jsx19("mo", { children: index === 0 ? "=" : "+" }),
952
- grouped && /* @__PURE__ */ jsx19("mo", { children: "(" }),
953
- /* @__PURE__ */ jsx19(
954
- SymbolValueMathmlView,
975
+ return /* @__PURE__ */ jsx20("div", { className: "cso-long-formula", children: (symbolicOnly ? [false] : showSymbolic ? [false, true] : [true]).map(
976
+ (numerical) => (
977
+ // biome-ignore lint/a11y/useSemanticElements: This labels a formula group, not a fieldset of form controls.
978
+ /* @__PURE__ */ jsx20(
979
+ "div",
980
+ {
981
+ className: "cso-formula-terms",
982
+ role: "group",
983
+ "aria-label": numerical ? "Substitution" : "Formula",
984
+ children: terms.map((rootKey, index) => {
985
+ const node = symbol.valueTree.nodes.find(
986
+ (node2) => node2.key === rootKey
987
+ );
988
+ const operator = (node == null ? void 0 : node.kind) === "function" ? getFunctionBinaryOperatorById2(node.functionId) : void 0;
989
+ const grouped = operator !== void 0 && (operator.priority < SheetOperatorPriority.AddSubtract || index > 0 && operator.priority === SheetOperatorPriority.AddSubtract) || node !== void 0 && requiresExplicitOperandGroup({
990
+ sheet,
991
+ node,
992
+ numerical,
993
+ literalsAsDrafts: true,
994
+ parentFunctionId: "fg.add",
995
+ argumentIndex: index === 0 ? 0 : 1
996
+ });
997
+ return /* @__PURE__ */ jsx20(
998
+ "span",
955
999
  {
956
- sheet,
957
- valueTree: __spreadProps(__spreadValues({}, symbol.valueTree), { rootKey }),
958
- noRootContainer: true,
959
- viewOptions: { numerical, literalsAsDrafts: true }
960
- }
961
- ),
962
- grouped && /* @__PURE__ */ jsx19("mo", { children: ")" })
963
- ] }) }, `${index}-${rootKey}`);
964
- })
965
- },
966
- String(numerical)
1000
+ className: "cso-formula-term",
1001
+ children: /* @__PURE__ */ jsxs10("math", { display: "inline", children: [
1002
+ index === 0 && /* @__PURE__ */ jsx20(AsciiMathView, { expression: symbol.glyph }),
1003
+ /* @__PURE__ */ jsx20("mo", { children: index === 0 ? "=" : "+" }),
1004
+ grouped && /* @__PURE__ */ jsx20("mo", { children: "(" }),
1005
+ /* @__PURE__ */ jsx20(
1006
+ SymbolValueMathmlView,
1007
+ {
1008
+ sheet,
1009
+ valueTree: __spreadProps(__spreadValues({}, symbol.valueTree), { rootKey }),
1010
+ noRootContainer: true,
1011
+ viewOptions: { numerical, literalsAsDrafts: true }
1012
+ }
1013
+ ),
1014
+ grouped && /* @__PURE__ */ jsx20("mo", { children: ")" })
1015
+ ] })
1016
+ },
1017
+ `${index}-${rootKey}`
1018
+ );
1019
+ })
1020
+ },
1021
+ String(numerical)
1022
+ )
967
1023
  )
968
- )) });
1024
+ ) });
969
1025
  }
970
- return /* @__PURE__ */ jsx19(
1026
+ return /* @__PURE__ */ jsx20(
971
1027
  SymbolValueMathBlock,
972
1028
  {
973
1029
  sheet,
974
1030
  symbol,
975
1031
  showGlyph: true,
976
- showSymbolic,
977
- showNumeric: true
1032
+ showSymbolic: symbolicOnly || showSymbolic,
1033
+ showNumeric: !symbolicOnly
978
1034
  }
979
1035
  );
980
1036
  };
981
1037
 
982
1038
  // src/formula-sheet/FormulaSheetSymbolRow.tsx
983
- import { jsx as jsx20, jsxs as jsxs10 } from "react/jsx-runtime";
1039
+ import { jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
1040
+ var bindingOrigin = ({
1041
+ sheet,
1042
+ symbol,
1043
+ label,
1044
+ computedReference = false
1045
+ }) => {
1046
+ const root = getValueNodeByKey2(symbol.valueTree, symbol.valueTree.rootKey);
1047
+ const source = root.kind === "symbol" ? sheet.symbols.find((item) => item.id === root.symbolId) : computedReference && root.kind === "function" ? symbol : void 0;
1048
+ if (root.kind === "symbol" && !source)
1049
+ throw new Error(`Missing binding origin '${root.symbolId}'`);
1050
+ if (source)
1051
+ return /* @__PURE__ */ jsxs11("span", { "data-binding-origin": source.id, "data-binding-call": label, children: [
1052
+ label ? `${label}: ` : "",
1053
+ "From ",
1054
+ /* @__PURE__ */ jsx21(GlyphMathBlock, { glyph: source.glyph })
1055
+ ] });
1056
+ if (root.kind === "literal" && root.value.kind === "number")
1057
+ return /* @__PURE__ */ jsxs11("span", { "data-binding-origin": "literal", "data-binding-call": label, children: [
1058
+ label ? `${label}: ` : "",
1059
+ "Given",
1060
+ " ",
1061
+ root.draft || (Object.is(root.value.value, -0) ? "-0" : String(root.value.value))
1062
+ ] });
1063
+ return void 0;
1064
+ };
984
1065
  var FormulaSheetSymbolRow = ({
985
1066
  sheet,
986
1067
  sheetItemIndex,
987
- item: symbol
1068
+ item: symbol,
1069
+ symbolicOnly = false,
1070
+ showFormula = true,
1071
+ numericKind,
1072
+ compactBinding = false,
1073
+ bindingOrigin: suppliedOrigin
988
1074
  }) => {
989
1075
  var _a, _b;
990
1076
  const { glyph: symbolGlyph } = symbol;
@@ -996,41 +1082,66 @@ var FormulaSheetSymbolRow = ({
996
1082
  symbol.valueTree.rootKey
997
1083
  );
998
1084
  const symbolIsSolidLiteral = rootNode.kind === "literal";
999
- return /* @__PURE__ */ jsx20("div", { className: "cso-symbol-row flex min-w-0 flex-col", children: /* @__PURE__ */ jsxs10("div", { className: "min-w-0", children: [
1000
- /* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 border-t border-gray-300", children: [
1001
- /* @__PURE__ */ jsx20(FormulaSheetSpacerCell, {}),
1002
- /* @__PURE__ */ jsx20(FormulaSheetDescriptionCell, { children: /* @__PURE__ */ jsxs10("span", { children: [
1003
- /* @__PURE__ */ jsx20(FormulaSheetItemIndex, { index: sheetItemIndex }),
1085
+ const origin = suppliedOrigin != null ? suppliedOrigin : compactBinding ? bindingOrigin({ sheet, symbol }) : void 0;
1086
+ return /* @__PURE__ */ jsx21("div", { className: "cso-symbol-row flex min-w-0 flex-col", children: /* @__PURE__ */ jsxs11("div", { className: "min-w-0", children: [
1087
+ /* @__PURE__ */ jsxs11("div", { className: "flex min-w-0 border-t border-gray-300", children: [
1088
+ /* @__PURE__ */ jsx21(FormulaSheetSpacerCell, {}),
1089
+ /* @__PURE__ */ jsx21(FormulaSheetDescriptionCell, { children: /* @__PURE__ */ jsxs11("span", { children: [
1090
+ /* @__PURE__ */ jsx21(FormulaSheetItemIndex, { index: sheetItemIndex }),
1004
1091
  " ",
1005
1092
  symbolDescription
1006
1093
  ] }) }),
1007
- /* @__PURE__ */ jsx20(FormulaSheetSymbolCell, { children: /* @__PURE__ */ jsx20(
1094
+ /* @__PURE__ */ jsx21(FormulaSheetSymbolCell, { children: /* @__PURE__ */ jsx21(
1008
1095
  GlyphMathBlock,
1009
1096
  {
1010
1097
  glyph: symbolGlyph,
1011
1098
  mathProps: { className: "shrink-0" }
1012
1099
  }
1013
1100
  ) }),
1014
- /* @__PURE__ */ jsx20(FormulaSheetResultCell, { literal: symbol.valueTree.result }),
1015
- /* @__PURE__ */ jsx20(FormulaSheetUnitCell, { children: /* @__PURE__ */ jsx20(UnitMathBlock, { unit: symbolUnit, optional: true }) }),
1016
- /* @__PURE__ */ jsx20(FormulaSheetCommentCell, { children: symbolComment || " " })
1101
+ symbolicOnly ? /* @__PURE__ */ jsx21(FormulaSheetValueCell, { children: /* @__PURE__ */ jsx21(
1102
+ "span",
1103
+ {
1104
+ className: "cso-symbolic-value",
1105
+ role: "img",
1106
+ "aria-label": "Value not yet defined",
1107
+ children: "\xD7"
1108
+ }
1109
+ ) }) : /* @__PURE__ */ jsx21(
1110
+ FormulaSheetResultCell,
1111
+ {
1112
+ literal: symbol.valueTree.result,
1113
+ numericKind
1114
+ }
1115
+ ),
1116
+ /* @__PURE__ */ jsx21(FormulaSheetUnitCell, { children: /* @__PURE__ */ jsx21(UnitMathBlock, { unit: symbolUnit, optional: true }) }),
1117
+ /* @__PURE__ */ jsxs11(FormulaSheetCommentCell, { children: [
1118
+ origin ? /* @__PURE__ */ jsx21("div", { children: origin }) : null,
1119
+ symbolComment || " "
1120
+ ] })
1017
1121
  ] }),
1018
- !symbolIsSolidLiteral && /* @__PURE__ */ jsx20("div", { className: "flex min-w-0", children: /* @__PURE__ */ jsx20("div", { className: "w-full min-w-0 overflow-visible border-t border-gray-300 text-[14px]", children: /* @__PURE__ */ jsxs10("div", { className: "my-2 flex min-w-0", children: [
1019
- /* @__PURE__ */ jsx20(FormulaSheetSpacerCell, {}),
1020
- /* @__PURE__ */ jsx20("div", { className: "min-w-0 max-w-full flex-1 overflow-visible", children: /* @__PURE__ */ jsx20(FormulaSheetValueTree, { sheet, symbol }) })
1122
+ showFormula && !origin && (!symbolIsSolidLiteral || symbolicOnly && rootNode.kind === "literal" && rootNode.value.kind !== "empty") && /* @__PURE__ */ jsx21("div", { className: "flex min-w-0", "data-derivation": "true", children: /* @__PURE__ */ jsx21("div", { className: "w-full min-w-0 overflow-visible border-t border-gray-300 text-[14px]", children: /* @__PURE__ */ jsxs11("div", { className: "my-2 flex min-w-0", children: [
1123
+ /* @__PURE__ */ jsx21(FormulaSheetSpacerCell, {}),
1124
+ /* @__PURE__ */ jsx21("div", { className: "min-w-0 max-w-full flex-1 overflow-visible", children: /* @__PURE__ */ jsx21(
1125
+ FormulaSheetValueTree,
1126
+ {
1127
+ sheet,
1128
+ symbol,
1129
+ symbolicOnly
1130
+ }
1131
+ ) })
1021
1132
  ] }) }) })
1022
1133
  ] }) });
1023
1134
  };
1024
1135
 
1025
1136
  // src/formula-sheet/FormulaSheetItem.tsx
1026
- import { jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
1137
+ import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
1027
1138
  var FormulaSheetItem = ({
1028
1139
  sheet,
1029
1140
  item,
1030
1141
  sheetItemIndex
1031
1142
  }) => {
1032
- return /* @__PURE__ */ jsxs11("div", { className: "relative min-w-0", children: [
1033
- item.kind === "section" && /* @__PURE__ */ jsx21(
1143
+ return /* @__PURE__ */ jsxs12("div", { className: "relative min-w-0", children: [
1144
+ item.kind === "section" && /* @__PURE__ */ jsx22(
1034
1145
  FormulaSheetSectionRow,
1035
1146
  {
1036
1147
  sheet,
@@ -1038,7 +1149,7 @@ var FormulaSheetItem = ({
1038
1149
  item: item.section
1039
1150
  }
1040
1151
  ),
1041
- item.kind === "symbol" && /* @__PURE__ */ jsx21(
1152
+ item.kind === "symbol" && /* @__PURE__ */ jsx22(
1042
1153
  FormulaSheetSymbolRow,
1043
1154
  {
1044
1155
  sheet,
@@ -1053,18 +1164,18 @@ var FormulaSheetItem = ({
1053
1164
  import {
1054
1165
  getRootSectionItems
1055
1166
  } from "@cs-object/core";
1056
- import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
1167
+ import { jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
1057
1168
  var getFormulaSheetItemKey = (item, sheetItemIndex) => `${sheetItemIndex}-${item.kind}-${item.kind === "section" ? item.section.id : item.symbol.id}`;
1058
1169
  var FormulaSheet = ({ sheet }) => {
1059
1170
  const sheetItems = getRootSectionItems(sheet);
1060
- return /* @__PURE__ */ jsxs12(
1171
+ return /* @__PURE__ */ jsxs13(
1061
1172
  "article",
1062
1173
  {
1063
1174
  "data-formula-sheet": "true",
1064
1175
  className: "flex min-h-[297mm] w-[210mm] min-w-[210mm] max-w-none flex-col items-stretch border border-gray-300 bg-white p-[5mm] [&_*:focus-visible]:outline-hidden",
1065
1176
  children: [
1066
- /* @__PURE__ */ jsx22(FormulaSheetHeader, {}),
1067
- sheetItems.map((item, sheetItemIndex) => /* @__PURE__ */ jsx22(
1177
+ /* @__PURE__ */ jsx23(FormulaSheetHeader, {}),
1178
+ sheetItems.map((item, sheetItemIndex) => /* @__PURE__ */ jsx23(
1068
1179
  FormulaSheetItem,
1069
1180
  {
1070
1181
  sheet,
@@ -1078,6 +1189,397 @@ var FormulaSheet = ({ sheet }) => {
1078
1189
  );
1079
1190
  };
1080
1191
 
1192
+ // src/formula-sheet/partition-comparisons.ts
1193
+ var FIT_TOLERANCE_PX = 2;
1194
+ function partitionColumnAxis(columnWidths, labelWidth, availableWidth, cap) {
1195
+ var _a;
1196
+ if (columnWidths.length === 0 || availableWidth <= 0) {
1197
+ return {
1198
+ groups: columnWidths.length ? [columnWidths.map((_, index) => index)] : []
1199
+ };
1200
+ }
1201
+ const limit = cap && cap > 0 ? cap : Number.POSITIVE_INFINITY;
1202
+ const groups = [];
1203
+ let current = [];
1204
+ let used = labelWidth;
1205
+ for (let index = 0; index < columnWidths.length; index += 1) {
1206
+ const width = (_a = columnWidths[index]) != null ? _a : 0;
1207
+ const alone = labelWidth + width;
1208
+ if (alone > availableWidth + FIT_TOLERANCE_PX) {
1209
+ return {
1210
+ groups: [],
1211
+ unfit: { column: index, required: alone, available: availableWidth }
1212
+ };
1213
+ }
1214
+ if (current.length > 0 && (current.length >= limit || used + width > availableWidth + FIT_TOLERANCE_PX)) {
1215
+ groups.push(current);
1216
+ current = [];
1217
+ used = labelWidth;
1218
+ }
1219
+ current.push(index);
1220
+ used += width;
1221
+ }
1222
+ if (current.length > 0) groups.push(current);
1223
+ return { groups };
1224
+ }
1225
+ function partitionRowAxis(rows, chromeHeight, availableHeight, firstAvailable = availableHeight) {
1226
+ var _a, _b, _c, _d;
1227
+ if (rows.length === 0 || availableHeight <= 0) {
1228
+ return { groups: rows.length ? [rows.map((_, index) => index)] : [] };
1229
+ }
1230
+ const groups = [];
1231
+ let current = [];
1232
+ let used = chromeHeight;
1233
+ let limit = firstAvailable > 0 ? firstAvailable : availableHeight;
1234
+ let banner = null;
1235
+ let bannerIncluded = false;
1236
+ for (let index = 0; index < rows.length; index += 1) {
1237
+ const row = rows[index];
1238
+ if (!row) continue;
1239
+ if (row.repeat) {
1240
+ banner = index;
1241
+ bannerIncluded = false;
1242
+ continue;
1243
+ }
1244
+ const bannerHeight = banner !== null && !bannerIncluded ? (_b = (_a = rows[banner]) == null ? void 0 : _a.height) != null ? _b : 0 : 0;
1245
+ const required = chromeHeight + bannerHeight + row.height;
1246
+ if (required > availableHeight + 2) {
1247
+ return {
1248
+ groups: [],
1249
+ unfit: { row: index, required, available: availableHeight }
1250
+ };
1251
+ }
1252
+ if (current.length === 0 && required > limit + 2) {
1253
+ limit = availableHeight;
1254
+ }
1255
+ if (current.length > 0 && used + bannerHeight + row.height > limit + 2) {
1256
+ groups.push(current);
1257
+ current = [];
1258
+ used = chromeHeight;
1259
+ bannerIncluded = false;
1260
+ limit = availableHeight;
1261
+ }
1262
+ if (banner !== null && !bannerIncluded) {
1263
+ current.push(banner);
1264
+ used += (_d = (_c = rows[banner]) == null ? void 0 : _c.height) != null ? _d : 0;
1265
+ bannerIncluded = true;
1266
+ }
1267
+ current.push(index);
1268
+ used += row.height;
1269
+ }
1270
+ if (current.length > 0) groups.push(current);
1271
+ return { groups };
1272
+ }
1273
+ function planComparisonParts(measurements) {
1274
+ return measurements.map((measurement) => {
1275
+ const partitioned = partitionColumnAxis(
1276
+ measurement.columnWidths,
1277
+ measurement.labelWidth,
1278
+ measurement.availableWidth,
1279
+ measurement.cap
1280
+ );
1281
+ return __spreadValues(__spreadProps(__spreadValues({}, measurement), {
1282
+ groups: partitioned.groups
1283
+ }), partitioned.unfit ? { unfit: partitioned.unfit } : {});
1284
+ });
1285
+ }
1286
+ function measureComparisons(root) {
1287
+ const scope = root != null ? root : document;
1288
+ const measurements = [];
1289
+ for (const comparison of scope.querySelectorAll(
1290
+ "[data-comparison-id]"
1291
+ )) {
1292
+ const table = comparison.querySelector(
1293
+ 'table[data-comparison-table="screen"]'
1294
+ );
1295
+ const scroll = comparison.querySelector(
1296
+ "[data-comparison-scroll]"
1297
+ );
1298
+ if (!table || !scroll || typeof table.getBoundingClientRect !== "function") {
1299
+ continue;
1300
+ }
1301
+ const labelWidth = [
1302
+ ...table.querySelectorAll("[data-comparison-label]")
1303
+ ].reduce(
1304
+ (max, cell) => Math.max(max, cell.getBoundingClientRect().width),
1305
+ 0
1306
+ );
1307
+ const columnWidths = [];
1308
+ for (const cell of table.querySelectorAll(
1309
+ "thead [data-comparison-column]"
1310
+ )) {
1311
+ const index = Number(cell.getAttribute("data-comparison-column"));
1312
+ if (!Number.isInteger(index) || columnWidths[index] !== void 0)
1313
+ continue;
1314
+ columnWidths[index] = cell.getBoundingClientRect().width;
1315
+ }
1316
+ const cap = Number(comparison.getAttribute("data-column-cap"));
1317
+ const measurement = {
1318
+ comparisonId: comparison.getAttribute("data-comparison-id") || "",
1319
+ sourcePlacementId: comparison.getAttribute("data-source-placement") || "",
1320
+ labelWidth,
1321
+ columnWidths,
1322
+ availableWidth: scroll.clientWidth
1323
+ };
1324
+ if (Number.isInteger(cap) && cap > 0) measurement.cap = cap;
1325
+ measurements.push(measurement);
1326
+ }
1327
+ return measurements;
1328
+ }
1329
+ function renderComparisonParts(plans, root, rowPartitioner = partitionRowAxis) {
1330
+ var _a;
1331
+ const noteMatches = (note, comparison, kept) => {
1332
+ if (comparison.getAttribute("data-cases-axis") === "rows") return true;
1333
+ const heading = note.getAttribute("data-case");
1334
+ if (!heading) return true;
1335
+ const header = [
1336
+ ...comparison.querySelectorAll(
1337
+ "thead [data-case-heading][data-comparison-column]"
1338
+ )
1339
+ ].find((cell) => cell.getAttribute("data-case-heading") === heading);
1340
+ if (!header) return true;
1341
+ return kept.has(Number(header.getAttribute("data-comparison-column")));
1342
+ };
1343
+ const keepColumn = (cell, kept) => {
1344
+ if (cell.hasAttribute("data-comparison-label")) return true;
1345
+ if (cell.hasAttribute("data-comparison-banner")) {
1346
+ cell.colSpan = kept.size + 1;
1347
+ return true;
1348
+ }
1349
+ const listed = cell.getAttribute("data-comparison-columns");
1350
+ if (listed !== null) {
1351
+ const next = listed.split(",").filter((value) => kept.has(Number(value)));
1352
+ if (next.length === 0) return false;
1353
+ cell.colSpan = next.length;
1354
+ cell.setAttribute("data-comparison-columns", next.join(","));
1355
+ return true;
1356
+ }
1357
+ const index = cell.getAttribute("data-comparison-column");
1358
+ return index === null || kept.has(Number(index));
1359
+ };
1360
+ const scope = root != null ? root : document;
1361
+ const diagnostics = [];
1362
+ for (const [comparisonIndex, plan] of plans.entries()) {
1363
+ const comparison = [
1364
+ ...scope.querySelectorAll("[data-comparison-id]")
1365
+ ].find(
1366
+ (element) => element.getAttribute("data-comparison-id") === plan.comparisonId
1367
+ );
1368
+ if (!comparison) continue;
1369
+ (_a = comparison.querySelector("[data-comparison-parts]")) == null ? void 0 : _a.remove();
1370
+ const selector = `[data-source-placement=${JSON.stringify(plan.sourcePlacementId)}]`;
1371
+ if (plan.unfit) {
1372
+ const overflowPx = Math.max(
1373
+ 0,
1374
+ plan.unfit.required - plan.unfit.available
1375
+ );
1376
+ const layout = {
1377
+ media: "print",
1378
+ selector,
1379
+ left: 0,
1380
+ right: plan.unfit.required,
1381
+ containerLeft: 0,
1382
+ containerRight: plan.unfit.available,
1383
+ overflowPx
1384
+ };
1385
+ if (plan.sourcePlacementId) {
1386
+ layout.sourcePlacementId = plan.sourcePlacementId;
1387
+ }
1388
+ diagnostics.push({
1389
+ code: "DOCUMENT_LAYOUT_OVERFLOW",
1390
+ stage: "rendering",
1391
+ check: "rendering",
1392
+ message: `Comparison column ${plan.unfit.column + 1} cannot fit with its labels in print layout: ${selector}, required ${plan.unfit.required.toFixed(2)}px, available ${plan.unfit.available.toFixed(2)}px.`,
1393
+ layout
1394
+ });
1395
+ continue;
1396
+ }
1397
+ const table = comparison.querySelector(
1398
+ 'table[data-comparison-table="screen"]'
1399
+ );
1400
+ if (!table || plan.groups.length === 0) continue;
1401
+ const parts = document.createElement("div");
1402
+ parts.setAttribute("data-comparison-parts", "");
1403
+ parts.className = "cso-comparison-parts";
1404
+ plan.groups.forEach((group, partIndex) => {
1405
+ var _a2, _b, _c, _d, _e, _f;
1406
+ const kept = new Set(group);
1407
+ const part = document.createElement("section");
1408
+ part.className = "cso-comparison-part";
1409
+ part.setAttribute("data-comparison-part", String(partIndex + 1));
1410
+ part.setAttribute("data-part-count", String(plan.groups.length));
1411
+ for (const note of comparison.querySelectorAll(
1412
+ ":scope > p.cso-branch-note"
1413
+ )) {
1414
+ if (noteMatches(note, comparison, kept))
1415
+ part.appendChild(note.cloneNode(true));
1416
+ }
1417
+ const clone = table.cloneNode(true);
1418
+ clone.removeAttribute("data-comparison-table");
1419
+ clone.setAttribute("data-comparison-part-table", String(partIndex + 1));
1420
+ for (const row of clone.querySelectorAll("tr")) {
1421
+ for (const cell of [...row.children]) {
1422
+ if (!keepColumn(cell, kept)) cell.remove();
1423
+ }
1424
+ }
1425
+ const columns = document.createElement("colgroup");
1426
+ const widths = [
1427
+ plan.labelWidth,
1428
+ ...group.map((index) => plan.columnWidths[index] || 0)
1429
+ ];
1430
+ const dataWidth = widths.slice(1).reduce((sum, width) => sum + width, 0);
1431
+ widths.forEach((width, index) => {
1432
+ const column = document.createElement("col");
1433
+ column.style.width = `${index === 0 ? width : dataWidth ? width / dataWidth * (plan.availableWidth - plan.labelWidth) : 0}px`;
1434
+ columns.appendChild(column);
1435
+ });
1436
+ clone.prepend(columns);
1437
+ clone.style.tableLayout = "fixed";
1438
+ const contextRow = document.createElement("tr");
1439
+ const context = document.createElement("th");
1440
+ context.colSpan = group.length + 1;
1441
+ context.setAttribute("data-comparison-context", "");
1442
+ const title = document.createElement("strong");
1443
+ title.textContent = ((_a2 = comparison.querySelector(":scope > h3")) == null ? void 0 : _a2.textContent) || "Comparison";
1444
+ if (plan.groups.length > 1)
1445
+ title.textContent += `. Part ${partIndex + 1} of ${plan.groups.length}`;
1446
+ context.appendChild(title);
1447
+ const methodReference = comparison.querySelector(
1448
+ ":scope > [data-method-reference]"
1449
+ );
1450
+ if (methodReference) context.appendChild(methodReference.cloneNode(true));
1451
+ for (const limit of table.querySelectorAll(
1452
+ 'th[data-outcome-kind="applicability"]'
1453
+ )) {
1454
+ const note = document.createElement("div");
1455
+ note.className = "cso-result-status";
1456
+ note.appendChild(document.createTextNode("Applicability limit "));
1457
+ note.appendChild(
1458
+ ((_b = limit.firstElementChild) == null ? void 0 : _b.cloneNode(true)) || document.createTextNode("")
1459
+ );
1460
+ context.appendChild(note);
1461
+ }
1462
+ if (comparison.getAttribute("data-cases-axis") === "columns") {
1463
+ const labels = [];
1464
+ let group2 = "";
1465
+ let indexes = [];
1466
+ const save = () => {
1467
+ if (group2 && indexes.length)
1468
+ labels.push(
1469
+ `${group2} ${indexes[0]}-${indexes[indexes.length - 1]}`
1470
+ );
1471
+ };
1472
+ for (const row of ((_c = clone.tBodies[0]) == null ? void 0 : _c.rows) || []) {
1473
+ const banner = row.querySelector("[data-comparison-banner]");
1474
+ if (banner) {
1475
+ save();
1476
+ group2 = banner.textContent || "";
1477
+ indexes = [];
1478
+ } else {
1479
+ const index = (_e = (_d = row.querySelector("[data-formula-sheet-item-index]")) == null ? void 0 : _d.textContent) == null ? void 0 : _e.replace(".", "");
1480
+ if (index) indexes.push(index);
1481
+ }
1482
+ }
1483
+ save();
1484
+ const key = document.createElement("div");
1485
+ key.className = "cso-result-status";
1486
+ key.textContent = labels.join(" \xB7 ");
1487
+ context.appendChild(key);
1488
+ }
1489
+ contextRow.appendChild(context);
1490
+ (_f = clone.tHead) == null ? void 0 : _f.prepend(contextRow);
1491
+ let rowNumber = 0;
1492
+ for (const row of clone.querySelectorAll("tr")) {
1493
+ const label = row.querySelector("[data-comparison-label]");
1494
+ if (!label) continue;
1495
+ const rowId = `cso-c${comparisonIndex}-p${partIndex}-r${rowNumber}`;
1496
+ rowNumber += 1;
1497
+ label.id = rowId;
1498
+ for (const cell of row.querySelectorAll(
1499
+ "[data-comparison-column]"
1500
+ )) {
1501
+ const column = cell.getAttribute("data-comparison-column");
1502
+ const header = clone.querySelector(
1503
+ `thead [data-comparison-column="${column}"]`
1504
+ );
1505
+ if (header && !header.id) {
1506
+ header.id = `cso-c${comparisonIndex}-p${partIndex}-c${column}`;
1507
+ }
1508
+ if (cell.tagName === "TD" && (header == null ? void 0 : header.id)) {
1509
+ cell.setAttribute("headers", `${rowId} ${header.id}`);
1510
+ }
1511
+ }
1512
+ }
1513
+ part.appendChild(clone);
1514
+ parts.appendChild(part);
1515
+ });
1516
+ const split = splitComparisonParts(parts);
1517
+ if (split) {
1518
+ const overflowPx = Math.max(0, split.required - split.available);
1519
+ const layout = {
1520
+ media: "print",
1521
+ selector,
1522
+ left: 0,
1523
+ right: split.required,
1524
+ containerLeft: 0,
1525
+ containerRight: split.available,
1526
+ overflowPx
1527
+ };
1528
+ if (plan.sourcePlacementId) {
1529
+ layout.sourcePlacementId = plan.sourcePlacementId;
1530
+ }
1531
+ diagnostics.push({
1532
+ code: "DOCUMENT_LAYOUT_OVERFLOW",
1533
+ stage: "rendering",
1534
+ check: "rendering",
1535
+ message: `Comparison row ${split.row + 1} cannot fit with its repeated headings in print layout: ${selector}, required ${split.required.toFixed(2)}px, available ${split.available.toFixed(2)}px.`,
1536
+ layout
1537
+ });
1538
+ continue;
1539
+ }
1540
+ comparison.appendChild(parts);
1541
+ }
1542
+ return diagnostics;
1543
+ function splitComparisonParts(parts) {
1544
+ var _a2;
1545
+ const frame = document.createElement("div");
1546
+ frame.className = "cso-comparison";
1547
+ Object.assign(frame.style, {
1548
+ position: "absolute",
1549
+ left: "0",
1550
+ top: "0",
1551
+ visibility: "hidden"
1552
+ });
1553
+ frame.style.width = getComputedStyle(document.documentElement).getPropertyValue("--cso-print-content-width").trim() || "190mm";
1554
+ const probe = document.createElement("div");
1555
+ probe.style.height = "calc(297mm - 24mm)";
1556
+ frame.appendChild(probe);
1557
+ (document.querySelector("[data-formula-sheet]") || document.body).appendChild(frame);
1558
+ frame.appendChild(parts);
1559
+ const available = probe.getBoundingClientRect().height;
1560
+ probe.remove();
1561
+ let unfit;
1562
+ for (const part of parts.querySelectorAll(
1563
+ ":scope > section"
1564
+ )) {
1565
+ const table = part.querySelector("table");
1566
+ const body = table == null ? void 0 : table.tBodies[0];
1567
+ if (!table || !body) continue;
1568
+ const check = rowPartitioner(
1569
+ [...body.rows].map((row) => ({
1570
+ height: row.getBoundingClientRect().height,
1571
+ repeat: Boolean(row.querySelector("[data-comparison-banner]"))
1572
+ })),
1573
+ ((_a2 = table.tHead) == null ? void 0 : _a2.getBoundingClientRect().height) || 0,
1574
+ available
1575
+ );
1576
+ if (check.unfit) unfit = check.unfit;
1577
+ }
1578
+ frame.remove();
1579
+ return unfit;
1580
+ }
1581
+ }
1582
+
1081
1583
  // src/formula-sheet/print.ts
1082
1584
  var DEFAULT_FORMULA_SHEET_SELECTOR = "[data-formula-sheet]";
1083
1585
  var FORMULA_SHEET_PRINT_BODY_CLASS = "formula-sheet-printing";
@@ -1150,6 +1652,10 @@ var printFormulaSheet = (options = {}) => {
1150
1652
  }
1151
1653
  cleanupTimeout = browser.window.setTimeout(cleanup, PRINT_CLEANUP_DELAY_MS);
1152
1654
  try {
1655
+ renderComparisonParts(
1656
+ planComparisonParts(measureComparisons(target)),
1657
+ printClone
1658
+ );
1153
1659
  browser.window.print();
1154
1660
  } catch (error) {
1155
1661
  cleanup();
@@ -1189,37 +1695,39 @@ var printFormulaSheet = (options = {}) => {
1189
1695
 
1190
1696
  // src/PreparedFormulaSheet.tsx
1191
1697
  import {
1192
- PreparedDocumentSchema,
1193
- createSheetFromCalculationSourceObject
1698
+ createSheetFromCalculationSourceObject,
1699
+ getValueNodeByKey as getValueNodeByKey3,
1700
+ PreparedDocumentSchema
1194
1701
  } from "@cs-object/core";
1702
+ import { Fragment as Fragment5 } from "react";
1195
1703
 
1196
1704
  // src/EngineeringMetadata.tsx
1197
- import { Fragment as Fragment3, jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
1705
+ import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
1198
1706
  var ContextValue = ({
1199
1707
  value
1200
1708
  }) => {
1201
1709
  switch (value.kind) {
1202
1710
  case "text":
1203
- return /* @__PURE__ */ jsx23("span", { "data-engineering-value": value.path, children: String(value.value) });
1711
+ return /* @__PURE__ */ jsx24("span", { "data-engineering-value": value.path, children: String(value.value) });
1204
1712
  case "math":
1205
- return /* @__PURE__ */ jsx23(
1713
+ return /* @__PURE__ */ jsx24(
1206
1714
  "span",
1207
1715
  {
1208
1716
  "data-engineering-value": value.path,
1209
1717
  "data-engineering-notation": "math",
1210
1718
  "data-engineering-source": value.value,
1211
- children: /* @__PURE__ */ jsx23(GlyphMathBlock, { glyph: value.value })
1719
+ children: /* @__PURE__ */ jsx24(GlyphMathBlock, { glyph: value.value })
1212
1720
  }
1213
1721
  );
1214
1722
  case "list":
1215
- return /* @__PURE__ */ jsx23("ul", { children: value.items.map((item, index) => (
1723
+ return /* @__PURE__ */ jsx24("ul", { children: value.items.map((item, index) => (
1216
1724
  // biome-ignore lint/suspicious/noArrayIndexKey: prepared order identifies repeated entries
1217
- /* @__PURE__ */ jsx23("li", { children: /* @__PURE__ */ jsx23(ContextValue, { value: item }) }, index)
1725
+ /* @__PURE__ */ jsx24("li", { children: /* @__PURE__ */ jsx24(ContextValue, { value: item }) }, index)
1218
1726
  )) });
1219
1727
  case "record":
1220
- return /* @__PURE__ */ jsx23("dl", { children: value.entries.map((entry) => /* @__PURE__ */ jsxs13("div", { children: [
1221
- /* @__PURE__ */ jsx23("dt", { children: entry.label }),
1222
- /* @__PURE__ */ jsx23("dd", { children: /* @__PURE__ */ jsx23(ContextValue, { value: entry.value }) })
1728
+ return /* @__PURE__ */ jsx24("dl", { children: value.entries.map((entry) => /* @__PURE__ */ jsxs14("div", { children: [
1729
+ /* @__PURE__ */ jsx24("dt", { children: entry.label }),
1730
+ /* @__PURE__ */ jsx24("dd", { children: /* @__PURE__ */ jsx24(ContextValue, { value: entry.value }) })
1223
1731
  ] }, entry.label)) });
1224
1732
  default: {
1225
1733
  const exhaustive = value;
@@ -1230,19 +1738,70 @@ var ContextValue = ({
1230
1738
  var EngineeringMetadata = ({
1231
1739
  entries,
1232
1740
  subject
1233
- }) => entries.length > 0 ? /* @__PURE__ */ jsx23("dl", { className: "cso-engineering-context", children: entries.map(({ label, path, value }) => /* @__PURE__ */ jsxs13("div", { "data-engineering-field": path, children: [
1234
- /* @__PURE__ */ jsxs13("dt", { children: [
1235
- subject && /* @__PURE__ */ jsxs13(Fragment3, { children: [
1741
+ }) => entries.length > 0 ? /* @__PURE__ */ jsx24("dl", { className: "cso-engineering-context", children: entries.map(({ label, path, value }) => /* @__PURE__ */ jsxs14("div", { "data-engineering-field": path, children: [
1742
+ /* @__PURE__ */ jsxs14("dt", { children: [
1743
+ subject && /* @__PURE__ */ jsxs14(Fragment3, { children: [
1236
1744
  subject,
1237
1745
  ": "
1238
1746
  ] }),
1239
1747
  label
1240
1748
  ] }),
1241
- /* @__PURE__ */ jsx23("dd", { children: /* @__PURE__ */ jsx23(ContextValue, { value }) })
1749
+ /* @__PURE__ */ jsx24("dd", { children: /* @__PURE__ */ jsx24(ContextValue, { value }) })
1242
1750
  ] }, path)) }) : null;
1243
1751
 
1752
+ // src/mathml/InlineFormulaMath.tsx
1753
+ import { Fragment as Fragment4, jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
1754
+ var InlineFormulaMath = ({
1755
+ sheet,
1756
+ symbol,
1757
+ showGlyph = true
1758
+ }) => /* @__PURE__ */ jsx25(
1759
+ "math",
1760
+ __spreadProps(__spreadValues({}, defaultMathBlockProps), {
1761
+ display: "inline",
1762
+ style: __spreadProps(__spreadValues({}, defaultMathBlockProps.style), { display: void 0 }),
1763
+ children: /* @__PURE__ */ jsxs15("mrow", { children: [
1764
+ showGlyph ? /* @__PURE__ */ jsxs15(Fragment4, { children: [
1765
+ /* @__PURE__ */ jsx25(AsciiMathView, { expression: symbol.glyph }),
1766
+ /* @__PURE__ */ jsx25("mo", { children: "=" })
1767
+ ] }) : null,
1768
+ /* @__PURE__ */ jsx25(
1769
+ SymbolValueMathmlView,
1770
+ {
1771
+ sheet,
1772
+ valueTree: symbol.valueTree,
1773
+ noRootContainer: true,
1774
+ viewOptions: { literalsAsDrafts: true }
1775
+ }
1776
+ )
1777
+ ] })
1778
+ })
1779
+ );
1780
+
1781
+ // src/table-case-notation.ts
1782
+ import {
1783
+ compactGlyphScope
1784
+ } from "@cs-object/core";
1785
+ var tableCaseQualifier = (invocationId, symbols) => {
1786
+ var _a, _b;
1787
+ for (const symbol of symbols) {
1788
+ const owner = (_a = symbol.metadata) == null ? void 0 : _a.invocationId;
1789
+ const scope = (_b = symbol.metadata) == null ? void 0 : _b.glyphScope;
1790
+ if (typeof owner !== "string" || typeof scope !== "string") continue;
1791
+ if (owner !== invocationId && !owner.startsWith(`${invocationId}/`))
1792
+ continue;
1793
+ const nestedDepth = owner === invocationId ? 0 : owner.slice(invocationId.length + 1).split("/").length;
1794
+ const bindings = scope.split(",");
1795
+ if (bindings.length <= nestedDepth) continue;
1796
+ return compactGlyphScope(
1797
+ bindings.slice(0, bindings.length - nestedDepth).join(",")
1798
+ );
1799
+ }
1800
+ return void 0;
1801
+ };
1802
+
1244
1803
  // src/PreparedFormulaSheet.tsx
1245
- import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
1804
+ import { Fragment as Fragment6, jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
1246
1805
  var mathSheet = (document2) => createSheetFromCalculationSourceObject(
1247
1806
  {
1248
1807
  schemaVersion: "1.0.0",
@@ -1253,6 +1812,11 @@ var mathSheet = (document2) => createSheetFromCalculationSourceObject(
1253
1812
  id: section.id,
1254
1813
  title: section.title,
1255
1814
  items: section.items.flatMap((item) => {
1815
+ if (item.kind === "externalCall") {
1816
+ return [...item.call.inputs, ...item.call.outputs].map(
1817
+ (quantity) => ({ kind: "symbolRef", id: quantity.symbolId })
1818
+ );
1819
+ }
1256
1820
  if (item.kind === "section") {
1257
1821
  return [{ kind: "section", id: item.id }];
1258
1822
  }
@@ -1274,16 +1838,118 @@ var mathSheet = (document2) => createSheetFromCalculationSourceObject(
1274
1838
  ).sheet;
1275
1839
  var requiredItem = (items, id) => {
1276
1840
  const item = items.get(id);
1277
- if (!item) {
1841
+ if (item === void 0) {
1278
1842
  throw new Error(`Missing prepared item '${id}'`);
1279
1843
  }
1280
1844
  return item;
1281
1845
  };
1846
+ var notationSheet = (id, symbols) => {
1847
+ const sheet = createSheetFromCalculationSourceObject(
1848
+ {
1849
+ schemaVersion: "1.0.0",
1850
+ title: id,
1851
+ source: { id, metadata: {} },
1852
+ rootSectionIds: [id],
1853
+ sections: [
1854
+ {
1855
+ id,
1856
+ title: id,
1857
+ items: symbols.map((symbol) => ({ kind: "symbol", symbol }))
1858
+ }
1859
+ ],
1860
+ detachedItems: []
1861
+ },
1862
+ { id, label: id }
1863
+ ).sheet;
1864
+ const byId = new Map(sheet.symbols.map((symbol) => [symbol.id, symbol]));
1865
+ const forwarded = new Set(
1866
+ symbols.filter((symbol) => {
1867
+ var _a;
1868
+ return ((_a = symbol.metadata) == null ? void 0 : _a.csoForwardedReturn) === true;
1869
+ }).map((symbol) => symbol.id)
1870
+ );
1871
+ return {
1872
+ row: (symbolId, index, options = {}) => /* @__PURE__ */ jsx26(
1873
+ FormulaSheetSymbolRow,
1874
+ {
1875
+ sheet,
1876
+ item: requiredItem(byId, symbolId),
1877
+ sheetItemIndex: index,
1878
+ symbolicOnly: true,
1879
+ compactBinding: options.compactBinding || forwarded.has(symbolId),
1880
+ bindingOrigin: options.bindingOrigin
1881
+ }
1882
+ ),
1883
+ origin: (symbolId, label) => bindingOrigin({
1884
+ sheet,
1885
+ symbol: requiredItem(byId, symbolId),
1886
+ label,
1887
+ computedReference: true
1888
+ }),
1889
+ isConnection: (symbolId) => {
1890
+ const symbol = requiredItem(byId, symbolId);
1891
+ const root = getValueNodeByKey3(
1892
+ symbol.valueTree,
1893
+ symbol.valueTree.rootKey
1894
+ );
1895
+ return root.kind === "symbol" || root.kind === "literal";
1896
+ },
1897
+ description: (symbolId) => requiredItem(byId, symbolId).description,
1898
+ formula: (symbolId, showGlyph = true) => /* @__PURE__ */ jsx26(
1899
+ InlineFormulaMath,
1900
+ {
1901
+ sheet,
1902
+ symbol: requiredItem(byId, symbolId),
1903
+ showGlyph
1904
+ }
1905
+ )
1906
+ };
1907
+ };
1908
+ var readableName = (name) => name.replaceAll("_", " ").replace(/\b\w/u, (letter) => letter.toUpperCase());
1909
+ var SymbolicValueNote = () => /* @__PURE__ */ jsx26("p", { className: "cso-symbolic-note", children: "Reusable function for downstream use. Values are not defined yet." });
1910
+ var procedureAnchor = (id) => `cso-procedure-${id}`;
1911
+ var FunctionIdentity = ({
1912
+ identity
1913
+ }) => /* @__PURE__ */ jsxs16(
1914
+ "p",
1915
+ {
1916
+ className: "cso-function-identity",
1917
+ "data-function-identity": `${identity.moduleId}::${identity.function}`,
1918
+ children: [
1919
+ "Function:",
1920
+ " ",
1921
+ /* @__PURE__ */ jsxs16("code", { children: [
1922
+ identity.moduleId,
1923
+ "::",
1924
+ identity.function
1925
+ ] })
1926
+ ]
1927
+ }
1928
+ );
1929
+ var Procedure = ({
1930
+ title,
1931
+ children,
1932
+ heading: Heading,
1933
+ functionIdentity
1934
+ }) => /* @__PURE__ */ jsxs16("table", { className: "cso-procedure-table", children: [
1935
+ /* @__PURE__ */ jsx26("thead", { children: /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsxs16("th", { children: [
1936
+ /* @__PURE__ */ jsx26(Heading, { children: title }),
1937
+ /* @__PURE__ */ jsx26(FunctionIdentity, { identity: functionIdentity }),
1938
+ /* @__PURE__ */ jsx26(SymbolicValueNote, {})
1939
+ ] }) }) }),
1940
+ /* @__PURE__ */ jsx26("tbody", { children: children.map((child, index) => /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsx26("td", { children: child }) }, index)) })
1941
+ ] });
1282
1942
  var PreparedFormulaSheet = ({
1283
1943
  document: input,
1284
1944
  showSourceDetails = true
1285
1945
  }) => {
1946
+ var _a, _b, _c, _d;
1286
1947
  const document2 = PreparedDocumentSchema.parse(input);
1948
+ const procedures = new Map(
1949
+ document2.sections.flatMap(
1950
+ (section) => section.items.flatMap((item) => item.kind === "method" ? [item] : [])
1951
+ ).map((method, index) => [method.id, `P${index + 1}`])
1952
+ );
1287
1953
  const sheet = mathSheet(document2);
1288
1954
  const sections = new Map(
1289
1955
  document2.sections.map((section) => [section.id, section])
@@ -1292,158 +1958,1067 @@ var PreparedFormulaSheet = ({
1292
1958
  document2.assets.map((asset) => [asset.asset.id, asset])
1293
1959
  );
1294
1960
  const symbols = new Map(sheet.symbols.map((symbol) => [symbol.id, symbol]));
1961
+ const capturedSymbols = [
1962
+ ...document2.detachedSymbols,
1963
+ ...document2.sections.flatMap(
1964
+ (section) => section.items.flatMap(
1965
+ (item) => item.kind === "symbol" ? [item.symbol] : []
1966
+ )
1967
+ )
1968
+ ];
1295
1969
  let symbolIndex = 0;
1296
- const renderSection = (section) => /* @__PURE__ */ jsxs14(
1297
- "section",
1298
- {
1299
- "data-section-id": section.id,
1300
- className: "cso-section",
1301
- children: [
1302
- /* @__PURE__ */ jsx24(
1303
- "h2",
1970
+ const renderMethodContent = (content, helpers, notation, shown) => {
1971
+ const helperById = /* @__PURE__ */ new Map();
1972
+ const indexHelpers = (records) => {
1973
+ for (const helper of records) {
1974
+ helperById.set(helper.id, helper);
1975
+ indexHelpers(helper.helpers);
1976
+ }
1977
+ };
1978
+ indexHelpers(helpers);
1979
+ const origins = /* @__PURE__ */ new Map();
1980
+ const inputRows = (items) => items.flatMap(
1981
+ (item) => item.kind === "quantity" && item.role === "input" ? [item] : item.kind === "section" ? inputRows(item.content) : []
1982
+ );
1983
+ const collectOrigins = (items, path = [], active = /* @__PURE__ */ new Set()) => {
1984
+ var _a2;
1985
+ for (const item of items) {
1986
+ if (item.kind === "section") collectOrigins(item.content, path, active);
1987
+ if (item.kind !== "call") continue;
1988
+ const helper = requiredItem(helperById, item.helperId);
1989
+ if (active.has(helper.id))
1990
+ throw new Error(`Cyclic helper '${helper.id}'`);
1991
+ const callPath = [...path, item.binding];
1992
+ for (const input2 of item.inputs) {
1993
+ const quantity = inputRows(helper.content).find(
1994
+ (row) => row.selectionName === input2.name
1995
+ );
1996
+ if (!quantity)
1997
+ throw new Error(`Missing helper input '${input2.name}'`);
1998
+ const bindings = (_a2 = origins.get(quantity.symbolId)) != null ? _a2 : [];
1999
+ bindings.push({
2000
+ path: callPath.join(" / "),
2001
+ symbolId: input2.symbolId
2002
+ });
2003
+ origins.set(quantity.symbolId, bindings);
2004
+ }
2005
+ collectOrigins(
2006
+ helper.content,
2007
+ callPath,
2008
+ /* @__PURE__ */ new Set([...active, helper.id])
2009
+ );
2010
+ }
2011
+ };
2012
+ collectOrigins(content);
2013
+ const renderItems = (items) => items.map((item, index) => {
2014
+ var _a2, _b2, _c2;
2015
+ if (item.kind === "external") {
2016
+ return /* @__PURE__ */ jsx26(
2017
+ "section",
1304
2018
  {
1305
- "data-source-placement": section.sourcePlacementId,
1306
- className: "cso-section-heading",
1307
- children: section.title
1308
- }
1309
- ),
1310
- /* @__PURE__ */ jsx24(EngineeringMetadata, { entries: section.context }),
1311
- section.items.map((item) => {
1312
- switch (item.kind) {
1313
- case "section": {
1314
- const child = requiredItem(sections, item.id);
1315
- return /* @__PURE__ */ jsxs14(
1316
- "div",
1317
- {
1318
- "data-source-placement": item.sourcePlacementId,
1319
- children: [
1320
- /* @__PURE__ */ jsx24(EngineeringMetadata, { entries: item.context }),
1321
- renderSection(child)
1322
- ]
1323
- },
1324
- item.sourcePlacementId
1325
- );
1326
- }
1327
- case "text": {
1328
- return /* @__PURE__ */ jsxs14(
1329
- "div",
2019
+ className: "cso-method-external cso-external-call",
2020
+ "data-method-external": item.binding,
2021
+ children: /* @__PURE__ */ jsxs16("table", { children: [
2022
+ /* @__PURE__ */ jsx26("thead", { children: /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsxs16("th", { colSpan: 2, children: [
2023
+ /* @__PURE__ */ jsx26("h4", { children: readableName(item.binding) }),
2024
+ /* @__PURE__ */ jsx26(SymbolicValueNote, {}),
2025
+ /* @__PURE__ */ jsxs16("p", { children: [
2026
+ "External source: ",
2027
+ item.adapter.moduleId,
2028
+ ",",
2029
+ " ",
2030
+ item.adapter.function
2031
+ ] }),
2032
+ /* @__PURE__ */ jsx26("p", { children: "CSO does not check the formulas inside this external calculation." })
2033
+ ] }) }) }),
2034
+ /* @__PURE__ */ jsxs16("tbody", { className: "cso-external-quantities", children: [
2035
+ /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsx26("th", { colSpan: 2, children: "Inputs" }) }),
2036
+ item.inputs.map((input2) => /* @__PURE__ */ jsx26(
2037
+ "tr",
2038
+ {
2039
+ "data-external-method-input": input2.name,
2040
+ children: /* @__PURE__ */ jsx26("td", { colSpan: 2, className: "cso-external-quantity-cell", children: notation.row(input2.symbolId, symbolIndex++, {
2041
+ compactBinding: true
2042
+ }) })
2043
+ },
2044
+ input2.name
2045
+ ))
2046
+ ] }),
2047
+ /* @__PURE__ */ jsxs16("tbody", { children: [
2048
+ /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsx26("th", { colSpan: 2, children: "Calculation procedure" }) }),
2049
+ item.declaration.interface.description.split(/\n\s*\n/u).map((paragraph, paragraphIndex) => /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsx26("td", { colSpan: 2, children: paragraph }) }, `paragraph-${paragraphIndex}`))
2050
+ ] }),
2051
+ /* @__PURE__ */ jsxs16("tbody", { className: "cso-external-quantities", children: [
2052
+ /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsx26("th", { colSpan: 2, children: "Outputs" }) }),
2053
+ item.outputs.map((output) => /* @__PURE__ */ jsx26(
2054
+ "tr",
2055
+ {
2056
+ "data-external-method-output": output.name,
2057
+ children: /* @__PURE__ */ jsx26("td", { colSpan: 2, className: "cso-external-quantity-cell", children: notation.row(output.symbolId, symbolIndex++) })
2058
+ },
2059
+ output.name
2060
+ ))
2061
+ ] })
2062
+ ] })
2063
+ },
2064
+ `external-${item.binding}`
2065
+ );
2066
+ }
2067
+ if (item.kind === "boolean") {
2068
+ return /* @__PURE__ */ jsxs16(
2069
+ "p",
2070
+ {
2071
+ className: "cso-branch-note",
2072
+ "data-boolean": item.localId,
2073
+ "data-formula": item.predicateText,
2074
+ children: [
2075
+ item.description.replace(/[.!?:]$/u, ""),
2076
+ ":",
2077
+ " ",
2078
+ item.predicateSymbolId ? notation.formula(item.predicateSymbolId, false) : item.predicateText
2079
+ ]
2080
+ },
2081
+ `boolean-${item.localId}-${index}`
2082
+ );
2083
+ }
2084
+ if (item.kind === "check" || item.kind === "applicability") {
2085
+ return /* @__PURE__ */ jsxs16(
2086
+ "p",
2087
+ {
2088
+ className: "cso-branch-note",
2089
+ "data-check": item.kind === "check" ? item.localId : void 0,
2090
+ "data-applicability": item.kind === "applicability" ? item.localId : void 0,
2091
+ "data-formula": item.predicateText,
2092
+ children: [
2093
+ item.explanation.replace(/[.!?:]$/u, ""),
2094
+ ":",
2095
+ " ",
2096
+ notation.formula(item.predicateSymbolId, false)
2097
+ ]
2098
+ },
2099
+ `${item.kind}-${item.localId}-${index}`
2100
+ );
2101
+ }
2102
+ if (item.kind === "quantity") {
2103
+ return /* @__PURE__ */ jsx26(
2104
+ "div",
2105
+ {
2106
+ className: "cso-method-quantity",
2107
+ "data-quantity": item.selectionName,
2108
+ "data-formula": item.formulaText || void 0,
2109
+ children: notation.row(item.symbolId, symbolIndex++, {
2110
+ bindingOrigin: (_a2 = origins.get(item.symbolId)) == null ? void 0 : _a2.map((origin) => /* @__PURE__ */ jsx26("div", { children: notation.origin(
2111
+ origin.symbolId,
2112
+ readableName(origin.path)
2113
+ ) }, origin.path))
2114
+ })
2115
+ },
2116
+ `quantity-${item.selectionName}-${index}`
2117
+ );
2118
+ }
2119
+ if (item.kind === "text") {
2120
+ return /* @__PURE__ */ jsx26(
2121
+ "p",
2122
+ {
2123
+ className: "cso-method-text",
2124
+ "data-method-text": item.localId,
2125
+ children: item.content
2126
+ },
2127
+ `text-${item.localId}`
2128
+ );
2129
+ }
2130
+ if (item.kind === "figure") {
2131
+ const asset = assets.get(item.assetId);
2132
+ if (!asset) {
2133
+ throw new Error(`Missing method asset '${item.assetId}'`);
2134
+ }
2135
+ return /* @__PURE__ */ jsxs16(
2136
+ "figure",
2137
+ {
2138
+ className: "cso-figure",
2139
+ "data-method-figure": item.localId,
2140
+ children: [
2141
+ /* @__PURE__ */ jsx26("img", { src: asset.dataUrl, alt: item.alt }),
2142
+ item.caption ? /* @__PURE__ */ jsx26("figcaption", { children: item.caption }) : null
2143
+ ]
2144
+ },
2145
+ `figure-${item.localId}`
2146
+ );
2147
+ }
2148
+ if (item.kind === "section") {
2149
+ return /* @__PURE__ */ jsxs16(
2150
+ "section",
2151
+ {
2152
+ className: "cso-method-section",
2153
+ "data-method-section": item.localId,
2154
+ children: [
2155
+ /* @__PURE__ */ jsx26("h4", { children: item.title }),
2156
+ /* @__PURE__ */ jsx26(EngineeringMetadata, { entries: (_b2 = item.context) != null ? _b2 : [] }),
2157
+ renderItems(item.content)
2158
+ ]
2159
+ },
2160
+ `section-${item.localId}`
2161
+ );
2162
+ }
2163
+ const helper = helperById.get(item.helperId);
2164
+ let explanation = null;
2165
+ if (helper && !shown.has(helper.id)) {
2166
+ shown.add(helper.id);
2167
+ explanation = /* @__PURE__ */ jsx26("div", { className: "cso-method-helper", "data-helper": helper.function, children: /* @__PURE__ */ jsx26(
2168
+ Procedure,
2169
+ {
2170
+ title: readableName(helper.function),
2171
+ heading: "h4",
2172
+ functionIdentity: helper.functionIdentity,
2173
+ children: [
2174
+ /* @__PURE__ */ jsx26(
2175
+ EngineeringMetadata,
1330
2176
  {
1331
- "data-source-placement": item.sourcePlacementId,
1332
- className: "cso-text",
1333
- children: [
1334
- item.text.content,
1335
- /* @__PURE__ */ jsx24(EngineeringMetadata, { entries: item.context })
1336
- ]
2177
+ entries: (_c2 = helper.context) != null ? _c2 : []
1337
2178
  },
1338
- item.sourcePlacementId
1339
- );
1340
- }
1341
- case "figure": {
1342
- const asset = requiredItem(assets, item.figure.assetId);
1343
- return /* @__PURE__ */ jsxs14(
1344
- "figure",
1345
- {
1346
- "data-source-placement": item.sourcePlacementId,
1347
- "data-asset-sha256": asset.asset.sha256,
1348
- className: "cso-figure",
1349
- children: [
1350
- /* @__PURE__ */ jsx24(
1351
- "img",
1352
- {
1353
- src: asset.dataUrl,
1354
- alt: item.figure.alt,
1355
- style: item.figure.width === void 0 ? void 0 : { width: item.figure.width }
1356
- }
1357
- ),
1358
- item.figure.caption && /* @__PURE__ */ jsx24("figcaption", { children: item.figure.caption }),
1359
- /* @__PURE__ */ jsx24(EngineeringMetadata, { entries: item.context })
1360
- ]
1361
- },
1362
- item.sourcePlacementId
1363
- );
2179
+ "context"
2180
+ ),
2181
+ ...renderItems(helper.content)
2182
+ ]
2183
+ }
2184
+ ) });
2185
+ }
2186
+ const calculations = item.inputs.filter(
2187
+ (input2) => !notation.isConnection(input2.symbolId)
2188
+ );
2189
+ return /* @__PURE__ */ jsxs16(
2190
+ "div",
2191
+ {
2192
+ className: explanation || calculations.length ? "cso-method-call" : void 0,
2193
+ "data-call": item.binding,
2194
+ children: [
2195
+ explanation,
2196
+ calculations.length ? /* @__PURE__ */ jsx26("div", { className: "cso-formula-terms", children: calculations.map((input2) => /* @__PURE__ */ jsx26(
2197
+ "span",
2198
+ {
2199
+ "data-formula": input2.formulaText,
2200
+ className: "cso-formula-term",
2201
+ children: notation.formula(input2.symbolId)
2202
+ },
2203
+ input2.name
2204
+ )) }) : null
2205
+ ]
2206
+ },
2207
+ `call-${item.binding}`
2208
+ );
2209
+ });
2210
+ return renderItems(content);
2211
+ };
2212
+ const renderSection = (section) => {
2213
+ var _a2;
2214
+ return /* @__PURE__ */ jsxs16(
2215
+ "section",
2216
+ {
2217
+ "data-section-id": section.id,
2218
+ className: "cso-section",
2219
+ children: [
2220
+ /* @__PURE__ */ jsx26(
2221
+ "h2",
2222
+ {
2223
+ "data-source-placement": section.sourcePlacementId,
2224
+ className: "cso-section-heading",
2225
+ children: section.title
1364
2226
  }
1365
- case "symbol":
1366
- case "symbolRef": {
1367
- const symbolId = item.kind === "symbol" ? item.symbol.id : item.id;
1368
- const symbol = requiredItem(symbols, symbolId);
1369
- const index = symbolIndex++;
1370
- return /* @__PURE__ */ jsxs14(
1371
- "div",
1372
- {
1373
- "data-source-placement": item.sourcePlacementId,
1374
- "data-symbol-id": symbolId,
1375
- className: "cso-symbol-placement",
1376
- children: [
1377
- /* @__PURE__ */ jsx24(EngineeringMetadata, { entries: item.context }),
1378
- item.operands.map(({ symbolId: id, context }) => /* @__PURE__ */ jsx24(
1379
- EngineeringMetadata,
1380
- {
1381
- entries: context,
1382
- subject: /* @__PURE__ */ jsxs14(Fragment4, { children: [
1383
- "Operand",
1384
- " ",
1385
- /* @__PURE__ */ jsx24(
1386
- GlyphMathBlock,
2227
+ ),
2228
+ /* @__PURE__ */ jsx26(EngineeringMetadata, { entries: section.context }),
2229
+ (_a2 = section.engineeringChecks) == null ? void 0 : _a2.map((check) => /* @__PURE__ */ jsx26(
2230
+ "p",
2231
+ {
2232
+ className: "cso-branch-note",
2233
+ "data-check": check.id,
2234
+ "data-check-result": check.reasons ? "not-applicable" : check.value ? "pass" : "fail",
2235
+ "data-formula": check.predicateText,
2236
+ children: check.reasons ? `Not applicable. ${check.reasons.join(" ")}` : `${check.value ? "Pass" : "Fail"}. ${check.explanation} ${check.predicateText}`
2237
+ },
2238
+ check.id
2239
+ )),
2240
+ section.items.map((item) => {
2241
+ var _a3, _b2, _c2, _d2, _e;
2242
+ switch (item.kind) {
2243
+ case "externalCall": {
2244
+ const outputLabel = (name) => {
2245
+ const output = item.call.outputs.find(
2246
+ (quantity) => quantity.name === name
2247
+ );
2248
+ return output ? requiredItem(symbols, output.symbolId).description : name;
2249
+ };
2250
+ const quantityRow = (quantity, role, index) => {
2251
+ var _a4;
2252
+ const symbol = requiredItem(symbols, quantity.symbolId);
2253
+ const qualification = (_a4 = item.qualifications) == null ? void 0 : _a4.find(
2254
+ (note) => note.symbolId === quantity.symbolId
2255
+ );
2256
+ return /* @__PURE__ */ jsx26(
2257
+ "tr",
2258
+ {
2259
+ "data-external-quantity": quantity.name,
2260
+ "data-external-role": role,
2261
+ "data-external-index": index,
2262
+ "data-symbol-id": quantity.symbolId,
2263
+ children: /* @__PURE__ */ jsxs16("td", { colSpan: 2, className: "cso-external-quantity-cell", children: [
2264
+ qualification ? /* @__PURE__ */ jsxs16(
2265
+ "p",
2266
+ {
2267
+ className: "cso-branch-note",
2268
+ "data-applicability": "not-applicable",
2269
+ children: [
2270
+ "Not applicable. ",
2271
+ qualification.reasons.join(" ")
2272
+ ]
2273
+ }
2274
+ ) : null,
2275
+ /* @__PURE__ */ jsx26(
2276
+ FormulaSheetSymbolRow,
2277
+ {
2278
+ sheet,
2279
+ item: symbol,
2280
+ sheetItemIndex: symbolIndex++,
2281
+ showFormula: false,
2282
+ numericKind: quantity.numericKind
2283
+ }
2284
+ )
2285
+ ] })
2286
+ },
2287
+ `${role}-${quantity.name}`
2288
+ );
2289
+ };
2290
+ return /* @__PURE__ */ jsxs16(
2291
+ "section",
2292
+ {
2293
+ "data-source-placement": item.sourcePlacementId,
2294
+ "data-external-call": item.call.id,
2295
+ className: "cso-external-call",
2296
+ children: [
2297
+ /* @__PURE__ */ jsxs16("table", { children: [
2298
+ /* @__PURE__ */ jsx26("thead", { children: /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsxs16("th", { colSpan: 2, children: [
2299
+ /* @__PURE__ */ jsx26("h3", { children: readableName(item.title) }),
2300
+ /* @__PURE__ */ jsxs16("p", { children: [
2301
+ "External source: ",
2302
+ item.call.adapter.moduleId,
2303
+ ",",
2304
+ " ",
2305
+ item.call.adapter.function
2306
+ ] }),
2307
+ /* @__PURE__ */ jsx26("p", { children: "CSO does not check the formulas inside this external calculation." })
2308
+ ] }) }) }),
2309
+ /* @__PURE__ */ jsxs16("tbody", { className: "cso-external-quantities", children: [
2310
+ /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsx26("th", { colSpan: 2, children: "Inputs" }) }),
2311
+ item.call.inputs.map(
2312
+ (quantity, index) => quantityRow(quantity, "input", index)
2313
+ )
2314
+ ] }),
2315
+ /* @__PURE__ */ jsxs16("tbody", { children: [
2316
+ /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsx26("th", { colSpan: 2, children: "Calculation procedure" }) }),
2317
+ item.call.description.split(/\n\s*\n/u).map((paragraph, index) => /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsx26("td", { colSpan: 2, children: paragraph }) }, `method-${index}`))
2318
+ ] }),
2319
+ /* @__PURE__ */ jsxs16("tbody", { className: "cso-external-quantities", children: [
2320
+ /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsx26("th", { colSpan: 2, children: "Outputs" }) }),
2321
+ item.call.outputs.map(
2322
+ (quantity, index) => quantityRow(quantity, "output", index)
2323
+ ),
2324
+ item.call.warnings.map((warning, index) => /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsx26("td", { colSpan: 2, children: warning }) }, `warning-${index}`)),
2325
+ ((_a3 = document2.verification) == null ? void 0 : _a3.externalReferenceCoverage) ? /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsxs16(
2326
+ "td",
1387
2327
  {
1388
- glyph: requiredItem(symbols, id).glyph
2328
+ colSpan: 2,
2329
+ className: "cso-external-reference-coverage",
2330
+ children: [
2331
+ /* @__PURE__ */ jsxs16("p", { children: [
2332
+ "Independent check coverage:",
2333
+ " ",
2334
+ document2.verification.externalReferenceCoverage.status,
2335
+ "."
2336
+ ] }),
2337
+ /* @__PURE__ */ jsxs16("p", { children: [
2338
+ "Independently checked:",
2339
+ " ",
2340
+ document2.verification.externalReferenceCoverage.checked.filter(
2341
+ (slot) => slot.externalCallId === item.call.id
2342
+ ).map((slot) => outputLabel(slot.outputName)).join(", ") || "None",
2343
+ "."
2344
+ ] }),
2345
+ /* @__PURE__ */ jsxs16("p", { children: [
2346
+ "Without an independent check:",
2347
+ " ",
2348
+ document2.verification.externalReferenceCoverage.uncovered.filter(
2349
+ (slot) => slot.externalCallId === item.call.id
2350
+ ).map((slot) => outputLabel(slot.outputName)).join(", ") || "None",
2351
+ "."
2352
+ ] })
2353
+ ]
1389
2354
  }
1390
- )
2355
+ ) }) : null
1391
2356
  ] })
1392
- },
1393
- id
1394
- )),
1395
- /* @__PURE__ */ jsx24(
1396
- FormulaSheetSymbolRow,
2357
+ ] }),
2358
+ /* @__PURE__ */ jsx26(EngineeringMetadata, { entries: item.context })
2359
+ ]
2360
+ },
2361
+ item.sourcePlacementId
2362
+ );
2363
+ }
2364
+ case "section": {
2365
+ const child = requiredItem(sections, item.id);
2366
+ return /* @__PURE__ */ jsxs16(
2367
+ "div",
2368
+ {
2369
+ "data-source-placement": item.sourcePlacementId,
2370
+ children: [
2371
+ /* @__PURE__ */ jsx26(EngineeringMetadata, { entries: item.context }),
2372
+ renderSection(child)
2373
+ ]
2374
+ },
2375
+ item.sourcePlacementId
2376
+ );
2377
+ }
2378
+ case "text": {
2379
+ return /* @__PURE__ */ jsxs16(
2380
+ "div",
2381
+ {
2382
+ "data-source-placement": item.sourcePlacementId,
2383
+ className: "cso-text",
2384
+ children: [
2385
+ item.text.content,
2386
+ /* @__PURE__ */ jsx26(EngineeringMetadata, { entries: item.context })
2387
+ ]
2388
+ },
2389
+ item.sourcePlacementId
2390
+ );
2391
+ }
2392
+ case "figure": {
2393
+ const asset = requiredItem(assets, item.figure.assetId);
2394
+ return /* @__PURE__ */ jsxs16(
2395
+ "figure",
2396
+ {
2397
+ "data-source-placement": item.sourcePlacementId,
2398
+ "data-asset-sha256": asset.asset.sha256,
2399
+ className: "cso-figure",
2400
+ children: [
2401
+ /* @__PURE__ */ jsx26(
2402
+ "img",
2403
+ {
2404
+ src: asset.dataUrl,
2405
+ alt: item.figure.alt,
2406
+ style: item.figure.width === void 0 ? void 0 : { width: item.figure.width }
2407
+ }
2408
+ ),
2409
+ item.figure.caption && /* @__PURE__ */ jsx26("figcaption", { children: item.figure.caption }),
2410
+ /* @__PURE__ */ jsx26(EngineeringMetadata, { entries: item.context })
2411
+ ]
2412
+ },
2413
+ item.sourcePlacementId
2414
+ );
2415
+ }
2416
+ case "method": {
2417
+ return /* @__PURE__ */ jsx26(
2418
+ "section",
2419
+ {
2420
+ "data-source-placement": item.sourcePlacementId,
2421
+ "data-method-id": item.id,
2422
+ id: procedureAnchor(requiredItem(procedures, item.id)),
2423
+ className: "cso-method",
2424
+ children: /* @__PURE__ */ jsx26(
2425
+ Procedure,
1397
2426
  {
1398
- sheet,
1399
- item: symbol,
1400
- sheetItemIndex: index
2427
+ title: `Procedure ${requiredItem(procedures, item.id)}: ${item.title}`,
2428
+ heading: "h3",
2429
+ functionIdentity: item.functionIdentity,
2430
+ children: [
2431
+ /* @__PURE__ */ jsx26(
2432
+ EngineeringMetadata,
2433
+ {
2434
+ entries: item.context
2435
+ },
2436
+ "context"
2437
+ ),
2438
+ ...renderMethodContent(
2439
+ item.content,
2440
+ item.helpers,
2441
+ notationSheet(item.id, item.symbols),
2442
+ /* @__PURE__ */ new Set()
2443
+ )
2444
+ ]
1401
2445
  }
1402
2446
  )
1403
- ]
1404
- },
1405
- item.sourcePlacementId
1406
- );
1407
- }
1408
- default: {
1409
- const exhaustive = item;
1410
- return exhaustive;
2447
+ },
2448
+ item.sourcePlacementId
2449
+ );
2450
+ }
2451
+ case "table": {
2452
+ const caseHeading = (caseItem) => {
2453
+ const qualifier = tableCaseQualifier(
2454
+ caseItem.invocationId,
2455
+ capturedSymbols
2456
+ );
2457
+ return /* @__PURE__ */ jsxs16(Fragment6, { children: [
2458
+ caseItem.heading,
2459
+ qualifier ? /* @__PURE__ */ jsxs16(
2460
+ "span",
2461
+ {
2462
+ className: "cso-comparison-case-qualifier",
2463
+ "data-case-qualifier": qualifier,
2464
+ children: [
2465
+ "Subscript: ",
2466
+ /* @__PURE__ */ jsx26(GlyphMathBlock, { glyph: qualifier })
2467
+ ]
2468
+ }
2469
+ ) : null
2470
+ ] });
2471
+ };
2472
+ const outcomeRows = (_b2 = item.outcomeRows) != null ? _b2 : [];
2473
+ const rowIndices = /* @__PURE__ */ new Map();
2474
+ for (const group of item.groups)
2475
+ for (const row of group.rows)
2476
+ rowIndices.set(`${group.role}:${row.quantity}`, symbolIndex++);
2477
+ for (const row of outcomeRows)
2478
+ rowIndices.set(row.id, symbolIndex++);
2479
+ const quantityHeading = (quantity) => /* @__PURE__ */ jsxs16("span", { className: "cso-comparison-quantity", children: [
2480
+ /* @__PURE__ */ jsxs16("span", { className: "cso-comparison-description", children: [
2481
+ /* @__PURE__ */ jsx26(
2482
+ FormulaSheetItemIndex,
2483
+ {
2484
+ index: requiredItem(
2485
+ rowIndices,
2486
+ `${quantity.role}:${quantity.quantity}`
2487
+ )
2488
+ }
2489
+ ),
2490
+ " ",
2491
+ quantity.description
2492
+ ] }),
2493
+ /* @__PURE__ */ jsxs16("span", { className: "cso-comparison-notation", children: [
2494
+ /* @__PURE__ */ jsx26(GlyphMathBlock, { glyph: quantity.glyph }),
2495
+ quantity.unit ? /* @__PURE__ */ jsx26("span", { className: "cso-comparison-unit", children: /* @__PURE__ */ jsx26(UnitMathBlock, { unit: quantity.unit }) }) : null
2496
+ ] })
2497
+ ] });
2498
+ const shownCell = (cell) => cell.applicability ? /* @__PURE__ */ jsxs16("span", { children: [
2499
+ /* @__PURE__ */ jsx26(
2500
+ NumericalValue,
2501
+ {
2502
+ value: cell.value,
2503
+ numericKind: cell.numericKind
2504
+ }
2505
+ ),
2506
+ /* @__PURE__ */ jsx26(
2507
+ "span",
2508
+ {
2509
+ className: "cso-result-status",
2510
+ title: cell.applicability.reasons.join(" "),
2511
+ children: "Not applicable"
2512
+ }
2513
+ )
2514
+ ] }) : /* @__PURE__ */ jsx26(
2515
+ NumericalValue,
2516
+ {
2517
+ value: cell.value,
2518
+ numericKind: cell.numericKind
2519
+ }
2520
+ );
2521
+ const notation = item.symbols ? notationSheet(item.id, item.symbols) : void 0;
2522
+ const outcomeHeading = (row) => {
2523
+ var _a4, _b3;
2524
+ const predicate = (_b3 = row.predicateSymbolId) != null ? _b3 : row.kind === "branch" ? (_a4 = row.cells.flatMap((cell) => cell.results)[0]) == null ? void 0 : _a4.conditionSymbolId : void 0;
2525
+ return /* @__PURE__ */ jsxs16("span", { className: "cso-comparison-description", children: [
2526
+ /* @__PURE__ */ jsx26(
2527
+ FormulaSheetItemIndex,
2528
+ {
2529
+ index: requiredItem(rowIndices, row.id)
2530
+ }
2531
+ ),
2532
+ " ",
2533
+ row.kind === "branch" ? `Rule used for ${row.label.toLowerCase()}` : row.label,
2534
+ predicate ? /* @__PURE__ */ jsx26("span", { className: "cso-result-status", children: notation == null ? void 0 : notation.formula(predicate, false) }) : null
2535
+ ] });
2536
+ };
2537
+ const outcomeCell = (row, heading) => {
2538
+ var _a4, _b3, _c3, _d3;
2539
+ if (row.kind === "branch") {
2540
+ const results2 = (_b3 = (_a4 = row.cells.find((cell) => cell.heading === heading)) == null ? void 0 : _a4.results) != null ? _b3 : [];
2541
+ return results2.length ? results2.map((result) => /* @__PURE__ */ jsxs16(
2542
+ "div",
2543
+ {
2544
+ "data-branch-note": heading,
2545
+ "data-case": heading,
2546
+ "data-symbol-id": result.symbolId,
2547
+ "data-node-key": result.nodeKey,
2548
+ "data-formula": result.value,
2549
+ children: [
2550
+ result.callPath ? /* @__PURE__ */ jsx26("span", { className: "cso-result-status", children: readableName(result.callPath) }) : null,
2551
+ notation == null ? void 0 : notation.formula(result.branchSymbolId, false),
2552
+ /* @__PURE__ */ jsx26("span", { className: "cso-result-status", children: result.conditionHolds ? "Condition holds" : "Otherwise" })
2553
+ ]
2554
+ },
2555
+ `${result.invocationId}:${result.nodeKey}`
2556
+ )) : "Not evaluated";
2557
+ }
2558
+ const results = (_d3 = (_c3 = row.cells.find((cell) => cell.heading === heading)) == null ? void 0 : _c3.results) != null ? _d3 : [];
2559
+ return results.length ? results.map((result) => {
2560
+ var _a5, _b4, _c4, _d4;
2561
+ const qualified = Boolean((_a5 = result.reasons) == null ? void 0 : _a5.length);
2562
+ const label = row.kind === "boolean" ? result.value ? "True" : "False" : qualified ? "Not applicable" : row.kind === "check" ? result.value ? "Pass" : "Fail" : result.value ? "Applicable" : "Not applicable";
2563
+ return /* @__PURE__ */ jsxs16(
2564
+ "div",
2565
+ {
2566
+ "data-case": heading,
2567
+ "data-invocation-id": result.invocationId,
2568
+ "data-boolean": row.kind === "boolean" ? row.id : void 0,
2569
+ "data-value": result.value,
2570
+ "data-check": row.kind === "check" ? (_b4 = row.localId) != null ? _b4 : row.id : void 0,
2571
+ "data-check-result": row.kind === "check" ? qualified ? "not-applicable" : result.value ? "pass" : "fail" : void 0,
2572
+ "data-applicability": row.kind === "applicability" ? (_c4 = row.localId) != null ? _c4 : row.id : void 0,
2573
+ "data-applicability-result": row.kind === "applicability" ? qualified || !result.value ? "not-applicable" : "applicable" : void 0,
2574
+ children: [
2575
+ result.callPath ? /* @__PURE__ */ jsx26("span", { className: "cso-result-status", children: readableName(result.callPath) }) : null,
2576
+ /* @__PURE__ */ jsx26("strong", { children: label }),
2577
+ ((_d4 = result.reasons) == null ? void 0 : _d4.length) ? /* @__PURE__ */ jsx26("span", { className: "cso-result-status", children: result.reasons.filter((reason) => reason !== row.label).map((reason) => {
2578
+ const limit = outcomeRows.find(
2579
+ (candidate) => candidate.kind === "applicability" && candidate.label === reason
2580
+ );
2581
+ return limit ? `See limit ${requiredItem(rowIndices, limit.id)}.` : reason;
2582
+ }).join(" ") }) : null
2583
+ ]
2584
+ },
2585
+ result.invocationId
2586
+ );
2587
+ }) : "Not evaluated";
2588
+ };
2589
+ const quantityColumn = /* @__PURE__ */ new Map();
2590
+ for (const group of item.groups) {
2591
+ for (const row of group.rows) {
2592
+ quantityColumn.set(
2593
+ `${group.role}:${row.quantity}`,
2594
+ quantityColumn.size
2595
+ );
2596
+ }
2597
+ }
2598
+ const groupColumns = (group) => group.rows.map(
2599
+ (row) => quantityColumn.get(`${group.role}:${row.quantity}`)
2600
+ ).join(",");
2601
+ return /* @__PURE__ */ jsxs16(
2602
+ "div",
2603
+ {
2604
+ "data-source-placement": item.sourcePlacementId,
2605
+ "data-comparison-id": item.id,
2606
+ "data-cases-axis": item.casesAxis,
2607
+ "data-column-cap": item.columnCap,
2608
+ className: "cso-comparison",
2609
+ children: [
2610
+ /* @__PURE__ */ jsx26("h3", { children: item.title }),
2611
+ /* @__PURE__ */ jsxs16(
2612
+ "p",
2613
+ {
2614
+ className: "cso-function-identity",
2615
+ "data-method-reference": item.methodId,
2616
+ "data-function-identity": `${item.functionIdentity.moduleId}::${item.functionIdentity.function}`,
2617
+ children: [
2618
+ /* @__PURE__ */ jsxs16(
2619
+ "a",
2620
+ {
2621
+ href: `#${procedureAnchor(requiredItem(procedures, item.methodId))}`,
2622
+ children: [
2623
+ "Uses procedure ",
2624
+ requiredItem(procedures, item.methodId)
2625
+ ]
2626
+ }
2627
+ ),
2628
+ ": ",
2629
+ /* @__PURE__ */ jsxs16("code", { children: [
2630
+ item.functionIdentity.moduleId,
2631
+ "::",
2632
+ item.functionIdentity.function
2633
+ ] })
2634
+ ]
2635
+ }
2636
+ ),
2637
+ !item.outcomeRows && ((_c2 = item.engineeringChecks) == null ? void 0 : _c2.map(
2638
+ (check) => check.results.map((result) => /* @__PURE__ */ jsxs16(
2639
+ "p",
2640
+ {
2641
+ className: "cso-branch-note",
2642
+ "data-check": check.id,
2643
+ "data-check-result": result.reasons ? "not-applicable" : result.value ? "pass" : "fail",
2644
+ "data-case": result.heading,
2645
+ "data-formula": check.predicateText,
2646
+ children: [
2647
+ result.heading,
2648
+ result.callPath ? ` / ${result.callPath}` : "",
2649
+ ":",
2650
+ " ",
2651
+ result.reasons ? `Not applicable. ${result.reasons.join(" ")}` : `${result.value ? "Pass" : "Fail"}. ${check.explanation}`
2652
+ ]
2653
+ },
2654
+ `${check.id}-${result.invocationId}`
2655
+ ))
2656
+ )),
2657
+ !item.outcomeRows && ((_d2 = item.applicabilityNotes) == null ? void 0 : _d2.map(
2658
+ (condition) => condition.results.map((result) => /* @__PURE__ */ jsxs16(
2659
+ "p",
2660
+ {
2661
+ className: "cso-branch-note",
2662
+ "data-applicability": condition.id,
2663
+ "data-applicability-result": result.value ? "applicable" : "not-applicable",
2664
+ "data-case": result.heading,
2665
+ "data-formula": condition.predicateText,
2666
+ children: [
2667
+ result.heading,
2668
+ result.callPath ? ` / ${result.callPath}` : "",
2669
+ ":",
2670
+ " ",
2671
+ result.reasons ? `Not applicable. ${result.reasons.join(" ")}` : condition.explanation
2672
+ ]
2673
+ },
2674
+ `${condition.id}-${result.invocationId}`
2675
+ ))
2676
+ )),
2677
+ !item.outcomeRows && ((_e = item.branchNotes) == null ? void 0 : _e.map((note) => /* @__PURE__ */ jsxs16(
2678
+ "p",
2679
+ {
2680
+ className: "cso-branch-note",
2681
+ "data-branch-note": note.heading,
2682
+ "data-case": note.heading,
2683
+ "data-symbol-id": note.symbolId,
2684
+ "data-node-key": note.nodeKey,
2685
+ "data-formula": note.label,
2686
+ children: [
2687
+ note.heading,
2688
+ note.callPath ? ` / ${note.callPath}` : "",
2689
+ ":",
2690
+ " ",
2691
+ notation == null ? void 0 : notation.description(note.branchSymbolId),
2692
+ " ",
2693
+ notation == null ? void 0 : notation.formula(note.branchSymbolId),
2694
+ ", because",
2695
+ " ",
2696
+ notation == null ? void 0 : notation.formula(note.conditionSymbolId, false),
2697
+ " ",
2698
+ note.conditionHolds ? "holds" : "does not hold",
2699
+ "."
2700
+ ]
2701
+ },
2702
+ `${note.invocationId}-${note.symbolId}-${note.nodeKey}`
2703
+ ))),
2704
+ item.emptyState ? /* @__PURE__ */ jsx26("p", { className: "cso-comparison-empty", children: item.emptyState }) : null,
2705
+ item.casesAxis === "rows" ? /* @__PURE__ */ jsx26(
2706
+ "div",
2707
+ {
2708
+ className: "cso-comparison-scroll",
2709
+ "data-comparison-scroll": "",
2710
+ children: /* @__PURE__ */ jsxs16("table", { "data-comparison-table": "screen", children: [
2711
+ /* @__PURE__ */ jsxs16("thead", { children: [
2712
+ /* @__PURE__ */ jsxs16("tr", { children: [
2713
+ /* @__PURE__ */ jsx26("th", { scope: "col", "data-comparison-label": "", children: "Case" }),
2714
+ item.groups.map((group) => /* @__PURE__ */ jsx26(
2715
+ "th",
2716
+ {
2717
+ scope: "colgroup",
2718
+ colSpan: group.rows.length,
2719
+ "data-comparison-columns": groupColumns(group),
2720
+ children: group.label
2721
+ },
2722
+ group.role
2723
+ )),
2724
+ outcomeRows.length ? /* @__PURE__ */ jsx26(
2725
+ "th",
2726
+ {
2727
+ scope: "colgroup",
2728
+ colSpan: outcomeRows.length,
2729
+ "data-comparison-columns": outcomeRows.map((_, index) => quantityColumn.size + index).join(","),
2730
+ children: "Checks and conditions"
2731
+ }
2732
+ ) : null
2733
+ ] }),
2734
+ /* @__PURE__ */ jsxs16("tr", { children: [
2735
+ /* @__PURE__ */ jsx26("th", { scope: "col", "data-comparison-label": "", children: "Quantity" }),
2736
+ item.groups.flatMap(
2737
+ (group) => group.rows.map((row) => /* @__PURE__ */ jsx26(
2738
+ "th",
2739
+ {
2740
+ scope: "col",
2741
+ "data-quantity": row.quantity,
2742
+ "data-comparison-column": quantityColumn.get(
2743
+ `${group.role}:${row.quantity}`
2744
+ ),
2745
+ children: quantityHeading(row)
2746
+ },
2747
+ `${group.role}-${row.quantity}`
2748
+ ))
2749
+ ),
2750
+ outcomeRows.map((row, index) => /* @__PURE__ */ jsx26(
2751
+ "th",
2752
+ {
2753
+ scope: "col",
2754
+ "data-outcome-kind": row.kind,
2755
+ "data-comparison-column": quantityColumn.size + index,
2756
+ children: outcomeHeading(row)
2757
+ },
2758
+ row.id
2759
+ ))
2760
+ ] })
2761
+ ] }),
2762
+ /* @__PURE__ */ jsx26("tbody", { children: item.cases.map((caseItem) => /* @__PURE__ */ jsxs16("tr", { children: [
2763
+ /* @__PURE__ */ jsx26(
2764
+ "th",
2765
+ {
2766
+ scope: "row",
2767
+ "data-comparison-label": "",
2768
+ "data-case-heading": caseItem.heading,
2769
+ children: caseHeading(caseItem)
2770
+ }
2771
+ ),
2772
+ item.groups.flatMap(
2773
+ (group) => group.rows.map((row) => {
2774
+ const cell = row.cells.find(
2775
+ (candidate) => candidate.invocationId === caseItem.invocationId
2776
+ );
2777
+ if (!cell) {
2778
+ throw new Error(
2779
+ `Missing ${row.quantity} for ${caseItem.heading}`
2780
+ );
2781
+ }
2782
+ return /* @__PURE__ */ jsx26(
2783
+ "td",
2784
+ {
2785
+ "data-quantity": row.quantity,
2786
+ "data-case": caseItem.heading,
2787
+ "data-symbol-id": cell.symbolId,
2788
+ "data-value": cell.value,
2789
+ "data-comparison-column": quantityColumn.get(
2790
+ `${group.role}:${row.quantity}`
2791
+ ),
2792
+ "data-applicability": cell.applicability ? "not-applicable" : void 0,
2793
+ children: shownCell(cell)
2794
+ },
2795
+ `${caseItem.invocationId}-${row.quantity}`
2796
+ );
2797
+ })
2798
+ ),
2799
+ outcomeRows.map((row, index) => /* @__PURE__ */ jsx26(
2800
+ "td",
2801
+ {
2802
+ "data-outcome-kind": row.kind,
2803
+ "data-comparison-column": quantityColumn.size + index,
2804
+ children: outcomeCell(row, caseItem.heading)
2805
+ },
2806
+ row.id
2807
+ ))
2808
+ ] }, caseItem.invocationId)) })
2809
+ ] })
2810
+ }
2811
+ ) : /* @__PURE__ */ jsx26(
2812
+ "div",
2813
+ {
2814
+ className: "cso-comparison-scroll",
2815
+ "data-comparison-scroll": "",
2816
+ children: /* @__PURE__ */ jsxs16("table", { "data-comparison-table": "screen", children: [
2817
+ /* @__PURE__ */ jsx26("thead", { children: /* @__PURE__ */ jsxs16("tr", { children: [
2818
+ /* @__PURE__ */ jsx26("th", { scope: "col", "data-comparison-label": "", children: "Quantity" }),
2819
+ item.cases.map((caseItem, index) => /* @__PURE__ */ jsx26(
2820
+ "th",
2821
+ {
2822
+ scope: "col",
2823
+ "data-case-heading": caseItem.heading,
2824
+ "data-comparison-column": index,
2825
+ children: caseHeading(caseItem)
2826
+ },
2827
+ caseItem.invocationId
2828
+ ))
2829
+ ] }) }),
2830
+ /* @__PURE__ */ jsxs16("tbody", { children: [
2831
+ item.groups.map((group) => /* @__PURE__ */ jsxs16(Fragment5, { children: [
2832
+ /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsx26(
2833
+ "th",
2834
+ {
2835
+ scope: "colgroup",
2836
+ colSpan: item.cases.length + 1,
2837
+ "data-comparison-banner": "",
2838
+ children: group.label
2839
+ }
2840
+ ) }),
2841
+ group.rows.map((row) => /* @__PURE__ */ jsxs16("tr", { children: [
2842
+ /* @__PURE__ */ jsx26(
2843
+ "th",
2844
+ {
2845
+ scope: "row",
2846
+ "data-quantity": row.quantity,
2847
+ "data-comparison-label": "",
2848
+ children: quantityHeading(row)
2849
+ }
2850
+ ),
2851
+ row.cells.map((cell, index) => /* @__PURE__ */ jsx26(
2852
+ "td",
2853
+ {
2854
+ "data-quantity": row.quantity,
2855
+ "data-case": cell.heading,
2856
+ "data-symbol-id": cell.symbolId,
2857
+ "data-value": cell.value,
2858
+ "data-comparison-column": index,
2859
+ "data-applicability": cell.applicability ? "not-applicable" : void 0,
2860
+ children: shownCell(cell)
2861
+ },
2862
+ cell.invocationId
2863
+ ))
2864
+ ] }, `${group.role}-${row.quantity}`))
2865
+ ] }, group.role)),
2866
+ outcomeRows.length ? /* @__PURE__ */ jsx26("tr", { children: /* @__PURE__ */ jsx26(
2867
+ "th",
2868
+ {
2869
+ scope: "colgroup",
2870
+ colSpan: item.cases.length + 1,
2871
+ "data-comparison-banner": "",
2872
+ children: "Checks and conditions"
2873
+ }
2874
+ ) }) : null,
2875
+ outcomeRows.map((row) => /* @__PURE__ */ jsxs16("tr", { children: [
2876
+ /* @__PURE__ */ jsx26(
2877
+ "th",
2878
+ {
2879
+ scope: "row",
2880
+ "data-comparison-label": "",
2881
+ "data-outcome-kind": row.kind,
2882
+ children: outcomeHeading(row)
2883
+ }
2884
+ ),
2885
+ item.cases.map((caseItem, index) => /* @__PURE__ */ jsx26(
2886
+ "td",
2887
+ {
2888
+ "data-outcome-kind": row.kind,
2889
+ "data-comparison-column": index,
2890
+ children: outcomeCell(row, caseItem.heading)
2891
+ },
2892
+ caseItem.invocationId
2893
+ ))
2894
+ ] }, row.id))
2895
+ ] })
2896
+ ] })
2897
+ }
2898
+ ),
2899
+ /* @__PURE__ */ jsx26(EngineeringMetadata, { entries: item.context })
2900
+ ]
2901
+ },
2902
+ item.sourcePlacementId
2903
+ );
2904
+ }
2905
+ case "symbol":
2906
+ case "symbolRef": {
2907
+ const symbolId = item.kind === "symbol" ? item.symbol.id : item.id;
2908
+ const symbol = requiredItem(symbols, symbolId);
2909
+ const index = symbolIndex++;
2910
+ return /* @__PURE__ */ jsxs16(
2911
+ "div",
2912
+ {
2913
+ "data-source-placement": item.sourcePlacementId,
2914
+ "data-symbol-id": symbolId,
2915
+ className: "cso-symbol-placement",
2916
+ children: [
2917
+ /* @__PURE__ */ jsx26(EngineeringMetadata, { entries: item.context }),
2918
+ "applicability" in item && item.applicability ? /* @__PURE__ */ jsxs16(
2919
+ "p",
2920
+ {
2921
+ className: "cso-branch-note",
2922
+ "data-applicability": "not-applicable",
2923
+ "data-symbol-id": symbolId,
2924
+ children: [
2925
+ "Not applicable. ",
2926
+ item.applicability.reasons.join(" ")
2927
+ ]
2928
+ }
2929
+ ) : null,
2930
+ item.operands.map(({ symbolId: id, context }) => /* @__PURE__ */ jsx26(
2931
+ EngineeringMetadata,
2932
+ {
2933
+ entries: context,
2934
+ subject: /* @__PURE__ */ jsxs16(Fragment6, { children: [
2935
+ "Operand",
2936
+ " ",
2937
+ /* @__PURE__ */ jsx26(
2938
+ GlyphMathBlock,
2939
+ {
2940
+ glyph: requiredItem(symbols, id).glyph
2941
+ }
2942
+ )
2943
+ ] })
2944
+ },
2945
+ id
2946
+ )),
2947
+ /* @__PURE__ */ jsx26(
2948
+ FormulaSheetSymbolRow,
2949
+ {
2950
+ sheet,
2951
+ item: symbol,
2952
+ sheetItemIndex: index
2953
+ }
2954
+ )
2955
+ ]
2956
+ },
2957
+ item.sourcePlacementId
2958
+ );
2959
+ }
2960
+ default: {
2961
+ const exhaustive = item;
2962
+ return exhaustive;
2963
+ }
1411
2964
  }
1412
- }
1413
- })
1414
- ]
1415
- },
1416
- section.id
1417
- );
1418
- return /* @__PURE__ */ jsxs14(
2965
+ })
2966
+ ]
2967
+ },
2968
+ section.id
2969
+ );
2970
+ };
2971
+ return /* @__PURE__ */ jsxs16(
1419
2972
  "article",
1420
2973
  {
1421
2974
  "data-formula-sheet": "true",
1422
2975
  "data-prepared-document": "true",
1423
2976
  className: "cso-document",
1424
2977
  children: [
1425
- /* @__PURE__ */ jsxs14("header", { className: "cso-document-header", children: [
1426
- /* @__PURE__ */ jsx24("h1", { children: document2.title }),
1427
- showSourceDetails && /* @__PURE__ */ jsx24("p", { children: document2.source.kind === "legacy" ? "Development preservation rendering. Numerical agreement has not been verified." : "Execution-bound document. Numerical verification is reported separately." }),
1428
- showSourceDetails && document2.source.kind === "execution" && /* @__PURE__ */ jsxs14("p", { children: [
1429
- "Function ",
1430
- document2.source.function,
1431
- ". Inputs",
1432
- " ",
1433
- Object.entries(document2.source.resolvedInputs).map(
1434
- ([key, value]) => `${key} = ${Object.is(value, -0) ? "-0" : value}`
1435
- ).join(", "),
1436
- "."
1437
- ] })
2978
+ /* @__PURE__ */ jsxs16("header", { className: "cso-document-header", children: [
2979
+ /* @__PURE__ */ jsx26("h1", { children: document2.title }),
2980
+ showSourceDetails && document2.source.kind === "legacy" ? /* @__PURE__ */ jsx26("p", { children: "Preview only. Numerical agreement has not been verified." }) : null
1438
2981
  ] }),
1439
- /* @__PURE__ */ jsx24(EngineeringMetadata, { entries: document2.context }),
2982
+ /* @__PURE__ */ jsx26(EngineeringMetadata, { entries: document2.context }),
1440
2983
  document2.rootSectionIds.map((id) => {
1441
2984
  const section = sections.get(id);
1442
2985
  if (!section) {
1443
2986
  throw new Error(`Missing prepared root '${id}'`);
1444
2987
  }
1445
2988
  return renderSection(section);
1446
- })
2989
+ }),
2990
+ /* @__PURE__ */ jsxs16("footer", { className: "cso-evidence-note", children: [
2991
+ !document2.verification && document2.source.kind === "execution" ? /* @__PURE__ */ jsx26("p", { children: "Numerical verification is reported separately." }) : null,
2992
+ showSourceDetails && document2.source.kind === "execution" ? /* @__PURE__ */ jsxs16("p", { children: [
2993
+ "Source calculation: ",
2994
+ readableName(document2.source.function),
2995
+ ".",
2996
+ Object.keys(document2.source.resolvedInputs).length ? /* @__PURE__ */ jsxs16(Fragment6, { children: [
2997
+ " ",
2998
+ "Supplied values:",
2999
+ " ",
3000
+ Object.entries(document2.source.resolvedInputs).map(
3001
+ ([key, value]) => `${readableName(key)} = ${Object.is(value, -0) ? "-0" : value}`
3002
+ ).join(", "),
3003
+ "."
3004
+ ] }) : null
3005
+ ] }) : null,
3006
+ ((_a = document2.verification) == null ? void 0 : _a.externalCoverage) ? /* @__PURE__ */ jsxs16("p", { children: [
3007
+ "External-result consistency:",
3008
+ " ",
3009
+ (_b = document2.verification.checks.externalResultConsistency) == null ? void 0 : _b.status,
3010
+ ". Formula checks:",
3011
+ " ",
3012
+ (_d = (_c = document2.verification.checks.formulaConsistency.counts) == null ? void 0 : _c.checked) != null ? _d : 0,
3013
+ ". Captured external calls:",
3014
+ " ",
3015
+ document2.verification.externalCoverage.calls,
3016
+ ". External results:",
3017
+ " ",
3018
+ document2.verification.externalCoverage.results,
3019
+ "."
3020
+ ] }) : null
3021
+ ] })
1447
3022
  ]
1448
3023
  }
1449
3024
  );
@@ -1451,18 +3026,24 @@ var PreparedFormulaSheet = ({
1451
3026
 
1452
3027
  // src/prepare-document.ts
1453
3028
  import {
1454
- executionBindingFrom,
1455
3029
  AssetRecordSchema,
1456
3030
  BoundPreparedDocumentSchema,
1457
3031
  CalculationSourceObjectSchema,
3032
+ contractIssuesToDiagnostics,
3033
+ deriveApplicability,
1458
3034
  ExecutionPayloadSchema,
3035
+ executionBindingFrom,
3036
+ executionBindingKey,
3037
+ VerificationReportSchema,
3038
+ methodInvocationBindings,
3039
+ tableOutcomeRows,
1459
3040
  HistoricalReviewSchema as HistoricalReviewSchema2,
1460
3041
  LegacyAssetManifestSchema,
1461
3042
  PreparedDocumentItemSchema,
1462
3043
  PreparedDocumentSchema as PreparedDocumentSchema2,
3044
+ functionIdentityFrom,
1463
3045
  PreparedDocumentSectionSchema,
1464
- ResolvedAssetSchema,
1465
- contractIssuesToDiagnostics
3046
+ ResolvedAssetSchema
1466
3047
  } from "@cs-object/core";
1467
3048
 
1468
3049
  // src/active-symbols.ts
@@ -1492,6 +3073,281 @@ var activeSymbolIds = (initialIds, definitionsById) => {
1492
3073
  return reachableSymbolIds;
1493
3074
  };
1494
3075
 
3076
+ // src/method-notation.ts
3077
+ import {
3078
+ scopedGlyph
3079
+ } from "@cs-object/core";
3080
+ var notationId = (...parts) => JSON.stringify(parts);
3081
+ var emptyTree = {
3082
+ rootKey: "value",
3083
+ nodes: [{ key: "value", mode: "LITERAL", literal: { kind: "empty" } }]
3084
+ };
3085
+ var reachableNodes = (nodes, rootKey) => {
3086
+ const byKey = new Map(nodes.map((node) => [node.key, node]));
3087
+ const seen = /* @__PURE__ */ new Set();
3088
+ const visit = (key) => {
3089
+ var _a, _b;
3090
+ if (seen.has(key)) return;
3091
+ seen.add(key);
3092
+ for (const argument of (_b = (_a = byKey.get(key)) == null ? void 0 : _a.funcArgs) != null ? _b : []) visit(argument.key);
3093
+ };
3094
+ visit(rootKey);
3095
+ return nodes.filter((node) => seen.has(node.key));
3096
+ };
3097
+ var calls = (content) => content.flatMap(
3098
+ (item) => item.kind === "call" || item.kind === "external" ? [item] : item.kind === "section" ? calls(item.content) : []
3099
+ );
3100
+ var isInput = (quantity) => {
3101
+ var _a;
3102
+ return quantity.nodes.length === 0 || ((_a = quantity.nodes[0]) == null ? void 0 : _a.mode) === "GIVEN_PARAMETER";
3103
+ };
3104
+ var methodNotation = (method, fail2) => {
3105
+ var _c, _d, _e, _f, _g, _h;
3106
+ const symbols = /* @__PURE__ */ new Map();
3107
+ const helpers = /* @__PURE__ */ new Map();
3108
+ const indexHelpers = (records) => {
3109
+ for (const helper of records) {
3110
+ helpers.set(helper.id, helper);
3111
+ indexHelpers(helper.helpers);
3112
+ }
3113
+ };
3114
+ indexHelpers(method.helpers);
3115
+ const add = (symbol) => {
3116
+ symbols.set(symbol.id, __spreadProps(__spreadValues({}, symbol), { notationScope: symbol.id }));
3117
+ return symbol.id;
3118
+ };
3119
+ const quantitySymbolId = (owner, variableName) => notationId(owner.id, variableName);
3120
+ const callHelper = (owner, binding) => {
3121
+ var _a;
3122
+ const call = calls(owner.content).find((item) => item.binding === binding);
3123
+ return (_a = helpers.get((call == null ? void 0 : call.kind) === "call" ? call.helperId : "")) != null ? _a : fail2(`Call '${binding}' has no helper in '${owner.id}'`);
3124
+ };
3125
+ const outputSymbolId = (owner, binding, output) => {
3126
+ var _a, _b, _c2, _d2;
3127
+ const id = notationId(owner.id, binding, "output", output);
3128
+ if (symbols.has(id)) return id;
3129
+ const external = calls(owner.content).find(
3130
+ (item) => item.kind === "external" && item.binding === binding
3131
+ );
3132
+ if ((external == null ? void 0 : external.kind) === "external") {
3133
+ const declared = (_b = (_a = external.declaration.interface.outputs.find(
3134
+ (item) => item[0] === output
3135
+ )) == null ? void 0 : _a[2]) != null ? _b : fail2(`Call '${binding}' has no external output '${output}'`);
3136
+ return add({
3137
+ id,
3138
+ glyph: scopedGlyph(declared.glyph, binding),
3139
+ description: declared.description,
3140
+ unit: declared.unit,
3141
+ comment: (_c2 = declared.comment) != null ? _c2 : "",
3142
+ valueTree: emptyTree
3143
+ });
3144
+ }
3145
+ const quantity = (_d2 = callHelper(owner, binding).quantities.find(
3146
+ (candidate) => candidate.role === "output" && candidate.selectionName === output
3147
+ )) != null ? _d2 : fail2(`Call '${binding}' has no output '${output}'`);
3148
+ return add(__spreadProps(__spreadValues({
3149
+ id,
3150
+ glyph: scopedGlyph(quantity.glyph, binding),
3151
+ description: quantity.description
3152
+ }, quantity.unit ? { unit: quantity.unit } : {}), {
3153
+ valueTree: emptyTree
3154
+ }));
3155
+ };
3156
+ const referencedId = (owner, node) => {
3157
+ var _a, _b, _c2, _d2, _e2, _f2;
3158
+ if (node.mode === "GIVEN_PARAMETER") {
3159
+ const quantity = (_a = owner.quantities.find(
3160
+ (candidate) => {
3161
+ var _a2;
3162
+ return ((_a2 = candidate.nodes[0]) == null ? void 0 : _a2.mode) === "GIVEN_PARAMETER" && candidate.nodes[0].parameter === node.parameter;
3163
+ }
3164
+ )) != null ? _a : fail2(`Given parameter '${node.parameter}' has no quantity`);
3165
+ return quantitySymbolId(owner, quantity.variableName);
3166
+ }
3167
+ if (((_b = node.ref) == null ? void 0 : _b.kind) === "output") {
3168
+ return outputSymbolId(owner, (_c2 = node.ref.call) != null ? _c2 : "", (_d2 = node.ref.output) != null ? _d2 : "");
3169
+ }
3170
+ const name = (_f2 = (_e2 = node.ref) == null ? void 0 : _e2.name) != null ? _f2 : "";
3171
+ if (!owner.quantities.some((quantity) => quantity.variableName === name)) {
3172
+ fail2(`Formula name '${name}' has no quantity in '${owner.id}'`);
3173
+ }
3174
+ return quantitySymbolId(owner, name);
3175
+ };
3176
+ const tree = (owner, nodes, rootKey = ((_b) => (_b = ((_a) => (_a = nodes[0]) == null ? void 0 : _a.key)()) != null ? _b : fail2("Empty formula"))()) => ({
3177
+ rootKey,
3178
+ nodes: reachableNodes(nodes, rootKey).map(
3179
+ (node) => {
3180
+ var _a2, _b2, _c2;
3181
+ const draft = node.draft === void 0 ? {} : { draft: node.draft };
3182
+ if (node.mode === "LITERAL") {
3183
+ const literal = (_a2 = node.literal) != null ? _a2 : fail2(`Literal '${node.key}' has no value`);
3184
+ return __spreadProps(__spreadValues({
3185
+ key: node.key,
3186
+ mode: "LITERAL"
3187
+ }, draft), {
3188
+ literal: {
3189
+ kind: "number",
3190
+ value: literal.value,
3191
+ numericKind: literal.numericKind
3192
+ }
3193
+ });
3194
+ }
3195
+ if (node.mode === "FUNCTION") {
3196
+ return __spreadProps(__spreadValues({
3197
+ key: node.key,
3198
+ mode: "FUNCTION"
3199
+ }, draft), {
3200
+ funcSpec: (_b2 = node.funcSpec) != null ? _b2 : fail2(`'${node.key}' has no function`),
3201
+ funcArgs: (_c2 = node.funcArgs) != null ? _c2 : []
3202
+ });
3203
+ }
3204
+ return __spreadProps(__spreadValues({
3205
+ key: node.key,
3206
+ mode: "SYMBOL"
3207
+ }, draft), {
3208
+ symbol: { id: referencedId(owner, node) }
3209
+ });
3210
+ }
3211
+ )
3212
+ });
3213
+ const ownerQuantity = (owner, variableName) => {
3214
+ var _a;
3215
+ return (_a = owner.quantities.find(
3216
+ (quantity) => quantity.variableName === variableName
3217
+ )) != null ? _a : fail2(`Quantity '${variableName}' is missing from '${owner.id}'`);
3218
+ };
3219
+ const symbolFor = (id, quantity, valueTree, glyph = quantity.glyph) => __spreadValues(__spreadProps(__spreadValues({
3220
+ id,
3221
+ glyph,
3222
+ description: quantity.description
3223
+ }, quantity.unit ? { unit: quantity.unit } : {}), {
3224
+ valueTree
3225
+ }), quantity.variableName.startsWith("__cso_return_") && quantity.role === "output" ? { metadata: { csoForwardedReturn: true } } : {});
3226
+ const owners = [method, ...helpers.values()];
3227
+ for (const owner of owners) {
3228
+ for (const quantity of owner.quantities) {
3229
+ add(
3230
+ symbolFor(
3231
+ quantitySymbolId(owner, quantity.variableName),
3232
+ quantity,
3233
+ isInput(quantity) ? emptyTree : tree(owner, quantity.nodes)
3234
+ )
3235
+ );
3236
+ }
3237
+ }
3238
+ for (const owner of owners) {
3239
+ for (const call of calls(owner.content)) {
3240
+ if (call.kind === "external") {
3241
+ for (const [name, , declared] of call.declaration.interface.inputs) {
3242
+ const supplied = call.inputs.find((input) => input.name === name);
3243
+ const fallback = call.declaration.interface.defaults.find(
3244
+ (input) => input.name === name
3245
+ );
3246
+ const valueTree = supplied ? tree(owner, supplied.nodes) : fallback ? {
3247
+ rootKey: "value",
3248
+ nodes: [
3249
+ {
3250
+ key: "value",
3251
+ mode: "LITERAL",
3252
+ literal: {
3253
+ kind: "number",
3254
+ value: fallback.value,
3255
+ numericKind: fallback.numericKind
3256
+ }
3257
+ }
3258
+ ]
3259
+ } : emptyTree;
3260
+ add({
3261
+ id: notationId(owner.id, call.binding, "input", name),
3262
+ glyph: scopedGlyph(declared.glyph, call.binding),
3263
+ description: declared.description,
3264
+ unit: declared.unit,
3265
+ comment: (_c = declared.comment) != null ? _c : "",
3266
+ valueTree
3267
+ });
3268
+ }
3269
+ for (const name of call.outputs)
3270
+ outputSymbolId(owner, call.binding, name);
3271
+ continue;
3272
+ }
3273
+ const helper = callHelper(owner, call.binding);
3274
+ for (const input of call.inputs) {
3275
+ const parameter = ownerQuantity(helper, input.name);
3276
+ add(
3277
+ symbolFor(
3278
+ notationId(owner.id, call.binding, "input", input.name),
3279
+ parameter,
3280
+ tree(owner, input.nodes),
3281
+ scopedGlyph(parameter.glyph, call.binding)
3282
+ )
3283
+ );
3284
+ }
3285
+ }
3286
+ for (const declaration of (_d = owner.booleans) != null ? _d : []) {
3287
+ if (declaration.expression.kind !== "predicate") continue;
3288
+ add({
3289
+ id: notationId(owner.id, "boolean", declaration.id),
3290
+ glyph: "b_{condition}",
3291
+ description: declaration.description,
3292
+ valueTree: tree(owner, declaration.expression.nodes)
3293
+ });
3294
+ }
3295
+ for (const condition of [
3296
+ ...((_e = owner.checks) != null ? _e : []).map((condition2) => __spreadProps(__spreadValues({}, condition2), {
3297
+ kind: "check"
3298
+ })),
3299
+ ...((_f = owner.applicability) != null ? _f : []).map((condition2) => __spreadProps(__spreadValues({}, condition2), {
3300
+ kind: "applicability"
3301
+ }))
3302
+ ]) {
3303
+ const targetName = (_g = condition.targets[0]) != null ? _g : "";
3304
+ const target = (_h = owner.quantities.find(
3305
+ (quantity) => quantity.variableName === targetName || quantity.selectionName === targetName
3306
+ )) != null ? _h : fail2(`Condition '${condition.id}' has no target quantity`);
3307
+ add(
3308
+ symbolFor(
3309
+ notationId(owner.id, condition.kind, condition.id),
3310
+ target,
3311
+ tree(owner, condition.nodes)
3312
+ )
3313
+ );
3314
+ }
3315
+ }
3316
+ return {
3317
+ quantityId: (owner, variableName) => quantitySymbolId(owner, variableName),
3318
+ callInputId: (owner, binding, name) => notationId(owner.id, binding, "input", name),
3319
+ callOutputId: (owner, binding, name) => outputSymbolId(owner, binding, name),
3320
+ conditionId: (owner, kind, id) => notationId(owner.id, kind, id),
3321
+ /** The branch a conditional chose and the test that chose it. */
3322
+ branch: (owner, variableName, nodeKey, chosenKey) => {
3323
+ var _a, _b;
3324
+ const quantity = ownerQuantity(owner, variableName);
3325
+ const conditional = (_a = quantity.nodes.find((node) => node.key === nodeKey)) != null ? _a : fail2(`Conditional '${nodeKey}' is missing from '${variableName}'`);
3326
+ const test = (_b = conditional.funcArgs) == null ? void 0 : _b[0];
3327
+ if (!test) fail2(`Conditional '${nodeKey}' is incomplete`);
3328
+ const base = quantitySymbolId(owner, variableName);
3329
+ return {
3330
+ quantitySymbolId: base,
3331
+ branchSymbolId: add(
3332
+ symbolFor(
3333
+ notationId(owner.id, variableName, nodeKey, "branch", chosenKey),
3334
+ quantity,
3335
+ tree(owner, quantity.nodes, chosenKey)
3336
+ )
3337
+ ),
3338
+ conditionSymbolId: add(
3339
+ symbolFor(
3340
+ notationId(owner.id, variableName, nodeKey, "condition"),
3341
+ quantity,
3342
+ tree(owner, quantity.nodes, test.key)
3343
+ )
3344
+ )
3345
+ };
3346
+ },
3347
+ symbols: () => [...symbols.values()]
3348
+ };
3349
+ };
3350
+
1495
3351
  // src/prepare-context.ts
1496
3352
  import {
1497
3353
  HistoricalReviewSchema
@@ -1580,7 +3436,30 @@ var engineeringFields = (value, path) => {
1580
3436
  return label && selected ? [{ label, value: selected, path: sourcePath }] : [];
1581
3437
  });
1582
3438
  };
1583
- var prepareDocumentContext = (document2) => {
3439
+ var placementContext = (source, path) => ["metadata", "contentMetadata", "additionalFields"].flatMap(
3440
+ (key) => engineeringFields(source == null ? void 0 : source[key], `${path}/${key}`)
3441
+ );
3442
+ var methodContentContext = (content, path) => content.map(
3443
+ (item, index) => item.kind !== "section" ? item : __spreadProps(__spreadValues({}, item), {
3444
+ context: placementContext(
3445
+ item.contextSource,
3446
+ `${path}/${index}/contextSource`
3447
+ ),
3448
+ content: methodContentContext(
3449
+ item.content,
3450
+ `${path}/${index}/content`
3451
+ )
3452
+ })
3453
+ );
3454
+ var methodHelperContext = (helpers, path) => helpers.map((helper, index) => __spreadProps(__spreadValues({}, helper), {
3455
+ context: placementContext(
3456
+ helper.contextSource,
3457
+ `${path}/${index}/contextSource`
3458
+ ),
3459
+ content: methodContentContext(helper.content, `${path}/${index}/content`),
3460
+ helpers: methodHelperContext(helper.helpers, `${path}/${index}/helpers`)
3461
+ }));
3462
+ var prepareDocumentContext = (document2, explained = /* @__PURE__ */ new Set()) => {
1584
3463
  const definitions = new Map([
1585
3464
  ...document2.sections.flatMap(
1586
3465
  (section, sectionIndex) => section.items.flatMap(
@@ -1602,7 +3481,9 @@ var prepareDocumentContext = (document2) => {
1602
3481
  const placed = new Set(
1603
3482
  document2.sections.flatMap(
1604
3483
  (section) => section.items.flatMap(
1605
- (item) => item.kind === "symbol" ? [item.symbol.id] : item.kind === "symbolRef" ? [item.id] : []
3484
+ (item) => item.kind === "symbol" ? [item.symbol.id] : item.kind === "externalCall" ? [...item.call.inputs, ...item.call.outputs].map(
3485
+ (quantity) => quantity.symbolId
3486
+ ) : item.kind === "symbolRef" ? [item.id] : []
1606
3487
  )
1607
3488
  )
1608
3489
  );
@@ -1645,23 +3526,22 @@ var prepareDocumentContext = (document2) => {
1645
3526
  ),
1646
3527
  items: section.items.map((item, itemIndex) => {
1647
3528
  const path = `/sections/${sectionIndex}/items/${itemIndex}/contextSource`;
1648
- const context = [
1649
- "metadata",
1650
- "contentMetadata",
1651
- "additionalFields"
1652
- ].flatMap(
1653
- (key) => {
1654
- var _a;
1655
- return engineeringFields((_a = item.contextSource) == null ? void 0 : _a[key], `${path}/${key}`);
1656
- }
1657
- );
3529
+ const context = placementContext(item.contextSource, path);
3530
+ if (item.kind === "method") {
3531
+ const itemPath = `/sections/${sectionIndex}/items/${itemIndex}`;
3532
+ return __spreadProps(__spreadValues({}, item), {
3533
+ context,
3534
+ content: methodContentContext(item.content, `${itemPath}/content`),
3535
+ helpers: methodHelperContext(item.helpers, `${itemPath}/helpers`)
3536
+ });
3537
+ }
1658
3538
  if (item.kind !== "symbol" && item.kind !== "symbolRef") {
1659
3539
  return __spreadProps(__spreadValues({}, item), { context });
1660
3540
  }
1661
3541
  const id = item.kind === "symbol" ? item.symbol.id : item.id;
1662
3542
  return __spreadProps(__spreadValues({}, item), {
1663
3543
  context: [...symbolContext(id), ...context],
1664
- operands: [...activeSymbolIds([id], symbols)].filter((id2) => !placed.has(id2)).map(operandContext)
3544
+ operands: [...activeSymbolIds([id], symbols)].filter((id2) => !placed.has(id2) && !explained.has(id2)).map(operandContext)
1665
3545
  });
1666
3546
  })
1667
3547
  }))
@@ -1967,9 +3847,481 @@ var resolveExecutionPlacementProvenance = (execution, item) => {
1967
3847
  location: (_i = (_h = metadata == null ? void 0 : metadata.location) != null ? _h : targetCallSite) != null ? _i : definitionLocation
1968
3848
  };
1969
3849
  };
3850
+ var applicabilityField = (reasons) => reasons && reasons.length > 0 ? {
3851
+ applicability: {
3852
+ state: "not-applicable",
3853
+ reasons: [...reasons]
3854
+ }
3855
+ } : {};
3856
+ var sectionChecks = (execution, invocationId, derived) => {
3857
+ var _a;
3858
+ if (typeof invocationId !== "string") return {};
3859
+ const plans = ((_a = execution.methods) != null ? _a : []).flatMap(function walk(plan) {
3860
+ return [plan, ...plan.helpers.flatMap(walk)];
3861
+ });
3862
+ const engineeringChecks = plans.flatMap(
3863
+ (plan) => {
3864
+ var _a2;
3865
+ return ((_a2 = plan.checks) != null ? _a2 : []).flatMap((check) => {
3866
+ var _a3;
3867
+ const outcome = ((_a3 = execution.checkOutcomes) != null ? _a3 : []).find(
3868
+ (item) => item.methodId === plan.id && item.invocationId === invocationId && item.checkId === check.id
3869
+ );
3870
+ return outcome ? [
3871
+ __spreadValues({
3872
+ id: check.id,
3873
+ explanation: check.explanation,
3874
+ predicateText: check.predicateText,
3875
+ value: outcome.value
3876
+ }, (() => {
3877
+ const reasons = derived.reasonsByCheck.get(
3878
+ `${invocationId}|${check.id}`
3879
+ );
3880
+ return reasons ? { reasons: [...reasons] } : {};
3881
+ })())
3882
+ ] : [];
3883
+ });
3884
+ }
3885
+ );
3886
+ return engineeringChecks.length > 0 ? { engineeringChecks } : {};
3887
+ };
3888
+ var groupedInvocationIds = (execution) => {
3889
+ var _a;
3890
+ return new Set(
3891
+ ((_a = execution.tables) != null ? _a : []).flatMap(
3892
+ (table) => table.cases.map((item) => item.invocationId)
3893
+ )
3894
+ );
3895
+ };
3896
+ var replacesInvocation = (invocationId, grouped) => invocationId !== void 0 && [...grouped].some(
3897
+ (id) => invocationId === id || invocationId.startsWith(`${id}/`)
3898
+ );
3899
+ var presentedCell = (execution, cell, applicability) => {
3900
+ var _a, _b;
3901
+ if (cell.role === "input") {
3902
+ const invocation = execution.invocations.find(
3903
+ (item) => item.id === cell.caseInvocationId
3904
+ );
3905
+ const value = invocation == null ? void 0 : invocation.resolvedInputs[cell.quantity];
3906
+ const numericKind = (_a = invocation == null ? void 0 : invocation.resolvedInputKinds) == null ? void 0 : _a[cell.quantity];
3907
+ if (value === void 0 || numericKind !== "int" && numericKind !== "float") {
3908
+ fail("CELL_BINDING_MISMATCH", `Missing input '${cell.quantity}'`);
3909
+ }
3910
+ return __spreadValues({
3911
+ heading: cell.heading,
3912
+ invocationId: cell.caseInvocationId,
3913
+ symbolId: cell.symbolId,
3914
+ value,
3915
+ numericKind
3916
+ }, applicabilityField(applicability.reasonsBySymbolId.get(cell.symbolId)));
3917
+ }
3918
+ const output = (_b = execution.authoring) == null ? void 0 : _b.outputs.find(
3919
+ (item) => item.invocationId === cell.caseInvocationId && item.name === cell.quantity && item.symbolId === cell.symbolId
3920
+ );
3921
+ if (!output || output.numericKind !== "int" && output.numericKind !== "float") {
3922
+ fail("CELL_BINDING_MISMATCH", `Missing output '${cell.quantity}'`);
3923
+ }
3924
+ return __spreadValues({
3925
+ heading: cell.heading,
3926
+ invocationId: cell.caseInvocationId,
3927
+ symbolId: cell.symbolId,
3928
+ value: output.value,
3929
+ numericKind: output.numericKind
3930
+ }, applicabilityField(applicability.reasonsBySymbolId.get(cell.symbolId)));
3931
+ };
3932
+ var notationFor = (method) => methodNotation(method, (message) => fail("UNKNOWN_QUANTITY", message));
3933
+ var presentMethodQuantity = (owner, quantity, notation) => ({
3934
+ selectionName: quantity.selectionName,
3935
+ role: quantity.role,
3936
+ glyph: quantity.glyph,
3937
+ description: quantity.description,
3938
+ unit: quantity.unit,
3939
+ formulaText: quantity.formulaText,
3940
+ symbolId: notation.quantityId(owner, quantity.variableName)
3941
+ });
3942
+ var presentMethodContent = (owner, content, notation) => content.map((item) => {
3943
+ var _a, _b, _c;
3944
+ if (item.kind === "external") {
3945
+ return {
3946
+ kind: "external",
3947
+ binding: item.binding,
3948
+ declaration: item.declaration,
3949
+ adapter: item.adapter,
3950
+ inputs: item.declaration.interface.inputs.map(([name]) => {
3951
+ var _a2, _b2, _c2, _d;
3952
+ return {
3953
+ name,
3954
+ formulaText: (_d = (_a2 = item.inputs.find((input) => input.name === name)) == null ? void 0 : _a2.formulaText) != null ? _d : String(
3955
+ (_c2 = (_b2 = item.declaration.interface.defaults.find(
3956
+ (input) => input.name === name
3957
+ )) == null ? void 0 : _b2.value) != null ? _c2 : ""
3958
+ ),
3959
+ symbolId: notation.callInputId(owner, item.binding, name)
3960
+ };
3961
+ }),
3962
+ outputs: item.outputs.map((name) => ({
3963
+ name,
3964
+ symbolId: notation.callOutputId(owner, item.binding, name)
3965
+ }))
3966
+ };
3967
+ }
3968
+ if (item.kind === "boolean") {
3969
+ const declared = (_a = owner.booleans) == null ? void 0 : _a.find(
3970
+ (candidate) => candidate.id === item.localId
3971
+ );
3972
+ if (!declared)
3973
+ fail("UNKNOWN_QUANTITY", `Boolean '${item.localId}' is missing`);
3974
+ return __spreadValues({
3975
+ kind: "boolean",
3976
+ localId: item.localId,
3977
+ description: declared.description,
3978
+ predicateText: declared.predicateText
3979
+ }, declared.expression.kind === "predicate" ? {
3980
+ predicateSymbolId: notation.conditionId(
3981
+ owner,
3982
+ "boolean",
3983
+ declared.id
3984
+ )
3985
+ } : {});
3986
+ }
3987
+ if (item.kind === "check" || item.kind === "applicability") {
3988
+ const declared = ((_b = item.kind === "check" ? owner.checks : owner.applicability) != null ? _b : []).find((candidate) => candidate.id === item.localId);
3989
+ if (!declared) {
3990
+ fail("UNKNOWN_QUANTITY", `Condition '${item.localId}' is missing`);
3991
+ }
3992
+ return {
3993
+ kind: item.kind,
3994
+ localId: item.localId,
3995
+ explanation: declared.explanation,
3996
+ predicateText: declared.predicateText,
3997
+ predicateSymbolId: notation.conditionId(owner, item.kind, declared.id)
3998
+ };
3999
+ }
4000
+ if (item.kind === "quantity") {
4001
+ const quantity = owner.quantities.find(
4002
+ (candidate) => candidate.variableName === item.variableName
4003
+ );
4004
+ if (!quantity) {
4005
+ fail("UNKNOWN_QUANTITY", `Quantity '${item.variableName}' is missing`);
4006
+ }
4007
+ return __spreadValues({
4008
+ kind: "quantity"
4009
+ }, presentMethodQuantity(owner, quantity, notation));
4010
+ }
4011
+ if (item.kind === "section") {
4012
+ return {
4013
+ kind: "section",
4014
+ localId: item.localId,
4015
+ title: item.title,
4016
+ contextSource: HistoricalReviewSchema2.shape.originalFields.parse({
4017
+ metadata: (_c = item.metadata) != null ? _c : {}
4018
+ }),
4019
+ content: presentMethodContent(owner, item.content, notation)
4020
+ };
4021
+ }
4022
+ if (item.kind === "call") {
4023
+ return __spreadProps(__spreadValues({}, item), {
4024
+ inputs: item.inputs.map(({ name, formulaText }) => ({
4025
+ name,
4026
+ formulaText,
4027
+ symbolId: notation.callInputId(owner, item.binding, name)
4028
+ }))
4029
+ });
4030
+ }
4031
+ return item;
4032
+ });
4033
+ var presentMethodHelpers = (helpers, notation) => helpers.map((helper) => {
4034
+ var _a;
4035
+ return {
4036
+ id: helper.id,
4037
+ function: helper.function,
4038
+ functionIdentity: functionIdentityFrom(helper),
4039
+ contextSource: HistoricalReviewSchema2.shape.originalFields.parse({
4040
+ metadata: (_a = helper.metadata) != null ? _a : {}
4041
+ }),
4042
+ content: presentMethodContent(helper, helper.content, notation),
4043
+ helpers: presentMethodHelpers(helper.helpers, notation)
4044
+ };
4045
+ });
4046
+ var presentedBranchNotes = (execution, table, method, notation, includeUniform = false) => {
4047
+ var _a, _b;
4048
+ const outcomes = (_a = execution.branchOutcomes) != null ? _a : [];
4049
+ const bound = table.cases.flatMap(
4050
+ (caseItem) => methodInvocationBindings(execution, method, caseItem.invocationId).flatMap(
4051
+ ({ plan, invocation, callPath }) => outcomes.filter((outcome) => outcome.invocationId === invocation.id).map((outcome) => {
4052
+ var _a2, _b2;
4053
+ const variable = (_a2 = invocation.symbols.find(
4054
+ (item) => item.symbolId === outcome.symbolId
4055
+ )) == null ? void 0 : _a2.variableName;
4056
+ const quantity = (_b2 = plan.quantities.find((item) => item.variableName === variable)) != null ? _b2 : fail(
4057
+ "UNKNOWN_QUANTITY",
4058
+ `Branch symbol '${outcome.symbolId}' is missing`
4059
+ );
4060
+ return { caseItem, plan, callPath, outcome, quantity };
4061
+ })
4062
+ )
4063
+ );
4064
+ const groupKey = (item) => JSON.stringify([
4065
+ item.plan.id,
4066
+ item.callPath,
4067
+ item.quantity.variableName,
4068
+ item.outcome.nodeKey
4069
+ ]);
4070
+ const labels = /* @__PURE__ */ new Map();
4071
+ for (const item of bound) {
4072
+ const key = groupKey(item);
4073
+ const values = (_b = labels.get(key)) != null ? _b : /* @__PURE__ */ new Set();
4074
+ values.add(item.outcome.label);
4075
+ labels.set(key, values);
4076
+ }
4077
+ return bound.filter(
4078
+ (item) => {
4079
+ var _a2, _b2;
4080
+ return includeUniform || ((_b2 = (_a2 = labels.get(groupKey(item))) == null ? void 0 : _a2.size) != null ? _b2 : 0) > 1;
4081
+ }
4082
+ ).map(({ caseItem, plan, callPath, outcome, quantity }) => {
4083
+ var _a2, _b2, _c, _d, _e, _f;
4084
+ const nodes = new Map(quantity.nodes.map((node) => [node.key, node]));
4085
+ let branch = outcome;
4086
+ let chosen;
4087
+ for (; ; ) {
4088
+ const arm = (_d = (_c = (_b2 = (_a2 = nodes.get(branch.nodeKey)) == null ? void 0 : _a2.funcArgs) == null ? void 0 : _b2[branch.value ? 1 : 2]) == null ? void 0 : _c.key) != null ? _d : fail(
4089
+ "UNKNOWN_QUANTITY",
4090
+ `Conditional '${branch.nodeKey}' is incomplete`
4091
+ );
4092
+ const inner = ((_f = (_e = nodes.get(arm)) == null ? void 0 : _e.funcSpec) == null ? void 0 : _f.id) === "fg.cnd" ? outcomes.find(
4093
+ (item) => item.invocationId === outcome.invocationId && item.symbolId === outcome.symbolId && item.nodeKey === arm
4094
+ ) : void 0;
4095
+ if (!inner) {
4096
+ chosen = arm;
4097
+ break;
4098
+ }
4099
+ branch = inner;
4100
+ }
4101
+ return __spreadValues(__spreadProps(__spreadValues({
4102
+ heading: caseItem.heading
4103
+ }, callPath.length > 0 ? { callPath: callPath.join(" / ") } : {}), {
4104
+ invocationId: outcome.invocationId,
4105
+ symbolId: outcome.symbolId,
4106
+ nodeKey: outcome.nodeKey,
4107
+ label: outcome.label,
4108
+ conditionHolds: outcome.value
4109
+ }), notation.branch(
4110
+ plan,
4111
+ quantity.variableName,
4112
+ outcome.nodeKey,
4113
+ chosen
4114
+ ));
4115
+ });
4116
+ };
4117
+ var comparisonPlacement = (execution, item, sectionId, index, applicability) => {
4118
+ var _a, _b, _c, _d, _e, _f, _g;
4119
+ if (item.kind !== "method" && item.kind !== "table") {
4120
+ fail("UNKNOWN_METHOD", "Expected a method or table placement");
4121
+ }
4122
+ const provenance = resolveExecutionPlacementProvenance(execution, item);
4123
+ const placement = __spreadValues(__spreadValues(__spreadValues({
4124
+ context: [],
4125
+ sourcePlacementId: placementId(sectionId, index)
4126
+ }, typeof provenance.localId === "string" ? { localId: provenance.localId } : {}), typeof provenance.invocationId === "string" ? { invocationId: provenance.invocationId } : {}), provenance.location ? { location: provenance.location } : {});
4127
+ if (item.kind === "method") {
4128
+ const method2 = (_a = execution.methods) == null ? void 0 : _a.find((record2) => record2.id === item.id);
4129
+ if (!method2) fail("UNKNOWN_METHOD", `Method '${item.id}' is missing`);
4130
+ const notation2 = notationFor(method2);
4131
+ return __spreadValues({
4132
+ kind: "method",
4133
+ id: item.id,
4134
+ title: method2.title,
4135
+ functionIdentity: functionIdentityFrom(method2),
4136
+ contextSource: HistoricalReviewSchema2.shape.originalFields.parse({
4137
+ metadata: (_b = item.metadata) != null ? _b : {},
4138
+ contentMetadata: (_c = method2.metadata) != null ? _c : {}
4139
+ }),
4140
+ quantities: method2.quantities.map(
4141
+ (quantity) => presentMethodQuantity(method2, quantity, notation2)
4142
+ ),
4143
+ content: presentMethodContent(method2, method2.content, notation2),
4144
+ helpers: presentMethodHelpers(method2.helpers, notation2),
4145
+ symbols: notation2.symbols()
4146
+ }, placement);
4147
+ }
4148
+ const table = (_d = execution.tables) == null ? void 0 : _d.find((record2) => record2.id === item.id);
4149
+ if (!table) fail("UNKNOWN_METHOD", `Table '${item.id}' is missing`);
4150
+ const method = (_e = execution.methods) == null ? void 0 : _e.find(
4151
+ (record2) => record2.id === table.methodId
4152
+ );
4153
+ if (!method) fail("UNKNOWN_METHOD", `Method '${table.methodId}' is missing`);
4154
+ const rows = (role, names) => names.map((name) => {
4155
+ const quantity = method.quantities.find(
4156
+ (candidate) => candidate.role === role && candidate.selectionName === name
4157
+ );
4158
+ if (!quantity) {
4159
+ fail(
4160
+ "UNKNOWN_QUANTITY",
4161
+ `Quantity '${name}' is missing from the method`
4162
+ );
4163
+ }
4164
+ return {
4165
+ quantity: name,
4166
+ role,
4167
+ glyph: quantity.glyph,
4168
+ description: quantity.description,
4169
+ unit: quantity.unit,
4170
+ cells: table.cases.map((caseItem) => {
4171
+ const cell = table.cells.find(
4172
+ (candidate) => candidate.caseInvocationId === caseItem.invocationId && candidate.quantity === name && candidate.role === role
4173
+ );
4174
+ if (!cell) {
4175
+ fail("CELL_BINDING_MISMATCH", `Missing cell for '${name}'`);
4176
+ }
4177
+ return presentedCell(execution, cell, applicability);
4178
+ })
4179
+ };
4180
+ });
4181
+ const notation = notationFor(method);
4182
+ const branchNotes = presentedBranchNotes(execution, table, method, notation);
4183
+ const bindings = table.cases.flatMap(
4184
+ (caseItem) => methodInvocationBindings(execution, method, caseItem.invocationId).map(
4185
+ (binding) => __spreadProps(__spreadValues({}, binding), { heading: caseItem.heading })
4186
+ )
4187
+ );
4188
+ const checkPlans = new Map(bindings.map(({ plan }) => [plan.id, plan]));
4189
+ const engineeringChecks = [...checkPlans.values()].flatMap(
4190
+ (plan) => {
4191
+ var _a2;
4192
+ return ((_a2 = plan.checks) != null ? _a2 : []).flatMap((check) => {
4193
+ const results = bindings.filter((binding) => binding.plan.id === plan.id).flatMap(({ invocation, callPath, heading }) => {
4194
+ var _a3;
4195
+ const outcome = ((_a3 = execution.checkOutcomes) != null ? _a3 : []).find(
4196
+ (item2) => item2.methodId === plan.id && item2.invocationId === invocation.id && item2.checkId === check.id
4197
+ );
4198
+ if (!outcome) return [];
4199
+ const reasons = applicability.reasonsByCheck.get(
4200
+ `${invocation.id}|${check.id}`
4201
+ );
4202
+ return [
4203
+ __spreadValues(__spreadValues({
4204
+ heading,
4205
+ invocationId: invocation.id,
4206
+ value: outcome.value
4207
+ }, callPath.length > 0 ? { callPath: callPath.join(" / ") } : {}), reasons ? { reasons: [...reasons] } : {})
4208
+ ];
4209
+ });
4210
+ return results.length > 0 ? [
4211
+ {
4212
+ id: plan.id === method.id ? check.id : JSON.stringify([plan.id, check.id]),
4213
+ explanation: check.explanation,
4214
+ predicateText: check.predicateText,
4215
+ results
4216
+ }
4217
+ ] : [];
4218
+ });
4219
+ }
4220
+ );
4221
+ const applicabilityPlans = [
4222
+ method,
4223
+ ...method.helpers.flatMap(function walk(helper) {
4224
+ return [helper, ...helper.helpers.flatMap(walk)];
4225
+ })
4226
+ ];
4227
+ const applicabilityNotes = applicabilityPlans.flatMap(
4228
+ (plan) => {
4229
+ var _a2;
4230
+ return ((_a2 = plan.applicability) != null ? _a2 : []).flatMap((condition) => {
4231
+ const results = table.cases.flatMap(
4232
+ (caseItem) => {
4233
+ var _a3;
4234
+ return ((_a3 = execution.applicabilityOutcomes) != null ? _a3 : []).filter(
4235
+ (item2) => item2.methodId === plan.id && item2.applicabilityId === condition.id && (item2.invocationId === caseItem.invocationId || item2.invocationId.startsWith(`${caseItem.invocationId}/`))
4236
+ ).map((outcome) => __spreadValues({
4237
+ heading: caseItem.heading,
4238
+ invocationId: outcome.invocationId,
4239
+ value: outcome.value
4240
+ }, outcome.value ? {} : { reasons: [condition.explanation] }));
4241
+ }
4242
+ );
4243
+ return results.length > 0 ? [
4244
+ {
4245
+ id: condition.id,
4246
+ explanation: condition.explanation,
4247
+ predicateText: condition.predicateText,
4248
+ results
4249
+ }
4250
+ ] : [];
4251
+ });
4252
+ }
4253
+ );
4254
+ const outcomeRows = tableOutcomeRows(execution, table);
4255
+ const allBranchNotes = presentedBranchNotes(
4256
+ execution,
4257
+ table,
4258
+ method,
4259
+ notation,
4260
+ true
4261
+ );
4262
+ const branchRows = /* @__PURE__ */ new Map();
4263
+ for (const note of allBranchNotes) {
4264
+ const id = JSON.stringify([note.quantitySymbolId, note.conditionSymbolId]);
4265
+ let row = branchRows.get(id);
4266
+ if (!row) {
4267
+ row = {
4268
+ kind: "branch",
4269
+ id,
4270
+ label: (_g = (_f = notation.symbols().find((symbol) => symbol.id === note.quantitySymbolId)) == null ? void 0 : _f.description) != null ? _g : "Selected rule",
4271
+ predicateText: "",
4272
+ cells: table.cases.map(({ heading }) => ({ heading, results: [] }))
4273
+ };
4274
+ branchRows.set(id, row);
4275
+ }
4276
+ const cell = row.cells.find((cell2) => cell2.heading === note.heading);
4277
+ if (cell) {
4278
+ const _h = note, { heading: _heading, label } = _h, evidence = __objRest(_h, ["heading", "label"]);
4279
+ cell.results.push(__spreadProps(__spreadValues({}, evidence), { value: label }));
4280
+ }
4281
+ }
4282
+ outcomeRows.push(...branchRows.values());
4283
+ return __spreadValues(__spreadProps(__spreadValues(__spreadProps(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({
4284
+ kind: "table",
4285
+ id: item.id,
4286
+ title: table.title,
4287
+ methodId: method.id,
4288
+ functionIdentity: functionIdentityFrom(method),
4289
+ casesAxis: table.casesAxis
4290
+ }, table.columnCap ? { columnCap: table.columnCap } : {}), branchNotes.length > 0 ? { branchNotes } : {}), outcomeRows.length > 0 ? { symbols: notation.symbols() } : {}), outcomeRows.length > 0 ? { outcomeRows } : {}), engineeringChecks.length > 0 ? { engineeringChecks } : {}), applicabilityNotes.length > 0 ? { applicabilityNotes } : {}), {
4291
+ cases: table.cases.map(({ heading, invocationId }) => ({
4292
+ heading,
4293
+ invocationId
4294
+ })),
4295
+ groups: [
4296
+ ...table.inputs.length > 0 ? [
4297
+ {
4298
+ role: "input",
4299
+ label: "Inputs",
4300
+ rows: rows("input", table.inputs)
4301
+ }
4302
+ ] : [],
4303
+ ...table.outputs.length > 0 ? [
4304
+ {
4305
+ role: "output",
4306
+ label: "Outputs",
4307
+ rows: rows("output", table.outputs)
4308
+ }
4309
+ ] : []
4310
+ ]
4311
+ }), table.cases.length === 0 ? { emptyState: "No cases evaluated" } : {}), {
4312
+ replacedSections: table.cases.map((caseItem) => caseItem.sectionId)
4313
+ }), placement);
4314
+ };
1970
4315
  var prepareExecutionDocument = (options) => {
1971
- var _a, _c;
4316
+ var _a, _b, _d;
1972
4317
  const execution = parseContent(ExecutionPayloadSchema, options.execution);
4318
+ const verification = options.verificationReport === void 0 ? void 0 : parseContent(VerificationReportSchema, options.verificationReport);
4319
+ if (verification && execution.externalCalls && (!verification.executionBinding || executionBindingKey(verification.executionBinding) !== executionBindingKey(executionBindingFrom(execution)))) {
4320
+ fail(
4321
+ "DOCUMENT_VERIFICATION_BINDING_MISMATCH",
4322
+ "Verification must belong to the exact captured execution"
4323
+ );
4324
+ }
1973
4325
  assertExtensionFields(options.execution.cso);
1974
4326
  for (const review of (_a = options.historicalReviews) != null ? _a : [])
1975
4327
  assertDocumentJson(review, "/historicalReview");
@@ -1990,9 +4342,58 @@ var prepareExecutionDocument = (options) => {
1990
4342
  );
1991
4343
  }
1992
4344
  }
1993
- const sections = reachableSections(cso).map((section) => {
1994
- var _a2, _b2, _c2;
1995
- return {
4345
+ const applicability = deriveApplicability(execution);
4346
+ const grouped = groupedInvocationIds(execution);
4347
+ const sectionsById = new Map(
4348
+ cso.sections.map((section) => [section.id, section])
4349
+ );
4350
+ const externalByInvocation = new Map(
4351
+ ((_b = execution.externalCalls) != null ? _b : []).map((call) => [call.id, call])
4352
+ );
4353
+ const externalPlacement = (call, sectionId, index, title = call.callBindingName, suffix = "") => ({
4354
+ kind: "externalCall",
4355
+ id: JSON.stringify([
4356
+ "externalCall",
4357
+ call.parentInvocationId,
4358
+ call.callBindingName
4359
+ ]),
4360
+ title,
4361
+ call,
4362
+ qualifications: [
4363
+ ...new Set(
4364
+ [...call.inputs, ...call.outputs].map((quantity) => quantity.symbolId)
4365
+ )
4366
+ ].flatMap((symbolId) => {
4367
+ const reasons = applicability.reasonsBySymbolId.get(symbolId);
4368
+ return (reasons == null ? void 0 : reasons.length) ? [
4369
+ {
4370
+ symbolId,
4371
+ state: "not-applicable",
4372
+ reasons: [...reasons]
4373
+ }
4374
+ ] : [];
4375
+ }),
4376
+ context: [],
4377
+ sourcePlacementId: placementId(sectionId, index) + suffix,
4378
+ localId: call.callBindingName,
4379
+ invocationId: call.parentInvocationId,
4380
+ location: call.callSite
4381
+ });
4382
+ const replaced = (section) => {
4383
+ var _a2;
4384
+ return replacesInvocation(
4385
+ typeof ((_a2 = section.metadata) == null ? void 0 : _a2.invocationId) === "string" ? section.metadata.invocationId : void 0,
4386
+ grouped
4387
+ );
4388
+ };
4389
+ const sections = reachableSections(cso).filter(
4390
+ (section) => {
4391
+ var _a2;
4392
+ return !replaced(section) && !externalByInvocation.has(String((_a2 = section.metadata) == null ? void 0 : _a2.invocationId));
4393
+ }
4394
+ ).map((section) => {
4395
+ var _a2, _b2, _c2, _d2;
4396
+ return __spreadProps(__spreadValues({
1996
4397
  id: section.id,
1997
4398
  title: section.title,
1998
4399
  sourcePlacementId: placementId(section.id, "heading"),
@@ -2000,15 +4401,64 @@ var prepareExecutionDocument = (options) => {
2000
4401
  localId: (_a2 = section.metadata) == null ? void 0 : _a2.localId,
2001
4402
  invocationId: (_b2 = section.metadata) == null ? void 0 : _b2.invocationId,
2002
4403
  location: (_c2 = section.metadata) == null ? void 0 : _c2.location,
2003
- metadata: retainedMetadata(section.metadata, true),
2004
- items: section.items.map((item, index) => {
2005
- return __spreadValues(__spreadProps(__spreadValues({}, itemFields(item)), {
2006
- context: [],
2007
- contextSource: retainItemContextSource(item, true),
2008
- sourcePlacementId: placementId(section.id, index)
2009
- }), resolveExecutionPlacementProvenance(execution, item));
4404
+ metadata: retainedMetadata(section.metadata, true)
4405
+ }, sectionChecks(
4406
+ execution,
4407
+ (_d2 = section.metadata) == null ? void 0 : _d2.invocationId,
4408
+ applicability
4409
+ )), {
4410
+ items: section.items.flatMap((item, index) => {
4411
+ var _a3, _b3, _c3;
4412
+ if (item.kind === "section") {
4413
+ const target = sectionsById.get(item.id);
4414
+ const call = externalByInvocation.get(
4415
+ String((_a3 = target == null ? void 0 : target.metadata) == null ? void 0 : _a3.invocationId)
4416
+ );
4417
+ if (call) return [externalPlacement(call, section.id, index)];
4418
+ if (target && replaced(target)) return [];
4419
+ }
4420
+ if (item.kind === "method" || item.kind === "table") {
4421
+ const table = item.kind === "table" ? (_b3 = execution.tables) == null ? void 0 : _b3.find((table2) => table2.id === item.id) : void 0;
4422
+ const retained = (_c3 = table == null ? void 0 : table.cases.flatMap(
4423
+ (caseItem) => {
4424
+ var _a4;
4425
+ return ((_a4 = execution.externalCalls) != null ? _a4 : []).filter(
4426
+ (call) => call.id.startsWith(`${caseItem.invocationId}/`)
4427
+ ).map(
4428
+ (call) => externalPlacement(
4429
+ call,
4430
+ section.id,
4431
+ index,
4432
+ `${caseItem.heading} / ${call.id.slice(caseItem.invocationId.length + 1).split("/").join(" / ")}`,
4433
+ `:external:${encodeURIComponent(call.id)}`
4434
+ )
4435
+ );
4436
+ }
4437
+ )) != null ? _c3 : [];
4438
+ return [
4439
+ comparisonPlacement(
4440
+ execution,
4441
+ item,
4442
+ section.id,
4443
+ index,
4444
+ applicability
4445
+ ),
4446
+ ...retained
4447
+ ];
4448
+ }
4449
+ return [
4450
+ __spreadValues(__spreadProps(__spreadValues(__spreadValues({}, itemFields(item)), applicabilityField(
4451
+ item.kind === "symbol" || item.kind === "symbolRef" ? applicability.reasonsBySymbolId.get(
4452
+ item.kind === "symbol" ? item.symbol.id : item.id
4453
+ ) : void 0
4454
+ )), {
4455
+ context: [],
4456
+ contextSource: retainItemContextSource(item, true),
4457
+ sourcePlacementId: placementId(section.id, index)
4458
+ }), resolveExecutionPlacementProvenance(execution, item))
4459
+ ];
2010
4460
  })
2011
- };
4461
+ });
2012
4462
  });
2013
4463
  const displayed = new Set(
2014
4464
  sections.flatMap(
@@ -2025,10 +4475,15 @@ var prepareExecutionDocument = (options) => {
2025
4475
  const placementHistory = itemHistory.filter(
2026
4476
  (item) => item.kind !== "text" && item.kind !== "figure"
2027
4477
  );
2028
- const _b = cso.source, { metadata: _sourceMetadata } = _b, sourceProvenance = __objRest(_b, ["metadata"]);
2029
- const document2 = parseDocument({
2030
- documentVersion: "2",
2031
- context: [],
4478
+ const _c = cso.source, { metadata: _sourceMetadata } = _c, sourceProvenance = __objRest(_c, ["metadata"]);
4479
+ const document2 = parseDocument(__spreadProps(__spreadValues({
4480
+ documentVersion: sections.some(
4481
+ (section) => section.items.some(
4482
+ (item) => item.kind === "method" || item.kind === "table"
4483
+ )
4484
+ ) ? "6" : execution.externalCalls ? "4" : "2",
4485
+ context: []
4486
+ }, verification ? { verification } : {}), {
2032
4487
  source: __spreadValues({
2033
4488
  kind: "execution"
2034
4489
  }, executionBindingFrom(execution)),
@@ -2057,12 +4512,19 @@ var prepareExecutionDocument = (options) => {
2057
4512
  return sections2.length > 0 ? { sections: sections2 } : {};
2058
4513
  })()), symbolHistory.length > 0 ? { symbols: symbolHistory } : {}), referencedSymbolHistory.length > 0 ? { referencedSymbols: referencedSymbolHistory } : {}), contentHistory.length > 0 ? { content: contentHistory } : {}), placementHistory.length > 0 ? { placements: placementHistory } : {})
2059
4514
  }),
2060
- ...(_c = options.historicalReviews) != null ? _c : []
4515
+ ...(_d = options.historicalReviews) != null ? _d : []
2061
4516
  ]
2062
- });
4517
+ }));
2063
4518
  return parseContent(BoundPreparedDocumentSchema, {
2064
4519
  execution,
2065
- document: prepareDocumentContext(document2)
4520
+ document: prepareDocumentContext(
4521
+ document2,
4522
+ new Set(
4523
+ execution.invocations.filter((invocation) => replacesInvocation(invocation.id, grouped)).flatMap(
4524
+ (invocation) => invocation.symbols.map((symbol) => symbol.symbolId)
4525
+ )
4526
+ )
4527
+ )
2066
4528
  }).document;
2067
4529
  };
2068
4530
  var legacyFigure = (options, manifest, item, sourcePlacementId) => {
@@ -2188,7 +4650,11 @@ export {
2188
4650
  DocumentPreparationError,
2189
4651
  FormulaSheet,
2190
4652
  PreparedFormulaSheet,
4653
+ measureComparisons,
4654
+ partitionRowAxis,
4655
+ planComparisonParts,
2191
4656
  prepareExecutionDocument,
2192
4657
  prepareLegacyDocument,
2193
- printFormulaSheet
4658
+ printFormulaSheet,
4659
+ renderComparisonParts
2194
4660
  };