Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>HeadNeck Dose Planner | Radiation Treatment Planning</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> | |
| .gradient-bg { | |
| background: linear-gradient(135deg, #1e3a8a 0%, #3b82f6 100%); | |
| } | |
| .dose-meter { | |
| height: 8px; | |
| border-radius: 4px; | |
| background: linear-gradient(90deg, #10b981 0%, #f59e0b 50%, #ef4444 100%); | |
| } | |
| .anatomy-illustration { | |
| background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"><path d="M100,20 C120,20 130,40 140,60 C150,80 160,100 150,120 C140,140 120,160 100,170 C80,160 60,140 50,120 C40,100 50,80 60,60 C70,40 80,20 100,20 Z" fill="%23e5e7eb" stroke="%236b7280" stroke-width="2"/><circle cx="90" cy="50" r="5" fill="%23ef4444"/><circle cx="110" cy="50" r="5" fill="%23ef4444"/><path d="M90,70 C95,80 105,80 110,70" stroke="%236b7280" stroke-width="2" fill="none"/></svg>'); | |
| background-repeat: no-repeat; | |
| background-position: center; | |
| background-size: contain; | |
| } | |
| .tumor-marker { | |
| position: absolute; | |
| width: 16px; | |
| height: 16px; | |
| border-radius: 50%; | |
| background-color: #ef4444; | |
| transform: translate(-50%, -50%); | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { transform: translate(-50%, -50%) scale(1); opacity: 1; } | |
| 50% { transform: translate(-50%, -50%) scale(1.2); opacity: 0.7; } | |
| 100% { transform: translate(-50%, -50%) scale(1); opacity: 1; } | |
| } | |
| .print-only { | |
| display: none; | |
| } | |
| @media print { | |
| .no-print { | |
| display: none; | |
| } | |
| .print-only { | |
| display: block; | |
| } | |
| body { | |
| padding: 20px; | |
| background: white; | |
| color: black; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 min-h-screen font-sans"> | |
| <!-- Header --> | |
| <header class="gradient-bg text-white shadow-lg"> | |
| <div class="container mx-auto px-4 py-6"> | |
| <div class="flex flex-col md:flex-row justify-between items-center"> | |
| <div class="flex items-center mb-4 md:mb-0"> | |
| <i class="fas fa-radiation-alt text-3xl mr-3"></i> | |
| <div> | |
| <h1 class="text-2xl font-bold">HeadNeck Dose Planner</h1> | |
| <p class="text-sm opacity-80">Personalized Radiation Treatment Planning</p> | |
| </div> | |
| </div> | |
| <nav class="flex space-x-4"> | |
| <a href="#" class="px-3 py-2 rounded hover:bg-blue-700 transition" id="homeLink">Home</a> | |
| <a href="#" class="px-3 py-2 rounded hover:bg-blue-700 transition" id="newPlanLink">New Plan</a> | |
| <a href="#" class="px-3 py-2 rounded hover:bg-blue-700 transition" id="savedPlansLink">Saved Plans</a> | |
| <a href="#" class="px-3 py-2 rounded hover:bg-blue-700 transition" id="guidelinesLink">Guidelines</a> | |
| </nav> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Main Content --> | |
| <main class="container mx-auto px-4 py-8"> | |
| <!-- Patient Information Section --> | |
| <section class="bg-white rounded-lg shadow-md p-6 mb-8"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> | |
| <i class="fas fa-user-circle mr-2 text-blue-600"></i> Patient Information | |
| </h2> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-6"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Patient ID</label> | |
| <input type="text" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Enter patient ID"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Name</label> | |
| <input type="text" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Patient name"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Age</label> | |
| <input type="number" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Age"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Gender</label> | |
| <select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> | |
| <option value="">Select</option> | |
| <option value="male">Male</option> | |
| <option value="female">Female</option> | |
| <option value="other">Other</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Weight (kg)</label> | |
| <input type="number" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Weight"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Height (cm)</label> | |
| <input type="number" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Height"> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Tumor Characteristics Section --> | |
| <section class="bg-white rounded-lg shadow-md p-6 mb-8"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> | |
| <i class="fas fa-tumor mr-2 text-red-600"></i> Tumor Characteristics | |
| </h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Tumor Type</label> | |
| <select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" id="tumorType"> | |
| <option value="">Select tumor type</option> | |
| <option value="nasopharynx">Nasopharyngeal carcinoma</option> | |
| <option value="oropharynx">Oropharyngeal carcinoma</option> | |
| <option value="hypopharynx">Hypopharyngeal carcinoma</option> | |
| <option value="larynx">Laryngeal carcinoma</option> | |
| <option value="oral">Oral cavity cancer</option> | |
| <option value="salivary">Salivary gland cancer</option> | |
| <option value="sinonasal">Sinonasal cancer</option> | |
| <option value="other">Other</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Tumor Stage</label> | |
| <select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" id="tumorStage"> | |
| <option value="">Select stage</option> | |
| <option value="I">Stage I</option> | |
| <option value="II">Stage II</option> | |
| <option value="III">Stage III</option> | |
| <option value="IVA">Stage IVA</option> | |
| <option value="IVB">Stage IVB</option> | |
| <option value="IVC">Stage IVC</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Tumor Size (cm)</label> | |
| <input type="number" step="0.1" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" id="tumorSize" placeholder="Diameter in cm"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Tumor Location</label> | |
| <select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" id="tumorLocation"> | |
| <option value="">Select location</option> | |
| <option value="right">Right side</option> | |
| <option value="left">Left side</option> | |
| <option value="midline">Midline</option> | |
| <option value="bilateral">Bilateral</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="mt-6 relative anatomy-illustration h-64 w-full rounded-md border border-gray-200" id="anatomyCanvas"> | |
| <!-- Tumor markers will be added here by JavaScript --> | |
| </div> | |
| <div class="mt-4 flex justify-center"> | |
| <button class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition mr-2" id="addTumorBtn"> | |
| <i class="fas fa-plus mr-1"></i> Add Tumor Marker | |
| </button> | |
| <button class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition" id="clearTumorsBtn"> | |
| <i class="fas fa-trash-alt mr-1"></i> Clear Markers | |
| </button> | |
| </div> | |
| </section> | |
| <!-- Treatment Planning Section --> | |
| <section class="bg-white rounded-lg shadow-md p-6 mb-8"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> | |
| <i class="fas fa-procedures mr-2 text-green-600"></i> Treatment Planning | |
| </h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Treatment Intent</label> | |
| <select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" id="treatmentIntent"> | |
| <option value="curative">Curative</option> | |
| <option value="palliative">Palliative</option> | |
| <option value="adjuvant">Adjuvant</option> | |
| <option value="neoadjuvant">Neoadjuvant</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Radiation Technique</label> | |
| <select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" id="radiationTechnique"> | |
| <option value="imrt">IMRT</option> | |
| <option value="vmat">VMAT</option> | |
| <option value="3dcrt">3D-CRT</option> | |
| <option value="protons">Proton Therapy</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Total Dose (Gy)</label> | |
| <input type="number" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" id="totalDose" placeholder="Total dose in Gy"> | |
| <div class="mt-2"> | |
| <div class="dose-meter w-full"></div> | |
| <div class="flex justify-between text-xs mt-1"> | |
| <span class="text-green-600">Safe</span> | |
| <span class="text-yellow-500">Caution</span> | |
| <span class="text-red-600">Danger</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Fractionation</label> | |
| <select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" id="fractionation"> | |
| <option value="standard">Standard (2 Gy/fx)</option> | |
| <option value="hyper">Hyperfractionated (1.2 Gy BID)</option> | |
| <option value="hypo">Hypofractionated (2.5-3 Gy/fx)</option> | |
| <option value="sbrt">SBRT (5-8 Gy/fx)</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Organs at Risk Priority</label> | |
| <select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" id="oarPriority"> | |
| <option value="balanced">Balanced Approach</option> | |
| <option value="spinal">Spinal Cord Priority</option> | |
| <option value="parotid">Parotid Sparing</option> | |
| <option value="mandible">Mandible Sparing</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Concurrent Chemotherapy</label> | |
| <select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" id="concurrentChemo"> | |
| <option value="no">No</option> | |
| <option value="cisplatin">Cisplatin</option> | |
| <option value="carboplatin">Carboplatin</option> | |
| <option value="cetuximab">Cetuximab</option> | |
| <option value="other">Other</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="mt-6"> | |
| <h3 class="text-lg font-medium text-gray-800 mb-2">Organs at Risk Constraints</h3> | |
| <div class="overflow-x-auto"> | |
| <table class="min-w-full divide-y divide-gray-200"> | |
| <thead class="bg-gray-50"> | |
| <tr> | |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Organ</th> | |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Max Dose (Gy)</th> | |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Mean Dose (Gy)</th> | |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Priority</th> | |
| </tr> | |
| </thead> | |
| <tbody class="bg-white divide-y divide-gray-200"> | |
| <tr> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-gray-900">Spinal Cord</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">45</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">-</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">High</td> | |
| </tr> | |
| <tr> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-gray-900">Brainstem</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">54</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">-</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">High</td> | |
| </tr> | |
| <tr> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-gray-900">Parotid Glands</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">-</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">26</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">Medium</td> | |
| </tr> | |
| <tr> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-gray-900">Mandible</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">70</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">-</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">Medium</td> | |
| </tr> | |
| <tr> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-gray-900">Optic Nerves</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">50</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">-</td> | |
| <td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">High</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Plan Summary & Actions --> | |
| <section class="bg-white rounded-lg shadow-md p-6 mb-8"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> | |
| <i class="fas fa-file-medical mr-2 text-purple-600"></i> Plan Summary | |
| </h2> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-6"> | |
| <div class="bg-blue-50 p-4 rounded-lg border border-blue-100"> | |
| <h3 class="font-medium text-blue-800 mb-2">Recommended Dose</h3> | |
| <p class="text-3xl font-bold text-blue-600" id="recommendedDose">0 Gy</p> | |
| <p class="text-sm text-blue-700 mt-1" id="doseExplanation">Based on tumor characteristics</p> | |
| </div> | |
| <div class="bg-green-50 p-4 rounded-lg border border-green-100"> | |
| <h3 class="font-medium text-green-800 mb-2">Fractionation</h3> | |
| <p class="text-2xl font-bold text-green-600" id="recommendedFractions">0 fractions</p> | |
| <p class="text-sm text-green-700 mt-1" id="fractionExplanation">Standard fractionation</p> | |
| </div> | |
| <div class="bg-purple-50 p-4 rounded-lg border border-purple-100"> | |
| <h3 class="font-medium text-purple-800 mb-2">Risk Assessment</h3> | |
| <p class="text-2xl font-bold text-purple-600" id="riskLevel">Low</p> | |
| <p class="text-sm text-purple-700 mt-1" id="riskExplanation">Normal tissue constraints achievable</p> | |
| </div> | |
| </div> | |
| <div class="mt-6 bg-yellow-50 p-4 rounded-lg border border-yellow-200" id="planNotes"> | |
| <h3 class="font-medium text-yellow-800 mb-2 flex items-center"> | |
| <i class="fas fa-exclamation-triangle mr-2"></i> Plan Notes | |
| </h3> | |
| <p class="text-yellow-700">Enter patient and tumor information to generate a personalized treatment plan.</p> | |
| </div> | |
| <div class="mt-6 flex flex-wrap justify-between"> | |
| <div class="mb-4 md:mb-0"> | |
| <button class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition mr-2 no-print" id="resetBtn"> | |
| <i class="fas fa-redo mr-1"></i> Reset Form | |
| </button> | |
| <button class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition no-print" id="calculateBtn"> | |
| <i class="fas fa-calculator mr-1"></i> Calculate Plan | |
| </button> | |
| </div> | |
| <div> | |
| <button class="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition mr-2 no-print" id="savePlanBtn"> | |
| <i class="fas fa-save mr-1"></i> Save Plan | |
| </button> | |
| <button class="px-4 py-2 bg-purple-600 text-white rounded-md hover:bg-purple-700 transition no-print" id="printPlanBtn"> | |
| <i class="fas fa-print mr-1"></i> Print Plan | |
| </button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Print Section (Hidden until printing) --> | |
| <section class="print-only bg-white p-6"> | |
| <div class="flex justify-between items-center mb-6 border-b pb-4"> | |
| <div> | |
| <h1 class="text-2xl font-bold text-gray-800">HeadNeck Dose Planner</h1> | |
| <p class="text-gray-600">Radiation Treatment Plan</p> | |
| </div> | |
| <div class="text-right"> | |
| <p class="text-sm text-gray-500">Generated on: <span id="printDate"></span></p> | |
| <p class="text-sm text-gray-500">Plan ID: <span id="printPlanId"></span></p> | |
| </div> | |
| </div> | |
| <div class="mb-6"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-2">Patient Information</h2> | |
| <div class="grid grid-cols-3 gap-4 text-sm"> | |
| <div> | |
| <p class="font-medium">Patient ID:</p> | |
| <p id="printPatientId"></p> | |
| </div> | |
| <div> | |
| <p class="font-medium">Name:</p> | |
| <p id="printPatientName"></p> | |
| </div> | |
| <div> | |
| <p class="font-medium">Age:</p> | |
| <p id="printPatientAge"></p> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mb-6"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-2">Tumor Characteristics</h2> | |
| <div class="grid grid-cols-3 gap-4 text-sm"> | |
| <div> | |
| <p class="font-medium">Tumor Type:</p> | |
| <p id="printTumorType"></p> | |
| </div> | |
| <div> | |
| <p class="font-medium">Stage:</p> | |
| <p id="printTumorStage"></p> | |
| </div> | |
| <div> | |
| <p class="font-medium">Size:</p> | |
| <p id="printTumorSize"></p> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mb-6"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-2">Treatment Plan</h2> | |
| <div class="grid grid-cols-3 gap-4 text-sm"> | |
| <div> | |
| <p class="font-medium">Total Dose:</p> | |
| <p id="printTotalDose"></p> | |
| </div> | |
| <div> | |
| <p class="font-medium">Fractions:</p> | |
| <p id="printFractions"></p> | |
| </div> | |
| <div> | |
| <p class="font-medium">Technique:</p> | |
| <p id="printTechnique"></p> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mb-6"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-2">Organs at Risk Constraints</h2> | |
| <table class="min-w-full border text-sm"> | |
| <thead> | |
| <tr class="bg-gray-100"> | |
| <th class="border px-4 py-2 text-left">Organ</th> | |
| <th class="border px-4 py-2 text-left">Max Dose (Gy)</th> | |
| <th class="border px-4 py-2 text-left">Mean Dose (Gy)</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td class="border px-4 py-2">Spinal Cord</td> | |
| <td class="border px-4 py-2">45</td> | |
| <td class="border px-4 py-2">-</td> | |
| </tr> | |
| <tr> | |
| <td class="border px-4 py-2">Brainstem</td> | |
| <td class="border px-4 py-2">54</td> | |
| <td class="border px-4 py-2">-</td> | |
| </tr> | |
| <tr> | |
| <td class="border px-4 py-2">Parotid Glands</td> | |
| <td class="border px-4 py-2">-</td> | |
| <td class="border px-4 py-2">26</td> | |
| </tr> | |
| <tr> | |
| <td class="border px-4 py-2">Mandible</td> | |
| <td class="border px-4 py-2">70</td> | |
| <td class="border px-4 py-2">-</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| <div class="mt-8 pt-4 border-t"> | |
| <div class="flex justify-between"> | |
| <div class="w-1/2 pr-4"> | |
| <p class="font-medium mb-2">Physician Signature:</p> | |
| <div class="h-16 border-b border-gray-400"></div> | |
| <p class="text-sm text-gray-500 mt-1">Name & Date</p> | |
| </div> | |
| <div class="w-1/2 pl-4"> | |
| <p class="font-medium mb-2">Medical Physicist Signature:</p> | |
| <div class="h-16 border-b border-gray-400"></div> | |
| <p class="text-sm text-gray-500 mt-1">Name & Date</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-8 text-center text-xs text-gray-500"> | |
| <p>This document was automatically generated by HeadNeck Dose Planner software.</p> | |
| <p>For clinical use only. Verify all dosimetric parameters before treatment.</p> | |
| </div> | |
| </section> | |
| </main> | |
| <!-- Footer --> | |
| <footer class="gradient-bg text-white py-6"> | |
| <div class="container mx-auto px-4"> | |
| <div class="flex flex-col md:flex-row justify-between items-center"> | |
| <div class="mb-4 md:mb-0"> | |
| <p class="text-sm">© 2023 HeadNeck Dose Planner. For medical professionals only.</p> | |
| <p class="text-xs opacity-70 mt-1">Version 1.0.0</p> | |
| </div> | |
| <div class="flex space-x-4"> | |
| <a href="#" class="text-sm hover:underline">Privacy Policy</a> | |
| <a href="#" class="text-sm hover:underline">Terms of Use</a> | |
| <a href="#" class="text-sm hover:underline">Contact Support</a> | |
| </div> | |
| </div> | |
| </div> | |
| </footer> | |
| <!-- JavaScript --> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Tumor marker functionality | |
| const anatomyCanvas = document.getElementById('anatomyCanvas'); | |
| const addTumorBtn = document.getElementById('addTumorBtn'); | |
| const clearTumorsBtn = document.getElementById('clearTumorsBtn'); | |
| const tumorSizeInput = document.getElementById('tumorSize'); | |
| const tumorLocationInput = document.getElementById('tumorLocation'); | |
| let tumorMarkers = []; | |
| addTumorBtn.addEventListener('click', function() { | |
| if (!tumorSizeInput.value || !tumorLocationInput.value) { | |
| alert('Please enter tumor size and location first'); | |
| return; | |
| } | |
| const size = parseFloat(tumorSizeInput.value); | |
| const location = tumorLocationInput.value; | |
| // Create a new tumor marker | |
| const marker = document.createElement('div'); | |
| marker.className = 'tumor-marker'; | |
| // Set size based on input (scaled for visualization) | |
| const markerSize = Math.min(16 + (size * 4), 40); | |
| marker.style.width = `${markerSize}px`; | |
| marker.style.height = `${markerSize}px`; | |
| // Position based on location | |
| let left, top; | |
| const canvasRect = anatomyCanvas.getBoundingClientRect(); | |
| const canvasWidth = canvasRect.width; | |
| const canvasHeight = canvasRect.height; | |
| switch(location) { | |
| case 'right': | |
| left = 70 + (Math.random() * 10); | |
| top = 50 + (Math.random() * 20); | |
| break; | |
| case 'left': | |
| left = 30 + (Math.random() * 10); | |
| top = 50 + (Math.random() * 20); | |
| break; | |
| case 'midline': | |
| left = 50 + (Math.random() * 10); | |
| top = 50 + (Math.random() * 10); | |
| break; | |
| case 'bilateral': | |
| left = 50 + (Math.random() * 40 - 20); | |
| top = 50 + (Math.random() * 20); | |
| break; | |
| default: | |
| left = 50; | |
| top = 50; | |
| } | |
| // Convert percentages to pixels | |
| const leftPx = (left / 100) * canvasWidth; | |
| const topPx = (top / 100) * canvasHeight; | |
| marker.style.left = `${leftPx}px`; | |
| marker.style.top = `${topPx}px`; | |
| // Add tooltip with tumor info | |
| marker.title = `Size: ${size} cm\nLocation: ${location}`; | |
| anatomyCanvas.appendChild(marker); | |
| tumorMarkers.push(marker); | |
| }); | |
| clearTumorsBtn.addEventListener('click', function() { | |
| tumorMarkers.forEach(marker => { | |
| anatomyCanvas.removeChild(marker); | |
| }); | |
| tumorMarkers = []; | |
| }); | |
| // Calculate plan functionality | |
| const calculateBtn = document.getElementById('calculateBtn'); | |
| const recommendedDose = document.getElementById('recommendedDose'); | |
| const doseExplanation = document.getElementById('doseExplanation'); | |
| const recommendedFractions = document.getElementById('recommendedFractions'); | |
| const fractionExplanation = document.getElementById('fractionExplanation'); | |
| const riskLevel = document.getElementById('riskLevel'); | |
| const riskExplanation = document.getElementById('riskExplanation'); | |
| const planNotes = document.getElementById('planNotes'); | |
| calculateBtn.addEventListener('click', function() { | |
| const tumorType = document.getElementById('tumorType').value; | |
| const tumorStage = document.getElementById('tumorStage').value; | |
| const treatmentIntent = document.getElementById('treatmentIntent').value; | |
| const fractionation = document.getElementById('fractionation').value; | |
| const concurrentChemo = document.getElementById('concurrentChemo').value; | |
| if (!tumorType || !tumorStage) { | |
| alert('Please enter tumor characteristics first'); | |
| return; | |
| } | |
| // Calculate recommended dose based on inputs | |
| let dose = 66; // Default for curative | |
| let fractions = 33; | |
| let risk = 'Low'; | |
| let notes = []; | |
| // Adjust based on treatment intent | |
| if (treatmentIntent === 'palliative') { | |
| dose = 20; | |
| fractions = 5; | |
| risk = 'Low'; | |
| notes.push('Palliative regimen selected'); | |
| } else if (treatmentIntent === 'adjuvant') { | |
| dose = 60; | |
| fractions = 30; | |
| notes.push('Adjuvant treatment after surgery'); | |
| } else if (treatmentIntent === 'neoadjuvant') { | |
| dose = 50; | |
| fractions = 25; | |
| notes.push('Neoadjuvant treatment before surgery'); | |
| } | |
| // Adjust based on tumor stage | |
| if (tumorStage === 'I') { | |
| dose = Math.max(50, dose - 6); | |
| } else if (tumorStage === 'II') { | |
| dose = Math.max(60, dose - 6); | |
| } else if (tumorStage === 'IVB' || tumorStage === 'IVC') { | |
| dose = Math.min(70, dose + 4); | |
| risk = 'High'; | |
| notes.push('Advanced stage disease - consider dose escalation'); | |
| } | |
| // Adjust based on fractionation | |
| if (fractionation === 'hyper') { | |
| fractions = Math.ceil(dose / 1.2) * 2; | |
| notes.push('Hyperfractionated regimen (BID)'); | |
| } else if (fractionation === 'hypo') { | |
| fractions = Math.ceil(dose / 2.5); | |
| notes.push('Hypofractionated regimen'); | |
| } else if (fractionation === 'sbrt') { | |
| fractions = 5; | |
| dose = 35; | |
| notes.push('SBRT regimen selected'); | |
| } | |
| // Adjust based on concurrent chemotherapy | |
| if (concurrentChemo !== 'no') { | |
| if (treatmentIntent === 'curative') { | |
| dose = 70; | |
| fractions = 35; | |
| } | |
| notes.push(`Concurrent ${concurrentChemo} - consider dose modifications`); | |
| risk = 'Medium'; | |
| } | |
| // Special cases for tumor types | |
| if (tumorType === 'nasopharynx') { | |
| dose = 70; | |
| fractions = 35; | |
| notes.push('Nasopharyngeal carcinoma - standard dose 70Gy'); | |
| } else if (tumorType === 'larynx') { | |
| if (tumorStage === 'I' || tumorStage === 'II') { | |
| dose = 66; | |
| fractions = 33; | |
| notes.push('Early stage laryngeal cancer - consider voice preservation'); | |
| } | |
| } | |
| // Update the UI | |
| recommendedDose.textContent = `${dose} Gy`; | |
| recommendedFractions.textContent = `${fractions} fractions`; | |
| // Set risk level and color | |
| riskLevel.textContent = risk; | |
| if (risk === 'High') { | |
| riskLevel.className = 'text-2xl font-bold text-red-600'; | |
| } else if (risk === 'Medium') { | |
| riskLevel.className = 'text-2xl font-bold text-yellow-600'; | |
| } else { | |
| riskLevel.className = 'text-2xl font-bold text-green-600'; | |
| } | |
| // Update explanations | |
| doseExplanation.textContent = getDoseExplanation(tumorType, tumorStage, treatmentIntent); | |
| fractionExplanation.textContent = getFractionExplanation(fractionation); | |
| riskExplanation.textContent = getRiskExplanation(risk); | |
| // Update plan notes | |
| if (notes.length > 0) { | |
| planNotes.innerHTML = ` | |
| <h3 class="font-medium text-yellow-800 mb-2 flex items-center"> | |
| <i class="fas fa-exclamation-triangle mr-2"></i> Plan Notes | |
| </h3> | |
| <ul class="list-disc list-inside text-yellow-700"> | |
| ${notes.map(note => `<li>${note}</li>`).join('')} | |
| </ul> | |
| `; | |
| } | |
| }); | |
| function getDoseExplanation(type, stage, intent) { | |
| if (intent === 'palliative') { | |
| return 'Palliative dose regimen'; | |
| } | |
| let explanation = `Standard dose for ${type}`; | |
| if (stage === 'I' || stage === 'II') { | |
| explanation += ' (early stage)'; | |
| } else if (stage === 'III' || stage === 'IVA') { | |
| explanation += ' (locally advanced)'; | |
| } else { | |
| explanation += ' (advanced/metastatic)'; | |
| } | |
| return explanation; | |
| } | |
| function getFractionExplanation(fractionation) { | |
| switch(fractionation) { | |
| case 'hyper': return 'Hyperfractionated (BID) regimen'; | |
| case 'hypo': return 'Hypofractionated regimen'; | |
| case 'sbrt': return 'Stereotactic body radiotherapy'; | |
| default: return 'Standard fractionation (2 Gy/fx)'; | |
| } | |
| } | |
| function getRiskExplanation(risk) { | |
| switch(risk) { | |
| case 'High': return 'Careful OAR evaluation needed'; | |
| case 'Medium': return 'Standard constraints achievable'; | |
| default: return 'Normal tissue constraints achievable'; | |
| } | |
| } | |
| // Print functionality | |
| const printPlanBtn = document.getElementById('printPlanBtn'); | |
| printPlanBtn.addEventListener('click', function() { | |
| // Set print date | |
| const now = new Date(); | |
| document.getElementById('printDate').textContent = now.toLocaleDateString() + ' ' + now.toLocaleTimeString(); | |
| // Generate random plan ID | |
| document.getElementById('printPlanId').textContent = 'PL-' + Math.floor(100000 + Math.random() * 900000); | |
| // Populate patient info | |
| document.getElementById('printPatientId').textContent = document.querySelector('input[placeholder="Enter patient ID"]').value || 'Not specified'; | |
| document.getElementById('printPatientName').textContent = document.querySelector('input[placeholder="Patient name"]').value || 'Not specified'; | |
| document.getElementById('printPatientAge').textContent = document.querySelector('input[placeholder="Age"]').value || 'Not specified'; | |
| // Populate tumor info | |
| document.getElementById('printTumorType').textContent = document.getElementById('tumorType').value || 'Not specified'; | |
| document.getElementById('printTumorStage').textContent = document.getElementById('tumorStage').value || 'Not specified'; | |
| document.getElementById('printTumorSize').textContent = tumorSizeInput.value ? tumorSizeInput.value + ' cm' : 'Not specified'; | |
| // Populate treatment info | |
| document.getElementById('printTotalDose').textContent = recommendedDose.textContent; | |
| document.getElementById('printFractions').textContent = recommendedFractions.textContent; | |
| document.getElementById('printTechnique').textContent = document.getElementById('radiationTechnique').value || 'Not specified'; | |
| // Trigger print | |
| window.print(); | |
| }); | |
| // Reset form | |
| const resetBtn = document.getElementById('resetBtn'); | |
| resetBtn.addEventListener('click', function() { | |
| if (confirm('Are you sure you want to reset all fields?')) { | |
| // Clear all form inputs | |
| document.querySelectorAll('input, select').forEach(element => { | |
| if (element.type !== 'button') { | |
| element.value = ''; | |
| } | |
| }); | |
| // Clear tumor markers | |
| clearTumorsBtn.click(); | |
| // Reset recommendations | |
| recommendedDose.textContent = '0 Gy'; | |
| recommendedFractions.textContent = '0 fractions'; | |
| riskLevel.textContent = 'Low'; | |
| riskLevel.className = 'text-2xl font-bold text-green-600'; | |
| doseExplanation.textContent = 'Based on tumor characteristics'; | |
| fractionExplanation.textContent = 'Standard fractionation'; | |
| riskExplanation.textContent = 'Normal tissue constraints achievable'; | |
| // Reset plan notes | |
| planNotes.innerHTML = ` | |
| <h3 class="font-medium text-yellow-800 mb-2 flex items-center"> | |
| <i class="fas fa-exclamation-triangle mr-2"></i> Plan Notes | |
| </h3> | |
| <p class="text-yellow-700">Enter patient and tumor information to generate a personalized treatment plan.</p> | |
| `; | |
| } | |
| }); | |
| // Save plan functionality (simulated) | |
| const savePlanBtn = document.getElementById('savePlanBtn'); | |
| savePlanBtn.addEventListener('click', function() { | |
| const patientId = document.querySelector('input[placeholder="Enter patient ID"]').value; | |
| if (!patientId) { | |
| alert('Please enter at least a Patient ID to save the plan'); | |
| return; | |
| } | |
| // In a real app, this would save to a database | |
| // Here we just simulate with a confirmation | |
| alert(`Plan saved for patient ${patientId}`); | |
| // Change button to indicate success | |
| savePlanBtn.innerHTML = '<i class="fas fa-check mr-1"></i> Plan Saved'; | |
| savePlanBtn.className = 'px-4 py-2 bg-green-600 text-white rounded-md transition mr-2 no-print'; | |
| setTimeout(() => { | |
| savePlanBtn.innerHTML = '<i class="fas fa-save mr-1"></i> Save Plan'; | |
| savePlanBtn.className = 'px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition mr-2 no-print'; | |
| }, 2000); | |
| }); | |
| // Navigation links | |
| document.querySelectorAll('#homeLink, #newPlanLink, #savedPlansLink, #guidelinesLink').forEach(link => { | |
| link.addEventListener('click', function(e) { | |
| e.preventDefault(); | |
| alert('Navigation would go to: ' + this.textContent); | |
| }); | |
| }); | |
| }); | |
| </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=Godito/dose-planner" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |