|
| 1 | +<!DOCTYPE html> |
| 2 | +<html lang="en"> |
| 3 | +<head> |
| 4 | + <meta charset="UTF-8"> |
| 5 | + <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 6 | + <title>LOGOS :: Autonomics Dashboard</title> |
| 7 | + <!-- Tailwind CSS for a modern, clean UI --> |
| 8 | + <script src="https://cdn.tailwindcss.com"></script> |
| 9 | + <!-- Google Fonts --> |
| 10 | + <link rel="preconnect" href="https://fonts.googleapis.com"> |
| 11 | + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> |
| 12 | + <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Roboto+Mono:wght@400;500&display=swap" rel="stylesheet"> |
| 13 | + <!-- Font Awesome for icons --> |
| 14 | + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css"> |
| 15 | + |
| 16 | + <!-- |
| 17 | + - LOGOS :: SYSTEMIC CONSTRUCTION LOG |
| 18 | + - ARTIFACT: Autonomics Dashboard v1.0 |
| 19 | + - FRAMEWORK: Harmonic Signal Codex, ⚙️ Codex |
| 20 | + - TIMESTAMP: 2025-06-26 16:40:00 PDT |
| 21 | + - STATUS: SIMULATION ONLINE |
| 22 | + --> |
| 23 | + <style> |
| 24 | + body { |
| 25 | + font-family: 'Inter', sans-serif; |
| 26 | + background-color: #0d1117; |
| 27 | + color: #c9d1d9; |
| 28 | + } |
| 29 | + .mono { |
| 30 | + font-family: 'Roboto Mono', monospace; |
| 31 | + } |
| 32 | + .glass-pane { |
| 33 | + background: rgba(22, 27, 34, 0.7); |
| 34 | + backdrop-filter: blur(15px) saturate(180%); |
| 35 | + -webkit-backdrop-filter: blur(15px) saturate(180%); |
| 36 | + border: 1px solid rgba(255, 255, 255, 0.1); |
| 37 | + } |
| 38 | + .network-canvas { |
| 39 | + position: relative; |
| 40 | + background-image: radial-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px); |
| 41 | + background-size: 20px 20px; |
| 42 | + } |
| 43 | + .node { |
| 44 | + position: absolute; |
| 45 | + width: 20px; |
| 46 | + height: 20px; |
| 47 | + border-radius: 50%; |
| 48 | + background-color: #4f46e5; /* Indigo */ |
| 49 | + box-shadow: 0 0 15px #4f46e5; |
| 50 | + transition: all 0.5s ease-in-out; |
| 51 | + } |
| 52 | + .node.threat { |
| 53 | + background-color: #ef4444; /* Red */ |
| 54 | + box-shadow: 0 0 15px #ef4444; |
| 55 | + animation: pulse-red 1.5s infinite; |
| 56 | + } |
| 57 | + .node.failed { |
| 58 | + background-color: #4b5563; /* Gray */ |
| 59 | + box-shadow: none; |
| 60 | + } |
| 61 | + .node-connection { |
| 62 | + position: absolute; |
| 63 | + background-color: rgba(79, 70, 229, 0.5); |
| 64 | + height: 1px; |
| 65 | + transform-origin: 0 0; |
| 66 | + transition: all 0.5s ease-in-out; |
| 67 | + } |
| 68 | + @keyframes pulse-red { |
| 69 | + 0%, 100% { transform: scale(1); box-shadow: 0 0 15px #ef4444; } |
| 70 | + 50% { transform: scale(1.2); box-shadow: 0 0 25px #ef4444; } |
| 71 | + } |
| 72 | + </style> |
| 73 | +</head> |
| 74 | +<body class="min-h-screen flex flex-col items-center justify-center p-8"> |
| 75 | + |
| 76 | + <div class="w-full max-w-7xl mx-auto"> |
| 77 | + <header class="text-center mb-6"> |
| 78 | + <h1 class="text-4xl font-bold text-white">Autonomics System Dashboard</h1> |
| 79 | + <p class="text-indigo-400 mono text-sm">Simulating a Self-Organizing, Self-Healing Network</p> |
| 80 | + </header> |
| 81 | + |
| 82 | + <div class="grid grid-cols-1 lg:grid-cols-3 gap-8 h-[600px]"> |
| 83 | + |
| 84 | + <!-- Left Panel: Network Visualization --> |
| 85 | + <main class="lg:col-span-2 glass-pane rounded-2xl p-4 relative"> |
| 86 | + <div id="network-canvas" class="network-canvas w-full h-full rounded-lg"> |
| 87 | + <!-- Nodes and connections will be drawn here --> |
| 88 | + </div> |
| 89 | + </main> |
| 90 | + |
| 91 | + <!-- Right Panel: Controls & Log --> |
| 92 | + <aside class="lg:col-span-1 glass-pane rounded-2xl p-6 flex flex-col"> |
| 93 | + <h2 class="text-2xl font-semibold text-white mb-4">System Controls</h2> |
| 94 | + <div class="grid grid-cols-2 gap-4 mb-6"> |
| 95 | + <button id="add-node-btn" class="bg-blue-600 hover:bg-blue-700 p-3 rounded-lg text-white transition"><i class="fas fa-plus-circle mr-2"></i>Add Node</button> |
| 96 | + <button id="optimize-btn" class="bg-green-600 hover:bg-green-700 p-3 rounded-lg text-white transition"><i class="fas fa-cogs mr-2"></i>Optimize</button> |
| 97 | + <button id="fail-node-btn" class="bg-yellow-600 hover:bg-yellow-700 p-3 rounded-lg text-white transition"><i class="fas fa-exclamation-triangle mr-2"></i>Sim Failure</button> |
| 98 | + <button id="add-threat-btn" class="bg-red-600 hover:bg-red-700 p-3 rounded-lg text-white transition"><i class="fas fa-shield-virus mr-2"></i>Add Threat</button> |
| 99 | + </div> |
| 100 | + |
| 101 | + <h2 class="text-2xl font-semibold text-white mb-4 border-t border-gray-700 pt-4">Operational Log</h2> |
| 102 | + <div id="log-output" class="mono text-xs flex-grow bg-gray-900/50 p-4 rounded-lg overflow-y-auto space-y-2"> |
| 103 | + <p class="text-gray-500">[LOGOS] Autonomics system initialized. Awaiting command.</p> |
| 104 | + </div> |
| 105 | + <button id="reset-btn" class="mt-4 w-full bg-gray-600 hover:bg-gray-700 text-white font-bold py-2 px-4 rounded-lg text-sm transition"> |
| 106 | + <i class="fas fa-sync-alt mr-2"></i>Reset Simulation |
| 107 | + </button> |
| 108 | + </aside> |
| 109 | + </div> |
| 110 | + </div> |
| 111 | + |
| 112 | + <script> |
| 113 | + document.addEventListener('DOMContentLoaded', () => { |
| 114 | + const canvas = document.getElementById('network-canvas'); |
| 115 | + const logOutput = document.getElementById('log-output'); |
| 116 | + |
| 117 | + const addNodeBtn = document.getElementById('add-node-btn'); |
| 118 | + const optimizeBtn = document.getElementById('optimize-btn'); |
| 119 | + const failNodeBtn = document.getElementById('fail-node-btn'); |
| 120 | + const addThreatBtn = document.getElementById('add-threat-btn'); |
| 121 | + const resetBtn = document.getElementById('reset-btn'); |
| 122 | + |
| 123 | + let nodes = []; |
| 124 | + let connections = []; |
| 125 | + const initialNodeCount = 5; |
| 126 | + |
| 127 | + function log(message, type = 'info') { |
| 128 | + const p = document.createElement('p'); |
| 129 | + const timestamp = new Date().toLocaleTimeString(); |
| 130 | + let colorClass = 'text-gray-400'; |
| 131 | + if (type === 'success') colorClass = 'text-green-400'; |
| 132 | + if (type === 'warning') colorClass = 'text-yellow-400'; |
| 133 | + if (type === 'danger') colorClass = 'text-red-400'; |
| 134 | + p.innerHTML = `<span class="text-gray-600">${timestamp}</span> <span class="${colorClass}">${message}</span>`; |
| 135 | + logOutput.appendChild(p); |
| 136 | + logOutput.scrollTop = logOutput.scrollHeight; |
| 137 | + } |
| 138 | + |
| 139 | + function createNode(id, x, y) { |
| 140 | + const nodeEl = document.createElement('div'); |
| 141 | + nodeEl.id = `node-${id}`; |
| 142 | + nodeEl.className = 'node'; |
| 143 | + nodeEl.style.left = `${x}px`; |
| 144 | + nodeEl.style.top = `${y}px`; |
| 145 | + canvas.appendChild(nodeEl); |
| 146 | + return { id, x, y, el: nodeEl, connections: [] }; |
| 147 | + } |
| 148 | + |
| 149 | + function drawConnections() { |
| 150 | + // Clear existing connections |
| 151 | + connections.forEach(conn => conn.remove()); |
| 152 | + connections = []; |
| 153 | + |
| 154 | + nodes.forEach((node1, i) => { |
| 155 | + if (node1.el.classList.contains('failed')) return; |
| 156 | + |
| 157 | + let closestNode = null; |
| 158 | + let minDistance = Infinity; |
| 159 | + |
| 160 | + nodes.forEach((node2, j) => { |
| 161 | + if (i === j || node2.el.classList.contains('failed')) return; |
| 162 | + const dx = node2.x - node1.x; |
| 163 | + const dy = node2.y - node1.y; |
| 164 | + const distance = Math.sqrt(dx * dx + dy * dy); |
| 165 | + if (distance < minDistance) { |
| 166 | + minDistance = distance; |
| 167 | + closestNode = node2; |
| 168 | + } |
| 169 | + }); |
| 170 | + |
| 171 | + if (closestNode) { |
| 172 | + const line = document.createElement('div'); |
| 173 | + line.className = 'node-connection'; |
| 174 | + const dx = closestNode.x - node1.x; |
| 175 | + const dy = closestNode.y - node1.y; |
| 176 | + const length = Math.sqrt(dx * dx + dy * dy); |
| 177 | + const angle = Math.atan2(dy, dx) * 180 / Math.PI; |
| 178 | + |
| 179 | + line.style.width = `${length}px`; |
| 180 | + line.style.left = `${node1.x + 10}px`; |
| 181 | + line.style.top = `${node1.y + 10}px`; |
| 182 | + line.style.transform = `rotate(${angle}deg)`; |
| 183 | + canvas.insertBefore(line, canvas.firstChild); |
| 184 | + connections.push(line); |
| 185 | + } |
| 186 | + }); |
| 187 | + } |
| 188 | + |
| 189 | + function initializeNetwork() { |
| 190 | + canvas.innerHTML = ''; |
| 191 | + nodes = []; |
| 192 | + connections = []; |
| 193 | + const { width, height } = canvas.getBoundingClientRect(); |
| 194 | + for (let i = 0; i < initialNodeCount; i++) { |
| 195 | + const x = Math.random() * (width - 40) + 20; |
| 196 | + const y = Math.random() * (height - 40) + 20; |
| 197 | + nodes.push(createNode(i, x, y)); |
| 198 | + } |
| 199 | + drawConnections(); |
| 200 | + log('Network initialized with 5 nodes.'); |
| 201 | + } |
| 202 | + |
| 203 | + // --- Control Button Logic --- |
| 204 | + |
| 205 | + // Self-Configuration |
| 206 | + addNodeBtn.addEventListener('click', () => { |
| 207 | + const { width, height } = canvas.getBoundingClientRect(); |
| 208 | + const x = Math.random() * (width - 40) + 20; |
| 209 | + const y = Math.random() * (height - 40) + 20; |
| 210 | + nodes.push(createNode(nodes.length, x, y)); |
| 211 | + drawConnections(); |
| 212 | + log('SELF-CONFIGURATION: New node added and integrated via harmonic handshake.', 'success'); |
| 213 | + }); |
| 214 | + |
| 215 | + // Self-Optimization |
| 216 | + optimizeBtn.addEventListener('click', () => { |
| 217 | + const { width, height } = canvas.getBoundingClientRect(); |
| 218 | + const centerX = width / 2; |
| 219 | + const centerY = height / 2; |
| 220 | + const radius = Math.min(width, height) / 2 - 40; |
| 221 | + nodes.forEach((node, i) => { |
| 222 | + const angle = (i / nodes.length) * 2 * Math.PI; |
| 223 | + node.x = centerX + radius * Math.cos(angle) - 10; |
| 224 | + node.y = centerY + radius * Math.sin(angle) - 10; |
| 225 | + node.el.style.left = `${node.x}px`; |
| 226 | + node.el.style.top = `${node.y}px`; |
| 227 | + }); |
| 228 | + drawConnections(); |
| 229 | + log('SELF-OPTIMIZATION: Network reconfigured to minimize Total Harmonic Distortion (THD).', 'success'); |
| 230 | + }); |
| 231 | + |
| 232 | + // Self-Healing |
| 233 | + failNodeBtn.addEventListener('click', () => { |
| 234 | + if (nodes.length > 1) { |
| 235 | + const activeNodes = nodes.filter(n => !n.el.classList.contains('failed')); |
| 236 | + if(activeNodes.length === 0) { |
| 237 | + log('No active nodes to fail.', 'warning'); |
| 238 | + return; |
| 239 | + } |
| 240 | + const nodeToFail = activeNodes[Math.floor(Math.random() * activeNodes.length)]; |
| 241 | + nodeToFail.el.classList.add('failed'); |
| 242 | + drawConnections(); |
| 243 | + log(`SELF-HEALING: Node ${nodeToFail.id} failure detected. Rerouting signal pathways.`, 'warning'); |
| 244 | + } |
| 245 | + }); |
| 246 | + |
| 247 | + // Self-Protection |
| 248 | + addThreatBtn.addEventListener('click', () => { |
| 249 | + const activeNodes = nodes.filter(n => !n.el.classList.contains('failed') && !n.el.classList.contains('threat')); |
| 250 | + if (activeNodes.length === 0) { |
| 251 | + log('No available nodes to target.', 'warning'); |
| 252 | + return; |
| 253 | + } |
| 254 | + const nodeToThreaten = activeNodes[Math.floor(Math.random() * activeNodes.length)]; |
| 255 | + nodeToThreaten.el.classList.add('threat'); |
| 256 | + log(`SELF-PROTECTION: Anomalous frequency detected at Node ${nodeToThreaten.id}. Applying harmonic quarantine.`, 'danger'); |
| 257 | + |
| 258 | + setTimeout(() => { |
| 259 | + if (nodeToThreaten.el.classList.contains('threat')) { |
| 260 | + nodeToThreaten.el.classList.remove('threat'); |
| 261 | + log(`Threat at Node ${nodeToThreaten.id} neutralized.`, 'success'); |
| 262 | + } |
| 263 | + }, 3000); |
| 264 | + }); |
| 265 | + |
| 266 | + resetBtn.addEventListener('click', () => { |
| 267 | + log('Resetting simulation...'); |
| 268 | + initializeNetwork(); |
| 269 | + }); |
| 270 | + |
| 271 | + // Initial setup |
| 272 | + initializeNetwork(); |
| 273 | + }); |
| 274 | + </script> |
| 275 | +</body> |
| 276 | +</html> |
0 commit comments