Spaces:
Running
Running
Download script.js from SinJR/medvision-model-viewer: direct link, hf CLI and curl.
- Browser
- Download file 8.37 kB
-
https://huggingface.co/spaces/SinJR/medvision-model-viewer/resolve/main/script.js
- Command line
-
hf download hf://spaces/SinJR/medvision-model-viewer/script.js
-
curl -L -o script.js https://huggingface.co/spaces/SinJR/medvision-model-viewer/resolve/main/script.js
8.37 kB
| // Global state | |
| const appState = { | |
| currentModel: 'yolov11n', | |
| inputModality: 'image', | |
| inputSource: 'file', | |
| isLoading: false, | |
| results: [] | |
| }; | |
| // Initialize the application | |
| function initApp() { | |
| console.log('MedVision Model Viewer initialized'); | |
| // Load default model (YOLOv11n) | |
| loadModel('yolov11n'); | |
| // Set up event listeners | |
| setupEventListeners(); | |
| } | |
| // Load a model into the application | |
| function loadModel(modelName) { | |
| appState.isLoading = true; | |
| document.getElementById('loading-overlay').classList.remove('hidden'); | |
| console.log(`Loading model: ${modelName}`); | |
| // Simulate model loading | |
| setTimeout(() => { | |
| appState.currentModel = modelName; | |
| appState.isLoading = false; | |
| document.getElementById('loading-overlay').classList.add('hidden'); | |
| updateUI(); | |
| }, 1500); | |
| } | |
| // Run inference with the current model | |
| function runInference(inputData) { | |
| if (appState.isLoading) return; | |
| appState.isLoading = true; | |
| document.getElementById('loading-overlay').classList.remove('hidden'); | |
| console.log(`Running inference with ${appState.currentModel} on ${appState.inputModality} input`); | |
| // Simulate inference | |
| setTimeout(() => { | |
| // Mock results for demo purposes | |
| appState.results = generateMockResults(); | |
| appState.isLoading = false; | |
| document.getElementById('loading-overlay').classList.add('hidden'); | |
| updateUI(); | |
| renderResults(); | |
| }, 2000); | |
| } | |
| // Generate mock results for demo | |
| function generateMockResults() { | |
| const classes = ['tumor', 'organ', 'lesion', 'vessel', 'bone']; | |
| const results = []; | |
| for (let i = 0; i < 5; i++) { | |
| results.push({ | |
| class: classes[Math.floor(Math.random() * classes.length)], | |
| confidence: (Math.random() * 0.9 + 0.1).toFixed(2), | |
| bbox: { | |
| x: Math.floor(Math.random() * 100), | |
| y: Math.floor(Math.random() * 100), | |
| width: Math.floor(Math.random() * 30 + 10), | |
| height: Math.floor(Math.random() * 30 + 10) | |
| }, | |
| color: `#${Math.floor(Math.random()*16777215).toString(16)}` | |
| }); | |
| } | |
| return results; | |
| } | |
| // Update the UI based on current state | |
| function updateUI() { | |
| // Update model indicator | |
| document.querySelectorAll('[data-model-indicator]').forEach(el => { | |
| el.textContent = appState.currentModel; | |
| }); | |
| } | |
| // Render results to the results table | |
| function renderResults() { | |
| const tbody = document.querySelector('tbody'); | |
| if (appState.results.length === 0) { | |
| tbody.innerHTML = ` | |
| <tr> | |
| <td colspan="4" class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 text-center">No results yet</td> | |
| </tr> | |
| `; | |
| return; | |
| } | |
| tbody.innerHTML = appState.results.map(result => ` | |
| <tr> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 capitalize">${result.class}</td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${result.confidence}</td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">[${result.bbox.x}, ${result.bbox.y}, ${result.bbox.width}, ${result.bbox.height}]</td> | |
| <td class="px-6 py-4 whitespace-nowrap"> | |
| <span class="inline-block w-4 h-4 rounded-full" style="background-color: ${result.color}"></span> | |
| </td> | |
| </tr> | |
| `).join(''); | |
| } | |
| // File upload handling | |
| document.getElementById('media-upload').addEventListener('change', (e) => { | |
| const file = e.target.files[0]; | |
| if (file) { | |
| const reader = new FileReader(); | |
| reader.onload = (event) => { | |
| const outputContainer = document.getElementById('output-container'); | |
| if (file.type.startsWith('image/')) { | |
| outputContainer.innerHTML = `<img src="${event.target.result}" class="max-w-full max-h-full" alt="Uploaded image">`; | |
| } else if (file.type.startsWith('video/')) { | |
| outputContainer.innerHTML = ` | |
| <video controls class="max-w-full max-h-full"> | |
| <source src="${event.target.result}" type="${file.type}"> | |
| Your browser does not support the video tag. | |
| </video> | |
| `; | |
| } | |
| }; | |
| reader.readAsDataURL(file); | |
| } | |
| }); | |
| // Make file upload area clickable | |
| const fileUploadArea = document.querySelector('#file-upload-container .border-dashed'); | |
| fileUploadArea.addEventListener('click', () => { | |
| document.getElementById('media-upload').click(); | |
| }); | |
| // Model upload handling | |
| const modelUpload = document.getElementById('model-upload'); | |
| if (modelUpload) { | |
| modelUpload.addEventListener('change', (e) => { | |
| const file = e.target.files[0]; | |
| if (file) { | |
| console.log('Model file selected:', file.name); | |
| // Here you would typically validate and process the model file | |
| alert(`Model file selected: ${file.name}`); | |
| } | |
| }); | |
| // Make model upload area clickable | |
| const modelUploadArea = document.querySelector('#custom-model-upload .border-dashed'); | |
| if (modelUploadArea) { | |
| modelUploadArea.addEventListener('click', () => { | |
| modelUpload.click(); | |
| }); | |
| } | |
| // Handle model URL input | |
| const modelUrlInput = document.querySelector('#custom-model-upload input[type="text"]'); | |
| if (modelUrlInput) { | |
| modelUrlInput.addEventListener('change', (e) => { | |
| const url = e.target.value.trim(); | |
| if (url) { | |
| console.log('Model URL entered:', url); | |
| // Here you would typically validate and load the model from URL | |
| alert(`Model URL entered: ${url}`); | |
| } | |
| }); | |
| } | |
| } | |
| // Drag and drop for file upload | |
| const uploadArea = document.getElementById('file-upload-container'); | |
| uploadArea.addEventListener('dragover', (e) => { | |
| e.preventDefault(); | |
| uploadArea.classList.add('border-primary-500', 'bg-amber-50'); | |
| }); | |
| uploadArea.addEventListener('dragleave', () => { | |
| uploadArea.classList.remove('border-primary-500', 'bg-amber-50'); | |
| }); | |
| uploadArea.addEventListener('drop', (e) => { | |
| e.preventDefault(); | |
| uploadArea.classList.remove('border-primary-500', 'bg-amber-50'); | |
| const file = e.dataTransfer.files[0]; | |
| if (file) { | |
| document.getElementById('media-upload').files = e.dataTransfer.files; | |
| const event = new Event('change'); | |
| document.getElementById('media-upload').dispatchEvent(event); | |
| } | |
| }); | |
| // Drag and drop for model upload | |
| const modelUploadArea = document.querySelector('#custom-model-upload'); | |
| if (modelUploadArea) { | |
| modelUploadArea.addEventListener('dragover', (e) => { | |
| e.preventDefault(); | |
| const dashedBorder = modelUploadArea.querySelector('.border-dashed'); | |
| dashedBorder.classList.add('border-primary-500', 'bg-amber-50'); | |
| }); | |
| modelUploadArea.addEventListener('dragleave', (e) => { | |
| const dashedBorder = modelUploadArea.querySelector('.border-dashed'); | |
| dashedBorder.classList.remove('border-primary-500', 'bg-amber-50'); | |
| }); | |
| modelUploadArea.addEventListener('drop', (e) => { | |
| e.preventDefault(); | |
| const dashedBorder = modelUploadArea.querySelector('.border-dashed'); | |
| dashedBorder.classList.remove('border-primary-500', 'bg-amber-50'); | |
| const file = e.dataTransfer.files[0]; | |
| if (file) { | |
| document.getElementById('model-upload').files = e.dataTransfer.files; | |
| const event = new Event('change'); | |
| document.getElementById('model-upload').dispatchEvent(event); | |
| } | |
| }); | |
| } | |
| } | |
| // Initialize the app when the DOM is loaded | |
| document.addEventListener('DOMContentLoaded', initApp); |