@cosyte/terminology 0.0.11 → 0.0.13
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 +194 -0
- package/README.md +33 -33
- package/dist/index.cjs +51 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +359 -359
- package/dist/index.d.ts +359 -359
- package/dist/index.mjs +51 -51
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
- package/vendor/ucum/NOTICE.md +4 -4
package/dist/index.cjs
CHANGED
|
@@ -20,7 +20,7 @@ function codeableConcept(init) {
|
|
|
20
20
|
// src/common/diagnostics.ts
|
|
21
21
|
var DIAGNOSTIC_CODES = {
|
|
22
22
|
/**
|
|
23
|
-
* A `$translate` found no target for the source code. A **first-class outcome, never an error
|
|
23
|
+
* A `$translate` found no target for the source code. A **first-class outcome, never an error**:
|
|
24
24
|
* the source is surfaced as `unmapped`, never replaced with a guessed target (the never-fabricate
|
|
25
25
|
* invariant).
|
|
26
26
|
*/
|
|
@@ -31,30 +31,30 @@ var DIAGNOSTIC_CODES = {
|
|
|
31
31
|
*/
|
|
32
32
|
TERM_SYSTEM_UNRECOGNIZED: "TERM_SYSTEM_UNRECOGNIZED",
|
|
33
33
|
/**
|
|
34
|
-
* An RRF (pipe-delimited RxNorm/UMLS release) row was structurally unusable
|
|
34
|
+
* An RRF (pipe-delimited RxNorm/UMLS release) row was structurally unusable: too few columns to
|
|
35
35
|
* reach a configured field, or a missing code. The row is **skipped and surfaced** as a load
|
|
36
36
|
* warning (liberal on load), never kept as a partially-parsed concept.
|
|
37
37
|
*/
|
|
38
38
|
TERM_RRF_MALFORMED_ROW: "TERM_RRF_MALFORMED_ROW",
|
|
39
39
|
/**
|
|
40
|
-
* A CSV (RFC-4180, e.g. LOINC `Loinc.csv`) row was structurally unusable
|
|
40
|
+
* A CSV (RFC-4180, e.g. LOINC `Loinc.csv`) row was structurally unusable: too few fields to reach
|
|
41
41
|
* a configured column. The row is **skipped and surfaced** as a load warning, never partial.
|
|
42
42
|
*/
|
|
43
43
|
TERM_CSV_MALFORMED: "TERM_CSV_MALFORMED",
|
|
44
44
|
/**
|
|
45
|
-
* A fixed-width (e.g. ICD-10-CM order file) row was structurally unusable
|
|
45
|
+
* A fixed-width (e.g. ICD-10-CM order file) row was structurally unusable: too short to contain
|
|
46
46
|
* the configured code field, or a missing code. Skipped and surfaced, never partial.
|
|
47
47
|
*/
|
|
48
48
|
TERM_FIXED_WIDTH_MALFORMED: "TERM_FIXED_WIDTH_MALFORMED",
|
|
49
49
|
/**
|
|
50
|
-
* A concept inside a FHIR `CodeSystem` resource was unusable
|
|
50
|
+
* A concept inside a FHIR `CodeSystem` resource was unusable: not an object, or missing its
|
|
51
51
|
* required `code`. Skipped and surfaced (the whole resource still loads); `line` is `0` since a
|
|
52
52
|
* JSON concept is not line-addressable.
|
|
53
53
|
*/
|
|
54
54
|
TERM_FHIR_CONCEPT_MALFORMED: "TERM_FHIR_CONCEPT_MALFORMED",
|
|
55
55
|
/**
|
|
56
56
|
* A `$lookup`/`$validate-code` found no concept for the code in the loaded release. A **first-class
|
|
57
|
-
* typed outcome, never a guess
|
|
57
|
+
* typed outcome, never a guess**: the engine returns `unknown`/`valid: false`, never a fabricated
|
|
58
58
|
* display or a coerced `valid: true` (the never-fabricate invariant, applied to code identity).
|
|
59
59
|
*/
|
|
60
60
|
TERM_CODE_UNKNOWN: "TERM_CODE_UNKNOWN",
|
|
@@ -71,7 +71,7 @@ var DIAGNOSTIC_CODES = {
|
|
|
71
71
|
*/
|
|
72
72
|
TERM_CONCEPT_HEADER_NOT_BILLABLE: "TERM_CONCEPT_HEADER_NOT_BILLABLE",
|
|
73
73
|
/**
|
|
74
|
-
* A ValueSet `compose` part could **not be expanded
|
|
74
|
+
* A ValueSet `compose` part could **not be expanded**: an intensional `include`/`exclude` whose
|
|
75
75
|
* code system was not supplied, an unresolvable referenced value set, or a `filter` operator the
|
|
76
76
|
* engine does not implement. Surfaced as a typed outcome that marks the expansion **incomplete**;
|
|
77
77
|
* the engine **never** fabricates a member and **never** returns a silently-empty "no members"
|
|
@@ -79,14 +79,14 @@ var DIAGNOSTIC_CODES = {
|
|
|
79
79
|
*/
|
|
80
80
|
TERM_VALUESET_CANNOT_EXPAND: "TERM_VALUESET_CANNOT_EXPAND",
|
|
81
81
|
/**
|
|
82
|
-
* A **pre-computed** `ValueSet.expansion` is **incomplete
|
|
82
|
+
* A **pre-computed** `ValueSet.expansion` is **incomplete**: its `total` exceeds the number of
|
|
83
83
|
* `contains` entries, or it is flagged too-costly (the VSAC `$expand` >1200-code truncation
|
|
84
84
|
* hazard). The engine **never treats a truncated expansion as complete membership**: a code
|
|
85
85
|
* absent from a truncated expansion is `undetermined`, never a confident "not a member".
|
|
86
86
|
*/
|
|
87
87
|
TERM_VALUESET_EXPANSION_TRUNCATED: "TERM_VALUESET_EXPANSION_TRUNCATED",
|
|
88
88
|
/**
|
|
89
|
-
* A UCUM unit expression is **not valid
|
|
89
|
+
* A UCUM unit expression is **not valid**: it does not parse against the UCUM grammar, or it
|
|
90
90
|
* names an atom absent from the vendored UCUM table. A **first-class typed outcome, never an
|
|
91
91
|
* error and never a guess**: {@link validateUcum} returns `{ valid: false, reason }`, never a
|
|
92
92
|
* coerced or "nearest" unit (the never-fabricate invariant, applied to units). The
|
|
@@ -94,7 +94,7 @@ var DIAGNOSTIC_CODES = {
|
|
|
94
94
|
*/
|
|
95
95
|
TERM_UCUM_INVALID: "TERM_UCUM_INVALID",
|
|
96
96
|
/**
|
|
97
|
-
* A crosswalk source code has an **authored No-Map
|
|
97
|
+
* A crosswalk source code has an **authored No-Map**: the steward declares it has no valid target
|
|
98
98
|
* in the other classification (a GEM `NoDx`/`NoPCS` sentinel, or a SNOMED complex-map `447638001`
|
|
99
99
|
* "cannot be classified" category). A **first-class typed outcome, never an error and never a
|
|
100
100
|
* guess** (the never-fabricate invariant, applied to crosswalks). Distinct from
|
|
@@ -102,7 +102,7 @@ var DIAGNOSTIC_CODES = {
|
|
|
102
102
|
*/
|
|
103
103
|
TERM_CROSSWALK_NO_MAP: "TERM_CROSSWALK_NO_MAP",
|
|
104
104
|
/**
|
|
105
|
-
* A crosswalk source code is **absent from the map entirely
|
|
105
|
+
* A crosswalk source code is **absent from the map entirely**: not an authored No-Map, simply not
|
|
106
106
|
* present. Surfaced as a typed outcome (never a fabricated target, never a silent success), and
|
|
107
107
|
* kept distinct from {@link TERM_CROSSWALK_NO_MAP} so a caller can tell "the steward said no target"
|
|
108
108
|
* from "this code was not in the file".
|
|
@@ -111,26 +111,26 @@ var DIAGNOSTIC_CODES = {
|
|
|
111
111
|
/**
|
|
112
112
|
* A SNOMED→ICD-10-CM complex-map group's decision needs **patient context** (an `IFA` age band or
|
|
113
113
|
* gender) the caller did not supply. The engine surfaces the candidate rules + advice and **refuses
|
|
114
|
-
* to pick a branch** it lacks the data for
|
|
114
|
+
* to pick a branch** it lacks the data for: never a silently-chosen target.
|
|
115
115
|
*/
|
|
116
116
|
TERM_CROSSWALK_CONTEXT_REQUIRED: "TERM_CROSSWALK_CONTEXT_REQUIRED",
|
|
117
117
|
/**
|
|
118
|
-
* A GEM file line was structurally unusable
|
|
118
|
+
* A GEM file line was structurally unusable: not three whitespace-delimited fields, or a flag
|
|
119
119
|
* field that is not a 5-digit code. The row is **skipped and surfaced** as a load warning (liberal
|
|
120
120
|
* on load), never kept as a partially-parsed entry.
|
|
121
121
|
*/
|
|
122
122
|
TERM_GEM_MALFORMED_ROW: "TERM_GEM_MALFORMED_ROW",
|
|
123
123
|
/**
|
|
124
|
-
* A SNOMED complex-map RF2 refset row was structurally unusable
|
|
124
|
+
* A SNOMED complex-map RF2 refset row was structurally unusable: missing its
|
|
125
125
|
* `referencedComponentId`/`mapGroup`/`mapPriority`. Skipped and surfaced, never partial.
|
|
126
126
|
*/
|
|
127
127
|
TERM_COMPLEX_MAP_MALFORMED_ROW: "TERM_COMPLEX_MAP_MALFORMED_ROW",
|
|
128
128
|
/**
|
|
129
|
-
* A RxNorm RRF row (`RXNCONSO` / `RXNREL` / `RXNSAT`) was structurally unusable
|
|
129
|
+
* A RxNorm RRF row (`RXNCONSO` / `RXNREL` / `RXNSAT`) was structurally unusable: too few columns to
|
|
130
130
|
* reach a required field, or a missing `RXCUI`/NDC value. The row is **skipped and surfaced** as a
|
|
131
131
|
* load warning (liberal on load), never kept as a partial concept/edge. Rows that are simply *not of
|
|
132
132
|
* interest* (a non-`RXNORM` atom, an atom-level relationship, a non-`NDC` attribute) are skipped
|
|
133
|
-
* **silently
|
|
133
|
+
* **silently**: they are expected, not faults.
|
|
134
134
|
*/
|
|
135
135
|
TERM_RXNORM_MALFORMED_ROW: "TERM_RXNORM_MALFORMED_ROW",
|
|
136
136
|
/**
|
|
@@ -144,7 +144,7 @@ var DIAGNOSTIC_CODES = {
|
|
|
144
144
|
*/
|
|
145
145
|
TERM_RXNORM_UNTYPED_CONCEPT: "TERM_RXNORM_UNTYPED_CONCEPT",
|
|
146
146
|
/**
|
|
147
|
-
* A RxNorm graph navigation was asked about an `RXCUI` **absent from the loaded release
|
|
147
|
+
* A RxNorm graph navigation was asked about an `RXCUI` **absent from the loaded release**: a
|
|
148
148
|
* first-class typed outcome, never a fabricated concept and never an empty "success" (the
|
|
149
149
|
* never-fabricate invariant, applied to the drug graph). Distinct from a *present*
|
|
150
150
|
* concept that simply has no edge of the requested relationship (that is a found result with empty
|
|
@@ -152,7 +152,7 @@ var DIAGNOSTIC_CODES = {
|
|
|
152
152
|
*/
|
|
153
153
|
TERM_RXNORM_UNKNOWN_RXCUI: "TERM_RXNORM_UNKNOWN_RXCUI",
|
|
154
154
|
/**
|
|
155
|
-
* An NDC could **not be resolved** to any `RXCUI` in the loaded RxNorm release
|
|
155
|
+
* An NDC could **not be resolved** to any `RXCUI` in the loaded RxNorm release: a typed, surfaced
|
|
156
156
|
* absence, never a guessed `RXCUI`. NDC↔RXCUI is many:1 and temporal, so a resolution
|
|
157
157
|
* is always release-scoped; an NDC not present in the loaded release is this diagnostic.
|
|
158
158
|
*/
|
|
@@ -160,33 +160,33 @@ var DIAGNOSTIC_CODES = {
|
|
|
160
160
|
};
|
|
161
161
|
var FATAL_CODES = {
|
|
162
162
|
/**
|
|
163
|
-
* A `ConceptMap` resource was structurally unusable
|
|
163
|
+
* A `ConceptMap` resource was structurally unusable: wrong `resourceType`, or a group/element
|
|
164
164
|
* missing a required field. Thrown rather than silently loading a partial, misleading map.
|
|
165
165
|
*/
|
|
166
166
|
TERM_CONCEPTMAP_MALFORMED: "TERM_CONCEPTMAP_MALFORMED",
|
|
167
167
|
/**
|
|
168
|
-
* A CodeSystem *source* was structurally unusable
|
|
168
|
+
* A CodeSystem *source* was structurally unusable: a FHIR resource with the wrong `resourceType`,
|
|
169
169
|
* or a delimited source whose configured code/display column is absent from the header. Thrown
|
|
170
170
|
* rather than silently loading an empty or mis-keyed release. (Malformed individual **rows** are
|
|
171
|
-
* skipped-and-surfaced load warnings, not fatals
|
|
171
|
+
* skipped-and-surfaced load warnings, not fatals: only an unusable *source* is fatal.)
|
|
172
172
|
*/
|
|
173
173
|
TERM_CODESYSTEM_MALFORMED: "TERM_CODESYSTEM_MALFORMED",
|
|
174
174
|
/**
|
|
175
|
-
* A `ValueSet` resource was structurally unusable
|
|
175
|
+
* A `ValueSet` resource was structurally unusable: wrong `resourceType`, or a `compose`/`expansion`
|
|
176
176
|
* whose required shape (an `include` that is not an object, a `contains` entry missing its `code`)
|
|
177
177
|
* is corrupt. Thrown rather than silently loading a partial value set that would bind *some* codes
|
|
178
|
-
* and quietly drop others. (A `filter` operator the engine does not implement is **not** fatal
|
|
178
|
+
* and quietly drop others. (A `filter` operator the engine does not implement is **not** fatal; it
|
|
179
179
|
* is the surfaced `TERM_VALUESET_CANNOT_EXPAND` diagnostic at expansion time.)
|
|
180
180
|
*/
|
|
181
181
|
TERM_VALUESET_MALFORMED: "TERM_VALUESET_MALFORMED",
|
|
182
182
|
/**
|
|
183
|
-
* A crosswalk map *source* was structurally unusable
|
|
183
|
+
* A crosswalk map *source* was structurally unusable: e.g. a SNOMED complex-map RF2 refset with
|
|
184
184
|
* empty content or a header missing a required column. Thrown rather than silently loading an empty
|
|
185
185
|
* or mis-keyed map. (Malformed individual **rows** are skipped-and-surfaced warnings, not fatals.)
|
|
186
186
|
*/
|
|
187
187
|
TERM_CROSSWALK_MALFORMED: "TERM_CROSSWALK_MALFORMED",
|
|
188
188
|
/**
|
|
189
|
-
* An **inversion** of a directional crosswalk was requested
|
|
189
|
+
* An **inversion** of a directional crosswalk was requested: a forbidden operation. The GEMs and
|
|
190
190
|
* the SNOMED→ICD-10-CM map are authoritative in **one direction only**; a forward map is not the
|
|
191
191
|
* inverse of the backward map. Thrown by {@link ../crosswalk/gems.invertGem} so the
|
|
192
192
|
* never-invert refusal is a first-class, discoverable contract rather than a silent absence.
|
|
@@ -199,7 +199,7 @@ var TerminologyError = class _TerminologyError extends Error {
|
|
|
199
199
|
/**
|
|
200
200
|
* @param code - The stable {@link FatalCode} describing the fault.
|
|
201
201
|
* @param message - A **value-free** structural description (path + fault; never an input value).
|
|
202
|
-
* Every piece of it must be engine-owned
|
|
202
|
+
* Every piece of it must be engine-owned: a literal, a frozen-table entry, or a locus this
|
|
203
203
|
* package built. This string reaches `err.stack`, so interpolating a caller-supplied or
|
|
204
204
|
* document-derived value into it is how a diagnostic becomes a leak.
|
|
205
205
|
*/
|
|
@@ -3914,7 +3914,7 @@ function parseTerm(cur, inParen) {
|
|
|
3914
3914
|
factors.push({ sign: op === "/" ? -1 : 1, node: comp.node });
|
|
3915
3915
|
}
|
|
3916
3916
|
if (inParen) {
|
|
3917
|
-
if (cur.s[cur.pos] !== ")") return { ok: false, reason: "unbalanced '('
|
|
3917
|
+
if (cur.s[cur.pos] !== ")") return { ok: false, reason: "unbalanced '(': missing ')'" };
|
|
3918
3918
|
cur.pos++;
|
|
3919
3919
|
}
|
|
3920
3920
|
return { ok: true, node: { kind: "term", factors } };
|
|
@@ -4187,10 +4187,10 @@ function applyGem(map, source) {
|
|
|
4187
4187
|
return Object.freeze(matched);
|
|
4188
4188
|
}
|
|
4189
4189
|
var NOT_INVERTIBLE_MESSAGE = /* @__PURE__ */ new Map([
|
|
4190
|
-
["9-to-10", "GEM map (direction 9-to-10) cannot be inverted
|
|
4191
|
-
["10-to-9", "GEM map (direction 10-to-9) cannot be inverted
|
|
4190
|
+
["9-to-10", "GEM map (direction 9-to-10) cannot be inverted: load the 10-to-9 GEM file instead"],
|
|
4191
|
+
["10-to-9", "GEM map (direction 10-to-9) cannot be inverted: load the 9-to-10 GEM file instead"]
|
|
4192
4192
|
]);
|
|
4193
|
-
var NOT_INVERTIBLE_UNKNOWN_DIRECTION = "GEM map cannot be inverted
|
|
4193
|
+
var NOT_INVERTIBLE_UNKNOWN_DIRECTION = "GEM map cannot be inverted: load the reverse GEM file instead";
|
|
4194
4194
|
function invertGem(map) {
|
|
4195
4195
|
throw new TerminologyError(
|
|
4196
4196
|
FATAL_CODES.TERM_MAP_NOT_INVERTIBLE,
|
|
@@ -4200,13 +4200,13 @@ function invertGem(map) {
|
|
|
4200
4200
|
|
|
4201
4201
|
// src/crosswalk/categories.ts
|
|
4202
4202
|
var MAP_CATEGORIES = {
|
|
4203
|
-
/** `447637006
|
|
4203
|
+
/** `447637006`: "Map source concept is properly classified" (a normal, usable target). */
|
|
4204
4204
|
PROPERLY_CLASSIFIED: "447637006",
|
|
4205
|
-
/** `447638001
|
|
4205
|
+
/** `447638001`: "Map source concept cannot be classified with available data" (a **No-Map**). */
|
|
4206
4206
|
NO_MAP: "447638001",
|
|
4207
|
-
/** `447639009
|
|
4207
|
+
/** `447639009`: "Map of source concept is context dependent" (needs runtime patient context). */
|
|
4208
4208
|
CONTEXT_DEPENDENT: "447639009",
|
|
4209
|
-
/** `447640006
|
|
4209
|
+
/** `447640006`: "Source concept is ambiguous" (surface candidates, never pick one). */
|
|
4210
4210
|
AMBIGUOUS: "447640006"
|
|
4211
4211
|
};
|
|
4212
4212
|
var NO_MAP_CATEGORIES = /* @__PURE__ */ new Set([MAP_CATEGORIES.NO_MAP]);
|
|
@@ -4635,37 +4635,37 @@ var RELA = {
|
|
|
4635
4635
|
* Neither reaches an `SCD`.
|
|
4636
4636
|
*/
|
|
4637
4637
|
INGREDIENT_OF: "ingredient_of",
|
|
4638
|
-
/** `has_precise_ingredient
|
|
4638
|
+
/** `has_precise_ingredient`: subject *has precise ingredient* object (a `PIN`). */
|
|
4639
4639
|
HAS_PRECISE_INGREDIENT: "has_precise_ingredient",
|
|
4640
|
-
/** `precise_ingredient_of
|
|
4640
|
+
/** `precise_ingredient_of`: inverse of `has_precise_ingredient`. */
|
|
4641
4641
|
PRECISE_INGREDIENT_OF: "precise_ingredient_of",
|
|
4642
|
-
/** `tradename_of
|
|
4642
|
+
/** `tradename_of`: subject (a branded concept) *is a tradename of* object (its generic). */
|
|
4643
4643
|
TRADENAME_OF: "tradename_of",
|
|
4644
|
-
/** `has_tradename
|
|
4644
|
+
/** `has_tradename`: subject (a generic concept) *has tradename* object (a branded concept). */
|
|
4645
4645
|
HAS_TRADENAME: "has_tradename",
|
|
4646
|
-
/** `has_dose_form
|
|
4646
|
+
/** `has_dose_form`: subject (a drug) *has dose form* object (a `DF`). */
|
|
4647
4647
|
HAS_DOSE_FORM: "has_dose_form",
|
|
4648
|
-
/** `dose_form_of
|
|
4648
|
+
/** `dose_form_of`: subject (a `DF`) *is the dose form of* object (a drug). */
|
|
4649
4649
|
DOSE_FORM_OF: "dose_form_of",
|
|
4650
|
-
/** `has_doseformgroup
|
|
4650
|
+
/** `has_doseformgroup`: subject *has dose-form group* object (a `DFG`). */
|
|
4651
4651
|
HAS_DOSE_FORM_GROUP: "has_doseformgroup",
|
|
4652
|
-
/** `doseformgroup_of
|
|
4652
|
+
/** `doseformgroup_of`: inverse of `has_doseformgroup`. */
|
|
4653
4653
|
DOSE_FORM_GROUP_OF: "doseformgroup_of",
|
|
4654
|
-
/** `consists_of
|
|
4654
|
+
/** `consists_of`: subject (an `SCD`/`SBD`) *consists of* object (its `SCDC`/`SBDC` component(s)). */
|
|
4655
4655
|
CONSISTS_OF: "consists_of",
|
|
4656
|
-
/** `constitutes
|
|
4656
|
+
/** `constitutes`: subject (a component) *constitutes* object (the drug). Inverse of `consists_of`. */
|
|
4657
4657
|
CONSTITUTES: "constitutes",
|
|
4658
|
-
/** `contains
|
|
4658
|
+
/** `contains`: subject (a pack) *contains* object (a member drug). */
|
|
4659
4659
|
CONTAINS: "contains",
|
|
4660
|
-
/** `contained_in
|
|
4660
|
+
/** `contained_in`: subject (a drug) *is contained in* object (a pack). Inverse of `contains`. */
|
|
4661
4661
|
CONTAINED_IN: "contained_in",
|
|
4662
|
-
/** `has_quantified_form
|
|
4662
|
+
/** `has_quantified_form`: subject *has quantified form* object. */
|
|
4663
4663
|
HAS_QUANTIFIED_FORM: "has_quantified_form",
|
|
4664
|
-
/** `quantified_form_of
|
|
4664
|
+
/** `quantified_form_of`: inverse of `has_quantified_form`. */
|
|
4665
4665
|
QUANTIFIED_FORM_OF: "quantified_form_of",
|
|
4666
|
-
/** `isa
|
|
4666
|
+
/** `isa`: subject *is a* object (hierarchical, e.g. `SCD isa SCDG`). */
|
|
4667
4667
|
ISA: "isa",
|
|
4668
|
-
/** `inverse_isa
|
|
4668
|
+
/** `inverse_isa`: subject *is a parent of* object. Inverse of `isa`. */
|
|
4669
4669
|
INVERSE_ISA: "inverse_isa"
|
|
4670
4670
|
};
|
|
4671
4671
|
var RELA_INVERSE = Object.freeze({
|
|
@@ -4776,7 +4776,7 @@ function approximateMatch(graph, query, options = {}) {
|
|
|
4776
4776
|
}
|
|
4777
4777
|
|
|
4778
4778
|
// src/index.ts
|
|
4779
|
-
var VERSION = "0.0.
|
|
4779
|
+
var VERSION = "0.0.13";
|
|
4780
4780
|
|
|
4781
4781
|
exports.COMPLEX_MAP_SOURCE_SYSTEM = COMPLEX_MAP_SOURCE_SYSTEM;
|
|
4782
4782
|
exports.DIAGNOSTIC_CODES = DIAGNOSTIC_CODES;
|