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.
Files changed (2) hide show
  1. package/dist/index.js +411 -170
  2. 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 { years, months, totalDecimal } = ageBreakdown(bd, refDate);
24460
- const decimalStr = totalDecimal.toFixed(2).replace(".", ",");
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: String(args.site),
25293
- measure: "bmd"
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. Use when user ONLY wants age calculation without growth parameters.",
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: 'Standard dataset. Use exact IDs from auxology dropdown: neyzi, who, cdc-extended-2022. "CDC" means cdc-extended-2022. [default: neyzi]', enum: ["neyzi", "who", "cdc-extended-2022"] },
26080
- syndrome: { type: "string", description: 'Condition dataset ID. Turner: turner-darendeliler, turner-ranke, turner-lyon, turner-rongen, turner-isojima. Use "none" for standard growth. When user says "standart neyzi" or "standard neyzi", use syndrome: none and dataset: neyzi.', enum: ["none", ...auxologySyndromeDatasetIds] }
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 (REQUIRED \u2014 do not assume from interval)" },
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: "Height-velocity dataset (different from auxology): who (age <5), neyzi (8\u201315 boys), kelly (5.5\u201318), baumgartner (0\u201318), tanner (0\u201319), achondroplasia. [default: who for age<5, neyzi for older]", enum: ["neyzi", "kelly", "baumgartner", "tanner", "who", "achondroplasia"] }
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: 'Three modes: (1) TARGET HEIGHT from parental heights: motherHeight + fatherHeight + sex. (2) Bayley-Pinneau (default): height + boneAge + sex. (3) RWT (Roche-Wainer-Thissen): height + weight + boneAge + chronologicalAge + motherHeight + fatherHeight + sex. User says "rwt/RWT" \u2192 method=rwt.',
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. bayley-pinneau (default, aka BP/PAH/\xD6EB/pah). rwt = Roche-Wainer-Thissen (needs weight + parents + chronologicalAge).", enum: ["bayley-pinneau", "rwt"] },
26117
- height: { type: "number", description: "Current height in cm [for PAH methods, NOT for target height from parents]" },
26118
- weight: { type: "number", description: "Weight in kg [required for RWT only]" },
26119
- boneAge: { type: "number", description: "Bone age in years [for PAH methods]" },
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 / IMMULITE / Siemens Immulite (default). eclia = ECLIA / Roche / Elecsys / Cobas. guven = G\xFCven (Turkish reference). When user mentions a kit/assay name, match to the correct enum.", enum: ["elmlinger", "eclia", "guven"] },
26142
- igfbp3Database: { type: "string", description: "IGFBP-3 reference kit. elmlinger = CLIA / IMMULITE / Siemens Immulite (default). ria-bc = RIA / Beckman Coulter / RIA-BC. guven = G\xFCven (Turkish reference). When user mentions a kit/assay name, match to the correct enum.", enum: ["elmlinger", "ria-bc", "guven"] }
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]. Turkish: ob, oturma boyu. NOT kula\xE7/kulac (that is armSpan)." },
26160
- armSpan: { type: "number", description: "Arm span in cm [optional]. Turkish: kulac, kulac boyu, kula\xE7 boyu = arm span." }
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. Extract weight, weekly schedule as "days:doseMg,days:doseMg" (days 1-7, supports off-day schedules), and optional concentration in IU/ml.',
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 (extract from user text)" },
26175
- usagePattern: { type: "string", description: 'Compact format "days:doseMg,days:doseMg". Extract from user text and convert. Days can sum to 1-7 (supports off-day schedules like 6 days on / 1 day off).' },
26176
- concentrationIU: { type: "number", description: 'Preparation concentration in IU (mg\xD73). IMPORTANT for box calc. Brand\u2192IU: Genotropin 5mg\u219215, 12mg\u219236. Norditropin 5mg\u219215, 10mg\u219230, 15mg\u219245. Omnitrope 5mg\u219215, 10mg\u219230, 15mg\u219245. Humatrope 6mg\u219218, 12mg\u219236, 24mg\u219272. Saizen 6mg\u219218, 12mg\u219236, 20mg\u219260. Or direct "30 IU/ml".' }
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. NOT for growth hormone dose calculation \u2014 use growth-hormone tool for that.",
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. Requires sex \u2014 do NOT assume male if user omits it; ask. Uses Fenton (2025) or Kurto\u011Flu (2012) reference data.",
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: "Measurement site", enum: ["spine", "hip", "femoral-neck", "total-body", "forearm"] }
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: ["uIU/mL", "mIU/L", "pmol/L"] },
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: ["ng/mL", "nmol/L", "pmol/L"] }
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. Enter a dose of one steroid and get equivalents for all others. Ratios: Hydrocortisone 1x, Prednisolone 4x, Methylprednisolone 5x, Dexamethasone 30x.",
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. Examples: testosterone, cortisol, estradiol, dht, dheas, glucose, calcium, phosphate, creatinine, t4, freeT4, t3, freeT3, insulin, igf1, prolactin, acth, vitamin25D, pth, aldosterone, androstenedione, ohProgesterone, progesterone, dhea, etc." },
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. If params are missing, the tool returns what to ask for \u2014 then ask the user.",
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 and Tanner stage-based",
26696
- searchKeywords: ["IGF-1", "IGFBP-3", "somatomedin", "Tanner", "evre", "stage", "SDS"]
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: ["tiroid", "thyroid", "guatr", "goiter", "hacim", "volume", "USG", "ultrason", "SDS"]
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.1.9" : "0.0.0-dev";
27191
- var visibleSchemas = toolSchemas.filter(
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 = SCHEMA_TO_META[schemaId] ?? schemaId;
27433
+ const mappedId = chatFunctionToMetadataId(schemaId);
27206
27434
  return toolsMetadata.find((m) => m.id === mappedId);
27207
27435
  }
27208
27436
  function getCategoryForSchema(schemaId) {
27209
- if (CATEGORY_OVERRIDE[schemaId]) return CATEGORY_OVERRIDE[schemaId];
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 (format === "json") {
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ceddcozum",
3
- "version": "0.1.9",
3
+ "version": "0.2.0",
4
4
  "description": "ÇEDD Çözüm pediatric clinical calculators - CLI interface",
5
5
  "license": "Apache-2.0",
6
6
  "author": "ÇEDD / TSPED",