@precisa-saude/fhir 0.34.0 → 0.35.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 (59) hide show
  1. package/dist/biomarkers.cjs +4 -2
  2. package/dist/biomarkers.cjs.map +1 -1
  3. package/dist/biomarkers.d.cts +34 -1
  4. package/dist/biomarkers.d.ts +34 -1
  5. package/dist/biomarkers.js +3 -1
  6. package/dist/{chunk-NJM45WAH.js → chunk-6QUGBBV2.js} +5 -3
  7. package/dist/chunk-6QUGBBV2.js.map +1 -0
  8. package/dist/{chunk-376KM7IL.cjs → chunk-77LDD6OP.cjs} +11 -9
  9. package/dist/chunk-77LDD6OP.cjs.map +1 -0
  10. package/dist/{chunk-VKLWTTUO.cjs → chunk-HZSW5T7E.cjs} +3 -3
  11. package/dist/{chunk-VKLWTTUO.cjs.map → chunk-HZSW5T7E.cjs.map} +1 -1
  12. package/dist/{chunk-4FKZG5GZ.js → chunk-KQ4CX67G.js} +35 -1
  13. package/dist/chunk-KQ4CX67G.js.map +1 -0
  14. package/dist/{chunk-5RC7C7HJ.cjs → chunk-LNL5QSHP.cjs} +3 -3
  15. package/dist/{chunk-5RC7C7HJ.cjs.map → chunk-LNL5QSHP.cjs.map} +1 -1
  16. package/dist/{chunk-P4G534AQ.js → chunk-O3FXUPW3.js} +2 -2
  17. package/dist/{chunk-K3VZ3F5Z.js → chunk-TLF3IVSN.js} +8 -6
  18. package/dist/chunk-TLF3IVSN.js.map +1 -0
  19. package/dist/{chunk-Q3H5C6UR.js → chunk-U2XW6DY4.js} +2 -2
  20. package/dist/{chunk-OAFAERDY.cjs → chunk-VMYB7KOE.cjs} +3 -3
  21. package/dist/{chunk-OAFAERDY.cjs.map → chunk-VMYB7KOE.cjs.map} +1 -1
  22. package/dist/{chunk-NKDUVSDK.cjs → chunk-XAIIZLZ7.cjs} +11 -9
  23. package/dist/chunk-XAIIZLZ7.cjs.map +1 -0
  24. package/dist/{chunk-E6MXDQXW.js → chunk-XT635TWP.js} +2 -2
  25. package/dist/{chunk-T75NZM56.cjs → chunk-YL65SZ6S.cjs} +38 -4
  26. package/dist/chunk-YL65SZ6S.cjs.map +1 -0
  27. package/dist/cli.js +37 -2
  28. package/dist/{converter-UygMzWlL.d.ts → converter-CTj83kPz.d.ts} +6 -0
  29. package/dist/{converter-DP8VkkO3.d.cts → converter-Dlwb6OfB.d.cts} +6 -0
  30. package/dist/converter.cjs +5 -5
  31. package/dist/converter.d.cts +1 -1
  32. package/dist/converter.d.ts +1 -1
  33. package/dist/converter.js +4 -4
  34. package/dist/importer.cjs +5 -5
  35. package/dist/importer.d.cts +2 -0
  36. package/dist/importer.d.ts +2 -0
  37. package/dist/importer.js +4 -4
  38. package/dist/index.cjs +12 -10
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.cts +3 -3
  41. package/dist/index.d.ts +3 -3
  42. package/dist/index.js +8 -6
  43. package/dist/index.js.map +1 -1
  44. package/dist/reference-ranges.cjs +4 -4
  45. package/dist/reference-ranges.js +3 -3
  46. package/dist/units.cjs +3 -3
  47. package/dist/units.js +2 -2
  48. package/dist/validators.cjs +4 -4
  49. package/dist/validators.js +3 -3
  50. package/package.json +1 -1
  51. package/dist/chunk-376KM7IL.cjs.map +0 -1
  52. package/dist/chunk-4FKZG5GZ.js.map +0 -1
  53. package/dist/chunk-K3VZ3F5Z.js.map +0 -1
  54. package/dist/chunk-NJM45WAH.js.map +0 -1
  55. package/dist/chunk-NKDUVSDK.cjs.map +0 -1
  56. package/dist/chunk-T75NZM56.cjs.map +0 -1
  57. /package/dist/{chunk-P4G534AQ.js.map → chunk-O3FXUPW3.js.map} +0 -0
  58. /package/dist/{chunk-Q3H5C6UR.js.map → chunk-U2XW6DY4.js.map} +0 -0
  59. /package/dist/{chunk-E6MXDQXW.js.map → chunk-XT635TWP.js.map} +0 -0
package/dist/cli.js CHANGED
@@ -115,6 +115,32 @@ var BIOMARKER_DEFINITIONS = [
115
115
  category: "coracao",
116
116
  code: "LDL",
117
117
  loinc: "2089-1",
118
+ // Os três irmãos de 2089-1 no eixo Method, conferidos ativos em out/2026.
119
+ // Medido em três dezenas de laudos reais, a única pista escrita foi a
120
+ // nota de rodapé de um laboratório norte-americano que declara o cálculo de
121
+ // Martin-Hopkins. Nenhum laudo brasileiro do corpus imprimiu "calculado",
122
+ // "direto" ou "Método:" perto do LDL, e por isso as outras duas variantes
123
+ // ficam sem pista até aparecer laudo que as afirme.
124
+ methodVariants: [
125
+ {
126
+ cues: { en: ["calculated using the Martin-Hopkins"], pt: [] },
127
+ loinc: "96259-7",
128
+ method: "Calculated.Martin-Hopkins",
129
+ note: 'Rodap\xE9 "LDL-C is now calculated using the Martin-Hopkins calculation", que menciona Friedewald s\xF3 para comparar. Por isso a pista \xE9 a frase afirmativa, e n\xE3o o nome do m\xE9todo.'
130
+ },
131
+ {
132
+ cues: { en: [], pt: [] },
133
+ loinc: "13457-7",
134
+ method: "Calculated",
135
+ note: "Friedewald. Sem pista: nenhum laudo do corpus afirmou o c\xE1lculo por escrito."
136
+ },
137
+ {
138
+ cues: { en: [], pt: [] },
139
+ loinc: "18262-6",
140
+ method: "Direct assay",
141
+ note: "Dosagem direta. Sem pista: nenhum laudo do corpus afirmou o m\xE9todo por escrito."
142
+ }
143
+ ],
118
144
  names: {
119
145
  en: ["LDL Cholesterol", "LDL", "Low-Density Lipoprotein"],
120
146
  pt: ["Colesterol LDL", "LDL", "LDL-Colesterol"]
@@ -3313,6 +3339,10 @@ for (const def of BIOMARKER_DEFINITIONS) {
3313
3339
  validLoincSet.add(alias);
3314
3340
  }
3315
3341
  }
3342
+ for (const variant of def.methodVariants ?? []) {
3343
+ loincToCodeMap.set(variant.loinc, def.code);
3344
+ validLoincSet.add(variant.loinc);
3345
+ }
3316
3346
  if (def.codeAliases) {
3317
3347
  for (const alias of def.codeAliases) {
3318
3348
  codeAliasToCanonicalMap.set(alias, def.code);
@@ -3324,6 +3354,9 @@ for (const def of BIOMARKER_DEFINITIONS) {
3324
3354
  function loincToCode(loinc) {
3325
3355
  return loincToCodeMap.get(loinc);
3326
3356
  }
3357
+ function methodVariantOf(code, loinc) {
3358
+ return codeToDefinitionMap.get(code)?.methodVariants?.find((v) => v.loinc === loinc);
3359
+ }
3327
3360
  function codeToLoinc(code) {
3328
3361
  return codeToLoincMap.get(code);
3329
3362
  }
@@ -6831,7 +6864,8 @@ var buildReferenceRanges = (observation, quantity) => {
6831
6864
  );
6832
6865
  };
6833
6866
  function labObservationToFHIR(observation, patientId, laboratoryName) {
6834
- const loincCode = codeToLoinc(observation.biomarkerCode);
6867
+ const methodLoinc = observation.methodLoinc && methodVariantOf(observation.biomarkerCode, observation.methodLoinc) ? observation.methodLoinc : void 0;
6868
+ const loincCode = methodLoinc ?? codeToLoinc(observation.biomarkerCode);
6835
6869
  const sourceUnit = observation.unit || getDefaultUnit(observation.biomarkerCode) || observation.unit;
6836
6870
  const ucumUnit = resolveUcum(sourceUnit, observation.biomarkerCode);
6837
6871
  const quantity = (value) => ({
@@ -7179,6 +7213,7 @@ function mapFHIRObservationToInternal(observation, index) {
7179
7213
  flag: extractFlag(observation),
7180
7214
  isQualitative,
7181
7215
  loincCode,
7216
+ ...loincCode && methodVariantOf(internalCode, loincCode) && { methodLoinc: loincCode },
7182
7217
  ...referenceKind && { referenceKind },
7183
7218
  referenceMax,
7184
7219
  referenceMin,
@@ -7877,7 +7912,7 @@ var COMMANDS = {
7877
7912
  async function main() {
7878
7913
  const { command, help, json, resto, version } = dividirArgv(process.argv.slice(2));
7879
7914
  if (version) {
7880
- process.stdout.write(`${"0.34.0"}
7915
+ process.stdout.write(`${"0.35.0"}
7881
7916
  `);
7882
7917
  return;
7883
7918
  }
@@ -101,6 +101,12 @@ interface LabObservationData {
101
101
  collectionDate?: string;
102
102
  flag: Flag;
103
103
  isQualitative?: boolean;
104
+ /**
105
+ * O LOINC por método, quando o laudo afirmou o método por escrito. Só vale
106
+ * se for uma das `methodVariants` declaradas para o biomarcador; qualquer
107
+ * outro valor é ignorado e sai o código sem método.
108
+ */
109
+ methodLoinc?: string;
104
110
  /**
105
111
  * Tipo da faixa simples (`referenceMin`/`referenceMax`), quando quem chama
106
112
  * sabe. Sai como `referenceRange.type`. Faixa impressa pelo laboratório
@@ -101,6 +101,12 @@ interface LabObservationData {
101
101
  collectionDate?: string;
102
102
  flag: Flag;
103
103
  isQualitative?: boolean;
104
+ /**
105
+ * O LOINC por método, quando o laudo afirmou o método por escrito. Só vale
106
+ * se for uma das `methodVariants` declaradas para o biomarcador; qualquer
107
+ * outro valor é ignorado e sai o código sem método.
108
+ */
109
+ methodLoinc?: string;
104
110
  /**
105
111
  * Tipo da faixa simples (`referenceMin`/`referenceMax`), quando quem chama
106
112
  * sabe. Sai como `referenceRange.type`. Faixa impressa pelo laboratório
@@ -3,15 +3,15 @@
3
3
 
4
4
 
5
5
 
6
- var _chunkNKDUVSDKcjs = require('./chunk-NKDUVSDK.cjs');
6
+ var _chunkXAIIZLZ7cjs = require('./chunk-XAIIZLZ7.cjs');
7
7
  require('./chunk-OR67NJDZ.cjs');
8
- require('./chunk-VKLWTTUO.cjs');
9
- require('./chunk-5RC7C7HJ.cjs');
10
- require('./chunk-T75NZM56.cjs');
8
+ require('./chunk-HZSW5T7E.cjs');
9
+ require('./chunk-LNL5QSHP.cjs');
10
+ require('./chunk-YL65SZ6S.cjs');
11
11
 
12
12
 
13
13
 
14
14
 
15
15
 
16
- exports.labObservationToFHIR = _chunkNKDUVSDKcjs.labObservationToFHIR; exports.labReportToFHIR = _chunkNKDUVSDKcjs.labReportToFHIR; exports.labResultToFHIRBundle = _chunkNKDUVSDKcjs.labResultToFHIRBundle; exports.userProfileToFHIR = _chunkNKDUVSDKcjs.userProfileToFHIR;
16
+ exports.labObservationToFHIR = _chunkXAIIZLZ7cjs.labObservationToFHIR; exports.labReportToFHIR = _chunkXAIIZLZ7cjs.labReportToFHIR; exports.labResultToFHIRBundle = _chunkXAIIZLZ7cjs.labResultToFHIRBundle; exports.userProfileToFHIR = _chunkXAIIZLZ7cjs.userProfileToFHIR;
17
17
  //# sourceMappingURL=converter.cjs.map
@@ -1,3 +1,3 @@
1
- export { l as labObservationToFHIR, b as labReportToFHIR, c as labResultToFHIRBundle, u as userProfileToFHIR } from './converter-DP8VkkO3.cjs';
1
+ export { l as labObservationToFHIR, b as labReportToFHIR, c as labResultToFHIRBundle, u as userProfileToFHIR } from './converter-Dlwb6OfB.cjs';
2
2
  export { e as FHIRAddress, f as FHIRAnnotation, g as FHIRAttachment, b as FHIRBundle, h as FHIRBundleEntry, i as FHIRCodeableConcept, d as FHIRCoding, j as FHIRContactPoint, k as FHIRDiagnosticReport, l as FHIRHumanName, c as FHIRIdentifier, F as FHIRMedicationStatement, a as FHIRObservation, m as FHIRPatient, n as FHIRPeriod, o as FHIRQuantity, p as FHIRReference, q as FHIRReferenceRange } from './fhir-types-Cn5WFbOI.cjs';
3
3
  import './reference-ranges.cjs';
@@ -1,3 +1,3 @@
1
- export { l as labObservationToFHIR, b as labReportToFHIR, c as labResultToFHIRBundle, u as userProfileToFHIR } from './converter-UygMzWlL.js';
1
+ export { l as labObservationToFHIR, b as labReportToFHIR, c as labResultToFHIRBundle, u as userProfileToFHIR } from './converter-CTj83kPz.js';
2
2
  export { e as FHIRAddress, f as FHIRAnnotation, g as FHIRAttachment, b as FHIRBundle, h as FHIRBundleEntry, i as FHIRCodeableConcept, d as FHIRCoding, j as FHIRContactPoint, k as FHIRDiagnosticReport, l as FHIRHumanName, c as FHIRIdentifier, F as FHIRMedicationStatement, a as FHIRObservation, m as FHIRPatient, n as FHIRPeriod, o as FHIRQuantity, p as FHIRReference, q as FHIRReferenceRange } from './fhir-types-Cn5WFbOI.js';
3
3
  import './reference-ranges.js';
package/dist/converter.js CHANGED
@@ -3,11 +3,11 @@ import {
3
3
  labReportToFHIR,
4
4
  labResultToFHIRBundle,
5
5
  userProfileToFHIR
6
- } from "./chunk-K3VZ3F5Z.js";
6
+ } from "./chunk-TLF3IVSN.js";
7
7
  import "./chunk-A6HR4XDK.js";
8
- import "./chunk-P4G534AQ.js";
9
- import "./chunk-Q3H5C6UR.js";
10
- import "./chunk-4FKZG5GZ.js";
8
+ import "./chunk-O3FXUPW3.js";
9
+ import "./chunk-U2XW6DY4.js";
10
+ import "./chunk-KQ4CX67G.js";
11
11
  export {
12
12
  labObservationToFHIR,
13
13
  labReportToFHIR,
package/dist/importer.cjs CHANGED
@@ -4,16 +4,16 @@
4
4
 
5
5
 
6
6
 
7
- var _chunk376KM7ILcjs = require('./chunk-376KM7IL.cjs');
8
- require('./chunk-OAFAERDY.cjs');
7
+ var _chunk77LDD6OPcjs = require('./chunk-77LDD6OP.cjs');
8
+ require('./chunk-VMYB7KOE.cjs');
9
9
  require('./chunk-OR67NJDZ.cjs');
10
- require('./chunk-5RC7C7HJ.cjs');
11
- require('./chunk-T75NZM56.cjs');
10
+ require('./chunk-LNL5QSHP.cjs');
11
+ require('./chunk-YL65SZ6S.cjs');
12
12
 
13
13
 
14
14
 
15
15
 
16
16
 
17
17
 
18
- exports.MAX_FILE_SIZE = _chunk376KM7ILcjs.MAX_FILE_SIZE; exports.MAX_OBSERVATIONS = _chunk376KM7ILcjs.MAX_OBSERVATIONS; exports.extractObservationsFromBundle = _chunk376KM7ILcjs.extractObservationsFromBundle; exports.mapFHIRObservationToInternal = _chunk376KM7ILcjs.mapFHIRObservationToInternal; exports.processImportBundle = _chunk376KM7ILcjs.processImportBundle;
18
+ exports.MAX_FILE_SIZE = _chunk77LDD6OPcjs.MAX_FILE_SIZE; exports.MAX_OBSERVATIONS = _chunk77LDD6OPcjs.MAX_OBSERVATIONS; exports.extractObservationsFromBundle = _chunk77LDD6OPcjs.extractObservationsFromBundle; exports.mapFHIRObservationToInternal = _chunk77LDD6OPcjs.mapFHIRObservationToInternal; exports.processImportBundle = _chunk77LDD6OPcjs.processImportBundle;
19
19
  //# sourceMappingURL=importer.cjs.map
@@ -15,6 +15,8 @@ interface ImportedObservation {
15
15
  isQualitative: boolean;
16
16
  /** Ausente nos biomarcadores sem LOINC publicado, como composição corporal. */
17
17
  loincCode?: string;
18
+ /** O `loincCode` quando ele é uma das variantes por método do biomarcador. */
19
+ methodLoinc?: string;
18
20
  /** Lido do `referenceRange.type`, quando o Bundle o traz. */
19
21
  referenceKind?: 'decision-threshold' | 'reference-interval';
20
22
  referenceMax?: number;
@@ -15,6 +15,8 @@ interface ImportedObservation {
15
15
  isQualitative: boolean;
16
16
  /** Ausente nos biomarcadores sem LOINC publicado, como composição corporal. */
17
17
  loincCode?: string;
18
+ /** O `loincCode` quando ele é uma das variantes por método do biomarcador. */
19
+ methodLoinc?: string;
18
20
  /** Lido do `referenceRange.type`, quando o Bundle o traz. */
19
21
  referenceKind?: 'decision-threshold' | 'reference-interval';
20
22
  referenceMax?: number;
package/dist/importer.js CHANGED
@@ -4,11 +4,11 @@ import {
4
4
  extractObservationsFromBundle,
5
5
  mapFHIRObservationToInternal,
6
6
  processImportBundle
7
- } from "./chunk-NJM45WAH.js";
8
- import "./chunk-E6MXDQXW.js";
7
+ } from "./chunk-6QUGBBV2.js";
8
+ import "./chunk-XT635TWP.js";
9
9
  import "./chunk-A6HR4XDK.js";
10
- import "./chunk-Q3H5C6UR.js";
11
- import "./chunk-4FKZG5GZ.js";
10
+ import "./chunk-U2XW6DY4.js";
11
+ import "./chunk-KQ4CX67G.js";
12
12
  export {
13
13
  MAX_FILE_SIZE,
14
14
  MAX_OBSERVATIONS,
package/dist/index.cjs CHANGED
@@ -5,19 +5,19 @@
5
5
 
6
6
 
7
7
 
8
- var _chunkNKDUVSDKcjs = require('./chunk-NKDUVSDK.cjs');
8
+ var _chunkXAIIZLZ7cjs = require('./chunk-XAIIZLZ7.cjs');
9
9
 
10
10
 
11
11
 
12
12
 
13
13
 
14
14
 
15
- var _chunk376KM7ILcjs = require('./chunk-376KM7IL.cjs');
15
+ var _chunk77LDD6OPcjs = require('./chunk-77LDD6OP.cjs');
16
16
 
17
17
 
18
18
 
19
19
 
20
- var _chunkOAFAERDYcjs = require('./chunk-OAFAERDY.cjs');
20
+ var _chunkVMYB7KOEcjs = require('./chunk-VMYB7KOE.cjs');
21
21
 
22
22
 
23
23
 
@@ -31,7 +31,7 @@ var _chunkOR67NJDZcjs = require('./chunk-OR67NJDZ.cjs');
31
31
 
32
32
 
33
33
 
34
- var _chunkVKLWTTUOcjs = require('./chunk-VKLWTTUO.cjs');
34
+ var _chunkHZSW5T7Ecjs = require('./chunk-HZSW5T7E.cjs');
35
35
 
36
36
 
37
37
 
@@ -47,7 +47,7 @@ var _chunk5FMR2U7Pcjs = require('./chunk-5FMR2U7P.cjs');
47
47
 
48
48
 
49
49
 
50
- var _chunk5RC7C7HJcjs = require('./chunk-5RC7C7HJ.cjs');
50
+ var _chunkLNL5QSHPcjs = require('./chunk-LNL5QSHP.cjs');
51
51
 
52
52
 
53
53
 
@@ -80,7 +80,8 @@ var _chunk5RC7C7HJcjs = require('./chunk-5RC7C7HJ.cjs');
80
80
 
81
81
 
82
82
 
83
- var _chunkT75NZM56cjs = require('./chunk-T75NZM56.cjs');
83
+
84
+ var _chunkYL65SZ6Scjs = require('./chunk-YL65SZ6S.cjs');
84
85
 
85
86
  // src/category-groups.ts
86
87
  var CATEGORY_GROUPS = {
@@ -242,14 +243,14 @@ function interventionToFHIRObservation(intervention, patientId) {
242
243
  }
243
244
  function interventionsToFHIRBundle(interventions, userProfile) {
244
245
  const patientId = userProfile.userId;
245
- const fhirPatient = _chunkNKDUVSDKcjs.userProfileToFHIR.call(void 0, userProfile);
246
+ const fhirPatient = _chunkXAIIZLZ7cjs.userProfileToFHIR.call(void 0, userProfile);
246
247
  const entries = interventions.map((intervention) => {
247
248
  const isMedication = intervention.type === "medication" || intervention.type === "supplement";
248
249
  const resource = isMedication ? interventionToFHIRMedicationStatement(intervention, patientId) : interventionToFHIRObservation(intervention, patientId);
249
- return { fullUrl: _chunkNKDUVSDKcjs.entryFullUrl.call(void 0, resource), resource };
250
+ return { fullUrl: _chunkXAIIZLZ7cjs.entryFullUrl.call(void 0, resource), resource };
250
251
  });
251
252
  return {
252
- entry: [{ fullUrl: _chunkNKDUVSDKcjs.entryFullUrl.call(void 0, fhirPatient), resource: fhirPatient }, ...entries],
253
+ entry: [{ fullUrl: _chunkXAIIZLZ7cjs.entryFullUrl.call(void 0, fhirPatient), resource: fhirPatient }, ...entries],
253
254
  resourceType: "Bundle",
254
255
  type: "collection"
255
256
  };
@@ -752,5 +753,6 @@ var specimenTypeCoding = (text) => BY_NORMALIZED_TEXT.get(normalize(text));
752
753
 
753
754
 
754
755
 
755
- exports.AGE_BRACKETS = AGE_BRACKETS; exports.BIOMARKER_CODE_SYSTEM = _chunkOR67NJDZcjs.BIOMARKER_CODE_SYSTEM; exports.BIOMARKER_DEFAULT_UNIT = _chunk5RC7C7HJcjs.BIOMARKER_DEFAULT_UNIT; exports.BIOMARKER_DEFINITIONS = _chunkT75NZM56cjs.BIOMARKER_DEFINITIONS; exports.BIOMARKER_UNITS = _chunk5RC7C7HJcjs.BIOMARKER_UNITS; exports.BODY_FAT_ZONES = BODY_FAT_ZONES; exports.BR_TIPO_AMOSTRA_VALUESET = BR_TIPO_AMOSTRA_VALUESET; exports.BUNDLE_BASE_URL = _chunkNKDUVSDKcjs.BUNDLE_BASE_URL; exports.CAC_INDICATOR_CODES = _chunkT75NZM56cjs.CAC_INDICATOR_CODES; exports.CATEGORY_GROUPS = CATEGORY_GROUPS; exports.CATEGORY_SCREENING_INTERVALS = CATEGORY_SCREENING_INTERVALS; exports.DEXA_CATEGORIES = _chunkT75NZM56cjs.DEXA_CATEGORIES; exports.DEXA_INDICATOR_CODES = _chunkT75NZM56cjs.DEXA_INDICATOR_CODES; exports.FHIR_BRASIL_EXTENSIONS = FHIR_BRASIL_EXTENSIONS; exports.HL7_SPECIMEN_TYPE_SYSTEM = HL7_SPECIMEN_TYPE_SYSTEM; exports.IG_CANONICAL = IG_CANONICAL; exports.LOINC_SYSTEM = _chunkOR67NJDZcjs.LOINC_SYSTEM; exports.MAX_FILE_SIZE = _chunk376KM7ILcjs.MAX_FILE_SIZE; exports.MAX_OBSERVATIONS = _chunk376KM7ILcjs.MAX_OBSERVATIONS; exports.SOURCE_REGISTRY = _chunk5FMR2U7Pcjs.SOURCE_REGISTRY; exports.T_SCORE_ZONES = T_SCORE_ZONES; exports.UNIT_TO_UCUM = _chunk5RC7C7HJcjs.UNIT_TO_UCUM; exports.ZONE_DEFS = ZONE_DEFS; exports.applyFallbackReferenceRanges = _chunkVKLWTTUOcjs.applyFallbackReferenceRanges; exports.biomarkerRangeDefinitions = _chunkVKLWTTUOcjs.biomarkerRangeDefinitions; exports.calculateNextScreeningDate = calculateNextScreeningDate; exports.cnsToFHIRIdentifier = cnsToFHIRIdentifier; exports.codeToLoinc = _chunkT75NZM56cjs.codeToLoinc; exports.convertUnit = _chunk5RC7C7HJcjs.convertUnit; exports.cpfToFHIRIdentifier = cpfToFHIRIdentifier; exports.defaultReferenceRanges = _chunkVKLWTTUOcjs.defaultReferenceRanges; exports.entryFullUrl = _chunkNKDUVSDKcjs.entryFullUrl; exports.extractObservationsFromBundle = _chunk376KM7ILcjs.extractObservationsFromBundle; exports.extractSourceKey = _chunk5FMR2U7Pcjs.extractSourceKey; exports.filterVisibleBiomarkers = _chunkT75NZM56cjs.filterVisibleBiomarkers; exports.findCodeByName = _chunkT75NZM56cjs.findCodeByName; exports.flagAgainstCatalogRange = _chunkVKLWTTUOcjs.flagAgainstCatalogRange; exports.formatCNS = formatCNS; exports.formatCPF = formatCPF; exports.generateCacFullReference = _chunkT75NZM56cjs.generateCacFullReference; exports.generateDexaFullReference = _chunkT75NZM56cjs.generateDexaFullReference; exports.generateFilteredLLMReference = _chunkT75NZM56cjs.generateFilteredLLMReference; exports.generateLLMReference = _chunkT75NZM56cjs.generateLLMReference; exports.getAllCodes = _chunkT75NZM56cjs.getAllCodes; exports.getAllDefinitions = _chunkT75NZM56cjs.getAllDefinitions; exports.getAllLoincCodes = _chunkT75NZM56cjs.getAllLoincCodes; exports.getAllSearchPatterns = _chunkT75NZM56cjs.getAllSearchPatterns; exports.getBiomarkersByCategory = _chunkT75NZM56cjs.getBiomarkersByCategory; exports.getBiomarkersForCategories = _chunkT75NZM56cjs.getBiomarkersForCategories; exports.getCanonicalUnit = _chunk5RC7C7HJcjs.getCanonicalUnit; exports.getCategoriesByInterval = getCategoriesByInterval; exports.getCategoryGroup = getCategoryGroup; exports.getDaysUntilScreening = getDaysUntilScreening; exports.getDefaultUnit = _chunk5RC7C7HJcjs.getDefaultUnit; exports.getDefinitionByCode = _chunkT75NZM56cjs.getDefinitionByCode; exports.getDefinitionByLoinc = _chunkT75NZM56cjs.getDefinitionByLoinc; exports.getDefinitionsBySex = _chunkT75NZM56cjs.getDefinitionsBySex; exports.getDueCategories = getDueCategories; exports.getFallbackReferenceRange = _chunkVKLWTTUOcjs.getFallbackReferenceRange; exports.getRangeDirection = _chunkVKLWTTUOcjs.getRangeDirection; exports.getReferenceRange = _chunkVKLWTTUOcjs.getReferenceRange; exports.getSIUnit = _chunk5RC7C7HJcjs.getSIUnit; exports.getScreeningInterval = getScreeningInterval; exports.getSexForCode = _chunkT75NZM56cjs.getSexForCode; exports.getVisibleDefinitions = _chunkT75NZM56cjs.getVisibleDefinitions; exports.interventionToFHIRMedicationStatement = interventionToFHIRMedicationStatement; exports.interventionToFHIRObservation = interventionToFHIRObservation; exports.interventionsToFHIRBundle = interventionsToFHIRBundle; exports.isBiomarkerVisible = _chunkT75NZM56cjs.isBiomarkerVisible; exports.isCacDocument = _chunkT75NZM56cjs.isCacDocument; exports.isDexaDocument = _chunkT75NZM56cjs.isDexaDocument; exports.isScreeningDue = isScreeningDue; exports.isUcumCode = _chunk5RC7C7HJcjs.isUcumCode; exports.isValidCode = _chunkT75NZM56cjs.isValidCode; exports.isValidLoinc = _chunkT75NZM56cjs.isValidLoinc; exports.labObservationToFHIR = _chunkNKDUVSDKcjs.labObservationToFHIR; exports.labReportToFHIR = _chunkNKDUVSDKcjs.labReportToFHIR; exports.labResultToFHIRBundle = _chunkNKDUVSDKcjs.labResultToFHIRBundle; exports.listMappedSubcategories = listMappedSubcategories; exports.loincToCode = _chunkT75NZM56cjs.loincToCode; exports.mapFHIRObservationToInternal = _chunk376KM7ILcjs.mapFHIRObservationToInternal; exports.normalizeCode = _chunkT75NZM56cjs.normalizeCode; exports.plural = plural; exports.pluralCount = pluralCount; exports.pluralPhrase = pluralPhrase; exports.pluralPhraseCount = pluralPhraseCount; exports.processImportBundle = _chunk376KM7ILcjs.processImportBundle; exports.referenceRangeMeaning = _chunkVKLWTTUOcjs.referenceRangeMeaning; exports.resolveUcum = _chunk5RC7C7HJcjs.resolveUcum; exports.specimenTypeCoding = specimenTypeCoding; exports.toBiomarkerTests = _chunkT75NZM56cjs.toBiomarkerTests; exports.unitToUCUM = _chunk5RC7C7HJcjs.unitToUCUM; exports.userProfileToFHIR = _chunkNKDUVSDKcjs.userProfileToFHIR; exports.validateCNS = validateCNS; exports.validateCPF = validateCPF; exports.validateFHIRDiagnosticReport = _chunkOAFAERDYcjs.validateFHIRDiagnosticReport; exports.validateFHIRImportBundle = _chunkOAFAERDYcjs.validateFHIRImportBundle; exports.validateFHIRObservation = _chunkOAFAERDYcjs.validateFHIRObservation; exports.validateLoincNameMatch = _chunkT75NZM56cjs.validateLoincNameMatch;
756
+
757
+ exports.AGE_BRACKETS = AGE_BRACKETS; exports.BIOMARKER_CODE_SYSTEM = _chunkOR67NJDZcjs.BIOMARKER_CODE_SYSTEM; exports.BIOMARKER_DEFAULT_UNIT = _chunkLNL5QSHPcjs.BIOMARKER_DEFAULT_UNIT; exports.BIOMARKER_DEFINITIONS = _chunkYL65SZ6Scjs.BIOMARKER_DEFINITIONS; exports.BIOMARKER_UNITS = _chunkLNL5QSHPcjs.BIOMARKER_UNITS; exports.BODY_FAT_ZONES = BODY_FAT_ZONES; exports.BR_TIPO_AMOSTRA_VALUESET = BR_TIPO_AMOSTRA_VALUESET; exports.BUNDLE_BASE_URL = _chunkXAIIZLZ7cjs.BUNDLE_BASE_URL; exports.CAC_INDICATOR_CODES = _chunkYL65SZ6Scjs.CAC_INDICATOR_CODES; exports.CATEGORY_GROUPS = CATEGORY_GROUPS; exports.CATEGORY_SCREENING_INTERVALS = CATEGORY_SCREENING_INTERVALS; exports.DEXA_CATEGORIES = _chunkYL65SZ6Scjs.DEXA_CATEGORIES; exports.DEXA_INDICATOR_CODES = _chunkYL65SZ6Scjs.DEXA_INDICATOR_CODES; exports.FHIR_BRASIL_EXTENSIONS = FHIR_BRASIL_EXTENSIONS; exports.HL7_SPECIMEN_TYPE_SYSTEM = HL7_SPECIMEN_TYPE_SYSTEM; exports.IG_CANONICAL = IG_CANONICAL; exports.LOINC_SYSTEM = _chunkOR67NJDZcjs.LOINC_SYSTEM; exports.MAX_FILE_SIZE = _chunk77LDD6OPcjs.MAX_FILE_SIZE; exports.MAX_OBSERVATIONS = _chunk77LDD6OPcjs.MAX_OBSERVATIONS; exports.SOURCE_REGISTRY = _chunk5FMR2U7Pcjs.SOURCE_REGISTRY; exports.T_SCORE_ZONES = T_SCORE_ZONES; exports.UNIT_TO_UCUM = _chunkLNL5QSHPcjs.UNIT_TO_UCUM; exports.ZONE_DEFS = ZONE_DEFS; exports.applyFallbackReferenceRanges = _chunkHZSW5T7Ecjs.applyFallbackReferenceRanges; exports.biomarkerRangeDefinitions = _chunkHZSW5T7Ecjs.biomarkerRangeDefinitions; exports.calculateNextScreeningDate = calculateNextScreeningDate; exports.cnsToFHIRIdentifier = cnsToFHIRIdentifier; exports.codeToLoinc = _chunkYL65SZ6Scjs.codeToLoinc; exports.convertUnit = _chunkLNL5QSHPcjs.convertUnit; exports.cpfToFHIRIdentifier = cpfToFHIRIdentifier; exports.defaultReferenceRanges = _chunkHZSW5T7Ecjs.defaultReferenceRanges; exports.entryFullUrl = _chunkXAIIZLZ7cjs.entryFullUrl; exports.extractObservationsFromBundle = _chunk77LDD6OPcjs.extractObservationsFromBundle; exports.extractSourceKey = _chunk5FMR2U7Pcjs.extractSourceKey; exports.filterVisibleBiomarkers = _chunkYL65SZ6Scjs.filterVisibleBiomarkers; exports.findCodeByName = _chunkYL65SZ6Scjs.findCodeByName; exports.flagAgainstCatalogRange = _chunkHZSW5T7Ecjs.flagAgainstCatalogRange; exports.formatCNS = formatCNS; exports.formatCPF = formatCPF; exports.generateCacFullReference = _chunkYL65SZ6Scjs.generateCacFullReference; exports.generateDexaFullReference = _chunkYL65SZ6Scjs.generateDexaFullReference; exports.generateFilteredLLMReference = _chunkYL65SZ6Scjs.generateFilteredLLMReference; exports.generateLLMReference = _chunkYL65SZ6Scjs.generateLLMReference; exports.getAllCodes = _chunkYL65SZ6Scjs.getAllCodes; exports.getAllDefinitions = _chunkYL65SZ6Scjs.getAllDefinitions; exports.getAllLoincCodes = _chunkYL65SZ6Scjs.getAllLoincCodes; exports.getAllSearchPatterns = _chunkYL65SZ6Scjs.getAllSearchPatterns; exports.getBiomarkersByCategory = _chunkYL65SZ6Scjs.getBiomarkersByCategory; exports.getBiomarkersForCategories = _chunkYL65SZ6Scjs.getBiomarkersForCategories; exports.getCanonicalUnit = _chunkLNL5QSHPcjs.getCanonicalUnit; exports.getCategoriesByInterval = getCategoriesByInterval; exports.getCategoryGroup = getCategoryGroup; exports.getDaysUntilScreening = getDaysUntilScreening; exports.getDefaultUnit = _chunkLNL5QSHPcjs.getDefaultUnit; exports.getDefinitionByCode = _chunkYL65SZ6Scjs.getDefinitionByCode; exports.getDefinitionByLoinc = _chunkYL65SZ6Scjs.getDefinitionByLoinc; exports.getDefinitionsBySex = _chunkYL65SZ6Scjs.getDefinitionsBySex; exports.getDueCategories = getDueCategories; exports.getFallbackReferenceRange = _chunkHZSW5T7Ecjs.getFallbackReferenceRange; exports.getRangeDirection = _chunkHZSW5T7Ecjs.getRangeDirection; exports.getReferenceRange = _chunkHZSW5T7Ecjs.getReferenceRange; exports.getSIUnit = _chunkLNL5QSHPcjs.getSIUnit; exports.getScreeningInterval = getScreeningInterval; exports.getSexForCode = _chunkYL65SZ6Scjs.getSexForCode; exports.getVisibleDefinitions = _chunkYL65SZ6Scjs.getVisibleDefinitions; exports.interventionToFHIRMedicationStatement = interventionToFHIRMedicationStatement; exports.interventionToFHIRObservation = interventionToFHIRObservation; exports.interventionsToFHIRBundle = interventionsToFHIRBundle; exports.isBiomarkerVisible = _chunkYL65SZ6Scjs.isBiomarkerVisible; exports.isCacDocument = _chunkYL65SZ6Scjs.isCacDocument; exports.isDexaDocument = _chunkYL65SZ6Scjs.isDexaDocument; exports.isScreeningDue = isScreeningDue; exports.isUcumCode = _chunkLNL5QSHPcjs.isUcumCode; exports.isValidCode = _chunkYL65SZ6Scjs.isValidCode; exports.isValidLoinc = _chunkYL65SZ6Scjs.isValidLoinc; exports.labObservationToFHIR = _chunkXAIIZLZ7cjs.labObservationToFHIR; exports.labReportToFHIR = _chunkXAIIZLZ7cjs.labReportToFHIR; exports.labResultToFHIRBundle = _chunkXAIIZLZ7cjs.labResultToFHIRBundle; exports.listMappedSubcategories = listMappedSubcategories; exports.loincToCode = _chunkYL65SZ6Scjs.loincToCode; exports.mapFHIRObservationToInternal = _chunk77LDD6OPcjs.mapFHIRObservationToInternal; exports.methodVariantOf = _chunkYL65SZ6Scjs.methodVariantOf; exports.normalizeCode = _chunkYL65SZ6Scjs.normalizeCode; exports.plural = plural; exports.pluralCount = pluralCount; exports.pluralPhrase = pluralPhrase; exports.pluralPhraseCount = pluralPhraseCount; exports.processImportBundle = _chunk77LDD6OPcjs.processImportBundle; exports.referenceRangeMeaning = _chunkHZSW5T7Ecjs.referenceRangeMeaning; exports.resolveUcum = _chunkLNL5QSHPcjs.resolveUcum; exports.specimenTypeCoding = specimenTypeCoding; exports.toBiomarkerTests = _chunkYL65SZ6Scjs.toBiomarkerTests; exports.unitToUCUM = _chunkLNL5QSHPcjs.unitToUCUM; exports.userProfileToFHIR = _chunkXAIIZLZ7cjs.userProfileToFHIR; exports.validateCNS = validateCNS; exports.validateCPF = validateCPF; exports.validateFHIRDiagnosticReport = _chunkVMYB7KOEcjs.validateFHIRDiagnosticReport; exports.validateFHIRImportBundle = _chunkVMYB7KOEcjs.validateFHIRImportBundle; exports.validateFHIRObservation = _chunkVMYB7KOEcjs.validateFHIRObservation; exports.validateLoincNameMatch = _chunkYL65SZ6Scjs.validateLoincNameMatch;
756
758
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/fhir-brasil/fhir-brasil/packages/core/dist/index.cjs","../src/category-groups.ts","../src/intervention-converter.ts","../src/dexa-zone-data.ts","../src/screening-intervals.ts","../src/i18n.ts","../src/identifiers.ts","../src/extension-urls.ts","../src/specimen-types.ts"],"names":[],"mappings":"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d,EAAA;AACE,EAAA;AACjC;AAW2C;AACS,EAAA;AACE,EAAA;AACL,EAAA;AACjD;AHoNoD;AACA;AI1TqB;AAAA;AAEvE,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AAAA;AAGA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AAAA;AAGA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACF;AAKiG;AAC7C,EAAA;AACpD;AAOkC;AACkB,EAAA;AACpD;AAK+D;AACf,EAAA;AACxB,EAAA;AAEgB,EAAA;AACW,EAAA;AAC1C,EAAA;AACT;AAQE;AAE4C,EAAA;AACtB,EAAA;AACE,EAAA;AAC1B;AAOE;AAE4C,EAAA;AACM,IAAA;AAC1B,IAAA;AACmB,IAAA;AAC1C,EAAA;AACH;AAOE;AAG4C,EAAA;AACtB,EAAA;AAEgB,EAAA;AACW,EAAA;AACnD;AJmRoD;AACA;AKreJ;AAML;AAAA;AAEhC,EAAA;AACI,EAAA;AAAA;AAED,EAAA;AAAA;AAED,EAAA;AACC,EAAA;AACA,EAAA;AACD,EAAA;AACF,EAAA;AACG,EAAA;AACD,EAAA;AACF,EAAA;AACF,EAAA;AACG,EAAA;AAEA,EAAA;AAAA;AAEF,EAAA;AACD,EAAA;AACG,EAAA;AACJ,EAAA;AACC,EAAA;AACC,EAAA;AACE,EAAA;AACA,EAAA;AACA,EAAA;AAEC,EAAA;AACF,EAAA;AAEC,EAAA;AACD,EAAA;AACX;AAMoD;AACR,EAAA;AAC5C;AAW+D;AACxB,EAAA;AACY,EAAA;AACnD;AASoE;AAC5B,EAAA;AACxC;AAWwF;AACjD,EAAA;AACjB,EAAA;AACS,IAAA;AAC7B,EAAA;AAC+C,EAAA;AACjD;AAS6F;AAC9C,EAAA;AAC/C;ALsboD;AACA;AMvhBjC;AACA;AAKwB;AACX,EAAA;AAChC;AAQkD;AACnB,EAAA;AAEI,EAAA;AAGO,EAAA;AAG9B,EAAA;AACkB,EAAA;AACO,IAAA;AACnC,EAAA;AAC6B,EAAA;AACK,EAAA;AACU,EAAA;AAGtC,EAAA;AACuB,EAAA;AACM,IAAA;AACnC,EAAA;AACyB,EAAA;AACS,EAAA;AACW,EAAA;AAEtC,EAAA;AACT;AAWkD;AACnB,EAAA;AAEI,EAAA;AAEN,EAAA;AAGuB,EAAA;AAGxC,EAAA;AACmB,EAAA;AACM,IAAA;AACnC,EAAA;AACoB,EAAA;AACtB;AAQ+C;AAChB,EAAA;AACI,EAAA;AACiB,EAAA;AACpD;AAQ+C;AAChB,EAAA;AACI,EAAA;AACiB,EAAA;AACpD;AASiE;AACxC,EAAA;AACS,IAAA;AAChC,EAAA;AACO,EAAA;AACG,IAAA;AACH,IAAA;AACgB,IAAA;AACvB,EAAA;AACF;AASiE;AACxC,EAAA;AACS,IAAA;AAChC,EAAA;AACO,EAAA;AACG,IAAA;AACH,IAAA;AACgB,IAAA;AACvB,EAAA;AACF;ANwdoD;AACA;AO3lBxB;AAEuC;AAS7B;AAAA;AAEO,EAAA;AAAA;AAEP,EAAA;AAAkB;AAEZ,EAAA;AAAuB;AAE3B,EAAA;AAAmB;AAEV,EAAA;AAAA;AAEH,EAAA;AAAA;AAET,EAAA;AACrC;APolBoD;AACA;AQnmBZ;AAUA;AAW0B;AACjC,EAAA;AACG,EAAA;AACI,EAAA;AACP,EAAA;AACE,EAAA;AACA,EAAA;AACnC;AAoBkB;AAIQ;AAOK;AACM,EAAA;AAChB,IAAA;AACQ,IAAA;AAC1B,EAAA;AACH;AAUE;AR6iBkD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/fhir-brasil/fhir-brasil/packages/core/dist/index.cjs","sourcesContent":[null,"/**\n * Agrupamento de categorias clínicas em 10 grupos de alto nível.\n *\n * `BiomarkerDefinition.category` armazena 20 sub-categorias (granularidade\n * fina, ex: `tireoide`, `pancreas`). Este módulo agrupa essas\n * sub-categorias em 10 buckets clínicos amplos para apresentação no\n * site, na API pública e em material de divulgação.\n *\n * As sub-categorias permanecem como fonte da verdade nos dados; este\n * agrupamento é uma camada derivada.\n */\n\nexport type CategoryGroup =\n | 'cardiovascular'\n | 'metabolico-endocrino'\n | 'renal-eletrolitico'\n | 'hepatico-biliar'\n | 'hematologico'\n | 'imunologico'\n | 'oncologico'\n | 'nutricional-ambiental'\n | 'saude-reprodutiva'\n | 'composicao-envelhecimento';\n\nexport interface CategoryGroupInfo {\n /** Rótulo em inglês */\n en: string;\n /** Rótulo em português */\n pt: string;\n /** Slug (kebab-case, sem acento) */\n slug: CategoryGroup;\n /** Sub-categorias da fonte agrupadas neste bucket */\n subcategories: readonly string[];\n}\n\nexport const CATEGORY_GROUPS: Record<CategoryGroup, CategoryGroupInfo> = {\n cardiovascular: {\n en: 'Cardiovascular',\n pt: 'Cardiovascular',\n slug: 'cardiovascular',\n subcategories: ['coracao'],\n },\n 'composicao-envelhecimento': {\n en: 'Body Composition & Aging',\n pt: 'Composição Corporal e Envelhecimento',\n slug: 'composicao-envelhecimento',\n subcategories: ['composicao-corporal', 'densidade-ossea', 'estresse-envelhecimento'],\n },\n hematologico: {\n en: 'Hematology',\n pt: 'Hematológico',\n slug: 'hematologico',\n subcategories: ['sangue'],\n },\n 'hepatico-biliar': {\n en: 'Hepatic & Biliary',\n pt: 'Hepático e Biliar',\n slug: 'hepatico-biliar',\n subcategories: ['figado'],\n },\n imunologico: {\n en: 'Immunology',\n pt: 'Imunológico',\n slug: 'imunologico',\n subcategories: ['autoimunidade', 'regulacao-imunologica'],\n },\n 'metabolico-endocrino': {\n en: 'Metabolic & Endocrine',\n pt: 'Metabólico e Endócrino',\n slug: 'metabolico-endocrino',\n subcategories: ['metabolico', 'pancreas', 'hormonios', 'tireoide'],\n },\n 'nutricional-ambiental': {\n en: 'Nutrition & Environmental Exposure',\n pt: 'Nutricional e Exposição Ambiental',\n slug: 'nutricional-ambiental',\n subcategories: ['nutrientes', 'toxinas-ambientais'],\n },\n oncologico: {\n en: 'Oncology',\n pt: 'Oncológico',\n slug: 'oncologico',\n subcategories: ['marcadores-tumorais'],\n },\n 'renal-eletrolitico': {\n en: 'Renal & Electrolytes',\n pt: 'Renal e Eletrolítico',\n slug: 'renal-eletrolitico',\n subcategories: ['rins', 'urina', 'eletrolitos'],\n },\n 'saude-reprodutiva': {\n en: 'Reproductive Health',\n pt: 'Saúde Reprodutiva',\n slug: 'saude-reprodutiva',\n subcategories: ['saude-feminina', 'saude-masculina'],\n },\n};\n\nconst SUBCATEGORY_TO_GROUP = new Map<string, CategoryGroup>();\nfor (const group of Object.values(CATEGORY_GROUPS)) {\n for (const sub of group.subcategories) {\n SUBCATEGORY_TO_GROUP.set(sub, group.slug);\n }\n}\n\n/**\n * Resolve a sub-categoria (granular) para o grupo de alto nível (10 buckets).\n */\nexport function getCategoryGroup(subcategory: string): CategoryGroup | undefined {\n return SUBCATEGORY_TO_GROUP.get(subcategory);\n}\n\n/**\n * Lista todas as sub-categorias mapeadas em algum grupo.\n */\nexport function listMappedSubcategories(): readonly string[] {\n return [...SUBCATEGORY_TO_GROUP.keys()];\n}\n","/**\n * FHIR Intervention Converter\n *\n * Converts interventions (medication, supplement, diet, exercise, sleep)\n * to FHIR R4 MedicationStatement and Observation resources.\n */\n\nimport { type Addressable, entryFullUrl } from './bundle-urls';\nimport { userProfileToFHIR } from './converter';\nimport type { FHIRBundle, FHIRMedicationStatement, FHIRObservation } from './fhir-types';\nimport type { InterventionData, UserProfileData } from './types';\n\n/**\n * Determine MedicationStatement/Observation status based on end date\n */\nfunction interventionStatus(endDate?: string): 'active' | 'completed' {\n if (!endDate) return 'active';\n return new Date(endDate) < new Date() ? 'completed' : 'active';\n}\n\n/**\n * LOINC-like codes for lifestyle observation types\n */\nconst LIFESTYLE_CODES: Record<string, { code: string; display: string }> = {\n diet: { code: '81259-4', display: 'Diet' },\n exercise: { code: '73985-4', display: 'Exercise activity' },\n sleep: { code: '93832-4', display: 'Sleep duration' },\n};\n\n/**\n * Convert medication/supplement intervention to FHIR MedicationStatement\n */\nexport function interventionToFHIRMedicationStatement(\n intervention: InterventionData,\n patientId: string,\n): Addressable<FHIRMedicationStatement> {\n const statement: Addressable<FHIRMedicationStatement> = {\n category: {\n coding: [\n {\n code: 'patientspecified',\n display: 'Patient Specified',\n system: 'http://terminology.hl7.org/CodeSystem/medication-statement-category',\n },\n ],\n },\n dateAsserted: intervention.startDate,\n effectivePeriod: {\n end: intervention.endDate,\n start: intervention.startDate,\n },\n id: `intervention-${intervention.interventionId}`,\n medicationCodeableConcept: {\n text: intervention.name,\n },\n resourceType: 'MedicationStatement',\n status: interventionStatus(intervention.endDate),\n subject: {\n reference: `Patient/${patientId}`,\n },\n };\n\n if (intervention.notes) {\n statement.note = [{ text: intervention.notes }];\n }\n\n return statement;\n}\n\n/**\n * Convert diet/exercise/sleep intervention to FHIR Observation (social-history)\n */\nexport function interventionToFHIRObservation(\n intervention: InterventionData,\n patientId: string,\n): Addressable<FHIRObservation> {\n const lifestyleCode = LIFESTYLE_CODES[intervention.type];\n\n const observation: Addressable<FHIRObservation> = {\n category: [\n {\n coding: [\n {\n code: 'social-history',\n display: 'Social History',\n system: 'http://terminology.hl7.org/CodeSystem/observation-category',\n },\n ],\n },\n ],\n code: {\n coding: lifestyleCode\n ? [\n {\n code: lifestyleCode.code,\n display: lifestyleCode.display,\n system: 'http://loinc.org',\n },\n ]\n : [],\n text: intervention.name,\n },\n effectivePeriod: {\n end: intervention.endDate,\n start: intervention.startDate,\n },\n id: `intervention-${intervention.interventionId}`,\n resourceType: 'Observation',\n status: 'final',\n subject: {\n reference: `Patient/${patientId}`,\n },\n valueString: intervention.name,\n };\n\n if (intervention.notes) {\n observation.note = [{ text: intervention.notes }];\n }\n\n return observation;\n}\n\n/**\n * Convert all interventions to a FHIR Bundle\n */\nexport function interventionsToFHIRBundle(\n interventions: InterventionData[],\n userProfile: UserProfileData,\n): FHIRBundle {\n const patientId = userProfile.userId;\n const fhirPatient = userProfileToFHIR(userProfile);\n\n const entries = interventions.map((intervention) => {\n const isMedication = intervention.type === 'medication' || intervention.type === 'supplement';\n const resource = isMedication\n ? interventionToFHIRMedicationStatement(intervention, patientId)\n : interventionToFHIRObservation(intervention, patientId);\n\n return { fullUrl: entryFullUrl(resource), resource };\n });\n\n return {\n entry: [{ fullUrl: entryFullUrl(fhirPatient), resource: fhirPatient }, ...entries],\n resourceType: 'Bundle',\n type: 'collection',\n };\n}\n","/**\n * Structured zone data for DEXA body composition and bone density charts.\n *\n * Body fat zones derived from Gallagher et al. Am J Clin Nutr 2000;72:694-701 (PMID: 10966886)\n * and ACSM Guidelines for Exercise Testing, 11th Ed (2021).\n *\n * T-Score zones from WHO criteria (Kanis JA, Osteoporos Int, PMID: 7696835).\n */\n\nexport interface BodyFatZone {\n ageMax: number;\n ageMin: number;\n color: string;\n fatPctMax: number;\n fatPctMin: number;\n label: string;\n sex: 'F' | 'M';\n}\n\ninterface AgeBracket {\n ageMax: number;\n ageMin: number;\n label: string;\n}\n\nconst AGE_BRACKETS: AgeBracket[] = [\n { ageMax: 25, ageMin: 18, label: '18-25' },\n { ageMax: 35, ageMin: 26, label: '26-35' },\n { ageMax: 45, ageMin: 36, label: '36-45' },\n { ageMax: 55, ageMin: 46, label: '46-55' },\n { ageMax: 99, ageMin: 56, label: '56+' },\n];\n\n// Zone boundaries per age bracket for men: [essential, athletic, fitness, average, obese]\n// Each value is the upper bound of the zone\nconst MALE_ZONES: number[][] = [\n [5, 10, 20, 25, 40],\n [5, 11, 21, 26, 40],\n [5, 12, 22, 27, 40],\n [5, 13, 23, 28, 40],\n [5, 14, 24, 29, 40],\n];\n\nconst FEMALE_ZONES: number[][] = [\n [13, 18, 28, 32, 45],\n [13, 18, 29, 33, 45],\n [13, 19, 30, 34, 45],\n [13, 20, 31, 35, 45],\n [13, 20, 32, 36, 45],\n];\n\ninterface ZoneDefinition {\n color: string;\n label: string;\n}\n\nconst ZONE_DEFS: ZoneDefinition[] = [\n { color: '#3b82f6', label: 'Essencial' },\n { color: '#06b6d4', label: 'Atlético' },\n { color: '#22c55e', label: 'Fitness' },\n { color: '#eab308', label: 'Média' },\n { color: '#ef4444', label: 'Obeso' },\n];\n\nfunction buildZones(sex: 'F' | 'M', zoneData: number[][]): BodyFatZone[] {\n const zones: BodyFatZone[] = [];\n for (let i = 0; i < AGE_BRACKETS.length; i++) {\n const bracket = AGE_BRACKETS[i]!;\n const b = zoneData[i]!;\n zones.push({\n ...bracket,\n color: ZONE_DEFS[0]!.color,\n fatPctMax: b[0]!,\n fatPctMin: 0,\n label: ZONE_DEFS[0]!.label,\n sex,\n });\n zones.push({\n ...bracket,\n color: ZONE_DEFS[1]!.color,\n fatPctMax: b[1]!,\n fatPctMin: b[0]!,\n label: ZONE_DEFS[1]!.label,\n sex,\n });\n zones.push({\n ...bracket,\n color: ZONE_DEFS[2]!.color,\n fatPctMax: b[2]!,\n fatPctMin: b[1]!,\n label: ZONE_DEFS[2]!.label,\n sex,\n });\n zones.push({\n ...bracket,\n color: ZONE_DEFS[3]!.color,\n fatPctMax: b[3]!,\n fatPctMin: b[2]!,\n label: ZONE_DEFS[3]!.label,\n sex,\n });\n zones.push({\n ...bracket,\n color: ZONE_DEFS[4]!.color,\n fatPctMax: b[4]!,\n fatPctMin: b[3]!,\n label: ZONE_DEFS[4]!.label,\n sex,\n });\n }\n return zones;\n}\n\nexport const BODY_FAT_ZONES: BodyFatZone[] = [\n ...buildZones('M', MALE_ZONES),\n ...buildZones('F', FEMALE_ZONES),\n];\n\nexport { AGE_BRACKETS, ZONE_DEFS };\n\nexport interface TScoreZone {\n color: string;\n label: string;\n max: number;\n min: number;\n}\n\nexport const T_SCORE_ZONES: TScoreZone[] = [\n { color: '#22c55e', label: 'Normal', max: 4, min: -1.0 },\n { color: '#eab308', label: 'Osteopenia', max: -1.0, min: -2.5 },\n { color: '#ef4444', label: 'Osteoporose', max: -2.5, min: -5 },\n];\n","/**\n * Screening Intervals Configuration\n *\n * Defines recommended screening intervals for different biomarker categories\n * based on clinical guidelines and best practices.\n */\n\n/**\n * Screening interval in months\n */\nexport type ScreeningIntervalMonths = 3 | 6 | 12;\n\n/**\n * Biomarker category with its recommended screening interval\n */\nexport interface CategoryScreeningInterval {\n category: string;\n intervalMonths: ScreeningIntervalMonths;\n nameEn: string;\n namePt: string;\n}\n\n/**\n * Screening interval configuration for each category\n *\n * Categories are grouped by their recommended screening intervals:\n * - 3 months: Body composition and bone density (frequently changing metrics)\n * - 6 months: Metabolic panel and nutrients (moderate change rate)\n * - 12 months: Standard blood panels (stable long-term markers)\n */\nexport const CATEGORY_SCREENING_INTERVALS: CategoryScreeningInterval[] = [\n // 3-month intervals - Body composition (frequently changing)\n {\n category: 'composicao-corporal',\n intervalMonths: 3,\n nameEn: 'Body Composition',\n namePt: 'Composição Corporal',\n },\n {\n category: 'densidade-ossea',\n intervalMonths: 3,\n nameEn: 'Bone Density',\n namePt: 'Densidade Óssea',\n },\n\n // 6-month intervals - Metabolic and nutrients\n {\n category: 'metabolico',\n intervalMonths: 6,\n nameEn: 'Metabolic Panel',\n namePt: 'Painel Metabólico',\n },\n {\n category: 'nutrientes',\n intervalMonths: 6,\n nameEn: 'Nutrients',\n namePt: 'Nutrientes',\n },\n {\n category: 'pancreas',\n intervalMonths: 6,\n nameEn: 'Pancreas',\n namePt: 'Pâncreas',\n },\n\n // 12-month intervals - Standard blood panels\n {\n category: 'coracao',\n intervalMonths: 12,\n nameEn: 'Heart Health',\n namePt: 'Saúde Cardiovascular',\n },\n {\n category: 'tireoide',\n intervalMonths: 12,\n nameEn: 'Thyroid',\n namePt: 'Tireoide',\n },\n {\n category: 'sangue',\n intervalMonths: 12,\n nameEn: 'Blood Count',\n namePt: 'Hemograma',\n },\n {\n category: 'figado',\n intervalMonths: 12,\n nameEn: 'Liver Function',\n namePt: 'Função Hepática',\n },\n {\n category: 'rins',\n intervalMonths: 12,\n nameEn: 'Kidney Function',\n namePt: 'Função Renal',\n },\n {\n category: 'saude-feminina',\n intervalMonths: 12,\n nameEn: \"Women's Health\",\n namePt: 'Saúde Feminina',\n },\n {\n category: 'saude-masculina',\n intervalMonths: 12,\n nameEn: \"Men's Health\",\n namePt: 'Saúde Masculina',\n },\n {\n category: 'eletrolitos',\n intervalMonths: 12,\n nameEn: 'Electrolytes',\n namePt: 'Eletrólitos',\n },\n {\n category: 'estresse-envelhecimento',\n intervalMonths: 12,\n nameEn: 'Stress & Aging',\n namePt: 'Estresse e Envelhecimento',\n },\n {\n category: 'autoimunidade',\n intervalMonths: 12,\n nameEn: 'Autoimmunity',\n namePt: 'Autoimunidade',\n },\n {\n category: 'regulacao-imunologica',\n intervalMonths: 12,\n nameEn: 'Immune Regulation',\n namePt: 'Regulação Imunológica',\n },\n {\n category: 'toxinas-ambientais',\n intervalMonths: 12,\n nameEn: 'Environmental Toxins',\n namePt: 'Toxinas Ambientais',\n },\n {\n category: 'urina',\n intervalMonths: 12,\n nameEn: 'Urinalysis',\n namePt: 'Urina',\n },\n];\n\n/**\n * Get screening interval for a category\n */\nexport const getScreeningInterval = (category: string): CategoryScreeningInterval | undefined => {\n return CATEGORY_SCREENING_INTERVALS.find((c) => c.category === category);\n};\n\n/**\n * Get all categories with a specific interval\n */\nexport const getCategoriesByInterval = (\n intervalMonths: ScreeningIntervalMonths,\n): CategoryScreeningInterval[] => {\n return CATEGORY_SCREENING_INTERVALS.filter((c) => c.intervalMonths === intervalMonths);\n};\n\n/**\n * Calculate next screening date based on last test date and category\n */\nexport const calculateNextScreeningDate = (lastTestDate: Date, category: string): Date | null => {\n const interval = getScreeningInterval(category);\n if (!interval) return null;\n\n const nextDate = new Date(lastTestDate);\n nextDate.setMonth(nextDate.getMonth() + interval.intervalMonths);\n return nextDate;\n};\n\n/**\n * Check if a category is due for screening\n */\nexport const isScreeningDue = (\n lastTestDate: Date,\n category: string,\n referenceDate: Date = new Date(),\n): boolean => {\n const nextDate = calculateNextScreeningDate(lastTestDate, category);\n if (!nextDate) return false;\n return referenceDate >= nextDate;\n};\n\n/**\n * Get categories that are due for screening based on last test dates\n */\nexport const getDueCategories = (\n lastTestDates: Record<string, Date>,\n referenceDate: Date = new Date(),\n): CategoryScreeningInterval[] => {\n return CATEGORY_SCREENING_INTERVALS.filter((interval) => {\n const lastDate = lastTestDates[interval.category];\n if (!lastDate) return true; // Never tested = due\n return isScreeningDue(lastDate, interval.category, referenceDate);\n });\n};\n\n/**\n * Get days until next screening for a category\n */\nexport const getDaysUntilScreening = (\n lastTestDate: Date,\n category: string,\n referenceDate: Date = new Date(),\n): number | null => {\n const nextDate = calculateNextScreeningDate(lastTestDate, category);\n if (!nextDate) return null;\n\n const diffTime = nextDate.getTime() - referenceDate.getTime();\n return Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n};\n","/**\n * Portuguese pluralization utility using native Intl.PluralRules\n * Provides automatic pluralization for common words used in the app\n */\n\nconst pluralRules = new Intl.PluralRules('pt-BR');\n\n/**\n * Dictionary of Portuguese words with their plural forms\n * Key is the singular form, value is the plural form\n */\nconst dictionary: Record<string, string> = {\n // Common nouns\n arquivo: 'arquivos',\n biomarcador: 'biomarcadores',\n // Past participles (masculine)\n cadastrado: 'cadastrados',\n // Past participles (feminine)\n concluída: 'concluídas',\n confirmado: 'confirmados',\n convertido: 'convertidos',\n convidado: 'convidados',\n convite: 'convites',\n disponível: 'disponíveis',\n documento: 'documentos',\n enviado: 'enviados',\n exame: 'exames',\n excluída: 'excluídas',\n\n excluído: 'excluídos',\n // Verbs (3rd person)\n falhou: 'falharam',\n falta: 'faltam',\n ignorado: 'ignorados',\n item: 'itens',\n outro: 'outros',\n página: 'páginas',\n pendente: 'pendentes',\n registro: 'registros',\n removido: 'removidos',\n\n resultado: 'resultados',\n revisão: 'revisões',\n\n revogado: 'revogados',\n usuário: 'usuários',\n};\n\n/**\n * Get the plural form of a word from the dictionary\n * Falls back to adding 's' if word is not in dictionary\n */\nconst getPluralForm = (singular: string): string => {\n return dictionary[singular] ?? `${singular}s`;\n};\n\n/**\n * Returns the correct singular or plural form based on count\n * Uses Intl.PluralRules for proper locale-aware pluralization\n *\n * @example\n * plural(1, 'usuário') // 'usuário'\n * plural(3, 'usuário') // 'usuários'\n * plural(0, 'registro') // 'registros'\n */\nexport const plural = (count: number, word: string): string => {\n const rule = pluralRules.select(count);\n return rule === 'one' ? word : getPluralForm(word);\n};\n\n/**\n * Returns count with the correct singular or plural form\n *\n * @example\n * pluralCount(1, 'usuário') // '1 usuário'\n * pluralCount(3, 'usuário') // '3 usuários'\n */\nexport const pluralCount = (count: number, word: string): string => {\n return `${count} ${plural(count, word)}`;\n};\n\n/**\n * Returns the correct form for compound phrases (noun + adjective)\n * Both words are pluralized together\n *\n * @example\n * pluralPhrase(1, 'usuário', 'cadastrado') // 'usuário cadastrado'\n * pluralPhrase(3, 'usuário', 'cadastrado') // 'usuários cadastrados'\n * pluralPhrase(2, 'revisão', 'excluída') // 'revisões excluídas'\n */\nexport const pluralPhrase = (count: number, noun: string, adjective: string): string => {\n const rule = pluralRules.select(count);\n if (rule === 'one') {\n return `${noun} ${adjective}`;\n }\n return `${getPluralForm(noun)} ${getPluralForm(adjective)}`;\n};\n\n/**\n * Returns count with the correct compound phrase form\n *\n * @example\n * pluralPhraseCount(1, 'usuário', 'cadastrado') // '1 usuário cadastrado'\n * pluralPhraseCount(3, 'convite', 'enviado') // '3 convites enviados'\n */\nexport const pluralPhraseCount = (count: number, noun: string, adjective: string): string => {\n return `${count} ${pluralPhrase(count, noun, adjective)}`;\n};\n","/**\n * Helpers para identificadores brasileiros — CPF e CNS\n *\n * Validação, formatação e conversão para FHIR Identifier.\n * Algoritmos de validação baseados nas especificações oficiais:\n * - CPF: Receita Federal (mod-11, dois dígitos verificadores)\n * - CNS: Ministério da Saúde (mod-11 para definitivos, soma ponderada para provisórios)\n */\n\nimport type { FHIRIdentifier } from './fhir-types';\n\nconst CPF_SYSTEM = 'http://rnds.saude.gov.br/fhir/r4/NamingSystem/cpf';\nconst CNS_SYSTEM = 'http://rnds.saude.gov.br/fhir/r4/NamingSystem/cns';\n\n/**\n * Remove caracteres não-numéricos de uma string.\n */\nfunction digitsOnly(value: string): string {\n return value.replace(/\\D/g, '');\n}\n\n/**\n * Valida um CPF brasileiro usando algoritmo mod-11.\n *\n * @param cpf — CPF com ou sem formatação (ex: \"123.456.789-09\" ou \"12345678909\")\n * @returns true se o CPF é estruturalmente válido\n */\nexport function validateCPF(cpf: string): boolean {\n const digits = digitsOnly(cpf);\n\n if (digits.length !== 11) return false;\n\n // Rejeitar sequências de dígitos iguais (ex: 111.111.111-11)\n if (/^(\\d)\\1{10}$/.test(digits)) return false;\n\n // Primeiro dígito verificador\n let sum = 0;\n for (let i = 0; i < 9; i++) {\n sum += Number(digits[i]) * (10 - i);\n }\n let remainder = (sum * 10) % 11;\n if (remainder === 10) remainder = 0;\n if (remainder !== Number(digits[9])) return false;\n\n // Segundo dígito verificador\n sum = 0;\n for (let i = 0; i < 10; i++) {\n sum += Number(digits[i]) * (11 - i);\n }\n remainder = (sum * 10) % 11;\n if (remainder === 10) remainder = 0;\n if (remainder !== Number(digits[10])) return false;\n\n return true;\n}\n\n/**\n * Valida um CNS (Cartão Nacional de Saúde) brasileiro.\n *\n * CNS definitivos começam com 1 ou 2 (mod-11).\n * CNS provisórios começam com 7, 8 ou 9 (soma ponderada mod-11 = 0).\n *\n * @param cns — CNS com 15 dígitos\n * @returns true se o CNS é estruturalmente válido\n */\nexport function validateCNS(cns: string): boolean {\n const digits = digitsOnly(cns);\n\n if (digits.length !== 15) return false;\n\n const firstDigit = digits[0]!;\n\n // CNS deve começar com 1, 2 (definitivo) ou 7, 8, 9 (provisório)\n if (!['1', '2', '7', '8', '9'].includes(firstDigit)) return false;\n\n // Ambos os tipos usam soma ponderada mod-11 = 0\n let sum = 0;\n for (let i = 0; i < 15; i++) {\n sum += Number(digits[i]) * (15 - i);\n }\n return sum % 11 === 0;\n}\n\n/**\n * Formata um CPF como XXX.XXX.XXX-XX.\n *\n * @param cpf — CPF com 11 dígitos (com ou sem formatação)\n * @returns CPF formatado ou a string original se inválido\n */\nexport function formatCPF(cpf: string): string {\n const digits = digitsOnly(cpf);\n if (digits.length !== 11) return cpf;\n return `${digits.slice(0, 3)}.${digits.slice(3, 6)}.${digits.slice(6, 9)}-${digits.slice(9)}`;\n}\n\n/**\n * Formata um CNS como XXX XXXX XXXX XXXX.\n *\n * @param cns — CNS com 15 dígitos\n * @returns CNS formatado ou a string original se inválido\n */\nexport function formatCNS(cns: string): string {\n const digits = digitsOnly(cns);\n if (digits.length !== 15) return cns;\n return `${digits.slice(0, 3)} ${digits.slice(3, 7)} ${digits.slice(7, 11)} ${digits.slice(11)}`;\n}\n\n/**\n * Converte um CPF para um FHIR Identifier.\n *\n * @param cpf — CPF com 11 dígitos (com ou sem formatação)\n * @returns FHIR Identifier com sistema RNDS para CPF\n * @throws Error se o CPF for inválido\n */\nexport function cpfToFHIRIdentifier(cpf: string): FHIRIdentifier {\n if (!validateCPF(cpf)) {\n throw new Error('CPF inválido');\n }\n return {\n system: CPF_SYSTEM,\n use: 'official',\n value: digitsOnly(cpf),\n };\n}\n\n/**\n * Converte um CNS para um FHIR Identifier.\n *\n * @param cns — CNS com 15 dígitos\n * @returns FHIR Identifier com sistema RNDS para CNS\n * @throws Error se o CNS for inválido\n */\nexport function cnsToFHIRIdentifier(cns: string): FHIRIdentifier {\n if (!validateCNS(cns)) {\n throw new Error('CNS inválido');\n }\n return {\n system: CNS_SYSTEM,\n use: 'official',\n value: digitsOnly(cns),\n };\n}\n","/**\n * URLs das extensões do IG do fhir-brasil.\n *\n * Quem emite a extensão e quem a lê precisam concordar literalmente na URL: um\n * consumidor procura a extensão pelo `url`, e uma grafia divergente faz o dado\n * sumir sem erro. O teste confere cada uma contra o `Id:` do FSH em\n * `ig/input/fsh/extensions/`, então extensão nova no IG sem constante aqui, ou\n * o inverso, reprova.\n */\n\n/** Canonical do IG, como está no `sushi-config.yaml`. */\nexport const IG_CANONICAL = 'https://fhir-brasil.dev.br/ig';\n\nconst structureDefinition = (id: string): string => `${IG_CANONICAL}/StructureDefinition/${id}`;\n\n/**\n * Extensões do IG, pela URL.\n *\n * As que têm partes (`extractionSource`, `extractionConfidence`, `asPrinted`)\n * levam as partes em `extension[]` aninhado, cada uma com `url` relativo: o\n * nome da parte, como `page` ou `reading`. Ver o FSH de cada uma.\n */\nexport const FHIR_BRASIL_EXTENSIONS = {\n /** `Observation`: valor e faixa como impressos, quando a Observation traz outros. */\n asPrinted: structureDefinition('as-printed'),\n /** `Observation`: extraída de PDF via OCR. */\n derivedFromOCR: structureDefinition('derived-from-ocr'),\n /** `Observation`: confiança na leitura e na interpretação, de 0 a 1. */\n extractionConfidence: structureDefinition('extraction-confidence'),\n /** `Observation`: páginas, trecho citado e caixa do trecho no documento. */\n extractionSource: structureDefinition('extraction-source'),\n /** `DiagnosticReport`: lido da tabela de histórico de outro laudo. */\n reprintedIn: structureDefinition('reprinted-in'),\n /** `Observation`: lido do documento, mas substituído por outro valor do mesmo laudo. */\n superseded: structureDefinition('superseded'),\n /** `Observation`: unidade impressa ao lado de um resultado em texto. */\n textValueUnit: structureDefinition('text-value-unit'),\n} as const;\n","/**\n * Código do tipo de amostra a partir do material impresso no laudo.\n *\n * O perfil `BRAmostraBiologica-1.0` da RNDS vincula `Specimen.type` ao ValueSet\n * `BRTipoAmostra-1.0` com força `required`, exige `type.coding` (1..1) e proíbe\n * `type.text` (0..0). Um `Specimen` só com o texto do laudo não passa, e é o que\n * a extração produzia.\n *\n * O ValueSet tem 63 códigos, e quase todos são de vigilância respiratória vindos\n * do GAL: swab nasofaríngeo, lavado brônquico, fragmento de órgão. Para laudo de\n * rotina sobram seis, e esses seis cobrem o que um painel de sangue e urina\n * imprime.\n *\n * Não há código para fezes no ValueSet. Isso não afeta a extração, cujo catálogo\n * não tem nenhum biomarcador de origem fecal: um parasitológico não vira\n * `Observation`, então não chega a pedir `Specimen`.\n *\n * @see https://rnds-fhir.saude.gov.br/StructureDefinition-BRAmostraBiologica-1.0.html\n * @see https://rnds-fhir.saude.gov.br/ValueSet-BRTipoAmostra-1.0.html\n */\nimport type { FHIRCoding } from './fhir-types';\n\n/** ValueSet ao qual `Specimen.type` está vinculado no `BRAmostraBiologica`. */\nexport const BR_TIPO_AMOSTRA_VALUESET = 'https://rnds-fhir.saude.gov.br/ValueSet/BRTipoAmostra-1.0';\n\n/**\n * CodeSystem dos códigos que este módulo emite.\n *\n * O ValueSet também inclui o `BRTipoAmostraGAL`, que traz \"Sangue\" e \"Sangue com\n * EDTA\" soltos. Ficaram de fora porque a URL canônica daquele CodeSystem não foi\n * confirmada na fonte, e código de terminologia não se deduz de slug. Material\n * assim cai no caminho de não mapeado até alguém abrir o IG e confirmar.\n */\nexport const HL7_SPECIMEN_TYPE_SYSTEM = 'http://terminology.hl7.org/CodeSystem/v2-0487';\n\n/**\n * Os `display` são cópia literal do ValueSet, com a caixa dele.\n *\n * A chave é o texto já normalizado, e por enquanto é só o próprio display. Não\n * há sinônimo inventado aqui: a extração copia o material verbatim do laudo, e a\n * lista de variações que os laboratórios de fato imprimem ainda não foi medida\n * (a captura de material entrou em produção em 05/09/2026). Variação real\n * observada entra depois, com o laudo que a produziu.\n */\nconst CODINGS: ReadonlyArray<{ code: string; display: string }> = [\n { code: 'SER', display: 'Soro' },\n { code: 'PLAS', display: 'Plasma' },\n { code: 'WB', display: 'Sangue Total' },\n { code: 'UR', display: 'Urina' },\n { code: 'CSF', display: 'Líquor' },\n { code: 'SAL', display: 'Saliva' },\n];\n\n/**\n * Caixa, acento e espaço sobrando não distinguem material.\n *\n * Só isso. Não separa `camelCase` nem troca barra por espaço, ao contrário do\n * normalizador de nomes de biomarcador: \"Soro/Plasma\" impresso numa linha só é\n * ambíguo de verdade, e escolher um dos dois seria inferência. Sem casar, ele\n * segue o caminho do não mapeado.\n *\n * Os caracteres invisíveis saem antes, e a divisão entre as duas regras é a do\n * próprio Unicode: `\\p{Cf}` são os de formatação, que não ocupam espaço e por\n * isso são apagados, e `\\s` são os de espaço, que são colapsados. A camada de\n * texto de PDF emite os dois tipos, e um U+200B no meio de \"Soro\" derruba o\n * casamento sem deixar rastro na tela.\n *\n * Vale a categoria em vez da lista porque a lista nunca fecha. Enumerando, o\n * hífen opcional (U+00AD) tinha ficado de fora, e ele aparece justamente onde\n * um nome composto como \"Sangue Total\" quebra de linha.\n */\nconst INVISIBLE = /\\p{Cf}/gu;\n\nconst normalize = (text: string): string =>\n text\n .replace(INVISIBLE, '')\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .trim();\n\nconst BY_NORMALIZED_TEXT = new Map(\n CODINGS.map(({ code, display }) => [\n normalize(display),\n { code, display, system: HL7_SPECIMEN_TYPE_SYSTEM } satisfies FHIRCoding,\n ]),\n);\n\n/**\n * Coding do ValueSet para o material impresso, ou `undefined` sem casar.\n *\n * `undefined` é resposta legítima e não erro: o laudo pode trazer um material\n * fora do ValueSet, ou uma grafia que ninguém viu ainda. Quem chama decide o que\n * fazer, e a decisão que não existe é preencher com um código aproximado.\n */\nexport const specimenTypeCoding = (text: string): FHIRCoding | undefined =>\n BY_NORMALIZED_TEXT.get(normalize(text));\n"]}
1
+ {"version":3,"sources":["/home/runner/work/fhir-brasil/fhir-brasil/packages/core/dist/index.cjs","../src/category-groups.ts","../src/intervention-converter.ts","../src/dexa-zone-data.ts","../src/screening-intervals.ts","../src/i18n.ts","../src/identifiers.ts","../src/extension-urls.ts","../src/specimen-types.ts"],"names":[],"mappings":"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C;AACd,EAAA;AACE,EAAA;AACjC;AAW2C;AACS,EAAA;AACE,EAAA;AACL,EAAA;AACjD;AHqNoD;AACA;AI3TqB;AAAA;AAEvE,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AAAA;AAGA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AAAA;AAGA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACA,EAAA;AACY,IAAA;AACM,IAAA;AACR,IAAA;AACA,IAAA;AACV,EAAA;AACF;AAKiG;AAC7C,EAAA;AACpD;AAOkC;AACkB,EAAA;AACpD;AAK+D;AACf,EAAA;AACxB,EAAA;AAEgB,EAAA;AACW,EAAA;AAC1C,EAAA;AACT;AAQE;AAE4C,EAAA;AACtB,EAAA;AACE,EAAA;AAC1B;AAOE;AAE4C,EAAA;AACM,IAAA;AAC1B,IAAA;AACmB,IAAA;AAC1C,EAAA;AACH;AAOE;AAG4C,EAAA;AACtB,EAAA;AAEgB,EAAA;AACW,EAAA;AACnD;AJoRoD;AACA;AKteJ;AAML;AAAA;AAEhC,EAAA;AACI,EAAA;AAAA;AAED,EAAA;AAAA;AAED,EAAA;AACC,EAAA;AACA,EAAA;AACD,EAAA;AACF,EAAA;AACG,EAAA;AACD,EAAA;AACF,EAAA;AACF,EAAA;AACG,EAAA;AAEA,EAAA;AAAA;AAEF,EAAA;AACD,EAAA;AACG,EAAA;AACJ,EAAA;AACC,EAAA;AACC,EAAA;AACE,EAAA;AACA,EAAA;AACA,EAAA;AAEC,EAAA;AACF,EAAA;AAEC,EAAA;AACD,EAAA;AACX;AAMoD;AACR,EAAA;AAC5C;AAW+D;AACxB,EAAA;AACY,EAAA;AACnD;AASoE;AAC5B,EAAA;AACxC;AAWwF;AACjD,EAAA;AACjB,EAAA;AACS,IAAA;AAC7B,EAAA;AAC+C,EAAA;AACjD;AAS6F;AAC9C,EAAA;AAC/C;ALuboD;AACA;AMxhBjC;AACA;AAKwB;AACX,EAAA;AAChC;AAQkD;AACnB,EAAA;AAEI,EAAA;AAGO,EAAA;AAG9B,EAAA;AACkB,EAAA;AACO,IAAA;AACnC,EAAA;AAC6B,EAAA;AACK,EAAA;AACU,EAAA;AAGtC,EAAA;AACuB,EAAA;AACM,IAAA;AACnC,EAAA;AACyB,EAAA;AACS,EAAA;AACW,EAAA;AAEtC,EAAA;AACT;AAWkD;AACnB,EAAA;AAEI,EAAA;AAEN,EAAA;AAGuB,EAAA;AAGxC,EAAA;AACmB,EAAA;AACM,IAAA;AACnC,EAAA;AACoB,EAAA;AACtB;AAQ+C;AAChB,EAAA;AACI,EAAA;AACiB,EAAA;AACpD;AAQ+C;AAChB,EAAA;AACI,EAAA;AACiB,EAAA;AACpD;AASiE;AACxC,EAAA;AACS,IAAA;AAChC,EAAA;AACO,EAAA;AACG,IAAA;AACH,IAAA;AACgB,IAAA;AACvB,EAAA;AACF;AASiE;AACxC,EAAA;AACS,IAAA;AAChC,EAAA;AACO,EAAA;AACG,IAAA;AACH,IAAA;AACgB,IAAA;AACvB,EAAA;AACF;ANydoD;AACA;AO5lBxB;AAEuC;AAS7B;AAAA;AAEO,EAAA;AAAA;AAEP,EAAA;AAAkB;AAEZ,EAAA;AAAuB;AAE3B,EAAA;AAAmB;AAEV,EAAA;AAAA;AAEH,EAAA;AAAA;AAET,EAAA;AACrC;APqlBoD;AACA;AQpmBZ;AAUA;AAW0B;AACjC,EAAA;AACG,EAAA;AACI,EAAA;AACP,EAAA;AACE,EAAA;AACA,EAAA;AACnC;AAoBkB;AAIQ;AAOK;AACM,EAAA;AAChB,IAAA;AACQ,IAAA;AAC1B,EAAA;AACH;AAUE;AR8iBkD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/fhir-brasil/fhir-brasil/packages/core/dist/index.cjs","sourcesContent":[null,"/**\n * Agrupamento de categorias clínicas em 10 grupos de alto nível.\n *\n * `BiomarkerDefinition.category` armazena 20 sub-categorias (granularidade\n * fina, ex: `tireoide`, `pancreas`). Este módulo agrupa essas\n * sub-categorias em 10 buckets clínicos amplos para apresentação no\n * site, na API pública e em material de divulgação.\n *\n * As sub-categorias permanecem como fonte da verdade nos dados; este\n * agrupamento é uma camada derivada.\n */\n\nexport type CategoryGroup =\n | 'cardiovascular'\n | 'metabolico-endocrino'\n | 'renal-eletrolitico'\n | 'hepatico-biliar'\n | 'hematologico'\n | 'imunologico'\n | 'oncologico'\n | 'nutricional-ambiental'\n | 'saude-reprodutiva'\n | 'composicao-envelhecimento';\n\nexport interface CategoryGroupInfo {\n /** Rótulo em inglês */\n en: string;\n /** Rótulo em português */\n pt: string;\n /** Slug (kebab-case, sem acento) */\n slug: CategoryGroup;\n /** Sub-categorias da fonte agrupadas neste bucket */\n subcategories: readonly string[];\n}\n\nexport const CATEGORY_GROUPS: Record<CategoryGroup, CategoryGroupInfo> = {\n cardiovascular: {\n en: 'Cardiovascular',\n pt: 'Cardiovascular',\n slug: 'cardiovascular',\n subcategories: ['coracao'],\n },\n 'composicao-envelhecimento': {\n en: 'Body Composition & Aging',\n pt: 'Composição Corporal e Envelhecimento',\n slug: 'composicao-envelhecimento',\n subcategories: ['composicao-corporal', 'densidade-ossea', 'estresse-envelhecimento'],\n },\n hematologico: {\n en: 'Hematology',\n pt: 'Hematológico',\n slug: 'hematologico',\n subcategories: ['sangue'],\n },\n 'hepatico-biliar': {\n en: 'Hepatic & Biliary',\n pt: 'Hepático e Biliar',\n slug: 'hepatico-biliar',\n subcategories: ['figado'],\n },\n imunologico: {\n en: 'Immunology',\n pt: 'Imunológico',\n slug: 'imunologico',\n subcategories: ['autoimunidade', 'regulacao-imunologica'],\n },\n 'metabolico-endocrino': {\n en: 'Metabolic & Endocrine',\n pt: 'Metabólico e Endócrino',\n slug: 'metabolico-endocrino',\n subcategories: ['metabolico', 'pancreas', 'hormonios', 'tireoide'],\n },\n 'nutricional-ambiental': {\n en: 'Nutrition & Environmental Exposure',\n pt: 'Nutricional e Exposição Ambiental',\n slug: 'nutricional-ambiental',\n subcategories: ['nutrientes', 'toxinas-ambientais'],\n },\n oncologico: {\n en: 'Oncology',\n pt: 'Oncológico',\n slug: 'oncologico',\n subcategories: ['marcadores-tumorais'],\n },\n 'renal-eletrolitico': {\n en: 'Renal & Electrolytes',\n pt: 'Renal e Eletrolítico',\n slug: 'renal-eletrolitico',\n subcategories: ['rins', 'urina', 'eletrolitos'],\n },\n 'saude-reprodutiva': {\n en: 'Reproductive Health',\n pt: 'Saúde Reprodutiva',\n slug: 'saude-reprodutiva',\n subcategories: ['saude-feminina', 'saude-masculina'],\n },\n};\n\nconst SUBCATEGORY_TO_GROUP = new Map<string, CategoryGroup>();\nfor (const group of Object.values(CATEGORY_GROUPS)) {\n for (const sub of group.subcategories) {\n SUBCATEGORY_TO_GROUP.set(sub, group.slug);\n }\n}\n\n/**\n * Resolve a sub-categoria (granular) para o grupo de alto nível (10 buckets).\n */\nexport function getCategoryGroup(subcategory: string): CategoryGroup | undefined {\n return SUBCATEGORY_TO_GROUP.get(subcategory);\n}\n\n/**\n * Lista todas as sub-categorias mapeadas em algum grupo.\n */\nexport function listMappedSubcategories(): readonly string[] {\n return [...SUBCATEGORY_TO_GROUP.keys()];\n}\n","/**\n * FHIR Intervention Converter\n *\n * Converts interventions (medication, supplement, diet, exercise, sleep)\n * to FHIR R4 MedicationStatement and Observation resources.\n */\n\nimport { type Addressable, entryFullUrl } from './bundle-urls';\nimport { userProfileToFHIR } from './converter';\nimport type { FHIRBundle, FHIRMedicationStatement, FHIRObservation } from './fhir-types';\nimport type { InterventionData, UserProfileData } from './types';\n\n/**\n * Determine MedicationStatement/Observation status based on end date\n */\nfunction interventionStatus(endDate?: string): 'active' | 'completed' {\n if (!endDate) return 'active';\n return new Date(endDate) < new Date() ? 'completed' : 'active';\n}\n\n/**\n * LOINC-like codes for lifestyle observation types\n */\nconst LIFESTYLE_CODES: Record<string, { code: string; display: string }> = {\n diet: { code: '81259-4', display: 'Diet' },\n exercise: { code: '73985-4', display: 'Exercise activity' },\n sleep: { code: '93832-4', display: 'Sleep duration' },\n};\n\n/**\n * Convert medication/supplement intervention to FHIR MedicationStatement\n */\nexport function interventionToFHIRMedicationStatement(\n intervention: InterventionData,\n patientId: string,\n): Addressable<FHIRMedicationStatement> {\n const statement: Addressable<FHIRMedicationStatement> = {\n category: {\n coding: [\n {\n code: 'patientspecified',\n display: 'Patient Specified',\n system: 'http://terminology.hl7.org/CodeSystem/medication-statement-category',\n },\n ],\n },\n dateAsserted: intervention.startDate,\n effectivePeriod: {\n end: intervention.endDate,\n start: intervention.startDate,\n },\n id: `intervention-${intervention.interventionId}`,\n medicationCodeableConcept: {\n text: intervention.name,\n },\n resourceType: 'MedicationStatement',\n status: interventionStatus(intervention.endDate),\n subject: {\n reference: `Patient/${patientId}`,\n },\n };\n\n if (intervention.notes) {\n statement.note = [{ text: intervention.notes }];\n }\n\n return statement;\n}\n\n/**\n * Convert diet/exercise/sleep intervention to FHIR Observation (social-history)\n */\nexport function interventionToFHIRObservation(\n intervention: InterventionData,\n patientId: string,\n): Addressable<FHIRObservation> {\n const lifestyleCode = LIFESTYLE_CODES[intervention.type];\n\n const observation: Addressable<FHIRObservation> = {\n category: [\n {\n coding: [\n {\n code: 'social-history',\n display: 'Social History',\n system: 'http://terminology.hl7.org/CodeSystem/observation-category',\n },\n ],\n },\n ],\n code: {\n coding: lifestyleCode\n ? [\n {\n code: lifestyleCode.code,\n display: lifestyleCode.display,\n system: 'http://loinc.org',\n },\n ]\n : [],\n text: intervention.name,\n },\n effectivePeriod: {\n end: intervention.endDate,\n start: intervention.startDate,\n },\n id: `intervention-${intervention.interventionId}`,\n resourceType: 'Observation',\n status: 'final',\n subject: {\n reference: `Patient/${patientId}`,\n },\n valueString: intervention.name,\n };\n\n if (intervention.notes) {\n observation.note = [{ text: intervention.notes }];\n }\n\n return observation;\n}\n\n/**\n * Convert all interventions to a FHIR Bundle\n */\nexport function interventionsToFHIRBundle(\n interventions: InterventionData[],\n userProfile: UserProfileData,\n): FHIRBundle {\n const patientId = userProfile.userId;\n const fhirPatient = userProfileToFHIR(userProfile);\n\n const entries = interventions.map((intervention) => {\n const isMedication = intervention.type === 'medication' || intervention.type === 'supplement';\n const resource = isMedication\n ? interventionToFHIRMedicationStatement(intervention, patientId)\n : interventionToFHIRObservation(intervention, patientId);\n\n return { fullUrl: entryFullUrl(resource), resource };\n });\n\n return {\n entry: [{ fullUrl: entryFullUrl(fhirPatient), resource: fhirPatient }, ...entries],\n resourceType: 'Bundle',\n type: 'collection',\n };\n}\n","/**\n * Structured zone data for DEXA body composition and bone density charts.\n *\n * Body fat zones derived from Gallagher et al. Am J Clin Nutr 2000;72:694-701 (PMID: 10966886)\n * and ACSM Guidelines for Exercise Testing, 11th Ed (2021).\n *\n * T-Score zones from WHO criteria (Kanis JA, Osteoporos Int, PMID: 7696835).\n */\n\nexport interface BodyFatZone {\n ageMax: number;\n ageMin: number;\n color: string;\n fatPctMax: number;\n fatPctMin: number;\n label: string;\n sex: 'F' | 'M';\n}\n\ninterface AgeBracket {\n ageMax: number;\n ageMin: number;\n label: string;\n}\n\nconst AGE_BRACKETS: AgeBracket[] = [\n { ageMax: 25, ageMin: 18, label: '18-25' },\n { ageMax: 35, ageMin: 26, label: '26-35' },\n { ageMax: 45, ageMin: 36, label: '36-45' },\n { ageMax: 55, ageMin: 46, label: '46-55' },\n { ageMax: 99, ageMin: 56, label: '56+' },\n];\n\n// Zone boundaries per age bracket for men: [essential, athletic, fitness, average, obese]\n// Each value is the upper bound of the zone\nconst MALE_ZONES: number[][] = [\n [5, 10, 20, 25, 40],\n [5, 11, 21, 26, 40],\n [5, 12, 22, 27, 40],\n [5, 13, 23, 28, 40],\n [5, 14, 24, 29, 40],\n];\n\nconst FEMALE_ZONES: number[][] = [\n [13, 18, 28, 32, 45],\n [13, 18, 29, 33, 45],\n [13, 19, 30, 34, 45],\n [13, 20, 31, 35, 45],\n [13, 20, 32, 36, 45],\n];\n\ninterface ZoneDefinition {\n color: string;\n label: string;\n}\n\nconst ZONE_DEFS: ZoneDefinition[] = [\n { color: '#3b82f6', label: 'Essencial' },\n { color: '#06b6d4', label: 'Atlético' },\n { color: '#22c55e', label: 'Fitness' },\n { color: '#eab308', label: 'Média' },\n { color: '#ef4444', label: 'Obeso' },\n];\n\nfunction buildZones(sex: 'F' | 'M', zoneData: number[][]): BodyFatZone[] {\n const zones: BodyFatZone[] = [];\n for (let i = 0; i < AGE_BRACKETS.length; i++) {\n const bracket = AGE_BRACKETS[i]!;\n const b = zoneData[i]!;\n zones.push({\n ...bracket,\n color: ZONE_DEFS[0]!.color,\n fatPctMax: b[0]!,\n fatPctMin: 0,\n label: ZONE_DEFS[0]!.label,\n sex,\n });\n zones.push({\n ...bracket,\n color: ZONE_DEFS[1]!.color,\n fatPctMax: b[1]!,\n fatPctMin: b[0]!,\n label: ZONE_DEFS[1]!.label,\n sex,\n });\n zones.push({\n ...bracket,\n color: ZONE_DEFS[2]!.color,\n fatPctMax: b[2]!,\n fatPctMin: b[1]!,\n label: ZONE_DEFS[2]!.label,\n sex,\n });\n zones.push({\n ...bracket,\n color: ZONE_DEFS[3]!.color,\n fatPctMax: b[3]!,\n fatPctMin: b[2]!,\n label: ZONE_DEFS[3]!.label,\n sex,\n });\n zones.push({\n ...bracket,\n color: ZONE_DEFS[4]!.color,\n fatPctMax: b[4]!,\n fatPctMin: b[3]!,\n label: ZONE_DEFS[4]!.label,\n sex,\n });\n }\n return zones;\n}\n\nexport const BODY_FAT_ZONES: BodyFatZone[] = [\n ...buildZones('M', MALE_ZONES),\n ...buildZones('F', FEMALE_ZONES),\n];\n\nexport { AGE_BRACKETS, ZONE_DEFS };\n\nexport interface TScoreZone {\n color: string;\n label: string;\n max: number;\n min: number;\n}\n\nexport const T_SCORE_ZONES: TScoreZone[] = [\n { color: '#22c55e', label: 'Normal', max: 4, min: -1.0 },\n { color: '#eab308', label: 'Osteopenia', max: -1.0, min: -2.5 },\n { color: '#ef4444', label: 'Osteoporose', max: -2.5, min: -5 },\n];\n","/**\n * Screening Intervals Configuration\n *\n * Defines recommended screening intervals for different biomarker categories\n * based on clinical guidelines and best practices.\n */\n\n/**\n * Screening interval in months\n */\nexport type ScreeningIntervalMonths = 3 | 6 | 12;\n\n/**\n * Biomarker category with its recommended screening interval\n */\nexport interface CategoryScreeningInterval {\n category: string;\n intervalMonths: ScreeningIntervalMonths;\n nameEn: string;\n namePt: string;\n}\n\n/**\n * Screening interval configuration for each category\n *\n * Categories are grouped by their recommended screening intervals:\n * - 3 months: Body composition and bone density (frequently changing metrics)\n * - 6 months: Metabolic panel and nutrients (moderate change rate)\n * - 12 months: Standard blood panels (stable long-term markers)\n */\nexport const CATEGORY_SCREENING_INTERVALS: CategoryScreeningInterval[] = [\n // 3-month intervals - Body composition (frequently changing)\n {\n category: 'composicao-corporal',\n intervalMonths: 3,\n nameEn: 'Body Composition',\n namePt: 'Composição Corporal',\n },\n {\n category: 'densidade-ossea',\n intervalMonths: 3,\n nameEn: 'Bone Density',\n namePt: 'Densidade Óssea',\n },\n\n // 6-month intervals - Metabolic and nutrients\n {\n category: 'metabolico',\n intervalMonths: 6,\n nameEn: 'Metabolic Panel',\n namePt: 'Painel Metabólico',\n },\n {\n category: 'nutrientes',\n intervalMonths: 6,\n nameEn: 'Nutrients',\n namePt: 'Nutrientes',\n },\n {\n category: 'pancreas',\n intervalMonths: 6,\n nameEn: 'Pancreas',\n namePt: 'Pâncreas',\n },\n\n // 12-month intervals - Standard blood panels\n {\n category: 'coracao',\n intervalMonths: 12,\n nameEn: 'Heart Health',\n namePt: 'Saúde Cardiovascular',\n },\n {\n category: 'tireoide',\n intervalMonths: 12,\n nameEn: 'Thyroid',\n namePt: 'Tireoide',\n },\n {\n category: 'sangue',\n intervalMonths: 12,\n nameEn: 'Blood Count',\n namePt: 'Hemograma',\n },\n {\n category: 'figado',\n intervalMonths: 12,\n nameEn: 'Liver Function',\n namePt: 'Função Hepática',\n },\n {\n category: 'rins',\n intervalMonths: 12,\n nameEn: 'Kidney Function',\n namePt: 'Função Renal',\n },\n {\n category: 'saude-feminina',\n intervalMonths: 12,\n nameEn: \"Women's Health\",\n namePt: 'Saúde Feminina',\n },\n {\n category: 'saude-masculina',\n intervalMonths: 12,\n nameEn: \"Men's Health\",\n namePt: 'Saúde Masculina',\n },\n {\n category: 'eletrolitos',\n intervalMonths: 12,\n nameEn: 'Electrolytes',\n namePt: 'Eletrólitos',\n },\n {\n category: 'estresse-envelhecimento',\n intervalMonths: 12,\n nameEn: 'Stress & Aging',\n namePt: 'Estresse e Envelhecimento',\n },\n {\n category: 'autoimunidade',\n intervalMonths: 12,\n nameEn: 'Autoimmunity',\n namePt: 'Autoimunidade',\n },\n {\n category: 'regulacao-imunologica',\n intervalMonths: 12,\n nameEn: 'Immune Regulation',\n namePt: 'Regulação Imunológica',\n },\n {\n category: 'toxinas-ambientais',\n intervalMonths: 12,\n nameEn: 'Environmental Toxins',\n namePt: 'Toxinas Ambientais',\n },\n {\n category: 'urina',\n intervalMonths: 12,\n nameEn: 'Urinalysis',\n namePt: 'Urina',\n },\n];\n\n/**\n * Get screening interval for a category\n */\nexport const getScreeningInterval = (category: string): CategoryScreeningInterval | undefined => {\n return CATEGORY_SCREENING_INTERVALS.find((c) => c.category === category);\n};\n\n/**\n * Get all categories with a specific interval\n */\nexport const getCategoriesByInterval = (\n intervalMonths: ScreeningIntervalMonths,\n): CategoryScreeningInterval[] => {\n return CATEGORY_SCREENING_INTERVALS.filter((c) => c.intervalMonths === intervalMonths);\n};\n\n/**\n * Calculate next screening date based on last test date and category\n */\nexport const calculateNextScreeningDate = (lastTestDate: Date, category: string): Date | null => {\n const interval = getScreeningInterval(category);\n if (!interval) return null;\n\n const nextDate = new Date(lastTestDate);\n nextDate.setMonth(nextDate.getMonth() + interval.intervalMonths);\n return nextDate;\n};\n\n/**\n * Check if a category is due for screening\n */\nexport const isScreeningDue = (\n lastTestDate: Date,\n category: string,\n referenceDate: Date = new Date(),\n): boolean => {\n const nextDate = calculateNextScreeningDate(lastTestDate, category);\n if (!nextDate) return false;\n return referenceDate >= nextDate;\n};\n\n/**\n * Get categories that are due for screening based on last test dates\n */\nexport const getDueCategories = (\n lastTestDates: Record<string, Date>,\n referenceDate: Date = new Date(),\n): CategoryScreeningInterval[] => {\n return CATEGORY_SCREENING_INTERVALS.filter((interval) => {\n const lastDate = lastTestDates[interval.category];\n if (!lastDate) return true; // Never tested = due\n return isScreeningDue(lastDate, interval.category, referenceDate);\n });\n};\n\n/**\n * Get days until next screening for a category\n */\nexport const getDaysUntilScreening = (\n lastTestDate: Date,\n category: string,\n referenceDate: Date = new Date(),\n): number | null => {\n const nextDate = calculateNextScreeningDate(lastTestDate, category);\n if (!nextDate) return null;\n\n const diffTime = nextDate.getTime() - referenceDate.getTime();\n return Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n};\n","/**\n * Portuguese pluralization utility using native Intl.PluralRules\n * Provides automatic pluralization for common words used in the app\n */\n\nconst pluralRules = new Intl.PluralRules('pt-BR');\n\n/**\n * Dictionary of Portuguese words with their plural forms\n * Key is the singular form, value is the plural form\n */\nconst dictionary: Record<string, string> = {\n // Common nouns\n arquivo: 'arquivos',\n biomarcador: 'biomarcadores',\n // Past participles (masculine)\n cadastrado: 'cadastrados',\n // Past participles (feminine)\n concluída: 'concluídas',\n confirmado: 'confirmados',\n convertido: 'convertidos',\n convidado: 'convidados',\n convite: 'convites',\n disponível: 'disponíveis',\n documento: 'documentos',\n enviado: 'enviados',\n exame: 'exames',\n excluída: 'excluídas',\n\n excluído: 'excluídos',\n // Verbs (3rd person)\n falhou: 'falharam',\n falta: 'faltam',\n ignorado: 'ignorados',\n item: 'itens',\n outro: 'outros',\n página: 'páginas',\n pendente: 'pendentes',\n registro: 'registros',\n removido: 'removidos',\n\n resultado: 'resultados',\n revisão: 'revisões',\n\n revogado: 'revogados',\n usuário: 'usuários',\n};\n\n/**\n * Get the plural form of a word from the dictionary\n * Falls back to adding 's' if word is not in dictionary\n */\nconst getPluralForm = (singular: string): string => {\n return dictionary[singular] ?? `${singular}s`;\n};\n\n/**\n * Returns the correct singular or plural form based on count\n * Uses Intl.PluralRules for proper locale-aware pluralization\n *\n * @example\n * plural(1, 'usuário') // 'usuário'\n * plural(3, 'usuário') // 'usuários'\n * plural(0, 'registro') // 'registros'\n */\nexport const plural = (count: number, word: string): string => {\n const rule = pluralRules.select(count);\n return rule === 'one' ? word : getPluralForm(word);\n};\n\n/**\n * Returns count with the correct singular or plural form\n *\n * @example\n * pluralCount(1, 'usuário') // '1 usuário'\n * pluralCount(3, 'usuário') // '3 usuários'\n */\nexport const pluralCount = (count: number, word: string): string => {\n return `${count} ${plural(count, word)}`;\n};\n\n/**\n * Returns the correct form for compound phrases (noun + adjective)\n * Both words are pluralized together\n *\n * @example\n * pluralPhrase(1, 'usuário', 'cadastrado') // 'usuário cadastrado'\n * pluralPhrase(3, 'usuário', 'cadastrado') // 'usuários cadastrados'\n * pluralPhrase(2, 'revisão', 'excluída') // 'revisões excluídas'\n */\nexport const pluralPhrase = (count: number, noun: string, adjective: string): string => {\n const rule = pluralRules.select(count);\n if (rule === 'one') {\n return `${noun} ${adjective}`;\n }\n return `${getPluralForm(noun)} ${getPluralForm(adjective)}`;\n};\n\n/**\n * Returns count with the correct compound phrase form\n *\n * @example\n * pluralPhraseCount(1, 'usuário', 'cadastrado') // '1 usuário cadastrado'\n * pluralPhraseCount(3, 'convite', 'enviado') // '3 convites enviados'\n */\nexport const pluralPhraseCount = (count: number, noun: string, adjective: string): string => {\n return `${count} ${pluralPhrase(count, noun, adjective)}`;\n};\n","/**\n * Helpers para identificadores brasileiros — CPF e CNS\n *\n * Validação, formatação e conversão para FHIR Identifier.\n * Algoritmos de validação baseados nas especificações oficiais:\n * - CPF: Receita Federal (mod-11, dois dígitos verificadores)\n * - CNS: Ministério da Saúde (mod-11 para definitivos, soma ponderada para provisórios)\n */\n\nimport type { FHIRIdentifier } from './fhir-types';\n\nconst CPF_SYSTEM = 'http://rnds.saude.gov.br/fhir/r4/NamingSystem/cpf';\nconst CNS_SYSTEM = 'http://rnds.saude.gov.br/fhir/r4/NamingSystem/cns';\n\n/**\n * Remove caracteres não-numéricos de uma string.\n */\nfunction digitsOnly(value: string): string {\n return value.replace(/\\D/g, '');\n}\n\n/**\n * Valida um CPF brasileiro usando algoritmo mod-11.\n *\n * @param cpf — CPF com ou sem formatação (ex: \"123.456.789-09\" ou \"12345678909\")\n * @returns true se o CPF é estruturalmente válido\n */\nexport function validateCPF(cpf: string): boolean {\n const digits = digitsOnly(cpf);\n\n if (digits.length !== 11) return false;\n\n // Rejeitar sequências de dígitos iguais (ex: 111.111.111-11)\n if (/^(\\d)\\1{10}$/.test(digits)) return false;\n\n // Primeiro dígito verificador\n let sum = 0;\n for (let i = 0; i < 9; i++) {\n sum += Number(digits[i]) * (10 - i);\n }\n let remainder = (sum * 10) % 11;\n if (remainder === 10) remainder = 0;\n if (remainder !== Number(digits[9])) return false;\n\n // Segundo dígito verificador\n sum = 0;\n for (let i = 0; i < 10; i++) {\n sum += Number(digits[i]) * (11 - i);\n }\n remainder = (sum * 10) % 11;\n if (remainder === 10) remainder = 0;\n if (remainder !== Number(digits[10])) return false;\n\n return true;\n}\n\n/**\n * Valida um CNS (Cartão Nacional de Saúde) brasileiro.\n *\n * CNS definitivos começam com 1 ou 2 (mod-11).\n * CNS provisórios começam com 7, 8 ou 9 (soma ponderada mod-11 = 0).\n *\n * @param cns — CNS com 15 dígitos\n * @returns true se o CNS é estruturalmente válido\n */\nexport function validateCNS(cns: string): boolean {\n const digits = digitsOnly(cns);\n\n if (digits.length !== 15) return false;\n\n const firstDigit = digits[0]!;\n\n // CNS deve começar com 1, 2 (definitivo) ou 7, 8, 9 (provisório)\n if (!['1', '2', '7', '8', '9'].includes(firstDigit)) return false;\n\n // Ambos os tipos usam soma ponderada mod-11 = 0\n let sum = 0;\n for (let i = 0; i < 15; i++) {\n sum += Number(digits[i]) * (15 - i);\n }\n return sum % 11 === 0;\n}\n\n/**\n * Formata um CPF como XXX.XXX.XXX-XX.\n *\n * @param cpf — CPF com 11 dígitos (com ou sem formatação)\n * @returns CPF formatado ou a string original se inválido\n */\nexport function formatCPF(cpf: string): string {\n const digits = digitsOnly(cpf);\n if (digits.length !== 11) return cpf;\n return `${digits.slice(0, 3)}.${digits.slice(3, 6)}.${digits.slice(6, 9)}-${digits.slice(9)}`;\n}\n\n/**\n * Formata um CNS como XXX XXXX XXXX XXXX.\n *\n * @param cns — CNS com 15 dígitos\n * @returns CNS formatado ou a string original se inválido\n */\nexport function formatCNS(cns: string): string {\n const digits = digitsOnly(cns);\n if (digits.length !== 15) return cns;\n return `${digits.slice(0, 3)} ${digits.slice(3, 7)} ${digits.slice(7, 11)} ${digits.slice(11)}`;\n}\n\n/**\n * Converte um CPF para um FHIR Identifier.\n *\n * @param cpf — CPF com 11 dígitos (com ou sem formatação)\n * @returns FHIR Identifier com sistema RNDS para CPF\n * @throws Error se o CPF for inválido\n */\nexport function cpfToFHIRIdentifier(cpf: string): FHIRIdentifier {\n if (!validateCPF(cpf)) {\n throw new Error('CPF inválido');\n }\n return {\n system: CPF_SYSTEM,\n use: 'official',\n value: digitsOnly(cpf),\n };\n}\n\n/**\n * Converte um CNS para um FHIR Identifier.\n *\n * @param cns — CNS com 15 dígitos\n * @returns FHIR Identifier com sistema RNDS para CNS\n * @throws Error se o CNS for inválido\n */\nexport function cnsToFHIRIdentifier(cns: string): FHIRIdentifier {\n if (!validateCNS(cns)) {\n throw new Error('CNS inválido');\n }\n return {\n system: CNS_SYSTEM,\n use: 'official',\n value: digitsOnly(cns),\n };\n}\n","/**\n * URLs das extensões do IG do fhir-brasil.\n *\n * Quem emite a extensão e quem a lê precisam concordar literalmente na URL: um\n * consumidor procura a extensão pelo `url`, e uma grafia divergente faz o dado\n * sumir sem erro. O teste confere cada uma contra o `Id:` do FSH em\n * `ig/input/fsh/extensions/`, então extensão nova no IG sem constante aqui, ou\n * o inverso, reprova.\n */\n\n/** Canonical do IG, como está no `sushi-config.yaml`. */\nexport const IG_CANONICAL = 'https://fhir-brasil.dev.br/ig';\n\nconst structureDefinition = (id: string): string => `${IG_CANONICAL}/StructureDefinition/${id}`;\n\n/**\n * Extensões do IG, pela URL.\n *\n * As que têm partes (`extractionSource`, `extractionConfidence`, `asPrinted`)\n * levam as partes em `extension[]` aninhado, cada uma com `url` relativo: o\n * nome da parte, como `page` ou `reading`. Ver o FSH de cada uma.\n */\nexport const FHIR_BRASIL_EXTENSIONS = {\n /** `Observation`: valor e faixa como impressos, quando a Observation traz outros. */\n asPrinted: structureDefinition('as-printed'),\n /** `Observation`: extraída de PDF via OCR. */\n derivedFromOCR: structureDefinition('derived-from-ocr'),\n /** `Observation`: confiança na leitura e na interpretação, de 0 a 1. */\n extractionConfidence: structureDefinition('extraction-confidence'),\n /** `Observation`: páginas, trecho citado e caixa do trecho no documento. */\n extractionSource: structureDefinition('extraction-source'),\n /** `DiagnosticReport`: lido da tabela de histórico de outro laudo. */\n reprintedIn: structureDefinition('reprinted-in'),\n /** `Observation`: lido do documento, mas substituído por outro valor do mesmo laudo. */\n superseded: structureDefinition('superseded'),\n /** `Observation`: unidade impressa ao lado de um resultado em texto. */\n textValueUnit: structureDefinition('text-value-unit'),\n} as const;\n","/**\n * Código do tipo de amostra a partir do material impresso no laudo.\n *\n * O perfil `BRAmostraBiologica-1.0` da RNDS vincula `Specimen.type` ao ValueSet\n * `BRTipoAmostra-1.0` com força `required`, exige `type.coding` (1..1) e proíbe\n * `type.text` (0..0). Um `Specimen` só com o texto do laudo não passa, e é o que\n * a extração produzia.\n *\n * O ValueSet tem 63 códigos, e quase todos são de vigilância respiratória vindos\n * do GAL: swab nasofaríngeo, lavado brônquico, fragmento de órgão. Para laudo de\n * rotina sobram seis, e esses seis cobrem o que um painel de sangue e urina\n * imprime.\n *\n * Não há código para fezes no ValueSet. Isso não afeta a extração, cujo catálogo\n * não tem nenhum biomarcador de origem fecal: um parasitológico não vira\n * `Observation`, então não chega a pedir `Specimen`.\n *\n * @see https://rnds-fhir.saude.gov.br/StructureDefinition-BRAmostraBiologica-1.0.html\n * @see https://rnds-fhir.saude.gov.br/ValueSet-BRTipoAmostra-1.0.html\n */\nimport type { FHIRCoding } from './fhir-types';\n\n/** ValueSet ao qual `Specimen.type` está vinculado no `BRAmostraBiologica`. */\nexport const BR_TIPO_AMOSTRA_VALUESET = 'https://rnds-fhir.saude.gov.br/ValueSet/BRTipoAmostra-1.0';\n\n/**\n * CodeSystem dos códigos que este módulo emite.\n *\n * O ValueSet também inclui o `BRTipoAmostraGAL`, que traz \"Sangue\" e \"Sangue com\n * EDTA\" soltos. Ficaram de fora porque a URL canônica daquele CodeSystem não foi\n * confirmada na fonte, e código de terminologia não se deduz de slug. Material\n * assim cai no caminho de não mapeado até alguém abrir o IG e confirmar.\n */\nexport const HL7_SPECIMEN_TYPE_SYSTEM = 'http://terminology.hl7.org/CodeSystem/v2-0487';\n\n/**\n * Os `display` são cópia literal do ValueSet, com a caixa dele.\n *\n * A chave é o texto já normalizado, e por enquanto é só o próprio display. Não\n * há sinônimo inventado aqui: a extração copia o material verbatim do laudo, e a\n * lista de variações que os laboratórios de fato imprimem ainda não foi medida\n * (a captura de material entrou em produção em 05/09/2026). Variação real\n * observada entra depois, com o laudo que a produziu.\n */\nconst CODINGS: ReadonlyArray<{ code: string; display: string }> = [\n { code: 'SER', display: 'Soro' },\n { code: 'PLAS', display: 'Plasma' },\n { code: 'WB', display: 'Sangue Total' },\n { code: 'UR', display: 'Urina' },\n { code: 'CSF', display: 'Líquor' },\n { code: 'SAL', display: 'Saliva' },\n];\n\n/**\n * Caixa, acento e espaço sobrando não distinguem material.\n *\n * Só isso. Não separa `camelCase` nem troca barra por espaço, ao contrário do\n * normalizador de nomes de biomarcador: \"Soro/Plasma\" impresso numa linha só é\n * ambíguo de verdade, e escolher um dos dois seria inferência. Sem casar, ele\n * segue o caminho do não mapeado.\n *\n * Os caracteres invisíveis saem antes, e a divisão entre as duas regras é a do\n * próprio Unicode: `\\p{Cf}` são os de formatação, que não ocupam espaço e por\n * isso são apagados, e `\\s` são os de espaço, que são colapsados. A camada de\n * texto de PDF emite os dois tipos, e um U+200B no meio de \"Soro\" derruba o\n * casamento sem deixar rastro na tela.\n *\n * Vale a categoria em vez da lista porque a lista nunca fecha. Enumerando, o\n * hífen opcional (U+00AD) tinha ficado de fora, e ele aparece justamente onde\n * um nome composto como \"Sangue Total\" quebra de linha.\n */\nconst INVISIBLE = /\\p{Cf}/gu;\n\nconst normalize = (text: string): string =>\n text\n .replace(INVISIBLE, '')\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .trim();\n\nconst BY_NORMALIZED_TEXT = new Map(\n CODINGS.map(({ code, display }) => [\n normalize(display),\n { code, display, system: HL7_SPECIMEN_TYPE_SYSTEM } satisfies FHIRCoding,\n ]),\n);\n\n/**\n * Coding do ValueSet para o material impresso, ou `undefined` sem casar.\n *\n * `undefined` é resposta legítima e não erro: o laudo pode trazer um material\n * fora do ValueSet, ou uma grafia que ninguém viu ainda. Quem chama decide o que\n * fazer, e a decisão que não existe é preencher com um código aproximado.\n */\nexport const specimenTypeCoding = (text: string): FHIRCoding | undefined =>\n BY_NORMALIZED_TEXT.get(normalize(text));\n"]}
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- import { I as InterventionData, A as Addressable, U as UserProfileData } from './converter-DP8VkkO3.cjs';
2
- export { B as BUNDLE_BASE_URL, F as Flag, G as Gender, L as LabObservationData, a as LabReportData, O as OverallStatus, e as entryFullUrl, l as labObservationToFHIR, b as labReportToFHIR, c as labResultToFHIRBundle, u as userProfileToFHIR } from './converter-DP8VkkO3.cjs';
3
- export { BIOMARKER_DEFINITIONS, BiomarkerDefinition, BiomarkerSearchPattern, CAC_INDICATOR_CODES, DEXA_CATEGORIES, DEXA_INDICATOR_CODES, SupportedBiomarker, codeToLoinc, filterVisibleBiomarkers, findCodeByName, generateCacFullReference, generateDexaFullReference, generateFilteredLLMReference, generateLLMReference, getAllCodes, getAllDefinitions, getAllLoincCodes, getAllSearchPatterns, getBiomarkersByCategory, getBiomarkersForCategories, getDefinitionByCode, getDefinitionByLoinc, getDefinitionsBySex, getSexForCode, getVisibleDefinitions, isBiomarkerVisible, isCacDocument, isDexaDocument, isValidCode, isValidLoinc, loincToCode, normalizeCode, toBiomarkerTests, validateLoincNameMatch } from './biomarkers.cjs';
1
+ import { I as InterventionData, A as Addressable, U as UserProfileData } from './converter-Dlwb6OfB.cjs';
2
+ export { B as BUNDLE_BASE_URL, F as Flag, G as Gender, L as LabObservationData, a as LabReportData, O as OverallStatus, e as entryFullUrl, l as labObservationToFHIR, b as labReportToFHIR, c as labResultToFHIRBundle, u as userProfileToFHIR } from './converter-Dlwb6OfB.cjs';
3
+ export { BIOMARKER_DEFINITIONS, BiomarkerDefinition, BiomarkerSearchPattern, CAC_INDICATOR_CODES, DEXA_CATEGORIES, DEXA_INDICATOR_CODES, MethodVariant, SupportedBiomarker, codeToLoinc, filterVisibleBiomarkers, findCodeByName, generateCacFullReference, generateDexaFullReference, generateFilteredLLMReference, generateLLMReference, getAllCodes, getAllDefinitions, getAllLoincCodes, getAllSearchPatterns, getBiomarkersByCategory, getBiomarkersForCategories, getDefinitionByCode, getDefinitionByLoinc, getDefinitionsBySex, getSexForCode, getVisibleDefinitions, isBiomarkerVisible, isCacDocument, isDexaDocument, isValidCode, isValidLoinc, loincToCode, methodVariantOf, normalizeCode, toBiomarkerTests, validateLoincNameMatch } from './biomarkers.cjs';
4
4
  export { BIOMARKER_DEFAULT_UNIT, BIOMARKER_UNITS, BiomarkerUnitConfig, ConversionResult, UNIT_TO_UCUM, convertUnit, getCanonicalUnit, getDefaultUnit, getSIUnit, isUcumCode, resolveUcum, unitToUCUM } from './units.cjs';
5
5
  import { F as FHIRMedicationStatement, a as FHIRObservation, b as FHIRBundle, c as FHIRIdentifier, d as FHIRCoding } from './fhir-types-Cn5WFbOI.cjs';
6
6
  export { e as FHIRAddress, f as FHIRAnnotation, g as FHIRAttachment, h as FHIRBundleEntry, i as FHIRCodeableConcept, j as FHIRContactPoint, k as FHIRDiagnosticReport, l as FHIRHumanName, m as FHIRPatient, n as FHIRPeriod, o as FHIRQuantity, p as FHIRReference, q as FHIRReferenceRange } from './fhir-types-Cn5WFbOI.cjs';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { I as InterventionData, A as Addressable, U as UserProfileData } from './converter-UygMzWlL.js';
2
- export { B as BUNDLE_BASE_URL, F as Flag, G as Gender, L as LabObservationData, a as LabReportData, O as OverallStatus, e as entryFullUrl, l as labObservationToFHIR, b as labReportToFHIR, c as labResultToFHIRBundle, u as userProfileToFHIR } from './converter-UygMzWlL.js';
3
- export { BIOMARKER_DEFINITIONS, BiomarkerDefinition, BiomarkerSearchPattern, CAC_INDICATOR_CODES, DEXA_CATEGORIES, DEXA_INDICATOR_CODES, SupportedBiomarker, codeToLoinc, filterVisibleBiomarkers, findCodeByName, generateCacFullReference, generateDexaFullReference, generateFilteredLLMReference, generateLLMReference, getAllCodes, getAllDefinitions, getAllLoincCodes, getAllSearchPatterns, getBiomarkersByCategory, getBiomarkersForCategories, getDefinitionByCode, getDefinitionByLoinc, getDefinitionsBySex, getSexForCode, getVisibleDefinitions, isBiomarkerVisible, isCacDocument, isDexaDocument, isValidCode, isValidLoinc, loincToCode, normalizeCode, toBiomarkerTests, validateLoincNameMatch } from './biomarkers.js';
1
+ import { I as InterventionData, A as Addressable, U as UserProfileData } from './converter-CTj83kPz.js';
2
+ export { B as BUNDLE_BASE_URL, F as Flag, G as Gender, L as LabObservationData, a as LabReportData, O as OverallStatus, e as entryFullUrl, l as labObservationToFHIR, b as labReportToFHIR, c as labResultToFHIRBundle, u as userProfileToFHIR } from './converter-CTj83kPz.js';
3
+ export { BIOMARKER_DEFINITIONS, BiomarkerDefinition, BiomarkerSearchPattern, CAC_INDICATOR_CODES, DEXA_CATEGORIES, DEXA_INDICATOR_CODES, MethodVariant, SupportedBiomarker, codeToLoinc, filterVisibleBiomarkers, findCodeByName, generateCacFullReference, generateDexaFullReference, generateFilteredLLMReference, generateLLMReference, getAllCodes, getAllDefinitions, getAllLoincCodes, getAllSearchPatterns, getBiomarkersByCategory, getBiomarkersForCategories, getDefinitionByCode, getDefinitionByLoinc, getDefinitionsBySex, getSexForCode, getVisibleDefinitions, isBiomarkerVisible, isCacDocument, isDexaDocument, isValidCode, isValidLoinc, loincToCode, methodVariantOf, normalizeCode, toBiomarkerTests, validateLoincNameMatch } from './biomarkers.js';
4
4
  export { BIOMARKER_DEFAULT_UNIT, BIOMARKER_UNITS, BiomarkerUnitConfig, ConversionResult, UNIT_TO_UCUM, convertUnit, getCanonicalUnit, getDefaultUnit, getSIUnit, isUcumCode, resolveUcum, unitToUCUM } from './units.js';
5
5
  import { F as FHIRMedicationStatement, a as FHIRObservation, b as FHIRBundle, c as FHIRIdentifier, d as FHIRCoding } from './fhir-types-Cn5WFbOI.js';
6
6
  export { e as FHIRAddress, f as FHIRAnnotation, g as FHIRAttachment, h as FHIRBundleEntry, i as FHIRCodeableConcept, j as FHIRContactPoint, k as FHIRDiagnosticReport, l as FHIRHumanName, m as FHIRPatient, n as FHIRPeriod, o as FHIRQuantity, p as FHIRReference, q as FHIRReferenceRange } from './fhir-types-Cn5WFbOI.js';
package/dist/index.js CHANGED
@@ -5,19 +5,19 @@ import {
5
5
  labReportToFHIR,
6
6
  labResultToFHIRBundle,
7
7
  userProfileToFHIR
8
- } from "./chunk-K3VZ3F5Z.js";
8
+ } from "./chunk-TLF3IVSN.js";
9
9
  import {
10
10
  MAX_FILE_SIZE,
11
11
  MAX_OBSERVATIONS,
12
12
  extractObservationsFromBundle,
13
13
  mapFHIRObservationToInternal,
14
14
  processImportBundle
15
- } from "./chunk-NJM45WAH.js";
15
+ } from "./chunk-6QUGBBV2.js";
16
16
  import {
17
17
  validateFHIRDiagnosticReport,
18
18
  validateFHIRImportBundle,
19
19
  validateFHIRObservation
20
- } from "./chunk-E6MXDQXW.js";
20
+ } from "./chunk-XT635TWP.js";
21
21
  import {
22
22
  BIOMARKER_CODE_SYSTEM,
23
23
  LOINC_SYSTEM
@@ -31,7 +31,7 @@ import {
31
31
  getRangeDirection,
32
32
  getReferenceRange,
33
33
  referenceRangeMeaning
34
- } from "./chunk-P4G534AQ.js";
34
+ } from "./chunk-O3FXUPW3.js";
35
35
  import {
36
36
  SOURCE_REGISTRY,
37
37
  extractSourceKey
@@ -47,7 +47,7 @@ import {
47
47
  isUcumCode,
48
48
  resolveUcum,
49
49
  unitToUCUM
50
- } from "./chunk-Q3H5C6UR.js";
50
+ } from "./chunk-U2XW6DY4.js";
51
51
  import {
52
52
  BIOMARKER_DEFINITIONS,
53
53
  CAC_INDICATOR_CODES,
@@ -77,10 +77,11 @@ import {
77
77
  isValidCode,
78
78
  isValidLoinc,
79
79
  loincToCode,
80
+ methodVariantOf,
80
81
  normalizeCode,
81
82
  toBiomarkerTests,
82
83
  validateLoincNameMatch
83
- } from "./chunk-4FKZG5GZ.js";
84
+ } from "./chunk-KQ4CX67G.js";
84
85
 
85
86
  // src/category-groups.ts
86
87
  var CATEGORY_GROUPS = {
@@ -734,6 +735,7 @@ export {
734
735
  listMappedSubcategories,
735
736
  loincToCode,
736
737
  mapFHIRObservationToInternal,
738
+ methodVariantOf,
737
739
  normalizeCode,
738
740
  plural,
739
741
  pluralCount,