extract AAP bilirubin threshold data
This commit is contained in:
parent
d8b8f9bdcb
commit
903cd7eca8
4 changed files with 1724 additions and 79 deletions
1582
public/data/calculators/aap-bilirubin-thresholds.json
Normal file
1582
public/data/calculators/aap-bilirubin-thresholds.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
import { parseAgeMonths, formatParsedAge } from './calculators/age.js';
|
||||
import { classifyBhutaniRisk, interpolateThreshold as interpolateBiliThreshold, loadBhutaniZones } from './calculators/bilirubin.js';
|
||||
import { calculateAapBilirubinAssessment, classifyBhutaniRisk, loadAapBilirubinThresholds, loadBhutaniZones } from './calculators/bilirubin.js';
|
||||
import { loadEquipmentData, renderEquipmentResult } from './calculators/equipment.js';
|
||||
import { initImageLightbox } from './calculators/lightbox.js';
|
||||
import { loadResusMedsData, renderResusMeds } from './calculators/resus.js';
|
||||
|
|
@ -1434,48 +1434,7 @@ initImageLightbox();
|
|||
});
|
||||
}
|
||||
|
||||
// AAP 2022 phototherapy thresholds (TSB in mg/dL) by hour of age
|
||||
// Source: Kemper et al., Pediatrics 2022;150(3):e2022058859, Figures 2-3
|
||||
// Values read from published nomogram curves at key time points
|
||||
// NOTE: The AAP 2022 raised thresholds ~2 mg/dL above the 2004 guidelines
|
||||
|
||||
// AAP 2022 — per-week phototherapy & exchange thresholds.
|
||||
// Extracted directly from peditools.org/bili2022 API (authoritative AAP 2022
|
||||
// clinical decision support tool) — 7 GA weeks × 85 hours × 2 risk profiles,
|
||||
// all 1190 values validated 1:1 against the peditools output (RMSE = 0).
|
||||
// Replaces earlier three-tier grouping (35 / 36-37 / ≥38) which returned
|
||||
// 38-week values for 39-41 week infants — underestimated thresholds by
|
||||
// up to 1.0 mg/dL and could miss phototherapy indications.
|
||||
//
|
||||
// Per AAP 2022: phototherapy NO-risk curves differ per week at 35,36,37,38,39,40+.
|
||||
// phototherapy WITH-risk plateaus at 38w (38-41 identical).
|
||||
// exchange (both risk states) plateaus at 38w.
|
||||
|
||||
// PHOTOTHERAPY — no neurotoxicity risk factors (per-week curves)
|
||||
var photoThresholds35 = {12:8.5,13:8.7,14:8.9,15:9.0,16:9.2,17:9.4,18:9.6,19:9.8,20:9.9,21:10.1,22:10.3,23:10.4,24:10.6,25:10.8,26:10.9,27:11.1,28:11.3,29:11.4,30:11.6,31:11.7,32:11.9,33:12.0,34:12.2,35:12.3,36:12.5,37:12.6,38:12.8,39:12.9,40:13.1,41:13.2,42:13.4,43:13.5,44:13.6,45:13.8,46:13.9,47:14.0,48:14.2,49:14.3,50:14.4,51:14.5,52:14.7,53:14.8,54:14.9,55:15.0,56:15.1,57:15.3,58:15.4,59:15.5,60:15.6,61:15.7,62:15.8,63:15.9,64:16.0,65:16.1,66:16.2,67:16.3,68:16.4,69:16.5,70:16.6,71:16.7,72:16.8,73:16.9,74:17.0,75:17.1,76:17.2,77:17.3,78:17.4,79:17.5,80:17.5,81:17.6,82:17.7,83:17.8,84:17.8,85:17.9,86:18.0,87:18.1,88:18.1,89:18.2,90:18.3,91:18.3,92:18.4,93:18.5,94:18.5,95:18.6,96:18.6};
|
||||
var photoThresholds36 = {12:9.0,13:9.2,14:9.4,15:9.6,16:9.8,17:9.9,18:10.1,19:10.3,20:10.5,21:10.6,22:10.8,23:11.0,24:11.2,25:11.3,26:11.5,27:11.7,28:11.8,29:12.0,30:12.1,31:12.3,32:12.5,33:12.6,34:12.8,35:12.9,36:13.1,37:13.2,38:13.4,39:13.5,40:13.7,41:13.8,42:13.9,43:14.1,44:14.2,45:14.4,46:14.5,47:14.6,48:14.8,49:14.9,50:15.0,51:15.1,52:15.3,53:15.4,54:15.5,55:15.6,56:15.8,57:15.9,58:16.0,59:16.1,60:16.2,61:16.3,62:16.5,63:16.6,64:16.7,65:16.8,66:16.9,67:17.0,68:17.1,69:17.2,70:17.3,71:17.4,72:17.5,73:17.6,74:17.7,75:17.8,76:17.9,77:17.9,78:18.0,79:18.1,80:18.2,81:18.3,82:18.4,83:18.4,84:18.5,85:18.6,86:18.7,87:18.8,88:18.8,89:18.9,90:19.0,91:19.0,92:19.1,93:19.2,94:19.2,95:19.3,96:19.3};
|
||||
var photoThresholds37 = {12:9.6,13:9.8,14:9.9,15:10.1,16:10.3,17:10.5,18:10.7,19:10.8,20:11.0,21:11.2,22:11.4,23:11.5,24:11.7,25:11.9,26:12.1,27:12.2,28:12.4,29:12.5,30:12.7,31:12.9,32:13.0,33:13.2,34:13.3,35:13.5,36:13.6,37:13.8,38:13.9,39:14.1,40:14.2,41:14.4,42:14.5,43:14.7,44:14.8,45:15.0,46:15.1,47:15.2,48:15.4,49:15.5,50:15.6,51:15.8,52:15.9,53:16.0,54:16.1,55:16.3,56:16.4,57:16.5,58:16.6,59:16.7,60:16.9,61:17.0,62:17.1,63:17.2,64:17.3,65:17.4,66:17.5,67:17.6,68:17.7,69:17.8,70:17.9,71:18.0,72:18.1,73:18.2,74:18.3,75:18.4,76:18.5,77:18.6,78:18.7,79:18.8,80:18.9,81:19.0,82:19.0,83:19.1,84:19.2,85:19.3,86:19.4,87:19.4,88:19.5,89:19.6,90:19.7,91:19.7,92:19.8,93:19.9,94:19.9,95:20.0,96:20.0};
|
||||
var photoThresholds38 = {12:10.1,13:10.3,14:10.5,15:10.7,16:10.8,17:11.0,18:11.2,19:11.4,20:11.6,21:11.7,22:11.9,23:12.1,24:12.3,25:12.4,26:12.6,27:12.8,28:12.9,29:13.1,30:13.3,31:13.4,32:13.6,33:13.8,34:13.9,35:14.1,36:14.2,37:14.4,38:14.5,39:14.7,40:14.8,41:15.0,42:15.1,43:15.3,44:15.4,45:15.6,46:15.7,47:15.8,48:16.0,49:16.1,50:16.2,51:16.4,52:16.5,53:16.6,54:16.8,55:16.9,56:17.0,57:17.1,58:17.3,59:17.4,60:17.5,61:17.6,62:17.7,63:17.8,64:17.9,65:18.1,66:18.2,67:18.3,68:18.4,69:18.5,70:18.6,71:18.7,72:18.8,73:18.9,74:19.0,75:19.1,76:19.2,77:19.3,78:19.4,79:19.5,80:19.5,81:19.6,82:19.7,83:19.8,84:19.9,85:20.0,86:20.0,87:20.1,88:20.2,89:20.3,90:20.3,91:20.4,92:20.5,93:20.6,94:20.6,95:20.7,96:20.7};
|
||||
var photoThresholds39 = {12:10.6,13:10.8,14:11.0,15:11.2,16:11.4,17:11.6,18:11.8,19:11.9,20:12.1,21:12.3,22:12.5,23:12.7,24:12.8,25:13.0,26:13.2,27:13.3,28:13.5,29:13.7,30:13.8,31:14.0,32:14.2,33:14.3,34:14.5,35:14.7,36:14.8,37:15.0,38:15.1,39:15.3,40:15.4,41:15.6,42:15.7,43:15.9,44:16.0,45:16.2,46:16.3,47:16.4,48:16.6,49:16.7,50:16.8,51:17.0,52:17.1,53:17.2,54:17.4,55:17.5,56:17.6,57:17.8,58:17.9,59:18.0,60:18.1,61:18.2,62:18.4,63:18.5,64:18.6,65:18.7,66:18.8,67:18.9,68:19.0,69:19.1,70:19.2,71:19.3,72:19.5,73:19.6,74:19.7,75:19.7,76:19.8,77:19.9,78:20.0,79:20.1,80:20.2,81:20.3,82:20.4,83:20.5,84:20.6,85:20.6,86:20.7,87:20.8,88:20.9,89:21.0,90:21.0,91:21.1,92:21.2,93:21.3,94:21.3,95:21.4,96:21.5};
|
||||
var photoThresholds40 = {12:11.1,13:11.3,14:11.5,15:11.7,16:11.9,17:12.1,18:12.2,19:12.4,20:12.6,21:12.8,22:13.0,23:13.1,24:13.3,25:13.5,26:13.6,27:13.8,28:14.0,29:14.1,30:14.3,31:14.5,32:14.6,33:14.8,34:15.0,35:15.1,36:15.3,37:15.4,38:15.6,39:15.7,40:15.9,41:16.0,42:16.2,43:16.3,44:16.4,45:16.6,46:16.7,47:16.9,48:17.0,49:17.1,50:17.3,51:17.4,52:17.5,53:17.7,54:17.8,55:17.9,56:18.0,57:18.2,58:18.3,59:18.4,60:18.5,61:18.6,62:18.8,63:18.9,64:19.0,65:19.1,66:19.2,67:19.3,68:19.4,69:19.5,70:19.6,71:19.7,72:19.8,73:19.9,74:20.0,75:20.1,76:20.2,77:20.3,78:20.4,79:20.5,80:20.6,81:20.7,82:20.7,83:20.8,84:20.9,85:21.0,86:21.1,87:21.1,88:21.2,89:21.3,90:21.4,91:21.4,92:21.5,93:21.6,94:21.6,95:21.7,96:21.8};
|
||||
|
||||
// PHOTOTHERAPY — WITH neurotoxicity risk factors (38-41 identical per AAP 2022)
|
||||
var photoThresholds35risk = {12:6.9,13:7.1,14:7.2,15:7.4,16:7.6,17:7.7,18:7.9,19:8.1,20:8.2,21:8.4,22:8.6,23:8.7,24:8.9,25:9.0,26:9.2,27:9.3,28:9.5,29:9.6,30:9.8,31:9.9,32:10.1,33:10.2,34:10.3,35:10.5,36:10.6,37:10.8,38:10.9,39:11.0,40:11.2,41:11.3,42:11.4,43:11.5,44:11.7,45:11.8,46:11.9,47:12.0,48:12.2,49:12.3,50:12.4,51:12.5,52:12.6,53:12.7,54:12.8,55:13.0,56:13.1,57:13.2,58:13.3,59:13.4,60:13.5,61:13.6,62:13.7,63:13.8,64:13.9,65:14.0,66:14.1,67:14.2,68:14.2,69:14.3,70:14.4,71:14.5,72:14.6,73:14.7,74:14.8,75:14.8,76:14.9,77:15.0,78:15.1,79:15.1,80:15.2,81:15.3,82:15.3,83:15.4,84:15.5,85:15.5,86:15.6,87:15.7,88:15.7,89:15.8,90:15.8,91:15.9,92:15.9,93:16.0,94:16.1,95:16.1,96:16.1};
|
||||
var photoThresholds36risk = {12:7.4,13:7.6,14:7.8,15:8.0,16:8.1,17:8.3,18:8.5,19:8.6,20:8.8,21:9.0,22:9.1,23:9.3,24:9.4,25:9.6,26:9.8,27:9.9,28:10.1,29:10.2,30:10.4,31:10.5,32:10.7,33:10.8,34:11.0,35:11.1,36:11.2,37:11.4,38:11.5,39:11.7,40:11.8,41:11.9,42:12.1,43:12.2,44:12.3,45:12.5,46:12.6,47:12.7,48:12.8,49:13.0,50:13.1,51:13.2,52:13.3,53:13.4,54:13.5,55:13.7,56:13.8,57:13.9,58:14.0,59:14.1,60:14.2,61:14.3,62:14.4,63:14.5,64:14.6,65:14.7,66:14.8,67:14.9,68:15.0,69:15.1,70:15.2,71:15.3,72:15.4,73:15.4,74:15.5,75:15.6,76:15.7,77:15.8,78:15.8,79:15.9,80:16.0,81:16.1,82:16.1,83:16.2,84:16.3,85:16.4,86:16.4,87:16.5,88:16.6,89:16.6,90:16.7,91:16.7,92:16.8,93:16.8,94:16.9,95:17.0,96:17.0};
|
||||
var photoThresholds37risk = {12:8.0,13:8.1,14:8.3,15:8.5,16:8.7,17:8.9,18:9.0,19:9.2,20:9.4,21:9.5,22:9.7,23:9.9,24:10.0,25:10.2,26:10.4,27:10.5,28:10.7,29:10.8,30:11.0,31:11.1,32:11.3,33:11.4,34:11.6,35:11.7,36:11.9,37:12.0,38:12.2,39:12.3,40:12.4,41:12.6,42:12.7,43:12.9,44:13.0,45:13.1,46:13.2,47:13.4,48:13.5,49:13.6,50:13.8,51:13.9,52:14.0,53:14.1,54:14.2,55:14.4,56:14.5,57:14.6,58:14.7,59:14.8,60:14.9,61:15.0,62:15.1,63:15.2,64:15.3,65:15.4,66:15.5,67:15.6,68:15.7,69:15.8,70:15.9,71:16.0,72:16.1,73:16.2,74:16.3,75:16.4,76:16.5,77:16.6,78:16.6,79:16.7,80:16.8,81:16.9,82:17.0,83:17.0,84:17.1,85:17.2,86:17.2,87:17.3,88:17.4,89:17.4,90:17.5,91:17.6,92:17.6,93:17.7,94:17.8,95:17.8,96:17.9};
|
||||
var photoThresholds38risk = {12:8.5,13:8.6,14:8.8,15:9.0,16:9.2,17:9.4,18:9.5,19:9.7,20:9.9,21:10.0,22:10.2,23:10.4,24:10.5,25:10.7,26:10.8,27:11.0,28:11.2,29:11.3,30:11.5,31:11.6,32:11.8,33:11.9,34:12.1,35:12.2,36:12.4,37:12.5,38:12.7,39:12.8,40:12.9,41:13.1,42:13.2,43:13.3,44:13.5,45:13.6,46:13.7,47:13.9,48:14.0,49:14.1,50:14.2,51:14.4,52:14.5,53:14.6,54:14.7,55:14.8,56:14.9,57:15.1,58:15.2,59:15.3,60:15.4,61:15.5,62:15.6,63:15.7,64:15.8,65:15.9,66:16.0,67:16.1,68:16.2,69:16.3,70:16.4,71:16.5,72:16.6,73:16.6,74:16.7,75:16.8,76:16.9,77:17.0,78:17.1,79:17.1,80:17.2,81:17.3,82:17.4,83:17.4,84:17.5,85:17.6,86:17.6,87:17.7,88:17.8,89:17.8,90:17.9,91:18.0,92:18.0,93:18.1,94:18.1,95:18.2,96:18.2};
|
||||
|
||||
// EXCHANGE TRANSFUSION — no risk (38-41 identical per AAP 2022)
|
||||
var exchangeThresholds35 = {12:16.4,13:16.5,14:16.6,15:16.8,16:16.9,17:17.0,18:17.2,19:17.3,20:17.4,21:17.5,22:17.7,23:17.8,24:17.9,25:18.0,26:18.2,27:18.3,28:18.4,29:18.5,30:18.7,31:18.8,32:18.9,33:19.0,34:19.1,35:19.2,36:19.4,37:19.5,38:19.6,39:19.7,40:19.8,41:19.9,42:20.0,43:20.1,44:20.2,45:20.3,46:20.5,47:20.6,48:20.7,49:20.8,50:20.9,51:21.0,52:21.1,53:21.2,54:21.3,55:21.4,56:21.5,57:21.6,58:21.7,59:21.7,60:21.8,61:21.9,62:22.0,63:22.1,64:22.2,65:22.3,66:22.4,67:22.5,68:22.6,69:22.6,70:22.7,71:22.8,72:22.9,73:23.0,74:23.1,75:23.1,76:23.2,77:23.3,78:23.4,79:23.4,80:23.5,81:23.6,82:23.7,83:23.7,84:23.8,85:23.9,86:23.9,87:24.0,88:24.1,89:24.1,90:24.2,91:24.3,92:24.3,93:24.4,94:24.4,95:24.5,96:24.5};
|
||||
var exchangeThresholds36 = {12:17.5,13:17.7,14:17.8,15:17.9,16:18.1,17:18.2,18:18.3,19:18.5,20:18.6,21:18.7,22:18.9,23:19.0,24:19.1,25:19.2,26:19.4,27:19.5,28:19.6,29:19.7,30:19.9,31:20.0,32:20.1,33:20.2,34:20.4,35:20.5,36:20.6,37:20.7,38:20.8,39:20.9,40:21.0,41:21.2,42:21.3,43:21.4,44:21.5,45:21.6,46:21.7,47:21.8,48:21.9,49:22.0,50:22.1,51:22.2,52:22.3,53:22.4,54:22.5,55:22.6,56:22.7,57:22.8,58:22.9,59:23.0,60:23.1,61:23.2,62:23.2,63:23.3,64:23.4,65:23.5,66:23.6,67:23.7,68:23.8,69:23.8,70:23.9,71:24.0,72:24.1,73:24.1,74:24.2,75:24.3,76:24.4,77:24.4,78:24.5,79:24.6,80:24.6,81:24.7,82:24.8,83:24.8,84:24.9,85:25.0,86:25.0,87:25.1,88:25.2,89:25.2,90:25.3,91:25.3,92:25.4,93:25.4,94:25.5,95:25.5,96:25.5};
|
||||
var exchangeThresholds37 = {12:18.7,13:18.8,14:18.9,15:19.1,16:19.2,17:19.4,18:19.5,19:19.6,20:19.8,21:19.9,22:20.1,23:20.2,24:20.3,25:20.5,26:20.6,27:20.7,28:20.8,29:21.0,30:21.1,31:21.2,32:21.3,33:21.5,34:21.6,35:21.7,36:21.8,37:21.9,38:22.1,39:22.2,40:22.3,41:22.4,42:22.5,43:22.6,44:22.7,45:22.8,46:22.9,47:23.0,48:23.1,49:23.2,50:23.3,51:23.4,52:23.5,53:23.6,54:23.7,55:23.8,56:23.9,57:24.0,58:24.1,59:24.2,60:24.3,61:24.4,62:24.5,63:24.5,64:24.6,65:24.7,66:24.8,67:24.9,68:24.9,69:25.0,70:25.1,71:25.2,72:25.2,73:25.3,74:25.4,75:25.5,76:25.5,77:25.6,78:25.7,79:25.7,80:25.8,81:25.8,82:25.9,83:26.0,84:26.0,85:26.1,86:26.1,87:26.2,88:26.2,89:26.3,90:26.3,91:26.4,92:26.4,93:26.5,94:26.5,95:26.5,96:26.6};
|
||||
var exchangeThresholds38 = {12:19.7,13:19.9,14:20.0,15:20.1,16:20.3,17:20.4,18:20.6,19:20.7,20:20.8,21:21.0,22:21.1,23:21.2,24:21.4,25:21.5,26:21.6,27:21.7,28:21.9,29:22.0,30:22.1,31:22.2,32:22.3,33:22.4,34:22.6,35:22.7,36:22.8,37:22.9,38:23.0,39:23.1,40:23.2,41:23.3,42:23.4,43:23.5,44:23.6,45:23.7,46:23.8,47:23.9,48:24.0,49:24.1,50:24.2,51:24.3,52:24.4,53:24.5,54:24.6,55:24.7,56:24.7,57:24.8,58:24.9,59:25.0,60:25.1,61:25.2,62:25.2,63:25.3,64:25.4,65:25.5,66:25.5,67:25.6,68:25.7,69:25.7,70:25.8,71:25.9,72:25.9,73:26.0,74:26.0,75:26.1,76:26.2,77:26.2,78:26.3,79:26.3,80:26.4,81:26.4,82:26.5,83:26.5,84:26.6,85:26.6,86:26.7,87:26.7,88:26.7,89:26.8,90:26.8,91:26.9,92:26.9,93:26.9,94:27.0,95:27.0,96:27.0};
|
||||
|
||||
// EXCHANGE TRANSFUSION — WITH risk (38-41 identical per AAP 2022)
|
||||
var exchangeThresholds35risk = {12:14.6,13:14.8,14:14.9,15:15.0,16:15.1,17:15.3,18:15.4,19:15.5,20:15.6,21:15.8,22:15.9,23:16.0,24:16.1,25:16.2,26:16.3,27:16.4,28:16.5,29:16.6,30:16.8,31:16.9,32:17.0,33:17.1,34:17.2,35:17.3,36:17.4,37:17.5,38:17.6,39:17.7,40:17.7,41:17.8,42:17.9,43:18.0,44:18.1,45:18.2,46:18.3,47:18.4,48:18.5,49:18.5,50:18.6,51:18.7,52:18.8,53:18.9,54:18.9,55:19.0,56:19.1,57:19.2,58:19.2,59:19.3,60:19.4,61:19.4,62:19.5,63:19.6,64:19.6,65:19.7,66:19.8,67:19.8,68:19.9,69:19.9,70:20.0,71:20.1,72:20.1,73:20.2,74:20.2,75:20.3,76:20.3,77:20.4,78:20.4,79:20.5,80:20.5,81:20.6,82:20.6,83:20.6,84:20.7,85:20.7,86:20.8,87:20.8,88:20.8,89:20.9,90:20.9,91:20.9,92:21.0,93:21.0,94:21.0,95:21.1,96:21.1};
|
||||
var exchangeThresholds36risk = {12:15.2,13:15.3,14:15.4,15:15.6,16:15.7,17:15.8,18:15.9,19:16.1,20:16.2,21:16.3,22:16.4,23:16.5,24:16.6,25:16.8,26:16.9,27:17.0,28:17.1,29:17.2,30:17.3,31:17.4,32:17.5,33:17.6,34:17.7,35:17.8,36:17.9,37:18.0,38:18.1,39:18.2,40:18.3,41:18.4,42:18.5,43:18.6,44:18.7,45:18.8,46:18.9,47:19.0,48:19.1,49:19.2,50:19.2,51:19.3,52:19.4,53:19.5,54:19.6,55:19.7,56:19.7,57:19.8,58:19.9,59:20.0,60:20.1,61:20.1,62:20.2,63:20.3,64:20.3,65:20.4,66:20.5,67:20.6,68:20.6,69:20.7,70:20.8,71:20.8,72:20.9,73:20.9,74:21.0,75:21.1,76:21.1,77:21.2,78:21.2,79:21.3,80:21.4,81:21.4,82:21.5,83:21.5,84:21.6,85:21.6,86:21.7,87:21.7,88:21.8,89:21.8,90:21.9,91:21.9,92:22.0,93:22.0,94:22.0,95:22.1,96:22.1};
|
||||
var exchangeThresholds37risk = {12:15.7,13:15.9,14:16.0,15:16.1,16:16.2,17:16.4,18:16.5,19:16.6,20:16.7,21:16.8,22:17.0,23:17.1,24:17.2,25:17.3,26:17.4,27:17.5,28:17.7,29:17.8,30:17.9,31:18.0,32:18.1,33:18.2,34:18.3,35:18.4,36:18.5,37:18.6,38:18.7,39:18.8,40:18.9,41:19.0,42:19.1,43:19.2,44:19.3,45:19.4,46:19.5,47:19.6,48:19.7,49:19.8,50:19.9,51:20.0,52:20.1,53:20.1,54:20.2,55:20.3,56:20.4,57:20.5,58:20.6,59:20.7,60:20.7,61:20.8,62:20.9,63:21.0,64:21.1,65:21.1,66:21.2,67:21.3,68:21.4,69:21.4,70:21.5,71:21.6,72:21.7,73:21.7,74:21.8,75:21.9,76:21.9,77:22.0,78:22.1,79:22.1,80:22.2,81:22.3,82:22.3,83:22.4,84:22.5,85:22.5,86:22.6,87:22.6,88:22.7,89:22.8,90:22.8,91:22.9,92:22.9,93:23.0,94:23.0,95:23.1,96:23.1};
|
||||
var exchangeThresholds38risk = {12:16.3,13:16.4,14:16.5,15:16.6,16:16.7,17:16.9,18:17.0,19:17.1,20:17.2,21:17.3,22:17.4,23:17.6,24:17.7,25:17.8,26:17.9,27:18.0,28:18.1,29:18.2,30:18.3,31:18.4,32:18.5,33:18.7,34:18.8,35:18.9,36:19.0,37:19.1,38:19.2,39:19.3,40:19.4,41:19.5,42:19.6,43:19.7,44:19.8,45:19.9,46:19.9,47:20.0,48:20.1,49:20.2,50:20.3,51:20.4,52:20.5,53:20.6,54:20.7,55:20.8,56:20.8,57:20.9,58:21.0,59:21.1,60:21.2,61:21.3,62:21.3,63:21.4,64:21.5,65:21.6,66:21.7,67:21.7,68:21.8,69:21.9,70:22.0,71:22.0,72:22.1,73:22.2,74:22.2,75:22.3,76:22.4,77:22.5,78:22.5,79:22.6,80:22.7,81:22.7,82:22.8,83:22.8,84:22.9,85:23.0,86:23.0,87:23.1,88:23.1,89:23.2,90:23.3,91:23.3,92:23.4,93:23.4,94:23.5,95:23.5,96:23.5};
|
||||
// AAP 2022 bilirubin treatment thresholds load from /data/calculators/aap-bilirubin-thresholds.json.
|
||||
|
||||
// Bili sub-pill nav
|
||||
document.querySelectorAll('[data-bili]').forEach(function(pill) {
|
||||
|
|
@ -1491,50 +1450,27 @@ initImageLightbox();
|
|||
});
|
||||
});
|
||||
|
||||
var AAP_BILI_THRESHOLDS = null;
|
||||
loadAapBilirubinThresholds()
|
||||
.then(function(data) { AAP_BILI_THRESHOLDS = data; })
|
||||
.catch(function(err) { console.warn('[calculators] AAP bilirubin threshold data unavailable:', err && err.message); });
|
||||
|
||||
document.getElementById('btn-calc-bili-aap').addEventListener('click', function() {
|
||||
var ga = document.getElementById('bili-ga').value;
|
||||
var hours = parseFloat(document.getElementById('bili-age-hours').value);
|
||||
var tsb = parseFloat(document.getElementById('bili-tsb').value);
|
||||
var risk = document.getElementById('bili-risk').value;
|
||||
if (!ga || isNaN(hours) || isNaN(tsb)) { showToast('Fill in all fields', 'error'); return; }
|
||||
if (!AAP_BILI_THRESHOLDS) { showToast('AAP bilirubin threshold data is still loading.', 'info'); return; }
|
||||
|
||||
var gaNum = parseInt(ga);
|
||||
// Per AAP 2022: phototherapy NO-risk curves differ per week (35,36,37,38,39,40+);
|
||||
// phototherapy WITH-risk plateaus at 38w (38+ identical);
|
||||
// exchange (both risk states) plateaus at 38w.
|
||||
var table;
|
||||
if (risk === 'medium') {
|
||||
if (gaNum === 35) table = photoThresholds35risk;
|
||||
else if (gaNum === 36) table = photoThresholds36risk;
|
||||
else if (gaNum === 37) table = photoThresholds37risk;
|
||||
else table = photoThresholds38risk; // 38+
|
||||
} else {
|
||||
if (gaNum === 35) table = photoThresholds35;
|
||||
else if (gaNum === 36) table = photoThresholds36;
|
||||
else if (gaNum === 37) table = photoThresholds37;
|
||||
else if (gaNum === 38) table = photoThresholds38;
|
||||
else if (gaNum === 39) table = photoThresholds39;
|
||||
else table = photoThresholds40; // 40+
|
||||
}
|
||||
|
||||
var threshold = interpolateBiliThreshold(table, hours);
|
||||
var aboveThreshold = tsb >= threshold;
|
||||
|
||||
// Exchange transfusion threshold — 38+ plateaus for both risk states
|
||||
var exchangeTable;
|
||||
if (risk === 'medium') {
|
||||
if (gaNum === 35) exchangeTable = exchangeThresholds35risk;
|
||||
else if (gaNum === 36) exchangeTable = exchangeThresholds36risk;
|
||||
else if (gaNum === 37) exchangeTable = exchangeThresholds37risk;
|
||||
else exchangeTable = exchangeThresholds38risk;
|
||||
} else {
|
||||
if (gaNum === 35) exchangeTable = exchangeThresholds35;
|
||||
else if (gaNum === 36) exchangeTable = exchangeThresholds36;
|
||||
else if (gaNum === 37) exchangeTable = exchangeThresholds37;
|
||||
else exchangeTable = exchangeThresholds38;
|
||||
}
|
||||
var exchangeThreshold = exchangeTable ? interpolateBiliThreshold(exchangeTable, hours) : null;
|
||||
var aboveExchange = exchangeThreshold && tsb >= exchangeThreshold;
|
||||
var assessment = calculateAapBilirubinAssessment(AAP_BILI_THRESHOLDS, gaNum, hours, tsb, risk);
|
||||
var table = assessment.phototherapyTable;
|
||||
var threshold = assessment.phototherapyThreshold;
|
||||
var aboveThreshold = assessment.abovePhototherapy;
|
||||
var exchangeTable = assessment.exchangeTable;
|
||||
var exchangeThreshold = assessment.exchangeThreshold;
|
||||
var aboveExchange = assessment.aboveExchange;
|
||||
|
||||
var cl;
|
||||
if (aboveExchange) cl = { text: 'ABOVE EXCHANGE TRANSFUSION THRESHOLD', color: '#7f1d1d', bg: '#fecaca' };
|
||||
|
|
|
|||
|
|
@ -1,4 +1,54 @@
|
|||
var bhutaniCache = null;
|
||||
var aapCache = null;
|
||||
|
||||
export function loadAapBilirubinThresholds() {
|
||||
if (aapCache) return Promise.resolve(aapCache);
|
||||
return fetch('/data/calculators/aap-bilirubin-thresholds.json', { credentials: 'same-origin' })
|
||||
.then(function(response) {
|
||||
if (!response.ok) throw new Error('Failed to load AAP bilirubin threshold data');
|
||||
return response.json();
|
||||
})
|
||||
.then(function(data) {
|
||||
aapCache = data;
|
||||
return aapCache;
|
||||
});
|
||||
}
|
||||
|
||||
function pickGestationalAgeTable(tables, gaWeeks, maxWeek) {
|
||||
var ga = Math.max(35, Math.min(maxWeek, parseInt(gaWeeks, 10)));
|
||||
return tables[String(ga)];
|
||||
}
|
||||
|
||||
export function selectAapBilirubinThresholdTables(thresholds, gaWeeks, risk) {
|
||||
var hasRiskFactors = risk === 'medium';
|
||||
return {
|
||||
phototherapy: hasRiskFactors
|
||||
? pickGestationalAgeTable(thresholds.phototherapy.risk, gaWeeks, 38)
|
||||
: pickGestationalAgeTable(thresholds.phototherapy.noRisk, gaWeeks, 40),
|
||||
exchange: hasRiskFactors
|
||||
? pickGestationalAgeTable(thresholds.exchange.risk, gaWeeks, 38)
|
||||
: pickGestationalAgeTable(thresholds.exchange.noRisk, gaWeeks, 38)
|
||||
};
|
||||
}
|
||||
|
||||
export function calculateAapBilirubinAssessment(thresholds, gaWeeks, hours, tsb, risk) {
|
||||
var tables = selectAapBilirubinThresholdTables(thresholds, gaWeeks, risk);
|
||||
var phototherapyThreshold = interpolateThreshold(tables.phototherapy, hours);
|
||||
var exchangeThreshold = interpolateThreshold(tables.exchange, hours);
|
||||
var aboveExchange = tsb >= exchangeThreshold;
|
||||
var abovePhototherapy = tsb >= phototherapyThreshold;
|
||||
return {
|
||||
phototherapyTable: tables.phototherapy,
|
||||
exchangeTable: tables.exchange,
|
||||
phototherapyThreshold: phototherapyThreshold,
|
||||
exchangeThreshold: exchangeThreshold,
|
||||
phototherapyMargin: tsb - phototherapyThreshold,
|
||||
exchangeMargin: tsb - exchangeThreshold,
|
||||
abovePhototherapy: abovePhototherapy,
|
||||
aboveExchange: aboveExchange,
|
||||
status: aboveExchange ? 'exchange' : (abovePhototherapy ? 'phototherapy' : 'below')
|
||||
};
|
||||
}
|
||||
|
||||
export function loadBhutaniZones() {
|
||||
if (bhutaniCache) return Promise.resolve(bhutaniCache);
|
||||
|
|
|
|||
|
|
@ -147,3 +147,80 @@ test('bilirubin helpers preserve Bhutani interpolation and classification', asyn
|
|||
assert.equal(bilirubin.classifyBhutaniRisk(zones, 24, 7).zone, 'Low-Intermediate Zone');
|
||||
assert.equal(bilirubin.classifyBhutaniRisk(zones, 24, 5).zone, 'Low-Risk Zone');
|
||||
});
|
||||
|
||||
test('aap-bilirubin-thresholds.json preserves treatment threshold anchors', () => {
|
||||
const raw = fs.readFileSync(path.join(__dirname, '..', 'public', 'data', 'calculators', 'aap-bilirubin-thresholds.json'), 'utf8');
|
||||
const data = JSON.parse(raw);
|
||||
assert.equal(data.version, '1.0');
|
||||
assert.deepEqual(Object.keys(data.phototherapy.noRisk), ['35', '36', '37', '38', '39', '40']);
|
||||
assert.deepEqual(Object.keys(data.phototherapy.risk), ['35', '36', '37', '38']);
|
||||
assert.deepEqual(Object.keys(data.exchange.noRisk), ['35', '36', '37', '38']);
|
||||
assert.deepEqual(Object.keys(data.exchange.risk), ['35', '36', '37', '38']);
|
||||
assert.equal(data.phototherapy.noRisk['35']['24'], 10.6);
|
||||
assert.equal(data.phototherapy.noRisk['40']['48'], 17.0);
|
||||
assert.equal(data.phototherapy.risk['38']['72'], 16.6);
|
||||
assert.equal(data.exchange.noRisk['38']['96'], 27.0);
|
||||
assert.equal(data.exchange.risk['35']['24'], 16.1);
|
||||
});
|
||||
|
||||
test('bilirubin helpers preserve AAP 2022 GA plateau selection and interpolation', async () => {
|
||||
const bilirubin = await import('../public/js/calculators/bilirubin.js');
|
||||
const raw = fs.readFileSync(path.join(__dirname, '..', 'public', 'data', 'calculators', 'aap-bilirubin-thresholds.json'), 'utf8');
|
||||
const data = JSON.parse(raw);
|
||||
assert.equal(bilirubin.interpolateThreshold(data.phototherapy.noRisk['35'], 12.5), 8.6);
|
||||
assert.equal(bilirubin.selectAapBilirubinThresholdTables(data, 41, 'none').phototherapy['48'], 17.0);
|
||||
assert.equal(bilirubin.selectAapBilirubinThresholdTables(data, 39, 'none').phototherapy['48'], 16.6);
|
||||
assert.equal(bilirubin.selectAapBilirubinThresholdTables(data, 41, 'medium').phototherapy['48'], 14.0);
|
||||
assert.equal(bilirubin.selectAapBilirubinThresholdTables(data, 40, 'none').exchange['48'], 24.0);
|
||||
});
|
||||
|
||||
test('AAP bilirubin sample calculation below phototherapy threshold', async () => {
|
||||
const bilirubin = await import('../public/js/calculators/bilirubin.js');
|
||||
const raw = fs.readFileSync(path.join(__dirname, '..', 'public', 'data', 'calculators', 'aap-bilirubin-thresholds.json'), 'utf8');
|
||||
const data = JSON.parse(raw);
|
||||
const assessment = bilirubin.calculateAapBilirubinAssessment(data, 40, 48, 16.0, 'none');
|
||||
assert.equal(assessment.phototherapyThreshold, 17.0);
|
||||
assert.equal(assessment.exchangeThreshold, 24.0);
|
||||
assert.equal(assessment.phototherapyMargin, -1.0);
|
||||
assert.equal(assessment.exchangeMargin, -8.0);
|
||||
assert.equal(assessment.abovePhototherapy, false);
|
||||
assert.equal(assessment.aboveExchange, false);
|
||||
assert.equal(assessment.status, 'below');
|
||||
});
|
||||
|
||||
test('AAP bilirubin sample calculation above phototherapy threshold', async () => {
|
||||
const bilirubin = await import('../public/js/calculators/bilirubin.js');
|
||||
const raw = fs.readFileSync(path.join(__dirname, '..', 'public', 'data', 'calculators', 'aap-bilirubin-thresholds.json'), 'utf8');
|
||||
const data = JSON.parse(raw);
|
||||
const assessment = bilirubin.calculateAapBilirubinAssessment(data, 39, 48, 17.0, 'none');
|
||||
assert.equal(assessment.phototherapyThreshold, 16.6);
|
||||
assert.equal(assessment.exchangeThreshold, 24.0);
|
||||
assert.equal(Math.round(assessment.phototherapyMargin * 10) / 10, 0.4);
|
||||
assert.equal(assessment.abovePhototherapy, true);
|
||||
assert.equal(assessment.aboveExchange, false);
|
||||
assert.equal(assessment.status, 'phototherapy');
|
||||
});
|
||||
|
||||
test('AAP bilirubin sample calculation above exchange threshold', async () => {
|
||||
const bilirubin = await import('../public/js/calculators/bilirubin.js');
|
||||
const raw = fs.readFileSync(path.join(__dirname, '..', 'public', 'data', 'calculators', 'aap-bilirubin-thresholds.json'), 'utf8');
|
||||
const data = JSON.parse(raw);
|
||||
const assessment = bilirubin.calculateAapBilirubinAssessment(data, 35, 24, 16.2, 'medium');
|
||||
assert.equal(assessment.phototherapyThreshold, 8.9);
|
||||
assert.equal(assessment.exchangeThreshold, 16.1);
|
||||
assert.equal(Math.round(assessment.phototherapyMargin * 10) / 10, 7.3);
|
||||
assert.equal(Math.round(assessment.exchangeMargin * 10) / 10, 0.1);
|
||||
assert.equal(assessment.abovePhototherapy, true);
|
||||
assert.equal(assessment.aboveExchange, true);
|
||||
assert.equal(assessment.status, 'exchange');
|
||||
});
|
||||
|
||||
test('AAP bilirubin sample calculation interpolates fractional age', async () => {
|
||||
const bilirubin = await import('../public/js/calculators/bilirubin.js');
|
||||
const raw = fs.readFileSync(path.join(__dirname, '..', 'public', 'data', 'calculators', 'aap-bilirubin-thresholds.json'), 'utf8');
|
||||
const data = JSON.parse(raw);
|
||||
const assessment = bilirubin.calculateAapBilirubinAssessment(data, 35, 12.5, 8.55, 'none');
|
||||
assert.equal(assessment.phototherapyThreshold, 8.6);
|
||||
assert.equal(assessment.abovePhototherapy, false);
|
||||
assert.equal(assessment.status, 'below');
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue