@primmel/primmel 1.14.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/src/check-rules.d.ts.map +1 -1
  2. package/dist/src/check-rules.js +13 -0
  3. package/dist/src/check-rules.js.map +1 -1
  4. package/dist/src/check.d.ts.map +1 -1
  5. package/dist/src/check.js +112 -0
  6. package/dist/src/check.js.map +1 -1
  7. package/dist/src/model-diff.d.ts.map +1 -1
  8. package/dist/src/model-diff.js +3 -0
  9. package/dist/src/model-diff.js.map +1 -1
  10. package/dist/src/ser-des/config/approval.d.ts.map +1 -1
  11. package/dist/src/ser-des/config/approval.js +56 -9
  12. package/dist/src/ser-des/config/approval.js.map +1 -1
  13. package/dist/src/ser-des/config/gateway.d.ts.map +1 -1
  14. package/dist/src/ser-des/config/gateway.js +57 -0
  15. package/dist/src/ser-des/config/gateway.js.map +1 -1
  16. package/dist/src/ser-des/config/index.d.ts.map +1 -1
  17. package/dist/src/ser-des/config/index.js +11 -0
  18. package/dist/src/ser-des/config/index.js.map +1 -1
  19. package/dist/src/ser-des/config/process.d.ts.map +1 -1
  20. package/dist/src/ser-des/config/process.js +46 -0
  21. package/dist/src/ser-des/config/process.js.map +1 -1
  22. package/dist/src/ser-des/config/workflowStage.d.ts +5 -0
  23. package/dist/src/ser-des/config/workflowStage.d.ts.map +1 -0
  24. package/dist/src/ser-des/config/workflowStage.js +96 -0
  25. package/dist/src/ser-des/config/workflowStage.js.map +1 -0
  26. package/dist/src/ser-des/package.d.ts.map +1 -1
  27. package/dist/src/ser-des/package.js +3 -0
  28. package/dist/src/ser-des/package.js.map +1 -1
  29. package/dist/src/ser-des/parse.d.ts.map +1 -1
  30. package/dist/src/ser-des/parse.js +2 -0
  31. package/dist/src/ser-des/parse.js.map +1 -1
  32. package/dist/src/ser-des/types.d.ts +2 -0
  33. package/dist/src/ser-des/types.d.ts.map +1 -1
  34. package/dist/src/types/Approval.d.ts +5 -0
  35. package/dist/src/types/Approval.d.ts.map +1 -1
  36. package/dist/src/types/Gateway.d.ts +22 -0
  37. package/dist/src/types/Gateway.d.ts.map +1 -1
  38. package/dist/src/types/Standard.d.ts +5 -0
  39. package/dist/src/types/Standard.d.ts.map +1 -1
  40. package/dist/src/types/WorkflowStage.d.ts +22 -0
  41. package/dist/src/types/WorkflowStage.d.ts.map +1 -0
  42. package/dist/src/types/WorkflowStage.js +37 -0
  43. package/dist/src/types/WorkflowStage.js.map +1 -0
  44. package/dist/src/types/process.d.ts +21 -0
  45. package/dist/src/types/process.d.ts.map +1 -1
  46. package/dist-browser/index.mjs +1167 -1095
  47. package/dist-cli/primmel.mjs +1833 -1541
  48. package/package.json +1 -1
@@ -261,6 +261,8 @@ function parse(mmelString, parsers, options = {}) {
261
261
  certificateTemplates: {},
262
262
  // The certification workflow step register (batch 3)
263
263
  workflowConfigs: {},
264
+ // The named pipeline stages (batch 5)
265
+ workflowStages: {},
264
266
  // The verification pathways (batch 3)
265
267
  verificationPathways: {},
266
268
  // The selection rules (batch 3)
@@ -589,1730 +591,1785 @@ function unwrapped(value) {
589
591
  return unwrapBlock(x);
590
592
  }
591
593
 
592
- // src/ser-des/config/approval.ts
593
- var parseApproval = function(id, data) {
594
- const result = {
595
- id,
596
- name: "",
597
- modality: "",
598
- actor: null,
599
- approver: null,
600
- records: [],
601
- ref: [],
602
- _relations: {
603
- actor: "",
604
- approver: "",
605
- records: [],
606
- ref: []
594
+ // src/ser-des/config/series.ts
595
+ function parseSeriesDecl(block) {
596
+ const decl = { axes: [], cellSymbol: "", cellUnit: "" };
597
+ const t = tokenize(block);
598
+ let i = 0;
599
+ while (i < t.length) {
600
+ const cmd = t[i++];
601
+ if (cmd !== "axis" && cmd !== "cell") {
602
+ if (i < t.length) {
603
+ unwrapBlock(t[i - 1]);
604
+ }
605
+ continue;
607
606
  }
608
- };
609
- forEachEntry(
610
- data,
611
- (keyword, value) => {
612
- if (keyword === "modality") {
613
- result.modality = value();
614
- } else if (keyword === "name") {
615
- result.name = unwrapped(value);
616
- } else if (keyword === "actor") {
617
- result._relations.actor = value();
618
- } else if (keyword === "approve_by") {
619
- result._relations.approver = value();
620
- } else if (keyword === "approval_record") {
621
- result._relations.records = tokenizePackage(value());
622
- } else if (keyword === "reference") {
623
- result._relations.ref = tokenizePackage(value());
624
- } else {
625
- return false;
607
+ if (cmd === "axis") {
608
+ const axis = {
609
+ id: stripWrapping(t[i++]),
610
+ unit: "",
611
+ type: "",
612
+ role: ""
613
+ };
614
+ if (i < t.length && t[i].startsWith("{")) {
615
+ const ablock = unwrapBlock(t[i++]);
616
+ const at = tokenize(ablock);
617
+ let j = 0;
618
+ while (j < at.length) {
619
+ const ac = at[j++];
620
+ if (j >= at.length) {
621
+ break;
622
+ }
623
+ if (ac === "unit") {
624
+ axis.unit = stripWrapping(at[j++]);
625
+ } else if (ac === "type") {
626
+ axis.type = stripWrapping(at[j++]);
627
+ } else if (ac === "role") {
628
+ axis.role = stripWrapping(at[j++]);
629
+ } else {
630
+ unwrapBlock(at[j++]);
631
+ }
632
+ }
633
+ }
634
+ decl.axes.push(axis);
635
+ } else {
636
+ const cblock = unwrapBlock(t[i++]);
637
+ const ct = tokenize(cblock);
638
+ let j = 0;
639
+ while (j < ct.length) {
640
+ const cc = ct[j++];
641
+ if (j >= ct.length) {
642
+ break;
643
+ }
644
+ if (cc === "symbol") {
645
+ decl.cellSymbol = stripWrapping(ct[j++]);
646
+ } else if (cc === "unit") {
647
+ decl.cellUnit = stripWrapping(ct[j++]);
648
+ } else {
649
+ unwrapBlock(ct[j++]);
650
+ }
626
651
  }
627
- return true;
628
- },
629
- { construct: "approval", id }
630
- );
631
- return (ctx) => {
632
- ctx.approvals[id] = result;
633
- return ctx;
634
- };
635
- };
636
- var resolveApproval = function(ctx, unresolved) {
637
- const { _relations, ...rest } = unresolved;
638
- const p = { ...rest, records: [], ref: [] };
639
- if (_relations.actor !== "") {
640
- p.actor = resolveFromContext(ctx, "roles", _relations.actor) ?? null;
641
- }
642
- if (_relations.approver !== "") {
643
- p.approver = resolveFromContext(ctx, "roles", _relations.approver) ?? null;
644
- }
645
- for (const id of _relations.records) {
646
- const r = resolveFromContext(ctx, "regs", id);
647
- if (r !== void 0) {
648
- p.records.push(r);
649
652
  }
650
653
  }
651
- for (const id of _relations.ref) {
652
- const r = resolveFromContext(ctx, "references", id);
653
- if (r !== void 0) {
654
- p.ref.push(r);
654
+ return decl;
655
+ }
656
+ function dumpSeriesDecl(decl) {
657
+ let out = "series { ";
658
+ for (const a of decl.axes) {
659
+ out += "axis " + a.id + " { ";
660
+ if (a.unit) {
661
+ out += 'unit "' + escapeString(a.unit) + '" ';
662
+ }
663
+ if (a.type) {
664
+ out += "type " + a.type + " ";
665
+ }
666
+ if (a.role) {
667
+ out += "role " + a.role + " ";
655
668
  }
669
+ out += "} ";
656
670
  }
657
- return p;
658
- };
659
- var dumpApproval = function(approval) {
660
- let out = "approval " + approval.id + " {\n";
661
- out += ' name "' + escapeString(approval.name) + '"\n';
662
- if (approval.actor !== null) {
663
- out += " actor " + approval.actor.id + "\n";
671
+ out += "cell { ";
672
+ if (decl.cellSymbol) {
673
+ out += "symbol " + decl.cellSymbol + " ";
664
674
  }
665
- out += " modality " + approval.modality + "\n";
666
- if (approval.approver !== null) {
667
- out += " approve_by " + approval.approver.id + "\n";
675
+ if (decl.cellUnit) {
676
+ out += 'unit "' + escapeString(decl.cellUnit) + '" ';
668
677
  }
669
- if (approval.records.length > 0) {
670
- out += " approval_record {\n";
671
- for (const dr of approval.records) {
672
- out += " " + dr.id + "\n";
678
+ out += "} }";
679
+ return out;
680
+ }
681
+
682
+ // src/ser-des/config/ref.ts
683
+ function parseRef(t, i, stripWrapping2, unwrapBlock2) {
684
+ const predicate = stripWrapping2(t[i++] ?? "");
685
+ const target = stripWrapping2(t[i++] ?? "");
686
+ const ref = { predicate, target };
687
+ if (i < t.length && t[i].startsWith("{")) {
688
+ const block = unwrapBlock2(t[i++]);
689
+ const m = /note\s+"([^"]*)"/.exec(block) ?? /note\s+(\S+)/.exec(block);
690
+ if (m) {
691
+ ref.note = m[1];
673
692
  }
674
- out += " }\n";
675
693
  }
676
- if (approval.ref.length > 0) {
677
- out += " reference {\n";
678
- for (const r of approval.ref) {
679
- out += " " + r.id + "\n";
680
- }
681
- out += " }\n";
694
+ return { ref, next: i };
695
+ }
696
+ function parseRefFromReaders(value, peek, stripWrapping2, unwrapBlock2) {
697
+ const parts = [value(), value()];
698
+ const next = peek();
699
+ if (next && next.startsWith("{")) {
700
+ parts.push(value());
701
+ }
702
+ return parseRef(parts, 0, stripWrapping2, unwrapBlock2).ref;
703
+ }
704
+ function dumpRefs(refs, indent, escapeString2) {
705
+ if (!refs || refs.length === 0) {
706
+ return "";
707
+ }
708
+ let out = "";
709
+ for (const r of refs) {
710
+ out += `${indent}ref ${r.predicate} "${escapeString2(r.target)}"`;
711
+ out += r.note ? ` {
712
+ ${indent} note "${escapeString2(r.note)}"
713
+ ${indent}}
714
+ ` : "\n";
682
715
  }
683
- out += "}\n";
684
716
  return out;
685
- };
686
-
687
- // src/ser-des/config/data.ts
688
- var parseEnum = (id, data) => {
689
- const result = {
690
- id,
691
- values: []
692
- };
693
- forEachEntry(
694
- data,
695
- (_vid, value) => {
696
- result.values.push(parseEnumValue(_vid, value()));
697
- return true;
698
- },
699
- { construct: "enum", id }
700
- );
701
- return (ctx) => {
702
- ctx.enums[id] = result;
703
- return ctx;
704
- };
705
- };
706
- var parseEnumValue = (id, data) => {
707
- const ev = {
708
- id,
709
- value: ""
710
- };
711
- forEachEntry(
712
- data,
713
- (command, value) => {
714
- if (command === "definition") {
715
- ev.value = unwrapped(value);
716
- } else {
717
- return false;
718
- }
719
- return true;
720
- },
721
- { construct: "enum value", id }
722
- );
723
- return ev;
724
- };
725
- var parseRegistry = function(id, data) {
726
- const result = {
727
- id,
728
- title: "",
729
- data: null,
730
- _relations: {
731
- data: ""
717
+ }
718
+ function refTargetToSourceRef(target) {
719
+ const m = /^(urn:[^#]+)(?:#(.+))?$/.exec(target);
720
+ if (!m) {
721
+ return null;
722
+ }
723
+ const anchor = m[2];
724
+ if (!anchor) {
725
+ return { doc: target, clause: "" };
726
+ }
727
+ if (anchor.startsWith("clause-")) {
728
+ const rest = anchor.slice("clause-".length);
729
+ const slash = rest.indexOf("/");
730
+ if (slash >= 0) {
731
+ return {
732
+ doc: m[1],
733
+ clause: rest.slice(0, slash),
734
+ fragment: rest.slice(slash + 1)
735
+ };
732
736
  }
733
- };
734
- forEachEntry(
735
- data,
736
- (command, value) => {
737
- if (command === "title") {
738
- result.title = unwrapped(value);
739
- } else if (command === "data_class") {
740
- result._relations.data = value();
741
- } else {
742
- return false;
743
- }
744
- return true;
745
- },
746
- { construct: "registry", id }
747
- );
748
- return (ctx) => {
749
- ctx.regs[id] = result;
750
- return ctx;
751
- };
752
- };
753
- var parseDataClass = function(id, data) {
754
- const result = {
755
- id,
756
- attributes: []
757
- };
758
- forEachAttribute(
759
- data,
760
- (basic, details) => {
761
- if (basic.startsWith("ref ")) {
762
- const m = basic.match(/^ref\s+(\S+)\s+"([^"]*)"$/);
763
- if (m) {
764
- const ref = { predicate: m[1], target: m[2] };
765
- if (details) {
766
- const noteMatch = /note\s+"([^"]*)"/.exec(details) ?? /note\s+(\S+)/.exec(details);
767
- if (noteMatch) {
768
- ref.note = noteMatch[1];
769
- }
770
- }
771
- result.ref ??= [];
772
- result.ref.push(ref);
773
- return;
774
- }
775
- }
776
- const head = basic.trim();
777
- if (head === "store") {
778
- result.store = details.trim();
779
- return;
780
- }
781
- if (head === "description") {
782
- result.description = stripWrapping(details.trim());
783
- return;
784
- }
785
- if (head === "indexes") {
786
- result.indexes = details.split(/\s+/).filter((x) => x.length > 0);
787
- return;
788
- }
789
- if (head === "helper") {
790
- result.helper = details.trim() === "true";
791
- return;
792
- }
793
- if (head === "extends") {
794
- result.extends = details.trim();
795
- return;
796
- }
797
- result.attributes.push(parseDataAttribute(head, details));
798
- },
799
- { construct: "class", id }
800
- );
801
- return (ctx) => {
802
- ctx.dataclasses[id] = result;
803
- return ctx;
804
- };
805
- };
806
- var parseDataAttribute = (basic, details) => {
807
- const result = {
808
- id: "",
809
- type: "",
810
- modality: "",
811
- cardinality: "",
812
- definition: "",
813
- ref: [],
814
- satisfy: [],
815
- _relations: {
816
- ref: []
817
- }
818
- };
819
- const cardMatch = basic.match(/^(.*?)\s*\[([\d*][^\]]*)\]\s*$/);
820
- if (cardMatch) {
821
- result.cardinality = cardMatch[2].trim();
822
- basic = cardMatch[1];
823
- }
824
- const colonIndex = basic.indexOf(":");
825
- if (colonIndex !== -1) {
826
- result.type = basic.substr(colonIndex + 1, basic.length - colonIndex - 1).trim();
827
- basic = basic.substr(0, colonIndex);
737
+ return { doc: m[1], clause: rest };
828
738
  }
829
- result.id = basic.trim();
830
- forEachEntry(
831
- details,
832
- (keyword, value) => {
833
- if (keyword === "modality") {
834
- result.modality = value();
835
- } else if (keyword === "definition") {
836
- result.definition = unwrapped(value);
837
- } else if (keyword === "reference") {
838
- result._relations.ref = tokenizePackage(value());
839
- } else if (keyword === "satisfy") {
840
- result.satisfy = tokenizePackage(value());
841
- } else if (keyword === "on_delete") {
842
- result.onDelete = value();
843
- } else if (keyword === "deprecated") {
844
- result.deprecated = value() === "true";
845
- } else if (keyword === "enum_values") {
846
- result.enumValues = tokenizePackage(value());
847
- } else if (keyword === "required") {
848
- result.required = value() === "true";
849
- } else if (keyword === "unit") {
850
- result.unit = unwrapped(value);
851
- } else if (keyword === "default") {
852
- result.defaultValue = unwrapped(value);
853
- } else {
854
- return false;
855
- }
739
+ return { doc: target, clause: "" };
740
+ }
741
+ function foldRefIntoLegacy(el, ref) {
742
+ if (ref.predicate === "derives-from") {
743
+ const roleChannel = el.fieldReferences ?? el.formReferences;
744
+ const hasProvenanceSlot = "source" in el || "sourceRef" in el || el.sourceRefs !== void 0;
745
+ if (roleChannel && !hasProvenanceSlot) {
746
+ roleChannel.push({ urn: ref.target, role: "source" });
856
747
  return true;
857
- },
858
- { construct: "data attribute", id: result.id }
859
- );
860
- return result;
861
- };
862
- var resolveDataClass = function(ctx, unresolved) {
863
- const attributes = unresolved.attributes.map((attr) => {
864
- const resolved = { ...attr, ref: [] };
865
- for (const id of attr._relations.ref) {
866
- const r = resolveFromContext(ctx, "references", id);
867
- if (r !== void 0) {
868
- resolved.ref.push(r);
869
- }
870
748
  }
871
- return resolved;
872
- });
873
- return {
874
- id: unresolved.id,
875
- attributes,
876
- ...unresolved.store !== void 0 ? { store: unresolved.store } : {},
877
- ...unresolved.indexes !== void 0 ? { indexes: unresolved.indexes } : {},
878
- ...unresolved.helper !== void 0 ? { helper: unresolved.helper } : {},
879
- ...unresolved.extends !== void 0 ? { extends: unresolved.extends } : {},
880
- ...unresolved.description !== void 0 ? { description: unresolved.description } : {},
881
- ...unresolved.ref !== void 0 ? { ref: unresolved.ref } : {}
882
- };
883
- };
884
- var resolveRegistry = function(ctx, unresolved) {
885
- const { _relations, ...rest } = unresolved;
886
- const p = { ...rest, data: null };
887
- if (_relations.data !== "") {
888
- const dc = resolveFromContext(
889
- ctx,
890
- "dataclasses",
891
- _relations.data
892
- );
893
- if (dc !== void 0) {
894
- p.data = dc;
749
+ const b = refTargetToSourceRef(ref.target);
750
+ if (!b) {
751
+ return false;
895
752
  }
753
+ (el.sourceRefs ??= []).push(b);
754
+ if ("source" in el && !el.source) {
755
+ el.source = b;
756
+ }
757
+ if ("sourceRef" in el && !el.sourceRef) {
758
+ el.sourceRef = b;
759
+ }
760
+ if ("reference" in el && !el.reference) {
761
+ el.reference = b.doc;
762
+ }
763
+ return true;
896
764
  }
897
- return p;
898
- };
899
- var dumpDataClass = function(dataclass) {
900
- let out = "class " + dataclass.id + " {\n";
901
- if (dataclass.store) {
902
- out += " store { " + dataclass.store + " }\n";
903
- }
904
- if (dataclass.description) {
905
- out += ' description { "' + escapeString(dataclass.description) + '" }\n';
906
- }
907
- if (dataclass.indexes && dataclass.indexes.length > 0) {
908
- out += " indexes { " + dataclass.indexes.join(" ") + " }\n";
909
- }
910
- if (dataclass.helper !== void 0) {
911
- out += " helper { " + dataclass.helper + " }\n";
912
- }
913
- if (dataclass.extends) {
914
- out += " extends { " + dataclass.extends + " }\n";
765
+ if (ref.predicate === "cites") {
766
+ if (el.fieldReferences) {
767
+ el.fieldReferences.push({ urn: ref.target, role: "reference" });
768
+ } else if (el.formReferences) {
769
+ el.formReferences.push({ urn: ref.target, role: "reference" });
770
+ } else if (el.referenceIds) {
771
+ el.referenceIds.push(ref.target);
772
+ }
773
+ return true;
915
774
  }
916
- if (dataclass.ref && dataclass.ref.length > 0) {
917
- for (const r of dataclass.ref) {
918
- out += " ref " + r.predicate + ' "' + escapeString(r.target) + '"';
919
- if (r.note) {
920
- out += ' { note "' + escapeString(r.note) + '" }';
921
- }
922
- out += "\n";
775
+ const CITATION_ROLES = [
776
+ "requirement",
777
+ "test-procedure",
778
+ "calculation",
779
+ "report-format",
780
+ "method"
781
+ ];
782
+ if (CITATION_ROLES.includes(ref.predicate)) {
783
+ const channel = el.fieldReferences ?? el.formReferences;
784
+ if (!channel) {
785
+ return false;
923
786
  }
787
+ channel.push({ urn: ref.target, role: ref.predicate });
788
+ return true;
924
789
  }
925
- for (const a of dataclass.attributes) {
926
- out += toDataAttributeModel(a);
790
+ return false;
791
+ }
792
+ function dumpSourceRefAsRef(src, indent, escapeString2) {
793
+ if (src.doc && src.doc.startsWith("urn:")) {
794
+ const anchor = `${src.doc}${src.clause ? "#clause-" + src.clause : ""}${src.fragment ? "/" + src.fragment : ""}`;
795
+ return `${indent}ref derives-from "${escapeString2(anchor)}"
796
+ `;
927
797
  }
928
- out += "}\n";
929
- return out;
930
- };
931
- var toDataAttributeModel = (attribute) => {
932
- let out = " " + attribute.id;
933
- if (attribute.type !== "") {
934
- out += ": " + attribute.type;
798
+ return `${indent}source { doc "${escapeString2(src.doc ?? "")}" clause "${escapeString2(String(src.clause ?? ""))}"` + (src.fragment ? ` fragment "${escapeString2(src.fragment)}"` : "") + " }\n";
799
+ }
800
+
801
+ // src/ser-des/config/correspondence.ts
802
+ function parseCorresponds(t, i, stripWrapping2) {
803
+ if (t[i] === void 0) {
804
+ throw new Error(
805
+ "Parsing error: corresponds: Expecting value for corresponds (the scheme and the concept)"
806
+ );
935
807
  }
936
- if (attribute.cardinality !== "") {
937
- out += "[" + attribute.cardinality + "]";
808
+ const scheme = stripWrapping2(t[i++]);
809
+ if (t[i] === void 0) {
810
+ throw new Error(
811
+ "Parsing error: corresponds: Expecting value for corresponds (the concept)"
812
+ );
938
813
  }
939
- out += " {\n";
940
- out += ' definition "' + escapeString(attribute.definition) + '"\n';
941
- if (attribute.modality !== "") {
942
- out += " modality " + attribute.modality + "\n";
943
- }
944
- if (attribute.onDelete) {
945
- out += " on_delete " + attribute.onDelete + "\n";
946
- }
947
- if (attribute.deprecated) {
948
- out += " deprecated true\n";
949
- }
950
- if (attribute.enumValues && attribute.enumValues.length > 0) {
951
- out += " enum_values { " + attribute.enumValues.join(" ") + " }\n";
952
- }
953
- if (attribute.required !== void 0) {
954
- out += " required " + (attribute.required ? "true" : "false") + "\n";
955
- }
956
- if (attribute.unit) {
957
- out += ' unit "' + escapeString(attribute.unit) + '"\n';
814
+ const corr = {
815
+ scheme,
816
+ concept: stripWrapping2(t[i++]),
817
+ projections: []
818
+ };
819
+ if (i < t.length && t[i].startsWith("{")) {
820
+ const block = unwrapBlock(t[i++]);
821
+ forEachEntry(
822
+ block,
823
+ (keyword, value, peek) => {
824
+ if (keyword === "projection") {
825
+ const codec = stripWrapping2(value());
826
+ const entries = [];
827
+ const next = peek();
828
+ if (next && next.startsWith("{")) {
829
+ forEachEntry(
830
+ unwrapBlock(value()),
831
+ (k, kv) => {
832
+ entries.push({ key: k, value: stripWrapping2(kv()) });
833
+ return true;
834
+ },
835
+ { construct: "corresponds.projection", id: codec }
836
+ );
837
+ }
838
+ corr.projections.push({ codec, entries });
839
+ return true;
840
+ }
841
+ return false;
842
+ },
843
+ { construct: "corresponds", id: corr.scheme }
844
+ );
958
845
  }
959
- if (attribute.defaultValue !== void 0) {
960
- out += ' default "' + escapeString(attribute.defaultValue) + '"\n';
846
+ return { corr, next: i };
847
+ }
848
+ function parseCorrespondsFromReaders(value, peek, stripWrapping2) {
849
+ const parts = [value(), value()];
850
+ const next = peek();
851
+ if (next && next.startsWith("{")) {
852
+ parts.push(value());
961
853
  }
962
- if (attribute.satisfy.length > 0) {
963
- out += " satisfy {\n";
964
- for (const s of attribute.satisfy) {
965
- out += " " + s + "\n";
966
- }
967
- out += " }\n";
854
+ return parseCorresponds(parts, 0, stripWrapping2).corr;
855
+ }
856
+ function dumpCorrespondences(corrs, indent, escapeString2, dumpBareSafe2) {
857
+ if (!corrs || corrs.length === 0) {
858
+ return "";
968
859
  }
969
- if (attribute.ref.length > 0) {
970
- out += " reference {\n";
971
- for (const r of attribute.ref) {
972
- out += " " + r.id + "\n";
860
+ let out = "";
861
+ for (const c of corrs) {
862
+ out += `${indent}corresponds ${dumpBareSafe2(c.scheme)} "${escapeString2(c.concept)}"`;
863
+ if (c.projections.length === 0) {
864
+ out += "\n";
865
+ continue;
973
866
  }
974
- out += " }\n";
975
- }
976
- out += " }\n";
977
- return out;
978
- };
979
- var dumpEnumValue = (ev) => {
980
- let out = " " + ev.id + " {\n";
981
- out += ' definition "' + escapeString(ev.value) + '"\n';
982
- out += " }\n";
983
- return out;
984
- };
985
- var dumpEnum = function(en) {
986
- let out = "enum " + en.id + " {\n";
987
- for (const v of en.values) {
988
- out += dumpEnumValue(v);
989
- }
990
- out += "}\n";
991
- return out;
992
- };
993
- var dumpRegistry = function(reg) {
994
- let out = "data_registry " + reg.id + " {\n";
995
- out += ' title "' + escapeString(reg.title) + '"\n';
996
- if (reg.data !== null) {
997
- out += " data_class " + reg.data.id + "\n";
998
- }
999
- out += "}\n";
1000
- return out;
1001
- };
1002
- var parseVariable = function(id, data) {
1003
- const result = {
1004
- id,
1005
- type: "",
1006
- definition: "",
1007
- description: ""
1008
- };
1009
- forEachEntry(
1010
- data,
1011
- (keyword, value) => {
1012
- if (keyword === "type") {
1013
- result.type = value();
1014
- } else if (keyword === "definition") {
1015
- result.definition = unwrapped(value);
1016
- } else if (keyword === "description") {
1017
- result.description = unwrapped(value);
1018
- } else {
1019
- return false;
867
+ out += " {\n";
868
+ for (const p of c.projections) {
869
+ out += `${indent} projection ${dumpBareSafe2(p.codec)} {`;
870
+ for (const e of p.entries) {
871
+ out += ` ${dumpBareSafe2(e.key)} ${dumpBareSafe2(e.value)}`;
1020
872
  }
1021
- return true;
1022
- },
1023
- { construct: "variable", id }
1024
- );
1025
- return (ctx) => {
1026
- ctx.variables[id] = result;
1027
- return ctx;
1028
- };
1029
- };
1030
- var dumpVariable = function(v) {
1031
- let out = "variable " + v.id + " {\n";
1032
- if (v.type !== "") {
1033
- out += " type " + v.type + "\n";
1034
- }
1035
- if (v.definition !== "") {
1036
- out += ' definition "' + escapeString(v.definition) + '"\n';
1037
- }
1038
- if (v.description !== "") {
1039
- out += ' description "' + escapeString(v.description) + '"\n';
873
+ out += " }\n";
874
+ }
875
+ out += `${indent}}
876
+ `;
1040
877
  }
1041
- out += "}\n";
1042
878
  return out;
1043
- };
879
+ }
1044
880
 
1045
- // src/ser-des/config/event.ts
1046
- var parseEndEvent = function(id, data) {
1047
- const result = {
1048
- id,
1049
- eventType: "end"
881
+ // src/ser-des/config/sourceDiscrepancy.ts
882
+ var VALID_RESOLUTIONS = ["follows_clause_x", "annotated_only"];
883
+ function parseSourceDiscrepancy(block) {
884
+ const sd = {
885
+ summary: "",
886
+ sources: [],
887
+ resolution: "",
888
+ rationale: ""
1050
889
  };
1051
- if (data !== "") {
1052
- const t = tokenizePackage(data);
1053
- if (t.length > 0) {
1054
- throw new Error(
1055
- `Parsing error: end_event. ID ${id}: Expecting empty body`
1056
- );
890
+ const t = tokenize(block);
891
+ let i = 0;
892
+ while (i < t.length) {
893
+ const cmd = t[i++];
894
+ if (i >= t.length) {
895
+ break;
1057
896
  }
1058
- }
1059
- return (ctx) => {
1060
- ctx.events[id] = result;
1061
- return ctx;
1062
- };
1063
- };
1064
- var parseSignalCatchEvent = function(id, data) {
1065
- const result = {
1066
- id,
1067
- eventType: "signalcatch",
1068
- signal: ""
1069
- };
1070
- if (data !== "") {
1071
- const t = tokenizePackage(data);
1072
- let i = 0;
1073
- while (i < t.length) {
1074
- const command = t[i++];
1075
- if (i < t.length) {
1076
- if (command === "catch") {
1077
- result.signal = unwrapBlock(t[i++]);
1078
- } else {
1079
- i++;
1080
- }
1081
- } else {
897
+ if (cmd === "summary") {
898
+ sd.summary = stripWrapping(t[i++]);
899
+ } else if (cmd === "sources") {
900
+ sd.sources = tokenize(stripWrapping(t[i++])).map(stripWrapping).filter((s) => s.length > 0);
901
+ } else if (cmd === "resolution") {
902
+ const r = stripWrapping(t[i++]);
903
+ if (!VALID_RESOLUTIONS.includes(r)) {
1082
904
  throw new Error(
1083
- `Parsing error: Signal Catch Event. ID ${id}: Expecting value for ${command}`
905
+ `Parsing error: source_discrepancy: Unknown resolution ${r} (valid: ${VALID_RESOLUTIONS.join(
906
+ ", "
907
+ )})`
1084
908
  );
1085
909
  }
910
+ sd.resolution = r;
911
+ } else if (cmd === "rationale") {
912
+ sd.rationale = stripWrapping(t[i++]);
913
+ } else {
914
+ unwrapBlock(t[i++]);
1086
915
  }
1087
916
  }
1088
- return (ctx) => {
1089
- ctx.events[id] = result;
1090
- return ctx;
1091
- };
1092
- };
1093
- var parseStartEvent = function(id, data) {
1094
- const result = {
1095
- id,
1096
- eventType: "start"
1097
- };
1098
- if (data !== "") {
1099
- const t = tokenizePackage(data);
1100
- if (t.length > 0) {
1101
- throw new Error(
1102
- `Parsing error: end_event. ID ${id}: Expecting empty body`
1103
- );
1104
- }
917
+ return sd;
918
+ }
919
+ function dumpSourceDiscrepancy(sd, indent) {
920
+ let out = indent + "source_discrepancy { ";
921
+ out += 'summary "' + escapeString(sd.summary) + '" ';
922
+ out += "sources { " + sd.sources.map((s) => '"' + escapeString(s) + '"').join(" ") + " } ";
923
+ out += "resolution " + sd.resolution + " ";
924
+ out += 'rationale "' + escapeString(sd.rationale) + '" ';
925
+ out += "}";
926
+ return out;
927
+ }
928
+
929
+ // src/ser-des/config/field-parser.ts
930
+ function readValueToken(t, i) {
931
+ const tok = t[i] ?? "";
932
+ if (!tok.startsWith("ocl{")) {
933
+ return { text: tok, next: i + 1 };
1105
934
  }
1106
- return (ctx) => {
1107
- ctx.events[id] = result;
1108
- return ctx;
1109
- };
1110
- };
1111
- var parseTimerEvent = function(id, data) {
1112
- const result = {
1113
- id,
1114
- eventType: "timer",
1115
- type: "",
1116
- para: ""
1117
- };
1118
- if (data !== "") {
1119
- const t = tokenizePackage(data);
1120
- let i = 0;
1121
- while (i < t.length) {
1122
- const command = t[i++];
1123
- if (i < t.length) {
1124
- if (command === "type") {
1125
- result.type = t[i++];
1126
- } else if (command === "para") {
1127
- result.para = unwrapBlock(t[i++]);
1128
- } else {
1129
- i++;
935
+ const delta = (s) => (s.match(/\{/g) || []).length - (s.match(/\}/g) || []).length;
936
+ let text = tok;
937
+ let depth = delta(tok);
938
+ let j = i + 1;
939
+ while (depth > 0 && j < t.length) {
940
+ const nt = t[j++];
941
+ depth += delta(nt);
942
+ text += " " + nt;
943
+ }
944
+ return { text, next: j };
945
+ }
946
+ function parseValueEntries(raw) {
947
+ const inner = raw.trim().replace(/^[[{]/, "").replace(/[\]}]$/, "");
948
+ const t = tokenizePackage(inner);
949
+ const out = [];
950
+ let i = 0;
951
+ while (i < t.length) {
952
+ const entry = stripWrapping(t[i++].replace(/,$/, ""));
953
+ if (!entry) {
954
+ continue;
955
+ }
956
+ if (i < t.length && t[i].startsWith("{")) {
957
+ const lb = tokenizePackage(unwrapBlock(t[i++]));
958
+ let label = "";
959
+ for (let k = 0; k + 1 < lb.length; k += 2) {
960
+ if (lb[k] === "label") {
961
+ label = stripWrapping(lb[k + 1]);
1130
962
  }
1131
- } else {
1132
- throw new Error(
1133
- `Parsing error: Timer Event. ID ${id}: Expecting value for ${command}`
1134
- );
1135
963
  }
964
+ out.push({ value: entry, label });
965
+ } else {
966
+ out.push(entry);
1136
967
  }
1137
968
  }
1138
- return (ctx) => {
1139
- ctx.events[id] = result;
1140
- return ctx;
1141
- };
1142
- };
1143
- var dumpEvent = function(event) {
1144
- if (event.eventType === "start") {
1145
- return dumpStartEvent(event);
1146
- }
1147
- if (event.eventType === "end") {
1148
- return dumpEndEvent(event);
1149
- }
1150
- if (event.eventType === "signalcatch") {
1151
- return dumpSignalCatchEvent(event);
1152
- }
1153
- if (event.eventType === "timer") {
1154
- return dumpTimerEvent(event);
1155
- }
1156
- return "";
1157
- };
1158
- function dumpEndEvent(end) {
1159
- return "end_event " + end.id + " {\n}\n";
969
+ return out;
1160
970
  }
1161
- function dumpSignalCatchEvent(sc) {
1162
- let out = "signal_catch_event " + sc.id + " {\n";
1163
- if (sc.signal !== "") {
1164
- out += ' catch "' + escapeString(sc.signal) + '"\n';
971
+ function dumpValueEntry(e) {
972
+ if (typeof e === "string") {
973
+ return e;
1165
974
  }
1166
- out += "}\n";
1167
- return out;
975
+ return e.value + ' { label "' + escapeString(e.label) + '" }';
1168
976
  }
1169
- function dumpStartEvent(s) {
1170
- return "start_event " + s.id + " {\n}\n";
977
+ function dumpBareSafe(v) {
978
+ return /[\s{}"]/.test(v) || v.endsWith(":") || v.startsWith("#") || v.startsWith("//") ? '"' + escapeString(v) + '"' : v;
1171
979
  }
1172
- function dumpTimerEvent(te) {
1173
- let out = "timer_event " + te.id + " {\n";
1174
- if (te.type !== "") {
1175
- out += " type " + te.type + "\n";
980
+ function stripColon(x) {
981
+ return x.endsWith(":") ? x.slice(0, -1) : x;
982
+ }
983
+ function readBalanced(t, i) {
984
+ const first = t[i] ?? "";
985
+ if (!first.startsWith("[")) {
986
+ return { text: first, next: i + 1 };
1176
987
  }
1177
- if (te.para !== "") {
1178
- out += ' para "' + escapeString(te.para) + '"\n';
988
+ let text = first;
989
+ let j = i + 1;
990
+ while (!text.includes("]") && j < t.length) {
991
+ text += " " + t[j++];
1179
992
  }
1180
- out += "}\n";
1181
- return out;
993
+ return { text, next: j };
1182
994
  }
1183
-
1184
- // src/ser-des/config/gateway.ts
1185
- var parseExclusiveGate = function(id, data) {
1186
- const gateway = {
1187
- id,
1188
- gatewayType: "exclusive_gateway",
1189
- label: ""
1190
- };
1191
- forEachEntry(
1192
- data,
1193
- (command, value) => {
1194
- if (command === "label") {
1195
- gateway.label = unwrapped(value);
1196
- } else {
1197
- return false;
1198
- }
1199
- return true;
1200
- },
1201
- { construct: "Exclusive gateway", id }
1202
- );
1203
- return (ctx) => {
1204
- ctx.gateways[id] = gateway;
1205
- return ctx;
1206
- };
1207
- };
1208
- var dumpGateway = function(gate) {
1209
- if (gate.gatewayType === "exclusive_gateway") {
1210
- return dumpEGate(gate);
1211
- }
1212
- return "";
1213
- };
1214
- function dumpEGate(egate) {
1215
- let out = "exclusive_gateway " + egate.id + " {\n";
1216
- if (egate.label !== "") {
1217
- out += ' label "' + escapeString(egate.label) + '"\n';
995
+ function subBlockTokens(block) {
996
+ return tokenizePackage(block).map((s) => s.replace(/^;+|;+$/g, "")).filter((s) => s.length > 0);
997
+ }
998
+ function readEntryTokens(value) {
999
+ if (value.startsWith("{")) {
1000
+ return subBlockTokens(unwrapBlock(value)).flatMap((s) => s.split(",")).map((s) => stripWrapping(s.trim())).filter((s) => s.length > 0);
1218
1001
  }
1219
- out += "}\n";
1220
- return out;
1002
+ const single = stripWrapping(value);
1003
+ return single === "" ? [] : [single];
1221
1004
  }
1222
-
1223
- // src/ser-des/config/metadata.ts
1224
- var parseMetadata = function(token) {
1225
- const metadata = {
1226
- schema: "",
1227
- author: "",
1228
- title: "",
1229
- edition: "",
1230
- namespace: "",
1231
- shortname: ""
1232
- };
1233
- if (token !== "") {
1234
- const t = tokenizePackage(token);
1235
- let i = 0;
1236
- while (i < t.length) {
1237
- const keyword = t[i++];
1238
- if (i < t.length) {
1239
- if (keyword === "title") {
1240
- metadata.title = stripWrapping(t[i++]);
1241
- } else if (keyword === "schema") {
1242
- metadata.schema = stripWrapping(t[i++]);
1243
- } else if (keyword === "edition") {
1244
- metadata.edition = stripWrapping(t[i++]);
1245
- } else if (keyword === "author") {
1246
- metadata.author = stripWrapping(t[i++]);
1247
- } else if (keyword === "namespace") {
1248
- metadata.namespace = stripWrapping(t[i++]);
1249
- } else if (keyword === "shortname") {
1250
- metadata.shortname = stripWrapping(t[i++]);
1251
- } else {
1252
- throw new Error(
1253
- "Parsing error: metadata. Unknown keyword " + keyword
1254
- );
1255
- }
1256
- } else {
1257
- throw new Error(
1258
- "Parsing error: metadata. Expecting value for " + keyword
1259
- );
1260
- }
1005
+ function readSource(block) {
1006
+ const src = { doc: "", clause: "" };
1007
+ const t = tokenize(block);
1008
+ let i = 0;
1009
+ while (i < t.length) {
1010
+ const cmd = t[i++];
1011
+ if (i >= t.length) {
1012
+ break;
1261
1013
  }
1262
- }
1263
- return (ctx) => {
1264
- ctx.metadata = metadata;
1265
- return ctx;
1266
- };
1267
- };
1268
-
1269
- // src/ser-des/config/ref.ts
1270
- function parseRef(t, i, stripWrapping2, unwrapBlock2) {
1271
- const predicate = stripWrapping2(t[i++] ?? "");
1272
- const target = stripWrapping2(t[i++] ?? "");
1273
- const ref = { predicate, target };
1274
- if (i < t.length && t[i].startsWith("{")) {
1275
- const block = unwrapBlock2(t[i++]);
1276
- const m = /note\s+"([^"]*)"/.exec(block) ?? /note\s+(\S+)/.exec(block);
1277
- if (m) {
1278
- ref.note = m[1];
1014
+ if (cmd === "doc") {
1015
+ src.doc = stripWrapping(t[i++]);
1016
+ } else if (cmd === "clause") {
1017
+ src.clause = stripWrapping(t[i++]);
1018
+ } else if (cmd === "fragment") {
1019
+ src.fragment = stripWrapping(t[i++]);
1020
+ } else {
1021
+ unwrapBlock(t[i++]);
1279
1022
  }
1280
1023
  }
1281
- return { ref, next: i };
1024
+ return src;
1282
1025
  }
1283
- function parseRefFromReaders(value, peek, stripWrapping2, unwrapBlock2) {
1284
- const parts = [value(), value()];
1285
- const next = peek();
1286
- if (next && next.startsWith("{")) {
1287
- parts.push(value());
1026
+ function readFieldHead(t, i) {
1027
+ const name = t[i++];
1028
+ if (name === void 0) {
1029
+ return null;
1288
1030
  }
1289
- return parseRef(parts, 0, stripWrapping2, unwrapBlock2).ref;
1290
- }
1291
- function dumpRefs(refs, indent, escapeString2) {
1292
- if (!refs || refs.length === 0) {
1293
- return "";
1031
+ let type = "";
1032
+ if (t[i] === ":") {
1033
+ i++;
1034
+ type = t[i++] ?? "";
1035
+ if (t[i] && t[i].startsWith("[") && t[i].endsWith("]")) {
1036
+ i++;
1037
+ }
1294
1038
  }
1295
- let out = "";
1296
- for (const r of refs) {
1297
- out += `${indent}ref ${r.predicate} "${escapeString2(r.target)}"`;
1298
- out += r.note ? ` {
1299
- ${indent} note "${escapeString2(r.note)}"
1300
- ${indent}}
1301
- ` : "\n";
1302
- }
1303
- return out;
1304
- }
1305
- function refTargetToSourceRef(target) {
1306
- const m = /^(urn:[^#]+)(?:#(.+))?$/.exec(target);
1307
- if (!m) {
1039
+ const blockToken = t[i++];
1040
+ if (blockToken === void 0 || !blockToken.startsWith("{")) {
1308
1041
  return null;
1309
1042
  }
1310
- const anchor = m[2];
1311
- if (!anchor) {
1312
- return { doc: target, clause: "" };
1043
+ return { name, type, block: unwrapBlock(blockToken), next: i };
1044
+ }
1045
+ function parseFormField(name, block, type) {
1046
+ const field = {
1047
+ name,
1048
+ type: type || "string",
1049
+ typeDeclared: !!type,
1050
+ label: "",
1051
+ definition: "",
1052
+ unit: "",
1053
+ symbol: "",
1054
+ verdict: "",
1055
+ targets: [],
1056
+ dimension: "",
1057
+ enumRef: "",
1058
+ pattern: "",
1059
+ required: false,
1060
+ requiredWhen: "",
1061
+ refs: [],
1062
+ measurementMethod: "",
1063
+ calculationId: null,
1064
+ calculationBindings: [],
1065
+ derivation: "",
1066
+ evaluation: null,
1067
+ values: [],
1068
+ trueLabel: "",
1069
+ falseLabel: "",
1070
+ enumValues: [],
1071
+ defaultValue: "",
1072
+ hasDefault: false,
1073
+ referenceIds: [],
1074
+ fieldReferences: [],
1075
+ specificationReference: "",
1076
+ applicability: [],
1077
+ sourceDiscrepancy: null,
1078
+ fields: [],
1079
+ itemsType: "",
1080
+ subformRef: null
1081
+ };
1082
+ if (!block || !block.trim()) {
1083
+ return field;
1313
1084
  }
1314
- if (anchor.startsWith("clause-")) {
1315
- const rest = anchor.slice("clause-".length);
1316
- const slash = rest.indexOf("/");
1317
- if (slash >= 0) {
1318
- return {
1319
- doc: m[1],
1320
- clause: rest.slice(0, slash),
1321
- fragment: rest.slice(slash + 1)
1322
- };
1085
+ const t = tokenize(block);
1086
+ let i = 0;
1087
+ while (i < t.length) {
1088
+ const cmd = t[i++];
1089
+ if (i >= t.length) {
1090
+ break;
1091
+ }
1092
+ if (cmd === "label") {
1093
+ field.label = stripWrapping(t[i++]);
1094
+ } else if (cmd === "definition") {
1095
+ field.definition = stripWrapping(t[i++]);
1096
+ } else if (cmd === "description") {
1097
+ field.description = stripWrapping(t[i++]);
1098
+ } else if (cmd === "type") {
1099
+ field.type = stripWrapping(t[i++]);
1100
+ field.typeDeclared = true;
1101
+ } else if (cmd === "unit") {
1102
+ field.unit = stripWrapping(t[i++]);
1103
+ } else if (cmd === "symbol") {
1104
+ field.symbol = stripWrapping(t[i++]);
1105
+ } else if (cmd === "verdict") {
1106
+ field.verdict = stripWrapping(t[i++]);
1107
+ } else if (cmd === "targets") {
1108
+ field.targets = tokenizePackage(t[i++]).map(stripWrapping);
1109
+ } else if (cmd === "dimension") {
1110
+ field.dimension = stripWrapping(t[i++]);
1111
+ } else if (cmd === "enum") {
1112
+ field.enumRef = stripWrapping(t[i++]);
1113
+ } else if (cmd === "pattern") {
1114
+ field.pattern = stripWrapping(t[i++]);
1115
+ } else if (cmd === "scope") {
1116
+ field.scope = stripWrapping(t[i++]);
1117
+ } else if (cmd === "examples") {
1118
+ field.examples = stripWrapping(t[i++]);
1119
+ } else if (cmd === "bind") {
1120
+ field.bind = stripWrapping(t[i++]);
1121
+ } else if (cmd === "required") {
1122
+ field.required = stripWrapping(t[i++]) === "true";
1123
+ } else if (cmd === "required_when") {
1124
+ const read = readValueToken(t, i);
1125
+ field.requiredWhen = stripWrapping(read.text);
1126
+ i = read.next;
1127
+ } else if (cmd === "measurement_method") {
1128
+ field.measurementMethod = stripWrapping(t[i++]);
1129
+ } else if (cmd === "calculation") {
1130
+ const read = readValueToken(t, i);
1131
+ field.calculationId = stripWrapping(read.text);
1132
+ i = read.next;
1133
+ } else if (cmd === "calculation_bindings") {
1134
+ field.calculationBindings = parseCalculationBindings(unwrapBlock(t[i++]));
1135
+ } else if (cmd === "derivation") {
1136
+ field.derivation = stripWrapping(t[i++]);
1137
+ } else if (cmd === "evaluation") {
1138
+ field.evaluation = parseEvaluation(unwrapBlock(t[i++]));
1139
+ } else if (cmd === "values") {
1140
+ const read = readBalanced(t, i);
1141
+ field.values = parseValueEntries(read.text);
1142
+ i = read.next;
1143
+ } else if (cmd === "default") {
1144
+ field.defaultValue = stripWrapping(t[i++]);
1145
+ field.hasDefault = true;
1146
+ } else if (cmd === "true_label") {
1147
+ field.trueLabel = stripWrapping(t[i++]);
1148
+ } else if (cmd === "false_label") {
1149
+ field.falseLabel = stripWrapping(t[i++]);
1150
+ } else if (cmd === "enum_values") {
1151
+ field.enumValues = parseValueEntries(t[i++]);
1152
+ } else if (cmd === "min_items") {
1153
+ const raw = stripWrapping(t[i++]);
1154
+ const n = parseInt(raw, 10);
1155
+ field.minItems = isNaN(n) ? raw : n;
1156
+ } else if (cmd === "max_items") {
1157
+ const raw = stripWrapping(t[i++]);
1158
+ const n = parseInt(raw, 10);
1159
+ field.maxItems = isNaN(n) ? raw : n;
1160
+ } else if (cmd === "items") {
1161
+ const iblock = unwrapBlock(t[i++]);
1162
+ const it = tokenize(iblock);
1163
+ const typeParts = [];
1164
+ let k = 0;
1165
+ while (k < it.length && it[k] !== "fields") {
1166
+ if (it[k] === "unit" && k + 1 < it.length) {
1167
+ field.itemsUnit = stripWrapping(it[k + 1]);
1168
+ k += 2;
1169
+ } else {
1170
+ typeParts.push(it[k++]);
1171
+ }
1172
+ }
1173
+ field.itemsType = typeParts.join(" ");
1174
+ if (it[k] === "fields") {
1175
+ k++;
1176
+ if (k < it.length) {
1177
+ field.fields = parseNestedFields(unwrapBlock(it[k]));
1178
+ }
1179
+ }
1180
+ } else if (cmd === "series") {
1181
+ field.series = parseSeriesDecl(unwrapBlock(t[i++]));
1182
+ } else if (cmd === "fields") {
1183
+ field.fields = parseNestedFields(unwrapBlock(t[i++]));
1184
+ } else if (cmd === "subform_ref") {
1185
+ const subformId = stripWrapping(t[i++]);
1186
+ const refBlock = i < t.length ? unwrapBlock(t[i++]) : "";
1187
+ field.subformRef = parseSubformRef(subformId, refBlock);
1188
+ if (!field.type || field.type === "string") {
1189
+ field.type = "array";
1190
+ }
1191
+ } else if (cmd === "reference") {
1192
+ field.referenceIds = tokenizePackage(t[i++]).map(stripWrapping);
1193
+ } else if (cmd === "references") {
1194
+ field.fieldReferences = parseRoleReferences(unwrapBlock(t[i++]));
1195
+ } else if (cmd === "ref") {
1196
+ const r = parseRef(t, i, stripWrapping, unwrapBlock);
1197
+ if (!foldRefIntoLegacy(field, r.ref)) {
1198
+ field.refs.push(r.ref);
1199
+ }
1200
+ i = r.next;
1201
+ } else if (cmd === "corresponds") {
1202
+ const cc = parseCorresponds(t, i, stripWrapping);
1203
+ (field.correspondences ??= []).push(cc.corr);
1204
+ i = cc.next;
1205
+ } else if (cmd === "specification_reference") {
1206
+ field.specificationReference = stripWrapping(t[i++]);
1207
+ } else if (cmd === "applicability") {
1208
+ field.applicability = parseApplicability(unwrapBlock(t[i++]));
1209
+ } else if (cmd === "source_discrepancy") {
1210
+ field.sourceDiscrepancy = parseSourceDiscrepancy(unwrapBlock(t[i++]));
1211
+ } else {
1212
+ unwrapBlock(t[i++]);
1323
1213
  }
1324
- return { doc: m[1], clause: rest };
1325
1214
  }
1326
- return { doc: target, clause: "" };
1215
+ return field;
1327
1216
  }
1328
- function foldRefIntoLegacy(el, ref) {
1329
- if (ref.predicate === "derives-from") {
1330
- const roleChannel = el.fieldReferences ?? el.formReferences;
1331
- const hasProvenanceSlot = "source" in el || "sourceRef" in el || el.sourceRefs !== void 0;
1332
- if (roleChannel && !hasProvenanceSlot) {
1333
- roleChannel.push({ urn: ref.target, role: "source" });
1334
- return true;
1217
+ function parseCalculationBindings(block) {
1218
+ const out = [];
1219
+ const t = tokenize(block);
1220
+ let i = 0;
1221
+ while (i < t.length) {
1222
+ const key = stripColon(t[i++]);
1223
+ if (i >= t.length) {
1224
+ break;
1335
1225
  }
1336
- const b = refTargetToSourceRef(ref.target);
1337
- if (!b) {
1338
- return false;
1226
+ if (t[i] === ":") {
1227
+ i++;
1339
1228
  }
1340
- (el.sourceRefs ??= []).push(b);
1341
- if ("source" in el && !el.source) {
1342
- el.source = b;
1229
+ if (i < t.length) {
1230
+ out.push({ inputName: key, pathExpr: stripWrapping(t[i++]) });
1343
1231
  }
1344
- if ("sourceRef" in el && !el.sourceRef) {
1345
- el.sourceRef = b;
1232
+ }
1233
+ return out;
1234
+ }
1235
+ function parseEvaluation(block) {
1236
+ const rule = { rule: "", condition: "", referenceId: null };
1237
+ const t = tokenize(block);
1238
+ let i = 0;
1239
+ while (i < t.length) {
1240
+ const cmd = t[i++];
1241
+ if (i >= t.length) {
1242
+ break;
1346
1243
  }
1347
- if ("reference" in el && !el.reference) {
1348
- el.reference = b.doc;
1244
+ if (cmd === "rule") {
1245
+ rule.rule = stripWrapping(t[i++]);
1246
+ } else if (cmd === "verdict") {
1247
+ rule.verdict = stripWrapping(t[i++]);
1248
+ } else if (cmd === "op") {
1249
+ rule.op = stripWrapping(t[i++]);
1250
+ } else if (cmd === "limit") {
1251
+ rule.limit = stripWrapping(t[i++]);
1252
+ } else if (cmd === "condition") {
1253
+ rule.condition = stripWrapping(t[i++]);
1254
+ } else if (cmd === "reference") {
1255
+ const ids = tokenizePackage(t[i++]).map(stripWrapping);
1256
+ rule.referenceId = ids[0] ?? null;
1257
+ } else if (cmd === "specification_reference") {
1258
+ rule.specificationReference = stripWrapping(t[i++]);
1259
+ } else if (cmd === "source_discrepancy") {
1260
+ rule.sourceDiscrepancy = parseSourceDiscrepancy(unwrapBlock(t[i++]));
1261
+ } else {
1262
+ unwrapBlock(t[i++]);
1349
1263
  }
1350
- return true;
1351
1264
  }
1352
- if (ref.predicate === "cites") {
1353
- if (el.fieldReferences) {
1354
- el.fieldReferences.push({ urn: ref.target, role: "reference" });
1355
- } else if (el.formReferences) {
1356
- el.formReferences.push({ urn: ref.target, role: "reference" });
1357
- } else if (el.referenceIds) {
1358
- el.referenceIds.push(ref.target);
1359
- }
1360
- return true;
1361
- }
1362
- const CITATION_ROLES = [
1363
- "requirement",
1364
- "test-procedure",
1365
- "calculation",
1366
- "report-format",
1367
- "method"
1368
- ];
1369
- if (CITATION_ROLES.includes(ref.predicate)) {
1370
- const channel = el.fieldReferences ?? el.formReferences;
1371
- if (!channel) {
1372
- return false;
1373
- }
1374
- channel.push({ urn: ref.target, role: ref.predicate });
1375
- return true;
1376
- }
1377
- return false;
1378
- }
1379
- function dumpSourceRefAsRef(src, indent, escapeString2) {
1380
- if (src.doc && src.doc.startsWith("urn:")) {
1381
- const anchor = `${src.doc}${src.clause ? "#clause-" + src.clause : ""}${src.fragment ? "/" + src.fragment : ""}`;
1382
- return `${indent}ref derives-from "${escapeString2(anchor)}"
1383
- `;
1384
- }
1385
- return `${indent}source { doc "${escapeString2(src.doc ?? "")}" clause "${escapeString2(String(src.clause ?? ""))}"` + (src.fragment ? ` fragment "${escapeString2(src.fragment)}"` : "") + " }\n";
1386
- }
1387
-
1388
- // src/ser-des/config/correspondence.ts
1389
- function parseCorresponds(t, i, stripWrapping2) {
1390
- if (t[i] === void 0) {
1391
- throw new Error(
1392
- "Parsing error: corresponds: Expecting value for corresponds (the scheme and the concept)"
1393
- );
1394
- }
1395
- const scheme = stripWrapping2(t[i++]);
1396
- if (t[i] === void 0) {
1397
- throw new Error(
1398
- "Parsing error: corresponds: Expecting value for corresponds (the concept)"
1399
- );
1400
- }
1401
- const corr = {
1402
- scheme,
1403
- concept: stripWrapping2(t[i++]),
1404
- projections: []
1405
- };
1406
- if (i < t.length && t[i].startsWith("{")) {
1407
- const block = unwrapBlock(t[i++]);
1408
- forEachEntry(
1409
- block,
1410
- (keyword, value, peek) => {
1411
- if (keyword === "projection") {
1412
- const codec = stripWrapping2(value());
1413
- const entries = [];
1414
- const next = peek();
1415
- if (next && next.startsWith("{")) {
1416
- forEachEntry(
1417
- unwrapBlock(value()),
1418
- (k, kv) => {
1419
- entries.push({ key: k, value: stripWrapping2(kv()) });
1420
- return true;
1421
- },
1422
- { construct: "corresponds.projection", id: codec }
1423
- );
1424
- }
1425
- corr.projections.push({ codec, entries });
1426
- return true;
1427
- }
1428
- return false;
1429
- },
1430
- { construct: "corresponds", id: corr.scheme }
1431
- );
1432
- }
1433
- return { corr, next: i };
1434
- }
1435
- function parseCorrespondsFromReaders(value, peek, stripWrapping2) {
1436
- const parts = [value(), value()];
1437
- const next = peek();
1438
- if (next && next.startsWith("{")) {
1439
- parts.push(value());
1440
- }
1441
- return parseCorresponds(parts, 0, stripWrapping2).corr;
1442
- }
1443
- function dumpCorrespondences(corrs, indent, escapeString2, dumpBareSafe2) {
1444
- if (!corrs || corrs.length === 0) {
1445
- return "";
1446
- }
1447
- let out = "";
1448
- for (const c of corrs) {
1449
- out += `${indent}corresponds ${dumpBareSafe2(c.scheme)} "${escapeString2(c.concept)}"`;
1450
- if (c.projections.length === 0) {
1451
- out += "\n";
1452
- continue;
1453
- }
1454
- out += " {\n";
1455
- for (const p of c.projections) {
1456
- out += `${indent} projection ${dumpBareSafe2(p.codec)} {`;
1457
- for (const e of p.entries) {
1458
- out += ` ${dumpBareSafe2(e.key)} ${dumpBareSafe2(e.value)}`;
1459
- }
1460
- out += " }\n";
1461
- }
1462
- out += `${indent}}
1463
- `;
1464
- }
1465
- return out;
1265
+ return rule;
1466
1266
  }
1467
-
1468
- // src/ser-des/config/series.ts
1469
- function parseSeriesDecl(block) {
1470
- const decl = { axes: [], cellSymbol: "", cellUnit: "" };
1267
+ function parseNestedFields(block) {
1268
+ const out = [];
1471
1269
  const t = tokenize(block);
1472
1270
  let i = 0;
1473
1271
  while (i < t.length) {
1474
1272
  const cmd = t[i++];
1475
- if (cmd !== "axis" && cmd !== "cell") {
1273
+ if (cmd !== "field") {
1476
1274
  if (i < t.length) {
1477
1275
  unwrapBlock(t[i - 1]);
1478
1276
  }
1479
1277
  continue;
1480
1278
  }
1481
- if (cmd === "axis") {
1482
- const axis = {
1483
- id: stripWrapping(t[i++]),
1484
- unit: "",
1485
- type: "",
1486
- role: ""
1487
- };
1488
- if (i < t.length && t[i].startsWith("{")) {
1489
- const ablock = unwrapBlock(t[i++]);
1490
- const at = tokenize(ablock);
1491
- let j = 0;
1492
- while (j < at.length) {
1493
- const ac = at[j++];
1494
- if (j >= at.length) {
1495
- break;
1496
- }
1497
- if (ac === "unit") {
1498
- axis.unit = stripWrapping(at[j++]);
1499
- } else if (ac === "type") {
1500
- axis.type = stripWrapping(at[j++]);
1501
- } else if (ac === "role") {
1502
- axis.role = stripWrapping(at[j++]);
1503
- } else {
1504
- unwrapBlock(at[j++]);
1505
- }
1506
- }
1507
- }
1508
- decl.axes.push(axis);
1509
- } else {
1510
- const cblock = unwrapBlock(t[i++]);
1511
- const ct = tokenize(cblock);
1512
- let j = 0;
1513
- while (j < ct.length) {
1514
- const cc = ct[j++];
1515
- if (j >= ct.length) {
1516
- break;
1517
- }
1518
- if (cc === "symbol") {
1519
- decl.cellSymbol = stripWrapping(ct[j++]);
1520
- } else if (cc === "unit") {
1521
- decl.cellUnit = stripWrapping(ct[j++]);
1522
- } else {
1523
- unwrapBlock(ct[j++]);
1524
- }
1525
- }
1526
- }
1527
- }
1528
- return decl;
1529
- }
1530
- function dumpSeriesDecl(decl) {
1531
- let out = "series { ";
1532
- for (const a of decl.axes) {
1533
- out += "axis " + a.id + " { ";
1534
- if (a.unit) {
1535
- out += 'unit "' + escapeString(a.unit) + '" ';
1536
- }
1537
- if (a.type) {
1538
- out += "type " + a.type + " ";
1539
- }
1540
- if (a.role) {
1541
- out += "role " + a.role + " ";
1279
+ const head = readFieldHead(t, i);
1280
+ if (!head) {
1281
+ break;
1542
1282
  }
1543
- out += "} ";
1544
- }
1545
- out += "cell { ";
1546
- if (decl.cellSymbol) {
1547
- out += "symbol " + decl.cellSymbol + " ";
1548
- }
1549
- if (decl.cellUnit) {
1550
- out += 'unit "' + escapeString(decl.cellUnit) + '" ';
1283
+ out.push(parseFormField(head.name, head.block, head.type || void 0));
1284
+ i = head.next;
1551
1285
  }
1552
- out += "} }";
1553
1286
  return out;
1554
1287
  }
1555
-
1556
- // src/ser-des/config/sourceDiscrepancy.ts
1557
- var VALID_RESOLUTIONS = ["follows_clause_x", "annotated_only"];
1558
- function parseSourceDiscrepancy(block) {
1559
- const sd = {
1560
- summary: "",
1561
- sources: [],
1562
- resolution: "",
1563
- rationale: ""
1564
- };
1288
+ function parseApplicability(block) {
1289
+ const entries = [];
1565
1290
  const t = tokenize(block);
1566
1291
  let i = 0;
1567
1292
  while (i < t.length) {
1568
- const cmd = t[i++];
1293
+ const dimension = stripColon(t[i++]);
1569
1294
  if (i >= t.length) {
1570
1295
  break;
1571
1296
  }
1572
- if (cmd === "summary") {
1573
- sd.summary = stripWrapping(t[i++]);
1574
- } else if (cmd === "sources") {
1575
- sd.sources = tokenize(stripWrapping(t[i++])).map(stripWrapping).filter((s) => s.length > 0);
1576
- } else if (cmd === "resolution") {
1577
- const r = stripWrapping(t[i++]);
1578
- if (!VALID_RESOLUTIONS.includes(r)) {
1579
- throw new Error(
1580
- `Parsing error: source_discrepancy: Unknown resolution ${r} (valid: ${VALID_RESOLUTIONS.join(
1581
- ", "
1582
- )})`
1583
- );
1584
- }
1585
- sd.resolution = r;
1586
- } else if (cmd === "rationale") {
1587
- sd.rationale = stripWrapping(t[i++]);
1588
- } else {
1589
- unwrapBlock(t[i++]);
1297
+ if (t[i] === ":") {
1298
+ i++;
1299
+ }
1300
+ if (i < t.length) {
1301
+ const read = readBalanced(t, i);
1302
+ i = read.next;
1303
+ const trimmed = read.text.trim();
1304
+ let entry;
1305
+ if (trimmed.startsWith("[")) {
1306
+ const inner = trimmed.slice(1, trimmed.lastIndexOf("]"));
1307
+ const values = inner.split(/[,\s]+/).filter((s) => s.length > 0);
1308
+ entry = { dimension, values, mapping: null, match: null };
1309
+ } else if (trimmed.startsWith("{")) {
1310
+ const inner = trimmed.slice(1, -1);
1311
+ const mapping = {};
1312
+ for (const pair of inner.split(/[,\n]+/).map((s) => s.trim()).filter((s) => s)) {
1313
+ const m = pair.match(/^(\w+)\s*:\s*(.+)$/);
1314
+ if (m) {
1315
+ mapping[m[1]] = m[2].trim();
1316
+ }
1317
+ }
1318
+ entry = { dimension, values: [], mapping, match: null };
1319
+ } else {
1320
+ entry = {
1321
+ dimension,
1322
+ values: [stripWrapping(trimmed)],
1323
+ mapping: null,
1324
+ match: null
1325
+ };
1326
+ }
1327
+ if (!entry.mapping && t[i] === "match") {
1328
+ i++;
1329
+ const mode = stripWrapping(t[i++] ?? "");
1330
+ if (mode !== "any" && mode !== "all" && mode !== "exact") {
1331
+ throw new Error(
1332
+ `Parsing error: applicability: Unknown match ${mode} (valid: any, all, exact)`
1333
+ );
1334
+ }
1335
+ entry.match = mode;
1336
+ }
1337
+ entries.push(entry);
1590
1338
  }
1591
1339
  }
1592
- return sd;
1593
- }
1594
- function dumpSourceDiscrepancy(sd, indent) {
1595
- let out = indent + "source_discrepancy { ";
1596
- out += 'summary "' + escapeString(sd.summary) + '" ';
1597
- out += "sources { " + sd.sources.map((s) => '"' + escapeString(s) + '"').join(" ") + " } ";
1598
- out += "resolution " + sd.resolution + " ";
1599
- out += 'rationale "' + escapeString(sd.rationale) + '" ';
1600
- out += "}";
1601
- return out;
1602
- }
1603
-
1604
- // src/ser-des/config/field-parser.ts
1605
- function readValueToken(t, i) {
1606
- const tok = t[i] ?? "";
1607
- if (!tok.startsWith("ocl{")) {
1608
- return { text: tok, next: i + 1 };
1609
- }
1610
- const delta = (s) => (s.match(/\{/g) || []).length - (s.match(/\}/g) || []).length;
1611
- let text = tok;
1612
- let depth = delta(tok);
1613
- let j = i + 1;
1614
- while (depth > 0 && j < t.length) {
1615
- const nt = t[j++];
1616
- depth += delta(nt);
1617
- text += " " + nt;
1618
- }
1619
- return { text, next: j };
1340
+ return entries;
1620
1341
  }
1621
- function parseValueEntries(raw) {
1622
- const inner = raw.trim().replace(/^[[{]/, "").replace(/[\]}]$/, "");
1623
- const t = tokenizePackage(inner);
1624
- const out = [];
1625
- let i = 0;
1626
- while (i < t.length) {
1627
- const entry = stripWrapping(t[i++].replace(/,$/, ""));
1628
- if (!entry) {
1629
- continue;
1630
- }
1631
- if (i < t.length && t[i].startsWith("{")) {
1632
- const lb = tokenizePackage(unwrapBlock(t[i++]));
1633
- let label = "";
1634
- for (let k = 0; k + 1 < lb.length; k += 2) {
1635
- if (lb[k] === "label") {
1636
- label = stripWrapping(lb[k + 1]);
1342
+ function parseSubformRef(subformId, block) {
1343
+ const ref = {
1344
+ subformId: stripWrapping(subformId),
1345
+ parameters: {},
1346
+ applicability: []
1347
+ };
1348
+ if (block && block.trim()) {
1349
+ const t = tokenize(block);
1350
+ let i = 0;
1351
+ while (i < t.length) {
1352
+ const cmd = t[i++];
1353
+ if (i < t.length) {
1354
+ if (cmd === "parameters") {
1355
+ const pblock = unwrapBlock(t[i++]);
1356
+ const pt = tokenize(pblock);
1357
+ let j = 0;
1358
+ while (j < pt.length) {
1359
+ const key = stripColon(pt[j++]);
1360
+ if (j < pt.length) {
1361
+ if (pt[j] === ":") {
1362
+ j++;
1363
+ }
1364
+ if (j < pt.length) {
1365
+ ref.parameters[key] = stripWrapping(pt[j++]);
1366
+ }
1367
+ }
1368
+ }
1369
+ } else if (cmd === "applicability") {
1370
+ ref.applicability = parseApplicability(unwrapBlock(t[i++]));
1371
+ } else {
1372
+ unwrapBlock(t[i++]);
1637
1373
  }
1638
1374
  }
1639
- out.push({ value: entry, label });
1640
- } else {
1641
- out.push(entry);
1642
1375
  }
1643
1376
  }
1644
- return out;
1377
+ return ref;
1645
1378
  }
1646
- function dumpValueEntry(e) {
1647
- if (typeof e === "string") {
1648
- return e;
1379
+ function dumpFormField(field, indent) {
1380
+ let out = "";
1381
+ if (field.subformRef && !field.name) {
1382
+ const sr = field.subformRef;
1383
+ out += indent + "subform_ref " + sr.subformId + " { ";
1384
+ const pkeys = Object.keys(sr.parameters);
1385
+ if (pkeys.length > 0) {
1386
+ out += "parameters { ";
1387
+ for (const k of pkeys) {
1388
+ out += k + ": " + sr.parameters[k] + " ";
1389
+ }
1390
+ out += "} ";
1391
+ }
1392
+ if (sr.applicability.length > 0) {
1393
+ out += "applicability { " + dumpApplicabilityEntries(sr.applicability) + "} ";
1394
+ }
1395
+ out += "}\n";
1396
+ return out;
1649
1397
  }
1650
- return e.value + ' { label "' + escapeString(e.label) + '" }';
1651
- }
1652
- function dumpBareSafe(v) {
1653
- return /[\s{}"]/.test(v) || v.endsWith(":") || v.startsWith("#") || v.startsWith("//") ? '"' + escapeString(v) + '"' : v;
1654
- }
1655
- function stripColon(x) {
1656
- return x.endsWith(":") ? x.slice(0, -1) : x;
1657
- }
1658
- function readBalanced(t, i) {
1659
- const first = t[i] ?? "";
1660
- if (!first.startsWith("[")) {
1661
- return { text: first, next: i + 1 };
1398
+ const inner = [];
1399
+ if (field.subformRef) {
1400
+ const sr = field.subformRef;
1401
+ let refLine = "subform_ref " + sr.subformId + " { ";
1402
+ const pkeys = Object.keys(sr.parameters);
1403
+ if (pkeys.length > 0) {
1404
+ refLine += "parameters { ";
1405
+ for (const k of pkeys) {
1406
+ refLine += k + ": " + sr.parameters[k] + " ";
1407
+ }
1408
+ refLine += "} ";
1409
+ }
1410
+ if (sr.applicability.length > 0) {
1411
+ refLine += "applicability { " + dumpApplicabilityEntries(sr.applicability) + "} ";
1412
+ }
1413
+ inner.push(refLine + "}");
1662
1414
  }
1663
- let text = first;
1664
- let j = i + 1;
1665
- while (!text.includes("]") && j < t.length) {
1666
- text += " " + t[j++];
1415
+ if (field.label) {
1416
+ inner.push('label "' + escapeString(field.label) + '"');
1667
1417
  }
1668
- return { text, next: j };
1669
- }
1670
- function subBlockTokens(block) {
1671
- return tokenizePackage(block).map((s) => s.replace(/^;+|;+$/g, "")).filter((s) => s.length > 0);
1672
- }
1673
- function readEntryTokens(value) {
1674
- if (value.startsWith("{")) {
1675
- return subBlockTokens(unwrapBlock(value)).flatMap((s) => s.split(",")).map((s) => stripWrapping(s.trim())).filter((s) => s.length > 0);
1418
+ if (field.definition) {
1419
+ inner.push('definition "' + escapeString(field.definition) + '"');
1676
1420
  }
1677
- const single = stripWrapping(value);
1678
- return single === "" ? [] : [single];
1679
- }
1680
- function readSource(block) {
1681
- const src = { doc: "", clause: "" };
1682
- const t = tokenize(block);
1683
- let i = 0;
1684
- while (i < t.length) {
1685
- const cmd = t[i++];
1686
- if (i >= t.length) {
1687
- break;
1688
- }
1689
- if (cmd === "doc") {
1690
- src.doc = stripWrapping(t[i++]);
1691
- } else if (cmd === "clause") {
1692
- src.clause = stripWrapping(t[i++]);
1693
- } else if (cmd === "fragment") {
1694
- src.fragment = stripWrapping(t[i++]);
1695
- } else {
1696
- unwrapBlock(t[i++]);
1697
- }
1421
+ if (field.description) {
1422
+ inner.push('description "' + escapeString(field.description) + '"');
1698
1423
  }
1699
- return src;
1700
- }
1701
- function readFieldHead(t, i) {
1702
- const name = t[i++];
1703
- if (name === void 0) {
1704
- return null;
1424
+ if (field.unit) {
1425
+ inner.push('unit "' + escapeString(field.unit) + '"');
1705
1426
  }
1706
- let type = "";
1707
- if (t[i] === ":") {
1708
- i++;
1709
- type = t[i++] ?? "";
1710
- if (t[i] && t[i].startsWith("[") && t[i].endsWith("]")) {
1711
- i++;
1712
- }
1427
+ if (field.symbol) {
1428
+ inner.push("symbol " + field.symbol);
1713
1429
  }
1714
- const blockToken = t[i++];
1715
- if (blockToken === void 0 || !blockToken.startsWith("{")) {
1716
- return null;
1430
+ if (field.verdict) {
1431
+ inner.push("verdict " + field.verdict);
1717
1432
  }
1718
- return { name, type, block: unwrapBlock(blockToken), next: i };
1719
- }
1720
- function parseFormField(name, block, type) {
1721
- const field = {
1722
- name,
1723
- type: type || "string",
1724
- typeDeclared: !!type,
1725
- label: "",
1726
- definition: "",
1727
- unit: "",
1728
- symbol: "",
1729
- verdict: "",
1730
- targets: [],
1731
- dimension: "",
1732
- enumRef: "",
1733
- pattern: "",
1734
- required: false,
1735
- requiredWhen: "",
1736
- refs: [],
1737
- measurementMethod: "",
1738
- calculationId: null,
1739
- calculationBindings: [],
1740
- derivation: "",
1741
- evaluation: null,
1742
- values: [],
1743
- trueLabel: "",
1744
- falseLabel: "",
1745
- enumValues: [],
1746
- defaultValue: "",
1747
- hasDefault: false,
1748
- referenceIds: [],
1749
- fieldReferences: [],
1750
- specificationReference: "",
1751
- applicability: [],
1752
- sourceDiscrepancy: null,
1753
- fields: [],
1754
- itemsType: "",
1755
- subformRef: null
1756
- };
1757
- if (!block || !block.trim()) {
1758
- return field;
1433
+ if (field.dimension) {
1434
+ inner.push("dimension " + field.dimension);
1759
1435
  }
1760
- const t = tokenize(block);
1761
- let i = 0;
1762
- while (i < t.length) {
1763
- const cmd = t[i++];
1764
- if (i >= t.length) {
1765
- break;
1766
- }
1767
- if (cmd === "label") {
1768
- field.label = stripWrapping(t[i++]);
1769
- } else if (cmd === "definition") {
1770
- field.definition = stripWrapping(t[i++]);
1771
- } else if (cmd === "description") {
1772
- field.description = stripWrapping(t[i++]);
1773
- } else if (cmd === "type") {
1774
- field.type = stripWrapping(t[i++]);
1775
- field.typeDeclared = true;
1776
- } else if (cmd === "unit") {
1777
- field.unit = stripWrapping(t[i++]);
1778
- } else if (cmd === "symbol") {
1779
- field.symbol = stripWrapping(t[i++]);
1780
- } else if (cmd === "verdict") {
1781
- field.verdict = stripWrapping(t[i++]);
1782
- } else if (cmd === "targets") {
1783
- field.targets = tokenizePackage(t[i++]).map(stripWrapping);
1784
- } else if (cmd === "dimension") {
1785
- field.dimension = stripWrapping(t[i++]);
1786
- } else if (cmd === "enum") {
1787
- field.enumRef = stripWrapping(t[i++]);
1788
- } else if (cmd === "pattern") {
1789
- field.pattern = stripWrapping(t[i++]);
1790
- } else if (cmd === "scope") {
1791
- field.scope = stripWrapping(t[i++]);
1792
- } else if (cmd === "examples") {
1793
- field.examples = stripWrapping(t[i++]);
1794
- } else if (cmd === "bind") {
1795
- field.bind = stripWrapping(t[i++]);
1796
- } else if (cmd === "required") {
1797
- field.required = stripWrapping(t[i++]) === "true";
1798
- } else if (cmd === "required_when") {
1799
- const read = readValueToken(t, i);
1800
- field.requiredWhen = stripWrapping(read.text);
1801
- i = read.next;
1802
- } else if (cmd === "measurement_method") {
1803
- field.measurementMethod = stripWrapping(t[i++]);
1804
- } else if (cmd === "calculation") {
1805
- const read = readValueToken(t, i);
1806
- field.calculationId = stripWrapping(read.text);
1807
- i = read.next;
1808
- } else if (cmd === "calculation_bindings") {
1809
- field.calculationBindings = parseCalculationBindings(unwrapBlock(t[i++]));
1810
- } else if (cmd === "derivation") {
1811
- field.derivation = stripWrapping(t[i++]);
1812
- } else if (cmd === "evaluation") {
1813
- field.evaluation = parseEvaluation(unwrapBlock(t[i++]));
1814
- } else if (cmd === "values") {
1815
- const read = readBalanced(t, i);
1816
- field.values = parseValueEntries(read.text);
1817
- i = read.next;
1818
- } else if (cmd === "default") {
1819
- field.defaultValue = stripWrapping(t[i++]);
1820
- field.hasDefault = true;
1821
- } else if (cmd === "true_label") {
1822
- field.trueLabel = stripWrapping(t[i++]);
1823
- } else if (cmd === "false_label") {
1824
- field.falseLabel = stripWrapping(t[i++]);
1825
- } else if (cmd === "enum_values") {
1826
- field.enumValues = parseValueEntries(t[i++]);
1827
- } else if (cmd === "min_items") {
1828
- const raw = stripWrapping(t[i++]);
1829
- const n = parseInt(raw, 10);
1830
- field.minItems = isNaN(n) ? raw : n;
1831
- } else if (cmd === "max_items") {
1832
- const raw = stripWrapping(t[i++]);
1833
- const n = parseInt(raw, 10);
1834
- field.maxItems = isNaN(n) ? raw : n;
1835
- } else if (cmd === "items") {
1836
- const iblock = unwrapBlock(t[i++]);
1837
- const it = tokenize(iblock);
1838
- const typeParts = [];
1839
- let k = 0;
1840
- while (k < it.length && it[k] !== "fields") {
1841
- if (it[k] === "unit" && k + 1 < it.length) {
1842
- field.itemsUnit = stripWrapping(it[k + 1]);
1843
- k += 2;
1844
- } else {
1845
- typeParts.push(it[k++]);
1846
- }
1847
- }
1848
- field.itemsType = typeParts.join(" ");
1849
- if (it[k] === "fields") {
1850
- k++;
1851
- if (k < it.length) {
1852
- field.fields = parseNestedFields(unwrapBlock(it[k]));
1853
- }
1436
+ if (field.enumRef) {
1437
+ inner.push("enum " + field.enumRef);
1438
+ }
1439
+ if (field.pattern) {
1440
+ inner.push('pattern "' + escapeString(field.pattern) + '"');
1441
+ }
1442
+ if (field.scope) {
1443
+ inner.push("scope " + field.scope);
1444
+ }
1445
+ if (field.examples) {
1446
+ inner.push('examples "' + escapeString(field.examples) + '"');
1447
+ }
1448
+ if (field.bind) {
1449
+ inner.push("bind " + dumpBareSafe(field.bind));
1450
+ }
1451
+ if (field.required) {
1452
+ inner.push("required true");
1453
+ }
1454
+ if (field.requiredWhen) {
1455
+ inner.push("required_when " + dumpBareSafe(field.requiredWhen));
1456
+ }
1457
+ if (field.measurementMethod) {
1458
+ inner.push("measurement_method " + field.measurementMethod);
1459
+ }
1460
+ if (field.calculationId) {
1461
+ inner.push("calculation " + dumpBareSafe(field.calculationId));
1462
+ }
1463
+ if (field.calculationBindings.length > 0) {
1464
+ inner.push(
1465
+ "calculation_bindings { " + field.calculationBindings.map((b) => b.inputName + ": " + b.pathExpr).join(" ") + "}"
1466
+ );
1467
+ }
1468
+ if (field.derivation) {
1469
+ inner.push('derivation "' + escapeString(field.derivation) + '"');
1470
+ }
1471
+ if (field.evaluation) {
1472
+ let ev = 'evaluation { rule "' + escapeString(field.evaluation.rule) + '"';
1473
+ if (field.evaluation.verdict) {
1474
+ ev += " verdict " + field.evaluation.verdict;
1475
+ }
1476
+ if (field.evaluation.op) {
1477
+ ev += " op " + field.evaluation.op;
1478
+ }
1479
+ if (field.evaluation.limit) {
1480
+ ev += ' limit "' + escapeString(field.evaluation.limit) + '"';
1481
+ }
1482
+ if (field.evaluation.condition) {
1483
+ ev += ' condition "' + escapeString(field.evaluation.condition) + '"';
1484
+ }
1485
+ if (field.evaluation.referenceId) {
1486
+ ev += " reference { " + field.evaluation.referenceId + " }";
1487
+ }
1488
+ if (field.evaluation.specificationReference) {
1489
+ ev += ' specification_reference "' + escapeString(field.evaluation.specificationReference) + '"';
1490
+ }
1491
+ if (field.evaluation.sourceDiscrepancy) {
1492
+ ev += " " + dumpSourceDiscrepancy(field.evaluation.sourceDiscrepancy, "");
1493
+ }
1494
+ inner.push(ev + " }");
1495
+ }
1496
+ if (field.values.length > 0) {
1497
+ inner.push("values { " + field.values.map(dumpValueEntry).join(" ") + " }");
1498
+ }
1499
+ if (field.hasDefault) {
1500
+ inner.push("default " + dumpBareSafe(field.defaultValue));
1501
+ }
1502
+ if (field.trueLabel) {
1503
+ inner.push('true_label "' + escapeString(field.trueLabel) + '"');
1504
+ }
1505
+ if (field.falseLabel) {
1506
+ inner.push('false_label "' + escapeString(field.falseLabel) + '"');
1507
+ }
1508
+ if (field.enumValues.length > 0) {
1509
+ inner.push(
1510
+ "enum_values { " + field.enumValues.map(dumpValueEntry).join(" ") + " }"
1511
+ );
1512
+ }
1513
+ if (field.itemsType) {
1514
+ let itemsLine = "items { " + field.itemsType;
1515
+ if (field.itemsUnit) {
1516
+ itemsLine += ' unit "' + escapeString(field.itemsUnit) + '"';
1517
+ }
1518
+ inner.push(itemsLine + " }");
1519
+ }
1520
+ if (field.minItems !== void 0 && field.minItems !== null) {
1521
+ inner.push("min_items " + dumpBareSafe(String(field.minItems)));
1522
+ }
1523
+ if (field.maxItems !== void 0 && field.maxItems !== null) {
1524
+ inner.push("max_items " + dumpBareSafe(String(field.maxItems)));
1525
+ }
1526
+ if (field.series) {
1527
+ inner.push(dumpSeriesDecl(field.series));
1528
+ }
1529
+ if (field.applicability.length > 0) {
1530
+ inner.push(
1531
+ "applicability { " + dumpApplicabilityEntries(field.applicability) + "}"
1532
+ );
1533
+ }
1534
+ if (field.targets.length > 0) {
1535
+ inner.push("targets { " + field.targets.join(" ") + " }");
1536
+ }
1537
+ if (field.sourceRefs && field.sourceRefs.length > 0) {
1538
+ for (const s of field.sourceRefs) {
1539
+ inner.push(dumpSourceRefAsRef(s, "", escapeString).trimEnd());
1540
+ }
1541
+ }
1542
+ if (field.fieldReferences.length > 0) {
1543
+ for (const r of field.fieldReferences) {
1544
+ inner.push(
1545
+ "ref " + roleToPredicateForDump(r.role) + ' "' + escapeString(r.urn) + '"'
1546
+ );
1547
+ }
1548
+ }
1549
+ if (field.refs && field.refs.length > 0) {
1550
+ for (const r of field.refs) {
1551
+ inner.push(
1552
+ "ref " + r.predicate + ' "' + escapeString(r.target) + '"' + (r.note ? ' { note "' + escapeString(r.note) + '" }' : "")
1553
+ );
1554
+ }
1555
+ }
1556
+ if (field.correspondences && field.correspondences.length > 0) {
1557
+ inner.push(
1558
+ dumpCorrespondences(
1559
+ field.correspondences,
1560
+ "",
1561
+ escapeString,
1562
+ dumpBareSafe
1563
+ ).trimEnd()
1564
+ );
1565
+ }
1566
+ if (field.specificationReference) {
1567
+ inner.push(
1568
+ 'specification_reference "' + escapeString(field.specificationReference) + '"'
1569
+ );
1570
+ }
1571
+ if (field.sourceDiscrepancy) {
1572
+ inner.push(dumpSourceDiscrepancy(field.sourceDiscrepancy, ""));
1573
+ }
1574
+ if (field.fields.length > 0) {
1575
+ inner.push(
1576
+ "fields {\n" + field.fields.map((f) => dumpFormField(f, indent + " ")).join("") + indent + " }"
1577
+ );
1578
+ }
1579
+ if (field.referenceIds.length > 0) {
1580
+ inner.push("reference { " + field.referenceIds.join(" ") + " }");
1581
+ }
1582
+ const typeSpec = field.type && (field.type !== "string" || field.typeDeclared) ? " : " + field.type : "";
1583
+ if (inner.length === 0) {
1584
+ return indent + "field " + field.name + typeSpec + " { }\n";
1585
+ }
1586
+ if (inner.every((s) => !s.includes("\n"))) {
1587
+ return indent + "field " + field.name + typeSpec + " { " + inner.join(" ") + " }\n";
1588
+ }
1589
+ return indent + "field " + field.name + typeSpec + " {\n" + inner.map((s) => indent + " " + s + "\n").join("") + indent + "}\n";
1590
+ }
1591
+ function dumpApplicabilityEntries(entries) {
1592
+ let out = "";
1593
+ for (const a of entries) {
1594
+ if (a.mapping) {
1595
+ out += a.dimension + ": { ";
1596
+ const pairs = [];
1597
+ for (const [k, v] of Object.entries(a.mapping)) {
1598
+ pairs.push(k + ": " + v);
1854
1599
  }
1855
- } else if (cmd === "series") {
1856
- field.series = parseSeriesDecl(unwrapBlock(t[i++]));
1857
- } else if (cmd === "fields") {
1858
- field.fields = parseNestedFields(unwrapBlock(t[i++]));
1859
- } else if (cmd === "subform_ref") {
1860
- const subformId = stripWrapping(t[i++]);
1861
- const refBlock = i < t.length ? unwrapBlock(t[i++]) : "";
1862
- field.subformRef = parseSubformRef(subformId, refBlock);
1863
- if (!field.type || field.type === "string") {
1864
- field.type = "array";
1600
+ out += pairs.join(", ") + " ";
1601
+ out += "} ";
1602
+ } else {
1603
+ out += a.dimension + ": [" + a.values.join(", ") + "] ";
1604
+ if (a.match) {
1605
+ out += "match " + a.match + " ";
1865
1606
  }
1866
- } else if (cmd === "reference") {
1867
- field.referenceIds = tokenizePackage(t[i++]).map(stripWrapping);
1868
- } else if (cmd === "references") {
1869
- field.fieldReferences = parseRoleReferences(unwrapBlock(t[i++]));
1870
- } else if (cmd === "ref") {
1871
- const r = parseRef(t, i, stripWrapping, unwrapBlock);
1872
- if (!foldRefIntoLegacy(field, r.ref)) {
1873
- field.refs.push(r.ref);
1607
+ }
1608
+ }
1609
+ return out;
1610
+ }
1611
+ function parseRoleReferences(block) {
1612
+ const out = [];
1613
+ const t = tokenize(block);
1614
+ let i = 0;
1615
+ while (i < t.length) {
1616
+ const role = stripColon(t[i++]);
1617
+ if (!role) {
1618
+ break;
1619
+ }
1620
+ if (i < t.length && t[i] === ":") {
1621
+ i++;
1622
+ }
1623
+ if (i < t.length && t[i].startsWith("{")) {
1624
+ const urns = tokenize(unwrapBlock(t[i++])).map(stripWrapping).filter((s) => s.length > 0);
1625
+ for (const urn of urns) {
1626
+ out.push({ urn, role });
1874
1627
  }
1875
- i = r.next;
1876
- } else if (cmd === "corresponds") {
1877
- const cc = parseCorresponds(t, i, stripWrapping);
1878
- (field.correspondences ??= []).push(cc.corr);
1879
- i = cc.next;
1880
- } else if (cmd === "specification_reference") {
1881
- field.specificationReference = stripWrapping(t[i++]);
1882
- } else if (cmd === "applicability") {
1883
- field.applicability = parseApplicability(unwrapBlock(t[i++]));
1884
- } else if (cmd === "source_discrepancy") {
1885
- field.sourceDiscrepancy = parseSourceDiscrepancy(unwrapBlock(t[i++]));
1886
- } else {
1887
- unwrapBlock(t[i++]);
1888
1628
  }
1889
1629
  }
1890
- return field;
1891
- }
1892
- function parseCalculationBindings(block) {
1893
- const out = [];
1894
- const t = tokenize(block);
1895
- let i = 0;
1896
- while (i < t.length) {
1897
- const key = stripColon(t[i++]);
1898
- if (i >= t.length) {
1899
- break;
1900
- }
1901
- if (t[i] === ":") {
1902
- i++;
1630
+ return out;
1631
+ }
1632
+ function roleToPredicateForDump(role) {
1633
+ if (role === "source") {
1634
+ return "derives-from";
1635
+ }
1636
+ if (role === "reference") {
1637
+ return "cites";
1638
+ }
1639
+ return role;
1640
+ }
1641
+
1642
+ // src/ser-des/config/approval.ts
1643
+ var parseApproval = function(id, data) {
1644
+ const result = {
1645
+ id,
1646
+ name: "",
1647
+ modality: "",
1648
+ actorRef: "",
1649
+ approverRef: "",
1650
+ recordRefs: [],
1651
+ actor: null,
1652
+ approver: null,
1653
+ records: [],
1654
+ ref: [],
1655
+ source: null,
1656
+ _relations: {
1657
+ actor: "",
1658
+ approver: "",
1659
+ records: [],
1660
+ ref: []
1661
+ }
1662
+ };
1663
+ forEachEntry(
1664
+ data,
1665
+ (keyword, value) => {
1666
+ if (keyword === "modality") {
1667
+ result.modality = value();
1668
+ } else if (keyword === "name") {
1669
+ result.name = unwrapped(value);
1670
+ } else if (keyword === "actor") {
1671
+ result._relations.actor = value();
1672
+ } else if (keyword === "approve_by") {
1673
+ result._relations.approver = value();
1674
+ } else if (keyword === "approval_record") {
1675
+ result._relations.records = tokenizePackage(value());
1676
+ } else if (keyword === "reference") {
1677
+ result._relations.ref = tokenizePackage(value());
1678
+ } else if (keyword === "source") {
1679
+ result.source = readSource(unwrapBlock(value()));
1680
+ } else {
1681
+ return false;
1682
+ }
1683
+ return true;
1684
+ },
1685
+ { construct: "approval", id }
1686
+ );
1687
+ return (ctx) => {
1688
+ ctx.approvals[id] = result;
1689
+ return ctx;
1690
+ };
1691
+ };
1692
+ var resolveApproval = function(ctx, unresolved) {
1693
+ const { _relations, ...rest } = unresolved;
1694
+ const p = {
1695
+ ...rest,
1696
+ // The raw reference ids survive resolution even when they name no
1697
+ // declared construct — the linter (C143) and the dumper read these.
1698
+ actorRef: _relations.actor,
1699
+ approverRef: _relations.approver,
1700
+ recordRefs: [..._relations.records],
1701
+ records: [],
1702
+ ref: []
1703
+ };
1704
+ if (_relations.actor !== "") {
1705
+ p.actor = resolveFromContext(ctx, "roles", _relations.actor) ?? null;
1706
+ }
1707
+ if (_relations.approver !== "") {
1708
+ p.approver = resolveFromContext(ctx, "roles", _relations.approver) ?? null;
1709
+ }
1710
+ for (const id of _relations.records) {
1711
+ const r = resolveFromContext(ctx, "regs", id);
1712
+ if (r !== void 0) {
1713
+ p.records.push(r);
1903
1714
  }
1904
- if (i < t.length) {
1905
- out.push({ inputName: key, pathExpr: stripWrapping(t[i++]) });
1715
+ }
1716
+ for (const id of _relations.ref) {
1717
+ const r = resolveFromContext(ctx, "references", id);
1718
+ if (r !== void 0) {
1719
+ p.ref.push(r);
1906
1720
  }
1907
1721
  }
1908
- return out;
1909
- }
1910
- function parseEvaluation(block) {
1911
- const rule = { rule: "", condition: "", referenceId: null };
1912
- const t = tokenize(block);
1913
- let i = 0;
1914
- while (i < t.length) {
1915
- const cmd = t[i++];
1916
- if (i >= t.length) {
1917
- break;
1722
+ return p;
1723
+ };
1724
+ var dumpApproval = function(approval) {
1725
+ let out = "approval " + approval.id + " {\n";
1726
+ out += ' name "' + escapeString(approval.name) + '"\n';
1727
+ if (approval.actorRef) {
1728
+ out += " actor " + approval.actorRef + "\n";
1729
+ }
1730
+ if (approval.modality !== "") {
1731
+ out += " modality " + approval.modality + "\n";
1732
+ }
1733
+ if (approval.approverRef) {
1734
+ out += " approve_by " + approval.approverRef + "\n";
1735
+ }
1736
+ if (approval.recordRefs.length > 0) {
1737
+ out += " approval_record {\n";
1738
+ for (const id of approval.recordRefs) {
1739
+ out += " " + id + "\n";
1918
1740
  }
1919
- if (cmd === "rule") {
1920
- rule.rule = stripWrapping(t[i++]);
1921
- } else if (cmd === "verdict") {
1922
- rule.verdict = stripWrapping(t[i++]);
1923
- } else if (cmd === "op") {
1924
- rule.op = stripWrapping(t[i++]);
1925
- } else if (cmd === "limit") {
1926
- rule.limit = stripWrapping(t[i++]);
1927
- } else if (cmd === "condition") {
1928
- rule.condition = stripWrapping(t[i++]);
1929
- } else if (cmd === "reference") {
1930
- const ids = tokenizePackage(t[i++]).map(stripWrapping);
1931
- rule.referenceId = ids[0] ?? null;
1932
- } else if (cmd === "specification_reference") {
1933
- rule.specificationReference = stripWrapping(t[i++]);
1934
- } else if (cmd === "source_discrepancy") {
1935
- rule.sourceDiscrepancy = parseSourceDiscrepancy(unwrapBlock(t[i++]));
1936
- } else {
1937
- unwrapBlock(t[i++]);
1741
+ out += " }\n";
1742
+ }
1743
+ if (approval.ref.length > 0) {
1744
+ out += " reference {\n";
1745
+ for (const r of approval.ref) {
1746
+ out += " " + r.id + "\n";
1938
1747
  }
1748
+ out += " }\n";
1939
1749
  }
1940
- return rule;
1941
- }
1942
- function parseNestedFields(block) {
1943
- const out = [];
1944
- const t = tokenize(block);
1945
- let i = 0;
1946
- while (i < t.length) {
1947
- const cmd = t[i++];
1948
- if (cmd !== "field") {
1949
- if (i < t.length) {
1950
- unwrapBlock(t[i - 1]);
1951
- }
1952
- continue;
1750
+ if (approval.source && (approval.source.doc || approval.source.clause)) {
1751
+ out += " source {\n";
1752
+ if (approval.source.doc) {
1753
+ out += ' doc "' + escapeString(approval.source.doc) + '"\n';
1953
1754
  }
1954
- const head = readFieldHead(t, i);
1955
- if (!head) {
1956
- break;
1755
+ if (approval.source.clause) {
1756
+ out += ' clause "' + escapeString(approval.source.clause) + '"\n';
1957
1757
  }
1958
- out.push(parseFormField(head.name, head.block, head.type || void 0));
1959
- i = head.next;
1758
+ out += " }\n";
1960
1759
  }
1760
+ out += "}\n";
1961
1761
  return out;
1962
- }
1963
- function parseApplicability(block) {
1964
- const entries = [];
1965
- const t = tokenize(block);
1966
- let i = 0;
1967
- while (i < t.length) {
1968
- const dimension = stripColon(t[i++]);
1969
- if (i >= t.length) {
1970
- break;
1971
- }
1972
- if (t[i] === ":") {
1973
- i++;
1974
- }
1975
- if (i < t.length) {
1976
- const read = readBalanced(t, i);
1977
- i = read.next;
1978
- const trimmed = read.text.trim();
1979
- let entry;
1980
- if (trimmed.startsWith("[")) {
1981
- const inner = trimmed.slice(1, trimmed.lastIndexOf("]"));
1982
- const values = inner.split(/[,\s]+/).filter((s) => s.length > 0);
1983
- entry = { dimension, values, mapping: null, match: null };
1984
- } else if (trimmed.startsWith("{")) {
1985
- const inner = trimmed.slice(1, -1);
1986
- const mapping = {};
1987
- for (const pair of inner.split(/[,\n]+/).map((s) => s.trim()).filter((s) => s)) {
1988
- const m = pair.match(/^(\w+)\s*:\s*(.+)$/);
1989
- if (m) {
1990
- mapping[m[1]] = m[2].trim();
1991
- }
1992
- }
1993
- entry = { dimension, values: [], mapping, match: null };
1762
+ };
1763
+
1764
+ // src/ser-des/config/data.ts
1765
+ var parseEnum = (id, data) => {
1766
+ const result = {
1767
+ id,
1768
+ values: []
1769
+ };
1770
+ forEachEntry(
1771
+ data,
1772
+ (_vid, value) => {
1773
+ result.values.push(parseEnumValue(_vid, value()));
1774
+ return true;
1775
+ },
1776
+ { construct: "enum", id }
1777
+ );
1778
+ return (ctx) => {
1779
+ ctx.enums[id] = result;
1780
+ return ctx;
1781
+ };
1782
+ };
1783
+ var parseEnumValue = (id, data) => {
1784
+ const ev = {
1785
+ id,
1786
+ value: ""
1787
+ };
1788
+ forEachEntry(
1789
+ data,
1790
+ (command, value) => {
1791
+ if (command === "definition") {
1792
+ ev.value = unwrapped(value);
1994
1793
  } else {
1995
- entry = {
1996
- dimension,
1997
- values: [stripWrapping(trimmed)],
1998
- mapping: null,
1999
- match: null
2000
- };
2001
- }
2002
- if (!entry.mapping && t[i] === "match") {
2003
- i++;
2004
- const mode = stripWrapping(t[i++] ?? "");
2005
- if (mode !== "any" && mode !== "all" && mode !== "exact") {
2006
- throw new Error(
2007
- `Parsing error: applicability: Unknown match ${mode} (valid: any, all, exact)`
2008
- );
2009
- }
2010
- entry.match = mode;
1794
+ return false;
2011
1795
  }
2012
- entries.push(entry);
1796
+ return true;
1797
+ },
1798
+ { construct: "enum value", id }
1799
+ );
1800
+ return ev;
1801
+ };
1802
+ var parseRegistry = function(id, data) {
1803
+ const result = {
1804
+ id,
1805
+ title: "",
1806
+ data: null,
1807
+ _relations: {
1808
+ data: ""
2013
1809
  }
2014
- }
2015
- return entries;
2016
- }
2017
- function parseSubformRef(subformId, block) {
2018
- const ref = {
2019
- subformId: stripWrapping(subformId),
2020
- parameters: {},
2021
- applicability: []
2022
1810
  };
2023
- if (block && block.trim()) {
2024
- const t = tokenize(block);
2025
- let i = 0;
2026
- while (i < t.length) {
2027
- const cmd = t[i++];
2028
- if (i < t.length) {
2029
- if (cmd === "parameters") {
2030
- const pblock = unwrapBlock(t[i++]);
2031
- const pt = tokenize(pblock);
2032
- let j = 0;
2033
- while (j < pt.length) {
2034
- const key = stripColon(pt[j++]);
2035
- if (j < pt.length) {
2036
- if (pt[j] === ":") {
2037
- j++;
2038
- }
2039
- if (j < pt.length) {
2040
- ref.parameters[key] = stripWrapping(pt[j++]);
2041
- }
1811
+ forEachEntry(
1812
+ data,
1813
+ (command, value) => {
1814
+ if (command === "title") {
1815
+ result.title = unwrapped(value);
1816
+ } else if (command === "data_class") {
1817
+ result._relations.data = value();
1818
+ } else {
1819
+ return false;
1820
+ }
1821
+ return true;
1822
+ },
1823
+ { construct: "registry", id }
1824
+ );
1825
+ return (ctx) => {
1826
+ ctx.regs[id] = result;
1827
+ return ctx;
1828
+ };
1829
+ };
1830
+ var parseDataClass = function(id, data) {
1831
+ const result = {
1832
+ id,
1833
+ attributes: []
1834
+ };
1835
+ forEachAttribute(
1836
+ data,
1837
+ (basic, details) => {
1838
+ if (basic.startsWith("ref ")) {
1839
+ const m = basic.match(/^ref\s+(\S+)\s+"([^"]*)"$/);
1840
+ if (m) {
1841
+ const ref = { predicate: m[1], target: m[2] };
1842
+ if (details) {
1843
+ const noteMatch = /note\s+"([^"]*)"/.exec(details) ?? /note\s+(\S+)/.exec(details);
1844
+ if (noteMatch) {
1845
+ ref.note = noteMatch[1];
2042
1846
  }
2043
1847
  }
2044
- } else if (cmd === "applicability") {
2045
- ref.applicability = parseApplicability(unwrapBlock(t[i++]));
2046
- } else {
2047
- unwrapBlock(t[i++]);
1848
+ result.ref ??= [];
1849
+ result.ref.push(ref);
1850
+ return;
2048
1851
  }
2049
1852
  }
2050
- }
2051
- }
2052
- return ref;
2053
- }
2054
- function dumpFormField(field, indent) {
2055
- let out = "";
2056
- if (field.subformRef && !field.name) {
2057
- const sr = field.subformRef;
2058
- out += indent + "subform_ref " + sr.subformId + " { ";
2059
- const pkeys = Object.keys(sr.parameters);
2060
- if (pkeys.length > 0) {
2061
- out += "parameters { ";
2062
- for (const k of pkeys) {
2063
- out += k + ": " + sr.parameters[k] + " ";
1853
+ const head = basic.trim();
1854
+ if (head === "store") {
1855
+ result.store = details.trim();
1856
+ return;
2064
1857
  }
2065
- out += "} ";
2066
- }
2067
- if (sr.applicability.length > 0) {
2068
- out += "applicability { " + dumpApplicabilityEntries(sr.applicability) + "} ";
1858
+ if (head === "description") {
1859
+ result.description = stripWrapping(details.trim());
1860
+ return;
1861
+ }
1862
+ if (head === "indexes") {
1863
+ result.indexes = details.split(/\s+/).filter((x) => x.length > 0);
1864
+ return;
1865
+ }
1866
+ if (head === "helper") {
1867
+ result.helper = details.trim() === "true";
1868
+ return;
1869
+ }
1870
+ if (head === "extends") {
1871
+ result.extends = details.trim();
1872
+ return;
1873
+ }
1874
+ result.attributes.push(parseDataAttribute(head, details));
1875
+ },
1876
+ { construct: "class", id }
1877
+ );
1878
+ return (ctx) => {
1879
+ ctx.dataclasses[id] = result;
1880
+ return ctx;
1881
+ };
1882
+ };
1883
+ var parseDataAttribute = (basic, details) => {
1884
+ const result = {
1885
+ id: "",
1886
+ type: "",
1887
+ modality: "",
1888
+ cardinality: "",
1889
+ definition: "",
1890
+ ref: [],
1891
+ satisfy: [],
1892
+ _relations: {
1893
+ ref: []
2069
1894
  }
2070
- out += "}\n";
2071
- return out;
1895
+ };
1896
+ const cardMatch = basic.match(/^(.*?)\s*\[([\d*][^\]]*)\]\s*$/);
1897
+ if (cardMatch) {
1898
+ result.cardinality = cardMatch[2].trim();
1899
+ basic = cardMatch[1];
2072
1900
  }
2073
- const inner = [];
2074
- if (field.subformRef) {
2075
- const sr = field.subformRef;
2076
- let refLine = "subform_ref " + sr.subformId + " { ";
2077
- const pkeys = Object.keys(sr.parameters);
2078
- if (pkeys.length > 0) {
2079
- refLine += "parameters { ";
2080
- for (const k of pkeys) {
2081
- refLine += k + ": " + sr.parameters[k] + " ";
1901
+ const colonIndex = basic.indexOf(":");
1902
+ if (colonIndex !== -1) {
1903
+ result.type = basic.substr(colonIndex + 1, basic.length - colonIndex - 1).trim();
1904
+ basic = basic.substr(0, colonIndex);
1905
+ }
1906
+ result.id = basic.trim();
1907
+ forEachEntry(
1908
+ details,
1909
+ (keyword, value) => {
1910
+ if (keyword === "modality") {
1911
+ result.modality = value();
1912
+ } else if (keyword === "definition") {
1913
+ result.definition = unwrapped(value);
1914
+ } else if (keyword === "reference") {
1915
+ result._relations.ref = tokenizePackage(value());
1916
+ } else if (keyword === "satisfy") {
1917
+ result.satisfy = tokenizePackage(value());
1918
+ } else if (keyword === "on_delete") {
1919
+ result.onDelete = value();
1920
+ } else if (keyword === "deprecated") {
1921
+ result.deprecated = value() === "true";
1922
+ } else if (keyword === "enum_values") {
1923
+ result.enumValues = tokenizePackage(value());
1924
+ } else if (keyword === "required") {
1925
+ result.required = value() === "true";
1926
+ } else if (keyword === "unit") {
1927
+ result.unit = unwrapped(value);
1928
+ } else if (keyword === "default") {
1929
+ result.defaultValue = unwrapped(value);
1930
+ } else {
1931
+ return false;
1932
+ }
1933
+ return true;
1934
+ },
1935
+ { construct: "data attribute", id: result.id }
1936
+ );
1937
+ return result;
1938
+ };
1939
+ var resolveDataClass = function(ctx, unresolved) {
1940
+ const attributes = unresolved.attributes.map((attr) => {
1941
+ const resolved = { ...attr, ref: [] };
1942
+ for (const id of attr._relations.ref) {
1943
+ const r = resolveFromContext(ctx, "references", id);
1944
+ if (r !== void 0) {
1945
+ resolved.ref.push(r);
2082
1946
  }
2083
- refLine += "} ";
2084
1947
  }
2085
- if (sr.applicability.length > 0) {
2086
- refLine += "applicability { " + dumpApplicabilityEntries(sr.applicability) + "} ";
1948
+ return resolved;
1949
+ });
1950
+ return {
1951
+ id: unresolved.id,
1952
+ attributes,
1953
+ ...unresolved.store !== void 0 ? { store: unresolved.store } : {},
1954
+ ...unresolved.indexes !== void 0 ? { indexes: unresolved.indexes } : {},
1955
+ ...unresolved.helper !== void 0 ? { helper: unresolved.helper } : {},
1956
+ ...unresolved.extends !== void 0 ? { extends: unresolved.extends } : {},
1957
+ ...unresolved.description !== void 0 ? { description: unresolved.description } : {},
1958
+ ...unresolved.ref !== void 0 ? { ref: unresolved.ref } : {}
1959
+ };
1960
+ };
1961
+ var resolveRegistry = function(ctx, unresolved) {
1962
+ const { _relations, ...rest } = unresolved;
1963
+ const p = { ...rest, data: null };
1964
+ if (_relations.data !== "") {
1965
+ const dc = resolveFromContext(
1966
+ ctx,
1967
+ "dataclasses",
1968
+ _relations.data
1969
+ );
1970
+ if (dc !== void 0) {
1971
+ p.data = dc;
2087
1972
  }
2088
- inner.push(refLine + "}");
2089
- }
2090
- if (field.label) {
2091
- inner.push('label "' + escapeString(field.label) + '"');
2092
- }
2093
- if (field.definition) {
2094
- inner.push('definition "' + escapeString(field.definition) + '"');
2095
- }
2096
- if (field.description) {
2097
- inner.push('description "' + escapeString(field.description) + '"');
2098
- }
2099
- if (field.unit) {
2100
- inner.push('unit "' + escapeString(field.unit) + '"');
2101
- }
2102
- if (field.symbol) {
2103
- inner.push("symbol " + field.symbol);
2104
- }
2105
- if (field.verdict) {
2106
- inner.push("verdict " + field.verdict);
2107
- }
2108
- if (field.dimension) {
2109
- inner.push("dimension " + field.dimension);
2110
- }
2111
- if (field.enumRef) {
2112
- inner.push("enum " + field.enumRef);
2113
- }
2114
- if (field.pattern) {
2115
- inner.push('pattern "' + escapeString(field.pattern) + '"');
2116
1973
  }
2117
- if (field.scope) {
2118
- inner.push("scope " + field.scope);
1974
+ return p;
1975
+ };
1976
+ var dumpDataClass = function(dataclass) {
1977
+ let out = "class " + dataclass.id + " {\n";
1978
+ if (dataclass.store) {
1979
+ out += " store { " + dataclass.store + " }\n";
2119
1980
  }
2120
- if (field.examples) {
2121
- inner.push('examples "' + escapeString(field.examples) + '"');
1981
+ if (dataclass.description) {
1982
+ out += ' description { "' + escapeString(dataclass.description) + '" }\n';
2122
1983
  }
2123
- if (field.bind) {
2124
- inner.push("bind " + dumpBareSafe(field.bind));
1984
+ if (dataclass.indexes && dataclass.indexes.length > 0) {
1985
+ out += " indexes { " + dataclass.indexes.join(" ") + " }\n";
2125
1986
  }
2126
- if (field.required) {
2127
- inner.push("required true");
1987
+ if (dataclass.helper !== void 0) {
1988
+ out += " helper { " + dataclass.helper + " }\n";
2128
1989
  }
2129
- if (field.requiredWhen) {
2130
- inner.push("required_when " + dumpBareSafe(field.requiredWhen));
1990
+ if (dataclass.extends) {
1991
+ out += " extends { " + dataclass.extends + " }\n";
2131
1992
  }
2132
- if (field.measurementMethod) {
2133
- inner.push("measurement_method " + field.measurementMethod);
1993
+ if (dataclass.ref && dataclass.ref.length > 0) {
1994
+ for (const r of dataclass.ref) {
1995
+ out += " ref " + r.predicate + ' "' + escapeString(r.target) + '"';
1996
+ if (r.note) {
1997
+ out += ' { note "' + escapeString(r.note) + '" }';
1998
+ }
1999
+ out += "\n";
2000
+ }
2134
2001
  }
2135
- if (field.calculationId) {
2136
- inner.push("calculation " + dumpBareSafe(field.calculationId));
2002
+ for (const a of dataclass.attributes) {
2003
+ out += toDataAttributeModel(a);
2137
2004
  }
2138
- if (field.calculationBindings.length > 0) {
2139
- inner.push(
2140
- "calculation_bindings { " + field.calculationBindings.map((b) => b.inputName + ": " + b.pathExpr).join(" ") + "}"
2141
- );
2005
+ out += "}\n";
2006
+ return out;
2007
+ };
2008
+ var toDataAttributeModel = (attribute) => {
2009
+ let out = " " + attribute.id;
2010
+ if (attribute.type !== "") {
2011
+ out += ": " + attribute.type;
2142
2012
  }
2143
- if (field.derivation) {
2144
- inner.push('derivation "' + escapeString(field.derivation) + '"');
2013
+ if (attribute.cardinality !== "") {
2014
+ out += "[" + attribute.cardinality + "]";
2145
2015
  }
2146
- if (field.evaluation) {
2147
- let ev = 'evaluation { rule "' + escapeString(field.evaluation.rule) + '"';
2148
- if (field.evaluation.verdict) {
2149
- ev += " verdict " + field.evaluation.verdict;
2150
- }
2151
- if (field.evaluation.op) {
2152
- ev += " op " + field.evaluation.op;
2153
- }
2154
- if (field.evaluation.limit) {
2155
- ev += ' limit "' + escapeString(field.evaluation.limit) + '"';
2156
- }
2157
- if (field.evaluation.condition) {
2158
- ev += ' condition "' + escapeString(field.evaluation.condition) + '"';
2159
- }
2160
- if (field.evaluation.referenceId) {
2161
- ev += " reference { " + field.evaluation.referenceId + " }";
2162
- }
2163
- if (field.evaluation.specificationReference) {
2164
- ev += ' specification_reference "' + escapeString(field.evaluation.specificationReference) + '"';
2165
- }
2166
- if (field.evaluation.sourceDiscrepancy) {
2167
- ev += " " + dumpSourceDiscrepancy(field.evaluation.sourceDiscrepancy, "");
2168
- }
2169
- inner.push(ev + " }");
2016
+ out += " {\n";
2017
+ out += ' definition "' + escapeString(attribute.definition) + '"\n';
2018
+ if (attribute.modality !== "") {
2019
+ out += " modality " + attribute.modality + "\n";
2170
2020
  }
2171
- if (field.values.length > 0) {
2172
- inner.push("values { " + field.values.map(dumpValueEntry).join(" ") + " }");
2021
+ if (attribute.onDelete) {
2022
+ out += " on_delete " + attribute.onDelete + "\n";
2173
2023
  }
2174
- if (field.hasDefault) {
2175
- inner.push("default " + dumpBareSafe(field.defaultValue));
2024
+ if (attribute.deprecated) {
2025
+ out += " deprecated true\n";
2176
2026
  }
2177
- if (field.trueLabel) {
2178
- inner.push('true_label "' + escapeString(field.trueLabel) + '"');
2027
+ if (attribute.enumValues && attribute.enumValues.length > 0) {
2028
+ out += " enum_values { " + attribute.enumValues.join(" ") + " }\n";
2179
2029
  }
2180
- if (field.falseLabel) {
2181
- inner.push('false_label "' + escapeString(field.falseLabel) + '"');
2030
+ if (attribute.required !== void 0) {
2031
+ out += " required " + (attribute.required ? "true" : "false") + "\n";
2182
2032
  }
2183
- if (field.enumValues.length > 0) {
2184
- inner.push(
2185
- "enum_values { " + field.enumValues.map(dumpValueEntry).join(" ") + " }"
2186
- );
2033
+ if (attribute.unit) {
2034
+ out += ' unit "' + escapeString(attribute.unit) + '"\n';
2187
2035
  }
2188
- if (field.itemsType) {
2189
- let itemsLine = "items { " + field.itemsType;
2190
- if (field.itemsUnit) {
2191
- itemsLine += ' unit "' + escapeString(field.itemsUnit) + '"';
2036
+ if (attribute.defaultValue !== void 0) {
2037
+ out += ' default "' + escapeString(attribute.defaultValue) + '"\n';
2038
+ }
2039
+ if (attribute.satisfy.length > 0) {
2040
+ out += " satisfy {\n";
2041
+ for (const s of attribute.satisfy) {
2042
+ out += " " + s + "\n";
2192
2043
  }
2193
- inner.push(itemsLine + " }");
2044
+ out += " }\n";
2194
2045
  }
2195
- if (field.minItems !== void 0 && field.minItems !== null) {
2196
- inner.push("min_items " + dumpBareSafe(String(field.minItems)));
2046
+ if (attribute.ref.length > 0) {
2047
+ out += " reference {\n";
2048
+ for (const r of attribute.ref) {
2049
+ out += " " + r.id + "\n";
2050
+ }
2051
+ out += " }\n";
2197
2052
  }
2198
- if (field.maxItems !== void 0 && field.maxItems !== null) {
2199
- inner.push("max_items " + dumpBareSafe(String(field.maxItems)));
2053
+ out += " }\n";
2054
+ return out;
2055
+ };
2056
+ var dumpEnumValue = (ev) => {
2057
+ let out = " " + ev.id + " {\n";
2058
+ out += ' definition "' + escapeString(ev.value) + '"\n';
2059
+ out += " }\n";
2060
+ return out;
2061
+ };
2062
+ var dumpEnum = function(en) {
2063
+ let out = "enum " + en.id + " {\n";
2064
+ for (const v of en.values) {
2065
+ out += dumpEnumValue(v);
2200
2066
  }
2201
- if (field.series) {
2202
- inner.push(dumpSeriesDecl(field.series));
2067
+ out += "}\n";
2068
+ return out;
2069
+ };
2070
+ var dumpRegistry = function(reg) {
2071
+ let out = "data_registry " + reg.id + " {\n";
2072
+ out += ' title "' + escapeString(reg.title) + '"\n';
2073
+ if (reg.data !== null) {
2074
+ out += " data_class " + reg.data.id + "\n";
2203
2075
  }
2204
- if (field.applicability.length > 0) {
2205
- inner.push(
2206
- "applicability { " + dumpApplicabilityEntries(field.applicability) + "}"
2207
- );
2076
+ out += "}\n";
2077
+ return out;
2078
+ };
2079
+ var parseVariable = function(id, data) {
2080
+ const result = {
2081
+ id,
2082
+ type: "",
2083
+ definition: "",
2084
+ description: ""
2085
+ };
2086
+ forEachEntry(
2087
+ data,
2088
+ (keyword, value) => {
2089
+ if (keyword === "type") {
2090
+ result.type = value();
2091
+ } else if (keyword === "definition") {
2092
+ result.definition = unwrapped(value);
2093
+ } else if (keyword === "description") {
2094
+ result.description = unwrapped(value);
2095
+ } else {
2096
+ return false;
2097
+ }
2098
+ return true;
2099
+ },
2100
+ { construct: "variable", id }
2101
+ );
2102
+ return (ctx) => {
2103
+ ctx.variables[id] = result;
2104
+ return ctx;
2105
+ };
2106
+ };
2107
+ var dumpVariable = function(v) {
2108
+ let out = "variable " + v.id + " {\n";
2109
+ if (v.type !== "") {
2110
+ out += " type " + v.type + "\n";
2208
2111
  }
2209
- if (field.targets.length > 0) {
2210
- inner.push("targets { " + field.targets.join(" ") + " }");
2112
+ if (v.definition !== "") {
2113
+ out += ' definition "' + escapeString(v.definition) + '"\n';
2211
2114
  }
2212
- if (field.sourceRefs && field.sourceRefs.length > 0) {
2213
- for (const s of field.sourceRefs) {
2214
- inner.push(dumpSourceRefAsRef(s, "", escapeString).trimEnd());
2215
- }
2115
+ if (v.description !== "") {
2116
+ out += ' description "' + escapeString(v.description) + '"\n';
2216
2117
  }
2217
- if (field.fieldReferences.length > 0) {
2218
- for (const r of field.fieldReferences) {
2219
- inner.push(
2220
- "ref " + roleToPredicateForDump(r.role) + ' "' + escapeString(r.urn) + '"'
2118
+ out += "}\n";
2119
+ return out;
2120
+ };
2121
+
2122
+ // src/ser-des/config/event.ts
2123
+ var parseEndEvent = function(id, data) {
2124
+ const result = {
2125
+ id,
2126
+ eventType: "end"
2127
+ };
2128
+ if (data !== "") {
2129
+ const t = tokenizePackage(data);
2130
+ if (t.length > 0) {
2131
+ throw new Error(
2132
+ `Parsing error: end_event. ID ${id}: Expecting empty body`
2221
2133
  );
2222
2134
  }
2223
2135
  }
2224
- if (field.refs && field.refs.length > 0) {
2225
- for (const r of field.refs) {
2226
- inner.push(
2227
- "ref " + r.predicate + ' "' + escapeString(r.target) + '"' + (r.note ? ' { note "' + escapeString(r.note) + '" }' : "")
2228
- );
2136
+ return (ctx) => {
2137
+ ctx.events[id] = result;
2138
+ return ctx;
2139
+ };
2140
+ };
2141
+ var parseSignalCatchEvent = function(id, data) {
2142
+ const result = {
2143
+ id,
2144
+ eventType: "signalcatch",
2145
+ signal: ""
2146
+ };
2147
+ if (data !== "") {
2148
+ const t = tokenizePackage(data);
2149
+ let i = 0;
2150
+ while (i < t.length) {
2151
+ const command = t[i++];
2152
+ if (i < t.length) {
2153
+ if (command === "catch") {
2154
+ result.signal = unwrapBlock(t[i++]);
2155
+ } else {
2156
+ i++;
2157
+ }
2158
+ } else {
2159
+ throw new Error(
2160
+ `Parsing error: Signal Catch Event. ID ${id}: Expecting value for ${command}`
2161
+ );
2162
+ }
2229
2163
  }
2230
2164
  }
2231
- if (field.correspondences && field.correspondences.length > 0) {
2232
- inner.push(
2233
- dumpCorrespondences(
2234
- field.correspondences,
2235
- "",
2236
- escapeString,
2237
- dumpBareSafe
2238
- ).trimEnd()
2239
- );
2165
+ return (ctx) => {
2166
+ ctx.events[id] = result;
2167
+ return ctx;
2168
+ };
2169
+ };
2170
+ var parseStartEvent = function(id, data) {
2171
+ const result = {
2172
+ id,
2173
+ eventType: "start"
2174
+ };
2175
+ if (data !== "") {
2176
+ const t = tokenizePackage(data);
2177
+ if (t.length > 0) {
2178
+ throw new Error(
2179
+ `Parsing error: end_event. ID ${id}: Expecting empty body`
2180
+ );
2181
+ }
2240
2182
  }
2241
- if (field.specificationReference) {
2242
- inner.push(
2243
- 'specification_reference "' + escapeString(field.specificationReference) + '"'
2244
- );
2183
+ return (ctx) => {
2184
+ ctx.events[id] = result;
2185
+ return ctx;
2186
+ };
2187
+ };
2188
+ var parseTimerEvent = function(id, data) {
2189
+ const result = {
2190
+ id,
2191
+ eventType: "timer",
2192
+ type: "",
2193
+ para: ""
2194
+ };
2195
+ if (data !== "") {
2196
+ const t = tokenizePackage(data);
2197
+ let i = 0;
2198
+ while (i < t.length) {
2199
+ const command = t[i++];
2200
+ if (i < t.length) {
2201
+ if (command === "type") {
2202
+ result.type = t[i++];
2203
+ } else if (command === "para") {
2204
+ result.para = unwrapBlock(t[i++]);
2205
+ } else {
2206
+ i++;
2207
+ }
2208
+ } else {
2209
+ throw new Error(
2210
+ `Parsing error: Timer Event. ID ${id}: Expecting value for ${command}`
2211
+ );
2212
+ }
2213
+ }
2245
2214
  }
2246
- if (field.sourceDiscrepancy) {
2247
- inner.push(dumpSourceDiscrepancy(field.sourceDiscrepancy, ""));
2215
+ return (ctx) => {
2216
+ ctx.events[id] = result;
2217
+ return ctx;
2218
+ };
2219
+ };
2220
+ var dumpEvent = function(event) {
2221
+ if (event.eventType === "start") {
2222
+ return dumpStartEvent(event);
2248
2223
  }
2249
- if (field.fields.length > 0) {
2250
- inner.push(
2251
- "fields {\n" + field.fields.map((f) => dumpFormField(f, indent + " ")).join("") + indent + " }"
2252
- );
2224
+ if (event.eventType === "end") {
2225
+ return dumpEndEvent(event);
2253
2226
  }
2254
- if (field.referenceIds.length > 0) {
2255
- inner.push("reference { " + field.referenceIds.join(" ") + " }");
2227
+ if (event.eventType === "signalcatch") {
2228
+ return dumpSignalCatchEvent(event);
2256
2229
  }
2257
- const typeSpec = field.type && (field.type !== "string" || field.typeDeclared) ? " : " + field.type : "";
2258
- if (inner.length === 0) {
2259
- return indent + "field " + field.name + typeSpec + " { }\n";
2230
+ if (event.eventType === "timer") {
2231
+ return dumpTimerEvent(event);
2260
2232
  }
2261
- if (inner.every((s) => !s.includes("\n"))) {
2262
- return indent + "field " + field.name + typeSpec + " { " + inner.join(" ") + " }\n";
2233
+ return "";
2234
+ };
2235
+ function dumpEndEvent(end) {
2236
+ return "end_event " + end.id + " {\n}\n";
2237
+ }
2238
+ function dumpSignalCatchEvent(sc) {
2239
+ let out = "signal_catch_event " + sc.id + " {\n";
2240
+ if (sc.signal !== "") {
2241
+ out += ' catch "' + escapeString(sc.signal) + '"\n';
2263
2242
  }
2264
- return indent + "field " + field.name + typeSpec + " {\n" + inner.map((s) => indent + " " + s + "\n").join("") + indent + "}\n";
2243
+ out += "}\n";
2244
+ return out;
2265
2245
  }
2266
- function dumpApplicabilityEntries(entries) {
2267
- let out = "";
2268
- for (const a of entries) {
2269
- if (a.mapping) {
2270
- out += a.dimension + ": { ";
2271
- const pairs = [];
2272
- for (const [k, v] of Object.entries(a.mapping)) {
2273
- pairs.push(k + ": " + v);
2274
- }
2275
- out += pairs.join(", ") + " ";
2276
- out += "} ";
2277
- } else {
2278
- out += a.dimension + ": [" + a.values.join(", ") + "] ";
2279
- if (a.match) {
2280
- out += "match " + a.match + " ";
2281
- }
2282
- }
2246
+ function dumpStartEvent(s) {
2247
+ return "start_event " + s.id + " {\n}\n";
2248
+ }
2249
+ function dumpTimerEvent(te) {
2250
+ let out = "timer_event " + te.id + " {\n";
2251
+ if (te.type !== "") {
2252
+ out += " type " + te.type + "\n";
2253
+ }
2254
+ if (te.para !== "") {
2255
+ out += ' para "' + escapeString(te.para) + '"\n';
2283
2256
  }
2257
+ out += "}\n";
2284
2258
  return out;
2285
2259
  }
2286
- function parseRoleReferences(block) {
2287
- const out = [];
2288
- const t = tokenize(block);
2289
- let i = 0;
2290
- while (i < t.length) {
2291
- const role = stripColon(t[i++]);
2292
- if (!role) {
2293
- break;
2294
- }
2295
- if (i < t.length && t[i] === ":") {
2296
- i++;
2297
- }
2298
- if (i < t.length && t[i].startsWith("{")) {
2299
- const urns = tokenize(unwrapBlock(t[i++])).map(stripWrapping).filter((s) => s.length > 0);
2300
- for (const urn of urns) {
2301
- out.push({ urn, role });
2260
+
2261
+ // src/ser-des/config/gateway.ts
2262
+ var parseExclusiveGate = function(id, data) {
2263
+ const gateway = {
2264
+ id,
2265
+ gatewayType: "exclusive_gateway",
2266
+ label: "",
2267
+ edges: []
2268
+ };
2269
+ forEachEntry(
2270
+ data,
2271
+ (command, value) => {
2272
+ if (command === "label") {
2273
+ gateway.label = unwrapped(value);
2274
+ } else if (command === "edge") {
2275
+ const edge = {
2276
+ target: stripWrapping(value()),
2277
+ condition: "",
2278
+ label: ""
2279
+ };
2280
+ const et = tokenize(unwrapBlock(value()));
2281
+ for (let j = 0; j + 1 < et.length; j += 2) {
2282
+ if (et[j] === "condition") {
2283
+ edge.condition = stripWrapping(et[j + 1]);
2284
+ } else if (et[j] === "label") {
2285
+ edge.label = stripWrapping(et[j + 1]);
2286
+ }
2287
+ }
2288
+ gateway.edges.push(edge);
2289
+ } else {
2290
+ return false;
2302
2291
  }
2292
+ return true;
2293
+ },
2294
+ { construct: "Exclusive gateway", id }
2295
+ );
2296
+ return (ctx) => {
2297
+ ctx.gateways[id] = gateway;
2298
+ return ctx;
2299
+ };
2300
+ };
2301
+ var dumpGateway = function(gate) {
2302
+ if (gate.gatewayType === "exclusive_gateway") {
2303
+ return dumpEGate(gate);
2304
+ }
2305
+ return "";
2306
+ };
2307
+ function dumpEGate(egate) {
2308
+ let out = "exclusive_gateway " + egate.id + " {\n";
2309
+ if (egate.label !== "") {
2310
+ out += ' label "' + escapeString(egate.label) + '"\n';
2311
+ }
2312
+ for (const e of egate.edges ?? []) {
2313
+ out += " edge " + dumpBareSafe(e.target) + " {";
2314
+ if (e.condition === "default") {
2315
+ out += " condition default";
2316
+ } else if (e.condition !== "") {
2317
+ out += ' condition "' + escapeString(e.condition) + '"';
2318
+ }
2319
+ if (e.label !== "") {
2320
+ out += ' label "' + escapeString(e.label) + '"';
2303
2321
  }
2322
+ out += " }\n";
2304
2323
  }
2324
+ out += "}\n";
2305
2325
  return out;
2306
2326
  }
2307
- function roleToPredicateForDump(role) {
2308
- if (role === "source") {
2309
- return "derives-from";
2310
- }
2311
- if (role === "reference") {
2312
- return "cites";
2327
+
2328
+ // src/ser-des/config/metadata.ts
2329
+ var parseMetadata = function(token) {
2330
+ const metadata = {
2331
+ schema: "",
2332
+ author: "",
2333
+ title: "",
2334
+ edition: "",
2335
+ namespace: "",
2336
+ shortname: ""
2337
+ };
2338
+ if (token !== "") {
2339
+ const t = tokenizePackage(token);
2340
+ let i = 0;
2341
+ while (i < t.length) {
2342
+ const keyword = t[i++];
2343
+ if (i < t.length) {
2344
+ if (keyword === "title") {
2345
+ metadata.title = stripWrapping(t[i++]);
2346
+ } else if (keyword === "schema") {
2347
+ metadata.schema = stripWrapping(t[i++]);
2348
+ } else if (keyword === "edition") {
2349
+ metadata.edition = stripWrapping(t[i++]);
2350
+ } else if (keyword === "author") {
2351
+ metadata.author = stripWrapping(t[i++]);
2352
+ } else if (keyword === "namespace") {
2353
+ metadata.namespace = stripWrapping(t[i++]);
2354
+ } else if (keyword === "shortname") {
2355
+ metadata.shortname = stripWrapping(t[i++]);
2356
+ } else {
2357
+ throw new Error(
2358
+ "Parsing error: metadata. Unknown keyword " + keyword
2359
+ );
2360
+ }
2361
+ } else {
2362
+ throw new Error(
2363
+ "Parsing error: metadata. Expecting value for " + keyword
2364
+ );
2365
+ }
2366
+ }
2313
2367
  }
2314
- return role;
2315
- }
2368
+ return (ctx) => {
2369
+ ctx.metadata = metadata;
2370
+ return ctx;
2371
+ };
2372
+ };
2316
2373
 
2317
2374
  // src/ser-des/config/quantity.ts
2318
2375
  var NUMERIC = /^-?\d+(\.\d+)?([eE][+-]?\d+)?$/;
@@ -2928,6 +2985,10 @@ var parseProcess = function(id, data) {
2928
2985
  id,
2929
2986
  name: "",
2930
2987
  modality: "",
2988
+ // The workflow facets (smart TODO.roadmap/40 batch 5)
2989
+ phase: "",
2990
+ guards: [],
2991
+ machineSteps: [],
2931
2992
  actor: null,
2932
2993
  output: [],
2933
2994
  input: [],
@@ -3002,6 +3063,12 @@ var parseProcess = function(id, data) {
3002
3063
  (keyword, value, peek) => {
3003
3064
  if (keyword === "modality") {
3004
3065
  result.modality = value();
3066
+ } else if (keyword === "phase") {
3067
+ result.phase = stripWrapping(value());
3068
+ } else if (keyword === "guard") {
3069
+ result.guards.push(unwrapped(value));
3070
+ } else if (keyword === "machine_steps") {
3071
+ result.machineSteps = tokenize(stripWrapping(value())).map(stripColon).map(stripWrapping).filter((s) => s.length > 0);
3005
3072
  } else if (keyword === "name") {
3006
3073
  result.name = unwrapped(value);
3007
3074
  } else if (keyword === "actor") {
@@ -3254,6 +3321,17 @@ var dumpProcess = function(process2, ctx) {
3254
3321
  if (process2.modality !== "") {
3255
3322
  out += " modality " + process2.modality + "\n";
3256
3323
  }
3324
+ if (process2.phase) {
3325
+ out += " phase " + dumpBareSafe(process2.phase) + "\n";
3326
+ }
3327
+ if (process2.guards && process2.guards.length > 0) {
3328
+ for (const g of process2.guards) {
3329
+ out += ' guard "' + escapeString(g) + '"\n';
3330
+ }
3331
+ }
3332
+ if (process2.machineSteps && process2.machineSteps.length > 0) {
3333
+ out += " machine_steps { " + process2.machineSteps.map(dumpBareSafe).join(" ") + " }\n";
3334
+ }
3257
3335
  if (process2.input.length > 0) {
3258
3336
  out += " reference_data_registry {\n";
3259
3337
  for (const dr of process2.input) {
@@ -3697,6 +3775,75 @@ var dumpWorkflowConfig = function(c) {
3697
3775
  return out;
3698
3776
  };
3699
3777
 
3778
+ // src/ser-des/config/workflowStage.ts
3779
+ function readTokenList2(block) {
3780
+ return tokenize(stripWrapping(block)).map(stripColon).map(stripWrapping).filter((s) => s.length > 0);
3781
+ }
3782
+ function dumpTokenList2(keyword, ids) {
3783
+ if (ids.length === 0) {
3784
+ return "";
3785
+ }
3786
+ return " " + keyword + " { " + ids.map(dumpBareSafe).join(" ") + " }\n";
3787
+ }
3788
+ var parseWorkflowStage = (id, data) => {
3789
+ const stage = {
3790
+ id,
3791
+ label: "",
3792
+ description: "",
3793
+ elements: [],
3794
+ startEvent: "",
3795
+ endEvents: [],
3796
+ approvals: [],
3797
+ gateways: []
3798
+ };
3799
+ forEachEntry(
3800
+ data,
3801
+ (keyword, value) => {
3802
+ if (keyword === "label") {
3803
+ stage.label = stripWrapping(value());
3804
+ } else if (keyword === "description") {
3805
+ stage.description = stripWrapping(value());
3806
+ } else if (keyword === "elements") {
3807
+ stage.elements = readTokenList2(value());
3808
+ } else if (keyword === "start_event") {
3809
+ stage.startEvent = stripWrapping(value());
3810
+ } else if (keyword === "end_events") {
3811
+ stage.endEvents = readTokenList2(value());
3812
+ } else if (keyword === "approvals") {
3813
+ stage.approvals = readTokenList2(value());
3814
+ } else if (keyword === "gateways") {
3815
+ stage.gateways = readTokenList2(value());
3816
+ } else {
3817
+ return false;
3818
+ }
3819
+ return true;
3820
+ },
3821
+ { construct: "workflow_stage", id }
3822
+ );
3823
+ return (ctx) => {
3824
+ ctx.workflowStages[id] = stage;
3825
+ return ctx;
3826
+ };
3827
+ };
3828
+ var dumpWorkflowStage = function(s) {
3829
+ let out = "workflow_stage " + dumpBareSafe(s.id) + " {\n";
3830
+ if (s.label) {
3831
+ out += ' label "' + escapeString(s.label) + '"\n';
3832
+ }
3833
+ if (s.description) {
3834
+ out += ' description "' + escapeString(s.description) + '"\n';
3835
+ }
3836
+ out += dumpTokenList2("elements", s.elements);
3837
+ if (s.startEvent) {
3838
+ out += " start_event " + dumpBareSafe(s.startEvent) + "\n";
3839
+ }
3840
+ out += dumpTokenList2("end_events", s.endEvents);
3841
+ out += dumpTokenList2("approvals", s.approvals);
3842
+ out += dumpTokenList2("gateways", s.gateways);
3843
+ out += "}\n";
3844
+ return out;
3845
+ };
3846
+
3700
3847
  // src/ser-des/config/verificationPathway.ts
3701
3848
  var VERIFICATION_KINDS = [
3702
3849
  "initial",
@@ -18588,6 +18735,16 @@ var CONSTRUCTS = [
18588
18735
  parse: parseWorkflowConfig,
18589
18736
  dump: dumpWorkflowConfig
18590
18737
  }),
18738
+ // The named pipeline stage (smart TODO.roadmap/40 batch 5) — groups
18739
+ // the workflow constructs per stage; the members-resolve discipline
18740
+ // is C142's.
18741
+ defineConstruct({
18742
+ keyword: "workflow_stage",
18743
+ field: "workflowStages",
18744
+ takesID: true,
18745
+ parse: parseWorkflowStage,
18746
+ dump: dumpWorkflowStage
18747
+ }),
18591
18748
  defineConstruct({
18592
18749
  keyword: "approval",
18593
18750
  field: "approvals",
@@ -19582,6 +19739,9 @@ var MERGE_FIELDS = [
19582
19739
  // The certification workflow step register (smart TODO.roadmap/40
19583
19740
  // batch 3) — the rec-overlay deep merge (OVERLAY_DEEP_MERGE_FIELDS).
19584
19741
  "workflowConfigs",
19742
+ // The named pipeline stages (smart TODO.roadmap/40 batch 5) compose
19743
+ // with uses-no-redefine semantics.
19744
+ "workflowStages",
19585
19745
  // The verification pathways (smart TODO.roadmap/40 batch 3) compose
19586
19746
  // with uses-no-redefine semantics.
19587
19747
  "verificationPathways",
@@ -20591,6 +20751,9 @@ var TIER_BY_FIELD = {
20591
20751
  // The certification workflow step register (smart TODO.roadmap/40
20592
20752
  // batch 3) — operational wiring, tertiary.
20593
20753
  workflowConfigs: "tertiary",
20754
+ // The named pipeline stages (smart TODO.roadmap/40 batch 5) —
20755
+ // operational wiring, tertiary.
20756
+ workflowStages: "tertiary",
20594
20757
  // The verification pathways (smart TODO.roadmap/40 batch 3) —
20595
20758
  // operational wiring, tertiary.
20596
20759
  verificationPathways: "tertiary",
@@ -22033,6 +22196,33 @@ var CHECK_RULES = [
22033
22196
  "normal",
22034
22197
  "smart TODO.roadmap/40 batch 3 (the packages-as-SSOT epic)"
22035
22198
  ),
22199
+ // C142 (smart TODO.roadmap/40 batch 5; the packages-as-SSOT epic): the
22200
+ // gateway routing cascade — edge targets resolve to declared processes
22201
+ // (gated), exactly one default edge per edge-carrying gateway, the
22202
+ // default recommended last (warning). The workflow_stage members-
22203
+ // resolve legs ride this rule (step 5d).
22204
+ R(
22205
+ "C142",
22206
+ "gateway-edges-resolve",
22207
+ "composition",
22208
+ "error",
22209
+ "normal",
22210
+ "smart TODO.roadmap/40 batch 5 (the packages-as-SSOT epic)"
22211
+ ),
22212
+ // C143 (smart TODO.roadmap/40 batch 5; the packages-as-SSOT epic): the
22213
+ // first approval rule — actor/approve_by resolve to declared roles,
22214
+ // the approval_record entries to declared entity-class stores (the
22215
+ // dataclass `store { … }` names), per-register gated (the C58
22216
+ // doctrine). Reads the raw reference ids so unresolvable ids are still
22217
+ // checked — and still round-trip.
22218
+ R(
22219
+ "C143",
22220
+ "approval-references-resolve",
22221
+ "composition",
22222
+ "error",
22223
+ "normal",
22224
+ "smart TODO.roadmap/40 batch 5 (the packages-as-SSOT epic)"
22225
+ ),
22036
22226
  // ── quantities / time / duality (TODO.roadmap/06) ─────────────────
22037
22227
  R(
22038
22228
  "C32",
@@ -27589,6 +27779,108 @@ function checkPackage(dir, options = {}) {
27589
27779
  }
27590
27780
  }
27591
27781
  }
27782
+ {
27783
+ const gwProcessIds = new Set((standard.processes ?? []).map((p) => p.id));
27784
+ for (const g of standard.gateways ?? []) {
27785
+ if (g.gatewayType !== "exclusive_gateway") {
27786
+ continue;
27787
+ }
27788
+ const edges = g.edges ?? [];
27789
+ const where = `exclusive_gateway ${g.id}`;
27790
+ edges.forEach((e, i) => {
27791
+ if (gwProcessIds.size > 0 && !gwProcessIds.has(e.target)) {
27792
+ err(
27793
+ "C142",
27794
+ `${where}: edge ${i + 1} targets "${e.target}", which is not a declared process (gateway-edges-resolve)`
27795
+ );
27796
+ }
27797
+ });
27798
+ if (edges.length > 0) {
27799
+ const defaults = edges.map((e, i) => ({ e, i })).filter((x) => x.e.condition === "default");
27800
+ if (defaults.length === 0) {
27801
+ err(
27802
+ "C142",
27803
+ `${where}: no default edge \u2014 the first-match-wins cascade needs its catch-all (gateway-edges-resolve)`
27804
+ );
27805
+ } else if (defaults.length > 1) {
27806
+ err(
27807
+ "C142",
27808
+ `${where}: ${defaults.length} default edges \u2014 exactly one catch-all is allowed (gateway-edges-resolve)`
27809
+ );
27810
+ } else if (defaults[0].i !== edges.length - 1) {
27811
+ warn(
27812
+ "C142",
27813
+ `${where}: the default edge is not last \u2014 it shadows the edges after it in the first-match-wins cascade (gateway-edges-resolve)`
27814
+ );
27815
+ }
27816
+ }
27817
+ }
27818
+ const stageApprovalIds = new Set((standard.approvals ?? []).map((a) => a.id));
27819
+ const stageGatewayIds = new Set((standard.gateways ?? []).map((g) => g.id));
27820
+ for (const s of standard.workflowStages ?? []) {
27821
+ const where = `workflow_stage ${s.id}`;
27822
+ for (const el of s.elements ?? []) {
27823
+ if (gwProcessIds.size > 0 && !gwProcessIds.has(el)) {
27824
+ err(
27825
+ "C142",
27826
+ `${where}: element "${el}" is not a declared process (gateway-edges-resolve)`
27827
+ );
27828
+ }
27829
+ }
27830
+ for (const a of s.approvals ?? []) {
27831
+ if (stageApprovalIds.size > 0 && !stageApprovalIds.has(a)) {
27832
+ err(
27833
+ "C142",
27834
+ `${where}: approval "${a}" is not a declared approval (gateway-edges-resolve)`
27835
+ );
27836
+ }
27837
+ }
27838
+ for (const g of s.gateways ?? []) {
27839
+ if (stageGatewayIds.size > 0 && !stageGatewayIds.has(g)) {
27840
+ err(
27841
+ "C142",
27842
+ `${where}: gateway "${g}" is not a declared gateway (gateway-edges-resolve)`
27843
+ );
27844
+ }
27845
+ }
27846
+ }
27847
+ }
27848
+ {
27849
+ const approvalRoleIds = new Set((standard.roles ?? []).map((r) => r.id));
27850
+ const approvalStores = /* @__PURE__ */ new Set();
27851
+ for (const c of standard.dataclasses ?? []) {
27852
+ if (c.store) {
27853
+ for (const s of c.store.split(/\s+/)) {
27854
+ if (s) {
27855
+ approvalStores.add(s);
27856
+ }
27857
+ }
27858
+ }
27859
+ }
27860
+ for (const a of standard.approvals ?? []) {
27861
+ const where = `approval ${a.id}`;
27862
+ if (a.actorRef && approvalRoleIds.size > 0 && !approvalRoleIds.has(a.actorRef)) {
27863
+ err(
27864
+ "C143",
27865
+ `${where}: actor "${a.actorRef}" is not a declared role (approval-references-resolve)`
27866
+ );
27867
+ }
27868
+ if (a.approverRef && approvalRoleIds.size > 0 && !approvalRoleIds.has(a.approverRef)) {
27869
+ err(
27870
+ "C143",
27871
+ `${where}: approver "${a.approverRef}" is not a declared role (approval-references-resolve)`
27872
+ );
27873
+ }
27874
+ for (const store of a.recordRefs ?? []) {
27875
+ if (approvalStores.size > 0 && !approvalStores.has(store)) {
27876
+ err(
27877
+ "C143",
27878
+ `${where}: approval_record "${store}" is not a declared entity-class store (approval-references-resolve)`
27879
+ );
27880
+ }
27881
+ }
27882
+ }
27883
+ }
27592
27884
  for (const d of standard.duals ?? []) {
27593
27885
  if (d.attribute && !attrIds.has(d.attribute)) {
27594
27886
  err(