Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Dr. Shafi Anesthesia Dosage Calculator</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .banded-row:nth-child(even) { | |
| background-color: #f8fafc; | |
| } | |
| .banded-row:hover { | |
| background-color: #e2e8f0; | |
| } | |
| .input-highlight { | |
| box-shadow: 0 0 0 2px #3b82f6; | |
| } | |
| .result-card { | |
| transition: all 0.3s ease; | |
| } | |
| .result-card:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); | |
| } | |
| .toggle-input { | |
| display: flex; | |
| align-items: center; | |
| } | |
| .toggle-input input[type="radio"] { | |
| display: none; | |
| } | |
| .toggle-input label { | |
| padding: 0.5rem 1rem; | |
| cursor: pointer; | |
| border: 1px solid #d1d5db; | |
| transition: all 0.2s; | |
| } | |
| .toggle-input label:first-of-type { | |
| border-radius: 0.375rem 0 0 0.375rem; | |
| border-right: none; | |
| } | |
| .toggle-input label:last-of-type { | |
| border-radius: 0 0.375rem 0.375rem 0; | |
| border-left: none; | |
| } | |
| .toggle-input input[type="radio"]:checked + label { | |
| background-color: #3b82f6; | |
| color: white; | |
| border-color: #3b82f6; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 min-h-screen"> | |
| <div class="container mx-auto px-4 py-8 max-w-6xl"> | |
| <!-- Header --> | |
| <header class="mb-8 text-center"> | |
| <h1 class="text-3xl font-bold text-blue-800 mb-2"> | |
| <i class="fas fa-syringe mr-2"></i>Dr. Shafi Anesthesia Dosage Calculator | |
| </h1> | |
| <p class="text-gray-600">Calculate precise anesthesia dosages based on patient weight or age</p> | |
| </header> | |
| <!-- Calculator Form --> | |
| <div class="bg-white rounded-lg shadow-md p-6 mb-8"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-4 border-b pb-2"> | |
| <i class="fas fa-calculator mr-2 text-blue-600"></i>Patient Information | |
| </h2> | |
| <div class="mb-4"> | |
| <p class="text-sm font-medium text-gray-700 mb-2">Input Method:</p> | |
| <div class="toggle-input"> | |
| <input type="radio" id="weightMethod" name="inputMethod" value="weight" checked> | |
| <label for="weightMethod" class="flex items-center"> | |
| <i class="fas fa-weight mr-1"></i> Weight | |
| </label> | |
| <input type="radio" id="ageMethod" name="inputMethod" value="age"> | |
| <label for="ageMethod" class="flex items-center"> | |
| <i class="fas fa-birthday-cake mr-1"></i> Age | |
| </label> | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <!-- Weight Input --> | |
| <div id="weightInputGroup"> | |
| <label for="weight" class="block text-sm font-medium text-gray-700 mb-1"> | |
| <i class="fas fa-weight mr-1"></i>Weight (kg) | |
| </label> | |
| <div class="relative"> | |
| <input type="number" id="weight" min="0" step="0.1" | |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 input-highlight" | |
| placeholder="Enter weight in kilograms"> | |
| <span class="absolute right-3 top-2 text-gray-500">kg</span> | |
| </div> | |
| </div> | |
| <!-- Age Input --> | |
| <div id="ageInputGroup" class="hidden"> | |
| <label class="block text-sm font-medium text-gray-700 mb-1"> | |
| <i class="fas fa-birthday-cake mr-1"></i>Age | |
| </label> | |
| <div class="grid grid-cols-2 gap-2"> | |
| <div> | |
| <input type="number" id="years" min="0" max="18" | |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" | |
| placeholder="Years"> | |
| </div> | |
| <div> | |
| <input type="number" id="months" min="0" max="11" | |
| class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" | |
| placeholder="Months"> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Additional Info --> | |
| <div> | |
| <label for="gender" class="block text-sm font-medium text-gray-700 mb-1"> | |
| <i class="fas fa-venus-mars mr-1"></i>Gender | |
| </label> | |
| <select id="gender" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| <option value="male">Male</option> | |
| <option value="female">Female</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="mt-6 flex justify-center"> | |
| <button id="calculateBtn" | |
| class="px-6 py-2 bg-blue-600 text-white font-medium rounded-md hover:bg-blue-700 transition duration-300 flex items-center"> | |
| <i class="fas fa-calculator mr-2"></i>Calculate Dosages | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Results Section --> | |
| <div id="resultsSection" class="hidden"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-4 border-b pb-2"> | |
| <i class="fas fa-prescription-bottle-alt mr-2 text-blue-600"></i>Calculated Dosages | |
| </h2> | |
| <!-- Summary Card --> | |
| <div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6 flex items-center"> | |
| <div class="mr-4 text-blue-800"> | |
| <i class="fas fa-info-circle text-2xl"></i> | |
| </div> | |
| <div> | |
| <h3 class="font-medium text-blue-800">Patient Summary</h3> | |
| <p id="patientSummary" class="text-sm text-gray-700"></p> | |
| <p id="weightSource" class="text-xs text-gray-500 mt-1"></p> | |
| </div> | |
| </div> | |
| <!-- Results Table --> | |
| <div class="overflow-x-auto bg-white rounded-lg shadow-md"> | |
| <table class="min-w-full divide-y divide-gray-200"> | |
| <thead class="bg-gray-100"> | |
| <tr> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-bold text-gray-700 uppercase tracking-wider">Drug</th> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-bold text-gray-700 uppercase tracking-wider">Dosage Range</th> | |
| <th scope="col" class="px-6 py-3 text-left text-xs font-bold text-gray-700 uppercase tracking-wider">Calculated Dosage (mg)</th> | |
| </tr> | |
| </thead> | |
| <tbody id="resultsTable" class="bg-white divide-y divide-gray-200"> | |
| <!-- Results will be inserted here by JavaScript --> | |
| </tbody> | |
| </table> | |
| </div> | |
| <!-- Notes Section --> | |
| <div class="mt-6 bg-yellow-50 border border-yellow-200 rounded-lg p-4"> | |
| <h3 class="font-medium text-yellow-800 flex items-center"> | |
| <i class="fas fa-exclamation-triangle mr-2"></i>Important Notes | |
| </h3> | |
| <ul class="list-disc pl-5 mt-2 text-sm text-gray-700 space-y-1"> | |
| <li>These calculations are for reference only. Always verify dosages before administration.</li> | |
| <li>Consider patient comorbidities, allergies, and other medications when determining final dosages.</li> | |
| <li>For pediatric patients, additional adjustments may be required based on age and clinical condition.</li> | |
| <li>Paracetamol dosage is calculated as IV (10-15mg/kg) for weights >25kg and as suppository (20mg/kg) for weights ≤25kg.</li> | |
| <li>Weight calculated from age is an estimate. Always measure actual weight when possible.</li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const weightInput = document.getElementById('weight'); | |
| const yearsInput = document.getElementById('years'); | |
| const monthsInput = document.getElementById('months'); | |
| const genderSelect = document.getElementById('gender'); | |
| const calculateBtn = document.getElementById('calculateBtn'); | |
| const resultsSection = document.getElementById('resultsSection'); | |
| const resultsTable = document.getElementById('resultsTable'); | |
| const patientSummary = document.getElementById('patientSummary'); | |
| const weightSource = document.getElementById('weightSource'); | |
| const weightMethod = document.getElementById('weightMethod'); | |
| const ageMethod = document.getElementById('ageMethod'); | |
| const weightInputGroup = document.getElementById('weightInputGroup'); | |
| const ageInputGroup = document.getElementById('ageInputGroup'); | |
| // Toggle between weight and age input | |
| weightMethod.addEventListener('change', function() { | |
| if (this.checked) { | |
| weightInputGroup.classList.remove('hidden'); | |
| ageInputGroup.classList.add('hidden'); | |
| } | |
| }); | |
| ageMethod.addEventListener('change', function() { | |
| if (this.checked) { | |
| weightInputGroup.classList.add('hidden'); | |
| ageInputGroup.classList.remove('hidden'); | |
| } | |
| }); | |
| // Drug database | |
| const drugs = [ | |
| { name: 'Glycopyrrolate', min: 0.005, max: 0.01 }, | |
| { name: 'Ondansetron', min: 0.05, max: 0.1 }, | |
| { name: 'Midazolam', min: 0.05, max: 0.1 }, | |
| { name: 'Atropine', min: 0.01, max: 0.02 }, | |
| { name: 'Fentanyl', min: 1, max: 2 }, | |
| { name: 'Propofol', min: 2, max: 3 }, | |
| { name: 'Atracurium', min: 0.5, max: 0.5 }, | |
| { name: 'Rocuronium', min: 0.6, max: 1.2 }, | |
| { name: 'Ketamine Sedation', min: 0.2, max: 0.8 }, | |
| { name: 'Ketamine Induction', min: 0.5, max: 2 }, | |
| { name: 'Ketamine IM Sedation', min: 2, max: 4 }, | |
| { name: 'Neostigmine', min: 0.05, max: 0.05 }, | |
| { name: 'Lidocaine', min: 1, max: 2 }, | |
| { name: 'Dexamethasone', min: 0.15, max: 15 }, | |
| { name: 'Succinylcholine', min: 1, max: 2 }, | |
| { name: 'Paracetamol IV', min: 10, max: 15 }, | |
| { name: 'Paracetamol Suppository', min: 20, max: 30 } | |
| ]; | |
| calculateBtn.addEventListener('click', function() { | |
| let weight, sourceText = ''; | |
| const years = parseInt(yearsInput.value) || 0; | |
| const months = parseInt(monthsInput.value) || 0; | |
| const gender = genderSelect.value; | |
| if (weightMethod.checked) { | |
| // Using direct weight input | |
| weight = parseFloat(weightInput.value); | |
| if (isNaN(weight) || weight <= 0) { | |
| alert('Please enter a valid weight in kilograms'); | |
| weightInput.focus(); | |
| return; | |
| } | |
| sourceText = 'Weight entered directly'; | |
| } else { | |
| // Calculate weight from age | |
| if (years === 0 && months === 0) { | |
| alert('Please enter either years or months of age'); | |
| yearsInput.focus(); | |
| return; | |
| } | |
| weight = calculateWeightFromAge(years, months, gender); | |
| sourceText = `Weight estimated from age (${years > 0 ? `${years} year${years > 1 ? 's' : ''}` : ''}${years > 0 && months > 0 ? ', ' : ''}${months > 0 ? `${months} month${months > 1 ? 's' : ''}` : ''}, ${gender})`; | |
| } | |
| // Calculate and display results | |
| calculateDosages(weight, years, months, sourceText); | |
| resultsSection.classList.remove('hidden'); | |
| // Scroll to results | |
| resultsSection.scrollIntoView({ behavior: 'smooth' }); | |
| }); | |
| function calculateWeightFromAge(years, months, gender) { | |
| const totalMonths = years * 12 + months; | |
| // Weight estimation formulas based on age (simplified pediatric growth charts) | |
| if (totalMonths <= 24) { // 0-2 years | |
| // For infants <2 years: weight (kg) = (age in months + 9)/2 | |
| return (totalMonths + 9) / 2; | |
| } else if (totalMonths <= 120) { // 2-10 years | |
| // For children 2-10 years: weight (kg) = (age in years × 2) + 8 | |
| return (years + (months / 12)) * 2 + 8; | |
| } else { // >10 years | |
| // For adolescents >10 years: different formulas for boys and girls | |
| if (gender === 'male') { | |
| return (years + (months / 12)) * 3 + 13; | |
| } else { | |
| return (years + (months / 12)) * 2.5 + 13; | |
| } | |
| } | |
| } | |
| function calculateDosages(weight, years, months, sourceText) { | |
| // Update patient summary | |
| let summaryText = `Weight: ${weight.toFixed(1)} kg`; | |
| if (years > 0 || months > 0) { | |
| summaryText += ` | Age: ${years > 0 ? `${years} year${years > 1 ? 's' : ''}` : ''}${years > 0 && months > 0 ? ', ' : ''}${months > 0 ? `${months} month${months > 1 ? 's' : ''}` : ''}`; | |
| } | |
| patientSummary.textContent = summaryText; | |
| weightSource.textContent = sourceText; | |
| // Clear previous results | |
| resultsTable.innerHTML = ''; | |
| // Calculate and add each drug | |
| drugs.forEach((drug, index) => { | |
| // Special handling for Paracetamol | |
| if (drug.name.includes('Paracetamol')) { | |
| if (drug.name === 'Paracetamol IV' && weight > 25) { | |
| addDrugRow(drug, weight, index); | |
| } else if (drug.name === 'Paracetamol Suppository' && weight <= 25) { | |
| addDrugRow(drug, weight, index); | |
| } | |
| } else { | |
| addDrugRow(drug, weight, index); | |
| } | |
| }); | |
| } | |
| function addDrugRow(drug, weight, index) { | |
| const minDose = drug.min * weight; | |
| const maxDose = drug.max * weight; | |
| const row = document.createElement('tr'); | |
| row.className = `banded-row ${index % 2 === 0 ? 'bg-white' : 'bg-gray-50'}`; | |
| // Special display for Paracetamol | |
| if (drug.name.includes('Paracetamol')) { | |
| const dosageText = weight > 25 ? '10-15 mg/kg (IV)' : '20 mg/kg (Suppository)'; | |
| const calculatedDose = weight > 25 ? (drug.min * weight).toFixed(1) + '-' + (drug.max * weight).toFixed(1) : (drug.min * weight).toFixed(1); | |
| row.innerHTML = ` | |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">Paracetamol</td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-700">${dosageText}</td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${calculatedDose}</td> | |
| `; | |
| } else { | |
| // Standard display for other drugs | |
| row.innerHTML = ` | |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${drug.name}</td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-700">${drug.min}-${drug.max} mg/kg</td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${minDose.toFixed(1)}${minDose !== maxDose ? `-${maxDose.toFixed(1)}` : ''}</td> | |
| `; | |
| } | |
| resultsTable.appendChild(row); | |
| } | |
| // Input validation | |
| weightInput.addEventListener('input', function() { | |
| if (this.value < 0) this.value = ''; | |
| }); | |
| yearsInput.addEventListener('input', function() { | |
| if (this.value < 0) this.value = ''; | |
| if (this.value > 18) this.value = 18; | |
| }); | |
| monthsInput.addEventListener('input', function() { | |
| if (this.value < 0) this.value = ''; | |
| if (this.value > 11) this.value = 11; | |
| }); | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Shfkvl/ped-dose-anesthesia" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |