ceddcozum 0.1.9 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +411 -170
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12800,8 +12800,8 @@ var neonatalDatasetRegistry = {
|
|
|
12800
12800
|
var syndromeDatasetRegistry = {
|
|
12801
12801
|
[downDataset.id]: downDataset,
|
|
12802
12802
|
...turnerDatasets,
|
|
12803
|
-
[noonanWittDataset.id]: noonanWittDataset,
|
|
12804
12803
|
[noonanMalaquiasDataset.id]: noonanMalaquiasDataset,
|
|
12804
|
+
[noonanWittDataset.id]: noonanWittDataset,
|
|
12805
12805
|
[noonanRankeDataset.id]: noonanRankeDataset,
|
|
12806
12806
|
[praderWilliDataset.id]: praderWilliDataset,
|
|
12807
12807
|
[praderWilliButlerDataset.id]: praderWilliButlerDataset,
|
|
@@ -13783,7 +13783,8 @@ var SUPPORTED_MEASUREMENTS = {
|
|
|
13783
13783
|
["williams" /* williams */]: ["height"],
|
|
13784
13784
|
["xlh" /* xlh */]: ["height"],
|
|
13785
13785
|
["osteogenesisImperfecta" /* osteogenesisImperfecta */]: ["height", "weight"],
|
|
13786
|
-
["mucopolysaccharidosis" /* mucopolysaccharidosis */]: ["height", "weight"]
|
|
13786
|
+
["mucopolysaccharidosis" /* mucopolysaccharidosis */]: ["height", "weight"],
|
|
13787
|
+
["klinefelter" /* klinefelter */]: ["height"]
|
|
13787
13788
|
};
|
|
13788
13789
|
function getDatasetDefinition(datasetId) {
|
|
13789
13790
|
return syndromeDatasetRegistry[datasetId];
|
|
@@ -15499,22 +15500,6 @@ var igfbp3GuvenSds = [
|
|
|
15499
15500
|
{ ageRange: "17-18", sex: "f", values: [], mean: 5.19, sd: 1.3 }
|
|
15500
15501
|
];
|
|
15501
15502
|
|
|
15502
|
-
// ../src/data/igf/tanner.ts
|
|
15503
|
-
var femaleTannerData = [
|
|
15504
|
-
{ stage: "I", igf1: { low: 49, median: 159, high: 342 }, igfbp3: { low: 1.2, median: 3.6, high: 6.4, isIGFBP3: true } },
|
|
15505
|
-
{ stage: "II", igf1: { low: 115, median: 269, high: 428 }, igfbp3: { low: 2.8, median: 4.5, high: 6.9, isIGFBP3: true } },
|
|
15506
|
-
{ stage: "III", igf1: { low: 145, median: 412, high: 760 }, igfbp3: { low: 3.9, median: 5.3, high: 9.4, isIGFBP3: true } },
|
|
15507
|
-
{ stage: "IV", igf1: { low: 244, median: 504, high: 787 }, igfbp3: { low: 3.3, median: 5.9, high: 8.1, isIGFBP3: true } },
|
|
15508
|
-
{ stage: "V", igf1: { low: 143, median: 408, high: 859 }, igfbp3: { low: 2.7, median: 5.6, high: 9.1, isIGFBP3: true } }
|
|
15509
|
-
];
|
|
15510
|
-
var maleTannerData = [
|
|
15511
|
-
{ stage: "I", igf1: { low: 63, median: 152, high: 279 }, igfbp3: { low: 1.4, median: 3.6, high: 5.2, isIGFBP3: true } },
|
|
15512
|
-
{ stage: "II", igf1: { low: 75, median: 190, high: 420 }, igfbp3: { low: 2.3, median: 3.9, high: 6.3, isIGFBP3: true } },
|
|
15513
|
-
{ stage: "III", igf1: { low: 94, median: 406, high: 765 }, igfbp3: { low: 3.1, median: 5.4, high: 8.9, isIGFBP3: true } },
|
|
15514
|
-
{ stage: "IV", igf1: { low: 192, median: 577, high: 861 }, igfbp3: { low: 3.7, median: 6.5, high: 8.7, isIGFBP3: true } },
|
|
15515
|
-
{ stage: "V", igf1: { low: 171, median: 422, high: 814 }, igfbp3: { low: 2.6, median: 5.2, high: 8.6, isIGFBP3: true } }
|
|
15516
|
-
];
|
|
15517
|
-
|
|
15518
15503
|
// ../src/data/igf/igf1EcliaLms.ts
|
|
15519
15504
|
var maleEcliaLms = [
|
|
15520
15505
|
{ age: 0.25, L: 0.3, M: 39.4, S: 0.5076 },
|
|
@@ -15569,8 +15554,6 @@ var femaleEcliaLms = [
|
|
|
15569
15554
|
var igfSdsData = igf1ElmlingerSds;
|
|
15570
15555
|
var igfbp3SdsDataElmlinger = igfbp3ElmlingerSds;
|
|
15571
15556
|
var igfbp3SdsDataRiaBc = igfbp3RiaBcSds;
|
|
15572
|
-
var femaleTannerData2 = femaleTannerData;
|
|
15573
|
-
var maleTannerData2 = maleTannerData;
|
|
15574
15557
|
var femaleLmsParams = femaleEcliaLms;
|
|
15575
15558
|
var maleLmsParams = maleEcliaLms;
|
|
15576
15559
|
function calculateIGFSds(input) {
|
|
@@ -15580,7 +15563,6 @@ function calculateIGFSds(input) {
|
|
|
15580
15563
|
if (!input.igf1Value && !input.igfbp3Value) {
|
|
15581
15564
|
return null;
|
|
15582
15565
|
}
|
|
15583
|
-
const tannerStage = input.tannerStage || "I";
|
|
15584
15566
|
const result = {
|
|
15585
15567
|
dataset: {
|
|
15586
15568
|
igf1: input.igf1Database,
|
|
@@ -15594,22 +15576,14 @@ function calculateIGFSds(input) {
|
|
|
15594
15576
|
if (input.igf1Value !== void 0 && input.igf1Value > 0) {
|
|
15595
15577
|
const igf1Result = calculateIGF1SDS(input.age, input.sex, input.igf1Value, input.igf1Database);
|
|
15596
15578
|
if (igf1Result) {
|
|
15597
|
-
result.igf1 =
|
|
15598
|
-
...igf1Result,
|
|
15599
|
-
// Only Elmlinger dataset has Tanner stage data
|
|
15600
|
-
tannerPercentile: input.igf1Database === "elmlinger" ? getTannerPercentile(input.sex, tannerStage, input.igf1Value, "igf1") : void 0
|
|
15601
|
-
};
|
|
15579
|
+
result.igf1 = igf1Result;
|
|
15602
15580
|
}
|
|
15603
15581
|
}
|
|
15604
15582
|
if (input.igfbp3Value !== void 0 && input.igfbp3Value > 0) {
|
|
15605
15583
|
const convertedValue = input.igfbp3Unit === "ngPerML" ? input.igfbp3Value / 1e3 : input.igfbp3Value;
|
|
15606
15584
|
const igfbp3Result = calculateIGFBP3SDS(input.age, input.sex, convertedValue, input.igfbp3Database);
|
|
15607
15585
|
if (igfbp3Result) {
|
|
15608
|
-
result.igfbp3 =
|
|
15609
|
-
...igfbp3Result,
|
|
15610
|
-
// Only Elmlinger dataset has Tanner stage data
|
|
15611
|
-
tannerPercentile: input.igfbp3Database === "elmlinger" ? getTannerPercentile(input.sex, tannerStage, convertedValue, "igfbp3", input.igfbp3Database) : void 0
|
|
15612
|
-
};
|
|
15586
|
+
result.igfbp3 = igfbp3Result;
|
|
15613
15587
|
}
|
|
15614
15588
|
}
|
|
15615
15589
|
return result;
|
|
@@ -15674,7 +15648,9 @@ function calculateElmlingerSDS(age, sex, value, data) {
|
|
|
15674
15648
|
return {
|
|
15675
15649
|
sds,
|
|
15676
15650
|
percentile,
|
|
15677
|
-
interpretation: getInterpretation(sds)
|
|
15651
|
+
interpretation: getInterpretation(sds),
|
|
15652
|
+
median: values[2] ?? null
|
|
15653
|
+
// index 2 = Mean (50th percentile)
|
|
15678
15654
|
};
|
|
15679
15655
|
}
|
|
15680
15656
|
function calculateECLIASDS(age, sex, value) {
|
|
@@ -15683,7 +15659,8 @@ function calculateECLIASDS(age, sex, value) {
|
|
|
15683
15659
|
return {
|
|
15684
15660
|
sds: null,
|
|
15685
15661
|
percentile: null,
|
|
15686
|
-
interpretation: null
|
|
15662
|
+
interpretation: null,
|
|
15663
|
+
median: null
|
|
15687
15664
|
};
|
|
15688
15665
|
}
|
|
15689
15666
|
const sds = calculateLMSSDS(value, params.L, params.M, params.S);
|
|
@@ -15691,7 +15668,9 @@ function calculateECLIASDS(age, sex, value) {
|
|
|
15691
15668
|
return {
|
|
15692
15669
|
sds,
|
|
15693
15670
|
percentile,
|
|
15694
|
-
interpretation: getInterpretation(sds)
|
|
15671
|
+
interpretation: getInterpretation(sds),
|
|
15672
|
+
median: params.M
|
|
15673
|
+
// M parameter = 50th percentile in LMS
|
|
15695
15674
|
};
|
|
15696
15675
|
}
|
|
15697
15676
|
function calculateRiaBcSDS(age, sex, value) {
|
|
@@ -15707,7 +15686,9 @@ function calculateRiaBcSDS(age, sex, value) {
|
|
|
15707
15686
|
return {
|
|
15708
15687
|
sds,
|
|
15709
15688
|
percentile,
|
|
15710
|
-
interpretation: getInterpretation(sds)
|
|
15689
|
+
interpretation: getInterpretation(sds),
|
|
15690
|
+
median: group.mean
|
|
15691
|
+
// mean ≈ 50th percentile for Mean-SD method
|
|
15711
15692
|
};
|
|
15712
15693
|
}
|
|
15713
15694
|
function calculateGuvenSDS(age, sex, value, data) {
|
|
@@ -15723,7 +15704,9 @@ function calculateGuvenSDS(age, sex, value, data) {
|
|
|
15723
15704
|
return {
|
|
15724
15705
|
sds,
|
|
15725
15706
|
percentile,
|
|
15726
|
-
interpretation: getInterpretation(sds)
|
|
15707
|
+
interpretation: getInterpretation(sds),
|
|
15708
|
+
median: group.mean
|
|
15709
|
+
// mean ≈ 50th percentile for Mean-SD method
|
|
15727
15710
|
};
|
|
15728
15711
|
}
|
|
15729
15712
|
function getLMSForAge(age, sex) {
|
|
@@ -15760,41 +15743,6 @@ function getLMSForAge(age, sex) {
|
|
|
15760
15743
|
};
|
|
15761
15744
|
}
|
|
15762
15745
|
var calculateLMSSDS = (measurement, L, M, S) => calculateLMSBasedSDS(measurement, L, M, S, false);
|
|
15763
|
-
function getTannerPercentile(sex, stage, value, type, database) {
|
|
15764
|
-
const tannerData = sex === "female" ? femaleTannerData2 : maleTannerData2;
|
|
15765
|
-
const stageData = tannerData.find((data) => data.stage === stage);
|
|
15766
|
-
if (!stageData) {
|
|
15767
|
-
return "N/A";
|
|
15768
|
-
}
|
|
15769
|
-
const range = type === "igf1" ? stageData.igf1 : stageData.igfbp3;
|
|
15770
|
-
if (type === "igfbp3" && (database === "riaBc" || database === "guven")) {
|
|
15771
|
-
return "N/A";
|
|
15772
|
-
}
|
|
15773
|
-
if (type === "igfbp3") {
|
|
15774
|
-
const convertedValue = value * 1e3;
|
|
15775
|
-
const convertedRange = {
|
|
15776
|
-
low: range.low * 1e3,
|
|
15777
|
-
median: range.median * 1e3,
|
|
15778
|
-
high: range.high * 1e3
|
|
15779
|
-
};
|
|
15780
|
-
return calculateTannerPercentile(convertedRange, convertedValue);
|
|
15781
|
-
}
|
|
15782
|
-
return calculateTannerPercentile(range, value);
|
|
15783
|
-
}
|
|
15784
|
-
function calculateTannerPercentile(range, value) {
|
|
15785
|
-
if (value < range.low) return "<2.5p";
|
|
15786
|
-
if (value > range.high) return ">97.5p";
|
|
15787
|
-
if (value === range.low) return "2.5p";
|
|
15788
|
-
if (value === range.high) return "97.5p";
|
|
15789
|
-
if (value === range.median) return "50p";
|
|
15790
|
-
if (value > range.low && value < range.median) {
|
|
15791
|
-
return "2.5-50p";
|
|
15792
|
-
}
|
|
15793
|
-
if (value > range.median && value < range.high) {
|
|
15794
|
-
return "50-97.5p";
|
|
15795
|
-
}
|
|
15796
|
-
return "Unknown";
|
|
15797
|
-
}
|
|
15798
15746
|
function isAgeInRange(age, range) {
|
|
15799
15747
|
const components = range.split(/[–-]/).map((s) => s.trim());
|
|
15800
15748
|
const startAge = parseFloat(components[0]);
|
|
@@ -16943,7 +16891,9 @@ function calculatePhosphateSds(input) {
|
|
|
16943
16891
|
sds: null,
|
|
16944
16892
|
percentile: null,
|
|
16945
16893
|
phosphateMmol,
|
|
16946
|
-
phosphateMgDl
|
|
16894
|
+
phosphateMgDl,
|
|
16895
|
+
p2_5Mmol: null,
|
|
16896
|
+
p97_5Mmol: null
|
|
16947
16897
|
};
|
|
16948
16898
|
}
|
|
16949
16899
|
const sds = calculateLMSBasedSDS(
|
|
@@ -16955,11 +16905,17 @@ function calculatePhosphateSds(input) {
|
|
|
16955
16905
|
// no SD23 correction needed for phosphate
|
|
16956
16906
|
);
|
|
16957
16907
|
const percentile = sdsToPercentile(sds);
|
|
16908
|
+
const Z_2_5 = -1.96;
|
|
16909
|
+
const Z_97_5 = 1.96;
|
|
16910
|
+
const p2_5Mmol = lmsToValue(lmsParams.L, lmsParams.M, lmsParams.S, Z_2_5);
|
|
16911
|
+
const p97_5Mmol = lmsToValue(lmsParams.L, lmsParams.M, lmsParams.S, Z_97_5);
|
|
16958
16912
|
return {
|
|
16959
16913
|
sds,
|
|
16960
16914
|
percentile,
|
|
16961
16915
|
phosphateMmol,
|
|
16962
|
-
phosphateMgDl
|
|
16916
|
+
phosphateMgDl,
|
|
16917
|
+
p2_5Mmol,
|
|
16918
|
+
p97_5Mmol
|
|
16963
16919
|
};
|
|
16964
16920
|
}
|
|
16965
16921
|
|
|
@@ -17224,6 +17180,8 @@ function getInterpretation2(ratio) {
|
|
|
17224
17180
|
};
|
|
17225
17181
|
}
|
|
17226
17182
|
}
|
|
17183
|
+
var INSULIN_UNITS = ["uIU/mL", "mIU/L", "pmol/L"];
|
|
17184
|
+
var CPEPTIDE_UNITS = ["ng/mL", "nmol/L", "pmol/L"];
|
|
17227
17185
|
|
|
17228
17186
|
// ../src/lib/calculators/hcg-test.ts
|
|
17229
17187
|
var CONVERSION_FACTORS = {
|
|
@@ -24248,6 +24206,170 @@ function calculateOsmolality(input) {
|
|
|
24248
24206
|
}
|
|
24249
24207
|
}
|
|
24250
24208
|
|
|
24209
|
+
// ../src/lib/processors/DateAgeConverter.ts
|
|
24210
|
+
function calculateAge2(input) {
|
|
24211
|
+
const errors = [];
|
|
24212
|
+
let birthDate = null;
|
|
24213
|
+
if (input.birthDate instanceof Date) {
|
|
24214
|
+
birthDate = input.birthDate;
|
|
24215
|
+
} else if (typeof input.birthDate === "string") {
|
|
24216
|
+
birthDate = parseDate(input.birthDate);
|
|
24217
|
+
}
|
|
24218
|
+
if (!birthDate || isNaN(birthDate.getTime())) {
|
|
24219
|
+
errors.push("Invalid birth date");
|
|
24220
|
+
}
|
|
24221
|
+
const measurementDateInput = input.measurementDate || input.targetDate || /* @__PURE__ */ new Date();
|
|
24222
|
+
let measurementDate = null;
|
|
24223
|
+
if (measurementDateInput instanceof Date) {
|
|
24224
|
+
measurementDate = measurementDateInput;
|
|
24225
|
+
} else if (typeof measurementDateInput === "string") {
|
|
24226
|
+
measurementDate = parseDate(measurementDateInput);
|
|
24227
|
+
}
|
|
24228
|
+
if (!measurementDate || isNaN(measurementDate.getTime())) {
|
|
24229
|
+
errors.push("Invalid measurement date");
|
|
24230
|
+
}
|
|
24231
|
+
if (birthDate && measurementDate) {
|
|
24232
|
+
if (measurementDate < birthDate) {
|
|
24233
|
+
errors.push("Measurement date cannot be before birth date");
|
|
24234
|
+
}
|
|
24235
|
+
if (birthDate.getFullYear() < 1900) {
|
|
24236
|
+
errors.push("Birth date is too far in the past");
|
|
24237
|
+
}
|
|
24238
|
+
if (measurementDate.getFullYear() > (/* @__PURE__ */ new Date()).getFullYear() + 1) {
|
|
24239
|
+
errors.push("Measurement date is too far in the future");
|
|
24240
|
+
}
|
|
24241
|
+
}
|
|
24242
|
+
if (errors.length === 0 && birthDate && measurementDate) {
|
|
24243
|
+
const age = calculateAgeBreakdownFromDates(birthDate, measurementDate);
|
|
24244
|
+
return {
|
|
24245
|
+
isValid: true,
|
|
24246
|
+
age,
|
|
24247
|
+
errors: [],
|
|
24248
|
+
parsedBirthDate: birthDate,
|
|
24249
|
+
parsedMeasurementDate: measurementDate
|
|
24250
|
+
};
|
|
24251
|
+
}
|
|
24252
|
+
return {
|
|
24253
|
+
isValid: false,
|
|
24254
|
+
age: null,
|
|
24255
|
+
errors,
|
|
24256
|
+
parsedBirthDate: birthDate,
|
|
24257
|
+
parsedMeasurementDate: measurementDate
|
|
24258
|
+
};
|
|
24259
|
+
}
|
|
24260
|
+
function calculateAgeBreakdownFromDates(birthDate, measurementDate) {
|
|
24261
|
+
const totalDays = Math.floor((measurementDate.getTime() - birthDate.getTime()) / (1e3 * 60 * 60 * 24));
|
|
24262
|
+
if (totalDays < 0) {
|
|
24263
|
+
const decimalYears2 = totalDays / 365.25;
|
|
24264
|
+
return {
|
|
24265
|
+
years: 0,
|
|
24266
|
+
months: 0,
|
|
24267
|
+
days: totalDays,
|
|
24268
|
+
totalDays,
|
|
24269
|
+
decimalYears: decimalYears2,
|
|
24270
|
+
decimalMonths: decimalYears2 * 12
|
|
24271
|
+
};
|
|
24272
|
+
}
|
|
24273
|
+
const { years, months, days } = calculateCalendarAge(birthDate, measurementDate);
|
|
24274
|
+
const decimalYears = convertYMDToDecimalYears(years, months, days);
|
|
24275
|
+
const decimalMonths = decimalYears * 12;
|
|
24276
|
+
return {
|
|
24277
|
+
years,
|
|
24278
|
+
months,
|
|
24279
|
+
days,
|
|
24280
|
+
totalDays,
|
|
24281
|
+
decimalYears,
|
|
24282
|
+
decimalMonths
|
|
24283
|
+
};
|
|
24284
|
+
}
|
|
24285
|
+
function calculateCalendarAge(startDate, endDate) {
|
|
24286
|
+
let years = endDate.getFullYear() - startDate.getFullYear();
|
|
24287
|
+
let months = endDate.getMonth() - startDate.getMonth();
|
|
24288
|
+
if (endDate.getDate() < startDate.getDate()) {
|
|
24289
|
+
months--;
|
|
24290
|
+
}
|
|
24291
|
+
if (months < 0) {
|
|
24292
|
+
years--;
|
|
24293
|
+
months += 12;
|
|
24294
|
+
}
|
|
24295
|
+
const refDate = new Date(startDate.getFullYear() + years, startDate.getMonth() + months, 1);
|
|
24296
|
+
const daysInRefMonth = new Date(refDate.getFullYear(), refDate.getMonth() + 1, 0).getDate();
|
|
24297
|
+
const clampedDay = Math.min(startDate.getDate(), daysInRefMonth);
|
|
24298
|
+
refDate.setDate(clampedDay);
|
|
24299
|
+
const days = Math.round((endDate.getTime() - refDate.getTime()) / (1e3 * 60 * 60 * 24));
|
|
24300
|
+
return { years, months, days };
|
|
24301
|
+
}
|
|
24302
|
+
function convertYMDToDecimalYears(years, months, days) {
|
|
24303
|
+
const monthsInYears = months / 12;
|
|
24304
|
+
const daysInYears = days / 365.25;
|
|
24305
|
+
return years + monthsInYears + daysInYears;
|
|
24306
|
+
}
|
|
24307
|
+
function parseDate(dateString) {
|
|
24308
|
+
if (!dateString || dateString.trim() === "") {
|
|
24309
|
+
return null;
|
|
24310
|
+
}
|
|
24311
|
+
const cleaned = dateString.trim();
|
|
24312
|
+
let date = new Date(cleaned);
|
|
24313
|
+
if (!isNaN(date.getTime())) {
|
|
24314
|
+
return date;
|
|
24315
|
+
}
|
|
24316
|
+
const formats = [
|
|
24317
|
+
// DD.MM.YYYY (Turkish)
|
|
24318
|
+
/^(\d{1,2})\.(\d{1,2})\.(\d{4})$/,
|
|
24319
|
+
// DD/MM/YYYY (European)
|
|
24320
|
+
/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/,
|
|
24321
|
+
// DD-MM-YYYY
|
|
24322
|
+
/^(\d{1,2})-(\d{1,2})-(\d{4})$/,
|
|
24323
|
+
// MM/DD/YYYY (American)
|
|
24324
|
+
/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/,
|
|
24325
|
+
// MM-DD-YYYY
|
|
24326
|
+
/^(\d{1,2})-(\d{1,2})-(\d{4})$/
|
|
24327
|
+
];
|
|
24328
|
+
const ddmmMatch = cleaned.match(/^(\d{1,2})\.(\d{1,2})\.(\d{4})$/);
|
|
24329
|
+
if (ddmmMatch) {
|
|
24330
|
+
const [, day, month, year] = ddmmMatch;
|
|
24331
|
+
date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
|
|
24332
|
+
if (!isNaN(date.getTime())) return date;
|
|
24333
|
+
}
|
|
24334
|
+
const ddmmSlashMatch = cleaned.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
|
|
24335
|
+
if (ddmmSlashMatch) {
|
|
24336
|
+
const [, day, month, year] = ddmmSlashMatch;
|
|
24337
|
+
date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
|
|
24338
|
+
if (!isNaN(date.getTime())) return date;
|
|
24339
|
+
}
|
|
24340
|
+
return null;
|
|
24341
|
+
}
|
|
24342
|
+
|
|
24343
|
+
// ../src/lib/calculators/cnpAnalogue.ts
|
|
24344
|
+
var VOSORITIDE_DOSE_TABLE = [
|
|
24345
|
+
{ minWeight: 3, maxWeight: 3, vialMg: 0.4, doseMg: 0.096, volumeMl: 0.12, reconcentration: 0.8 },
|
|
24346
|
+
{ minWeight: 4, maxWeight: 4, vialMg: 0.4, doseMg: 0.12, volumeMl: 0.15, reconcentration: 0.8 },
|
|
24347
|
+
{ minWeight: 5, maxWeight: 5, vialMg: 0.4, doseMg: 0.16, volumeMl: 0.2, reconcentration: 0.8 },
|
|
24348
|
+
{ minWeight: 6, maxWeight: 7, vialMg: 0.4, doseMg: 0.2, volumeMl: 0.25, reconcentration: 0.8 },
|
|
24349
|
+
{ minWeight: 8, maxWeight: 11, vialMg: 0.4, doseMg: 0.24, volumeMl: 0.3, reconcentration: 0.8 },
|
|
24350
|
+
{ minWeight: 12, maxWeight: 16, vialMg: 0.56, doseMg: 0.28, volumeMl: 0.35, reconcentration: 0.8 },
|
|
24351
|
+
{ minWeight: 17, maxWeight: 21, vialMg: 0.56, doseMg: 0.32, volumeMl: 0.4, reconcentration: 0.8 },
|
|
24352
|
+
{ minWeight: 22, maxWeight: 32, vialMg: 0.56, doseMg: 0.4, volumeMl: 0.5, reconcentration: 0.8 },
|
|
24353
|
+
{ minWeight: 33, maxWeight: 43, vialMg: 1.2, doseMg: 0.5, volumeMl: 0.25, reconcentration: 2 },
|
|
24354
|
+
{ minWeight: 44, maxWeight: 59, vialMg: 1.2, doseMg: 0.6, volumeMl: 0.3, reconcentration: 2 },
|
|
24355
|
+
{ minWeight: 60, maxWeight: 89, vialMg: 1.2, doseMg: 0.7, volumeMl: 0.35, reconcentration: 2 },
|
|
24356
|
+
{ minWeight: 90, maxWeight: Infinity, vialMg: 1.2, doseMg: 0.8, volumeMl: 0.4, reconcentration: 2 }
|
|
24357
|
+
];
|
|
24358
|
+
var NAVEPEGRITIDE_DOSE_MCG_KG_WEEK = 100;
|
|
24359
|
+
function lookupVosoritideDose(weightKg) {
|
|
24360
|
+
const rounded = Math.round(weightKg);
|
|
24361
|
+
if (rounded < 3) return null;
|
|
24362
|
+
return VOSORITIDE_DOSE_TABLE.find((e) => rounded >= e.minWeight && rounded <= e.maxWeight) ?? null;
|
|
24363
|
+
}
|
|
24364
|
+
function mcgPerKgDayVosoritide(entry, weightKgRounded) {
|
|
24365
|
+
return entry.doseMg * 1e3 / weightKgRounded;
|
|
24366
|
+
}
|
|
24367
|
+
function computeNavepegritideWeeklyDose(weightKg) {
|
|
24368
|
+
if (!weightKg || !isFinite(weightKg) || weightKg <= 0) return null;
|
|
24369
|
+
const doseMcg = NAVEPEGRITIDE_DOSE_MCG_KG_WEEK * weightKg;
|
|
24370
|
+
return { doseMcg, doseMg: doseMcg / 1e3 };
|
|
24371
|
+
}
|
|
24372
|
+
|
|
24251
24373
|
// ../src/lib/chat/toolExecutor.ts
|
|
24252
24374
|
function severity(sds) {
|
|
24253
24375
|
if (sds === null) return "normal";
|
|
@@ -24370,6 +24492,11 @@ function buildInputEcho(name, args) {
|
|
|
24370
24492
|
if (gw != null) parts.push(`${gw}w${gd ? `+${gd}d` : ""}`);
|
|
24371
24493
|
return { label: "", value: parts.join(" \xB7 "), tag: "echo" };
|
|
24372
24494
|
}
|
|
24495
|
+
case "cnp-analogue": {
|
|
24496
|
+
if (args.mode) parts.push(String(args.mode));
|
|
24497
|
+
if (args.weightKg != null) parts.push(`${args.weightKg} kg`);
|
|
24498
|
+
return { label: "", value: parts.join(" \xB7 "), tag: "echo" };
|
|
24499
|
+
}
|
|
24373
24500
|
}
|
|
24374
24501
|
const age = args.age != null ? Number(args.age) : args.ageYears != null ? Number(args.ageYears) : NaN;
|
|
24375
24502
|
if (!isNaN(age)) {
|
|
@@ -24416,18 +24543,6 @@ function formatDateTR(d) {
|
|
|
24416
24543
|
const mm = String(d.getMonth() + 1).padStart(2, "0");
|
|
24417
24544
|
return `${dd}/${mm}/${d.getFullYear()}`;
|
|
24418
24545
|
}
|
|
24419
|
-
function ageBreakdown(birth, ref) {
|
|
24420
|
-
let years = ref.getFullYear() - birth.getFullYear();
|
|
24421
|
-
let months = ref.getMonth() - birth.getMonth();
|
|
24422
|
-
if (ref.getDate() < birth.getDate()) months--;
|
|
24423
|
-
if (months < 0) {
|
|
24424
|
-
years--;
|
|
24425
|
-
months += 12;
|
|
24426
|
-
}
|
|
24427
|
-
const diffMs = ref.getTime() - birth.getTime();
|
|
24428
|
-
const totalDecimal = diffMs / (365.25 * 24 * 60 * 60 * 1e3);
|
|
24429
|
-
return { years, months, totalDecimal };
|
|
24430
|
-
}
|
|
24431
24546
|
function executeDecimalAge(args) {
|
|
24432
24547
|
const birthDatesStr = String(args.birthDates || "");
|
|
24433
24548
|
const refDateStr = args.referenceDate ? String(args.referenceDate) : (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
@@ -24456,8 +24571,13 @@ function executeDecimalAge(args) {
|
|
|
24456
24571
|
results.push({ label: formatDateTR(bd), value: "Hen\xFCz do\u011Fmad\u0131", severity: "severe" });
|
|
24457
24572
|
continue;
|
|
24458
24573
|
}
|
|
24459
|
-
const
|
|
24460
|
-
|
|
24574
|
+
const ageResult = calculateAge2({ birthDate: bd, measurementDate: refDate });
|
|
24575
|
+
if (!ageResult.isValid || !ageResult.age) {
|
|
24576
|
+
results.push({ label: `#${i + 1}`, value: `Hesaplanamad\u0131: ${birthDates[i]}`, severity: "severe" });
|
|
24577
|
+
continue;
|
|
24578
|
+
}
|
|
24579
|
+
const { years, months, decimalYears } = ageResult.age;
|
|
24580
|
+
const decimalStr = decimalYears.toFixed(2).replace(".", ",");
|
|
24461
24581
|
if (isBatch) {
|
|
24462
24582
|
results.push({
|
|
24463
24583
|
label: formatDateTR(bd),
|
|
@@ -24467,6 +24587,14 @@ function executeDecimalAge(args) {
|
|
|
24467
24587
|
results.push({ label: "Do\u011Fum tarihi", value: formatDateTR(bd) });
|
|
24468
24588
|
results.push({ label: "Ya\u015F", value: `${years} y\u0131l ${months} ay` });
|
|
24469
24589
|
results.push({ label: "Desimal ya\u015F", value: `${decimalStr} y\u0131l` });
|
|
24590
|
+
const roundedAge = parseFloat(decimalYears.toFixed(2));
|
|
24591
|
+
results.push({
|
|
24592
|
+
label: "",
|
|
24593
|
+
value: "Calculate growth SDS with this age",
|
|
24594
|
+
tag: "alt",
|
|
24595
|
+
altToolName: "auxology",
|
|
24596
|
+
altArgs: { age: roundedAge, ...sex ? { sex } : {} }
|
|
24597
|
+
});
|
|
24470
24598
|
}
|
|
24471
24599
|
}
|
|
24472
24600
|
return results;
|
|
@@ -24502,6 +24630,9 @@ function executeTool(name, args) {
|
|
|
24502
24630
|
case "body-ratios":
|
|
24503
24631
|
results = executeBodyRatios(args);
|
|
24504
24632
|
break;
|
|
24633
|
+
case "cnp-analogue":
|
|
24634
|
+
results = executeCnpAnalogue(args);
|
|
24635
|
+
break;
|
|
24505
24636
|
case "growth-hormone":
|
|
24506
24637
|
results = executeGrowthHormone(args);
|
|
24507
24638
|
break;
|
|
@@ -24591,7 +24722,7 @@ function executeTool(name, args) {
|
|
|
24591
24722
|
return [{ label: "Info", value: `Calculator "${name}" is not available in the chat. Please use it from the Tools panel.` }];
|
|
24592
24723
|
}
|
|
24593
24724
|
if (results.length > 0 && results[0].label === "Error") return results;
|
|
24594
|
-
const ECHO_TOOLS = /* @__PURE__ */ new Set(["growth-hormone"]);
|
|
24725
|
+
const ECHO_TOOLS = /* @__PURE__ */ new Set(["growth-hormone", "cnp-analogue"]);
|
|
24595
24726
|
if (ECHO_TOOLS.has(name)) {
|
|
24596
24727
|
const echo = buildInputEcho(name, args);
|
|
24597
24728
|
if (echo.value && echo.value !== "\u2014") {
|
|
@@ -25022,9 +25153,6 @@ function executeIGFSds(args) {
|
|
|
25022
25153
|
percentile: result.igf1.percentile,
|
|
25023
25154
|
severity: result.igf1.sds != null ? severity(result.igf1.sds) : "normal"
|
|
25024
25155
|
});
|
|
25025
|
-
if (result.igf1.tannerPercentile) {
|
|
25026
|
-
results.push({ label: "IGF-1 Tanner", value: result.igf1.tannerPercentile });
|
|
25027
|
-
}
|
|
25028
25156
|
}
|
|
25029
25157
|
if (result.igfbp3) {
|
|
25030
25158
|
results.push({
|
|
@@ -25116,6 +25244,44 @@ function executeBodyRatios(args) {
|
|
|
25116
25244
|
}
|
|
25117
25245
|
return results.length > 1 ? results : [patientRow({ age, sex }), { label: "Note", value: "Provide sittingHeight or armSpan" }];
|
|
25118
25246
|
}
|
|
25247
|
+
function executeCnpAnalogue(args) {
|
|
25248
|
+
const mode = args.mode === "weekly" || args.mode === "daily" ? args.mode : null;
|
|
25249
|
+
const weightKg = Number(args.weightKg);
|
|
25250
|
+
if (!mode || !isFinite(weightKg) || weightKg <= 0) {
|
|
25251
|
+
return [{ label: "Error", value: 'Provide mode ("daily" or "weekly") and weightKg > 0.', severity: "severe" }];
|
|
25252
|
+
}
|
|
25253
|
+
if (mode === "weekly") {
|
|
25254
|
+
const wk = computeNavepegritideWeeklyDose(weightKg);
|
|
25255
|
+
if (!wk) {
|
|
25256
|
+
return [{ label: "Error", value: "Invalid weight for weekly dose.", severity: "severe" }];
|
|
25257
|
+
}
|
|
25258
|
+
return [
|
|
25259
|
+
{ label: "Agent", value: "Navepegritide (weekly)" },
|
|
25260
|
+
{ label: "Weekly dose", value: wk.doseMg.toFixed(3), unit: "mg" },
|
|
25261
|
+
{ label: "Dose intensity", value: String(NAVEPEGRITIDE_DOSE_MCG_KG_WEEK), unit: "mcg/kg/week" }
|
|
25262
|
+
];
|
|
25263
|
+
}
|
|
25264
|
+
const rounded = Math.round(weightKg);
|
|
25265
|
+
const row = lookupVosoritideDose(weightKg);
|
|
25266
|
+
if (!row) {
|
|
25267
|
+
return [
|
|
25268
|
+
{
|
|
25269
|
+
label: "Error",
|
|
25270
|
+
value: "Weight out of range for vosoritide table (minimum 3 kg after rounding to nearest kg).",
|
|
25271
|
+
severity: "severe"
|
|
25272
|
+
}
|
|
25273
|
+
];
|
|
25274
|
+
}
|
|
25275
|
+
const mcgKg = mcgPerKgDayVosoritide(row, rounded);
|
|
25276
|
+
return [
|
|
25277
|
+
{ label: "Agent", value: "Vosoritide (daily)" },
|
|
25278
|
+
{ label: "Dose", value: row.doseMg.toFixed(3), unit: "mg" },
|
|
25279
|
+
{ label: "Approx. intensity", value: mcgKg.toFixed(1), unit: "mcg/kg/day" },
|
|
25280
|
+
{ label: "Vial", value: String(row.vialMg), unit: "mg" },
|
|
25281
|
+
{ label: "Concentration", value: row.reconcentration.toFixed(1), unit: "mg/mL" },
|
|
25282
|
+
{ label: "Injection volume", value: row.volumeMl.toFixed(2), unit: "mL" }
|
|
25283
|
+
];
|
|
25284
|
+
}
|
|
25119
25285
|
function parseUsagePattern(raw) {
|
|
25120
25286
|
const compactNormalized = raw.replace(/:(\d+),(\d+)/g, ":$1.$2");
|
|
25121
25287
|
const compactParts = compactNormalized.split(/[,;]/).map((p) => p.trim());
|
|
@@ -25285,12 +25451,25 @@ function executeCorrectedAge(args) {
|
|
|
25285
25451
|
return rows;
|
|
25286
25452
|
}
|
|
25287
25453
|
function executeBmdSds(args) {
|
|
25454
|
+
const siteRaw = String(args.site);
|
|
25455
|
+
const validSites = ["spine", "neck", "tblh"];
|
|
25456
|
+
if (!validSites.includes(siteRaw)) {
|
|
25457
|
+
return [
|
|
25458
|
+
{
|
|
25459
|
+
label: "Error",
|
|
25460
|
+
value: `BMD SDS supports sites: ${validSites.join(", ")}. Retry with one of those.`,
|
|
25461
|
+
severity: "severe"
|
|
25462
|
+
}
|
|
25463
|
+
];
|
|
25464
|
+
}
|
|
25465
|
+
const isTblh = siteRaw === "tblh";
|
|
25288
25466
|
const result = calculateBmdSds({
|
|
25289
25467
|
value: Number(args.value),
|
|
25290
25468
|
age: Number(args.age),
|
|
25291
25469
|
sex: String(args.sex),
|
|
25292
|
-
site:
|
|
25293
|
-
measure: "
|
|
25470
|
+
site: isTblh ? "spine" : siteRaw,
|
|
25471
|
+
measure: "aBMD",
|
|
25472
|
+
...isTblh && { dataset: "tblh" }
|
|
25294
25473
|
});
|
|
25295
25474
|
const ageVal = Number(args.age);
|
|
25296
25475
|
const sexVal = String(args.sex);
|
|
@@ -26039,6 +26218,44 @@ function executeCorrectedSodium(args) {
|
|
|
26039
26218
|
];
|
|
26040
26219
|
}
|
|
26041
26220
|
|
|
26221
|
+
// ../src/lib/chat/chatToolIdMapping.ts
|
|
26222
|
+
var CHAT_FUNCTION_NAME_ALIASES = {
|
|
26223
|
+
hba1c: "hba1c-estimation",
|
|
26224
|
+
"igf-lagh-adjustment": "igf-sds-lagh-adjustment"
|
|
26225
|
+
};
|
|
26226
|
+
var CHAT_NAME_CATEGORY_OVERRIDE = {
|
|
26227
|
+
"decimal-age": "misc"
|
|
26228
|
+
};
|
|
26229
|
+
function chatFunctionToMetadataId(chatFunctionName) {
|
|
26230
|
+
return CHAT_FUNCTION_NAME_ALIASES[chatFunctionName] ?? chatFunctionName;
|
|
26231
|
+
}
|
|
26232
|
+
function chatFunctionCategoryOverride(chatFunctionName) {
|
|
26233
|
+
return CHAT_NAME_CATEGORY_OVERRIDE[chatFunctionName];
|
|
26234
|
+
}
|
|
26235
|
+
|
|
26236
|
+
// ../src/lib/hiddenToolIds.ts
|
|
26237
|
+
var HIDDEN_TOOL_IDS = [
|
|
26238
|
+
"steroid-tapering",
|
|
26239
|
+
"periop-adrenal",
|
|
26240
|
+
"preop-diabetes",
|
|
26241
|
+
"dka-fluid",
|
|
26242
|
+
"gri",
|
|
26243
|
+
"basal-bolus",
|
|
26244
|
+
"meal-bolus",
|
|
26245
|
+
"custom-iv-fluid",
|
|
26246
|
+
"cp-height",
|
|
26247
|
+
"oral-phosphorus",
|
|
26248
|
+
"corrected-calcium",
|
|
26249
|
+
"gfr",
|
|
26250
|
+
"leptin-sds"
|
|
26251
|
+
];
|
|
26252
|
+
function isToolVisible(toolId, isUnlocked) {
|
|
26253
|
+
if (!HIDDEN_TOOL_IDS.includes(toolId)) {
|
|
26254
|
+
return true;
|
|
26255
|
+
}
|
|
26256
|
+
return isUnlocked;
|
|
26257
|
+
}
|
|
26258
|
+
|
|
26042
26259
|
// ../src/lib/chat/toolSchemas.ts
|
|
26043
26260
|
var toolSchemas = [
|
|
26044
26261
|
// ╔══════════════════════════════════════════╗
|
|
@@ -26048,7 +26265,7 @@ var toolSchemas = [
|
|
|
26048
26265
|
type: "function",
|
|
26049
26266
|
function: {
|
|
26050
26267
|
name: "decimal-age",
|
|
26051
|
-
description: "Calculate decimal age(s) from birth date(s). Accepts one or multiple comma-separated birth dates. Returns decimal age in years for each.
|
|
26268
|
+
description: "Calculate decimal age(s) from birth date(s). Accepts one or multiple comma-separated birth dates. Returns decimal age in years for each.",
|
|
26052
26269
|
parameters: {
|
|
26053
26270
|
type: "object",
|
|
26054
26271
|
properties: {
|
|
@@ -26076,8 +26293,8 @@ var toolSchemas = [
|
|
|
26076
26293
|
height: { type: "number", description: "Height in cm [optional]" },
|
|
26077
26294
|
weight: { type: "number", description: "Weight in kg [optional]" },
|
|
26078
26295
|
headCircumference: { type: "number", description: "Head circumference in cm [optional]" },
|
|
26079
|
-
dataset: { type: "string", description:
|
|
26080
|
-
syndrome: { type: "string", description: 'Condition dataset ID.
|
|
26296
|
+
dataset: { type: "string", description: "Standard dataset [default: neyzi]", enum: ["neyzi", "who", "cdc-extended-2022"] },
|
|
26297
|
+
syndrome: { type: "string", description: 'Condition dataset ID. Use "none" for standard growth.', enum: ["none", ...auxologySyndromeDatasetIds] }
|
|
26081
26298
|
},
|
|
26082
26299
|
required: ["sex", "age"]
|
|
26083
26300
|
}
|
|
@@ -26092,13 +26309,13 @@ var toolSchemas = [
|
|
|
26092
26309
|
type: "object",
|
|
26093
26310
|
properties: {
|
|
26094
26311
|
sex: { type: "string", description: "Sex", enum: ["male", "female"] },
|
|
26095
|
-
currentAge: { type: "number", description: "Age at last measurement in years
|
|
26312
|
+
currentAge: { type: "number", description: "Age at last measurement in years" },
|
|
26096
26313
|
previousAge: { type: "number", description: "Previous age in years [optional if intervalMonths given]" },
|
|
26097
26314
|
currentHeight: { type: "number", description: "Current height in cm [optional if heightChange given]" },
|
|
26098
26315
|
previousHeight: { type: "number", description: "Previous height in cm [optional if heightChange given]" },
|
|
26099
26316
|
heightChange: { type: "number", description: "Height gained in cm [optional, alternative to two heights]" },
|
|
26100
26317
|
intervalMonths: { type: "number", description: "Interval between measurements in months [optional, alternative to two ages]" },
|
|
26101
|
-
dataset: { type: "string", description: "
|
|
26318
|
+
dataset: { type: "string", description: "Reference dataset [default: auto by age]", enum: ["neyzi", "kelly", "baumgartner", "tanner", "who", "achondroplasia"] }
|
|
26102
26319
|
},
|
|
26103
26320
|
required: ["sex", "currentAge"]
|
|
26104
26321
|
}
|
|
@@ -26108,15 +26325,15 @@ var toolSchemas = [
|
|
|
26108
26325
|
type: "function",
|
|
26109
26326
|
function: {
|
|
26110
26327
|
name: "predicted-height",
|
|
26111
|
-
description:
|
|
26328
|
+
description: "Predicted adult height. Three modes: (1) Target height from parental heights. (2) Bayley-Pinneau (default): height + bone age. (3) RWT (Roche-Wainer-Thissen): height + weight + bone age + parents.",
|
|
26112
26329
|
parameters: {
|
|
26113
26330
|
type: "object",
|
|
26114
26331
|
properties: {
|
|
26115
26332
|
sex: { type: "string", description: "Sex", enum: ["male", "female"] },
|
|
26116
|
-
method: { type: "string", description: "PAH method
|
|
26117
|
-
height: { type: "number", description: "Current height in cm [
|
|
26118
|
-
weight: { type: "number", description: "Weight in kg [required for RWT
|
|
26119
|
-
boneAge: { type: "number", description: "Bone age in years [
|
|
26333
|
+
method: { type: "string", description: "PAH method [default: bayley-pinneau]", enum: ["bayley-pinneau", "rwt"] },
|
|
26334
|
+
height: { type: "number", description: "Current height in cm [optional]" },
|
|
26335
|
+
weight: { type: "number", description: "Weight in kg [optional, required for RWT]" },
|
|
26336
|
+
boneAge: { type: "number", description: "Bone age in years [optional]" },
|
|
26120
26337
|
chronologicalAge: { type: "number", description: "Chronological age in years" },
|
|
26121
26338
|
motherHeight: { type: "number", description: "Mother height in cm" },
|
|
26122
26339
|
fatherHeight: { type: "number", description: "Father height in cm" }
|
|
@@ -26138,8 +26355,8 @@ var toolSchemas = [
|
|
|
26138
26355
|
igf1Value: { type: "number", description: "IGF-1 concentration in ng/mL [optional]" },
|
|
26139
26356
|
igfbp3Value: { type: "number", description: "IGFBP-3 concentration [optional]" },
|
|
26140
26357
|
igfbp3Unit: { type: "string", description: "IGFBP-3 unit [default: mcg/mL]", enum: ["mcg/mL", "ng/mL"] },
|
|
26141
|
-
igf1Database: { type: "string", description: "IGF-1 reference kit. elmlinger = CLIA
|
|
26142
|
-
igfbp3Database: { type: "string", description: "IGFBP-3 reference kit. elmlinger = CLIA
|
|
26358
|
+
igf1Database: { type: "string", description: "IGF-1 reference kit. elmlinger = CLIA/IMMULITE (default). eclia = ECLIA/Roche. guven = G\xFCven.", enum: ["elmlinger", "eclia", "guven"] },
|
|
26359
|
+
igfbp3Database: { type: "string", description: "IGFBP-3 reference kit. elmlinger = CLIA/IMMULITE (default). ria-bc = RIA/Beckman Coulter. guven = G\xFCven.", enum: ["elmlinger", "ria-bc", "guven"] }
|
|
26143
26360
|
},
|
|
26144
26361
|
required: ["age", "sex"]
|
|
26145
26362
|
}
|
|
@@ -26156,24 +26373,39 @@ var toolSchemas = [
|
|
|
26156
26373
|
sex: { type: "string", description: "Sex", enum: ["male", "female"] },
|
|
26157
26374
|
age: { type: "number", description: "Age in years" },
|
|
26158
26375
|
height: { type: "number", description: "Standing height in cm" },
|
|
26159
|
-
sittingHeight: { type: "number", description: "Sitting height in cm [optional]
|
|
26160
|
-
armSpan: { type: "number", description: "Arm span in cm [optional]
|
|
26376
|
+
sittingHeight: { type: "number", description: "Sitting height in cm [optional]" },
|
|
26377
|
+
armSpan: { type: "number", description: "Arm span in cm [optional]" }
|
|
26161
26378
|
},
|
|
26162
26379
|
required: ["sex", "age", "height"]
|
|
26163
26380
|
}
|
|
26164
26381
|
}
|
|
26165
26382
|
},
|
|
26383
|
+
{
|
|
26384
|
+
type: "function",
|
|
26385
|
+
function: {
|
|
26386
|
+
name: "cnp-analogue",
|
|
26387
|
+
description: "CNP analogue dosing for achondroplasia. daily = vosoritide (label weight-band table, ~15 mcg/kg/day). weekly = navepegritide 100 mcg/kg/week SC.",
|
|
26388
|
+
parameters: {
|
|
26389
|
+
type: "object",
|
|
26390
|
+
properties: {
|
|
26391
|
+
mode: { type: "string", description: "daily (vosoritide) or weekly (navepegritide)", enum: ["daily", "weekly"] },
|
|
26392
|
+
weightKg: { type: "number", description: "Body weight in kg (daily table uses weight rounded to nearest kg)" }
|
|
26393
|
+
},
|
|
26394
|
+
required: ["mode", "weightKg"]
|
|
26395
|
+
}
|
|
26396
|
+
}
|
|
26397
|
+
},
|
|
26166
26398
|
{
|
|
26167
26399
|
type: "function",
|
|
26168
26400
|
function: {
|
|
26169
26401
|
name: "growth-hormone",
|
|
26170
|
-
description: 'Growth hormone dosing analysis.
|
|
26402
|
+
description: 'Growth hormone dosing analysis. Weekly schedule as "days:doseMg,days:doseMg" (days 1-7, supports off-day schedules).',
|
|
26171
26403
|
parameters: {
|
|
26172
26404
|
type: "object",
|
|
26173
26405
|
properties: {
|
|
26174
|
-
weight: { type: "number", description: "Weight in kg
|
|
26175
|
-
usagePattern: { type: "string", description: 'Compact format "days:doseMg,days:doseMg".
|
|
26176
|
-
concentrationIU: { type: "number", description:
|
|
26406
|
+
weight: { type: "number", description: "Weight in kg" },
|
|
26407
|
+
usagePattern: { type: "string", description: 'Compact format "days:doseMg,days:doseMg". Days can sum to 1-7 (supports off-day schedules).' },
|
|
26408
|
+
concentrationIU: { type: "number", description: "Preparation concentration in IU (mg\xD73) [optional, for box calculation]" }
|
|
26177
26409
|
},
|
|
26178
26410
|
required: ["weight", "usagePattern"]
|
|
26179
26411
|
}
|
|
@@ -26183,7 +26415,7 @@ var toolSchemas = [
|
|
|
26183
26415
|
type: "function",
|
|
26184
26416
|
function: {
|
|
26185
26417
|
name: "igf-lagh-adjustment",
|
|
26186
|
-
description: "Adjust IGF-1 value for long-acting growth hormone (somatrogon). Corrects measured IGF-1 based on hours after dose.
|
|
26418
|
+
description: "Adjust IGF-1 value for long-acting growth hormone (somatrogon). Corrects measured IGF-1 based on hours after dose.",
|
|
26187
26419
|
parameters: {
|
|
26188
26420
|
type: "object",
|
|
26189
26421
|
properties: {
|
|
@@ -26201,7 +26433,7 @@ var toolSchemas = [
|
|
|
26201
26433
|
type: "function",
|
|
26202
26434
|
function: {
|
|
26203
26435
|
name: "neonatal-parameters",
|
|
26204
|
-
description: "Calculate SDS/percentile for neonatal birth parameters (weight, length, head circumference) by gestational week.
|
|
26436
|
+
description: "Calculate SDS/percentile for neonatal birth parameters (weight, length, head circumference) by gestational week. Uses Fenton (2025) or Kurto\u011Flu (2012) reference data.",
|
|
26205
26437
|
parameters: {
|
|
26206
26438
|
type: "object",
|
|
26207
26439
|
properties: {
|
|
@@ -26248,7 +26480,7 @@ var toolSchemas = [
|
|
|
26248
26480
|
sex: { type: "string", description: "Sex", enum: ["male", "female"] },
|
|
26249
26481
|
age: { type: "number", description: "Age in years" },
|
|
26250
26482
|
value: { type: "number", description: "BMD value in g/cm\xB2" },
|
|
26251
|
-
site: { type: "string", description: "
|
|
26483
|
+
site: { type: "string", description: "DXA measurement site: spine (L1-L4), neck (femoral neck), or tblh (total body less head)", enum: ["spine", "neck", "tblh"] }
|
|
26252
26484
|
},
|
|
26253
26485
|
required: ["sex", "age", "value", "site"]
|
|
26254
26486
|
}
|
|
@@ -26386,9 +26618,9 @@ var toolSchemas = [
|
|
|
26386
26618
|
type: "object",
|
|
26387
26619
|
properties: {
|
|
26388
26620
|
insulin: { type: "number", description: "Insulin value" },
|
|
26389
|
-
insulinUnit: { type: "string", description: "Insulin unit", enum: [
|
|
26621
|
+
insulinUnit: { type: "string", description: "Insulin unit", enum: [...INSULIN_UNITS] },
|
|
26390
26622
|
cPeptide: { type: "number", description: "C-Peptide value" },
|
|
26391
|
-
cPeptideUnit: { type: "string", description: "C-Peptide unit", enum: [
|
|
26623
|
+
cPeptideUnit: { type: "string", description: "C-Peptide unit", enum: [...CPEPTIDE_UNITS] }
|
|
26392
26624
|
},
|
|
26393
26625
|
required: ["insulin", "insulinUnit", "cPeptide", "cPeptideUnit"]
|
|
26394
26626
|
}
|
|
@@ -26401,7 +26633,7 @@ var toolSchemas = [
|
|
|
26401
26633
|
type: "function",
|
|
26402
26634
|
function: {
|
|
26403
26635
|
name: "steroid-conversion",
|
|
26404
|
-
description: "Convert equivalent doses between glucocorticoids
|
|
26636
|
+
description: "Convert equivalent doses between glucocorticoids (Hydrocortisone, Prednisolone, Methylprednisolone, Dexamethasone).",
|
|
26405
26637
|
parameters: {
|
|
26406
26638
|
type: "object",
|
|
26407
26639
|
properties: {
|
|
@@ -26587,7 +26819,7 @@ var toolSchemas = [
|
|
|
26587
26819
|
parameters: {
|
|
26588
26820
|
type: "object",
|
|
26589
26821
|
properties: {
|
|
26590
|
-
substance: { type: "string", description: "Substance to convert.
|
|
26822
|
+
substance: { type: "string", description: "Substance to convert (e.g. testosterone, cortisol, estradiol, glucose, calcium, insulin, igf1, prolactin, etc.)" },
|
|
26591
26823
|
value: { type: "number", description: "Numeric value to convert" },
|
|
26592
26824
|
fromUnit: { type: "string", description: "Source unit (e.g. ng/dL, nmol/L, mg/dL, mmol/L, \xB5g/dL, pg/mL, pmol/L, ng/mL, \xB5U/mL, mIU/L)" }
|
|
26593
26825
|
},
|
|
@@ -26599,7 +26831,7 @@ var toolSchemas = [
|
|
|
26599
26831
|
type: "function",
|
|
26600
26832
|
function: {
|
|
26601
26833
|
name: "osmolality",
|
|
26602
|
-
description: "Calculate serum or urine osmolality. Serum: 2\xD7Na + Glucose/18 + BUN/2.8. Urine: 2\xD7(Na+K) + Glucose/18 + UUN/2.8.
|
|
26834
|
+
description: "Calculate serum or urine osmolality. Serum: 2\xD7Na + Glucose/18 + BUN/2.8. Urine: 2\xD7(Na+K) + Glucose/18 + UUN/2.8.",
|
|
26603
26835
|
parameters: {
|
|
26604
26836
|
type: "object",
|
|
26605
26837
|
properties: {
|
|
@@ -26631,6 +26863,12 @@ var toolSchemas = [
|
|
|
26631
26863
|
}
|
|
26632
26864
|
}
|
|
26633
26865
|
];
|
|
26866
|
+
function isChatCatalogSchema(s) {
|
|
26867
|
+
const name = s.function.name;
|
|
26868
|
+
const metaId = chatFunctionToMetadataId(name);
|
|
26869
|
+
return isToolVisible(metaId, false);
|
|
26870
|
+
}
|
|
26871
|
+
var chatToolSchemas = toolSchemas.filter(isChatCatalogSchema);
|
|
26634
26872
|
|
|
26635
26873
|
// ../src/data/toolMetadata.ts
|
|
26636
26874
|
var toolsMetadata = [
|
|
@@ -26675,16 +26913,6 @@ var toolsMetadata = [
|
|
|
26675
26913
|
subtitleFallback: "Growth hormone dose calculator",
|
|
26676
26914
|
searchKeywords: ["GH", "b\xFCy\xFCme hormonu", "somatropin", "Norditropin", "Genotropin", "Nutropin", "doz", "dose", "IU", "mg"]
|
|
26677
26915
|
},
|
|
26678
|
-
{
|
|
26679
|
-
id: "cnp-analogue",
|
|
26680
|
-
category: "growth",
|
|
26681
|
-
type: "calcs",
|
|
26682
|
-
titleKey: "tools.cnp-analogue.title",
|
|
26683
|
-
subtitleKey: "tools.cnp-analogue.subtitle",
|
|
26684
|
-
titleFallback: "CNP Analogue",
|
|
26685
|
-
subtitleFallback: "Vosoritide & navepegritide dosing",
|
|
26686
|
-
searchKeywords: ["vosoritide", "CNP", "achondroplasia", "akondroplazi", "navepegritide", "natriuretic peptide", "doz", "dose", "c\xFCcelik", "dwarfism", "skeletal dysplasia", "cnp analogue", "cnp analog"]
|
|
26687
|
-
},
|
|
26688
26916
|
{
|
|
26689
26917
|
id: "igf-sds",
|
|
26690
26918
|
category: "growth",
|
|
@@ -26692,8 +26920,8 @@ var toolsMetadata = [
|
|
|
26692
26920
|
titleKey: "tools.igf-sds.title",
|
|
26693
26921
|
subtitleKey: "tools.igf-sds.subtitle",
|
|
26694
26922
|
titleFallback: "IGF-1 & IGFBP-3 SDS",
|
|
26695
|
-
subtitleFallback: "Age
|
|
26696
|
-
searchKeywords: ["IGF-1", "IGFBP-3", "somatomedin", "
|
|
26923
|
+
subtitleFallback: "Age-based IGF-1 & IGFBP-3 SDS calculation",
|
|
26924
|
+
searchKeywords: ["IGF-1", "IGFBP-3", "somatomedin", "SDS"]
|
|
26697
26925
|
},
|
|
26698
26926
|
{
|
|
26699
26927
|
id: "igf-sds-lagh-adjustment",
|
|
@@ -26735,6 +26963,16 @@ var toolsMetadata = [
|
|
|
26735
26963
|
subtitleFallback: "Height estimation from segmental measurements",
|
|
26736
26964
|
searchKeywords: ["serebral palsi", "cerebral palsy", "CP", "segmental", "segment", "Stevenson", "boy tahmini"]
|
|
26737
26965
|
},
|
|
26966
|
+
{
|
|
26967
|
+
id: "cnp-analogue",
|
|
26968
|
+
category: "growth",
|
|
26969
|
+
type: "calcs",
|
|
26970
|
+
titleKey: "tools.cnp-analogue.title",
|
|
26971
|
+
subtitleKey: "tools.cnp-analogue.subtitle",
|
|
26972
|
+
titleFallback: "CNP Analogue",
|
|
26973
|
+
subtitleFallback: "Vosoritide & navepegritide dosing",
|
|
26974
|
+
searchKeywords: ["vosoritide", "CNP", "achondroplasia", "akondroplazi", "navepegritide", "natriuretic peptide", "doz", "dose", "c\xFCcelik", "dwarfism", "skeletal dysplasia", "cnp analogue", "cnp analog"]
|
|
26975
|
+
},
|
|
26738
26976
|
// BONE CATEGORY
|
|
26739
26977
|
{
|
|
26740
26978
|
id: "bmd-sds",
|
|
@@ -27008,7 +27246,26 @@ var toolsMetadata = [
|
|
|
27008
27246
|
subtitleKey: "tools.thyroid-volume.subtitle",
|
|
27009
27247
|
titleFallback: "Thyroid",
|
|
27010
27248
|
subtitleFallback: "Thyroid volume SDS",
|
|
27011
|
-
searchKeywords: [
|
|
27249
|
+
searchKeywords: [
|
|
27250
|
+
"tiroid",
|
|
27251
|
+
"thyroid",
|
|
27252
|
+
"guatr",
|
|
27253
|
+
"goiter",
|
|
27254
|
+
"hacim",
|
|
27255
|
+
"volume",
|
|
27256
|
+
"USG",
|
|
27257
|
+
"ultrason",
|
|
27258
|
+
"SDS",
|
|
27259
|
+
"neonatal thyroid",
|
|
27260
|
+
"yenido\u011Fan tiroid",
|
|
27261
|
+
"newborn thyroid",
|
|
27262
|
+
"gestational",
|
|
27263
|
+
"gestasyon",
|
|
27264
|
+
"TSH",
|
|
27265
|
+
"Kurto\u011Flu",
|
|
27266
|
+
"Mutlu",
|
|
27267
|
+
"Tuzcu"
|
|
27268
|
+
]
|
|
27012
27269
|
},
|
|
27013
27270
|
{
|
|
27014
27271
|
id: "pituitary-height",
|
|
@@ -27094,23 +27351,6 @@ var toolsMetadata = [
|
|
|
27094
27351
|
}
|
|
27095
27352
|
];
|
|
27096
27353
|
|
|
27097
|
-
// ../src/lib/hiddenToolIds.ts
|
|
27098
|
-
var HIDDEN_TOOL_IDS = [
|
|
27099
|
-
"steroid-tapering",
|
|
27100
|
-
"periop-adrenal",
|
|
27101
|
-
"preop-diabetes",
|
|
27102
|
-
"dka-fluid",
|
|
27103
|
-
"gri",
|
|
27104
|
-
"basal-bolus",
|
|
27105
|
-
"meal-bolus",
|
|
27106
|
-
"custom-iv-fluid",
|
|
27107
|
-
"cp-height",
|
|
27108
|
-
"oral-phosphorus",
|
|
27109
|
-
"corrected-calcium",
|
|
27110
|
-
"gfr",
|
|
27111
|
-
"leptin-sds"
|
|
27112
|
-
];
|
|
27113
|
-
|
|
27114
27354
|
// src/formatter.ts
|
|
27115
27355
|
var useColor = !process.env.NO_COLOR && !!process.stdout.isTTY;
|
|
27116
27356
|
var bold = (s) => useColor ? `\x1B[1m${s}\x1B[0m` : s;
|
|
@@ -27187,26 +27427,15 @@ var cyan2 = (s) => useColor2 ? `\x1B[36m${s}\x1B[0m` : s;
|
|
|
27187
27427
|
var green = (s) => useColor2 ? `\x1B[32m${s}\x1B[0m` : s;
|
|
27188
27428
|
var yellow2 = (s) => useColor2 ? `\x1B[33m${s}\x1B[0m` : s;
|
|
27189
27429
|
var magenta = (s) => useColor2 ? `\x1B[35m${s}\x1B[0m` : s;
|
|
27190
|
-
var VERSION = true ? "0.
|
|
27191
|
-
var visibleSchemas =
|
|
27192
|
-
(s) => !HIDDEN_TOOL_IDS.includes(s.function.name)
|
|
27193
|
-
);
|
|
27194
|
-
var SCHEMA_TO_META = {
|
|
27195
|
-
"hba1c": "hba1c-estimation",
|
|
27196
|
-
"igf-lagh-adjustment": "igf-sds-lagh-adjustment",
|
|
27197
|
-
"decimal-age": "decimal-age"
|
|
27198
|
-
// no metadata entry — handled by fallback category
|
|
27199
|
-
};
|
|
27200
|
-
var CATEGORY_OVERRIDE = {
|
|
27201
|
-
"igf-lagh-adjustment": "growth",
|
|
27202
|
-
"decimal-age": "misc"
|
|
27203
|
-
};
|
|
27430
|
+
var VERSION = true ? "0.2.0" : "0.0.0-dev";
|
|
27431
|
+
var visibleSchemas = chatToolSchemas;
|
|
27204
27432
|
function findMeta(schemaId) {
|
|
27205
|
-
const mappedId =
|
|
27433
|
+
const mappedId = chatFunctionToMetadataId(schemaId);
|
|
27206
27434
|
return toolsMetadata.find((m) => m.id === mappedId);
|
|
27207
27435
|
}
|
|
27208
27436
|
function getCategoryForSchema(schemaId) {
|
|
27209
|
-
|
|
27437
|
+
const override = chatFunctionCategoryOverride(schemaId);
|
|
27438
|
+
if (override) return override;
|
|
27210
27439
|
const meta = findMeta(schemaId);
|
|
27211
27440
|
return meta?.category ?? "misc";
|
|
27212
27441
|
}
|
|
@@ -27288,6 +27517,7 @@ ${bold2("USAGE")}
|
|
|
27288
27517
|
|
|
27289
27518
|
${bold2("OPTIONS")}
|
|
27290
27519
|
--format human|json ${dim2("Output format (default: human)")}
|
|
27520
|
+
--pipe ${dim2("Output only decimal age(s) for command chaining")}
|
|
27291
27521
|
--help ${dim2("Show this help")}
|
|
27292
27522
|
--version ${dim2("Show version")}
|
|
27293
27523
|
|
|
@@ -27455,7 +27685,7 @@ function parseKeyValueArgs(pairs, schema) {
|
|
|
27455
27685
|
}
|
|
27456
27686
|
return args;
|
|
27457
27687
|
}
|
|
27458
|
-
function runToolWithArgs(name, args, format) {
|
|
27688
|
+
function runToolWithArgs(name, args, format, pipe) {
|
|
27459
27689
|
const schema = getSchemaByName(name);
|
|
27460
27690
|
const errors = validateArgs(name, args);
|
|
27461
27691
|
if (errors.length > 0) {
|
|
@@ -27474,7 +27704,17 @@ ${yellow2("!")} Validation errors for ${bold2(name)}:`);
|
|
|
27474
27704
|
console.error(`${yellow2("!")} Error executing ${bold2(name)}:`, err instanceof Error ? err.message : err);
|
|
27475
27705
|
process.exit(1);
|
|
27476
27706
|
}
|
|
27477
|
-
if (
|
|
27707
|
+
if (pipe && name === "decimal-age") {
|
|
27708
|
+
for (const r of results) {
|
|
27709
|
+
if (r.label === "Desimal ya\u015F") {
|
|
27710
|
+
const match = r.value.match(/([\d,]+)\s*yıl/);
|
|
27711
|
+
if (match) console.log(match[1].replace(",", "."));
|
|
27712
|
+
} else if (r.tag !== "echo" && r.value.includes("y\u0131l") && r.label.match(/^\d{2}\/\d{2}\/\d{4}$/)) {
|
|
27713
|
+
const match = r.value.match(/\(([\d,]+)\s*yıl\)/);
|
|
27714
|
+
if (match) console.log(match[1].replace(",", "."));
|
|
27715
|
+
}
|
|
27716
|
+
}
|
|
27717
|
+
} else if (format === "json") {
|
|
27478
27718
|
const dataResults = results.filter((r) => r.tag !== "alt" && r.tag !== "sexAlt");
|
|
27479
27719
|
console.log(JSON.stringify(dataResults, null, 2));
|
|
27480
27720
|
} else {
|
|
@@ -27491,7 +27731,8 @@ function main() {
|
|
|
27491
27731
|
schemas: { type: "boolean" },
|
|
27492
27732
|
schema: { type: "boolean" },
|
|
27493
27733
|
args: { type: "string", short: "a" },
|
|
27494
|
-
format: { type: "string", short: "f", default: "human" }
|
|
27734
|
+
format: { type: "string", short: "f", default: "human" },
|
|
27735
|
+
pipe: { type: "boolean", short: "p" }
|
|
27495
27736
|
}
|
|
27496
27737
|
});
|
|
27497
27738
|
if (values.help && positionals.length === 0) {
|
|
@@ -27556,10 +27797,10 @@ Apache-2.0 \xA9 \xC7EDD / TSPED`);
|
|
|
27556
27797
|
console.error(`${yellow2("!")} Invalid JSON in --args: ${values.args}`);
|
|
27557
27798
|
process.exit(1);
|
|
27558
27799
|
}
|
|
27559
|
-
runToolWithArgs(toolName, args, format);
|
|
27800
|
+
runToolWithArgs(toolName, args, format, values.pipe);
|
|
27560
27801
|
} else if (kvPairs.length > 0) {
|
|
27561
27802
|
const args = parseKeyValueArgs(kvPairs, schema);
|
|
27562
|
-
runToolWithArgs(toolName, args, format);
|
|
27803
|
+
runToolWithArgs(toolName, args, format, values.pipe);
|
|
27563
27804
|
} else {
|
|
27564
27805
|
printToolInfo(toolName);
|
|
27565
27806
|
}
|