ezmedicationinput 0.1.43 → 0.1.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/advice-rules.json +772 -0
- package/dist/advice-terminology.json +104 -0
- package/dist/advice.d.ts +16 -0
- package/dist/advice.js +1375 -0
- package/dist/event-trigger.d.ts +14 -0
- package/dist/event-trigger.js +501 -0
- package/dist/fhir-translations.d.ts +5 -0
- package/dist/fhir-translations.js +117 -0
- package/dist/fhir.d.ts +6 -4
- package/dist/fhir.js +566 -134
- package/dist/format.d.ts +4 -2
- package/dist/format.js +515 -218
- package/dist/i18n.d.ts +2 -2
- package/dist/i18n.js +641 -199
- package/dist/index.d.ts +0 -1
- package/dist/index.js +219 -168
- package/dist/internal-types.d.ts +5 -5
- package/dist/ir.d.ts +4 -0
- package/dist/ir.js +178 -0
- package/dist/lexer/lex.d.ts +2 -0
- package/dist/lexer/lex.js +401 -0
- package/dist/lexer/meaning.d.ts +71 -0
- package/dist/lexer/meaning.js +619 -0
- package/dist/lexer/surface.d.ts +2 -0
- package/dist/lexer/surface.js +62 -0
- package/dist/lexer/token-types.d.ts +36 -0
- package/dist/lexer/token-types.js +19 -0
- package/dist/maps.d.ts +6 -12
- package/dist/maps.js +793 -247
- package/dist/parser-state.d.ts +101 -0
- package/dist/parser-state.js +441 -0
- package/dist/parser.d.ts +7 -7
- package/dist/parser.js +3598 -1974
- package/dist/prn.d.ts +4 -0
- package/dist/prn.js +59 -0
- package/dist/schedule.js +230 -32
- package/dist/site-phrases.d.ts +35 -0
- package/dist/site-phrases.js +344 -0
- package/dist/timing-summary.d.ts +13 -3
- package/dist/timing-summary.js +7 -7
- package/dist/types.d.ts +237 -32
- package/dist/types.js +49 -1
- package/dist/utils/text.d.ts +3 -0
- package/dist/utils/text.js +48 -0
- package/package.json +1 -1
package/dist/format.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatCanonicalClause = formatCanonicalClause;
|
|
3
4
|
exports.formatInternal = formatInternal;
|
|
5
|
+
const prn_1 = require("./prn");
|
|
4
6
|
const types_1 = require("./types");
|
|
5
7
|
const timing_summary_1 = require("./timing-summary");
|
|
6
8
|
const ROUTE_SHORT = {
|
|
@@ -63,9 +65,11 @@ const EN_TIMES_PER_DAY = {
|
|
|
63
65
|
3: "three times daily",
|
|
64
66
|
4: "four times daily"
|
|
65
67
|
};
|
|
68
|
+
const SLOWLY_QUALIFIER_CODE = "419443000";
|
|
69
|
+
const EMPTY_STOMACH_QUALIFIER_CODE = "717154004";
|
|
66
70
|
const DEFAULT_ROUTE_GRAMMAR = { verb: "Use" };
|
|
67
71
|
const ROUTE_GRAMMAR = {
|
|
68
|
-
[types_1.RouteCode["Oral route"]]: { verb: "Take", routePhrase: "
|
|
72
|
+
[types_1.RouteCode["Oral route"]]: { verb: "Take", routePhrase: "orally" },
|
|
69
73
|
[types_1.RouteCode["Ophthalmic route"]]: {
|
|
70
74
|
verb: "Instill",
|
|
71
75
|
routePhrase: ({ hasSite }) => (hasSite ? undefined : "in the eye"),
|
|
@@ -81,6 +85,11 @@ const ROUTE_GRAMMAR = {
|
|
|
81
85
|
routePhrase: ({ hasSite }) => (hasSite ? undefined : "rectally"),
|
|
82
86
|
sitePreposition: "into"
|
|
83
87
|
},
|
|
88
|
+
[types_1.RouteCode["Per vagina"]]: {
|
|
89
|
+
verb: "Insert",
|
|
90
|
+
routePhrase: ({ hasSite }) => (hasSite ? undefined : "vaginally"),
|
|
91
|
+
sitePreposition: "into"
|
|
92
|
+
},
|
|
84
93
|
[types_1.RouteCode["Topical route"]]: {
|
|
85
94
|
verb: "Apply",
|
|
86
95
|
routePhrase: ({ hasSite }) => (hasSite ? undefined : "topically"),
|
|
@@ -117,6 +126,10 @@ const ROUTE_GRAMMAR = {
|
|
|
117
126
|
sitePreposition: "into"
|
|
118
127
|
}
|
|
119
128
|
};
|
|
129
|
+
function scheduleOf(clause) {
|
|
130
|
+
var _a;
|
|
131
|
+
return (_a = clause.schedule) !== null && _a !== void 0 ? _a : {};
|
|
132
|
+
}
|
|
120
133
|
function grammarFromRouteText(text) {
|
|
121
134
|
if (!text) {
|
|
122
135
|
return undefined;
|
|
@@ -152,6 +165,9 @@ function grammarFromRouteText(text) {
|
|
|
152
165
|
if (normalized.includes("rectal") || normalized.includes("rectum")) {
|
|
153
166
|
return ROUTE_GRAMMAR[types_1.RouteCode["Per rectum"]];
|
|
154
167
|
}
|
|
168
|
+
if (normalized.includes("vagin")) {
|
|
169
|
+
return ROUTE_GRAMMAR[types_1.RouteCode["Per vagina"]];
|
|
170
|
+
}
|
|
155
171
|
if (normalized.includes("nasal")) {
|
|
156
172
|
return ROUTE_GRAMMAR[types_1.RouteCode["Nasal route"]];
|
|
157
173
|
}
|
|
@@ -160,41 +176,89 @@ function grammarFromRouteText(text) {
|
|
|
160
176
|
}
|
|
161
177
|
return undefined;
|
|
162
178
|
}
|
|
163
|
-
function resolveRouteGrammar(
|
|
179
|
+
function resolveRouteGrammar(clause) {
|
|
180
|
+
var _a, _b, _c, _d;
|
|
181
|
+
const routeCode = (_a = clause.route) === null || _a === void 0 ? void 0 : _a.code;
|
|
182
|
+
if (routeCode && ROUTE_GRAMMAR[routeCode]) {
|
|
183
|
+
return (_b = ROUTE_GRAMMAR[routeCode]) !== null && _b !== void 0 ? _b : DEFAULT_ROUTE_GRAMMAR;
|
|
184
|
+
}
|
|
185
|
+
return (_d = grammarFromRouteText((_c = clause.route) === null || _c === void 0 ? void 0 : _c.text)) !== null && _d !== void 0 ? _d : DEFAULT_ROUTE_GRAMMAR;
|
|
186
|
+
}
|
|
187
|
+
function resolveMethodVerb(clause, grammar) {
|
|
164
188
|
var _a, _b;
|
|
165
|
-
|
|
166
|
-
|
|
189
|
+
const methodText = (_b = (_a = clause.method) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.trim();
|
|
190
|
+
if (methodText) {
|
|
191
|
+
return methodText;
|
|
167
192
|
}
|
|
168
|
-
return
|
|
193
|
+
return grammar.verb;
|
|
169
194
|
}
|
|
170
195
|
function pluralize(unit, value) {
|
|
171
196
|
if (Math.abs(value) === 1) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
197
|
+
switch (unit) {
|
|
198
|
+
case "tab":
|
|
199
|
+
return "tablet";
|
|
200
|
+
case "cap":
|
|
201
|
+
return "capsule";
|
|
202
|
+
default:
|
|
203
|
+
return unit;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (unit.endsWith(" ribbon")) {
|
|
176
207
|
return unit;
|
|
177
208
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
209
|
+
switch (unit) {
|
|
210
|
+
case "tab":
|
|
211
|
+
case "tablet":
|
|
212
|
+
return "tablets";
|
|
213
|
+
case "cap":
|
|
214
|
+
case "capsule":
|
|
215
|
+
return "capsules";
|
|
216
|
+
case "mL":
|
|
217
|
+
case "mg":
|
|
218
|
+
return unit;
|
|
219
|
+
case "puff":
|
|
220
|
+
return "puffs";
|
|
221
|
+
case "patch":
|
|
222
|
+
return "patches";
|
|
223
|
+
case "drop":
|
|
224
|
+
return "drops";
|
|
225
|
+
case "suppository":
|
|
226
|
+
return "suppositories";
|
|
227
|
+
case "pump":
|
|
228
|
+
return "pumps";
|
|
229
|
+
case "squeeze":
|
|
230
|
+
return "squeezes";
|
|
231
|
+
case "applicatorful":
|
|
232
|
+
return "applicatorfuls";
|
|
233
|
+
case "capful":
|
|
234
|
+
return "capfuls";
|
|
235
|
+
case "scoop":
|
|
236
|
+
return "scoops";
|
|
237
|
+
case "application":
|
|
238
|
+
return "applications";
|
|
239
|
+
case "fingertip unit":
|
|
240
|
+
return "fingertip units";
|
|
241
|
+
case "finger length":
|
|
242
|
+
return "finger lengths";
|
|
243
|
+
default:
|
|
244
|
+
return unit;
|
|
245
|
+
}
|
|
195
246
|
}
|
|
196
|
-
function
|
|
197
|
-
const
|
|
247
|
+
function formatPatientInstructionSentence(text) {
|
|
248
|
+
const trimmed = text === null || text === void 0 ? void 0 : text.trim();
|
|
249
|
+
if (!trimmed) {
|
|
250
|
+
return undefined;
|
|
251
|
+
}
|
|
252
|
+
const sentence = /^[.!?]$/.test(trimmed.slice(-1)) ? trimmed : `${trimmed}.`;
|
|
253
|
+
return sentence.charAt(0).toUpperCase() + sentence.slice(1);
|
|
254
|
+
}
|
|
255
|
+
function describeFrequency(schedule) {
|
|
256
|
+
const frequency = schedule === null || schedule === void 0 ? void 0 : schedule.frequency;
|
|
257
|
+
const frequencyMax = schedule === null || schedule === void 0 ? void 0 : schedule.frequencyMax;
|
|
258
|
+
const period = schedule === null || schedule === void 0 ? void 0 : schedule.period;
|
|
259
|
+
const periodMax = schedule === null || schedule === void 0 ? void 0 : schedule.periodMax;
|
|
260
|
+
const periodUnit = schedule === null || schedule === void 0 ? void 0 : schedule.periodUnit;
|
|
261
|
+
const timingCode = schedule === null || schedule === void 0 ? void 0 : schedule.timingCode;
|
|
198
262
|
if (frequency !== undefined &&
|
|
199
263
|
frequencyMax !== undefined &&
|
|
200
264
|
periodUnit === types_1.FhirPeriodUnit.Day &&
|
|
@@ -214,6 +278,12 @@ function describeFrequency(internal) {
|
|
|
214
278
|
}
|
|
215
279
|
return `${stripTrailingZero(frequency)} times daily`;
|
|
216
280
|
}
|
|
281
|
+
if (periodUnit === types_1.FhirPeriodUnit.Minute && period) {
|
|
282
|
+
if (periodMax && periodMax !== period) {
|
|
283
|
+
return `every ${stripTrailingZero(period)} to ${stripTrailingZero(periodMax)} minutes`;
|
|
284
|
+
}
|
|
285
|
+
return `every ${stripTrailingZero(period)} minute${period === 1 ? "" : "s"}`;
|
|
286
|
+
}
|
|
217
287
|
if (periodUnit === types_1.FhirPeriodUnit.Hour && period) {
|
|
218
288
|
if (periodMax && periodMax !== period) {
|
|
219
289
|
return `every ${stripTrailingZero(period)} to ${stripTrailingZero(periodMax)} hours`;
|
|
@@ -247,6 +317,15 @@ function describeFrequency(internal) {
|
|
|
247
317
|
}
|
|
248
318
|
return `every ${stripTrailingZero(period)} months`;
|
|
249
319
|
}
|
|
320
|
+
if (periodUnit === types_1.FhirPeriodUnit.Year && period) {
|
|
321
|
+
if (period === 1 && (!periodMax || periodMax === 1)) {
|
|
322
|
+
return "once yearly";
|
|
323
|
+
}
|
|
324
|
+
if (periodMax && periodMax !== period) {
|
|
325
|
+
return `every ${stripTrailingZero(period)} to ${stripTrailingZero(periodMax)} years`;
|
|
326
|
+
}
|
|
327
|
+
return `every ${stripTrailingZero(period)} years`;
|
|
328
|
+
}
|
|
250
329
|
if (timingCode) {
|
|
251
330
|
if (timingCode === "WK") {
|
|
252
331
|
return "once weekly";
|
|
@@ -268,8 +347,9 @@ function describeFrequency(internal) {
|
|
|
268
347
|
}
|
|
269
348
|
}
|
|
270
349
|
if (frequency && periodUnit === undefined && period === undefined) {
|
|
271
|
-
if (frequency === 1)
|
|
350
|
+
if (frequency === 1) {
|
|
272
351
|
return "once";
|
|
352
|
+
}
|
|
273
353
|
return `${stripTrailingZero(frequency)} times`;
|
|
274
354
|
}
|
|
275
355
|
return undefined;
|
|
@@ -284,36 +364,99 @@ function describeFrequencyCount(count) {
|
|
|
284
364
|
}
|
|
285
365
|
return `${stripTrailingZero(count)} times daily`;
|
|
286
366
|
}
|
|
287
|
-
function
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
367
|
+
function describeStandaloneOccurrenceCount(schedule) {
|
|
368
|
+
var _a, _b, _c;
|
|
369
|
+
const count = schedule === null || schedule === void 0 ? void 0 : schedule.count;
|
|
370
|
+
if (!count || count <= 0) {
|
|
371
|
+
return undefined;
|
|
372
|
+
}
|
|
373
|
+
if ((schedule === null || schedule === void 0 ? void 0 : schedule.frequency) !== undefined ||
|
|
374
|
+
(schedule === null || schedule === void 0 ? void 0 : schedule.frequencyMax) !== undefined ||
|
|
375
|
+
(schedule === null || schedule === void 0 ? void 0 : schedule.period) !== undefined ||
|
|
376
|
+
(schedule === null || schedule === void 0 ? void 0 : schedule.periodMax) !== undefined ||
|
|
377
|
+
(schedule === null || schedule === void 0 ? void 0 : schedule.periodUnit) !== undefined ||
|
|
378
|
+
((_a = schedule === null || schedule === void 0 ? void 0 : schedule.dayOfWeek) === null || _a === void 0 ? void 0 : _a.length) ||
|
|
379
|
+
((_b = schedule === null || schedule === void 0 ? void 0 : schedule.when) === null || _b === void 0 ? void 0 : _b.length) ||
|
|
380
|
+
((_c = schedule === null || schedule === void 0 ? void 0 : schedule.timeOfDay) === null || _c === void 0 ? void 0 : _c.length) ||
|
|
381
|
+
(schedule === null || schedule === void 0 ? void 0 : schedule.duration) !== undefined ||
|
|
382
|
+
(schedule === null || schedule === void 0 ? void 0 : schedule.durationMax) !== undefined ||
|
|
383
|
+
(schedule === null || schedule === void 0 ? void 0 : schedule.durationUnit) !== undefined ||
|
|
384
|
+
(schedule === null || schedule === void 0 ? void 0 : schedule.timingCode)) {
|
|
385
|
+
return undefined;
|
|
386
|
+
}
|
|
387
|
+
switch (count) {
|
|
388
|
+
case 1:
|
|
389
|
+
return "once";
|
|
390
|
+
case 2:
|
|
391
|
+
return "twice";
|
|
392
|
+
default:
|
|
393
|
+
return `${stripTrailingZero(count)} times`;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
function formatDoseShort(dose) {
|
|
397
|
+
if (!dose) {
|
|
398
|
+
return undefined;
|
|
399
|
+
}
|
|
400
|
+
if (dose.range) {
|
|
401
|
+
if (dose.range.low !== undefined && dose.range.high !== undefined) {
|
|
402
|
+
const base = `${stripTrailingZero(dose.range.low)}-${stripTrailingZero(dose.range.high)}`;
|
|
403
|
+
if (dose.unit) {
|
|
404
|
+
return `${base} ${dose.unit}`;
|
|
405
|
+
}
|
|
406
|
+
return base;
|
|
407
|
+
}
|
|
408
|
+
if (dose.range.low !== undefined) {
|
|
409
|
+
const base = `>=${stripTrailingZero(dose.range.low)}`;
|
|
410
|
+
if (dose.unit) {
|
|
411
|
+
return `${base} ${dose.unit}`;
|
|
412
|
+
}
|
|
413
|
+
return base;
|
|
414
|
+
}
|
|
415
|
+
if (dose.range.high !== undefined) {
|
|
416
|
+
const base = `<=${stripTrailingZero(dose.range.high)}`;
|
|
417
|
+
if (dose.unit) {
|
|
418
|
+
return `${base} ${dose.unit}`;
|
|
419
|
+
}
|
|
420
|
+
return base;
|
|
293
421
|
}
|
|
294
|
-
return base;
|
|
295
422
|
}
|
|
296
|
-
if (
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
return
|
|
423
|
+
if (dose.value !== undefined) {
|
|
424
|
+
if (dose.unit) {
|
|
425
|
+
return `${stripTrailingZero(dose.value)} ${dose.unit}`;
|
|
426
|
+
}
|
|
427
|
+
return `${stripTrailingZero(dose.value)}`;
|
|
301
428
|
}
|
|
302
429
|
return undefined;
|
|
303
430
|
}
|
|
304
|
-
function formatDoseLong(
|
|
305
|
-
if (
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
431
|
+
function formatDoseLong(dose) {
|
|
432
|
+
if (!dose) {
|
|
433
|
+
return undefined;
|
|
434
|
+
}
|
|
435
|
+
if (dose.range) {
|
|
436
|
+
if (dose.range.low !== undefined && dose.range.high !== undefined) {
|
|
437
|
+
if (dose.unit) {
|
|
438
|
+
return `${stripTrailingZero(dose.range.low)} to ${stripTrailingZero(dose.range.high)} ${pluralize(dose.unit, dose.range.high)}`;
|
|
439
|
+
}
|
|
440
|
+
return `${stripTrailingZero(dose.range.low)} to ${stripTrailingZero(dose.range.high)}`;
|
|
441
|
+
}
|
|
442
|
+
if (dose.range.low !== undefined) {
|
|
443
|
+
if (dose.unit) {
|
|
444
|
+
return `at least ${stripTrailingZero(dose.range.low)} ${pluralize(dose.unit, dose.range.low)}`;
|
|
445
|
+
}
|
|
446
|
+
return `at least ${stripTrailingZero(dose.range.low)}`;
|
|
447
|
+
}
|
|
448
|
+
if (dose.range.high !== undefined) {
|
|
449
|
+
if (dose.unit) {
|
|
450
|
+
return `up to ${stripTrailingZero(dose.range.high)} ${pluralize(dose.unit, dose.range.high)}`;
|
|
451
|
+
}
|
|
452
|
+
return `up to ${stripTrailingZero(dose.range.high)}`;
|
|
309
453
|
}
|
|
310
|
-
return `${stripTrailingZero(low)} to ${stripTrailingZero(high)}`;
|
|
311
454
|
}
|
|
312
|
-
if (
|
|
313
|
-
if (
|
|
314
|
-
return `${stripTrailingZero(
|
|
455
|
+
if (dose.value !== undefined) {
|
|
456
|
+
if (dose.unit) {
|
|
457
|
+
return `${stripTrailingZero(dose.value)} ${pluralize(dose.unit, dose.value)}`;
|
|
315
458
|
}
|
|
316
|
-
return `${stripTrailingZero(
|
|
459
|
+
return `${stripTrailingZero(dose.value)}`;
|
|
317
460
|
}
|
|
318
461
|
return undefined;
|
|
319
462
|
}
|
|
@@ -327,9 +470,10 @@ function summarizeMealTimingGroup(group) {
|
|
|
327
470
|
}
|
|
328
471
|
return `${relationText} ${joinWithAnd(group.meals)}`;
|
|
329
472
|
}
|
|
330
|
-
function collectWhenPhrases(
|
|
331
|
-
var _a, _b;
|
|
332
|
-
|
|
473
|
+
function collectWhenPhrases(schedule, options) {
|
|
474
|
+
var _a, _b, _c;
|
|
475
|
+
const when = (_a = schedule === null || schedule === void 0 ? void 0 : schedule.when) !== null && _a !== void 0 ? _a : [];
|
|
476
|
+
if (!when.length) {
|
|
333
477
|
return [];
|
|
334
478
|
}
|
|
335
479
|
const unique = [];
|
|
@@ -337,7 +481,7 @@ function collectWhenPhrases(internal, options) {
|
|
|
337
481
|
let hasSpecificAfter = false;
|
|
338
482
|
let hasSpecificBefore = false;
|
|
339
483
|
let hasSpecificWith = false;
|
|
340
|
-
for (const code of
|
|
484
|
+
for (const code of when) {
|
|
341
485
|
if (!seen.has(code)) {
|
|
342
486
|
seen.add(code);
|
|
343
487
|
unique.push(code);
|
|
@@ -351,16 +495,13 @@ function collectWhenPhrases(internal, options) {
|
|
|
351
495
|
code === types_1.EventTiming["Before Dinner"]) {
|
|
352
496
|
hasSpecificBefore = true;
|
|
353
497
|
}
|
|
354
|
-
if (code === types_1.EventTiming.Breakfast ||
|
|
355
|
-
code === types_1.EventTiming.Lunch ||
|
|
356
|
-
code === types_1.EventTiming.Dinner) {
|
|
498
|
+
if (code === types_1.EventTiming.Breakfast || code === types_1.EventTiming.Lunch || code === types_1.EventTiming.Dinner) {
|
|
357
499
|
hasSpecificWith = true;
|
|
358
500
|
}
|
|
359
501
|
}
|
|
360
502
|
}
|
|
361
503
|
const filtered = [];
|
|
362
|
-
for (
|
|
363
|
-
const code = unique[i];
|
|
504
|
+
for (const code of unique) {
|
|
364
505
|
if (code === types_1.EventTiming["After Meal"] && hasSpecificAfter) {
|
|
365
506
|
continue;
|
|
366
507
|
}
|
|
@@ -373,29 +514,28 @@ function collectWhenPhrases(internal, options) {
|
|
|
373
514
|
filtered.push(code);
|
|
374
515
|
}
|
|
375
516
|
const mealGroup = (0, timing_summary_1.getMealTimingGroup)(filtered, options);
|
|
376
|
-
if (mealGroup) {
|
|
377
|
-
const groupedCodes = new Set(mealGroup.codes);
|
|
517
|
+
if (!mealGroup) {
|
|
378
518
|
const phrases = [];
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
const code = filtered[i];
|
|
382
|
-
if (groupedCodes.has(code)) {
|
|
383
|
-
if (!insertedGroup) {
|
|
384
|
-
phrases.push(summarizeMealTimingGroup(mealGroup));
|
|
385
|
-
insertedGroup = true;
|
|
386
|
-
}
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
389
|
-
const text = (_a = WHEN_TEXT[code]) !== null && _a !== void 0 ? _a : code;
|
|
519
|
+
for (const code of filtered) {
|
|
520
|
+
const text = (_b = WHEN_TEXT[code]) !== null && _b !== void 0 ? _b : code;
|
|
390
521
|
if (text) {
|
|
391
522
|
phrases.push(text);
|
|
392
523
|
}
|
|
393
524
|
}
|
|
394
525
|
return phrases;
|
|
395
526
|
}
|
|
527
|
+
const groupedCodes = new Set(mealGroup.codes);
|
|
396
528
|
const phrases = [];
|
|
397
|
-
|
|
398
|
-
|
|
529
|
+
let insertedGroup = false;
|
|
530
|
+
for (const code of filtered) {
|
|
531
|
+
if (groupedCodes.has(code)) {
|
|
532
|
+
if (!insertedGroup) {
|
|
533
|
+
phrases.push(summarizeMealTimingGroup(mealGroup));
|
|
534
|
+
insertedGroup = true;
|
|
535
|
+
}
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
const text = (_c = WHEN_TEXT[code]) !== null && _c !== void 0 ? _c : code;
|
|
399
539
|
if (text) {
|
|
400
540
|
phrases.push(text);
|
|
401
541
|
}
|
|
@@ -426,21 +566,23 @@ function combineFrequencyAndEvents(frequency, events) {
|
|
|
426
566
|
}
|
|
427
567
|
if (events.length === 1 && events[0] === "at bedtime") {
|
|
428
568
|
const lowerFrequency = frequency.toLowerCase();
|
|
429
|
-
if (lowerFrequency === "twice daily" ||
|
|
569
|
+
if (lowerFrequency === "twice daily" ||
|
|
570
|
+
lowerFrequency === "three times daily" ||
|
|
571
|
+
lowerFrequency === "four times daily") {
|
|
430
572
|
return { frequency: `${frequency} and ${events[0]}` };
|
|
431
573
|
}
|
|
432
574
|
}
|
|
433
575
|
return { frequency, event: joinWithAnd(events) };
|
|
434
576
|
}
|
|
435
|
-
function buildRoutePhrase(
|
|
436
|
-
var _a;
|
|
577
|
+
function buildRoutePhrase(clause, grammar, hasSite) {
|
|
578
|
+
var _a, _b;
|
|
437
579
|
if (typeof grammar.routePhrase === "function") {
|
|
438
|
-
return grammar.routePhrase({ hasSite,
|
|
580
|
+
return grammar.routePhrase({ hasSite, clause });
|
|
439
581
|
}
|
|
440
582
|
if (typeof grammar.routePhrase === "string") {
|
|
441
583
|
return grammar.routePhrase;
|
|
442
584
|
}
|
|
443
|
-
const text = (_a =
|
|
585
|
+
const text = (_b = (_a = clause.route) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.trim();
|
|
444
586
|
if (!text) {
|
|
445
587
|
return undefined;
|
|
446
588
|
}
|
|
@@ -449,7 +591,7 @@ function buildRoutePhrase(internal, grammar, hasSite) {
|
|
|
449
591
|
return text;
|
|
450
592
|
}
|
|
451
593
|
if (normalized === "oral") {
|
|
452
|
-
return "
|
|
594
|
+
return "orally";
|
|
453
595
|
}
|
|
454
596
|
if (normalized === "intravenous") {
|
|
455
597
|
return "intravenously";
|
|
@@ -474,17 +616,34 @@ function buildRoutePhrase(internal, grammar, hasSite) {
|
|
|
474
616
|
}
|
|
475
617
|
return `via ${text}`;
|
|
476
618
|
}
|
|
477
|
-
function formatSite(
|
|
478
|
-
var _a;
|
|
479
|
-
|
|
619
|
+
function formatSite(clause, grammar) {
|
|
620
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
621
|
+
let text = (_b = (_a = clause.site) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.trim();
|
|
622
|
+
if (!text) {
|
|
623
|
+
const display = (_e = (_d = (_c = clause.site) === null || _c === void 0 ? void 0 : _c.coding) === null || _d === void 0 ? void 0 : _d.display) === null || _e === void 0 ? void 0 : _e.trim();
|
|
624
|
+
if (display) {
|
|
625
|
+
text = display.charAt(0).toLowerCase() + display.slice(1);
|
|
626
|
+
}
|
|
627
|
+
else {
|
|
628
|
+
text = (_h = (_g = (_f = clause.site) === null || _f === void 0 ? void 0 : _f.coding) === null || _g === void 0 ? void 0 : _g.code) === null || _h === void 0 ? void 0 : _h.trim();
|
|
629
|
+
}
|
|
630
|
+
}
|
|
480
631
|
if (!text) {
|
|
481
632
|
return undefined;
|
|
482
633
|
}
|
|
483
634
|
const lower = text.toLowerCase();
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
635
|
+
const routeText = (_k = (_j = clause.route) === null || _j === void 0 ? void 0 : _j.text) === null || _k === void 0 ? void 0 : _k.trim().toLowerCase();
|
|
636
|
+
const isRectalRoute = ((_l = clause.route) === null || _l === void 0 ? void 0 : _l.code) === types_1.RouteCode["Per rectum"] ||
|
|
637
|
+
routeText === "rectum" ||
|
|
638
|
+
routeText === "rectal";
|
|
639
|
+
const isVaginalRoute = ((_m = clause.route) === null || _m === void 0 ? void 0 : _m.code) === types_1.RouteCode["Per vagina"] ||
|
|
640
|
+
routeText === "vagina" ||
|
|
641
|
+
routeText === "vaginal";
|
|
642
|
+
if (isRectalRoute && (lower === "rectum" || lower === "rectal")) {
|
|
643
|
+
return undefined;
|
|
644
|
+
}
|
|
645
|
+
if (isVaginalRoute && (lower === "vagina" || lower === "vaginal")) {
|
|
646
|
+
return undefined;
|
|
488
647
|
}
|
|
489
648
|
let preposition = grammar.sitePreposition;
|
|
490
649
|
if (!preposition) {
|
|
@@ -500,7 +659,7 @@ function formatSite(internal, grammar) {
|
|
|
500
659
|
else if (lower.includes("ear")) {
|
|
501
660
|
preposition = "in";
|
|
502
661
|
}
|
|
503
|
-
else if (/(skin|arm|leg|thigh|abdomen|shoulder|hand|foot|cheek|forearm|back|buttock|hip|face|hair|scalp|forehead|chin|neck)/.test(lower)) {
|
|
662
|
+
else if (/(skin|head|temple|arm|leg|thigh|abdomen|shoulder|elbow|wrist|ankle|knee|hand|foot|cheek|forearm|back|chest|breast|axilla|armpit|groin|lip|buttock|hip|face|hair|scalp|forehead|eyelid|chin|neck)/.test(lower)) {
|
|
504
663
|
preposition = "to";
|
|
505
664
|
}
|
|
506
665
|
else {
|
|
@@ -513,15 +672,7 @@ function formatSite(internal, grammar) {
|
|
|
513
672
|
function formatSiteNoun(site, preposition) {
|
|
514
673
|
const trimmed = site.trim();
|
|
515
674
|
const lower = trimmed.toLowerCase();
|
|
516
|
-
const skipArticlePrefixes = [
|
|
517
|
-
"the ",
|
|
518
|
-
"both ",
|
|
519
|
-
"each ",
|
|
520
|
-
"either ",
|
|
521
|
-
"every ",
|
|
522
|
-
"all ",
|
|
523
|
-
"bilateral ",
|
|
524
|
-
];
|
|
675
|
+
const skipArticlePrefixes = ["the ", "both ", "each ", "either ", "every ", "all ", "bilateral "];
|
|
525
676
|
for (const prefix of skipArticlePrefixes) {
|
|
526
677
|
if (lower.startsWith(prefix)) {
|
|
527
678
|
return trimmed;
|
|
@@ -531,111 +682,157 @@ function formatSiteNoun(site, preposition) {
|
|
|
531
682
|
if (needsArticle || preposition === "at") {
|
|
532
683
|
return `the ${trimmed}`;
|
|
533
684
|
}
|
|
534
|
-
if (/(eye|nostril|ear|arm|leg|thigh|abdomen|hand|foot|cheek|skin|back)/.test(lower)) {
|
|
535
|
-
return `the ${trimmed}`;
|
|
536
|
-
}
|
|
537
685
|
return `the ${trimmed}`;
|
|
538
686
|
}
|
|
539
|
-
function describeDayOfWeek(
|
|
540
|
-
|
|
687
|
+
function describeDayOfWeek(schedule) {
|
|
688
|
+
var _a, _b;
|
|
689
|
+
const dayOfWeek = (_a = schedule === null || schedule === void 0 ? void 0 : schedule.dayOfWeek) !== null && _a !== void 0 ? _a : [];
|
|
690
|
+
if (!dayOfWeek.length) {
|
|
541
691
|
return undefined;
|
|
542
692
|
}
|
|
543
|
-
const days =
|
|
544
|
-
|
|
693
|
+
const days = [];
|
|
694
|
+
for (const day of dayOfWeek) {
|
|
695
|
+
days.push((_b = DAY_NAMES[day]) !== null && _b !== void 0 ? _b : day);
|
|
696
|
+
}
|
|
697
|
+
return days.length ? `on ${joinWithAnd(days)}` : undefined;
|
|
698
|
+
}
|
|
699
|
+
function formatDurationShort(schedule) {
|
|
700
|
+
if (schedule.duration === undefined || !schedule.durationUnit) {
|
|
545
701
|
return undefined;
|
|
546
702
|
}
|
|
547
|
-
|
|
703
|
+
const base = stripTrailingZero(schedule.duration);
|
|
704
|
+
const qualifier = schedule.durationMax !== undefined && schedule.durationMax !== schedule.duration
|
|
705
|
+
? `${base}-${stripTrailingZero(schedule.durationMax)}`
|
|
706
|
+
: base;
|
|
707
|
+
return `x${qualifier}${schedule.durationUnit}`;
|
|
548
708
|
}
|
|
549
|
-
function
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
long: formatLong(internal, options)
|
|
553
|
-
};
|
|
554
|
-
if (!localization) {
|
|
555
|
-
return defaults[style];
|
|
709
|
+
function describeDuration(schedule) {
|
|
710
|
+
if (!schedule || schedule.duration === undefined || !schedule.durationUnit) {
|
|
711
|
+
return undefined;
|
|
556
712
|
}
|
|
557
|
-
const
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
713
|
+
const unit = schedule.durationUnit;
|
|
714
|
+
const label = (value) => {
|
|
715
|
+
switch (unit) {
|
|
716
|
+
case types_1.FhirPeriodUnit.Minute:
|
|
717
|
+
return value === 1 ? "minute" : "minutes";
|
|
718
|
+
case types_1.FhirPeriodUnit.Hour:
|
|
719
|
+
return value === 1 ? "hour" : "hours";
|
|
720
|
+
case types_1.FhirPeriodUnit.Day:
|
|
721
|
+
return value === 1 ? "day" : "days";
|
|
722
|
+
case types_1.FhirPeriodUnit.Week:
|
|
723
|
+
return value === 1 ? "week" : "weeks";
|
|
724
|
+
case types_1.FhirPeriodUnit.Month:
|
|
725
|
+
return value === 1 ? "month" : "months";
|
|
726
|
+
case types_1.FhirPeriodUnit.Year:
|
|
727
|
+
return value === 1 ? "year" : "years";
|
|
728
|
+
default:
|
|
729
|
+
return value === 1 ? "unit" : "units";
|
|
730
|
+
}
|
|
731
|
+
};
|
|
732
|
+
if (schedule.durationMax !== undefined && schedule.durationMax !== schedule.duration) {
|
|
733
|
+
return `for ${stripTrailingZero(schedule.duration)} to ${stripTrailingZero(schedule.durationMax)} ${label(schedule.durationMax)}`;
|
|
568
734
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
735
|
+
return `for ${stripTrailingZero(schedule.duration)} ${label(schedule.duration)}`;
|
|
736
|
+
}
|
|
737
|
+
function shouldUseGenericMedicationObject(clause) {
|
|
738
|
+
var _a, _b;
|
|
739
|
+
const methodText = (_b = (_a = clause.method) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.trim();
|
|
740
|
+
switch (methodText) {
|
|
741
|
+
case "Apply sunscreen":
|
|
742
|
+
case "Reapply sunscreen":
|
|
743
|
+
case "Use shampoo":
|
|
744
|
+
return false;
|
|
745
|
+
default:
|
|
746
|
+
return true;
|
|
579
747
|
}
|
|
580
|
-
return defaults[style];
|
|
581
748
|
}
|
|
582
|
-
function
|
|
749
|
+
function shouldSuppressRoutePhrase(clause, grammar, verb) {
|
|
583
750
|
var _a;
|
|
751
|
+
if (((_a = clause.route) === null || _a === void 0 ? void 0 : _a.code) !== types_1.RouteCode["Oral route"]) {
|
|
752
|
+
return false;
|
|
753
|
+
}
|
|
754
|
+
if (grammar.routePhrase !== "orally") {
|
|
755
|
+
return false;
|
|
756
|
+
}
|
|
757
|
+
switch (verb) {
|
|
758
|
+
case "Drink":
|
|
759
|
+
case "Swallow":
|
|
760
|
+
return true;
|
|
761
|
+
default:
|
|
762
|
+
return false;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
function formatShort(clause) {
|
|
766
|
+
var _a, _b, _c, _d, _e, _f;
|
|
767
|
+
const schedule = scheduleOf(clause);
|
|
584
768
|
const parts = [];
|
|
585
|
-
const dosePart = formatDoseShort(
|
|
769
|
+
const dosePart = formatDoseShort(clause.dose);
|
|
586
770
|
if (dosePart) {
|
|
587
771
|
parts.push(dosePart);
|
|
588
772
|
}
|
|
589
|
-
|
|
590
|
-
|
|
773
|
+
const routeCode = (_a = clause.route) === null || _a === void 0 ? void 0 : _a.code;
|
|
774
|
+
const routeText = (_b = clause.route) === null || _b === void 0 ? void 0 : _b.text;
|
|
775
|
+
if (routeCode) {
|
|
776
|
+
const short = ROUTE_SHORT[routeCode];
|
|
591
777
|
if (short) {
|
|
592
778
|
parts.push(short);
|
|
593
779
|
}
|
|
594
|
-
else if (
|
|
595
|
-
parts.push(
|
|
780
|
+
else if (routeText) {
|
|
781
|
+
parts.push(routeText);
|
|
596
782
|
}
|
|
597
783
|
}
|
|
598
|
-
else if (
|
|
599
|
-
parts.push(
|
|
784
|
+
else if (routeText) {
|
|
785
|
+
parts.push(routeText);
|
|
600
786
|
}
|
|
601
|
-
if (
|
|
602
|
-
parts.push(
|
|
787
|
+
if (schedule.timingCode) {
|
|
788
|
+
parts.push(schedule.timingCode);
|
|
603
789
|
}
|
|
604
|
-
else if (
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
(!
|
|
608
|
-
parts.push(`${stripTrailingZero(
|
|
790
|
+
else if (schedule.frequency !== undefined &&
|
|
791
|
+
schedule.frequencyMax !== undefined &&
|
|
792
|
+
schedule.periodUnit === types_1.FhirPeriodUnit.Day &&
|
|
793
|
+
(!schedule.period || schedule.period === 1)) {
|
|
794
|
+
parts.push(`${stripTrailingZero(schedule.frequency)}-${stripTrailingZero(schedule.frequencyMax)}x/d`);
|
|
609
795
|
}
|
|
610
|
-
else if (
|
|
611
|
-
|
|
612
|
-
(!
|
|
613
|
-
parts.push(`${stripTrailingZero(
|
|
796
|
+
else if (schedule.frequency &&
|
|
797
|
+
schedule.periodUnit === types_1.FhirPeriodUnit.Day &&
|
|
798
|
+
(!schedule.period || schedule.period === 1)) {
|
|
799
|
+
parts.push(`${stripTrailingZero(schedule.frequency)}x/d`);
|
|
614
800
|
}
|
|
615
|
-
else if (
|
|
616
|
-
const base = stripTrailingZero(
|
|
617
|
-
const qualifier =
|
|
618
|
-
? `${base}-${stripTrailingZero(
|
|
801
|
+
else if (schedule.period && schedule.periodUnit) {
|
|
802
|
+
const base = stripTrailingZero(schedule.period);
|
|
803
|
+
const qualifier = schedule.periodMax && schedule.periodMax !== schedule.period
|
|
804
|
+
? `${base}-${stripTrailingZero(schedule.periodMax)}`
|
|
619
805
|
: base;
|
|
620
|
-
parts.push(`Q${qualifier}${
|
|
806
|
+
parts.push(`Q${qualifier}${schedule.periodUnit.toUpperCase()}`);
|
|
807
|
+
}
|
|
808
|
+
if ((_c = schedule.when) === null || _c === void 0 ? void 0 : _c.length) {
|
|
809
|
+
parts.push(schedule.when.join(" "));
|
|
621
810
|
}
|
|
622
|
-
if (
|
|
623
|
-
|
|
811
|
+
if ((_d = schedule.dayOfWeek) === null || _d === void 0 ? void 0 : _d.length) {
|
|
812
|
+
const days = [];
|
|
813
|
+
for (const day of schedule.dayOfWeek) {
|
|
814
|
+
days.push(day.charAt(0).toUpperCase() + day.slice(1, 3));
|
|
815
|
+
}
|
|
816
|
+
parts.push(days.join(","));
|
|
624
817
|
}
|
|
625
|
-
if (
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
.
|
|
818
|
+
if ((_e = schedule.timeOfDay) === null || _e === void 0 ? void 0 : _e.length) {
|
|
819
|
+
const times = [];
|
|
820
|
+
for (const time of schedule.timeOfDay) {
|
|
821
|
+
times.push(time.slice(0, 5));
|
|
822
|
+
}
|
|
823
|
+
parts.push(times.join(","));
|
|
629
824
|
}
|
|
630
|
-
if (
|
|
631
|
-
parts.push(
|
|
825
|
+
if (schedule.count !== undefined) {
|
|
826
|
+
parts.push(`x${stripTrailingZero(schedule.count)}`);
|
|
632
827
|
}
|
|
633
|
-
|
|
634
|
-
|
|
828
|
+
const durationShort = formatDurationShort(schedule);
|
|
829
|
+
if (durationShort) {
|
|
830
|
+
parts.push(durationShort);
|
|
635
831
|
}
|
|
636
|
-
if (
|
|
637
|
-
|
|
638
|
-
|
|
832
|
+
if ((_f = clause.prn) === null || _f === void 0 ? void 0 : _f.enabled) {
|
|
833
|
+
const reason = (0, prn_1.getPreferredCanonicalPrnReasonText)(clause.prn.reason, clause.prn.reasons);
|
|
834
|
+
if (reason) {
|
|
835
|
+
parts.push(`PRN ${reason}`);
|
|
639
836
|
}
|
|
640
837
|
else {
|
|
641
838
|
parts.push("PRN");
|
|
@@ -643,40 +840,50 @@ function formatShort(internal) {
|
|
|
643
840
|
}
|
|
644
841
|
return parts.filter(Boolean).join(" ");
|
|
645
842
|
}
|
|
646
|
-
function formatLong(
|
|
647
|
-
var _a, _b, _c;
|
|
648
|
-
const
|
|
649
|
-
const
|
|
650
|
-
const
|
|
651
|
-
const
|
|
652
|
-
const
|
|
653
|
-
const
|
|
654
|
-
|
|
843
|
+
function formatLong(clause, options) {
|
|
844
|
+
var _a, _b, _c, _d, _e, _f;
|
|
845
|
+
const schedule = scheduleOf(clause);
|
|
846
|
+
const grammar = resolveRouteGrammar(clause);
|
|
847
|
+
const verb = resolveMethodVerb(clause, grammar);
|
|
848
|
+
const explicitDosePart = formatDoseLong(clause.dose);
|
|
849
|
+
const dosePart = explicitDosePart !== null && explicitDosePart !== void 0 ? explicitDosePart : (shouldUseGenericMedicationObject(clause) ? "the medication" : undefined);
|
|
850
|
+
const sitePart = formatSite(clause, grammar);
|
|
851
|
+
const routePart = shouldSuppressRoutePhrase(clause, grammar, verb)
|
|
852
|
+
? undefined
|
|
853
|
+
: buildRoutePhrase(clause, grammar, Boolean(sitePart));
|
|
854
|
+
const standaloneOccurrenceCount = describeStandaloneOccurrenceCount(schedule);
|
|
855
|
+
const frequencyPart = (_b = (_a = describeFrequency(schedule)) !== null && _a !== void 0 ? _a : standaloneOccurrenceCount) !== null && _b !== void 0 ? _b : describeFrequencyCount((0, timing_summary_1.inferDailyOccurrenceCount)(schedule, options));
|
|
856
|
+
const eventParts = collectWhenPhrases(schedule, options);
|
|
857
|
+
if ((_c = schedule.timeOfDay) === null || _c === void 0 ? void 0 : _c.length) {
|
|
655
858
|
const timeStrings = [];
|
|
656
|
-
for (const time of
|
|
859
|
+
for (const time of schedule.timeOfDay) {
|
|
657
860
|
const parts = time.split(":");
|
|
658
|
-
const
|
|
659
|
-
const
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
861
|
+
const hours = Number(parts[0]);
|
|
862
|
+
const minutes = Number(parts[1]);
|
|
863
|
+
if (!Number.isFinite(hours) || !Number.isFinite(minutes)) {
|
|
864
|
+
continue;
|
|
865
|
+
}
|
|
866
|
+
const isAm = hours < 12;
|
|
867
|
+
const displayHours = hours % 12 || 12;
|
|
868
|
+
const displayMinutes = minutes < 10 ? `0${minutes}` : `${minutes}`;
|
|
869
|
+
timeStrings.push(`${displayHours}:${displayMinutes}${isAm ? " am" : " pm"}`);
|
|
870
|
+
}
|
|
871
|
+
if (timeStrings.length) {
|
|
666
872
|
eventParts.push(`at ${timeStrings.join(", ")}`);
|
|
667
873
|
}
|
|
668
874
|
}
|
|
669
875
|
const timing = combineFrequencyAndEvents(frequencyPart, eventParts);
|
|
670
|
-
const dayPart = describeDayOfWeek(
|
|
671
|
-
const countPart =
|
|
672
|
-
? `for ${stripTrailingZero(
|
|
673
|
-
: undefined;
|
|
674
|
-
const asNeededPart = internal.asNeeded
|
|
675
|
-
? internal.asNeededReason
|
|
676
|
-
? `as needed for ${internal.asNeededReason}`
|
|
677
|
-
: "as needed"
|
|
876
|
+
const dayPart = describeDayOfWeek(schedule);
|
|
877
|
+
const countPart = schedule.count !== undefined && !standaloneOccurrenceCount
|
|
878
|
+
? `for ${stripTrailingZero(schedule.count)} ${schedule.count === 1 ? "dose" : "doses"}`
|
|
678
879
|
: undefined;
|
|
679
|
-
const
|
|
880
|
+
const durationPart = describeDuration(schedule);
|
|
881
|
+
const reason = (0, prn_1.getPreferredCanonicalPrnReasonText)((_d = clause.prn) === null || _d === void 0 ? void 0 : _d.reason, (_e = clause.prn) === null || _e === void 0 ? void 0 : _e.reasons);
|
|
882
|
+
const asNeededPart = ((_f = clause.prn) === null || _f === void 0 ? void 0 : _f.enabled) ? (reason ? `as needed for ${reason}` : "as needed") : undefined;
|
|
883
|
+
const segments = [];
|
|
884
|
+
if (dosePart) {
|
|
885
|
+
segments.push(dosePart);
|
|
886
|
+
}
|
|
680
887
|
if (routePart) {
|
|
681
888
|
segments.push(routePart);
|
|
682
889
|
}
|
|
@@ -692,6 +899,9 @@ function formatLong(internal, options) {
|
|
|
692
899
|
if (countPart) {
|
|
693
900
|
segments.push(countPart);
|
|
694
901
|
}
|
|
902
|
+
if (durationPart) {
|
|
903
|
+
segments.push(durationPart);
|
|
904
|
+
}
|
|
695
905
|
if (asNeededPart) {
|
|
696
906
|
segments.push(asNeededPart);
|
|
697
907
|
}
|
|
@@ -699,34 +909,121 @@ function formatLong(internal, options) {
|
|
|
699
909
|
segments.push(sitePart);
|
|
700
910
|
}
|
|
701
911
|
const body = segments.filter(Boolean).join(" ").replace(/\s+/g, " ").trim();
|
|
912
|
+
const instructionPhrases = [];
|
|
913
|
+
const instructionText = formatAdditionalInstructions(clause);
|
|
914
|
+
if (instructionText) {
|
|
915
|
+
instructionPhrases.push(instructionText);
|
|
916
|
+
}
|
|
917
|
+
const patientInstruction = formatPatientInstructionSentence(clause.patientInstruction);
|
|
918
|
+
if (patientInstruction) {
|
|
919
|
+
instructionPhrases.push(patientInstruction);
|
|
920
|
+
}
|
|
921
|
+
const trailingInstructionText = instructionPhrases.join(" ").trim() || undefined;
|
|
702
922
|
if (!body) {
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
return `${grammar.verb}.`;
|
|
923
|
+
if (!trailingInstructionText) {
|
|
924
|
+
return `${verb}.`;
|
|
706
925
|
}
|
|
707
|
-
return `${
|
|
926
|
+
return `${verb}. ${trailingInstructionText}`.trim();
|
|
708
927
|
}
|
|
709
|
-
const
|
|
710
|
-
|
|
711
|
-
return instructionText ? `${baseSentence} ${instructionText}` : baseSentence;
|
|
928
|
+
const baseSentence = `${verb} ${body}.`;
|
|
929
|
+
return trailingInstructionText ? `${baseSentence} ${trailingInstructionText}` : baseSentence;
|
|
712
930
|
}
|
|
713
|
-
function formatAdditionalInstructions(
|
|
714
|
-
var _a;
|
|
715
|
-
|
|
931
|
+
function formatAdditionalInstructions(clause) {
|
|
932
|
+
var _a, _b, _c, _d, _e, _f;
|
|
933
|
+
const instructions = (_a = clause.additionalInstructions) !== null && _a !== void 0 ? _a : [];
|
|
934
|
+
if (!instructions.length) {
|
|
716
935
|
return undefined;
|
|
717
936
|
}
|
|
718
|
-
const phrases =
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
937
|
+
const phrases = [];
|
|
938
|
+
const grammar = resolveRouteGrammar(clause);
|
|
939
|
+
const verb = resolveMethodVerb(clause, grammar);
|
|
940
|
+
for (const instruction of instructions) {
|
|
941
|
+
if (((_b = instruction.coding) === null || _b === void 0 ? void 0 : _b.code) === SLOWLY_QUALIFIER_CODE) {
|
|
942
|
+
const contextual = verb ? `${verb} slowly` : "Slowly";
|
|
943
|
+
phrases.push(contextual);
|
|
944
|
+
continue;
|
|
945
|
+
}
|
|
946
|
+
if (((_c = instruction.coding) === null || _c === void 0 ? void 0 : _c.code) === EMPTY_STOMACH_QUALIFIER_CODE ||
|
|
947
|
+
((_d = instruction.frames) === null || _d === void 0 ? void 0 : _d.some((frame) => frame.relation === types_1.AdviceRelation.On &&
|
|
948
|
+
frame.args.some((arg) => arg.role === types_1.AdviceArgumentRole.MealState &&
|
|
949
|
+
arg.conceptId === "empty_stomach")))) {
|
|
950
|
+
phrases.push("On an empty stomach");
|
|
951
|
+
continue;
|
|
952
|
+
}
|
|
953
|
+
const text = (_e = instruction.text) !== null && _e !== void 0 ? _e : (_f = instruction.coding) === null || _f === void 0 ? void 0 : _f.display;
|
|
954
|
+
if (!text) {
|
|
955
|
+
continue;
|
|
956
|
+
}
|
|
957
|
+
const trimmed = text.trim();
|
|
958
|
+
if (trimmed) {
|
|
959
|
+
phrases.push(trimmed);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
723
962
|
if (!phrases.length) {
|
|
724
963
|
return undefined;
|
|
725
964
|
}
|
|
726
|
-
return phrases
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
965
|
+
return phrases.map((phrase) => (/[.!?]$/.test(phrase) ? phrase : `${phrase}.`)).join(" ").trim();
|
|
966
|
+
}
|
|
967
|
+
function firstCanonicalClause(internal) {
|
|
968
|
+
const clauses = internal.clauses;
|
|
969
|
+
if (clauses.length > 0) {
|
|
970
|
+
return clauses[0];
|
|
971
|
+
}
|
|
972
|
+
return {
|
|
973
|
+
kind: "administration",
|
|
974
|
+
rawText: internal.input,
|
|
975
|
+
raw: { start: 0, end: internal.input.length, text: internal.input },
|
|
976
|
+
leftovers: [],
|
|
977
|
+
evidence: [],
|
|
978
|
+
confidence: 0
|
|
979
|
+
};
|
|
980
|
+
}
|
|
981
|
+
function formatCanonicalClause(clause, style, localization, options) {
|
|
982
|
+
let shortDefault;
|
|
983
|
+
let longDefault;
|
|
984
|
+
const formatDefault = (target) => {
|
|
985
|
+
switch (target) {
|
|
986
|
+
case "short":
|
|
987
|
+
if (shortDefault === undefined) {
|
|
988
|
+
shortDefault = formatShort(clause);
|
|
989
|
+
}
|
|
990
|
+
return shortDefault;
|
|
991
|
+
case "long":
|
|
992
|
+
if (longDefault === undefined) {
|
|
993
|
+
longDefault = formatLong(clause, options);
|
|
994
|
+
}
|
|
995
|
+
return longDefault;
|
|
996
|
+
}
|
|
997
|
+
};
|
|
998
|
+
if (!localization) {
|
|
999
|
+
return formatDefault(style);
|
|
1000
|
+
}
|
|
1001
|
+
if (style === "short" && localization.formatShort) {
|
|
1002
|
+
const context = {
|
|
1003
|
+
style: "short",
|
|
1004
|
+
clause,
|
|
1005
|
+
defaultText: formatDefault("short"),
|
|
1006
|
+
groupMealTimingsByRelation: Boolean(options === null || options === void 0 ? void 0 : options.groupMealTimingsByRelation),
|
|
1007
|
+
includeTimesPerDaySummary: Boolean(options === null || options === void 0 ? void 0 : options.includeTimesPerDaySummary),
|
|
1008
|
+
formatDefault
|
|
1009
|
+
};
|
|
1010
|
+
return localization.formatShort(context);
|
|
1011
|
+
}
|
|
1012
|
+
if (style === "long" && localization.formatLong) {
|
|
1013
|
+
const context = {
|
|
1014
|
+
style: "long",
|
|
1015
|
+
clause,
|
|
1016
|
+
defaultText: formatDefault("long"),
|
|
1017
|
+
groupMealTimingsByRelation: Boolean(options === null || options === void 0 ? void 0 : options.groupMealTimingsByRelation),
|
|
1018
|
+
includeTimesPerDaySummary: Boolean(options === null || options === void 0 ? void 0 : options.includeTimesPerDaySummary),
|
|
1019
|
+
formatDefault
|
|
1020
|
+
};
|
|
1021
|
+
return localization.formatLong(context);
|
|
1022
|
+
}
|
|
1023
|
+
return formatDefault(style);
|
|
1024
|
+
}
|
|
1025
|
+
function formatInternal(internal, style, localization, options) {
|
|
1026
|
+
return formatCanonicalClause(firstCanonicalClause(internal), style, localization, options);
|
|
730
1027
|
}
|
|
731
1028
|
function stripTrailingZero(value) {
|
|
732
1029
|
const text = value.toString();
|