diff --git a/public/js/calculators.js b/public/js/calculators.js index eabce8b..70d5243 100644 --- a/public/js/calculators.js +++ b/public/js/calculators.js @@ -1,7 +1,6 @@ import { parseAgeMonths, formatParsedAge } from './calculators/age.js'; import { loadEquipmentData, renderEquipmentResult } from './calculators/equipment.js'; import { initImageLightbox } from './calculators/lightbox.js'; -import { calcZ as calcNeonatalZ, classifyBirthWeight, classifyGA, classifyWeight, interpolateLMS, loadFentonLmsData, zToPercentile } from './calculators/neonatal.js'; import { loadResusMedsData, renderResusMeds } from './calculators/resus.js'; import { loadVitalsData, renderVitalsResult } from './calculators/vitals.js'; @@ -1806,567 +1805,3 @@ initImageLightbox(); } } })(); - -// ============================================================ -// NEONATAL ASSESSMENT -// ============================================================ -(function() { - var fentonLMS = { male: {}, female: {} }; - loadFentonLmsData() - .then(function(data) { fentonLMS = data; }) - .catch(function(err) { console.warn('[calculators] Fenton LMS data unavailable:', err && err.message); }); - - document.addEventListener('click', function(e) { - if (e.target.id === 'btn-neo-assess' || e.target.closest('#btn-neo-assess')) neoAssess(); - }); - - function neoAssess() { - var weeks = parseInt(document.getElementById('neo-ga-weeks').value); - var days = parseInt(document.getElementById('neo-ga-days').value) || 0; - var weight = parseFloat(document.getElementById('neo-weight').value); - var sex = document.getElementById('neo-sex').value; - var resultDiv = document.getElementById('neo-result'); - - if (!weeks || !weight) { - resultDiv.innerHTML = '

Enter GA and birth weight.

'; - return; - } - if (!fentonLMS[sex] || Object.keys(fentonLMS[sex]).length === 0) { - resultDiv.innerHTML = '

Fenton growth data is still loading.

'; - return; - } - - var gaDecimal = weeks + days / 7; - var gaClass = classifyGA(weeks, days); - var bwClass = classifyBirthWeight(weight); - - // Calculate percentile using Fenton LMS - var lms = interpolateLMS(fentonLMS[sex], gaDecimal); - var z = calcNeonatalZ(weight, lms.L, lms.M, lms.S); - var percentile = zToPercentile(z); - var wtClass = classifyWeight(percentile); - var expectedWeight = Math.round(lms.M); - - var html = ''; - - // GA Classification - html += '
'; - html += '
'; - html += '
Gestational Age Classification
'; - html += '
' + gaClass.label + '
'; - html += '
' + weeks + ' weeks ' + days + ' days (' + gaDecimal.toFixed(1) + ' weeks)
'; - html += '
'; - - // Weight Classification (AGA/SGA/LGA) - html += '
'; - html += '
Weight for Gestational Age
'; - html += '
' + wtClass.label + '
'; - html += '
' + percentile.toFixed(1) + 'th percentile (' + wtClass.detail + ')
'; - html += '
'; - html += '
'; - - // Birth Weight Category - html += '
'; - html += '
'; - html += '
Birth Weight Category
'; - html += '
' + bwClass.label + '
'; - html += '
' + weight + 'g (' + (weight/1000).toFixed(2) + ' kg)
'; - html += '
'; - - // Stats - html += '
'; - html += '
Fenton Growth Data (' + (sex === 'male' ? 'Male' : 'Female') + ')
'; - html += '
'; - html += 'Expected weight (50th %ile): ' + expectedWeight + 'g
'; - html += 'Z-score: ' + z.toFixed(2) + '
'; - html += 'Percentile: ' + percentile.toFixed(1) + '%'; - html += '
'; - html += '
'; - - // Reference - html += '

Fenton TR, Kim JH. A systematic review and meta-analysis to revise the Fenton growth chart for preterm infants. BMC Pediatrics 2013;13:59. GA classification per ACOG/AAP definitions.

'; - - resultDiv.innerHTML = html; - } -})(); - -// ============================================================ -// RESPIRATORY MANAGEMENT (Asthma, Croup, Bronchiolitis) -// ============================================================ -(function() { - // Sub-pill navigation - document.addEventListener('click', function(e) { - var pill = e.target.closest('[data-resp]'); - if (pill) { - document.querySelectorAll('[data-resp]').forEach(function(p) { p.classList.remove('active'); }); - pill.classList.add('active'); - ['asthma','croup','bronchiolitis'].forEach(function(s) { - var el = document.getElementById('resp-' + s); - if (el) el.style.display = pill.dataset.resp === s ? '' : 'none'; - }); - } - if (e.target.closest('[data-asthma-severity]')) asthmaManagement(e.target.closest('[data-asthma-severity]').dataset.asthmaSeverity); - if (e.target.id === 'btn-pram-calc' || e.target.closest('#btn-pram-calc')) calcPRAM(); - if (e.target.id === 'btn-croup-calc' || e.target.closest('#btn-croup-calc')) calcCroup(); - if (e.target.id === 'btn-bronch-calc' || e.target.closest('#btn-bronch-calc')) calcBronchiolitis(); - }); - - function dose(wt, mgPerKg, maxMg) { var d = Math.round(wt * mgPerKg * 10) / 10; return maxMg ? Math.min(d, maxMg) : d; } - // Delegates to the shared _EM.dStr so the per-kg math is visible to the prescriber. - function doseStr(wt, mgPerKg, maxMg, unit) { - return window._EM.dStr(wt, mgPerKg, maxMg, unit); - } - function drugRow(name, doseText, route, notes) { - return '' + name + '' + doseText + '' + route + '' + (notes || '') + ''; - } - function drugTable(rows) { - return '
' + rows + '
DrugDoseRouteNotes
'; - } - function severityBadge(label, color) { return '' + label + ''; } - - function asthmaManagement(severity) { - var wt = parseFloat(document.getElementById('resp-weight').value); - var resultDiv = document.getElementById('asthma-result'); - if (!wt) { resultDiv.innerHTML = '

Enter weight (kg).

'; return; } - - var html = ''; - if (severity === 'mild') { - html += severityBadge('Mild Exacerbation', '#10b981'); - html += '

Speaks in sentences, no accessory muscle use, SpO2 ≥94%

'; - html += drugTable( - drugRow('Albuterol (MDI)', '4-8 puffs via spacer', 'Inhaled', 'q20min x 3 doses, then q1-4h') + - drugRow('Albuterol (neb)', doseStr(wt, 0.15, 5, ' mg') + ' (min 2.5 mg)', 'Nebulized', 'q20min x 3 doses') + - drugRow('Dexamethasone', doseStr(wt, 0.6, 16), 'PO/IV', 'Single dose, or 2 days') + - drugRow('Prednisolone', doseStr(wt, 1, 60) + '/day', 'PO', 'Alternative: 3-5 day course') - ); - html += '
Reassess after 1 hour. If improving → discharge with albuterol MDI + spacer + oral steroid course. If not improving → escalate to moderate.
'; - } else if (severity === 'moderate') { - html += severityBadge('Moderate Exacerbation', '#f59e0b'); - html += '

Speaks in phrases, some accessory muscle use, SpO2 90-93%

'; - html += drugTable( - drugRow('Albuterol (neb)', doseStr(wt, 0.15, 5, ' mg') + ' (min 2.5 mg)', 'Nebulized', 'q20min x 3 doses, then continuous if needed') + - drugRow('Ipratropium', wt < 20 ? '250 mcg' : '500 mcg', 'Nebulized', 'q20min x 3 doses with albuterol') + - drugRow('Dexamethasone', doseStr(wt, 0.6, 16), 'PO/IV/IM', 'Single dose') + - drugRow('O2 supplemental', 'Target SpO2 ≥94%', 'Nasal cannula/mask', 'Titrate to effect') - ); - html += '
Reassess after 1-2 hours. If improving → step down to mild protocol. If worsening or no improvement → escalate to severe.
'; - } else { - html += severityBadge('Severe / Life-Threatening', '#ef4444'); - html += '

Speaks in words only, significant accessory muscle use, SpO2 <90%. Consider ICU.

'; - html += drugTable( - drugRow('Albuterol continuous', doseStr(wt, 0.5, 20, ' mg') + '/hr', 'Continuous neb', 'Or 0.15-0.3 mg/kg q20min') + - drugRow('Ipratropium', wt < 20 ? '250 mcg' : '500 mcg', 'Nebulized', 'q20min x 3 doses with albuterol') + - drugRow('Dexamethasone', doseStr(wt, 0.6, 16), 'IV', 'Or methylprednisolone 2 mg/kg IV (max 60 mg)') + - drugRow('Magnesium sulfate', doseStr(wt, 50, 2000) + ' IV over 20 min', 'IV', 'Single dose, monitor BP') + - drugRow('Epinephrine (IM)', doseStr(wt, 0.01, 0.5) + ' (1:1000)', 'IM', 'If impending arrest / no IV access') + - drugRow('Terbutaline', doseStr(wt, 0.01, 0.4) + ' SC/IV', 'SC or IV bolus', 'Then 0.1-10 mcg/kg/min infusion') + - drugRow('O2 supplemental', 'Target SpO2 ≥94%', 'High flow / NIPPV', 'Consider BiPAP/CPAP') - ); - html += '
Continuous monitoring. Consider ICU admission. If no response to magnesium → terbutaline infusion. If impending respiratory failure → intubation (ketamine preferred induction agent).
'; - - // Clinical decision points specific to severe asthma - html += '
'; - - // ABG - html += '
' + - '
When to obtain a blood gas
' + - '• Severe exacerbation not responding after 1-2 h aggressive therapy
' + - '• Impending respiratory failure — altered mentation, fatigue, silent chest
' + - '• SpO2 <92% despite supplemental O2
' + - '• Suspected CO2 retention (rising PCO2 in a previously tachypneic patient)
' + - 'Interpretation: asthmatics hyperventilate → expect low PCO2. A "normal" or rising PCO2 = impending failure. Don\'t delay treatment for the gas.' + - '
'; - - // Intubation - html += '
' + - '
When to intubate (mostly clinical)
' + - '• Absolute: apnea, cardiac arrest, coma, inability to protect airway
' + - '• Progressive fatigue despite maximal therapy (NIV, mag, terbutaline, heliox)
' + - '• Refractory hypoxemia / hypercapnia with acidosis
' + - '• Silent chest + deteriorating consciousness
' + - 'RSI choice: ketamine 1-2 mg/kg (bronchodilator, preserves BP) + rocuronium. Avoid succs if hyperkalemic. Permissive hypercapnia after tube; allow expiration (low rate, I:E 1:3-4).' + - '
'; - - // Heliox - html += '
' + - '
Heliox (He/O2)
' + - '• Lower gas density → less turbulence → reduced work of breathing through narrowed airways.
' + - '• Consider in: severe asthma not responding to max therapy (bridge), upper airway obstruction (croup, post-extubation stridor, FB partial).
' + - '• Typical mix: 70:30 He:O2 (or 80:20). Delivered via tight non-rebreather or in-line with neb.
' + - '• Limitation: requires FiO2 ≤ 30-40%. If patient needs higher FiO2, heliox can\'t help.
' + - '• Evidence in asthma is mixed — use as adjunct, not substitute.' + - '
'; - - html += '
'; - } - html += '

NAEPP/GINA guidelines. Always use clinical judgment. Verify doses against institutional protocols.

'; - resultDiv.innerHTML = html; - } - - function calcPRAM() { - var total = ['pram-spo2','pram-retractions','pram-scalene','pram-air','pram-wheeze'].reduce(function(s, id) { - return s + parseInt(document.getElementById(id).value); - }, 0); - var severity = total <= 3 ? 'Mild' : total <= 7 ? 'Moderate' : 'Severe'; - var color = total <= 3 ? '#10b981' : total <= 7 ? '#f59e0b' : '#ef4444'; - document.getElementById('pram-result').innerHTML = '
PRAM Score: ' + total + '/12 — ' + severity + '

Mild (0-3): outpatient management. Moderate (4-7): consider oral steroids + frequent bronchodilators. Severe (8-12): aggressive treatment, consider ICU.

'; - } - - function calcCroup() { - var wt = parseFloat(document.getElementById('resp-weight').value) || 10; - var total = ['croup-conscious','croup-cyanosis','croup-stridor','croup-air','croup-retractions'].reduce(function(s, id) { - return s + parseInt(document.getElementById(id).value); - }, 0); - var severity, color, treatment; - if (total <= 2) { severity = 'Mild'; color = '#10b981'; treatment = drugTable(drugRow('Dexamethasone', doseStr(wt, 0.6, 16), 'PO (single dose)', 'Preferred corticosteroid') + drugRow('Supportive care', 'Cool mist, comfort measures', '', 'Discharge if tolerating PO')); } - else if (total <= 5) { severity = 'Moderate'; color = '#f59e0b'; treatment = drugTable(drugRow('Dexamethasone', doseStr(wt, 0.6, 16), 'PO/IM', 'Single dose') + drugRow('Racemic epinephrine', '0.5 mL of 2.25% solution', 'Nebulized', 'Observe 2-4 hrs after for rebound') + drugRow('Nebulized epinephrine', '0.5 mL/kg of 1:1000 (max 5 mL)', 'Nebulized', 'Alternative to racemic')); } - else if (total <= 11) { severity = 'Severe'; color = '#ef4444'; treatment = drugTable(drugRow('Dexamethasone', doseStr(wt, 0.6, 16), 'IV/IM', 'Immediate') + drugRow('Racemic epinephrine', '0.5 mL of 2.25% solution', 'Nebulized', 'May repeat q15-20min, observe 2-4 hrs') + drugRow('Nebulized epinephrine', '0.5 mL/kg of 1:1000 (max 5 mL)', 'Nebulized', 'Alternative') + drugRow('Heliox', '70:30 or 80:20', 'Face mask', 'Consider if not responding') + drugRow('O2 supplemental', 'Target SpO2 ≥94%', 'Blow-by preferred', 'Minimize agitation')); } - else { severity = 'Impending Respiratory Failure'; color = '#dc2626'; treatment = '
Immediate airway management. Prepare for intubation (use ETT 0.5-1 size smaller than predicted). Call anesthesia/ENT. Continue nebulized epinephrine and dexamethasone IV.
'; } - - document.getElementById('croup-result').innerHTML = '
Westley Score: ' + total + '/17 — ' + severity + '
' + treatment + '

Westley WJ et al. Nebulized racemic epinephrine by IPPB for the treatment of croup. Am J Dis Child 1978. Mild ≤2, Moderate 3-5, Severe 6-11, Impending failure ≥12.

'; - } - - function calcBronchiolitis() { - var wt = parseFloat(document.getElementById('resp-weight').value) || 5; - var age = document.getElementById('bronch-age').value; - var spo2 = document.getElementById('bronch-spo2').value; - var hydration = document.getElementById('bronch-hydration').value; - var distress = document.getElementById('bronch-distress').value; - - var html = '

Bronchiolitis Management

'; - var admit = distress === 'severe' || spo2 === 'low' || hydration === 'poor' || age === '<12w'; - - if (admit) { - html += severityBadge('Admit / Observe', '#ef4444'); - html += '
'; - if (age === '<12w') html += '

⚠ Age <12 weeks — high risk for apnea. Monitor closely.

'; - html += '
'; - } else { - html += severityBadge('Likely Safe for Discharge', '#10b981'); - } - - html += '
Supportive Care (evidence-based):
'; - html += drugTable( - drugRow('Nasal suctioning', 'Bulb suction or NasalClear', 'Nasal', 'Before feeds and as needed') + - drugRow('O2 supplemental', 'Target SpO2 ≥90%', 'NC / high flow', spo2 === 'low' ? 'Required' : 'If needed') + - drugRow('Hypertonic saline 3%', '4 mL nebulized', 'Nebulized', 'Consider in inpatients (AAP weak recommendation)') + - (hydration === 'poor' ? drugRow('IV fluids', 'NS/LR bolus ' + doseStr(wt, 20, null, ' mL'), 'IV', 'Then maintenance D5 0.45NS') + drugRow('NG feeds', 'If unable to feed orally', 'NG tube', 'Preferred over IV if gut functional') : '') - ); - - html += '
NOT recommended (AAP 2014/2023): Albuterol/salbutamol (no benefit in bronchiolitis), epinephrine (no evidence of benefit), systemic corticosteroids (no benefit), antibiotics (unless secondary bacterial infection), chest physiotherapy.
'; - html += '

AAP Clinical Practice Guideline: Management of Bronchiolitis in Infants and Children (2014, reaffirmed 2023). RSV is the most common cause (50-80%).

'; - document.getElementById('bronch-result').innerHTML = html; - } -})(); - -// ============================================================ -// SEIZURE MANAGEMENT -// ============================================================ -(function() { - document.addEventListener('click', function(e) { - if (e.target.id === 'btn-seizure-calc' || e.target.closest('#btn-seizure-calc')) calcSeizure(); - }); - - function d(wt, mgPerKg, max) { var v = Math.round(wt * mgPerKg * 100) / 100; return max ? Math.min(v, max) : v; } - function row(phase, drug, dose, route, notes) { - return '' + phase + '' + drug + '' + dose + '' + route + '' + notes + ''; - } - - // Visual pathway row — time badge + step card linked by vertical line - function stepRow(time, color, title, bodyHtml, isLast) { - return '
' + - '
' + - '
' + time + '
' + - (isLast ? '' : '
') + - '
' + - '
' + - '
' + title + '
' + - '
' + bodyHtml + '
' + - '
' + - '
'; - } - - // Fallback inline data — mirrors the non-refractory seizure entries in - // drugs.json. Refractory infusion drips are kept inline below because - // their dose strings (bolus → gtt range) don't map cleanly to the - // single-row JSON schema. - var SEIZURE_FALLBACK = [ - { name: 'Lorazepam', phase: '1st benzo', dose_mg_per_kg: 0.1, max_mg: 4, unit: 'mg', route: 'IV / IO', label_suffix: ' (IV preferred)', notes: 'Slow push over 1-2 min.' }, - { name: 'Midazolam', phase: '1st benzo', dose_mg_per_kg: 0.2, max_mg: 10, unit: 'mg', route: 'IM / IN / buccal', notes: 'Use 5 mg/mL concentrate for IN; split between nares.' }, - { name: 'Diazepam', phase: '1st benzo', dose_mg_per_kg: 0.5, max_mg: 20, unit: 'mg', route: 'PR', notes: 'Only if no IV/IM/IN access.' }, - { name: 'Levetiracetam', phase: '2nd-line', dose_mg_per_kg: 60, max_mg: 4500, unit: 'mg', route: 'IV over 5-15 min', label_suffix: ' (preferred)', notes: 'Best tolerability. No ECG monitoring needed.' }, - { name: 'Fosphenytoin', phase: '2nd-line', dose_mg_per_kg: 20, max_mg: 1500, unit: 'mg PE', route: 'IV over 10 min', notes: 'Max rate 3 mg PE/kg/min. Monitor ECG, BP. Avoid if cardiac dysrhythmia.' }, - { name: 'Valproic acid', phase: '2nd-line', dose_mg_per_kg: 40, max_mg: 3000, unit: 'mg', route: 'IV over 10 min', notes: 'Avoid <2 yr, hepatic / mitochondrial disease, pregnancy.' }, - { name: 'Phenobarbital', phase: '2nd-line', dose_mg_per_kg: 20, max_mg: 1000, unit: 'mg', route: 'IV over 20 min', notes: 'Last-choice 2nd line. High risk of resp depression + hypotension.' } - ]; - - function seizureDrugs() { - var s = window._DRUGS && window._DRUGS.sections && window._DRUGS.sections.seizure; - if (s && s.drugs && s.drugs.length) { - return s.drugs.map(function(d) { - var fb = SEIZURE_FALLBACK.filter(function(x) { return x.name === d.name; })[0] || {}; - return Object.assign({}, fb, d); - }); - } - return SEIZURE_FALLBACK; - } - - // Build the joined S.drugRow output for one phase ("1st benzo" / "2nd-line"). - function seizureRowsByPhase(wt, phase) { - var S = window._EM; - return seizureDrugs().filter(function(dg) { return dg.phase === phase; }).map(function(dg) { - var label = dg.name + (dg.label_suffix || ''); - var unitArg = dg.unit && dg.unit !== 'mg' ? ' ' + dg.unit : undefined; - var dose = unitArg - ? S.dStr(wt, dg.dose_mg_per_kg, dg.max_mg, unitArg) - : S.dStr(wt, dg.dose_mg_per_kg, dg.max_mg); - return S.drugRow(label, dose, dg.route, dg.notes); - }).join(''); - } - - function calcSeizure() { - var wt = parseFloat(document.getElementById('seizure-weight').value); - var resultDiv = document.getElementById('seizure-result'); - if (!wt) { resultDiv.innerHTML = '

Enter weight (kg).

'; return; } - var S = window._EM; - var d10Low = Math.round(wt * 2 * 10) / 10; - var d10High = Math.round(wt * 5 * 10) / 10; - - var html = '
Status Epilepticus Pathway — ' + wt + ' kg
Time = 0 at seizure onset. Do not pause between steps for benzo to take effect — act on the clock.
'; - - // 0 min — STABILIZE - html += stepRow('0 min', '#3b82f6', 'Stabilize', - 'ABCs — position, 100% O2 via NC / NRB, suction. IV or IO × 2. Continuous SpO2, ECG, BP. ' + - 'POC glucose — if <60 mg/dL: D10W ' + d10Low + '-' + d10High + ' mL IV (2-5 mL/kg). ' + - 'Labs: CBC, CMP, Mg, Ca, Phos, VBG, lactate, AED levels, toxicology if unclear etiology. ' + - 'Consider pyridoxine 100 mg IV in infants <18 mo or INH ingestion. Temperature: treat hyperthermia aggressively.' - ); - - // 5 min — 1ST BENZO - html += stepRow('5 min', '#8b5cf6', '1st benzodiazepine (give once, pick by access)', - S.drugTable(seizureRowsByPhase(wt, '1st benzo')) - ); - - // 10 min — 2ND BENZO - html += stepRow('10 min', '#a855f7', '2nd benzodiazepine — if still seizing', - 'Repeat same agent + dose once. Prepare 2nd-line now (don\'t wait to see if benzo works). If apnea/airway compromise: BVM, consider advanced airway.' - ); - - // 20 min — 2ND-LINE - html += stepRow('20 min', '#f59e0b', '2nd-line anti-epileptic — pick one (ESETT: equivalent efficacy)', - S.drugTable(seizureRowsByPhase(wt, '2nd-line')) - ); - - // 30 min — 2nd of 2nd-line (optional) - html += stepRow('30 min', '#ef4444', 'Still seizing? Consider 2nd agent from 2nd-line OR proceed to refractory', - 'If the first 2nd-line drug failed, give a different 2nd-line agent OR move directly to refractory therapy. Activate ICU, prepare for intubation. Confirm etiology not reversible (electrolytes, glucose, fever, toxin).' - ); - - // 40 min — REFRACTORY - html += stepRow('40 min', '#dc2626', 'Refractory status — intubate + continuous infusion + continuous EEG', - S.drugTable( - S.drugRow('Midazolam (1st-line infusion)', 'Bolus ' + d(wt, 0.2, 10) + ' mg → gtt ' + d(wt, 0.05, 2) + '-' + d(wt, 0.5, 18) + ' mg/hr (bolus 0.2 mg/kg, gtt 0.05-0.5 mg/kg/hr)', 'IV', 'Titrate to seizure control / burst suppression.') + - S.drugRow('Pentobarbital', 'Bolus ' + d(wt, 5, 200) + ' mg → gtt ' + d(wt, 1, null) + '-' + d(wt, 5, null) + ' mg/hr (bolus 5 mg/kg, gtt 1-5 mg/kg/hr)', 'IV', 'Causes hypotension — often need pressors.') + - S.drugRow('Propofol', 'Bolus ' + d(wt, 2, 100) + ' mg → gtt ' + d(wt, 2, null) + '-' + d(wt, 5, null) + ' mg/hr (bolus 2 mg/kg, gtt 2-5 mg/kg/hr)', 'IV', 'PRIS risk in children — limit to <4 mg/kg/hr and duration <48 h.') + - S.drugRow('Ketamine', 'Bolus ' + d(wt, 2, 100) + ' mg → gtt ' + d(wt, 1, null) + '-' + d(wt, 5, null) + ' mg/hr (bolus 2 mg/kg, gtt 1-5 mg/kg/hr)', 'IV', 'NMDA antagonist — rescue. Good BP profile; useful if refractory to GABAergics.') - ) + - '
Continuous EEG within 1 h — target electrographic seizure suppression × 24-48 h, then wean. Reassess etiology: CNS imaging, LP, expanded workup.
' - , true); - - // Key points - html += '
Key points
' + - '• Do NOT wait for benzo response before starting the 2nd-line — parallel preparation.
' + - '• Maximum 2 benzo doses total (1 pre-hospital + 1 in ED, or 2 in ED).
' + - '• Respiratory depression is common — have BVM, airway equipment, naloxone, flumazenil accessible (but avoid flumazenil here).
' + - '• ESETT trial: levetiracetam = fosphenytoin = valproate for efficacy. Pick by tolerability / contraindications.
' + - '• Always reassess: ongoing seizure? Non-convulsive status? Pseudo-seizure? → continuous EEG if any doubt.
'; - - html += '

Based on AES Guidelines 2016 and ESETT (Kapur et al., NEJM 2019). Verify all doses against institutional protocols.

'; - resultDiv.innerHTML = html; - } -})(); - -// ============================================================ -// ANAPHYLAXIS MANAGEMENT -// ============================================================ -(function() { - document.addEventListener('click', function(e) { - if (e.target.id === 'btn-anaph-calc' || e.target.closest('#btn-anaph-calc')) calcAnaphylaxis(); - }); - - function d(wt, mgPerKg, max) { var v = Math.round(wt * mgPerKg * 100) / 100; return max ? Math.min(v, max) : v; } - - // Lookup a drug entry (by name) from window._DRUGS.sections.anaphylaxis, - // falling back to a hardcoded record so rendering stays identical if the - // JSON fetch hasn't resolved (or failed). Returns an object exposing the - // per-kg + max fields needed by S.dStr. - var ANAPH_FALLBACK = { - 'Epinephrine IM': { dose_mg_per_kg: 0.01, max_mg: 0.5, unit: 'mg' }, - 'Normal saline bolus': { dose_mg_per_kg: 20, max_mg: null, unit: 'mL' }, - 'Diphenhydramine': { dose_mg_per_kg: 1.25, max_mg: 50, unit: 'mg' }, - 'Ranitidine': { dose_mg_per_kg: 1, max_mg: 50, unit: 'mg' }, - 'Dexamethasone': { dose_mg_per_kg: 0.6, max_mg: 16, unit: 'mg' }, - 'Methylprednisolone': { dose_mg_per_kg: 2, max_mg: 125, unit: 'mg' }, - 'Glucagon': { dose_mg_per_kg: 0.02, max_mg: 1, unit: 'mg' } - }; - function anaphDrug(name) { - var s = window._DRUGS && window._DRUGS.sections && window._DRUGS.sections.anaphylaxis; - if (s && s.drugs) { - var hit = s.drugs.filter(function(x) { return x.name === name; })[0]; - if (hit) return hit; - } - return ANAPH_FALLBACK[name] || {}; - } - - function calcAnaphylaxis() { - var wt = parseFloat(document.getElementById('anaph-weight').value); - var age = document.getElementById('anaph-age').value; - var resultDiv = document.getElementById('anaph-result'); - if (!wt) { resultDiv.innerHTML = '

Enter weight (kg).

'; return; } - var S = window._EM; - - var epi = anaphDrug('Epinephrine IM'); - var fluids = anaphDrug('Normal saline bolus'); - var dph = anaphDrug('Diphenhydramine'); - var rnt = anaphDrug('Ranitidine'); - var dex = anaphDrug('Dexamethasone'); - var mpn = anaphDrug('Methylprednisolone'); - var glc = anaphDrug('Glucagon'); - - var epiDose = d(wt, epi.dose_mg_per_kg, epi.max_mg); - var epiVol = Math.round(epiDose * 10) / 10; // 1:1000 = 1 mg/mL - var autoInjector = wt < 10 ? 'Draw up manually' : wt <= 25 ? 'EpiPen Jr / Auvi-Q 0.15 mg' : 'EpiPen / Auvi-Q 0.3 mg'; - - var html = '
'; - html += '
STEP 1: Epinephrine IM — GIVE IMMEDIATELY
'; - html += '
Epinephrine 1:1000 (1 mg/mL): ' + epiDose + ' mg (' + epiVol + ' mL) IM to lateral thigh
'; - html += '
' + epi.dose_mg_per_kg + ' mg/kg (max ' + epi.max_mg + ' mg) | Auto-injector: ' + autoInjector + '
'; - html += '
May repeat every 5-15 minutes if symptoms persist. No contraindications in anaphylaxis.
'; - html += '
'; - - html += '
'; - - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - - html += ''; - html += ''; - - html += '
StepDrugDoseRouteNotes
STEP 2PositionSupine + legs elevatedIf dyspneic: sitting position. If vomiting: recovery position
STEP 3O2High flow 10-15 L/minFace mask100% O2. Prepare for airway management
STEP 4IV fluidsNS ' + S.dStr(wt, fluids.dose_mg_per_kg, fluids.max_mg, ' mL') + ' bolusIV/IORepeat up to 60 mL/kg for hypotension
STEP 5Diphenhydramine' + S.dStr(wt, dph.dose_mg_per_kg, dph.max_mg) + 'IV/IM/POH1 blocker. NOT first-line — adjunct only
Ranitidine' + S.dStr(wt, rnt.dose_mg_per_kg, rnt.max_mg) + 'IV over 5 minH2 blocker. Optional adjunct
STEP 6Dexamethasone' + S.dStr(wt, dex.dose_mg_per_kg, dex.max_mg) + 'IV/IM/POPrevents biphasic reaction (4-6 hrs later)
Methylprednisolone' + S.dStr(wt, mpn.dose_mg_per_kg, mpn.max_mg) + 'IVAlternative steroid
IF REFRACTORYEpinephrine gtt0.1-1 mcg/kg/minIV infusionFor persistent hypotension despite fluids + IM epi
Glucagon' + S.dStr(wt, glc.dose_mg_per_kg, glc.max_mg) + 'IV/IMFor patients on beta-blockers not responding to epi
'; - html += '
Observe minimum 4-6 hours after last dose of epinephrine (biphasic reactions occur in 5-20% of cases). Discharge with EpiPen prescription and anaphylaxis action plan. Refer to allergist.
'; - html += '

ASCIA Anaphylaxis Guidelines 2021. WAO Anaphylaxis Guidance 2020. AAP/ACAAI Practice Parameters.

'; - resultDiv.innerHTML = html; - } -})(); - -// ============================================================ -// PROCEDURAL SEDATION -// ============================================================ -(function() { - document.addEventListener('click', function(e) { - if (e.target.id === 'btn-sed-calc' || e.target.closest('#btn-sed-calc')) calcSedation(); - }); - - function d(wt, mgPerKg, max) { var v = Math.round(wt * mgPerKg * 100) / 100; return max ? Math.min(v, max) : v; } - - // Fallback inline data — mirrors drugs.json sedation section. The first - // table's rows group by drug (Ketamine has both IV + IM lines), hence the - // display vs name split. `reverses` marks the final 2 rows as reversal - // agents shown in a separate table. - var SED_FALLBACK = [ - { name: 'Ketamine IV', display: 'Ketamine', dose_mg_per_kg_low: 1.5, dose_mg_per_kg_high: 2, max_mg_low: 100, max_mg_high: 150, unit: 'mg', route: 'IV', onset: '1 min', duration: '15-30 min', notes: 'Dissociative. Preserves airway reflexes.' }, - { name: 'Ketamine IM', display: '', dose_mg_per_kg_low: 4, dose_mg_per_kg_high: 5, max_mg_low: 300, max_mg_high: 400, unit: 'mg', route: 'IM', onset: '3-5 min', duration: '30-60 min', notes: 'Give atropine 0.01 mg/kg to reduce secretions.' }, - { name: 'Midazolam IV', display: 'Midazolam', dose_mg_per_kg_low: 0.05, dose_mg_per_kg_high: 0.1, max_mg_low: 2, max_mg_high: 5, unit: 'mg', route: 'IV', onset: '2-3 min', duration: '30-60 min', notes: 'Anxiolysis. Titrate q3-5 min.' }, - { name: 'Midazolam IN/PO', display: '', dose_mg_per_kg: 0.5, max_mg: 20, unit: 'mg', route: 'IN/PO', onset: '10-15 min', duration: '30-60 min', notes: 'IN (max 10 mg / naris) or PO (max 20 mg).' }, - { name: 'Propofol', display: 'Propofol', dose_mg_per_kg: 1, max_mg: 40, unit: 'mg', route: 'IV', onset: '30 sec', duration: '5-10 min', notes: 'Short procedures. Causes apnea — manage airway.' }, - { name: 'Fentanyl IV', display: 'Fentanyl', dose_mg_per_kg: 1, max_mg: 100, unit: 'mcg', route: 'IV', onset: '2-3 min', duration: '30-60 min', notes: 'Analgesic. Often combined with midazolam.' }, - { name: 'Fentanyl IN', display: '', dose_mg_per_kg: 2, max_mg: 100, unit: 'mcg', route: 'IN', onset: '5-10 min', duration: '30-60 min', notes: 'Intranasal.' }, - { name: 'Nitrous oxide', display: 'Nitrous oxide', dose_display: '50:50 or 70:30 mix', unit: 'mix', route: 'Inhaled',onset: '2-5 min', duration: '5 min off', notes: 'Self-administered via demand valve. Anxiolysis + mild analgesia.' }, - { name: 'Dexmedetomidine IN', display: 'Dexmedetomidine', dose_mg_per_kg_low: 2, dose_mg_per_kg_high: 3, max_mg_low: 100, max_mg_high: null, unit: 'mcg', route: 'IN', onset: '15-30 min', duration: '60-90 min', notes: 'Intranasal. No respiratory depression. Good for imaging.' }, - { name: 'Naloxone', display: 'Naloxone', dose_mg_per_kg: 0.1, max_mg: 2, unit: 'mg', route: 'IV/IM/IN', reverses: 'Opioids (fentanyl, morphine)', notes: 'Max 2 mg. Repeat q2-3 min. Duration shorter than opioids — monitor for re-sedation.' }, - { name: 'Flumazenil', display: 'Flumazenil', dose_mg_per_kg: 0.01, max_mg: 0.2, unit: 'mg', route: 'IV', reverses: 'Benzodiazepines (midazolam)', notes: 'Max 0.2 mg single dose. Repeat q1 min to max 1 mg total. Risk of seizures — use cautiously.' } - ]; - - function sedDrugs() { - var s = window._DRUGS && window._DRUGS.sections && window._DRUGS.sections.sedation; - if (s && s.drugs && s.drugs.length) { - return s.drugs.map(function(d) { - var fb = SED_FALLBACK.filter(function(x) { return x.name === d.name; })[0] || {}; - return Object.assign({}, fb, d); - }); - } - return SED_FALLBACK; - } - - // perKg footer that matches the original inline format exactly. - function sedPerKg(lo, hi, unit) { - unit = unit || 'mg'; - return ' (' + lo + (hi != null ? '-' + hi : '') + ' ' + unit + '/kg)'; - } - - // Build the Dose cell text for a sedation drug (supports low/high range - // and single-dose entries; honors custom dose_display for fixed doses). - function sedDoseCell(wt, dg) { - if (dg.dose_display) return dg.dose_display; - var unitLabel = dg.unit === 'mcg' ? ' mcg' : (dg.unit === 'mix' ? '' : ' mg'); - var perKgUnit = dg.unit === 'mcg' ? 'mcg' : 'mg'; - if (dg.dose_mg_per_kg_low != null) { - var lo = d(wt, dg.dose_mg_per_kg_low, dg.max_mg_low); - if (dg.dose_mg_per_kg_high != null) { - var hi = d(wt, dg.dose_mg_per_kg_high, dg.max_mg_high); - return lo + '-' + hi + unitLabel + sedPerKg(dg.dose_mg_per_kg_low, dg.dose_mg_per_kg_high, perKgUnit); - } - return lo + unitLabel + sedPerKg(dg.dose_mg_per_kg_low, null, perKgUnit); - } - if (dg.dose_mg_per_kg != null) { - var v = d(wt, dg.dose_mg_per_kg, dg.max_mg); - return v + unitLabel + sedPerKg(dg.dose_mg_per_kg, null, perKgUnit); - } - return ''; - } - - function sedRow(wt, dg, showReverses) { - var displayName = dg.display == null ? dg.name : dg.display; - var nameCell = displayName - ? '' + displayName + '' - : ''; - var dose = sedDoseCell(wt, dg); - if (showReverses) { - return '' + nameCell + '' + dose + '' + dg.route + '' + (dg.reverses || '') + '' + dg.notes + ''; - } - return '' + nameCell + '' + dose + '' + dg.route + '' + (dg.onset || '') + '' + (dg.duration || '') + '' + dg.notes + ''; - } - - function calcSedation() { - var wt = parseFloat(document.getElementById('sed-weight').value); - var resultDiv = document.getElementById('sed-result'); - if (!wt) { resultDiv.innerHTML = '

Enter weight (kg).

'; return; } - - var all = sedDrugs(); - var agents = all.filter(function(dg) { return !dg.reverses; }); - var reversals = all.filter(function(dg) { return !!dg.reverses; }); - - var html = '
Procedural Sedation — ' + wt + ' kg patient
'; - - // Sedation agents - html += '

Sedation Agents

'; - html += '
'; - html += agents.map(function(dg) { return sedRow(wt, dg, false); }).join(''); - html += '
DrugDoseRouteOnsetDurationNotes
'; - - // Reversal agents - html += '

Reversal Agents

'; - html += '
'; - html += reversals.map(function(dg) { return sedRow(wt, dg, true); }).join(''); - html += '
DrugDoseRouteReversesNotes
'; - - html += '
Pre-sedation checklist: NPO status (2h clear liquids, 6h solids), consent, monitoring equipment (pulse ox, capnography, BP), resuscitation equipment at bedside, suction ready, IV access. Minimum monitoring: continuous SpO2, HR, capnography. Provider capable of managing airway must be present.
'; - html += '

AAP Guidelines for Monitoring and Management of Pediatric Patients Before, During, and After Sedation. ASA Practice Guidelines for Sedation and Analgesia by Non-Anesthesiologists.

'; - resultDiv.innerHTML = html; - } -})();