@cosyte/terminology 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/README.md +3 -0
- package/dist/index.cjs +430 -106
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +56 -38
- package/dist/index.d.ts +56 -38
- package/dist/index.mjs +430 -106
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -4
package/dist/index.mjs
CHANGED
|
@@ -210,7 +210,7 @@ var FATAL_CODES = {
|
|
|
210
210
|
/**
|
|
211
211
|
* An **inversion** of a directional crosswalk was requested: a forbidden operation. The GEMs and
|
|
212
212
|
* the SNOMED→ICD-10-CM map are authoritative in **one direction only**; a forward map is not the
|
|
213
|
-
* inverse of the backward map. Thrown by {@link
|
|
213
|
+
* inverse of the backward map. Thrown by {@link invertGem} so the
|
|
214
214
|
* never-invert refusal is a first-class, discoverable contract rather than a silent absence.
|
|
215
215
|
*/
|
|
216
216
|
TERM_MAP_NOT_INVERTIBLE: "TERM_MAP_NOT_INVERTIBLE"
|
|
@@ -444,6 +444,10 @@ function loadUnmapped(raw, path) {
|
|
|
444
444
|
assignString(out, raw, "url");
|
|
445
445
|
return Object.freeze(out);
|
|
446
446
|
}
|
|
447
|
+
var loadedGroups = /* @__PURE__ */ new WeakSet();
|
|
448
|
+
function isLoadedGroup(group) {
|
|
449
|
+
return loadedGroups.has(group);
|
|
450
|
+
}
|
|
447
451
|
function loadGroup(raw, path) {
|
|
448
452
|
if (!isJsonObject(raw)) malformed(path, "group is not an object");
|
|
449
453
|
const rawElements = getArray(raw, "element") ?? [];
|
|
@@ -458,7 +462,9 @@ function loadGroup(raw, path) {
|
|
|
458
462
|
if (isJsonObject(raw) && raw["unmapped"] !== void 0) {
|
|
459
463
|
out.unmapped = loadUnmapped(raw["unmapped"], `${path}.unmapped`);
|
|
460
464
|
}
|
|
461
|
-
|
|
465
|
+
const group = Object.freeze(out);
|
|
466
|
+
loadedGroups.add(group);
|
|
467
|
+
return group;
|
|
462
468
|
}
|
|
463
469
|
function loadConceptMap(json) {
|
|
464
470
|
if (!isJsonObject(json)) malformed("", "resource is not a JSON object");
|
|
@@ -502,6 +508,24 @@ function groupApplies(group, system) {
|
|
|
502
508
|
if (system === void 0) return true;
|
|
503
509
|
return group.source === void 0 || group.source === system;
|
|
504
510
|
}
|
|
511
|
+
var elementIndex = /* @__PURE__ */ new WeakMap();
|
|
512
|
+
var NO_ELEMENTS = Object.freeze([]);
|
|
513
|
+
function candidates(group, code) {
|
|
514
|
+
if (typeof code !== "string" || !isLoadedGroup(group)) return group.element;
|
|
515
|
+
let index = elementIndex.get(group);
|
|
516
|
+
if (index === void 0) {
|
|
517
|
+
const built = /* @__PURE__ */ new Map();
|
|
518
|
+
for (const element of group.element) {
|
|
519
|
+
if (element.code === void 0) continue;
|
|
520
|
+
const list = built.get(element.code);
|
|
521
|
+
if (list === void 0) built.set(element.code, [element]);
|
|
522
|
+
else list.push(element);
|
|
523
|
+
}
|
|
524
|
+
index = built;
|
|
525
|
+
elementIndex.set(group, index);
|
|
526
|
+
}
|
|
527
|
+
return index.get(code) ?? NO_ELEMENTS;
|
|
528
|
+
}
|
|
505
529
|
function provenanceOf(map, group, sourceSystem) {
|
|
506
530
|
const out = {};
|
|
507
531
|
if (map.url !== void 0) out.conceptMapUrl = map.url;
|
|
@@ -535,7 +559,7 @@ function translate(sourceCoding, map) {
|
|
|
535
559
|
for (const group of map.group) {
|
|
536
560
|
if (!groupApplies(group, system)) continue;
|
|
537
561
|
if (fallbackGroup === void 0 && group.unmapped !== void 0) fallbackGroup = group;
|
|
538
|
-
for (const element of group.
|
|
562
|
+
for (const element of candidates(group, source.code)) {
|
|
539
563
|
if (element.code !== source.code) continue;
|
|
540
564
|
sourceCodePresent = true;
|
|
541
565
|
for (const t of element.target) {
|
|
@@ -638,6 +662,12 @@ function frozenMap(source, what) {
|
|
|
638
662
|
return Object.freeze(view);
|
|
639
663
|
}
|
|
640
664
|
|
|
665
|
+
// src/common/own-string.ts
|
|
666
|
+
var VIEW_MIN_LENGTH = 13;
|
|
667
|
+
function ownString(s) {
|
|
668
|
+
return s.length < VIEW_MIN_LENGTH ? s : ` ${s}`.slice(1);
|
|
669
|
+
}
|
|
670
|
+
|
|
641
671
|
// src/codesystem/status.ts
|
|
642
672
|
var defaultStatusMapper = (raw) => {
|
|
643
673
|
switch (raw.trim().toUpperCase()) {
|
|
@@ -672,7 +702,79 @@ function makeStatus(activity, raw, billable) {
|
|
|
672
702
|
}
|
|
673
703
|
|
|
674
704
|
// src/codesystem/csv.ts
|
|
675
|
-
|
|
705
|
+
var QUOTE = 34;
|
|
706
|
+
var COMMA = 44;
|
|
707
|
+
var LINE_FEED = 10;
|
|
708
|
+
var CARRIAGE_RETURN = 13;
|
|
709
|
+
function scanCsv(content, sink) {
|
|
710
|
+
if (typeof content !== "string") return readCsvByCharAt(content, sink);
|
|
711
|
+
const n = content.length;
|
|
712
|
+
const cells = [];
|
|
713
|
+
let column = 0;
|
|
714
|
+
const keeps = (col) => sink.wanted === void 0 || sink.wanted[col] === true;
|
|
715
|
+
let keep = keeps(0);
|
|
716
|
+
let field = "";
|
|
717
|
+
let runStart = 0;
|
|
718
|
+
let inQuotes = false;
|
|
719
|
+
let fieldStart = true;
|
|
720
|
+
let sawAny = false;
|
|
721
|
+
const endField = (end) => {
|
|
722
|
+
if (keep) cells[column] = field + content.slice(runStart, end);
|
|
723
|
+
field = "";
|
|
724
|
+
};
|
|
725
|
+
const endRow = () => {
|
|
726
|
+
sink.row(cells, column + 1);
|
|
727
|
+
column = 0;
|
|
728
|
+
keep = keeps(0);
|
|
729
|
+
};
|
|
730
|
+
for (let i = 0; i < n; i++) {
|
|
731
|
+
const ch = content.charCodeAt(i);
|
|
732
|
+
if (inQuotes) {
|
|
733
|
+
if (ch === QUOTE) {
|
|
734
|
+
if (content.charCodeAt(i + 1) === QUOTE) {
|
|
735
|
+
if (keep) field += content.slice(runStart, i + 1);
|
|
736
|
+
i++;
|
|
737
|
+
} else {
|
|
738
|
+
if (keep) field += content.slice(runStart, i);
|
|
739
|
+
inQuotes = false;
|
|
740
|
+
}
|
|
741
|
+
runStart = i + 1;
|
|
742
|
+
}
|
|
743
|
+
continue;
|
|
744
|
+
}
|
|
745
|
+
if (ch === QUOTE && fieldStart) {
|
|
746
|
+
inQuotes = true;
|
|
747
|
+
fieldStart = false;
|
|
748
|
+
sawAny = true;
|
|
749
|
+
runStart = i + 1;
|
|
750
|
+
} else if (ch === COMMA) {
|
|
751
|
+
endField(i);
|
|
752
|
+
column++;
|
|
753
|
+
keep = keeps(column);
|
|
754
|
+
runStart = i + 1;
|
|
755
|
+
fieldStart = true;
|
|
756
|
+
sawAny = true;
|
|
757
|
+
} else if (ch === LINE_FEED) {
|
|
758
|
+
endField(i);
|
|
759
|
+
endRow();
|
|
760
|
+
runStart = i + 1;
|
|
761
|
+
fieldStart = true;
|
|
762
|
+
sawAny = false;
|
|
763
|
+
} else if (ch === CARRIAGE_RETURN) {
|
|
764
|
+
if (keep) field += content.slice(runStart, i);
|
|
765
|
+
runStart = i + 1;
|
|
766
|
+
} else {
|
|
767
|
+
fieldStart = false;
|
|
768
|
+
sawAny = true;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
if (sawAny) {
|
|
772
|
+
endField(n);
|
|
773
|
+
endRow();
|
|
774
|
+
}
|
|
775
|
+
return inQuotes;
|
|
776
|
+
}
|
|
777
|
+
function readCsvByCharAt(content, sink) {
|
|
676
778
|
const rows = [];
|
|
677
779
|
let row = [];
|
|
678
780
|
let field = "";
|
|
@@ -711,20 +813,30 @@ function parseCsvRows(content) {
|
|
|
711
813
|
field = "";
|
|
712
814
|
fieldStart = true;
|
|
713
815
|
sawAny = false;
|
|
714
|
-
} else if (ch
|
|
816
|
+
} else if (ch !== "\r") {
|
|
715
817
|
field += ch;
|
|
716
818
|
fieldStart = false;
|
|
717
819
|
sawAny = true;
|
|
718
820
|
}
|
|
719
821
|
}
|
|
720
|
-
if (sawAny
|
|
822
|
+
if (sawAny) {
|
|
721
823
|
row.push(field);
|
|
722
824
|
rows.push(row);
|
|
723
825
|
}
|
|
724
|
-
|
|
826
|
+
for (const r of rows) sink.row(r, r.length);
|
|
827
|
+
return inQuotes;
|
|
725
828
|
}
|
|
726
829
|
function parseCsv(content) {
|
|
727
|
-
|
|
830
|
+
const rows = [];
|
|
831
|
+
scanCsv(content, {
|
|
832
|
+
wanted: void 0,
|
|
833
|
+
row: (cells, count) => {
|
|
834
|
+
const row = [];
|
|
835
|
+
for (let c = 0; c < count; c++) row.push(ownString(cells[c]));
|
|
836
|
+
rows.push(row);
|
|
837
|
+
}
|
|
838
|
+
});
|
|
839
|
+
return rows;
|
|
728
840
|
}
|
|
729
841
|
var MISSING_COLUMN_MESSAGE = Object.freeze({
|
|
730
842
|
code: "CSV source: the configured 'code' column is not present in the header row",
|
|
@@ -741,47 +853,44 @@ function requireHeader(header, name, role) {
|
|
|
741
853
|
}
|
|
742
854
|
function parseCsvSource(source) {
|
|
743
855
|
const statusMap = source.statusMap ?? defaultStatusMapper;
|
|
744
|
-
const
|
|
745
|
-
const header = rows[0];
|
|
746
|
-
if (header === void 0) {
|
|
747
|
-
throw new TerminologyError(
|
|
748
|
-
FATAL_CODES.TERM_CODESYSTEM_MALFORMED,
|
|
749
|
-
"CSV source: the file has no header row"
|
|
750
|
-
);
|
|
751
|
-
}
|
|
752
|
-
const warnings = [];
|
|
753
|
-
if (unterminatedQuote) {
|
|
754
|
-
warnings.push(
|
|
755
|
-
Object.freeze({
|
|
756
|
-
code: DIAGNOSTIC_CODES.TERM_CSV_MALFORMED,
|
|
757
|
-
line: rows.length,
|
|
758
|
-
detail: "an opened quoted field was not terminated before end-of-input"
|
|
759
|
-
})
|
|
760
|
-
);
|
|
761
|
-
}
|
|
762
|
-
const codeIdx = requireHeader(header, source.columns.code, "code");
|
|
763
|
-
const displayIdx = requireHeader(header, source.columns.display, "display");
|
|
764
|
-
const statusIdx = source.columns.status !== void 0 ? requireHeader(header, source.columns.status, "status") : void 0;
|
|
765
|
-
const propIdx = (source.columns.properties ?? []).map((n) => ({
|
|
766
|
-
name: n,
|
|
767
|
-
index: requireHeader(header, n, "property")
|
|
768
|
-
}));
|
|
769
|
-
const needCols = Math.max(codeIdx, displayIdx, statusIdx ?? 0, ...propIdx.map((p) => p.index)) + 1;
|
|
856
|
+
const content = source.content;
|
|
770
857
|
const concepts = /* @__PURE__ */ new Map();
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
858
|
+
const warnings = [];
|
|
859
|
+
let rowCount = 0;
|
|
860
|
+
let codeIdx = 0;
|
|
861
|
+
let displayIdx = 0;
|
|
862
|
+
let statusIdx;
|
|
863
|
+
const propIdx = [];
|
|
864
|
+
let needCols = 0;
|
|
865
|
+
const header = (cells, count) => {
|
|
866
|
+
const names = cells.slice(0, count);
|
|
867
|
+
codeIdx = requireHeader(names, source.columns.code, "code");
|
|
868
|
+
displayIdx = requireHeader(names, source.columns.display, "display");
|
|
869
|
+
statusIdx = source.columns.status !== void 0 ? requireHeader(names, source.columns.status, "status") : void 0;
|
|
870
|
+
for (const n of source.columns.properties ?? []) {
|
|
871
|
+
propIdx.push({ name: n, index: requireHeader(names, n, "property") });
|
|
872
|
+
}
|
|
873
|
+
needCols = Math.max(codeIdx, displayIdx, statusIdx ?? 0, ...propIdx.map((p) => p.index)) + 1;
|
|
874
|
+
const wanted = [];
|
|
875
|
+
wanted[codeIdx] = true;
|
|
876
|
+
wanted[displayIdx] = true;
|
|
877
|
+
if (statusIdx !== void 0) wanted[statusIdx] = true;
|
|
878
|
+
for (const p of propIdx) wanted[p.index] = true;
|
|
879
|
+
sink.wanted = wanted;
|
|
880
|
+
};
|
|
881
|
+
const dataRow = (cells, count, lineNo) => {
|
|
882
|
+
if (count < needCols) {
|
|
775
883
|
warnings.push(
|
|
776
884
|
Object.freeze({
|
|
777
885
|
code: DIAGNOSTIC_CODES.TERM_CSV_MALFORMED,
|
|
778
886
|
line: lineNo,
|
|
779
|
-
detail: `row has ${String(
|
|
887
|
+
detail: `row has ${String(count)} fields, need ${String(needCols)}`
|
|
780
888
|
})
|
|
781
889
|
);
|
|
782
|
-
|
|
890
|
+
return;
|
|
783
891
|
}
|
|
784
|
-
const
|
|
892
|
+
const cell3 = (index) => cells[index];
|
|
893
|
+
const code = cell3(codeIdx).trim();
|
|
785
894
|
if (code === "") {
|
|
786
895
|
warnings.push(
|
|
787
896
|
Object.freeze({
|
|
@@ -790,23 +899,47 @@ function parseCsvSource(source) {
|
|
|
790
899
|
detail: "row is missing its code"
|
|
791
900
|
})
|
|
792
901
|
);
|
|
793
|
-
|
|
902
|
+
return;
|
|
794
903
|
}
|
|
795
|
-
if (concepts.has(code))
|
|
796
|
-
const out = { code, properties: [] };
|
|
797
|
-
const display = (
|
|
798
|
-
if (display !== "") out.display = display;
|
|
904
|
+
if (concepts.has(code)) return;
|
|
905
|
+
const out = { code: ownString(code), properties: [] };
|
|
906
|
+
const display = cell3(displayIdx).trim();
|
|
907
|
+
if (display !== "") out.display = ownString(display);
|
|
799
908
|
if (statusIdx !== void 0) {
|
|
800
|
-
const rawStatus = (
|
|
909
|
+
const rawStatus = ownString(cell3(statusIdx).trim());
|
|
801
910
|
out.status = makeStatus(statusMap(rawStatus), rawStatus);
|
|
802
911
|
}
|
|
803
912
|
const props = [];
|
|
804
913
|
for (const p of propIdx) {
|
|
805
|
-
const value = (
|
|
806
|
-
if (value !== "") props.push(Object.freeze({ code: p.name, value }));
|
|
914
|
+
const value = cell3(p.index).trim();
|
|
915
|
+
if (value !== "") props.push(Object.freeze({ code: p.name, value: ownString(value) }));
|
|
807
916
|
}
|
|
808
917
|
out.properties = Object.freeze(props);
|
|
809
|
-
concepts.set(code, Object.freeze(out));
|
|
918
|
+
concepts.set(out.code, Object.freeze(out));
|
|
919
|
+
};
|
|
920
|
+
const sink = {
|
|
921
|
+
wanted: void 0,
|
|
922
|
+
row: (cells, count) => {
|
|
923
|
+
rowCount++;
|
|
924
|
+
if (rowCount === 1) header(cells, count);
|
|
925
|
+
else dataRow(cells, count, rowCount);
|
|
926
|
+
}
|
|
927
|
+
};
|
|
928
|
+
const unterminatedQuote = scanCsv(content, sink);
|
|
929
|
+
if (rowCount === 0) {
|
|
930
|
+
throw new TerminologyError(
|
|
931
|
+
FATAL_CODES.TERM_CODESYSTEM_MALFORMED,
|
|
932
|
+
"CSV source: the file has no header row"
|
|
933
|
+
);
|
|
934
|
+
}
|
|
935
|
+
if (unterminatedQuote) {
|
|
936
|
+
warnings.unshift(
|
|
937
|
+
Object.freeze({
|
|
938
|
+
code: DIAGNOSTIC_CODES.TERM_CSV_MALFORMED,
|
|
939
|
+
line: rowCount,
|
|
940
|
+
detail: "an opened quoted field was not terminated before end-of-input"
|
|
941
|
+
})
|
|
942
|
+
);
|
|
810
943
|
}
|
|
811
944
|
return { concepts, warnings };
|
|
812
945
|
}
|
|
@@ -854,9 +987,10 @@ function collectConcepts(rawConcepts, into, warnings, parentCode) {
|
|
|
854
987
|
if (code !== void 0 && code !== "" && !into.has(code)) {
|
|
855
988
|
const props = [];
|
|
856
989
|
for (const p of getArray(raw, "property") ?? []) {
|
|
990
|
+
if (!isJsonObject(p)) continue;
|
|
857
991
|
const pcode = getString(p, "code");
|
|
858
992
|
if (pcode === void 0) continue;
|
|
859
|
-
const value =
|
|
993
|
+
const value = readPropertyValue(p);
|
|
860
994
|
if (value !== void 0) props.push(Object.freeze({ code: pcode, value }));
|
|
861
995
|
}
|
|
862
996
|
if (parentCode !== void 0 && !props.some((p) => p.code === "parent" && p.value === parentCode)) {
|
|
@@ -919,9 +1053,21 @@ var ICD10CM_ORDER_FILE_FIELDS = Object.freeze({
|
|
|
919
1053
|
Object.freeze({ name: "shortDescription", slice: Object.freeze({ start: 16, end: 76 }) })
|
|
920
1054
|
])
|
|
921
1055
|
});
|
|
1056
|
+
function requirePropertyFields(fields) {
|
|
1057
|
+
for (const p of fields.properties ?? []) {
|
|
1058
|
+
const entry = p;
|
|
1059
|
+
if (typeof entry !== "object" || entry === null) {
|
|
1060
|
+
throw new TerminologyError(
|
|
1061
|
+
FATAL_CODES.TERM_CODESYSTEM_MALFORMED,
|
|
1062
|
+
"fixed-width source: a configured property field is not an object"
|
|
1063
|
+
);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
922
1067
|
function parseFixedWidth(source) {
|
|
923
1068
|
const statusMap = source.statusMap ?? defaultStatusMapper;
|
|
924
1069
|
const fields = source.fields;
|
|
1070
|
+
requirePropertyFields(fields);
|
|
925
1071
|
const concepts = /* @__PURE__ */ new Map();
|
|
926
1072
|
const warnings = [];
|
|
927
1073
|
const lines = source.content.split(/\r?\n/);
|
|
@@ -983,7 +1129,16 @@ function parseRrfLine(line) {
|
|
|
983
1129
|
function maxColumn(source) {
|
|
984
1130
|
const { code, display, status, properties } = source.columns;
|
|
985
1131
|
let max = Math.max(code, display, status ?? 0);
|
|
986
|
-
for (const p of properties ?? [])
|
|
1132
|
+
for (const p of properties ?? []) {
|
|
1133
|
+
const entry = p;
|
|
1134
|
+
if (typeof entry !== "object" || entry === null) {
|
|
1135
|
+
throw new TerminologyError(
|
|
1136
|
+
FATAL_CODES.TERM_CODESYSTEM_MALFORMED,
|
|
1137
|
+
"RRF source: a configured property column is not an object"
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1140
|
+
max = Math.max(max, p.column);
|
|
1141
|
+
}
|
|
987
1142
|
return max;
|
|
988
1143
|
}
|
|
989
1144
|
function cell(cells, index) {
|
|
@@ -1044,6 +1199,10 @@ function parseRrf(source) {
|
|
|
1044
1199
|
}
|
|
1045
1200
|
|
|
1046
1201
|
// src/codesystem/load.ts
|
|
1202
|
+
var loadedConcepts = /* @__PURE__ */ new WeakSet();
|
|
1203
|
+
function isLoadedConcepts(concepts) {
|
|
1204
|
+
return loadedConcepts.has(concepts);
|
|
1205
|
+
}
|
|
1047
1206
|
function loadCodeSystem(source) {
|
|
1048
1207
|
let concepts;
|
|
1049
1208
|
let warnings;
|
|
@@ -1082,6 +1241,7 @@ function loadCodeSystem(source) {
|
|
|
1082
1241
|
}
|
|
1083
1242
|
out.count = concepts.size;
|
|
1084
1243
|
out.concepts = frozenMap(concepts, "a loaded CodeSystem's concepts map");
|
|
1244
|
+
loadedConcepts.add(out.concepts);
|
|
1085
1245
|
out.warnings = Object.freeze(warnings);
|
|
1086
1246
|
return Object.freeze(out);
|
|
1087
1247
|
}
|
|
@@ -1284,8 +1444,11 @@ function directParents(concept) {
|
|
|
1284
1444
|
return parents;
|
|
1285
1445
|
}
|
|
1286
1446
|
function buildSubsumption(cs) {
|
|
1447
|
+
return subsumptionOver(cs.concepts);
|
|
1448
|
+
}
|
|
1449
|
+
function subsumptionOver(concepts) {
|
|
1287
1450
|
const parentsOf = /* @__PURE__ */ new Map();
|
|
1288
|
-
for (const concept of
|
|
1451
|
+
for (const concept of concepts.values()) {
|
|
1289
1452
|
const parents = directParents(concept);
|
|
1290
1453
|
if (parents.length > 0) parentsOf.set(concept.code, parents);
|
|
1291
1454
|
}
|
|
@@ -1306,6 +1469,17 @@ function buildSubsumption(cs) {
|
|
|
1306
1469
|
};
|
|
1307
1470
|
return { ancestorsOf };
|
|
1308
1471
|
}
|
|
1472
|
+
var loadedSubsumption = /* @__PURE__ */ new WeakMap();
|
|
1473
|
+
function subsumptionOf(cs) {
|
|
1474
|
+
const concepts = cs.concepts;
|
|
1475
|
+
if (!isLoadedConcepts(concepts)) return subsumptionOver(concepts);
|
|
1476
|
+
let sub = loadedSubsumption.get(concepts);
|
|
1477
|
+
if (sub === void 0) {
|
|
1478
|
+
sub = subsumptionOver(concepts);
|
|
1479
|
+
loadedSubsumption.set(concepts, sub);
|
|
1480
|
+
}
|
|
1481
|
+
return sub;
|
|
1482
|
+
}
|
|
1309
1483
|
function isA(sub, code, anchor) {
|
|
1310
1484
|
return code === anchor || sub.ancestorsOf(code).has(anchor);
|
|
1311
1485
|
}
|
|
@@ -1390,8 +1564,7 @@ function makeCoding(system, code, display, version) {
|
|
|
1390
1564
|
return coding(init);
|
|
1391
1565
|
}
|
|
1392
1566
|
function cannotExpand(detail, path) {
|
|
1393
|
-
const d = { code: "TERM_VALUESET_CANNOT_EXPAND", detail };
|
|
1394
|
-
if (path !== void 0) d.path = path;
|
|
1567
|
+
const d = { code: "TERM_VALUESET_CANNOT_EXPAND", detail, path };
|
|
1395
1568
|
return Object.freeze(d);
|
|
1396
1569
|
}
|
|
1397
1570
|
function truncated(detail, path) {
|
|
@@ -1405,9 +1578,9 @@ function truncated(detail, path) {
|
|
|
1405
1578
|
function enumeratedUndefined(detail, path) {
|
|
1406
1579
|
const d = {
|
|
1407
1580
|
code: "TERM_VALUESET_ENUMERATED_CODE_UNDEFINED",
|
|
1408
|
-
detail
|
|
1581
|
+
detail,
|
|
1582
|
+
path
|
|
1409
1583
|
};
|
|
1410
|
-
if (path !== void 0) d.path = path;
|
|
1411
1584
|
return Object.freeze(d);
|
|
1412
1585
|
}
|
|
1413
1586
|
function expansionIncompleteDetail(unclosed) {
|
|
@@ -1441,7 +1614,8 @@ function screenActive(members, component, ctx) {
|
|
|
1441
1614
|
}
|
|
1442
1615
|
function underPath(d, prefix) {
|
|
1443
1616
|
const out = { code: d.code, detail: d.detail };
|
|
1444
|
-
|
|
1617
|
+
if (d.path === void 0) out.path = prefix;
|
|
1618
|
+
else out.path = `${prefix}/${d.path}`;
|
|
1445
1619
|
return Object.freeze(out);
|
|
1446
1620
|
}
|
|
1447
1621
|
function intersectInto(into, other) {
|
|
@@ -1637,8 +1811,7 @@ function expand(vs, ctx = {}) {
|
|
|
1637
1811
|
|
|
1638
1812
|
// src/valueset/validate.ts
|
|
1639
1813
|
function cannotExpand2(detail, path) {
|
|
1640
|
-
const d = { code: "TERM_VALUESET_CANNOT_EXPAND", detail };
|
|
1641
|
-
if (path !== void 0) d.path = path;
|
|
1814
|
+
const d = { code: "TERM_VALUESET_CANNOT_EXPAND", detail, path };
|
|
1642
1815
|
return Object.freeze(d);
|
|
1643
1816
|
}
|
|
1644
1817
|
function expansionIncompleteDetail2(unclosed) {
|
|
@@ -1656,7 +1829,8 @@ function usableRelease2(component, system, ctx) {
|
|
|
1656
1829
|
}
|
|
1657
1830
|
function underPath2(d, prefix) {
|
|
1658
1831
|
const out = { code: d.code, detail: d.detail };
|
|
1659
|
-
|
|
1832
|
+
if (d.path === void 0) out.path = prefix;
|
|
1833
|
+
else out.path = `${prefix}/${d.path}`;
|
|
1660
1834
|
return Object.freeze(out);
|
|
1661
1835
|
}
|
|
1662
1836
|
function matchComponent(target, component, ctx, visited, path, activeOnly = false) {
|
|
@@ -1708,7 +1882,7 @@ function matchComponent(target, component, ctx, visited, path, activeOnly = fals
|
|
|
1708
1882
|
baseComplete = false;
|
|
1709
1883
|
} else {
|
|
1710
1884
|
const concpt = cs.concepts.get(target.code);
|
|
1711
|
-
baseMatched = concpt !== void 0 && matchesAllFilters(concpt, filter,
|
|
1885
|
+
baseMatched = concpt !== void 0 && matchesAllFilters(concpt, filter, subsumptionOf(cs)).matched;
|
|
1712
1886
|
}
|
|
1713
1887
|
} else {
|
|
1714
1888
|
baseMatched = cs.concepts.get(target.code) !== void 0;
|
|
@@ -1716,10 +1890,13 @@ function matchComponent(target, component, ctx, visited, path, activeOnly = fals
|
|
|
1716
1890
|
}
|
|
1717
1891
|
}
|
|
1718
1892
|
if (system !== void 0 && target.system === void 0 && baseComplete) baseMatched = false;
|
|
1893
|
+
if (baseMatched === null && !hasVs) return { matched: false, complete: true, diagnostics };
|
|
1719
1894
|
let refDefiniteFalse = false;
|
|
1720
1895
|
let refUndetermined = false;
|
|
1721
1896
|
if (hasVs) {
|
|
1897
|
+
let refsRead = 0;
|
|
1722
1898
|
for (const [i, url] of valueSet2.entries()) {
|
|
1899
|
+
refsRead++;
|
|
1723
1900
|
const refPath = `${path}.valueSet[${String(i)}]`;
|
|
1724
1901
|
if (visited.has(url)) {
|
|
1725
1902
|
diagnostics.push(cannotExpand2("cyclic value set reference", refPath));
|
|
@@ -1740,6 +1917,7 @@ function matchComponent(target, component, ctx, visited, path, activeOnly = fals
|
|
|
1740
1917
|
refDefiniteFalse = true;
|
|
1741
1918
|
}
|
|
1742
1919
|
}
|
|
1920
|
+
if (refsRead === 0) refDefiniteFalse = true;
|
|
1743
1921
|
}
|
|
1744
1922
|
const baseDefiniteFalse = baseMatched === false && baseComplete;
|
|
1745
1923
|
const baseDefiniteTrue = baseMatched === null || baseMatched === true && baseComplete;
|
|
@@ -3991,7 +4169,32 @@ function atBoundary(s, pos) {
|
|
|
3991
4169
|
const c = s[pos];
|
|
3992
4170
|
return c === "." || c === "/" || c === ")";
|
|
3993
4171
|
}
|
|
4172
|
+
function prefixRank(m) {
|
|
4173
|
+
return m.prefix ? 1 : 0;
|
|
4174
|
+
}
|
|
4175
|
+
function byPreference(a, b) {
|
|
4176
|
+
return b.len - a.len || prefixRank(a) - prefixRank(b);
|
|
4177
|
+
}
|
|
3994
4178
|
function simpleMatches(essence, s, pos) {
|
|
4179
|
+
if (typeof s !== "string") return simpleMatchesByScan(essence, s, pos);
|
|
4180
|
+
const index = indexOf(essence);
|
|
4181
|
+
const out = [];
|
|
4182
|
+
for (const atom of index.atoms.get(s.charCodeAt(pos)) ?? NONE) {
|
|
4183
|
+
if (s.startsWith(atom.code, pos)) out.push({ atom, len: atom.code.length });
|
|
4184
|
+
}
|
|
4185
|
+
for (const prefix of index.prefixes.get(s.charCodeAt(pos)) ?? NONE) {
|
|
4186
|
+
if (!s.startsWith(prefix.code, pos)) continue;
|
|
4187
|
+
const rem = pos + prefix.code.length;
|
|
4188
|
+
for (const atom of index.metricAtoms.get(s.charCodeAt(rem)) ?? NONE) {
|
|
4189
|
+
if (s.startsWith(atom.code, rem)) {
|
|
4190
|
+
out.push({ prefix, atom, len: prefix.code.length + atom.code.length });
|
|
4191
|
+
}
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
out.sort(byPreference);
|
|
4195
|
+
return out;
|
|
4196
|
+
}
|
|
4197
|
+
function simpleMatchesByScan(essence, s, pos) {
|
|
3995
4198
|
const out = [];
|
|
3996
4199
|
for (const atom of essence.atoms) {
|
|
3997
4200
|
if (s.startsWith(atom.code, pos)) out.push({ atom, len: atom.code.length });
|
|
@@ -4005,9 +4208,33 @@ function simpleMatches(essence, s, pos) {
|
|
|
4005
4208
|
}
|
|
4006
4209
|
}
|
|
4007
4210
|
}
|
|
4008
|
-
out.sort(
|
|
4211
|
+
out.sort(byPreference);
|
|
4212
|
+
return out;
|
|
4213
|
+
}
|
|
4214
|
+
var NONE = Object.freeze([]);
|
|
4215
|
+
var firstCharIndexes = /* @__PURE__ */ new WeakMap();
|
|
4216
|
+
function byFirstChar(items) {
|
|
4217
|
+
const out = /* @__PURE__ */ new Map();
|
|
4218
|
+
for (const item of items) {
|
|
4219
|
+
const first = item.code.charCodeAt(0);
|
|
4220
|
+
const list = out.get(first);
|
|
4221
|
+
if (list === void 0) out.set(first, [item]);
|
|
4222
|
+
else list.push(item);
|
|
4223
|
+
}
|
|
4009
4224
|
return out;
|
|
4010
4225
|
}
|
|
4226
|
+
function indexOf(essence) {
|
|
4227
|
+
let index = firstCharIndexes.get(essence);
|
|
4228
|
+
if (index === void 0) {
|
|
4229
|
+
index = {
|
|
4230
|
+
atoms: byFirstChar(essence.atoms),
|
|
4231
|
+
metricAtoms: byFirstChar(essence.atoms.filter((a) => a.metric)),
|
|
4232
|
+
prefixes: byFirstChar(essence.prefixes)
|
|
4233
|
+
};
|
|
4234
|
+
firstCharIndexes.set(essence, index);
|
|
4235
|
+
}
|
|
4236
|
+
return index;
|
|
4237
|
+
}
|
|
4011
4238
|
var MAX_PAREN_DEPTH = 100;
|
|
4012
4239
|
function parseExponent(cur) {
|
|
4013
4240
|
const { s } = cur;
|
|
@@ -4040,8 +4267,8 @@ function parseAnnotation(cur) {
|
|
|
4040
4267
|
return { ok: false, reason: "annotation is not closed with '}'" };
|
|
4041
4268
|
}
|
|
4042
4269
|
function parseSimpleUnit(cur) {
|
|
4043
|
-
const
|
|
4044
|
-
for (const cand of
|
|
4270
|
+
const candidates2 = simpleMatches(cur.essence, cur.s, cur.pos);
|
|
4271
|
+
for (const cand of candidates2) {
|
|
4045
4272
|
const save = cur.pos;
|
|
4046
4273
|
cur.pos = save + cand.len;
|
|
4047
4274
|
const exp = parseExponent(cur);
|
|
@@ -4267,57 +4494,62 @@ function isNoMapSentinel(target) {
|
|
|
4267
4494
|
return target === NO_DX || target === NO_PCS;
|
|
4268
4495
|
}
|
|
4269
4496
|
function decodeFlags(raw) {
|
|
4270
|
-
if (!/^[0-9]{5}$/.test(raw)) return void 0;
|
|
4271
4497
|
return Object.freeze({
|
|
4272
|
-
approximate: raw
|
|
4273
|
-
noMap: raw
|
|
4274
|
-
combination: raw
|
|
4275
|
-
scenario:
|
|
4276
|
-
choiceList:
|
|
4498
|
+
approximate: raw.charCodeAt(0) === DIGIT_ONE,
|
|
4499
|
+
noMap: raw.charCodeAt(1) === DIGIT_ONE,
|
|
4500
|
+
combination: raw.charCodeAt(2) === DIGIT_ONE,
|
|
4501
|
+
scenario: raw.charCodeAt(3) - DIGIT_ZERO,
|
|
4502
|
+
choiceList: raw.charCodeAt(4) - DIGIT_ZERO,
|
|
4277
4503
|
raw
|
|
4278
4504
|
});
|
|
4279
4505
|
}
|
|
4506
|
+
var DIGIT_ZERO = 48;
|
|
4507
|
+
var DIGIT_ONE = 49;
|
|
4508
|
+
var DIGIT_NINE = 57;
|
|
4509
|
+
var SPACE = 32;
|
|
4510
|
+
var NON_ASCII_SPACE = /^\s$/;
|
|
4511
|
+
function isSpace(c) {
|
|
4512
|
+
if (c < 128) return c === SPACE || c >= 9 && c <= 13;
|
|
4513
|
+
return NON_ASCII_SPACE.test(String.fromCharCode(c));
|
|
4514
|
+
}
|
|
4280
4515
|
function loadGems(source) {
|
|
4281
4516
|
const entries = /* @__PURE__ */ new Map();
|
|
4282
4517
|
const warnings = [];
|
|
4283
4518
|
let count = 0;
|
|
4284
|
-
const
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
if (raw === void 0) continue;
|
|
4288
|
-
const trimmed = raw.trim();
|
|
4289
|
-
if (trimmed === "") continue;
|
|
4290
|
-
const fields = trimmed.split(/\s+/);
|
|
4291
|
-
if (fields.length !== 3) {
|
|
4519
|
+
const sink = {
|
|
4520
|
+
flags: /* @__PURE__ */ new Map(),
|
|
4521
|
+
malformed: (lineNo, fieldCount) => {
|
|
4292
4522
|
warnings.push(
|
|
4293
4523
|
Object.freeze({
|
|
4294
4524
|
code: "TERM_GEM_MALFORMED_ROW",
|
|
4295
|
-
line:
|
|
4296
|
-
detail: `expected 3 whitespace-delimited fields, found ${String(
|
|
4525
|
+
line: lineNo,
|
|
4526
|
+
detail: `expected 3 whitespace-delimited fields, found ${String(fieldCount)}`
|
|
4297
4527
|
})
|
|
4298
4528
|
);
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4529
|
+
},
|
|
4530
|
+
line: (lineNo, src, tgt, flags) => {
|
|
4531
|
+
if (flags === void 0) {
|
|
4532
|
+
warnings.push(
|
|
4533
|
+
Object.freeze({
|
|
4534
|
+
code: "TERM_GEM_MALFORMED_ROW",
|
|
4535
|
+
line: lineNo,
|
|
4536
|
+
detail: "flag field is not a 5-digit code"
|
|
4537
|
+
})
|
|
4538
|
+
);
|
|
4539
|
+
return;
|
|
4540
|
+
}
|
|
4541
|
+
const frozen = Object.freeze(
|
|
4542
|
+
isNoMapSentinel(tgt) ? { source: src, flags } : { source: src, flags, target: tgt }
|
|
4310
4543
|
);
|
|
4311
|
-
|
|
4544
|
+
const list = entries.get(src);
|
|
4545
|
+
if (list) list.push(frozen);
|
|
4546
|
+
else entries.set(src, [frozen]);
|
|
4547
|
+
count++;
|
|
4312
4548
|
}
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
if (list) list.push(frozen);
|
|
4318
|
-
else entries.set(src, [frozen]);
|
|
4319
|
-
count++;
|
|
4320
|
-
}
|
|
4549
|
+
};
|
|
4550
|
+
const content = source.content;
|
|
4551
|
+
if (typeof content === "string") readLinesInPlace(content, sink);
|
|
4552
|
+
else readLinesBySplit(content, sink);
|
|
4321
4553
|
for (const list of entries.values()) Object.freeze(list);
|
|
4322
4554
|
return Object.freeze({
|
|
4323
4555
|
direction: source.direction,
|
|
@@ -4327,6 +4559,90 @@ function loadGems(source) {
|
|
|
4327
4559
|
warnings: Object.freeze(warnings)
|
|
4328
4560
|
});
|
|
4329
4561
|
}
|
|
4562
|
+
function sharedFlags(sink, text, from, to) {
|
|
4563
|
+
const key = fiveDigitsAt(text, from, to);
|
|
4564
|
+
if (key === -1) return void 0;
|
|
4565
|
+
let flags = sink.flags.get(key);
|
|
4566
|
+
if (flags === void 0) {
|
|
4567
|
+
flags = decodeFlags(text.slice(from, to));
|
|
4568
|
+
sink.flags.set(key, flags);
|
|
4569
|
+
}
|
|
4570
|
+
return flags;
|
|
4571
|
+
}
|
|
4572
|
+
function fiveDigitsAt(content, from, to) {
|
|
4573
|
+
if (to - from !== 5) return -1;
|
|
4574
|
+
let value = 0;
|
|
4575
|
+
for (let i = from; i < to; i++) {
|
|
4576
|
+
const c = content.charCodeAt(i);
|
|
4577
|
+
if (c < DIGIT_ZERO || c > DIGIT_NINE) return -1;
|
|
4578
|
+
value = value * 10 + (c - DIGIT_ZERO);
|
|
4579
|
+
}
|
|
4580
|
+
return value;
|
|
4581
|
+
}
|
|
4582
|
+
function readLinesInPlace(content, sink) {
|
|
4583
|
+
const n = content.length;
|
|
4584
|
+
let lineNo = 0;
|
|
4585
|
+
for (let start = 0; start <= n; ) {
|
|
4586
|
+
let end = content.indexOf("\n", start);
|
|
4587
|
+
if (end === -1) end = n;
|
|
4588
|
+
lineNo++;
|
|
4589
|
+
let fieldCount = 0;
|
|
4590
|
+
let srcStart = 0;
|
|
4591
|
+
let srcEnd = 0;
|
|
4592
|
+
let tgtStart = 0;
|
|
4593
|
+
let tgtEnd = 0;
|
|
4594
|
+
let flagStart = 0;
|
|
4595
|
+
let flagEnd = 0;
|
|
4596
|
+
for (let i = start; i < end; ) {
|
|
4597
|
+
if (isSpace(content.charCodeAt(i))) {
|
|
4598
|
+
i++;
|
|
4599
|
+
continue;
|
|
4600
|
+
}
|
|
4601
|
+
const from = i;
|
|
4602
|
+
while (i < end && !isSpace(content.charCodeAt(i))) i++;
|
|
4603
|
+
fieldCount++;
|
|
4604
|
+
if (fieldCount === 1) {
|
|
4605
|
+
srcStart = from;
|
|
4606
|
+
srcEnd = i;
|
|
4607
|
+
} else if (fieldCount === 2) {
|
|
4608
|
+
tgtStart = from;
|
|
4609
|
+
tgtEnd = i;
|
|
4610
|
+
} else if (fieldCount === 3) {
|
|
4611
|
+
flagStart = from;
|
|
4612
|
+
flagEnd = i;
|
|
4613
|
+
}
|
|
4614
|
+
}
|
|
4615
|
+
start = end + 1;
|
|
4616
|
+
if (fieldCount === 0) continue;
|
|
4617
|
+
if (fieldCount !== 3) {
|
|
4618
|
+
sink.malformed(lineNo, fieldCount);
|
|
4619
|
+
continue;
|
|
4620
|
+
}
|
|
4621
|
+
const flags = sharedFlags(sink, content, flagStart, flagEnd);
|
|
4622
|
+
sink.line(
|
|
4623
|
+
lineNo,
|
|
4624
|
+
ownString(content.slice(srcStart, srcEnd)),
|
|
4625
|
+
ownString(content.slice(tgtStart, tgtEnd)),
|
|
4626
|
+
flags
|
|
4627
|
+
);
|
|
4628
|
+
}
|
|
4629
|
+
}
|
|
4630
|
+
function readLinesBySplit(content, sink) {
|
|
4631
|
+
const lines = content.split(/\r?\n/);
|
|
4632
|
+
for (let i = 0; i < lines.length; i++) {
|
|
4633
|
+
const raw = lines[i];
|
|
4634
|
+
if (raw === void 0) continue;
|
|
4635
|
+
const trimmed = raw.trim();
|
|
4636
|
+
if (trimmed === "") continue;
|
|
4637
|
+
const fields = trimmed.split(/\s+/);
|
|
4638
|
+
if (fields.length !== 3) {
|
|
4639
|
+
sink.malformed(i + 1, fields.length);
|
|
4640
|
+
continue;
|
|
4641
|
+
}
|
|
4642
|
+
const [src, tgt, flagStr] = fields;
|
|
4643
|
+
sink.line(i + 1, src, tgt, sharedFlags(sink, flagStr, 0, flagStr.length));
|
|
4644
|
+
}
|
|
4645
|
+
}
|
|
4330
4646
|
function buildCombinations(entries) {
|
|
4331
4647
|
const combo = entries.filter((e) => e.flags.combination && e.target !== void 0);
|
|
4332
4648
|
if (combo.length === 0) return void 0;
|
|
@@ -4410,7 +4726,7 @@ var MAP_CATEGORIES = {
|
|
|
4410
4726
|
NO_MAP: "447638001",
|
|
4411
4727
|
/** `447639009`: "Map of source concept is context dependent" (needs runtime patient context). */
|
|
4412
4728
|
CONTEXT_DEPENDENT: "447639009",
|
|
4413
|
-
/** `447640006`: "Source concept is ambiguous" (
|
|
4729
|
+
/** `447640006`: "Source concept is ambiguous" (carried through on the result; the rule decides). */
|
|
4414
4730
|
AMBIGUOUS: "447640006"
|
|
4415
4731
|
};
|
|
4416
4732
|
var NO_MAP_CATEGORIES = /* @__PURE__ */ new Set([MAP_CATEGORIES.NO_MAP]);
|
|
@@ -4543,8 +4859,15 @@ function evaluateConjunct(clause, context) {
|
|
|
4543
4859
|
const bound = Number(ageMatch[2]);
|
|
4544
4860
|
if (context.ageYears === void 0 || !Number.isFinite(bound)) return "unknown";
|
|
4545
4861
|
const age = context.ageYears;
|
|
4546
|
-
|
|
4547
|
-
if (
|
|
4862
|
+
let ok;
|
|
4863
|
+
if (op === "<=") ok = age <= bound;
|
|
4864
|
+
else if (op === ">=") ok = age >= bound;
|
|
4865
|
+
else if (op === "<") ok = age < bound;
|
|
4866
|
+
else if (op === ">") ok = age > bound;
|
|
4867
|
+
else {
|
|
4868
|
+
if (op === "=") ok = age === bound;
|
|
4869
|
+
else return "unknown";
|
|
4870
|
+
}
|
|
4548
4871
|
return ok ? "match" : "no-match";
|
|
4549
4872
|
}
|
|
4550
4873
|
return "unknown";
|
|
@@ -4963,7 +5286,8 @@ function jaccard(a, b) {
|
|
|
4963
5286
|
let inter = 0;
|
|
4964
5287
|
for (const t of a) if (b.has(t)) inter++;
|
|
4965
5288
|
const union = a.size + b.size - inter;
|
|
4966
|
-
|
|
5289
|
+
if (union === 0) return 0;
|
|
5290
|
+
return inter / union;
|
|
4967
5291
|
}
|
|
4968
5292
|
function approximateMatch(graph, query, options = {}) {
|
|
4969
5293
|
const minScore = options.minScore ?? 0.34;
|
|
@@ -4980,7 +5304,7 @@ function approximateMatch(graph, query, options = {}) {
|
|
|
4980
5304
|
}
|
|
4981
5305
|
|
|
4982
5306
|
// src/index.ts
|
|
4983
|
-
var VERSION = "0.1.
|
|
5307
|
+
var VERSION = "0.1.7";
|
|
4984
5308
|
|
|
4985
5309
|
export { COMPLEX_MAP_SOURCE_SYSTEM, DIAGNOSTIC_CODES, FATAL_CODES, HL7_V2_OID_ROOT, HL7_V2_URL_PREFIX, ICD10CM_ORDER_FILE_FIELDS, ICD10CM_SYSTEM, ICD9CM_SYSTEM, MAP_CATEGORIES, NO_MAP_CATEGORIES, RELA, RELA_INVERSE, RXNORM_SYSTEM, SNOMEDCT_SYSTEM, SYSTEM_IDENTITIES, TERM_TYPES, TerminologyError, VERSION, applyComplexMap, applyGem, approximateMatch, asTermType, brandsFor, buildSubsumption, codeableConcept, coding, consistsOf, defaultStatusMapper, doseFormsOf, expand, genericFor, getArray, getBoolean, getConcept, getNumber, getString, ingredientsOf, invertGem, isA, isJsonObject, isSynonymTermType, isUnknownSystem, loadCodeSystem, loadComplexMap, loadConceptMap, loadGems, loadRxNormGraph, loadUcumEssence, loadValueSet, lookup, makeStatus, matchesFilter, parseCsv, parseCsvSource, parseFhirCodeSystem, parseFixedWidth, parseRrf, parseRrfLine, parseUcum, reduce, relatedByRela, resolveNdc, resolveSystem, sliceField, translate, ucumEqual, unsupportedOps, validateCode, validateCodeInValueSet, validateUcum };
|
|
4986
5310
|
//# sourceMappingURL=index.mjs.map
|