ezmedicationinput 0.1.44 → 0.1.46

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 (75) hide show
  1. package/README.md +265 -2
  2. package/dist/body-site-grammar.d.ts +39 -0
  3. package/dist/body-site-lookup.d.ts +84 -0
  4. package/dist/body-site-resolution.d.ts +9 -0
  5. package/dist/body-site-spatial.d.ts +6 -0
  6. package/dist/clause-tail-grammar.d.ts +18 -0
  7. package/dist/fhir-translations.d.ts +4 -1
  8. package/dist/fhir.d.ts +9 -1
  9. package/dist/hpsg/chart.d.ts +14 -0
  10. package/dist/hpsg/clause-parser.d.ts +3 -0
  11. package/dist/hpsg/defaults.d.ts +9 -0
  12. package/dist/hpsg/lexical-classes.d.ts +89 -0
  13. package/dist/hpsg/method-lexicon.d.ts +13 -0
  14. package/dist/hpsg/projection.d.ts +12 -0
  15. package/dist/hpsg/rule-context.d.ts +32 -0
  16. package/dist/hpsg/rules/core-rules.d.ts +8 -0
  17. package/dist/hpsg/rules/instruction-rules.d.ts +4 -0
  18. package/dist/hpsg/rules/prn-rules.d.ts +3 -0
  19. package/dist/hpsg/rules/product-route.d.ts +2 -0
  20. package/dist/hpsg/rules/site-rules.d.ts +4 -0
  21. package/dist/hpsg/rules/timing-rules.d.ts +12 -0
  22. package/dist/hpsg/segmenter.d.ts +6 -0
  23. package/dist/hpsg/signature.d.ts +116 -0
  24. package/dist/hpsg/timing-lexicon.d.ts +31 -0
  25. package/dist/hpsg/unification.d.ts +8 -0
  26. package/dist/index.cjs +21052 -0
  27. package/dist/index.d.ts +5 -0
  28. package/dist/index.js +20865 -680
  29. package/dist/maps.d.ts +4 -2
  30. package/dist/parser-state.d.ts +4 -1
  31. package/dist/parser.d.ts +3 -13
  32. package/dist/prn-reason-coding.d.ts +8 -0
  33. package/dist/site-coding.d.ts +5 -0
  34. package/dist/snomed-postcoordination.d.ts +25 -0
  35. package/dist/snomed.d.ts +13 -0
  36. package/dist/types.d.ts +61 -16
  37. package/dist/unit-lexicon.d.ts +4 -0
  38. package/package.json +17 -6
  39. package/dist/advice-rules.json +0 -772
  40. package/dist/advice-terminology.json +0 -104
  41. package/dist/advice.js +0 -1375
  42. package/dist/context.js +0 -50
  43. package/dist/event-trigger.d.ts +0 -14
  44. package/dist/event-trigger.js +0 -501
  45. package/dist/fhir-translations.js +0 -117
  46. package/dist/fhir.js +0 -693
  47. package/dist/format.js +0 -1034
  48. package/dist/i18n.js +0 -1341
  49. package/dist/internal-types.d.ts +0 -60
  50. package/dist/internal-types.js +0 -2
  51. package/dist/ir.js +0 -178
  52. package/dist/lexer/lex.js +0 -401
  53. package/dist/lexer/meaning.js +0 -619
  54. package/dist/lexer/surface.js +0 -62
  55. package/dist/lexer/token-types.js +0 -19
  56. package/dist/maps.js +0 -2226
  57. package/dist/package.json +0 -3
  58. package/dist/parser-state.js +0 -441
  59. package/dist/parser.js +0 -5631
  60. package/dist/prn.js +0 -59
  61. package/dist/safety.js +0 -15
  62. package/dist/schedule.js +0 -1636
  63. package/dist/segment.d.ts +0 -6
  64. package/dist/segment.js +0 -203
  65. package/dist/site-phrases.js +0 -344
  66. package/dist/suggest.js +0 -907
  67. package/dist/timing-summary.js +0 -138
  68. package/dist/types.js +0 -276
  69. package/dist/utils/array.js +0 -11
  70. package/dist/utils/enum.d.ts +0 -2
  71. package/dist/utils/enum.js +0 -7
  72. package/dist/utils/object.js +0 -34
  73. package/dist/utils/strength.js +0 -149
  74. package/dist/utils/text.js +0 -48
  75. package/dist/utils/units.js +0 -82
package/dist/i18n.js DELETED
@@ -1,1341 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.THAI_SITE_TRANSLATIONS = exports.getRegisteredSigTranslations = exports.registerSigTranslation = void 0;
4
- exports.registerSigLocalization = registerSigLocalization;
5
- exports.getRegisteredSigLocalizations = getRegisteredSigLocalizations;
6
- exports.resolveSigLocalization = resolveSigLocalization;
7
- exports.resolveSigTranslation = resolveSigTranslation;
8
- const advice_1 = require("./advice");
9
- const fhir_translations_1 = require("./fhir-translations");
10
- const maps_1 = require("./maps");
11
- const prn_1 = require("./prn");
12
- const types_1 = require("./types");
13
- const timing_summary_1 = require("./timing-summary");
14
- const REGISTERED_LOCALIZATIONS = new Map();
15
- function registerSigLocalization(localization) {
16
- REGISTERED_LOCALIZATIONS.set(localization.locale.toLowerCase(), localization);
17
- }
18
- function getRegisteredSigLocalizations() {
19
- return Array.from(REGISTERED_LOCALIZATIONS.values());
20
- }
21
- function resolveSigLocalization(locale, config) {
22
- var _a, _b, _c, _d, _e, _f, _g;
23
- const normalizedLocale = (_a = config === null || config === void 0 ? void 0 : config.locale) !== null && _a !== void 0 ? _a : locale;
24
- const targetKey = normalizedLocale === null || normalizedLocale === void 0 ? void 0 : normalizedLocale.toLowerCase();
25
- const base = targetKey ? REGISTERED_LOCALIZATIONS.get(targetKey) : undefined;
26
- const inherited = (config === null || config === void 0 ? void 0 : config.inherit)
27
- ? REGISTERED_LOCALIZATIONS.get(config.inherit.toLowerCase())
28
- : undefined;
29
- if (!base && !inherited && !config) {
30
- return undefined;
31
- }
32
- const resolvedLocale = (_f = (_e = (_d = (_c = (_b = config === null || config === void 0 ? void 0 : config.locale) !== null && _b !== void 0 ? _b : config === null || config === void 0 ? void 0 : config.inherit) !== null && _c !== void 0 ? _c : base === null || base === void 0 ? void 0 : base.locale) !== null && _d !== void 0 ? _d : inherited === null || inherited === void 0 ? void 0 : inherited.locale) !== null && _e !== void 0 ? _e : targetKey) !== null && _f !== void 0 ? _f : "custom";
33
- const result = {
34
- locale: resolvedLocale
35
- };
36
- if (base === null || base === void 0 ? void 0 : base.formatShort) {
37
- result.formatShort = base.formatShort;
38
- }
39
- if (base === null || base === void 0 ? void 0 : base.formatLong) {
40
- result.formatLong = base.formatLong;
41
- }
42
- if (inherited === null || inherited === void 0 ? void 0 : inherited.formatShort) {
43
- result.formatShort = inherited.formatShort;
44
- }
45
- if (inherited === null || inherited === void 0 ? void 0 : inherited.formatLong) {
46
- result.formatLong = inherited.formatLong;
47
- }
48
- if ((config === null || config === void 0 ? void 0 : config.formatShort) !== undefined) {
49
- result.formatShort = config.formatShort;
50
- }
51
- if ((config === null || config === void 0 ? void 0 : config.formatLong) !== undefined) {
52
- result.formatLong = config.formatLong;
53
- }
54
- if (!result.formatShort && !result.formatLong) {
55
- return (_g = base !== null && base !== void 0 ? base : inherited) !== null && _g !== void 0 ? _g : result;
56
- }
57
- return result;
58
- }
59
- registerSigLocalization({
60
- locale: "en",
61
- formatShort: ({ defaultText }) => defaultText,
62
- formatLong: ({ defaultText }) => defaultText
63
- });
64
- exports.registerSigTranslation = registerSigLocalization;
65
- exports.getRegisteredSigTranslations = getRegisteredSigLocalizations;
66
- function resolveSigTranslation(locale, config) {
67
- return resolveSigLocalization(locale, config);
68
- }
69
- function createThaiLocalization() {
70
- return {
71
- locale: "th",
72
- formatShort: ({ clause }) => formatShortThai(clause),
73
- formatLong: ({ clause, groupMealTimingsByRelation, includeTimesPerDaySummary }) => formatLongThai(clause, {
74
- groupMealTimingsByRelation,
75
- includeTimesPerDaySummary
76
- })
77
- };
78
- }
79
- registerSigLocalization(createThaiLocalization());
80
- // Thai formatting helpers
81
- const ROUTE_SHORT = {
82
- [types_1.RouteCode["Oral route"]]: "PO",
83
- [types_1.RouteCode["Sublingual route"]]: "SL",
84
- [types_1.RouteCode["Buccal route"]]: "BUC",
85
- [types_1.RouteCode["Respiratory tract route (qualifier value)"]]: "INH",
86
- [types_1.RouteCode["Nasal route"]]: "IN",
87
- [types_1.RouteCode["Topical route"]]: "TOP",
88
- [types_1.RouteCode["Transdermal route"]]: "TD",
89
- [types_1.RouteCode["Subcutaneous route"]]: "SC",
90
- [types_1.RouteCode["Intramuscular route"]]: "IM",
91
- [types_1.RouteCode["Intravenous route"]]: "IV",
92
- [types_1.RouteCode["Per rectum"]]: "PR",
93
- [types_1.RouteCode["Per vagina"]]: "PV",
94
- [types_1.RouteCode["Ophthalmic route"]]: "OPH",
95
- [types_1.RouteCode["Otic route"]]: "OT",
96
- [types_1.RouteCode["Intravitreal route (qualifier value)"]]: "IVT"
97
- };
98
- const WHEN_TEXT_THAI = {
99
- [types_1.EventTiming["Before Sleep"]]: "ก่อนนอน",
100
- [types_1.EventTiming["Before Meal"]]: "ก่อนอาหาร",
101
- [types_1.EventTiming["Before Breakfast"]]: "ก่อนอาหารเช้า",
102
- [types_1.EventTiming["Before Lunch"]]: "ก่อนอาหารกลางวัน",
103
- [types_1.EventTiming["Before Dinner"]]: "ก่อนอาหารเย็น",
104
- [types_1.EventTiming["After Meal"]]: "หลังอาหาร",
105
- [types_1.EventTiming["After Breakfast"]]: "หลังอาหารเช้า",
106
- [types_1.EventTiming["After Lunch"]]: "หลังอาหารกลางวัน",
107
- [types_1.EventTiming["After Dinner"]]: "หลังอาหารเย็น",
108
- [types_1.EventTiming.Meal]: "พร้อมอาหาร",
109
- [types_1.EventTiming.Breakfast]: "พร้อมอาหารเช้า",
110
- [types_1.EventTiming.Lunch]: "พร้อมอาหารกลางวัน",
111
- [types_1.EventTiming.Dinner]: "พร้อมอาหารเย็น",
112
- [types_1.EventTiming.Morning]: "ตอนเช้า",
113
- [types_1.EventTiming["Early Morning"]]: "เช้าตรู่",
114
- [types_1.EventTiming["Late Morning"]]: "สาย",
115
- [types_1.EventTiming.Noon]: "ตอนเที่ยง",
116
- [types_1.EventTiming.Afternoon]: "ตอนบ่าย",
117
- [types_1.EventTiming["Early Afternoon"]]: "บ่ายต้น",
118
- [types_1.EventTiming["Late Afternoon"]]: "บ่ายแก่",
119
- [types_1.EventTiming.Evening]: "ตอนเย็น",
120
- [types_1.EventTiming["Early Evening"]]: "หัวค่ำ",
121
- [types_1.EventTiming["Late Evening"]]: "ดึก",
122
- [types_1.EventTiming.Night]: "ตอนกลางคืน",
123
- [types_1.EventTiming.Wake]: "หลังตื่นนอน",
124
- [types_1.EventTiming["After Sleep"]]: "หลังจากนอน",
125
- [types_1.EventTiming.Immediate]: "ทันที"
126
- };
127
- const DAY_NAMES_THAI = {
128
- mon: "วันจันทร์",
129
- tue: "วันอังคาร",
130
- wed: "วันพุธ",
131
- thu: "วันพฤหัสบดี",
132
- fri: "วันศุกร์",
133
- sat: "วันเสาร์",
134
- sun: "วันอาทิตย์"
135
- };
136
- const TH_TIMES_PER_DAY = {
137
- 1: "วันละครั้ง",
138
- 2: "วันละ 2 ครั้ง",
139
- 3: "วันละ 3 ครั้ง",
140
- 4: "วันละ 4 ครั้ง"
141
- };
142
- const SLOWLY_QUALIFIER_CODE = "419443000";
143
- const EMPTY_STOMACH_QUALIFIER_CODE = "717154004";
144
- exports.THAI_SITE_TRANSLATIONS = {
145
- eye: "ตา",
146
- eyes: "ตา",
147
- "right eye": "ตาขวา",
148
- "left eye": "ตาซ้าย",
149
- "both eyes": "ตาทั้งสองข้าง",
150
- "bilateral eyes": "ตาทั้งสองข้าง",
151
- "right ear": "หูขวา",
152
- "left ear": "หูซ้าย",
153
- "both ears": "หูทั้งสองข้าง",
154
- "bilateral ears": "หูทั้งสองข้าง",
155
- ear: "หู",
156
- ears: "หูทั้งสองข้าง",
157
- nostril: "รูจมูก",
158
- nostrils: "รูจมูกทั้งสองข้าง",
159
- "right nostril": "รูจมูกขวา",
160
- "left nostril": "รูจมูกซ้าย",
161
- "both nostrils": "รูจมูกทั้งสองข้าง",
162
- "left naris": "รูจมูกซ้าย",
163
- "right naris": "รูจมูกขวา",
164
- nares: "รูจมูกทั้งสองข้าง",
165
- "anterior nares": "รูจมูกด้านหน้า",
166
- nose: "จมูก",
167
- mouth: "ปาก",
168
- tongue: "ลิ้น",
169
- tongues: "ลิ้น",
170
- "right arm": "แขนขวา",
171
- "left arm": "แขนซ้าย",
172
- "both arms": "แขนทั้งสองข้าง",
173
- arm: "แขน",
174
- "upper arm": "ต้นแขน",
175
- "left upper arm": "ต้นแขนซ้าย",
176
- "right upper arm": "ต้นแขนขวา",
177
- "bilateral arms": "แขนทั้งสองข้าง",
178
- shoulder: "ไหล่",
179
- shoulders: "ไหล่ทั้งสองข้าง",
180
- "left shoulder": "ไหล่ซ้าย",
181
- "right shoulder": "ไหล่ขวา",
182
- elbow: "ข้อศอก",
183
- "left elbow": "ข้อศอกซ้าย",
184
- "right elbow": "ข้อศอกขวา",
185
- "right leg": "ขาขวา",
186
- "left leg": "ขาซ้าย",
187
- "both legs": "ขาทั้งสองข้าง",
188
- leg: "ขา",
189
- "lower leg": "ขาส่วนล่าง",
190
- "left lower leg": "ขาส่วนล่างซ้าย",
191
- "right lower leg": "ขาส่วนล่างขวา",
192
- "bilateral legs": "ขาทั้งสองข้าง",
193
- knee: "เข่า",
194
- "left knee": "เข่าซ้าย",
195
- "right knee": "เข่าขวา",
196
- "both knees": "เข่าทั้งสองข้าง",
197
- "bilateral knees": "เข่าทั้งสองข้าง",
198
- wrist: "ข้อมือ",
199
- "left wrist": "ข้อมือซ้าย",
200
- "right wrist": "ข้อมือขวา",
201
- ankle: "ข้อเท้า",
202
- "left ankle": "ข้อเท้าซ้าย",
203
- "right ankle": "ข้อเท้าขวา",
204
- "both ankles": "ข้อเท้าทั้งสองข้าง",
205
- "bilateral ankles": "ข้อเท้าทั้งสองข้าง",
206
- hip: "สะโพก",
207
- "left hip": "สะโพกซ้าย",
208
- "right hip": "สะโพกขวา",
209
- "right hand": "มือขวา",
210
- "left hand": "มือซ้าย",
211
- "both hands": "มือทั้งสองข้าง",
212
- hand: "มือ",
213
- hands: "มือทั้งสองข้าง",
214
- "right foot": "เท้าขวา",
215
- "left foot": "เท้าซ้าย",
216
- "both feet": "เท้าทั้งสองข้าง",
217
- foot: "เท้า",
218
- feet: "เท้า",
219
- abdomen: "ช่องท้อง",
220
- abdominal: "ช่องท้อง",
221
- belly: "ท้อง",
222
- "affected area": "บริเวณที่เป็น",
223
- "affected site": "บริเวณที่เป็น",
224
- "บริเวณที่เป็น": "บริเวณที่เป็น",
225
- head: "ศีรษะ",
226
- "left head": "ศีรษะซ้าย",
227
- "left side of head": "ศีรษะซ้าย",
228
- "right head": "ศีรษะขวา",
229
- "right side of head": "ศีรษะขวา",
230
- back: "แผ่นหลัง",
231
- chest: "ทรวงอก",
232
- "chest wall": "ผนังทรวงอก",
233
- breast: "เต้านม",
234
- "left breast": "เต้านมซ้าย",
235
- "right breast": "เต้านมขวา",
236
- "both breasts": "เต้านมทั้งสองข้าง",
237
- "bilateral breasts": "เต้านมทั้งสองข้าง",
238
- axilla: "รักแร้",
239
- axillae: "รักแร้ทั้งสองข้าง",
240
- armpit: "รักแร้",
241
- armpits: "รักแร้ทั้งสองข้าง",
242
- groin: "ขาหนีบ",
243
- scalp: "หนังศีรษะ",
244
- face: "ใบหน้า",
245
- cheek: "แก้ม",
246
- cheeks: "แก้มทั้งสองข้าง",
247
- forehead: "หน้าผาก",
248
- temple: "ขมับ",
249
- "temple region": "ขมับ",
250
- "temporal region": "ขมับ",
251
- temples: "ขมับทั้งสองข้าง",
252
- "left temple": "ขมับซ้าย",
253
- "left temple region": "ขมับซ้าย",
254
- "left temporal region": "ขมับซ้าย",
255
- "right temple": "ขมับขวา",
256
- "right temple region": "ขมับขวา",
257
- "right temporal region": "ขมับขวา",
258
- "both temples": "ขมับทั้งสองข้าง",
259
- "bilateral temples": "ขมับทั้งสองข้าง",
260
- chin: "คาง",
261
- neck: "คอ",
262
- eyelid: "เปลือกตา",
263
- eyelids: "เปลือกตา",
264
- lip: "ริมฝีปาก",
265
- lips: "ริมฝีปาก",
266
- forearm: "ปลายแขน",
267
- "left forearm": "ปลายแขนซ้าย",
268
- "right forearm": "ปลายแขนขวา",
269
- thigh: "ต้นขา",
270
- thighs: "ต้นขาทั้งสองข้าง",
271
- "left thigh": "ต้นขาซ้าย",
272
- "right thigh": "ต้นขาขวา",
273
- gum: "เหงือก",
274
- gums: "เหงือก",
275
- tooth: "ฟัน",
276
- teeth: "ฟัน",
277
- buttock: "สะโพก",
278
- buttocks: "สะโพกทั้งสองข้าง",
279
- gluteal: "สะโพก",
280
- glute: "สะโพก",
281
- "left buttock": "สะโพกซ้าย",
282
- "left gluteal": "สะโพกซ้าย",
283
- "right buttock": "สะโพกขวา",
284
- "right gluteal": "สะโพกขวา",
285
- muscle: "กล้ามเนื้อ",
286
- muscles: "กล้ามเนื้อทั้งหมด",
287
- vein: "หลอดเลือดดำ",
288
- veins: "หลอดเลือดดำทั้งหมด",
289
- vagina: "ช่องคลอด",
290
- vaginal: "บริเวณช่องคลอด",
291
- penis: "อวัยวะเพศชาย",
292
- penile: "บริเวณอวัยวะเพศชาย",
293
- rectum: "ไส้ตรง",
294
- rectal: "บริเวณทวารหนัก",
295
- anus: "ทวารหนัก",
296
- perineum: "ฝีเย็บ",
297
- skin: "ผิวหนัง",
298
- hair: "เส้นผม"
299
- };
300
- const THAI_SITE_CODE_TRANSLATIONS = (() => {
301
- var _a;
302
- const translations = {};
303
- for (const { names, definition } of maps_1.DEFAULT_BODY_SITE_SNOMED_SOURCE) {
304
- const code = (_a = definition.coding) === null || _a === void 0 ? void 0 : _a.code;
305
- if (!code || translations[code]) {
306
- continue;
307
- }
308
- let translated;
309
- for (const name of names) {
310
- const candidate = exports.THAI_SITE_TRANSLATIONS[(0, maps_1.normalizeBodySiteKey)(name)];
311
- if (candidate) {
312
- translated = candidate;
313
- break;
314
- }
315
- }
316
- if (translated) {
317
- translations[code] = translated;
318
- }
319
- }
320
- return translations;
321
- })();
322
- const DEFAULT_THAI_ROUTE_GRAMMAR = { verb: "ใช้" };
323
- const THAI_ROUTE_GRAMMAR = {
324
- [types_1.RouteCode["Oral route"]]: { verb: "รับประทาน", routePhrase: "ทางปาก" },
325
- [types_1.RouteCode["Sublingual route"]]: { verb: "อมใต้ลิ้น", routePhrase: "ใต้ลิ้น" },
326
- [types_1.RouteCode["Buccal route"]]: { verb: "อมกระพุ้งแก้ม", routePhrase: "ที่กระพุ้งแก้ม" },
327
- [types_1.RouteCode["Respiratory tract route (qualifier value)"]]: {
328
- verb: "สูด",
329
- sitePreposition: "ที่"
330
- },
331
- [types_1.RouteCode["Nasal route"]]: {
332
- verb: "พ่น",
333
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "ทางจมูก"),
334
- sitePreposition: "ที่"
335
- },
336
- [types_1.RouteCode["Topical route"]]: {
337
- verb: "ทา",
338
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "บริเวณผิวหนัง"),
339
- sitePreposition: "บริเวณ"
340
- },
341
- [types_1.RouteCode["Transdermal route"]]: {
342
- verb: "ติด",
343
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "แบบแผ่นแปะผิวหนัง"),
344
- sitePreposition: "บริเวณ"
345
- },
346
- [types_1.RouteCode["Subcutaneous route"]]: {
347
- verb: "ฉีด",
348
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "เข้าใต้ผิวหนัง"),
349
- sitePreposition: "ที่"
350
- },
351
- [types_1.RouteCode["Intramuscular route"]]: {
352
- verb: "ฉีด",
353
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "เข้ากล้ามเนื้อ"),
354
- sitePreposition: "ที่"
355
- },
356
- [types_1.RouteCode["Intravenous route"]]: {
357
- verb: "ฉีด",
358
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "เข้าหลอดเลือดดำ"),
359
- sitePreposition: "ที่"
360
- },
361
- [types_1.RouteCode["Per rectum"]]: {
362
- verb: "สอด",
363
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "ทางทวารหนัก"),
364
- sitePreposition: "ที่"
365
- },
366
- [types_1.RouteCode["Per vagina"]]: {
367
- verb: "สอด",
368
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "ทางช่องคลอด"),
369
- sitePreposition: "ที่"
370
- },
371
- [types_1.RouteCode["Ophthalmic route"]]: {
372
- verb: "หยอด",
373
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "ที่ดวงตา"),
374
- sitePreposition: "ที่"
375
- },
376
- [types_1.RouteCode["Otic route"]]: {
377
- verb: "หยอด",
378
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "ที่หู"),
379
- sitePreposition: "ที่"
380
- },
381
- [types_1.RouteCode["Intravitreal route (qualifier value)"]]: {
382
- verb: "ฉีด",
383
- routePhrase: ({ hasSite }) => (hasSite ? undefined : "เข้าดวงตา"),
384
- sitePreposition: "ที่"
385
- }
386
- };
387
- const THAI_METHOD_TEXT_VERBS = {
388
- Apply: "ทา",
389
- "Apply sunscreen": "ทากันแดด",
390
- Dab: "แต้ม",
391
- Drink: "รับประทาน",
392
- Insert: "สอด",
393
- Instill: "หยอด",
394
- Massage: "นวด",
395
- Reapply: "ทาซ้ำ",
396
- "Reapply sunscreen": "ทากันแดดซ้ำ",
397
- Rub: "ถู",
398
- Spray: "พ่น",
399
- Shampoo: "สระ",
400
- Swallow: "รับประทาน",
401
- Take: "รับประทาน",
402
- "Use shampoo": "สระ",
403
- Wash: "ล้าง"
404
- };
405
- const THAI_IMPLIED_OBJECT_VERBS = new Set([
406
- "ทา",
407
- "ทาซ้ำ",
408
- "แต้ม",
409
- "ถู",
410
- "นวด",
411
- "พ่น",
412
- "หยอด",
413
- "สอด",
414
- "ล้าง",
415
- "สระ"
416
- ]);
417
- const THAI_SUPPRESSIBLE_ROUTE_VERBS = new Set([
418
- "ทา",
419
- "ทากันแดด",
420
- "ทาซ้ำ",
421
- "ทากันแดดซ้ำ",
422
- "แต้ม",
423
- "ถู",
424
- "นวด",
425
- "ล้าง",
426
- "สระ"
427
- ]);
428
- const THAI_SITE_FIRST_VERBS = new Set([
429
- "ทา",
430
- "ทากันแดด",
431
- "ทาซ้ำ",
432
- "ทากันแดดซ้ำ",
433
- "แต้ม",
434
- "ถู",
435
- "นวด",
436
- "ล้าง",
437
- "สระ",
438
- "พ่น"
439
- ]);
440
- function resolveThaiMethodVerb(clause, grammar) {
441
- var _a, _b, _c, _d, _e;
442
- const translatedText = (0, fhir_translations_1.getPrimitiveTranslation)((_a = clause.method) === null || _a === void 0 ? void 0 : _a._text, "th");
443
- if (translatedText) {
444
- return translatedText;
445
- }
446
- const methodText = (_c = (_b = clause.method) === null || _b === void 0 ? void 0 : _b.text) === null || _c === void 0 ? void 0 : _c.trim();
447
- if (methodText) {
448
- const overridden = THAI_METHOD_TEXT_VERBS[methodText];
449
- if (overridden) {
450
- return overridden;
451
- }
452
- }
453
- const translatedDisplay = (0, fhir_translations_1.getPrimitiveTranslation)((_e = (_d = clause.method) === null || _d === void 0 ? void 0 : _d.coding) === null || _e === void 0 ? void 0 : _e._display, "th");
454
- if (translatedDisplay) {
455
- return translatedDisplay;
456
- }
457
- return grammar.verb;
458
- }
459
- function joinThaiVerbAndBody(verb, body) {
460
- const trimmedBody = body.trim();
461
- if (!trimmedBody) {
462
- return verb;
463
- }
464
- switch (verb) {
465
- case "พ่น":
466
- if (trimmedBody.startsWith("เข้า")) {
467
- return `${verb}${trimmedBody}`;
468
- }
469
- break;
470
- case "ทาซ้ำ":
471
- case "ทากันแดดซ้ำ":
472
- case "สระ":
473
- if (trimmedBody.startsWith("ทุก") ||
474
- trimmedBody.startsWith("วัน") ||
475
- trimmedBody.startsWith("ก่อน") ||
476
- trimmedBody.startsWith("หลัง")) {
477
- return `${verb}${trimmedBody}`;
478
- }
479
- break;
480
- default:
481
- break;
482
- }
483
- return `${verb} ${trimmedBody}`;
484
- }
485
- function shouldUseGenericMedicationObjectThai(clause, verb, explicitDosePart) {
486
- var _a;
487
- if (explicitDosePart) {
488
- return false;
489
- }
490
- if (THAI_IMPLIED_OBJECT_VERBS.has(verb)) {
491
- return false;
492
- }
493
- switch ((_a = clause.route) === null || _a === void 0 ? void 0 : _a.code) {
494
- case types_1.RouteCode["Topical route"]:
495
- case types_1.RouteCode["Transdermal route"]:
496
- case types_1.RouteCode["Nasal route"]:
497
- case types_1.RouteCode["Ophthalmic route"]:
498
- case types_1.RouteCode["Otic route"]:
499
- case types_1.RouteCode["Per rectum"]:
500
- case types_1.RouteCode["Per vagina"]:
501
- return false;
502
- default:
503
- return true;
504
- }
505
- }
506
- function shouldSuppressRoutePhraseThai(clause, verb, hasSite, explicitDosePart) {
507
- var _a;
508
- if (hasSite || explicitDosePart) {
509
- return false;
510
- }
511
- if (!THAI_SUPPRESSIBLE_ROUTE_VERBS.has(verb)) {
512
- return false;
513
- }
514
- switch ((_a = clause.route) === null || _a === void 0 ? void 0 : _a.code) {
515
- case types_1.RouteCode["Topical route"]:
516
- case types_1.RouteCode["Transdermal route"]:
517
- return true;
518
- default:
519
- return false;
520
- }
521
- }
522
- function scheduleOf(clause) {
523
- var _a;
524
- return (_a = clause.schedule) !== null && _a !== void 0 ? _a : {};
525
- }
526
- function resolveRouteGrammarThai(clause) {
527
- var _a, _b, _c, _d, _e, _f;
528
- const routeCode = (_a = clause.route) === null || _a === void 0 ? void 0 : _a.code;
529
- if (routeCode && THAI_ROUTE_GRAMMAR[routeCode]) {
530
- return (_b = THAI_ROUTE_GRAMMAR[routeCode]) !== null && _b !== void 0 ? _b : DEFAULT_THAI_ROUTE_GRAMMAR;
531
- }
532
- const grammar = grammarFromRouteTextThai((_c = clause.route) === null || _c === void 0 ? void 0 : _c.text);
533
- if (grammar) {
534
- return grammar;
535
- }
536
- if (((_e = (_d = clause.dose) === null || _d === void 0 ? void 0 : _d.unit) === null || _e === void 0 ? void 0 : _e.trim().toLowerCase()) === "puff") {
537
- return ((_f = THAI_ROUTE_GRAMMAR[types_1.RouteCode["Respiratory tract route (qualifier value)"]]) !== null && _f !== void 0 ? _f : DEFAULT_THAI_ROUTE_GRAMMAR);
538
- }
539
- return DEFAULT_THAI_ROUTE_GRAMMAR;
540
- }
541
- function grammarFromRouteTextThai(text) {
542
- if (!text) {
543
- return undefined;
544
- }
545
- const normalized = text.trim().toLowerCase();
546
- if (!normalized) {
547
- return undefined;
548
- }
549
- if (normalized.includes("mouth") || normalized.includes("oral")) {
550
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Oral route"]];
551
- }
552
- if (normalized.includes("ophthalm")) {
553
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Ophthalmic route"]];
554
- }
555
- if (normalized.includes("intravitreal")) {
556
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Intravitreal route (qualifier value)"]];
557
- }
558
- if (normalized.includes("topical")) {
559
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Topical route"]];
560
- }
561
- if (normalized.includes("transdermal")) {
562
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Transdermal route"]];
563
- }
564
- if (normalized.includes("subcutaneous") || normalized === "sc" || normalized === "sq") {
565
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Subcutaneous route"]];
566
- }
567
- if (normalized.includes("intramuscular") || normalized === "im") {
568
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Intramuscular route"]];
569
- }
570
- if (normalized.includes("intravenous") || normalized === "iv") {
571
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Intravenous route"]];
572
- }
573
- if (normalized.includes("rectal") || normalized.includes("rectum")) {
574
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Per rectum"]];
575
- }
576
- if (normalized.includes("vagin")) {
577
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Per vagina"]];
578
- }
579
- if (normalized.includes("nasal")) {
580
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Nasal route"]];
581
- }
582
- if (normalized.includes("inhal")) {
583
- return THAI_ROUTE_GRAMMAR[types_1.RouteCode["Respiratory tract route (qualifier value)"]];
584
- }
585
- return undefined;
586
- }
587
- function formatDoseThaiShort(dose) {
588
- if (!dose) {
589
- return undefined;
590
- }
591
- if (dose.range) {
592
- if (dose.range.low !== undefined && dose.range.high !== undefined) {
593
- const base = `${stripTrailingZero(dose.range.low)}-${stripTrailingZero(dose.range.high)}`;
594
- if (dose.unit) {
595
- return `${base} ${formatUnitThai(dose.unit, dose.range.high, "short")}`;
596
- }
597
- return base;
598
- }
599
- if (dose.range.low !== undefined) {
600
- const base = `>=${stripTrailingZero(dose.range.low)}`;
601
- if (dose.unit) {
602
- return `${base} ${formatUnitThai(dose.unit, dose.range.low, "short")}`;
603
- }
604
- return base;
605
- }
606
- if (dose.range.high !== undefined) {
607
- const base = `<=${stripTrailingZero(dose.range.high)}`;
608
- if (dose.unit) {
609
- return `${base} ${formatUnitThai(dose.unit, dose.range.high, "short")}`;
610
- }
611
- return base;
612
- }
613
- }
614
- if (dose.value !== undefined) {
615
- if (dose.unit) {
616
- return `${stripTrailingZero(dose.value)} ${formatUnitThai(dose.unit, dose.value, "short")}`;
617
- }
618
- return stripTrailingZero(dose.value);
619
- }
620
- return undefined;
621
- }
622
- function formatDoseThaiLong(dose) {
623
- if (!dose) {
624
- return undefined;
625
- }
626
- if (dose.range) {
627
- if (dose.range.low !== undefined && dose.range.high !== undefined) {
628
- if (dose.unit) {
629
- return `ครั้งละ ${stripTrailingZero(dose.range.low)} ถึง ${stripTrailingZero(dose.range.high)} ${formatUnitThai(dose.unit, dose.range.high, "long")}`;
630
- }
631
- return `ครั้งละ ${stripTrailingZero(dose.range.low)} ถึง ${stripTrailingZero(dose.range.high)}`;
632
- }
633
- if (dose.range.low !== undefined) {
634
- if (dose.unit) {
635
- return `ครั้งละ อย่างน้อย ${stripTrailingZero(dose.range.low)} ${formatUnitThai(dose.unit, dose.range.low, "long")}`;
636
- }
637
- return `ครั้งละ อย่างน้อย ${stripTrailingZero(dose.range.low)}`;
638
- }
639
- if (dose.range.high !== undefined) {
640
- if (dose.unit) {
641
- return `ครั้งละ ไม่เกิน ${stripTrailingZero(dose.range.high)} ${formatUnitThai(dose.unit, dose.range.high, "long")}`;
642
- }
643
- return `ครั้งละ ไม่เกิน ${stripTrailingZero(dose.range.high)}`;
644
- }
645
- }
646
- if (dose.value !== undefined) {
647
- if (dose.unit) {
648
- return `ครั้งละ ${stripTrailingZero(dose.value)} ${formatUnitThai(dose.unit, dose.value, "long")}`;
649
- }
650
- return `ครั้งละ ${stripTrailingZero(dose.value)}`;
651
- }
652
- return undefined;
653
- }
654
- function formatUnitThai(unit, _value, style) {
655
- const lower = unit.toLowerCase();
656
- const mapping = {
657
- tab: { short: "เม็ด", long: "เม็ด" },
658
- tablet: { short: "เม็ด", long: "เม็ด" },
659
- cap: { short: "แคปซูล", long: "แคปซูล" },
660
- capsule: { short: "แคปซูล", long: "แคปซูล" },
661
- ml: { short: "มล.", long: "มิลลิลิตร" },
662
- milliliter: { short: "มล.", long: "มิลลิลิตร" },
663
- milliliters: { short: "มล.", long: "มิลลิลิตร" },
664
- mg: { short: "มก.", long: "มิลลิกรัม" },
665
- mcg: { short: "ไมโครกรัม", long: "ไมโครกรัม" },
666
- ug: { short: "ไมโครกรัม", long: "ไมโครกรัม" },
667
- puff: { short: "พัฟ", long: "พัฟ" },
668
- puffs: { short: "พัฟ", long: "พัฟ" },
669
- spray: { short: "พ่น", long: "พ่น" },
670
- sprays: { short: "พ่น", long: "พ่น" },
671
- drop: { short: "หยด", long: "หยด" },
672
- drops: { short: "หยด", long: "หยด" },
673
- patch: { short: "แผ่น", long: "แผ่นแปะ" },
674
- patches: { short: "แผ่น", long: "แผ่นแปะ" },
675
- suppository: { short: "ยาเหน็บ", long: "ยาเหน็บ" },
676
- suppositories: { short: "ยาเหน็บ", long: "ยาเหน็บ" }
677
- };
678
- const entry = mapping[lower];
679
- return entry ? entry[style] : unit;
680
- }
681
- function describeFrequencyThai(schedule) {
682
- var _a;
683
- const frequency = schedule === null || schedule === void 0 ? void 0 : schedule.frequency;
684
- const frequencyMax = schedule === null || schedule === void 0 ? void 0 : schedule.frequencyMax;
685
- const period = schedule === null || schedule === void 0 ? void 0 : schedule.period;
686
- const periodMax = schedule === null || schedule === void 0 ? void 0 : schedule.periodMax;
687
- const periodUnit = schedule === null || schedule === void 0 ? void 0 : schedule.periodUnit;
688
- const timingCode = schedule === null || schedule === void 0 ? void 0 : schedule.timingCode;
689
- if (frequency !== undefined &&
690
- frequencyMax !== undefined &&
691
- periodUnit === types_1.FhirPeriodUnit.Day &&
692
- (!period || period === 1)) {
693
- if (frequency === 1 && frequencyMax === 1) {
694
- return "วันละครั้ง";
695
- }
696
- if (frequency === 1 && frequencyMax === 2) {
697
- return "วันละ 1 ถึง 2 ครั้ง";
698
- }
699
- return `วันละ ${stripTrailingZero(frequency)} ถึง ${stripTrailingZero(frequencyMax)} ครั้ง`;
700
- }
701
- if (frequency && periodUnit === types_1.FhirPeriodUnit.Day && (!period || period === 1)) {
702
- return (_a = TH_TIMES_PER_DAY[frequency]) !== null && _a !== void 0 ? _a : `วันละ ${stripTrailingZero(frequency)} ครั้ง`;
703
- }
704
- if (periodUnit === types_1.FhirPeriodUnit.Minute && period) {
705
- if (periodMax && periodMax !== period) {
706
- return `ทุก ${stripTrailingZero(period)} ถึง ${stripTrailingZero(periodMax)} นาที`;
707
- }
708
- return `ทุก ${stripTrailingZero(period)} นาที`;
709
- }
710
- if (periodUnit === types_1.FhirPeriodUnit.Hour && period) {
711
- if (periodMax && periodMax !== period) {
712
- return `ทุก ${stripTrailingZero(period)} ถึง ${stripTrailingZero(periodMax)} ชั่วโมง`;
713
- }
714
- return `ทุก ${stripTrailingZero(period)} ชั่วโมง`;
715
- }
716
- if (periodUnit === types_1.FhirPeriodUnit.Day && period && period !== 1) {
717
- if (period === 2 && (!periodMax || periodMax === 2)) {
718
- return "วันเว้นวัน";
719
- }
720
- if (periodMax && periodMax !== period) {
721
- return `ทุก ${stripTrailingZero(period)} ถึง ${stripTrailingZero(periodMax)} วัน`;
722
- }
723
- return `ทุก ${stripTrailingZero(period)} วัน`;
724
- }
725
- if (periodUnit === types_1.FhirPeriodUnit.Week && period) {
726
- if (period === 1 && (!periodMax || periodMax === 1)) {
727
- return "สัปดาห์ละครั้ง";
728
- }
729
- if (periodMax && periodMax !== period) {
730
- return `ทุก ${stripTrailingZero(period)} ถึง ${stripTrailingZero(periodMax)} สัปดาห์`;
731
- }
732
- return `ทุก ${stripTrailingZero(period)} สัปดาห์`;
733
- }
734
- if (periodUnit === types_1.FhirPeriodUnit.Month && period) {
735
- if (period === 1 && (!periodMax || periodMax === 1)) {
736
- return "เดือนละครั้ง";
737
- }
738
- if (periodMax && periodMax !== period) {
739
- return `ทุก ${stripTrailingZero(period)} ถึง ${stripTrailingZero(periodMax)} เดือน`;
740
- }
741
- return `ทุก ${stripTrailingZero(period)} เดือน`;
742
- }
743
- if (periodUnit === types_1.FhirPeriodUnit.Year && period) {
744
- if (period === 1 && (!periodMax || periodMax === 1)) {
745
- return "ปีละครั้ง";
746
- }
747
- if (periodMax && periodMax !== period) {
748
- return `ทุก ${stripTrailingZero(period)} ถึง ${stripTrailingZero(periodMax)} ปี`;
749
- }
750
- return `ทุก ${stripTrailingZero(period)} ปี`;
751
- }
752
- if (timingCode) {
753
- const map = {
754
- BID: "วันละ 2 ครั้ง",
755
- TID: "วันละ 3 ครั้ง",
756
- QID: "วันละ 4 ครั้ง",
757
- QD: "วันละครั้ง",
758
- QOD: "วันเว้นวัน",
759
- Q6H: "ทุก 6 ชั่วโมง",
760
- Q8H: "ทุก 8 ชั่วโมง",
761
- WK: "สัปดาห์ละครั้ง",
762
- MO: "เดือนละครั้ง"
763
- };
764
- const value = map[timingCode.toUpperCase()];
765
- if (value) {
766
- return value;
767
- }
768
- }
769
- if (frequency && periodUnit === undefined && period === undefined) {
770
- if (frequency === 1) {
771
- return "ครั้งเดียว";
772
- }
773
- return `${stripTrailingZero(frequency)} ครั้ง`;
774
- }
775
- return undefined;
776
- }
777
- function describeFrequencyCountThai(count) {
778
- var _a;
779
- if (!count || count <= 0) {
780
- return undefined;
781
- }
782
- return (_a = TH_TIMES_PER_DAY[count]) !== null && _a !== void 0 ? _a : `วันละ ${stripTrailingZero(count)} ครั้ง`;
783
- }
784
- function describeStandaloneOccurrenceCountThai(schedule) {
785
- var _a, _b, _c;
786
- const count = schedule === null || schedule === void 0 ? void 0 : schedule.count;
787
- if (!count || count <= 0) {
788
- return undefined;
789
- }
790
- if ((schedule === null || schedule === void 0 ? void 0 : schedule.frequency) !== undefined ||
791
- (schedule === null || schedule === void 0 ? void 0 : schedule.frequencyMax) !== undefined ||
792
- (schedule === null || schedule === void 0 ? void 0 : schedule.period) !== undefined ||
793
- (schedule === null || schedule === void 0 ? void 0 : schedule.periodMax) !== undefined ||
794
- (schedule === null || schedule === void 0 ? void 0 : schedule.periodUnit) !== undefined ||
795
- ((_a = schedule === null || schedule === void 0 ? void 0 : schedule.dayOfWeek) === null || _a === void 0 ? void 0 : _a.length) ||
796
- ((_b = schedule === null || schedule === void 0 ? void 0 : schedule.when) === null || _b === void 0 ? void 0 : _b.length) ||
797
- ((_c = schedule === null || schedule === void 0 ? void 0 : schedule.timeOfDay) === null || _c === void 0 ? void 0 : _c.length) ||
798
- (schedule === null || schedule === void 0 ? void 0 : schedule.duration) !== undefined ||
799
- (schedule === null || schedule === void 0 ? void 0 : schedule.durationMax) !== undefined ||
800
- (schedule === null || schedule === void 0 ? void 0 : schedule.durationUnit) !== undefined ||
801
- (schedule === null || schedule === void 0 ? void 0 : schedule.timingCode)) {
802
- return undefined;
803
- }
804
- return `${stripTrailingZero(count)} ครั้ง`;
805
- }
806
- function joinMealNamesThai(parts) {
807
- if (!parts.length) {
808
- return "";
809
- }
810
- if (parts.length === 1) {
811
- return parts[0];
812
- }
813
- if (parts.length === 2) {
814
- return `${parts[0]} และ${parts[1]}`;
815
- }
816
- let text = parts[0];
817
- for (let i = 1; i < parts.length - 1; i += 1) {
818
- text += ` ${parts[i]}`;
819
- }
820
- return `${text} และ${parts[parts.length - 1]}`;
821
- }
822
- function summarizeMealTimingGroupThai(group) {
823
- const relationText = {
824
- before: "ก่อนอาหาร",
825
- after: "หลังอาหาร",
826
- with: "พร้อมอาหาร"
827
- };
828
- const mealText = {
829
- breakfast: "เช้า",
830
- lunch: "กลางวัน",
831
- dinner: "เย็น"
832
- };
833
- const meals = [];
834
- for (const meal of group.meals) {
835
- meals.push(mealText[meal]);
836
- }
837
- return `${relationText[group.relation]}${joinMealNamesThai(meals)}`;
838
- }
839
- function collectWhenPhrasesThai(schedule, options) {
840
- var _a;
841
- const when = (_a = schedule === null || schedule === void 0 ? void 0 : schedule.when) !== null && _a !== void 0 ? _a : [];
842
- if (!when.length) {
843
- return [];
844
- }
845
- const unique = [];
846
- const seen = new Set();
847
- let hasSpecificAfter = false;
848
- let hasSpecificBefore = false;
849
- let hasSpecificWith = false;
850
- for (const code of when) {
851
- if (!seen.has(code)) {
852
- seen.add(code);
853
- unique.push(code);
854
- if (code === types_1.EventTiming["After Breakfast"] ||
855
- code === types_1.EventTiming["After Lunch"] ||
856
- code === types_1.EventTiming["After Dinner"]) {
857
- hasSpecificAfter = true;
858
- }
859
- if (code === types_1.EventTiming["Before Breakfast"] ||
860
- code === types_1.EventTiming["Before Lunch"] ||
861
- code === types_1.EventTiming["Before Dinner"]) {
862
- hasSpecificBefore = true;
863
- }
864
- if (code === types_1.EventTiming.Breakfast || code === types_1.EventTiming.Lunch || code === types_1.EventTiming.Dinner) {
865
- hasSpecificWith = true;
866
- }
867
- }
868
- }
869
- const filtered = [];
870
- for (const code of unique) {
871
- if (code === types_1.EventTiming["After Meal"] && hasSpecificAfter) {
872
- continue;
873
- }
874
- if (code === types_1.EventTiming["Before Meal"] && hasSpecificBefore) {
875
- continue;
876
- }
877
- if (code === types_1.EventTiming.Meal && hasSpecificWith) {
878
- continue;
879
- }
880
- filtered.push(code);
881
- }
882
- const mealGroup = (0, timing_summary_1.getMealTimingGroup)(filtered, options);
883
- if (!mealGroup) {
884
- const phrases = [];
885
- for (const code of filtered) {
886
- const text = WHEN_TEXT_THAI[code];
887
- if (text) {
888
- phrases.push(text);
889
- }
890
- }
891
- return phrases;
892
- }
893
- const groupedCodes = new Set(mealGroup.codes);
894
- const phrases = [];
895
- let insertedGroup = false;
896
- for (const code of filtered) {
897
- if (groupedCodes.has(code)) {
898
- if (!insertedGroup) {
899
- phrases.push(summarizeMealTimingGroupThai(mealGroup));
900
- insertedGroup = true;
901
- }
902
- continue;
903
- }
904
- const text = WHEN_TEXT_THAI[code];
905
- if (text) {
906
- phrases.push(text);
907
- }
908
- }
909
- return phrases;
910
- }
911
- function joinWithAndThai(parts) {
912
- if (!parts.length) {
913
- return "";
914
- }
915
- if (parts.length === 1) {
916
- return parts[0];
917
- }
918
- if (parts.length === 2) {
919
- return `${parts[0]} และ ${parts[1]}`;
920
- }
921
- return `${parts.slice(0, -1).join(", ")} และ ${parts[parts.length - 1]}`;
922
- }
923
- function combineFrequencyAndEventsThai(frequency, events) {
924
- if (!frequency) {
925
- if (!events.length) {
926
- return {};
927
- }
928
- return { event: joinWithAndThai(events) };
929
- }
930
- if (!events.length) {
931
- return { frequency };
932
- }
933
- if (events.length === 1 && events[0] === "ก่อนนอน" && frequency.includes("วันละ")) {
934
- return { frequency: `${frequency} และ ${events[0]}` };
935
- }
936
- return { frequency, event: joinWithAndThai(events) };
937
- }
938
- function isOralRouteThai(clause) {
939
- var _a, _b, _c;
940
- if (((_a = clause.route) === null || _a === void 0 ? void 0 : _a.code) === types_1.RouteCode["Oral route"]) {
941
- return true;
942
- }
943
- const text = (_c = (_b = clause.route) === null || _b === void 0 ? void 0 : _b.text) === null || _c === void 0 ? void 0 : _c.trim().toLowerCase();
944
- if (!text) {
945
- return false;
946
- }
947
- return text === "po" || text === "oral" || text.includes("mouth") || text.includes("per os");
948
- }
949
- function buildRoutePhraseThai(clause, grammar, hasSite) {
950
- var _a, _b;
951
- if (grammar.verb === "รับประทาน" && isOralRouteThai(clause)) {
952
- return undefined;
953
- }
954
- if (typeof grammar.routePhrase === "function") {
955
- return grammar.routePhrase({ hasSite, clause });
956
- }
957
- if (typeof grammar.routePhrase === "string") {
958
- return grammar.routePhrase;
959
- }
960
- const text = (_b = (_a = clause.route) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.trim();
961
- if (!text) {
962
- return undefined;
963
- }
964
- const normalized = text.toLowerCase();
965
- if (normalized.startsWith("by ") || normalized.startsWith("per ") || normalized.startsWith("via ")) {
966
- return text;
967
- }
968
- if (normalized === "oral") {
969
- return "ทางปาก";
970
- }
971
- if (normalized === "intravenous") {
972
- return "เข้าหลอดเลือดดำ";
973
- }
974
- if (normalized === "intramuscular") {
975
- return "เข้ากล้ามเนื้อ";
976
- }
977
- if (normalized === "subcutaneous") {
978
- return "เข้าใต้ผิวหนัง";
979
- }
980
- if (normalized === "topical") {
981
- return "บริเวณผิวหนัง";
982
- }
983
- if (normalized === "transdermal") {
984
- return "แบบแผ่นแปะผิวหนัง";
985
- }
986
- if (normalized === "intranasal" || normalized === "nasal") {
987
- return "ทางจมูก";
988
- }
989
- if (normalized.includes("inhal")) {
990
- return undefined;
991
- }
992
- return text;
993
- }
994
- function formatSiteThai(clause, grammar) {
995
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
996
- const text = ((_b = (_a = clause.site) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b.trim()) || ((_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());
997
- const lower = text === null || text === void 0 ? void 0 : text.toLowerCase();
998
- const codingCode = (_g = (_f = clause.site) === null || _f === void 0 ? void 0 : _f.coding) === null || _g === void 0 ? void 0 : _g.code;
999
- const routeText = (_j = (_h = clause.route) === null || _h === void 0 ? void 0 : _h.text) === null || _j === void 0 ? void 0 : _j.trim().toLowerCase();
1000
- const isRectalRoute = ((_k = clause.route) === null || _k === void 0 ? void 0 : _k.code) === types_1.RouteCode["Per rectum"] ||
1001
- routeText === "rectum" ||
1002
- routeText === "rectal";
1003
- const isVaginalRoute = ((_l = clause.route) === null || _l === void 0 ? void 0 : _l.code) === types_1.RouteCode["Per vagina"] ||
1004
- routeText === "vagina" ||
1005
- routeText === "vaginal";
1006
- const isRectumSite = codingCode === "34402009" || lower === "rectum" || lower === "rectal";
1007
- const isVaginaSite = codingCode === "76784001" || lower === "vagina" || lower === "vaginal";
1008
- if (isRectalRoute &&
1009
- isRectumSite) {
1010
- return undefined;
1011
- }
1012
- if (isVaginalRoute &&
1013
- isVaginaSite) {
1014
- return undefined;
1015
- }
1016
- const translated = translateSiteThai(text, codingCode);
1017
- if (!translated) {
1018
- return undefined;
1019
- }
1020
- if (((_m = clause.route) === null || _m === void 0 ? void 0 : _m.code) === types_1.RouteCode["Nasal route"]) {
1021
- return `เข้า${translated}`;
1022
- }
1023
- const preposition = (_o = grammar.sitePreposition) !== null && _o !== void 0 ? _o : "ที่";
1024
- const separator = /^[\u0E00-\u0E7F]/.test(translated) ? "" : " ";
1025
- return `${preposition}${separator}${translated}`.trim();
1026
- }
1027
- function translateSiteThai(site, code) {
1028
- var _a;
1029
- if (code) {
1030
- const translatedByCode = THAI_SITE_CODE_TRANSLATIONS[code];
1031
- if (translatedByCode) {
1032
- return translatedByCode;
1033
- }
1034
- }
1035
- if (!site) {
1036
- return undefined;
1037
- }
1038
- const normalized = (0, maps_1.normalizeBodySiteKey)(site);
1039
- if (!normalized) {
1040
- return site;
1041
- }
1042
- return (_a = exports.THAI_SITE_TRANSLATIONS[normalized]) !== null && _a !== void 0 ? _a : site;
1043
- }
1044
- function describeDayOfWeekThai(schedule) {
1045
- var _a;
1046
- const dayOfWeek = (_a = schedule === null || schedule === void 0 ? void 0 : schedule.dayOfWeek) !== null && _a !== void 0 ? _a : [];
1047
- if (!dayOfWeek.length) {
1048
- return undefined;
1049
- }
1050
- const days = [];
1051
- for (const day of dayOfWeek) {
1052
- const text = DAY_NAMES_THAI[day];
1053
- if (text) {
1054
- days.push(text);
1055
- }
1056
- }
1057
- return days.length ? `ใน${joinWithAndThai(days)}` : undefined;
1058
- }
1059
- function formatDurationShortThai(schedule) {
1060
- if (schedule.duration === undefined || !schedule.durationUnit) {
1061
- return undefined;
1062
- }
1063
- const base = stripTrailingZero(schedule.duration);
1064
- const qualifier = schedule.durationMax !== undefined && schedule.durationMax !== schedule.duration
1065
- ? `${base}-${stripTrailingZero(schedule.durationMax)}`
1066
- : base;
1067
- return `x${qualifier}${schedule.durationUnit}`;
1068
- }
1069
- function describeDurationThai(schedule) {
1070
- if (!schedule || schedule.duration === undefined || !schedule.durationUnit) {
1071
- return undefined;
1072
- }
1073
- const unit = schedule.durationUnit;
1074
- const label = () => {
1075
- switch (unit) {
1076
- case types_1.FhirPeriodUnit.Minute:
1077
- return "นาที";
1078
- case types_1.FhirPeriodUnit.Hour:
1079
- return "ชั่วโมง";
1080
- case types_1.FhirPeriodUnit.Day:
1081
- return "วัน";
1082
- case types_1.FhirPeriodUnit.Week:
1083
- return "สัปดาห์";
1084
- case types_1.FhirPeriodUnit.Month:
1085
- return "เดือน";
1086
- case types_1.FhirPeriodUnit.Year:
1087
- return "ปี";
1088
- default:
1089
- return unit;
1090
- }
1091
- };
1092
- if (schedule.durationMax !== undefined && schedule.durationMax !== schedule.duration) {
1093
- return `เป็นเวลา ${stripTrailingZero(schedule.duration)} ถึง ${stripTrailingZero(schedule.durationMax)} ${label()}`;
1094
- }
1095
- return `เป็นเวลา ${stripTrailingZero(schedule.duration)} ${label()}`;
1096
- }
1097
- function formatAsNeededThai(clause) {
1098
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
1099
- if (!((_a = clause.prn) === null || _a === void 0 ? void 0 : _a.enabled)) {
1100
- return undefined;
1101
- }
1102
- if ((_b = clause.prn.reasons) === null || _b === void 0 ? void 0 : _b.length) {
1103
- const translatedReasons = [];
1104
- for (const reason of clause.prn.reasons) {
1105
- let text = (_c = reason.text) !== null && _c !== void 0 ? _c : (_d = reason.coding) === null || _d === void 0 ? void 0 : _d.display;
1106
- const coding = reason.coding;
1107
- if (coding === null || coding === void 0 ? void 0 : coding.code) {
1108
- const definition = (0, maps_1.findPrnReasonDefinitionByCoding)((_e = coding.system) !== null && _e !== void 0 ? _e : "http://snomed.info/sct", coding.code);
1109
- text = (_g = (_f = definition === null || definition === void 0 ? void 0 : definition.i18n) === null || _f === void 0 ? void 0 : _f.th) !== null && _g !== void 0 ? _g : text;
1110
- }
1111
- translatedReasons.push({ text, coding: reason.coding });
1112
- }
1113
- const joined = (0, prn_1.getPreferredCanonicalPrnReasonText)(undefined, translatedReasons, "หรือ");
1114
- if (joined) {
1115
- return `ใช้เมื่อจำเป็นสำหรับ ${joined}`;
1116
- }
1117
- }
1118
- let translation;
1119
- const coding = (_h = clause.prn.reason) === null || _h === void 0 ? void 0 : _h.coding;
1120
- if (coding === null || coding === void 0 ? void 0 : coding.code) {
1121
- const definition = (0, maps_1.findPrnReasonDefinitionByCoding)((_j = coding.system) !== null && _j !== void 0 ? _j : "http://snomed.info/sct", coding.code);
1122
- translation = (_k = definition === null || definition === void 0 ? void 0 : definition.i18n) === null || _k === void 0 ? void 0 : _k.th;
1123
- }
1124
- const reason = (_l = translation !== null && translation !== void 0 ? translation : (0, prn_1.getPreferredCanonicalPrnReasonText)(clause.prn.reason, clause.prn.reasons, "หรือ")) !== null && _l !== void 0 ? _l : coding === null || coding === void 0 ? void 0 : coding.display;
1125
- if (reason) {
1126
- return `ใช้เมื่อจำเป็นสำหรับ ${reason}`;
1127
- }
1128
- return "ใช้เมื่อจำเป็น";
1129
- }
1130
- function formatShortThai(clause) {
1131
- var _a, _b, _c, _d, _e, _f;
1132
- const schedule = scheduleOf(clause);
1133
- const parts = [];
1134
- const dose = formatDoseThaiShort(clause.dose);
1135
- if (dose) {
1136
- parts.push(dose);
1137
- }
1138
- if ((_a = clause.route) === null || _a === void 0 ? void 0 : _a.code) {
1139
- const short = ROUTE_SHORT[clause.route.code];
1140
- if (short) {
1141
- parts.push(short);
1142
- }
1143
- else if (clause.route.text) {
1144
- parts.push(clause.route.text);
1145
- }
1146
- }
1147
- else if ((_b = clause.route) === null || _b === void 0 ? void 0 : _b.text) {
1148
- parts.push(clause.route.text);
1149
- }
1150
- const timing = describeFrequencyThai(schedule);
1151
- if (timing) {
1152
- parts.push(timing);
1153
- }
1154
- else if (schedule.timingCode) {
1155
- parts.push(schedule.timingCode);
1156
- }
1157
- else if (schedule.period && schedule.periodUnit) {
1158
- const base = stripTrailingZero(schedule.period);
1159
- const qualifier = schedule.periodMax && schedule.periodMax !== schedule.period
1160
- ? `${base}-${stripTrailingZero(schedule.periodMax)}`
1161
- : base;
1162
- parts.push(`Q${qualifier}${schedule.periodUnit.toUpperCase()}`);
1163
- }
1164
- const events = collectWhenPhrasesThai(schedule);
1165
- if (events.length) {
1166
- parts.push(events.join(" "));
1167
- }
1168
- if ((_c = schedule.timeOfDay) === null || _c === void 0 ? void 0 : _c.length) {
1169
- const times = [];
1170
- for (const time of schedule.timeOfDay) {
1171
- times.push(time.slice(0, 5));
1172
- }
1173
- parts.push(times.join(","));
1174
- }
1175
- if ((_d = schedule.dayOfWeek) === null || _d === void 0 ? void 0 : _d.length) {
1176
- const days = [];
1177
- for (const day of schedule.dayOfWeek) {
1178
- days.push((_f = (_e = DAY_NAMES_THAI[day]) === null || _e === void 0 ? void 0 : _e.replace(/^วัน/, "")) !== null && _f !== void 0 ? _f : day);
1179
- }
1180
- parts.push(days.join(","));
1181
- }
1182
- if (schedule.count !== undefined) {
1183
- parts.push(`x${stripTrailingZero(schedule.count)}`);
1184
- }
1185
- const durationShort = formatDurationShortThai(schedule);
1186
- if (durationShort) {
1187
- parts.push(durationShort);
1188
- }
1189
- const asNeeded = formatAsNeededThai(clause);
1190
- if (asNeeded) {
1191
- parts.push(asNeeded);
1192
- }
1193
- return parts.filter(Boolean).join(" ");
1194
- }
1195
- function formatLongThai(clause, options) {
1196
- var _a, _b, _c;
1197
- const schedule = scheduleOf(clause);
1198
- const grammar = resolveRouteGrammarThai(clause);
1199
- const verb = resolveThaiMethodVerb(clause, grammar);
1200
- const explicitDosePart = formatDoseThaiLong(clause.dose);
1201
- const sitePart = formatSiteThai(clause, grammar);
1202
- const dosePart = shouldUseGenericMedicationObjectThai(clause, verb, explicitDosePart)
1203
- ? explicitDosePart !== null && explicitDosePart !== void 0 ? explicitDosePart : "ยา"
1204
- : explicitDosePart;
1205
- const routePart = shouldSuppressRoutePhraseThai(clause, verb, Boolean(sitePart), explicitDosePart)
1206
- ? undefined
1207
- : buildRoutePhraseThai(clause, grammar, Boolean(sitePart));
1208
- const standaloneOccurrenceCount = describeStandaloneOccurrenceCountThai(schedule);
1209
- const frequencyPart = (_b = (_a = describeFrequencyThai(schedule)) !== null && _a !== void 0 ? _a : standaloneOccurrenceCount) !== null && _b !== void 0 ? _b : describeFrequencyCountThai((0, timing_summary_1.inferDailyOccurrenceCount)(schedule, options));
1210
- const eventParts = collectWhenPhrasesThai(schedule, options);
1211
- if ((_c = schedule.timeOfDay) === null || _c === void 0 ? void 0 : _c.length) {
1212
- const timeStrings = [];
1213
- for (const time of schedule.timeOfDay) {
1214
- const parts = time.split(":");
1215
- const hours = Number(parts[0]);
1216
- const minutes = Number(parts[1]);
1217
- if (!Number.isFinite(hours) || !Number.isFinite(minutes)) {
1218
- continue;
1219
- }
1220
- const displayMinutes = minutes < 10 ? `0${minutes}` : `${minutes}`;
1221
- const displayHours = hours < 10 ? `0${hours}` : `${hours}`;
1222
- timeStrings.push(`${displayHours}:${displayMinutes}`);
1223
- }
1224
- if (timeStrings.length) {
1225
- eventParts.push(`เวลา ${timeStrings.join(", ")}`);
1226
- }
1227
- }
1228
- const timing = combineFrequencyAndEventsThai(frequencyPart, eventParts);
1229
- const dayPart = describeDayOfWeekThai(schedule);
1230
- const countPart = schedule.count !== undefined && !standaloneOccurrenceCount
1231
- ? `จำนวน ${stripTrailingZero(schedule.count)} ครั้ง`
1232
- : undefined;
1233
- const durationPart = describeDurationThai(schedule);
1234
- const asNeeded = formatAsNeededThai(clause);
1235
- const segments = [];
1236
- if (dosePart) {
1237
- segments.push(dosePart);
1238
- }
1239
- if (routePart) {
1240
- segments.push(routePart);
1241
- }
1242
- const siteFirst = Boolean(sitePart) &&
1243
- THAI_SITE_FIRST_VERBS.has(verb) &&
1244
- explicitDosePart === undefined &&
1245
- routePart === undefined;
1246
- if (siteFirst && sitePart) {
1247
- segments.push(sitePart);
1248
- }
1249
- if (timing.frequency) {
1250
- segments.push(timing.frequency);
1251
- }
1252
- if (timing.event) {
1253
- segments.push(timing.event);
1254
- }
1255
- if (dayPart) {
1256
- segments.push(dayPart);
1257
- }
1258
- if (countPart) {
1259
- segments.push(countPart);
1260
- }
1261
- if (durationPart) {
1262
- segments.push(durationPart);
1263
- }
1264
- if (asNeeded) {
1265
- segments.push(asNeeded);
1266
- }
1267
- if (!siteFirst && sitePart) {
1268
- segments.push(sitePart);
1269
- }
1270
- const body = segments.filter(Boolean).join(" ").replace(/\s+/g, " ").trim();
1271
- const instructionPhrases = [];
1272
- const instructionText = formatAdditionalInstructionsThai(clause);
1273
- if (instructionText) {
1274
- instructionPhrases.push(instructionText);
1275
- }
1276
- const patientInstruction = formatPatientInstructionSentence(clause.patientInstruction);
1277
- if (patientInstruction) {
1278
- instructionPhrases.push(patientInstruction);
1279
- }
1280
- const trailingInstructionText = instructionPhrases.join(" ").trim() || undefined;
1281
- const baseSentence = `${joinThaiVerbAndBody(verb, body)}.`;
1282
- if (!body) {
1283
- return trailingInstructionText ? `${baseSentence} ${trailingInstructionText}` : baseSentence;
1284
- }
1285
- return trailingInstructionText ? `${baseSentence} ${trailingInstructionText}` : baseSentence;
1286
- }
1287
- function formatAdditionalInstructionsThai(clause) {
1288
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
1289
- const instructions = (_a = clause.additionalInstructions) !== null && _a !== void 0 ? _a : [];
1290
- if (!instructions.length) {
1291
- return undefined;
1292
- }
1293
- const phrases = [];
1294
- const grammar = resolveRouteGrammarThai(clause);
1295
- const verb = resolveThaiMethodVerb(clause, grammar);
1296
- for (const instruction of instructions) {
1297
- if (((_b = instruction.coding) === null || _b === void 0 ? void 0 : _b.code) === SLOWLY_QUALIFIER_CODE) {
1298
- const contextual = verb ? `${verb}ช้าๆ` : "ช้าๆ";
1299
- phrases.push(contextual);
1300
- continue;
1301
- }
1302
- if (((_c = instruction.coding) === null || _c === void 0 ? void 0 : _c.code) === EMPTY_STOMACH_QUALIFIER_CODE ||
1303
- ((_d = instruction.frames) === null || _d === void 0 ? void 0 : _d.some((frame) => frame.relation === types_1.AdviceRelation.On &&
1304
- frame.args.some((arg) => arg.role === types_1.AdviceArgumentRole.MealState &&
1305
- arg.conceptId === "empty_stomach")))) {
1306
- phrases.push("ขณะท้องว่าง");
1307
- continue;
1308
- }
1309
- let text = (_e = instruction.text) !== null && _e !== void 0 ? _e : (_f = instruction.coding) === null || _f === void 0 ? void 0 : _f.display;
1310
- if ((_g = instruction.coding) === null || _g === void 0 ? void 0 : _g.code) {
1311
- const definition = (0, advice_1.findAdditionalInstructionDefinitionByCoding)((_h = instruction.coding.system) !== null && _h !== void 0 ? _h : "http://snomed.info/sct", instruction.coding.code);
1312
- text = (_k = (_j = definition === null || definition === void 0 ? void 0 : definition.i18n) === null || _j === void 0 ? void 0 : _j.th) !== null && _k !== void 0 ? _k : text;
1313
- }
1314
- if (!text) {
1315
- continue;
1316
- }
1317
- const trimmed = text.trim();
1318
- if (trimmed) {
1319
- phrases.push(trimmed);
1320
- }
1321
- }
1322
- if (!phrases.length) {
1323
- return undefined;
1324
- }
1325
- return phrases.map((phrase) => (/[.!?]$/.test(phrase) ? phrase : `${phrase}.`)).join(" ").trim();
1326
- }
1327
- function formatPatientInstructionSentence(text) {
1328
- const trimmed = text === null || text === void 0 ? void 0 : text.trim();
1329
- if (!trimmed) {
1330
- return undefined;
1331
- }
1332
- const sentence = /^[.!?]$/.test(trimmed.slice(-1)) ? trimmed : `${trimmed}.`;
1333
- return sentence.charAt(0).toUpperCase() + sentence.slice(1);
1334
- }
1335
- function stripTrailingZero(value) {
1336
- const text = value.toString();
1337
- if (text.includes(".")) {
1338
- return text.replace(/\.0+$/, "").replace(/0+$/, "");
1339
- }
1340
- return text;
1341
- }