Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>EDC16 Binary Analyzer & Tuner</title> | |
| <!-- Font Awesome for Icons --> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| :root { | |
| --bg-dark: #050505; | |
| --bg-panel: #0f1115; | |
| --bg-input: #1c1f26; | |
| --text-main: #d1d5db; | |
| --text-muted: #6b7280; | |
| --accent-red: #ef2d3b; /* Audi Red */ | |
| --accent-green: #00e676; | |
| --accent-blue: #2979ff; | |
| --border: #2d3748; | |
| --font-ui: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; | |
| --font-mono: 'Courier New', Courier, monospace; | |
| } | |
| * { | |
| box-sizing: box-box; | |
| margin: 0; | |
| padding: 0; | |
| } | |
| body { | |
| background-color: var(--bg-dark); | |
| color: var(--text-main); | |
| font-family: var(--font-ui); | |
| height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| overflow: hidden; | |
| } | |
| /* --- Header --- */ | |
| header { | |
| height: 60px; | |
| background: var(--bg-panel); | |
| border-bottom: 1px solid var(--border); | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 0 20px; | |
| z-index: 10; | |
| } | |
| .logo-area { | |
| display: flex; | |
| align-items: center; | |
| gap: 15px; | |
| } | |
| .logo-icon { | |
| color: var(--accent-red); | |
| font-size: 1.5rem; | |
| } | |
| .logo-text { | |
| font-weight: 800; | |
| font-size: 1.1rem; | |
| letter-spacing: 1px; | |
| } | |
| .logo-text span { | |
| color: var(--text-muted); | |
| font-weight: 400; | |
| } | |
| .anycoder-link { | |
| position: absolute; | |
| top: 10px; | |
| right: 20px; | |
| font-size: 0.75rem; | |
| color: var(--text-muted); | |
| text-decoration: none; | |
| opacity: 0.6; | |
| transition: opacity 0.3s; | |
| font-family: var(--font-mono); | |
| } | |
| .anycoder-link:hover { | |
| opacity: 1; | |
| color: var(--accent-blue); | |
| } | |
| /* --- Main Grid --- */ | |
| main { | |
| display: grid; | |
| grid-template-columns: 350px 1fr; /* Sidebar for controls, Main for analysis */ | |
| height: 100%; | |
| overflow: hidden; | |
| } | |
| @media (max-width: 900px) { | |
| main { | |
| grid-template-columns: 1fr; | |
| grid-template-rows: auto 1fr; | |
| } | |
| } | |
| /* --- Sidebar (Controls) --- */ | |
| .sidebar { | |
| background: var(--bg-panel); | |
| border-right: 1px solid var(--border); | |
| padding: 20px; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 20px; | |
| overflow-y: auto; | |
| } | |
| .upload-area { | |
| border: 2px dashed var(--border); | |
| padding: 20px; | |
| text-align: center; | |
| border-radius: 6px; | |
| cursor: pointer; | |
| transition: all 0.3s; | |
| background: rgba(0,0,0,0.2); | |
| } | |
| .upload-area:hover { | |
| border-color: var(--accent-blue); | |
| background: rgba(0,0,0,0.4); | |
| } | |
| .upload-icon { | |
| font-size: 2rem; | |
| color: var(--text-muted); | |
| margin-bottom: 10px; | |
| } | |
| .file-name { | |
| font-family: var(--font-mono); | |
| font-size: 0.8rem; | |
| color: var(--accent-blue); | |
| margin-top: 5px; | |
| } | |
| .section-title { | |
| font-size: 0.9rem; | |
| text-transform: uppercase; | |
| letter-spacing: 1px; | |
| color: var(--text-muted); | |
| margin-bottom: 10px; | |
| border-bottom: 1px solid var(--border); | |
| padding-bottom: 5px; | |
| } | |
| /* --- Tuning Cards --- */ | |
| .tuning-card { | |
| background: var(--bg-input); | |
| border: 1px solid var(--border); | |
| border-radius: 4px; | |
| padding: 15px; | |
| margin-bottom: 15px; | |
| transition: border-color 0.3s; | |
| } | |
| .tuning-card.active { | |
| border-color: var(--accent-red); | |
| box-shadow: 0 0 10px rgba(239, 29, 35, 0.1); | |
| } | |
| .card-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 10px; | |
| } | |
| .card-title { | |
| font-weight: 600; | |
| font-size: 0.9rem; | |
| } | |
| .toggle-btn { | |
| background: transparent; | |
| border: 1px solid var(--text-muted); | |
| color: var(--text-muted); | |
| padding: 4px 10px; | |
| font-size: 0.7rem; | |
| cursor: pointer; | |
| border-radius: 2px; | |
| transition: all 0.2s; | |
| } | |
| .toggle-btn.active { | |
| background: var(--accent-red); | |
| border-color: var(--accent-red); | |
| color: white; | |
| box-shadow: 0 0 8px var(--accent-red); | |
| } | |
| .param-grid { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 10px; | |
| } | |
| .param-item label { | |
| display: block; | |
| font-size: 0.7rem; | |
| color: var(--text-muted); | |
| margin-bottom: 4px; | |
| } | |
| .param-input { | |
| width: 100%; | |
| background: #000; | |
| border: 1px solid var(--border); | |
| color: var(--accent-green); | |
| font-family: var(--font-mono); | |
| padding: 5px; | |
| font-size: 0.8rem; | |
| } | |
| /* --- Analysis Area (Main) --- */ | |
| .analysis-view { | |
| display: flex; | |
| flex-direction: column; | |
| padding: 20px; | |
| gap: 20px; | |
| overflow: hidden; | |
| } | |
| /* ECU Info Box */ | |
| .ecu-info-bar { | |
| display: flex; | |
| gap: 20px; | |
| background: var(--bg-panel); | |
| padding: 15px; | |
| border: 1px solid var(--border); | |
| border-radius: 4px; | |
| font-family: var(--font-mono); | |
| font-size: 0.85rem; | |
| } | |
| .info-item { | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .info-label { | |
| color: var(--text-muted); | |
| font-size: 0.7rem; | |
| } | |
| .info-value { | |
| color: var(--accent-blue); | |
| font-weight: bold; | |
| } | |
| /* Hex Dump / Decompilation View */ | |
| .code-window { | |
| flex-grow: 1; | |
| background: #000; | |
| border: 1px solid var(--border); | |
| border-radius: 4px; | |
| padding: 15px; | |
| font-family: var(--font-mono); | |
| font-size: 0.8rem; | |
| overflow-y: auto; | |
| color: #a5d6ff; | |
| box-shadow: inset 0 0 20px rgba(0,0,0,0.5); | |
| position: relative; | |
| } | |
| .code-line { | |
| display: flex; | |
| line-height: 1.6; | |
| } | |
| .line-num { | |
| color: #444; | |
| width: 40px; | |
| text-align: right; | |
| margin-right: 15px; | |
| user-select: none; | |
| } | |
| .hex-data { | |
| color: #5c6370; | |
| margin-right: 15px; | |
| } | |
| .asm-code { | |
| color: #d1d5db; | |
| } | |
| .asm-highlight { | |
| color: var(--accent-red); | |
| background: rgba(239, 29, 35, 0.2); | |
| } | |
| .asm-comment { | |
| color: #6a737d; | |
| } | |
| /* --- Scanning Animation --- */ | |
| .scan-overlay { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0, 234, 116, 0.1) 50%, rgba(0,0,0,0) 100%); | |
| pointer-events: none; | |
| animation: scan 3s linear infinite; | |
| display: none; | |
| z-index: 5; | |
| } | |
| @keyframes scan { | |
| 0% { transform: translateY(-100%); } | |
| 100% { transform: translateY(100%); } | |
| } | |
| .scan-overlay.active { | |
| display: block; | |
| } | |
| /* --- Footer Status --- */ | |
| .status-bar { | |
| height: 30px; | |
| background: var(--bg-panel); | |
| border-top: 1px solid var(--border); | |
| display: flex; | |
| align-items: center; | |
| padding: 0 20px; | |
| font-size: 0.75rem; | |
| color: var(--text-muted); | |
| justify-content: space-between; | |
| } | |
| .status-indicator { | |
| display: inline-block; | |
| width: 8px; | |
| height: 8px; | |
| border-radius: 50%; | |
| background: #333; | |
| margin-right: 8px; | |
| } | |
| .status-indicator.ready { background: var(--accent-green); box-shadow: 0 0 5px var(--accent-green); } | |
| .status-indicator.busy { background: var(--accent-red); box-shadow: 0 0 5px var(--accent-red); } | |
| </style> | |
| </head> | |
| <body> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" class="anycoder-link">Built with anycoder</a> | |
| <header> | |
| <div class="logo-area"> | |
| <i class="fas fa-microchip logo-icon"></i> | |
| <div class="logo-text">EDC<span>16</span> ANALYZER</div> | |
| </div> | |
| <div style="font-family: var(--font-mono); font-size: 0.8rem; color: var(--text-muted);"> | |
| V 2.4.1 (BUILD 892) | |
| </div> | |
| </header> | |
| <main> | |
| <!-- LEFT: CONTROL PANEL --> | |
| <div class="sidebar"> | |
| <!-- File Upload --> | |
| <div class="upload-area" onclick="triggerUpload()"> | |
| <i class="fas fa-cloud-upload-alt upload-icon"></i> | |
| <div style="font-size: 0.9rem; font-weight: 600;">Load .BIN File</div> | |
| <div style="font-size: 0.7rem; color: var(--text-muted);">Drag & Drop or Click</div> | |
| <input type="file" id="fileInput" accept=".bin" style="display: none;"> | |
| <div class="file-name" id="fileNameDisplay">No file loaded</div> | |
| </div> | |
| <!-- Modifications --> | |
| <div class="section-title">Available Modifications</div> | |
| <!-- ESP Pop & Bangs --> | |
| <div class="tuning-card" id="card-esp"> | |
| <div class="card-header"> | |
| <span class="card-title">ESP POP & BANGS</span> | |
| <button class="toggle-btn" onclick="toggleMod('esp')">OFF</button> | |
| </div> | |
| <div class="param-grid"> | |
| <div class="param-item"> | |
| <label>Ignition Cut (%)</label> | |
| <input type="number" class="param-input" value="15"> | |
| </div> | |
| <div class="param-item"> | |
| <label>Duration (ms)</label> | |
| <input type="number" class="param-input" value="300"> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Hardcut with Flames --> | |
| <div class="tuning-card" id="card-flames"> | |
| <div class="card-header"> | |
| <span class="card-title">HARDCUT + FLAMES</span> | |
| <button class="toggle-btn" onclick="toggleMod('flames')">OFF</button> | |
| </div> | |
| <div class="param-grid"> | |
| <div class="param-item"> | |
| <label>RPM Limit</label> | |
| <input type="number" class="param-input" value="4800"> | |
| </div> | |
| <div class="param-item"> | |
| <label>Flame Intensity</label> | |
| <input type="number" class="param-input" value="80"> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Damos/Map Viewer Placeholder --> | |
| <div class="section-title">Map Visualization</div> | |
| <div style="background: #000; height: 150px; border: 1px solid var(--border); position: relative; overflow: hidden; display: flex; align-items: center; justify-content: center;"> | |
| <div id="map-viz" style="width: 100%; height: 100%; opacity: 0.5;"> | |
| <!-- Simple CSS Grid for map viz --> | |
| <div style="display: grid; grid-template-columns: repeat(10, 1fr); height: 100%;"> | |
| <!-- Generated by JS --> | |
| </div> | |
| </div> | |
| <div style="position: absolute; bottom: 5px; right: 5px; font-size: 0.6rem; color: var(--text-muted);">DAMOS VIEW</div> | |
| </div> | |
| </div> | |
| <!-- RIGHT: ANALYSIS --> | |
| <div class="analysis-view"> | |
| <!-- ECU Info Bar --> | |
| <div class="ecu-info-bar"> | |
| <div class="info-item"> | |
| <span class="info-label">ECU TYPE</span> | |
| <span class="info-value" id="ecu-type">WAITING...</span> | |
| </div> | |
| <div class="info-item"> | |
| <span class="info-label">SOFTWARE</span> | |
| <span class="info-value" id="ecu-sw">WAITING...</span> | |
| </div> | |
| <div class="info-item"> | |
| <span class="info-label">CHECKSUM</span> | |
| <span class="info-value" id="ecu-check">WAITING...</span> | |
| </div> | |
| <div class="info-item"> | |
| <span class="info-label">FILE SIZE</span> | |
| <span class="info-value" id="ecu-size">0 KB</span> | |
| </div> | |
| </div> | |
| <!-- Code/Hex Window --> | |
| <div class="code-window" id="codeWindow"> | |
| <div class="scan-overlay" id="scanOverlay"></div> | |
| <div id="codeContent"> | |
| <div class="code-line"> | |
| <span class="line-num">00</span> | |
| <span class="hex-data">-- -- -- --</span> | |
| <span class="asm-code">NOP</span> | |
| <span class="asm-comment">// System Idle. Load .BIN to analyze.</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <div class="status-bar"> | |
| <div> | |
| <span class="status-indicator" id="statusLed"></span> | |
| <span id="statusText">READY FOR INPUT</span> | |
| </div> | |
| <div> | |
| MEMORY ADDRESS: 0x00000000 | |
| </div> | |
| </div> | |
| <script> | |
| // --- State Management --- | |
| const state = { | |
| fileLoaded: false, | |
| mods: { | |
| esp: false, | |
| flames: false | |
| } | |
| }; | |
| // --- File Handling --- | |
| const fileInput = document.getElementById('fileInput'); | |
| const fileNameDisplay = document.getElementById('fileNameDisplay'); | |
| const scanOverlay = document.getElementById('scanOverlay'); | |
| const codeContent = document.getElementById('codeContent'); | |
| const statusLed = document.getElementById('statusLed'); | |
| const statusText = document.getElementById('statusText'); | |
| // ECU Info Elements | |
| const ecuType = document.getElementById('ecu-type'); | |
| const ecuSw = document.getElementById('ecu-sw'); | |
| const ecuCheck = document.getElementById('ecu-check'); | |
| const ecuSize = document.getElementById('ecu-size'); | |
| function triggerUpload() { | |
| fileInput.click(); | |
| } | |
| fileInput.addEventListener('change', (e) => { | |
| const file = e.target.files[0]; | |
| if (file) { | |
| fileNameDisplay.innerText = file.name; | |
| analyzeFile(file); | |
| } | |
| }); | |
| function analyzeFile(file) { | |
| // UI Reset | |
| state.fileLoaded = true; | |
| statusLed.classList.remove('ready'); | |
| statusLed.classList.add('busy'); | |
| statusText.innerText = "ANALYZING BINARY..."; | |
| scanOverlay.classList.add('active'); | |
| codeContent.innerHTML = ''; // Clear previous code | |
| // Simulate Analysis Delay | |
| setTimeout(() => { | |
| scanOverlay.classList.remove('active'); | |
| statusLed.classList.remove('busy'); | |
| statusLed.classList.add('ready'); | |
| statusText.innerText = "ANALYSIS COMPLETE"; | |
| // Populate Fake ECU Data based on file size/name | |
| const sizeKB = (file.size / 1024).toFixed(1); | |
| ecuSize.innerText = `${sizeKB} KB`; | |
| ecuType.innerText = "EDC16CP34 (VAG)"; | |
| ecuSw.innerText = "038906019N (TDI 3.0)"; | |
| ecuCheck.innerText = "CRC: 0x" + Math.floor(Math.random()*16777215).toString(16).toUpperCase(); | |
| generateHexDump(file.name); | |
| renderMapViz(); | |
| }, 2000); | |
| } | |
| // --- Hex Dump Generator (Simulation) --- | |
| function generateHexDump(fileName) { | |
| let html = ''; | |
| const lines = 40; // Show 40 lines | |
| for(let i=0; i<lines; i++) { | |
| // Random Hex | |
| const hex1 = Math.floor(Math.random()*255).toString(16).padStart(2, '0').toUpperCase(); | |
| const hex2 = Math.floor(Math.random()*255).toString(16).padStart(2, '0').toUpperCase(); | |
| const hex3 = Math.floor(Math.random()*255).toString(16).padStart(2, '0').toUpperCase(); | |
| const hex4 = Math.floor(Math.random()*255).toString(16).padStart(2, '0').toUpperCase(); | |
| // Random Assembly Mnemonics | |
| const ops = ['MOV', 'ADD', 'SUB', 'CMP', 'JMP', 'CALL', 'NOP', 'LDI']; | |
| const op = ops[Math.floor(Math.random() * ops.length)]; | |
| const arg = Math.floor(Math.random() * 255); | |
| let comment = ""; | |
| if(i === 10) comment = "// MAP: Torque Limiters"; | |
| if(i === 25) comment = "// MAP: Inject Quantity"; | |
| if(i === 35) comment = "// ESP Intervention Logic"; | |
| html += ` | |
| <div class="code-line"> | |
| <span class="line-num">${(i*4).toString(16).padStart(4, '0')}</span> | |
| <span class="hex-data">${hex1} ${hex2} ${hex3} ${hex4}</span> | |
| <span class="asm-code">${op} R${i%8}, #${arg}</span> | |
| <span class="asm-comment">${comment}</span> | |
| </div> | |
| `; | |
| } | |
| codeContent.innerHTML = html; | |
| } | |
| // --- Modification Logic --- | |
| function toggleMod(modName) { | |
| if(!state.fileLoaded) { | |
| alert("Please load a .BIN file first."); | |
| return; | |
| } | |
| state.mods[modName] = !state.mods[modName]; | |
| const btn = document.querySelector(`#card-${modName} .toggle-btn`); | |
| const card = document.querySelector(`#card-${modName}`); | |
| if(state.mods[modName]) { | |
| btn.innerText = "ON"; | |
| btn.classList.add('active'); | |
| card.classList.add('active'); | |
| injectCodeChanges(modName); | |
| } else { | |
| btn.innerText = "OFF"; | |
| btn.classList.remove('active'); | |
| card.classList.remove('active'); | |
| // Re-generate base code without mods | |
| if(state.fileLoaded) generateHexDump(fileNameDisplay.innerText); | |
| } | |
| } | |
| function injectCodeChanges(modName) { | |
| // Visual feedback in the code window | |
| const lines = codeContent.querySelectorAll('.code-line'); | |
| // Find a random line to "modify" | |
| const targetIndex = Math.floor(Math.random() * lines.length); | |
| const targetLine = lines[targetIndex]; | |
| const asmSpan = targetLine.querySelector('.asm-code'); | |
| const commentSpan = targetLine.querySelector('.asm-comment'); | |
| if(modName === 'esp') { | |
| asmSpan.innerText = "CMP ESP_FLAG, #0xFF"; | |
| asmSpan.classList.add('asm-highlight'); | |
| commentSpan.innerText = "// ESP OVERRIDE ENABLED"; | |
| } else if (modName === 'flames') { | |
| asmSpan.innerText = "SUB RPM_LIMIT, #500"; | |
| asmSpan.classList.add('asm-highlight'); | |
| commentSpan.innerText = "// HARDCUT FLAME TRIGGER"; | |
| } | |
| } | |
| // --- Map Visualization (Damos Style) --- | |
| function renderMapViz() { | |
| const container = document.getElementById('map-viz').querySelector('div'); | |
| container.innerHTML = ''; | |
| // Create a grid of "cells" representing map data | |
| for(let i=0; i<100; i++) { | |
| const cell = document.createElement('div'); | |
| // Random height for 3D effect simulation | |
| const h = 20 + Math.random() * 80; | |
| cell.style.background = `rgba(0, 234, 116, ${h/100})`; | |
| cell.style.border = '1px solid rgba(0,0,0,0.2)'; | |
| cell.style.height = `${h}%`; | |
| cell.style.marginBottom = 'auto'; // Stick to bottom | |
| container.appendChild(cell); | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> |