anycoder-75441bba / index.html
caustino's picture
Upload folder using huggingface_hub
d1aae9a verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RIGOR-PRS-Secure++ | Electrochemical Genotyping Interface</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&family=Fira+Code:wght@400;600&display=swap" rel="stylesheet">
<style>
/* Modern CSS Reset & Custom Properties */
:root {
--primary-color: #0a192f;
--secondary-color: #64ffda;
--accent-color: #00a8cc;
--warning-color: #ff6b6b;
--success-color: #4ecdc4;
--text-primary: #e6f1ff;
--text-secondary: #8892b0;
--bg-primary: #0a192f;
--bg-secondary: #112240;
--bg-tertiary: #172a45;
--border-color: #233554;
--gradient-primary: linear-gradient(135deg, #0a192f 0%, #112240 100%);
--gradient-accent: linear-gradient(135deg, #64ffda 0%, #00a8cc 100%);
--shadow-primary: 0 10px 30px -15px rgba(100, 255, 218, 0.2);
--shadow-heavy: 0 20px 50px -20px rgba(0, 0, 0, 0.5);
--glass-bg: rgba(17, 34, 64, 0.7);
--glass-border: rgba(100, 255, 218, 0.1);
--terminal-bg: #0d1117;
--terminal-text: #58a6ff;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
overflow-x: hidden;
}
/* Typography */
h1, h2, h3, h4 {
font-weight: 700;
line-height: 1.2;
}
h1 {
font-size: clamp(2rem, 5vw, 3.5rem);
background: var(--gradient-accent);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
h2 {
font-size: clamp(1.5rem, 3vw, 2.5rem);
color: var(--secondary-color);
}
h3 {
font-size: clamp(1.2rem, 2vw, 1.8rem);
color: var(--text-primary);
}
h4 {
font-size: 1.1rem;
color: var(--text-secondary);
}
p, li {
color: var(--text-secondary);
}
/* Header & Navigation */
header {
position: fixed;
top: 0;
width: 100%;
background: var(--glass-bg);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border-bottom: 1px solid var(--glass-border);
z-index: 1000;
padding: 1rem 0;
transition: all 0.3s ease;
}
.header-container {
max-width: 1400px;
margin: 0 auto;
padding: 0 2rem;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 1rem;
}
.logo-section {
display: flex;
align-items: center;
gap: 1rem;
}
.logo {
width: 40px;
height: 40px;
background: var(--gradient-accent);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
color: var(--primary-color);
}
.brand-text {
display: flex;
flex-direction: column;
}
.brand-name {
font-size: 1.2rem;
font-weight: 700;
color: var(--secondary-color);
}
.brand-tagline {
font-size: 0.8rem;
color: var(--text-secondary);
}
.anycoder-link {
background: var(--gradient-accent);
padding: 0.5rem 1rem;
border-radius: 20px;
text-decoration: none;
color: var(--primary-color);
font-weight: 600;
font-size: 0.9rem;
transition: transform 0.3s ease, box-shadow 0.3s ease;
box-shadow: var(--shadow-primary);
}
.anycoder-link:hover {
transform: translateY(-2px);
box-shadow: 0 15px 35px -15px rgba(100, 255, 218, 0.3);
}
/* Main Container */
.container {
max-width: 1400px;
margin: 0 auto;
padding: 6rem 2rem 2rem;
}
/* Hero Section */
.hero {
text-align: center;
padding: 4rem 0;
position: relative;
}
/* Section Cards */
.section {
background: var(--glass-bg);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid var(--glass-border);
border-radius: 16px;
padding: 2rem;
margin: 2rem 0;
box-shadow: var(--shadow-heavy);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.section:hover {
transform: translateY(-5px);
box-shadow: 0 25px 60px -20px rgba(100, 255, 218, 0.15);
}
.section-header {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 1.5rem;
padding-bottom: 1rem;
border-bottom: 1px solid var(--border-color);
}
.section-icon {
width: 50px;
height: 50px;
background: var(--gradient-accent);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
color: var(--primary-color);
}
/* Buttons */
.btn {
background: var(--gradient-accent);
color: var(--primary-color);
border: none;
padding: 0.75rem 1.5rem;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 0.5rem;
text-decoration: none;
font-size: 1rem;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px -10px rgba(100, 255, 218, 0.4);
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
transform: none;
}
.btn-secondary {
background: var(--bg-tertiary);
color: var(--secondary-color);
border: 1px solid var(--border-color);
}
/* Hardware Interface */
.hardware-interface {
display: grid;
grid-template-columns: 300px 1fr;
gap: 2rem;
}
@media (max-width: 900px) {
.hardware-interface {
grid-template-columns: 1fr;
}
}
.device-panel {
background: var(--bg-tertiary);
border-radius: 12px;
padding: 1.5rem;
border: 1px solid var(--border-color);
}
.status-row {
display: flex;
justify-content: space-between;
margin-bottom: 0.8rem;
font-size: 0.9rem;
}
.status-value {
color: var(--secondary-color);
font-family: 'Fira Code', monospace;
}
/* Electrode Grid */
.electrode-grid-container {
background: #000;
border-radius: 8px;
padding: 1rem;
border: 1px solid var(--border-color);
position: relative;
}
.electrode-grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 4px;
aspect-ratio: 4/3;
}
.electrode {
background: #1a1a1a;
border-radius: 2px;
transition: all 0.2s ease;
position: relative;
}
.electrode:hover {
border: 1px solid #fff;
z-index: 10;
}
.electrode.active-scan {
background: #f1c40f;
box-shadow: 0 0 10px #f1c40f;
}
.electrode.ref-detected {
background: var(--success-color);
}
.electrode.alt-detected {
background: var(--warning-color);
}
.electrode.qc-pass {
background: var(--accent-color);
}
/* Terminal/Console */
.terminal-window {
background: var(--terminal-bg);
border-radius: 8px;
border: 1px solid #30363d;
font-family: 'Fira Code', monospace;
margin-top: 2rem;
overflow: hidden;
display: flex;
flex-direction: column;
}
.terminal-header {
background: #161b22;
padding: 0.5rem 1rem;
border-bottom: 1px solid #30363d;
display: flex;
justify-content: space-between;
align-items: center;
}
.terminal-title {
font-size: 0.85rem;
color: #8b949e;
}
.terminal-body {
height: 200px;
overflow-y: auto;
padding: 1rem;
font-size: 0.85rem;
color: var(--text-secondary);
}
.log-entry {
margin-bottom: 0.25rem;
word-break: break-all;
}
.log-tx { color: var(--secondary-color); }
.log-rx { color: var(--accent-color); }
.log-sys { color: var(--warning-color); font-style: italic; }
/* Voltammetry Chart */
.chart-container {
width: 100%;
height: 200px;
background: var(--bg-tertiary);
border-radius: 8px;
margin-top: 1rem;
position: relative;
border: 1px solid var(--border-color);
}
canvas {
width: 100%;
height: 100%;
}
/* Manufacturing Visualization (New) */
.manufacturing-line {
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
padding: 2rem 0;
overflow-x: auto;
}
.mfg-step {
display: flex;
flex-direction: column;
align-items: center;
z-index: 2;
min-width: 100px;
}
.mfg-icon {
width: 60px;
height: 60px;
background: var(--bg-secondary);
border: 2px solid var(--border-color);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
color: var(--text-secondary);
margin-bottom: 0.5rem;
transition: all 0.5s ease;
}
.mfg-step.active .mfg-icon {
border-color: var(--secondary-color);
background: var(--gradient-accent);
color: var(--primary-color);
box-shadow: 0 0 15px var(--secondary-color);
}
.mfg-label {
font-size: 0.8rem;
text-align: center;
}
.mfg-track {
position: absolute;
top: 50%;
left: 0;
width: 100%;
height: 4px;
background: var(--bg-tertiary);
transform: translateY(-50%);
z-index: 1;
}
.mfg-progress {
height: 100%;
background: var(--gradient-accent);
width: 0%;
transition: width 0.5s ease;
}
/* Blockchain Section (New) */
.blockchain-viz {
display: flex;
flex-direction: column;
gap: 1rem;
}
.chain-step {
display: flex;
align-items: center;
gap: 1rem;
background: var(--bg-secondary);
padding: 1rem;
border-radius: 8px;
border-left: 4px solid var(--border-color);
opacity: 0.5;
transition: all 0.3s ease;
}
.chain-step.active {
opacity: 1;
border-left-color: var(--secondary-color);
background: rgba(100, 255, 218, 0.05);
}
.chain-step i {
font-size: 1.2rem;
width: 30px;
text-align: center;
}
.hash-display {
font-family: 'Fira Code', monospace;
font-size: 0.8rem;
color: var(--accent-color);
word-break: break-all;
}
/* Upload Zone */
.upload-zone {
border: 2px dashed var(--border-color);
border-radius: 12px;
padding: 3rem;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
}
.upload-zone:hover {
border-color: var(--secondary-color);
background: rgba(100, 255, 218, 0.02);
}
.file-list {
margin-top: 1rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.file-item {
background: var(--bg-secondary);
padding: 0.75rem;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: space-between;
}
/* Results & Tables */
.results-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
margin: 2rem 0;
}
.result-card {
background: var(--bg-secondary);
border-radius: 12px;
padding: 1.5rem;
border-left: 4px solid var(--accent-color);
transition: transform 0.3s ease;
}
.result-value {
font-size: 2rem;
font-weight: 700;
color: var(--secondary-color);
margin: 0.5rem 0;
}
.data-table {
width: 100%;
border-collapse: collapse;
margin: 1rem 0;
border-radius: 8px;
overflow: hidden;
}
.data-table th {
background: var(--bg-tertiary);
padding: 1rem;
text-align: left;
font-weight: 600;
color: var(--secondary-color);
border-bottom: 1px solid var(--border-color);
}
.data-table td {
padding: 0.75rem 1rem;
border-bottom: 1px solid var(--border-color);
}
.data-table tr:hover {
background: rgba(100, 255, 218, 0.05);
}
/* Accessibility & Utilities */
.accessibility-controls {
position: fixed;
bottom: 2rem;
right: 2rem;
background: var(--glass-bg);
backdrop-filter: blur(10px);
border: 1px solid var(--glass-border);
border-radius: 12px;
padding: 1rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
z-index: 999;
}
.accessibility-btn {
width: 40px;
height: 40px;
border: none;
background: var(--bg-secondary);
color: var(--text-primary);
border-radius: 8px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
.accessibility-btn:hover, .accessibility-btn.active {
background: var(--secondary-color);
color: var(--primary-color);
}
/* Animations */
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.5; }
100% { opacity: 1; }
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid var(--border-color);
border-top: 4px solid var(--secondary-color);
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 2rem auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.fade-in {
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* Scrollbar */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: var(--bg-primary);
}
::-webkit-scrollbar-thumb {
background: var(--secondary-color);
border-radius: 4px;
}
</style>
</head>
<body>
<!-- Header -->
<header role="banner">
<div class="header-container">
<div class="logo-section">
<div class="logo" aria-hidden="true">RIGOR</div>
<div class="brand-text">
<div class="brand-name">RIGOR-PRS-Secure++</div>
<div class="brand-tagline">Electrochemical Genotyping & PRS Platform</div>
</div>
</div>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link"
aria-label="Built with anycoder - Visit Hugging Face Space">
<i class="fas fa-rocket" aria-hidden="true"></i>
Built with anycoder
</a>
</div>
</header>
<!-- Main Container -->
<main class="container" role="main">
<!-- Hero -->
<section class="hero" aria-labelledby="main-title">
<h1 id="main-title">Hardware-Integrated Genetic Analysis</h1>
<p class="hero-subtitle">Direct USB-C interface to 96-electrode electrochemical cartridges with real-time
voltammetry and post-quantum evidence hashing.</p>
</section>
<!-- SECTION 1: Hardware Interface -->
<section class="section fade-in" aria-labelledby="hardware-title">
<div class="section-header">
<div class="section-icon" aria-hidden="true">
<i class="fas fa-microchip"></i>
</div>
<div>
<h2 id="hardware-title">1. Electrochemical Reader Interface</h2>
<p>Phase 2: USB-C Device Detection & Multiplexer Control</p>
</div>
</div>
<div class="hardware-interface">
<!-- Left: Device Controls -->
<div class="device-panel">
<h3>Device Status</h3>
<div style="height: 1rem;"></div>
<div class="status-row">
<span>Connection:</span>
<span class="status-value" id="hw-conn-status" style="color: var(--warning-color)">Disconnected</span>
</div>
<div class="status-row">
<span>Port:</span>
<span class="status-value" id="hw-port">--</span>
</div>
<div class="status-row">
<span>MCU:</span>
<span class="status-value">RP2040</span>
</div>
<div class="status-row">
<span>Firmware:</span>
<span class="status-value">v1.2.3</span>
</div>
<hr style="border: 0; border-top: 1px solid var(--border-color); margin: 1.5rem 0;">
<h3>Real-time Telemetry</h3>
<div style="height: 1rem;"></div>
<div class="status-row">
<span>Supply Voltage:</span>
<span class="status-value" id="hw-voltage">0.00 V</span>
</div>
<div class="status-row">
<span>Current:</span>
<span class="status-value" id="hw-current">0.00 mA</span>
</div>
<div class="status-row">
<span>Temp (NTC):</span>
<span class="status-value" id="hw-temp">-- °C</span>
</div>
<div style="margin-top: 2rem;">
<button class="btn" id="btn-connect" onclick="toggleConnection()" style="width: 100%; justify-content: center;">
<i class="fas fa-plug"></i> Connect Reader
</button>
<button class="btn btn-secondary" id="btn-start-hw-test" onclick="startHardwareTest()" disabled style="width: 100%; justify-content: center; margin-top: 1rem;">
<i class="fas fa-play"></i> Start Cartridge Scan
</button>
</div>
</div>
<!-- Right: Grid & Charts -->
<div>
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem;">
<h4>96-Electrode Array (ADG731 Mux)</h4>
<span style="font-size: 0.8rem; color: var(--text-secondary);">Spatial Multiplexing Map</span>
</div>
<div class="electrode-grid-container">
<div class="electrode-grid" id="electrode-grid">
<!-- Generated by JS -->
</div>
</div>
<div class="chart-container">
<canvas id="voltammetryChart"></canvas>
<div
style="position: absolute; top: 10px; left: 10px; font-size: 0.8rem; color: var(--text-secondary); background: rgba(10,25,47,0.8); padding: 2px 5px; border-radius: 4px;">
SWV Signal (Current vs Potential)
</div>
</div>
</div>
</div>
<!-- API Terminal -->
<div class="terminal-window">
<div class="terminal-header">
<span class="terminal-title"><i class="fas fa-terminal"></i> API CONSOLE (CDC-ACM)</span>
<i class="fas fa-wifi" style="color: var(--success-color); opacity: 0;"></i>
</div>
<div class="terminal-body" id="terminal-output">
<div class="log-entry log-sys">System ready. Waiting for USB-C device enumeration...</div>
</div>
</div>
</section>
<!-- SECTION 2: Manufacturing Visualization -->
<section class="section fade-in" aria-labelledby="mfg-title">
<div class="section-header">
<div class="section-icon" aria-hidden="true">
<i class="fas fa-industry"></i>
</div>
<div>
<h2 id="mfg-title">2. Roll-to-Roll Manufacturing (FIG. 9)</h2>
<p>Visualizing the cartridge production line: 15 m/min web speed</p>
</div>
</div>
<div class="manufacturing-line">
<div class="mfg-track">
<div class="mfg-progress" id="mfg-progress-bar"></div>
</div>
<div class="mfg-step" id="step-0">
<div class="mfg-icon"><i class="fas fa-file"></i></div>
<div class="mfg-label">PET Stock</div>
</div>
<div class="mfg-step" id="step-1">
<div class="mfg-icon"><i class="fas fa-print"></i></div>
<div class="mfg-label">Gravure Carbon</div>
</div>
<div class="mfg-step" id="step-2">
<div class="mfg-icon"><i class="fas fa-temperature-high"></i></div>
<div class="mfg-label">IR Dry</div>
</div>
<div class="mfg-step" id="step-3">
<div class="mfg-icon"><i class="fas fa-mask"></i></div>
<div class="mfg-label">Screen Ag/AgCl</div>
</div>
<div class="mfg-step" id="step-4">
<div class="mfg-icon"><i class="fas fa-sun"></i></div>
<div class="mfg-label">UV Cure</div>
</div>
<div class="mfg-step" id="step-5">
<div class="mfg-icon"><i class="fas fa-bolt"></i></div>
<div class="mfg-label">Laser Ablate</div>
</div>
<div class="mfg-step" id="step-6">
<div class="mfg-icon"><i class="fas fa-layer-group"></i></div>
<div class="mfg-label">Laminate</div>
</div>
<div class="mfg-step" id="step-7">
<div class="mfg-icon"><i class="fas fa-cut"></i></div>
<div class="mfg-label">Die-Cut</div>
</div>
</div>
<div style="margin-top: 1rem; text-align: center;">
<button class="btn btn-secondary" onclick="runManufacturingSim()">
<i class="fas fa-play-circle"></i> Simulate Production Batch
</button>
<p id="mfg-status" style="margin-top: 0.5rem; font-size: 0.9rem; font-family: 'Fira Code';">Status: Idle</p>
</div>
</section>
<!-- File Upload Section (Fallback/Software Mode) -->
<section class="section fade-in" aria-labelledby="upload-title">
<div class="section-header">
<div class="section-icon" aria-hidden="true">
<i class="fas fa-upload"></i>
</div>
<div>
<h2 id="upload-title">3. Software Mode: Encrypted Ingestion</h2>
<p>Upload VCF or PLINK files if hardware is unavailable</p>
</div>
</div>
<div class="upload-zone" id="upload-zone" role="button" tabindex="0"
aria-label="Drag and drop files here or click to browse">
<div class="upload-icon" aria-hidden="true" style="font-size: 3rem; color: var(--secondary-color); margin-bottom: 1rem;">
<i class="fas fa-dna"></i>
</div>
<h3>Drop Genotype Files Here</h3>
<p>Supports VCF, PLINK binary (.bed/.bim/.fam)</p>
<button class="btn" onclick="document.getElementById('file-input').click()" style="margin-top: 1rem;">
<i class="fas fa-folder-open"></i> Browse Files
</button>
<input type="file" id="file-input" class="file-input" multiple accept=".vcf,.vcf.gz,.bed,.bim,.fam" style="display: none;">
</div>
<div class="file-list" id="file-list" aria-live="polite"></div>
<button class="btn" id="process-btn" onclick="startProcessing()" disabled style="margin-top: 1rem; width: 100%; justify-content: center;">
<i class="fas fa-cogs"></i> Process Software Data
</button>
</section>
<!-- SECTION 3: Blockchain Evidence Anchoring -->
<section class="section fade-in" id="blockchain-section" aria-labelledby="bc-title" style="display: none;">
<div class="section-header">
<div class="section-icon" aria-hidden="true">
<i class="fas fa-link"></i>
</div>
<div>
<h2 id="bc-title">4. Quantum-Resistant Blockchain Anchoring</h2>
<p>Post-Quantum Cryptography (Dilithium) & Hyperledger Fabric</p>
</div>
</div>
<div class="blockchain-viz">
<!-- Step A -->
<div class="chain-step" id="bc-step-a">
<i class="fas fa-file-contract"></i>
<div>
<h4>Step A: Prepare Evidence Packet</h4>
<p style="font-size: 0.9rem;">UID + Timestamp + Hash(Genotype Vector)</p>
<div class="hash-display" id="bc-packet-hash">Calculating...</div>
</div>
</div>
<!-- Step B -->
<div class="chain-step" id="bc-step-b">
<i class="fas fa-key"></i>
<div>
<h4>Step B: Lattice-Based Signing (Dilithium)</h4>
<p style="font-size: 0.9rem;">Signing with Private Key (Post-Quantum Secure)</p>
<div class="spinner" id="bc-spinner" style="width: 20px; height: 20px; margin: 0.5rem 0; border-width: 2px;"></div>
</div>
</div>
<!-- Step C -->
<div class="chain-step" id="bc-step-c">
<i class="fas fa-network-wired"></i>
<div>
<h4>Step C: Submit to Hyperledger Fabric</h4>
<p style="font-size: 0.9rem;">Broadcasting transaction to permissioned nodes</p>
</div>
</div>
<!-- Result -->
<div class="chain-step active" id="bc-result" style="display: none; border-left-color: var(--success-color);">
<i class="fas fa-check-circle" style="color: var(--success-color);"></i>
<div>
<h4 style="color: var(--success-color);">Evidence Anchored Successfully</h4>
<p style="font-size: 0.9rem;">TXID: <span id="bc-txid" class="hash-display"></span></p>
<button class="btn btn-secondary" style="margin-top: 0.5rem; padding: 0.5rem;" onclick="downloadCertificate()">
<i class="fas fa-download"></i> Download JSON-LD Certificate
</button>
</div>
</div>
<button id="btn-start-bc" class="btn" onclick="startBlockchainProcess()" style="margin-top: 1rem; align-self: flex-start;">
<i class="fas fa-shield-alt"></i> Sign & Anchor Evidence
</button>
</div>
</section>
<!-- Results Section -->
<section class="section fade-in" id="results-section" aria-labelledby="results-title" style="display: none;">
<div class="section-header">
<div class="section-icon" aria-hidden="true">
<i class="fas fa-chart-line"></i>
</div>
<div>
<h2 id="results-title">5. Analysis Results</h2>
<p>Polygenic Risk Scores & Evidence Authentication</p>
</div>
</div>
<div class="results-grid">
<div class="result-card">
<div class="result-label">Raw PRS Score</div>
<div class="result-value" id="raw-score">0.00</div>
<small>Sum of weighted risk alleles</small>
</div>
<div class="result-card">
<div class="result-label">Z-Score</div>
<div class="result-value" id="z-score">0.00</div>
<small>Std dev from mean</small>
</div>
<div class="result-card">
<div class="result-label">Percentile</div>
<div class="result-value" id="percentile">0th</div>
<small>Population rank</small>
</div>
<div class="result-card">
<div class="result-label">Blockchain TXID</div>
<div class="result-value" style="font-size: 1rem; word-break: break-all;" id="res-txid">Pending...</div>
<small>Dilithium Signed</small>
</div>
</div>
<h3>Genotype Vector</h3>
<div class="table-container" style="overflow-x: auto;">
<table class="data-table" id="variant-table">
<thead>
<tr>
<th scope="col">SNP ID</th>
<th scope="col">Chr</th>
<th scope="col">Genotype</th>
<th scope="col">Signal (µA)</th>
<th scope="col">Confidence</th>
</tr>
</thead>
<tbody id="variant-table-body">
<!-- Populated by JS -->
</tbody>
</table>
</div>
</section>
</main>
<!-- Accessibility Controls -->
<div class="accessibility-controls" role="group" aria-label="Accessibility controls">
<button class="accessibility-btn" id="high-contrast-btn" onclick="toggleHighContrast()" title="Toggle high contrast mode" aria-label="Toggle high contrast mode">
<i class="fas fa-adjust"></i>
</button>
<button class="accessibility-btn" onclick="increaseFontSize()" title="Increase font size" aria-label="Increase font size">
<i class="fas fa-search-plus"></i>
</button>
<button class="accessibility-btn" onclick="decreaseFontSize()" title="Decrease font size" aria-label="Decrease font size">
<i class="fas fa-search-minus"></i>
</button>
</div>
<script>
// --- CONSTANTS & STATE ---
const GRID_SIZE = 96;
let isConnected = false;
let isScanning = false;
let scanInterval;
let chartAnimationId;
let genotypeData = []; // Store for blockchain
// --- INITIALIZATION ---
document.addEventListener('DOMContentLoaded', () => {
initGrid();
initChart();
initFileUpload();
logToTerminal('SYS', 'Application initialized. Waiting for device...');
});
// --- HARDWARE SIMULATION ---
function toggleConnection() {
const btn = document.getElementById('btn-connect');
const statusLabel = document.getElementById('hw-conn-status');
const portLabel = document.getElementById('hw-port');
const testBtn = document.getElementById('btn-start-hw-test');
if (!isConnected) {
// Simulate Connection
btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Connecting...';
btn.disabled = true;
logToTerminal('TX', 'CONNECT {"timeout": 5000}');
setTimeout(() => {
isConnected = true;
btn.innerHTML = '<i class="fas fa-eject"></i