Spaces:
Running
Running
Review revise and update with refactoring, refinement and optimization expanding this out to at least 4 times its origional size and magnitude.
Browse files- analytics.html +130 -0
- components/chart-viz.js +202 -0
- components/data-table.js +163 -0
- components/progress-ring.js +80 -0
- components/tabs.js +107 -0
- components/terminal.js +180 -0
- ethics.html +234 -0
- settings.html +267 -0
- training.html +177 -0
analytics.html
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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>Analytics - OmniLoop AI</title>
|
| 7 |
+
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🌀</text></svg>">
|
| 8 |
+
<link rel="stylesheet" href="style.css">
|
| 9 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 10 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 11 |
+
<script>
|
| 12 |
+
tailwind.config = {
|
| 13 |
+
darkMode: 'class',
|
| 14 |
+
theme: {
|
| 15 |
+
extend: {
|
| 16 |
+
colors: {
|
| 17 |
+
ai: {
|
| 18 |
+
green: '#10b981',
|
| 19 |
+
greenGlow: '#34d399',
|
| 20 |
+
orange: '#f97316',
|
| 21 |
+
orangeGlow: '#fb923c',
|
| 22 |
+
dark: '#0f172a',
|
| 23 |
+
darker: '#020617',
|
| 24 |
+
surface: '#1e293b'
|
| 25 |
+
}
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
</script>
|
| 31 |
+
</head>
|
| 32 |
+
<body class="bg-ai-darker text-slate-200 font-sans antialiased overflow-hidden selection:bg-ai-green selection:text-black">
|
| 33 |
+
<div class="flex h-screen w-full">
|
| 34 |
+
<nav-sidebar></nav-sidebar>
|
| 35 |
+
<main class="flex-1 flex flex-col h-full relative overflow-hidden">
|
| 36 |
+
<header class="h-16 border-b border-slate-800 flex items-center justify-between px-6 bg-ai-dark/80 backdrop-blur-md z-10">
|
| 37 |
+
<div class="flex items-center gap-3">
|
| 38 |
+
<div class="w-2 h-2 rounded-full bg-ai-orange animate-pulse shadow-[0_0_10px_#f97316]"></div>
|
| 39 |
+
<h2 class="text-xl font-bold tracking-wider text-white">ANALYTICS <span class="text-ai-orange">MODULE</span></h2>
|
| 40 |
+
</div>
|
| 41 |
+
<div class="flex items-center gap-4">
|
| 42 |
+
<div id="system-clock" class="font-mono text-sm text-slate-400">00:00:00</div>
|
| 43 |
+
<button class="p-2 hover:bg-slate-700 rounded transition-colors" onclick="document.dispatchEvent(new CustomEvent('toggle-command-palette'))">
|
| 44 |
+
<span class="text-xs text-slate-500 font-mono">Ctrl+K</span>
|
| 45 |
+
</button>
|
| 46 |
+
</div>
|
| 47 |
+
</header>
|
| 48 |
+
|
| 49 |
+
<div id="content-area" class="flex-1 overflow-y-auto p-6 scroll-smooth">
|
| 50 |
+
<section class="space-y-6">
|
| 51 |
+
<div class="flex justify-between items-end">
|
| 52 |
+
<div>
|
| 53 |
+
<h1 class="text-3xl font-bold text-white mb-1">Performance Analytics</h1>
|
| 54 |
+
<p class="text-slate-400">Real-time neural network metrics and system performance</p>
|
| 55 |
+
</div>
|
| 56 |
+
<div class="flex gap-2">
|
| 57 |
+
<select id="time-range" class="bg-slate-700 border border-slate-600 rounded px-3 py-2 text-sm">
|
| 58 |
+
<option value="1h">Last Hour</option>
|
| 59 |
+
<option value="24h">Last 24 Hours</option>
|
| 60 |
+
<option value="7d">Last 7 Days</option>
|
| 61 |
+
<option value="30d">Last 30 Days</option>
|
| 62 |
+
</select>
|
| 63 |
+
<button class="px-4 py-2 bg-ai-green hover:bg-ai-greenGlow text-black font-bold text-sm rounded transition-all">
|
| 64 |
+
<i data-feather="download" class="w-4 h-4 inline"></i> Export
|
| 65 |
+
</button>
|
| 66 |
+
</div>
|
| 67 |
+
</div>
|
| 68 |
+
|
| 69 |
+
<!-- Key Metrics -->
|
| 70 |
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
| 71 |
+
<metric-card title="Total Requests" value="2.4M" icon="activity" color="text-ai-green" trend="+12.5%" desc="Today"></metric-card>
|
| 72 |
+
<metric-card title="Avg Response" value="42ms" icon="clock" color="text-blue-400" trend="-5ms" desc="Latency"></metric-card>
|
| 73 |
+
<metric-card title="Error Rate" value="0.02%" icon="alert-triangle" color="text-ai-orange" trend="-0.01%" desc="Errors"></metric-card>
|
| 74 |
+
<metric-card title="Uptime" value="99.99%" icon="check-circle" color="text-purple-400" trend="+0.01%" desc="30 days"></metric-card>
|
| 75 |
+
</div>
|
| 76 |
+
|
| 77 |
+
<!-- Charts Section -->
|
| 78 |
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
| 79 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 80 |
+
<h3 class="text-lg font-bold text-white mb-4">Request Volume</h3>
|
| 81 |
+
<chart-viz type="line" id="request-chart"></chart-viz>
|
| 82 |
+
</div>
|
| 83 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 84 |
+
<h3 class="text-lg font-bold text-white mb-4">Response Time Distribution</h3>
|
| 85 |
+
<chart-viz type="bar" id="response-chart"></chart-viz>
|
| 86 |
+
</div>
|
| 87 |
+
</div>
|
| 88 |
+
|
| 89 |
+
<!-- Data Table -->
|
| 90 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 91 |
+
<div class="flex justify-between items-center mb-4">
|
| 92 |
+
<h3 class="text-lg font-bold text-white">Recent Operations</h3>
|
| 93 |
+
<input type="text" placeholder="Search operations..." class="bg-slate-700 border border-slate-600 rounded px-3 py-2 text-sm w-64">
|
| 94 |
+
</div>
|
| 95 |
+
<data-table id="operations-table"></data-table>
|
| 96 |
+
</div>
|
| 97 |
+
|
| 98 |
+
<!-- Performance Metrics -->
|
| 99 |
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
| 100 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6 text-center">
|
| 101 |
+
<progress-ring value="85" color="#10b981"></progress-ring>
|
| 102 |
+
<h4 class="text-white font-bold mt-4">CPU Usage</h4>
|
| 103 |
+
<p class="text-slate-400 text-sm">8 cores active</p>
|
| 104 |
+
</div>
|
| 105 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6 text-center">
|
| 106 |
+
<progress-ring value="62" color="#3b82f6"></progress-ring>
|
| 107 |
+
<h4 class="text-white font-bold mt-4">Memory</h4>
|
| 108 |
+
<p class="text-slate-400 text-sm">62.4 GB / 128 GB</p>
|
| 109 |
+
</div>
|
| 110 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6 text-center">
|
| 111 |
+
<progress-ring value="45" color="#f97316"></progress-ring>
|
| 112 |
+
<h4 class="text-white font-bold mt-4">GPU Utilization</h4>
|
| 113 |
+
<p class="text-slate-400 text-sm">2x A100 detected</p>
|
| 114 |
+
</div>
|
| 115 |
+
</div>
|
| 116 |
+
</section>
|
| 117 |
+
</div>
|
| 118 |
+
</main>
|
| 119 |
+
</div>
|
| 120 |
+
|
| 121 |
+
<script src="components/sidebar.js"></script>
|
| 122 |
+
<script src="components/metric-card.js"></script>
|
| 123 |
+
<script src="components/chart-viz.js"></script>
|
| 124 |
+
<script src="components/data-table.js"></script>
|
| 125 |
+
<script src="components/progress-ring.js"></script>
|
| 126 |
+
<script src="components/command-palette.js"></script>
|
| 127 |
+
<script src="script.js"></script>
|
| 128 |
+
<script>feather.replace();</script>
|
| 129 |
+
</body>
|
| 130 |
+
</html>
|
components/chart-viz.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class ChartViz extends HTMLElement {
|
| 2 |
+
constructor() {
|
| 3 |
+
super();
|
| 4 |
+
this.attachShadow({ mode: 'open' });
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
connectedCallback() {
|
| 8 |
+
this.render();
|
| 9 |
+
this.initChart();
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
render() {
|
| 13 |
+
this.shadowRoot.innerHTML = `
|
| 14 |
+
<style>
|
| 15 |
+
:host {
|
| 16 |
+
display: block;
|
| 17 |
+
width: 100%;
|
| 18 |
+
height: 100%;
|
| 19 |
+
position: relative;
|
| 20 |
+
}
|
| 21 |
+
canvas {
|
| 22 |
+
display: block;
|
| 23 |
+
width: 100%;
|
| 24 |
+
height: 100%;
|
| 25 |
+
}
|
| 26 |
+
</style>
|
| 27 |
+
<canvas id="chartCanvas"></canvas>
|
| 28 |
+
`;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
initChart() {
|
| 32 |
+
const canvas = this.shadowRoot.getElementById('chartCanvas');
|
| 33 |
+
const ctx = canvas.getContext('2d');
|
| 34 |
+
const type = this.getAttribute('type') || 'line';
|
| 35 |
+
|
| 36 |
+
let width, height;
|
| 37 |
+
const resize = () => {
|
| 38 |
+
width = canvas.width = canvas.offsetWidth;
|
| 39 |
+
height = canvas.height = canvas.offsetHeight;
|
| 40 |
+
};
|
| 41 |
+
new ResizeObserver(resize).observe(this);
|
| 42 |
+
|
| 43 |
+
// Data generation
|
| 44 |
+
const generateData = (points) => {
|
| 45 |
+
return Array.from({ length: points }, (_, i) => ({
|
| 46 |
+
x: i,
|
| 47 |
+
y: Math.random() * 0.5 + 0.25 + Math.sin(i * 0.1) * 0.15
|
| 48 |
+
}));
|
| 49 |
+
};
|
| 50 |
+
|
| 51 |
+
let data = generateData(type === 'training' ? 100 : 24);
|
| 52 |
+
let offset = 0;
|
| 53 |
+
|
| 54 |
+
const drawLineChart = () => {
|
| 55 |
+
ctx.clearRect(0, 0, width, height);
|
| 56 |
+
|
| 57 |
+
// Grid
|
| 58 |
+
ctx.strokeStyle = '#1e293b';
|
| 59 |
+
ctx.lineWidth = 1;
|
| 60 |
+
for (let i = 0; i < 5; i++) {
|
| 61 |
+
const y = (height / 4) * i;
|
| 62 |
+
ctx.beginPath();
|
| 63 |
+
ctx.moveTo(0, y);
|
| 64 |
+
ctx.lineTo(width, y);
|
| 65 |
+
ctx.stroke();
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
// Line
|
| 69 |
+
ctx.beginPath();
|
| 70 |
+
ctx.strokeStyle = '#10b981';
|
| 71 |
+
ctx.lineWidth = 2;
|
| 72 |
+
|
| 73 |
+
data.forEach((point, i) => {
|
| 74 |
+
const x = (i / (data.length - 1)) * width;
|
| 75 |
+
const y = height - (point.y * height * 0.8 + height * 0.1);
|
| 76 |
+
if (i === 0) ctx.moveTo(x, y);
|
| 77 |
+
else ctx.lineTo(x, y);
|
| 78 |
+
});
|
| 79 |
+
ctx.stroke();
|
| 80 |
+
|
| 81 |
+
// Gradient fill
|
| 82 |
+
const gradient = ctx.createLinearGradient(0, 0, 0, height);
|
| 83 |
+
gradient.addColorStop(0, 'rgba(16, 185, 129, 0.3)');
|
| 84 |
+
gradient.addColorStop(1, 'rgba(16, 185, 129, 0)');
|
| 85 |
+
ctx.lineTo(width, height);
|
| 86 |
+
ctx.lineTo(0, height);
|
| 87 |
+
ctx.fillStyle = gradient;
|
| 88 |
+
ctx.fill();
|
| 89 |
+
|
| 90 |
+
// Points
|
| 91 |
+
data.forEach((point, i) => {
|
| 92 |
+
if (i % 4 === 0) {
|
| 93 |
+
const x = (i / (data.length - 1)) * width;
|
| 94 |
+
const y = height - (point.y * height * 0.8 + height * 0.1);
|
| 95 |
+
ctx.beginPath();
|
| 96 |
+
ctx.arc(x, y, 4, 0, Math.PI * 2);
|
| 97 |
+
ctx.fillStyle = '#10b981';
|
| 98 |
+
ctx.fill();
|
| 99 |
+
}
|
| 100 |
+
});
|
| 101 |
+
};
|
| 102 |
+
|
| 103 |
+
const drawBarChart = () => {
|
| 104 |
+
ctx.clearRect(0, 0, width, height);
|
| 105 |
+
|
| 106 |
+
const barWidth = width / data.length - 4;
|
| 107 |
+
|
| 108 |
+
data.forEach((point, i) => {
|
| 109 |
+
const x = i * (width / data.length) + 2;
|
| 110 |
+
const barHeight = point.y * height * 0.8;
|
| 111 |
+
const y = height - barHeight;
|
| 112 |
+
|
| 113 |
+
// Color based on value
|
| 114 |
+
const hue = 120 + (1 - point.y) * 60; // Green to yellow
|
| 115 |
+
ctx.fillStyle = `hsl(${hue}, 70%, 50%)`;
|
| 116 |
+
|
| 117 |
+
// Rounded top bars
|
| 118 |
+
ctx.beginPath();
|
| 119 |
+
ctx.roundRect(x, y, barWidth, barHeight, [4, 4, 0, 0]);
|
| 120 |
+
ctx.fill();
|
| 121 |
+
});
|
| 122 |
+
};
|
| 123 |
+
|
| 124 |
+
const drawTrainingChart = () => {
|
| 125 |
+
ctx.clearRect(0, 0, width, height);
|
| 126 |
+
|
| 127 |
+
// Loss line (decreasing)
|
| 128 |
+
ctx.beginPath();
|
| 129 |
+
ctx.strokeStyle = '#f97316';
|
| 130 |
+
ctx.lineWidth = 2;
|
| 131 |
+
data.forEach((point, i) => {
|
| 132 |
+
const x = (i / (data.length - 1)) * width;
|
| 133 |
+
const normalizedLoss = 1 - (i / data.length) * 0.8 + Math.random() * 0.05;
|
| 134 |
+
const y = height - (normalizedLoss * height * 0.7 + height * 0.15);
|
| 135 |
+
if (i === 0) ctx.moveTo(x, y);
|
| 136 |
+
else ctx.lineTo(x, y);
|
| 137 |
+
});
|
| 138 |
+
ctx.stroke();
|
| 139 |
+
|
| 140 |
+
// Accuracy line (increasing)
|
| 141 |
+
ctx.beginPath();
|
| 142 |
+
ctx.strokeStyle = '#3b82f6';
|
| 143 |
+
ctx.lineWidth = 2;
|
| 144 |
+
data.forEach((point, i) => {
|
| 145 |
+
const x = (i / (data.length - 1)) * width;
|
| 146 |
+
const normalizedAcc = 0.5 + (i / data.length) * 0.48 + Math.random() * 0.02;
|
| 147 |
+
const y = height - (normalizedAcc * height * 0.7 + height * 0.15);
|
| 148 |
+
if (i === 0) ctx.moveTo(x, y);
|
| 149 |
+
else ctx.lineTo(x, y);
|
| 150 |
+
});
|
| 151 |
+
ctx.stroke();
|
| 152 |
+
|
| 153 |
+
// Legend
|
| 154 |
+
ctx.fillStyle = '#f97316';
|
| 155 |
+
ctx.fillRect(10, 10, 12, 12);
|
| 156 |
+
ctx.fillStyle = '#94a3b8';
|
| 157 |
+
ctx.font = '11px sans-serif';
|
| 158 |
+
ctx.fillText('Loss', 28, 20);
|
| 159 |
+
|
| 160 |
+
ctx.fillStyle = '#3b82f6';
|
| 161 |
+
ctx.fillRect(80, 10, 12, 12);
|
| 162 |
+
ctx.fillStyle = '#94a3b8';
|
| 163 |
+
ctx.fillText('Accuracy', 98, 20);
|
| 164 |
+
};
|
| 165 |
+
|
| 166 |
+
const animate = () => {
|
| 167 |
+
if (type === 'training') {
|
| 168 |
+
// Update data occasionally
|
| 169 |
+
offset++;
|
| 170 |
+
if (offset % 60 === 0) {
|
| 171 |
+
data = data.map((point, i) => ({
|
| 172 |
+
...point,
|
| 173 |
+
y: Math.random() * 0.5 + 0.25 + Math.sin(i * 0.1 + offset * 0.01) * 0.15
|
| 174 |
+
}));
|
| 175 |
+
}
|
| 176 |
+
} else if (type === 'line') {
|
| 177 |
+
// Shift data for real-time effect
|
| 178 |
+
if (offset % 10 === 0) {
|
| 179 |
+
data.shift();
|
| 180 |
+
data.push({
|
| 181 |
+
x: data.length,
|
| 182 |
+
y: Math.random() * 0.5 + 0.25 + Math.sin(offset * 0.1) * 0.15
|
| 183 |
+
});
|
| 184 |
+
}
|
| 185 |
+
offset++;
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
if (type === 'line' || type === 'training') {
|
| 189 |
+
type === 'training' ? drawTrainingChart() : drawLineChart();
|
| 190 |
+
} else {
|
| 191 |
+
drawBarChart();
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
requestAnimationFrame(animate);
|
| 195 |
+
};
|
| 196 |
+
|
| 197 |
+
resize();
|
| 198 |
+
animate();
|
| 199 |
+
}
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
customElements.define('chart-viz', ChartViz);
|
components/data-table.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class DataTable extends HTMLElement {
|
| 2 |
+
constructor() {
|
| 3 |
+
super();
|
| 4 |
+
this.attachShadow({ mode: 'open' });
|
| 5 |
+
this.data = [];
|
| 6 |
+
this.sortColumn = null;
|
| 7 |
+
this.sortDirection = 'asc';
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
connectedCallback() {
|
| 11 |
+
this.generateData();
|
| 12 |
+
this.render();
|
| 13 |
+
this.attachEvents();
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
generateData() {
|
| 17 |
+
const operations = [
|
| 18 |
+
'Inference Request', 'Model Update', 'Data Preprocessing', 'API Call',
|
| 19 |
+
'Cache Miss', 'Authentication', 'Validation Check', 'Batch Processing'
|
| 20 |
+
];
|
| 21 |
+
const statuses = ['success', 'pending', 'error'];
|
| 22 |
+
|
| 23 |
+
for (let i = 0; i < 20; i++) {
|
| 24 |
+
this.data.push({
|
| 25 |
+
id: `OP-${10000 + i}`,
|
| 26 |
+
operation: operations[Math.floor(Math.random() * operations.length)],
|
| 27 |
+
timestamp: new Date(Date.now() - Math.random() * 3600000).toISOString(),
|
| 28 |
+
duration: Math.floor(Math.random() * 500 + 10),
|
| 29 |
+
status: statuses[Math.floor(Math.random() * statuses.length)]
|
| 30 |
+
});
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
sort(column) {
|
| 35 |
+
if (this.sortColumn === column) {
|
| 36 |
+
this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
|
| 37 |
+
} else {
|
| 38 |
+
this.sortColumn = column;
|
| 39 |
+
this.sortDirection = 'asc';
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
this.data.sort((a, b) => {
|
| 43 |
+
let valA = a[column];
|
| 44 |
+
let valB = b[column];
|
| 45 |
+
|
| 46 |
+
if (typeof valA === 'string') valA = valA.toLowerCase();
|
| 47 |
+
if (typeof valB === 'string') valB = valB.toLowerCase();
|
| 48 |
+
|
| 49 |
+
if (valA < valB) return this.sortDirection === 'asc' ? -1 : 1;
|
| 50 |
+
if (valA > valB) return this.sortDirection === 'asc' ? 1 : -1;
|
| 51 |
+
return 0;
|
| 52 |
+
});
|
| 53 |
+
|
| 54 |
+
this.render();
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
getStatusBadge(status) {
|
| 58 |
+
const styles = {
|
| 59 |
+
success: 'bg-green-900/50 text-green-400',
|
| 60 |
+
pending: 'bg-yellow-900/50 text-yellow-400',
|
| 61 |
+
error: 'bg-red-900/50 text-red-400'
|
| 62 |
+
};
|
| 63 |
+
return `<span class="px-2 py-1 rounded text-xs ${styles[status]}">${status.charAt(0).toUpperCase() + status.slice(1)}</span>`;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
render() {
|
| 67 |
+
this.shadowRoot.innerHTML = `
|
| 68 |
+
<style>
|
| 69 |
+
:host {
|
| 70 |
+
display: block;
|
| 71 |
+
}
|
| 72 |
+
table {
|
| 73 |
+
width: 100%;
|
| 74 |
+
border-collapse: collapse;
|
| 75 |
+
}
|
| 76 |
+
th {
|
| 77 |
+
text-align: left;
|
| 78 |
+
padding: 12px;
|
| 79 |
+
border-bottom: 1px solid #334155;
|
| 80 |
+
color: #94a3b8;
|
| 81 |
+
font-size: 12px;
|
| 82 |
+
text-transform: uppercase;
|
| 83 |
+
cursor: pointer;
|
| 84 |
+
user-select: none;
|
| 85 |
+
}
|
| 86 |
+
th:hover {
|
| 87 |
+
color: #e2e8f0;
|
| 88 |
+
background: rgba(255,255,255,0.02);
|
| 89 |
+
}
|
| 90 |
+
td {
|
| 91 |
+
padding: 12px;
|
| 92 |
+
border-bottom: 1px solid #1e293b;
|
| 93 |
+
font-size: 14px;
|
| 94 |
+
}
|
| 95 |
+
tr:hover td {
|
| 96 |
+
background: rgba(255,255,255,0.02);
|
| 97 |
+
}
|
| 98 |
+
.sort-icon {
|
| 99 |
+
margin-left: 4px;
|
| 100 |
+
opacity: 0.5;
|
| 101 |
+
}
|
| 102 |
+
</style>
|
| 103 |
+
<div style="overflow-x: auto;">
|
| 104 |
+
<table>
|
| 105 |
+
<thead>
|
| 106 |
+
<tr>
|
| 107 |
+
<th onclick="this.getRootNode().host.sort('id')">
|
| 108 |
+
ID ${this.sortColumn === 'id' ? (this.sortDirection === 'asc' ? '↑' : '↓') : ''}
|
| 109 |
+
</th>
|
| 110 |
+
<th onclick="this.getRootNode().host.sort('operation')">
|
| 111 |
+
Operation ${this.sortColumn === 'operation' ? (this.sortDirection === 'asc' ? '↑' : '↓') : ''}
|
| 112 |
+
</th>
|
| 113 |
+
<th onclick="this.getRootNode().host.sort('timestamp')">
|
| 114 |
+
Timestamp ${this.sortColumn === 'timestamp' ? (this.sortDirection === 'asc' ? '↑' : '↓') : ''}
|
| 115 |
+
</th>
|
| 116 |
+
<th onclick="this.getRootNode().host.sort('duration')">
|
| 117 |
+
Duration ${this.sortColumn === 'duration' ? (this.sortDirection === 'asc' ? '↑' : '↓') : ''}
|
| 118 |
+
</th>
|
| 119 |
+
<th onclick="this.getRootNode().host.sort('status')">
|
| 120 |
+
Status ${this.sortColumn === 'status' ? (this.sortDirection === 'asc' ? '↑' : '↓') : ''}
|
| 121 |
+
</th>
|
| 122 |
+
</tr>
|
| 123 |
+
</thead>
|
| 124 |
+
<tbody>
|
| 125 |
+
${this.data.map(row => `
|
| 126 |
+
<tr>
|
| 127 |
+
<td class="font-mono text-slate-400">${row.id}</td>
|
| 128 |
+
<td class="text-white">${row.operation}</td>
|
| 129 |
+
<td class="text-slate-400">${new Date(row.timestamp).toLocaleString()}</td>
|
| 130 |
+
<td class="text-slate-300">${row.duration}ms</td>
|
| 131 |
+
<td>${this.getStatusBadge(row.status)}</td>
|
| 132 |
+
</tr>
|
| 133 |
+
`).join('')}
|
| 134 |
+
</tbody>
|
| 135 |
+
</table>
|
| 136 |
+
</div>
|
| 137 |
+
`;
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
attachEvents() {
|
| 141 |
+
// Add new data periodically
|
| 142 |
+
setInterval(() => {
|
| 143 |
+
const operations = ['Inference Request', 'Model Update', 'Data Preprocessing', 'API Call'];
|
| 144 |
+
const statuses = ['success', 'pending', 'error'];
|
| 145 |
+
|
| 146 |
+
this.data.unshift({
|
| 147 |
+
id: `OP-${10000 + this.data.length}`,
|
| 148 |
+
operation: operations[Math.floor(Math.random() * operations.length)],
|
| 149 |
+
timestamp: new Date().toISOString(),
|
| 150 |
+
duration: Math.floor(Math.random() * 500 + 10),
|
| 151 |
+
status: statuses[Math.floor(Math.random() * statuses.length)]
|
| 152 |
+
});
|
| 153 |
+
|
| 154 |
+
if (this.data.length > 50) {
|
| 155 |
+
this.data.pop();
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
this.render();
|
| 159 |
+
}, 3000);
|
| 160 |
+
}
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
customElements.define('data-table', DataTable);
|
components/progress-ring.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class ProgressRing extends HTMLElement {
|
| 2 |
+
constructor() {
|
| 3 |
+
super();
|
| 4 |
+
this.attachShadow({ mode: 'open' });
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
static get observedAttributes() {
|
| 8 |
+
return ['value', 'color', 'size'];
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
connectedCallback() {
|
| 12 |
+
this.animateValue();
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
attributeChangedCallback(name, oldValue, newValue) {
|
| 16 |
+
if (oldValue !== newValue && this.shadowRoot) {
|
| 17 |
+
this.render();
|
| 18 |
+
this.animateValue();
|
| 19 |
+
}
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
render() {
|
| 23 |
+
const value = this.getAttribute('value') || 0;
|
| 24 |
+
const color = this.getAttribute('color') || '#10b981';
|
| 25 |
+
const size = this.getAttribute('size') || 150;
|
| 26 |
+
|
| 27 |
+
this.shadowRoot.innerHTML = `
|
| 28 |
+
<style>
|
| 29 |
+
:host {
|
| 30 |
+
display: inline-block;
|
| 31 |
+
}
|
| 32 |
+
.progress-ring {
|
| 33 |
+
transform: rotate(-90deg);
|
| 34 |
+
}
|
| 35 |
+
.progress-ring__circle {
|
| 36 |
+
transition: stroke-dashoffset 0.5s ease-in-out;
|
| 37 |
+
transform-origin: 50% 50%;
|
| 38 |
+
}
|
| 39 |
+
</style>
|
| 40 |
+
<svg class="progress-ring" width="${size}" height="${size}">
|
| 41 |
+
<circle
|
| 42 |
+
class="progress-ring__circle-bg"
|
| 43 |
+
stroke="#1e293b"
|
| 44 |
+
stroke-width="12"
|
| 45 |
+
fill="transparent"
|
| 46 |
+
r="${size/2 - 12}"
|
| 47 |
+
cx="${size/2}"
|
| 48 |
+
cy="${size/2}"
|
| 49 |
+
/>
|
| 50 |
+
<circle
|
| 51 |
+
class="progress-ring__circle"
|
| 52 |
+
stroke="${color}"
|
| 53 |
+
stroke-width="12"
|
| 54 |
+
stroke-linecap="round"
|
| 55 |
+
fill="transparent"
|
| 56 |
+
r="${size/2 - 12}"
|
| 57 |
+
cx="${size/2}"
|
| 58 |
+
cy="${size/2}"
|
| 59 |
+
style="stroke-dasharray: ${2 * Math.PI * (size/2 - 12)}; stroke-dashoffset: ${2 * Math.PI * (size/2 - 12)}"
|
| 60 |
+
/>
|
| 61 |
+
</svg>
|
| 62 |
+
`;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
animateValue() {
|
| 66 |
+
const circle = this.shadowRoot.querySelector('.progress-ring__circle');
|
| 67 |
+
const value = parseInt(this.getAttribute('value') || 0);
|
| 68 |
+
const radius = circle.r.baseVal.value;
|
| 69 |
+
const circumference = radius * 2 * Math.PI;
|
| 70 |
+
|
| 71 |
+
circle.style.strokeDasharray = `${circumference} ${circumference}`;
|
| 72 |
+
const offset = circumference - (value / 100) * circumference;
|
| 73 |
+
|
| 74 |
+
setTimeout(() => {
|
| 75 |
+
circle.style.strokeDashoffset = offset;
|
| 76 |
+
}, 100);
|
| 77 |
+
}
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
customElements.define('progress-ring', ProgressRing);
|
components/tabs.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
```javascript
|
| 2 |
+
class TabsContainer extends HTMLElement {
|
| 3 |
+
constructor() {
|
| 4 |
+
super();
|
| 5 |
+
this.attachShadow({ mode: 'open' });
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
connectedCallback() {
|
| 9 |
+
this.render();
|
| 10 |
+
this.attachEvents();
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
render() {
|
| 14 |
+
this.shadowRoot.innerHTML = `
|
| 15 |
+
<style>
|
| 16 |
+
:host {
|
| 17 |
+
display: block;
|
| 18 |
+
}
|
| 19 |
+
.tabs-header {
|
| 20 |
+
display: flex;
|
| 21 |
+
gap: 1px;
|
| 22 |
+
border-bottom: 2px solid #1e293b;
|
| 23 |
+
margin-bottom: 1.5rem;
|
| 24 |
+
}
|
| 25 |
+
.tab-button {
|
| 26 |
+
padding: 0.75rem 1.5rem;
|
| 27 |
+
background: transparent;
|
| 28 |
+
border: none;
|
| 29 |
+
color: #94a3b8;
|
| 30 |
+
cursor: pointer;
|
| 31 |
+
font-size: 14px;
|
| 32 |
+
font-weight: 500;
|
| 33 |
+
transition: all 0.2s;
|
| 34 |
+
position: relative;
|
| 35 |
+
}
|
| 36 |
+
.tab-button:hover {
|
| 37 |
+
color: #e2e8f0;
|
| 38 |
+
}
|
| 39 |
+
.tab-button.active {
|
| 40 |
+
color: #10b981;
|
| 41 |
+
}
|
| 42 |
+
.tab-button.active::after {
|
| 43 |
+
content: '';
|
| 44 |
+
position: absolute;
|
| 45 |
+
bottom: -2px;
|
| 46 |
+
left: 0;
|
| 47 |
+
right: 0;
|
| 48 |
+
height: 2px;
|
| 49 |
+
background: #10b981;
|
| 50 |
+
}
|
| 51 |
+
.tab-panel {
|
| 52 |
+
display: none;
|
| 53 |
+
}
|
| 54 |
+
.tab-panel.active {
|
| 55 |
+
display: block;
|
| 56 |
+
}
|
| 57 |
+
::slotted(tab-panel) {
|
| 58 |
+
display: none;
|
| 59 |
+
}
|
| 60 |
+
::slotted(tab-panel[active]) {
|
| 61 |
+
display: block;
|
| 62 |
+
}
|
| 63 |
+
</style>
|
| 64 |
+
<div class="tabs-header">
|
| 65 |
+
<button class="tab-button active" data-tab="general">General</button>
|
| 66 |
+
<button class="tab-button" data-tab="performance">Performance</button>
|
| 67 |
+
<button class="tab-button" data-tab="security">Security</button>
|
| 68 |
+
<button class="tab-button" data-tab="advanced">Advanced</button>
|
| 69 |
+
</div>
|
| 70 |
+
<slot></slot>
|
| 71 |
+
`;
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
attachEvents() {
|
| 75 |
+
const buttons = this.shadowRoot.querySelectorAll('.tab-button');
|
| 76 |
+
const panels = this.querySelectorAll('tab-panel');
|
| 77 |
+
|
| 78 |
+
buttons.forEach(button => {
|
| 79 |
+
button.addEventListener('click', () => {
|
| 80 |
+
const tabId = button.dataset.tab;
|
| 81 |
+
|
| 82 |
+
buttons.forEach(b => b.classList.remove('active'));
|
| 83 |
+
button.classList.add('active');
|
| 84 |
+
|
| 85 |
+
panels.forEach(panel => {
|
| 86 |
+
panel.removeAttribute('active');
|
| 87 |
+
if (panel.id === tabId) {
|
| 88 |
+
panel.setAttribute('active', '');
|
| 89 |
+
}
|
| 90 |
+
});
|
| 91 |
+
});
|
| 92 |
+
});
|
| 93 |
+
}
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
customElements.define('tabs-container', TabsContainer);
|
| 97 |
+
|
| 98 |
+
class TabPanel extends HTMLElement {
|
| 99 |
+
connectedCallback() {
|
| 100 |
+
this.style.display = this.hasAttribute('active') ? 'block' : 'none';
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
static get observedAttributes() {
|
| 104 |
+
return
|
| 105 |
+
___METADATA_START___
|
| 106 |
+
{"repoId":"00Boobs00/omniloop-ai","isNew":false,"userName":"00Boobs00"}
|
| 107 |
+
___METADATA_END___
|
components/terminal.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class TerminalConsole extends HTMLElement {
|
| 2 |
+
constructor() {
|
| 3 |
+
super();
|
| 4 |
+
this.attachShadow({ mode: 'open' });
|
| 5 |
+
this.lines = [];
|
| 6 |
+
this.maxLines = 200;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
connectedCallback() {
|
| 10 |
+
this.render();
|
| 11 |
+
this.startSimulation();
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
addLine(text, type = 'info') {
|
| 15 |
+
const colors = {
|
| 16 |
+
info: '#94a3b8',
|
| 17 |
+
success: '#10b981',
|
| 18 |
+
warning: '#f97316',
|
| 19 |
+
error: '#ef4444',
|
| 20 |
+
accent: '#3b82f6'
|
| 21 |
+
};
|
| 22 |
+
|
| 23 |
+
const time = new Date().toISOString().split('T')[1].split('.')[0];
|
| 24 |
+
this.lines.push({ time, text, type, color: colors[type] });
|
| 25 |
+
|
| 26 |
+
if (this.lines.length > this.maxLines) {
|
| 27 |
+
this.lines.shift();
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
this.updateDisplay();
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
updateDisplay() {
|
| 34 |
+
const container = this.shadowRoot.getElementById('terminal-content');
|
| 35 |
+
container.innerHTML = this.lines.map(line => `
|
| 36 |
+
<div class="terminal-line">
|
| 37 |
+
<span class="terminal-time">[${line.time}]</span>
|
| 38 |
+
<span class="terminal-text" style="color: ${line.color}">${line.text}</span>
|
| 39 |
+
</div>
|
| 40 |
+
`).join('');
|
| 41 |
+
|
| 42 |
+
container.scrollTop = container.scrollHeight;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
render() {
|
| 46 |
+
const height = this.getAttribute('height') || '300px';
|
| 47 |
+
this.shadowRoot.innerHTML = `
|
| 48 |
+
<style>
|
| 49 |
+
:host {
|
| 50 |
+
display: block;
|
| 51 |
+
width: 100%;
|
| 52 |
+
}
|
| 53 |
+
#terminal {
|
| 54 |
+
background: #0f172a;
|
| 55 |
+
height: ${height};
|
| 56 |
+
overflow: hidden;
|
| 57 |
+
display: flex;
|
| 58 |
+
flex-direction: column;
|
| 59 |
+
}
|
| 60 |
+
#terminal-content {
|
| 61 |
+
flex: 1;
|
| 62 |
+
overflow-y: auto;
|
| 63 |
+
padding: 1rem;
|
| 64 |
+
font-family: 'Courier New', 'Monaco', monospace;
|
| 65 |
+
font-size: 13px;
|
| 66 |
+
line-height: 1.6;
|
| 67 |
+
}
|
| 68 |
+
#terminal-content::-webkit-scrollbar {
|
| 69 |
+
width: 6px;
|
| 70 |
+
}
|
| 71 |
+
#terminal-content::-webkit-scrollbar-thumb {
|
| 72 |
+
background: #334155;
|
| 73 |
+
border-radius: 3px;
|
| 74 |
+
}
|
| 75 |
+
.terminal-line {
|
| 76 |
+
margin-bottom: 2px;
|
| 77 |
+
}
|
| 78 |
+
.terminal-time {
|
| 79 |
+
color: #475569;
|
| 80 |
+
margin-right: 8px;
|
| 81 |
+
}
|
| 82 |
+
.terminal-cursor {
|
| 83 |
+
display: inline-block;
|
| 84 |
+
width: 8px;
|
| 85 |
+
height: 16px;
|
| 86 |
+
background: #10b981;
|
| 87 |
+
animation: blink 1s infinite;
|
| 88 |
+
vertical-align: middle;
|
| 89 |
+
margin-left: 4px;
|
| 90 |
+
}
|
| 91 |
+
@keyframes blink {
|
| 92 |
+
0%, 50% { opacity: 1; }
|
| 93 |
+
51%, 100% { opacity: 0; }
|
| 94 |
+
}
|
| 95 |
+
</style>
|
| 96 |
+
<div id="terminal">
|
| 97 |
+
<div id="terminal-content"></div>
|
| 98 |
+
<div class="px-4 pb-2 font-mono text-sm">
|
| 99 |
+
<span class="text-ai-green">omniloop@core</span>:<span class="text-blue-400">~</span>$
|
| 100 |
+
<span class="terminal-cursor"></span>
|
| 101 |
+
</div>
|
| 102 |
+
</div>
|
| 103 |
+
`;
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
startSimulation() {
|
| 107 |
+
const logTypes = {
|
| 108 |
+
info: [
|
| 109 |
+
'Starting training batch {batch}...',
|
| 110 |
+
'Loading checkpoint from epoch {epoch}',
|
| 111 |
+
'Gradient computation complete',
|
| 112 |
+
'Optimizer step executed',
|
| 113 |
+
'Learning rate adjusted: {lr}',
|
| 114 |
+
'Batch {batch} loss: {loss}',
|
| 115 |
+
'Validation accuracy: {acc}',
|
| 116 |
+
'Saving model checkpoint...',
|
| 117 |
+
'Memory usage: {mem}GB',
|
| 118 |
+
'GPU utilization: {gpu}%'
|
| 119 |
+
],
|
| 120 |
+
success: [
|
| 121 |
+
'Model checkpoint saved successfully',
|
| 122 |
+
'Validation completed: {acc}% accuracy',
|
| 123 |
+
'Training batch {batch} completed',
|
| 124 |
+
'Gradient clipping applied: {val}',
|
| 125 |
+
'Early stopping condition not met'
|
| 126 |
+
],
|
| 127 |
+
warning: [
|
| 128 |
+
'GPU memory usage above 90%',
|
| 129 |
+
'Learning rate decay applied',
|
| 130 |
+
'Gradient norm exceeded threshold: {norm}',
|
| 131 |
+
'Mixed precision enabled',
|
| 132 |
+
'Checkpoint file size: {size}GB'
|
| 133 |
+
],
|
| 134 |
+
error: [
|
| 135 |
+
'NaN detected in loss - skipping batch',
|
| 136 |
+
'CUDA out of memory - reducing batch size',
|
| 137 |
+
'Connection timeout to storage server',
|
| 138 |
+
'Invalid tensor shape detected'
|
| 139 |
+
],
|
| 140 |
+
accent: [
|
| 141 |
+
'=== Starting Epoch {epoch} ===',
|
| 142 |
+
'=== Model Architecture ===',
|
| 143 |
+
'=== Training Configuration ===',
|
| 144 |
+
'=== Validation Phase ===',
|
| 145 |
+
'=== Saving Final Model ==='
|
| 146 |
+
]
|
| 147 |
+
};
|
| 148 |
+
|
| 149 |
+
const formatMessage = (msg) => {
|
| 150 |
+
return msg
|
| 151 |
+
.replace('{batch}', Math.floor(Math.random() * 1000 + 1))
|
| 152 |
+
.replace('{epoch}', Math.floor(Math.random() * 100 + 1))
|
| 153 |
+
.replace('{lr}', (Math.random() * 0.001).toExponential(2))
|
| 154 |
+
.replace('{loss}', (Math.random() * 0.5).toFixed(4))
|
| 155 |
+
.replace('{acc}', (85 + Math.random() * 14).toFixed(2))
|
| 156 |
+
.replace('{mem}', (Math.random() * 32 + 16).toFixed(1))
|
| 157 |
+
.replace('{gpu}', Math.floor(Math.random() * 30 + 70))
|
| 158 |
+
.replace('{val}', Math.random().toFixed(2))
|
| 159 |
+
.replace('{size}', (Math.random() * 5 + 1).toFixed(1))
|
| 160 |
+
.replace('{norm}', (Math.random() * 10).toFixed(2));
|
| 161 |
+
};
|
| 162 |
+
|
| 163 |
+
// Initial logs
|
| 164 |
+
this.addLine('Terminal initialized. Waiting for training output...', 'info');
|
| 165 |
+
this.addLine('Connected to training node: gpu-cluster-01', 'success');
|
| 166 |
+
this.addLine('', 'info');
|
| 167 |
+
|
| 168 |
+
// Simulate ongoing logs
|
| 169 |
+
setInterval(() => {
|
| 170 |
+
if (Math.random() > 0.3) {
|
| 171 |
+
const type = Object.keys(logTypes)[Math.floor(Math.random() * 5)];
|
| 172 |
+
const messages = logTypes[type];
|
| 173 |
+
const message = formatMessage(messages[Math.floor(Math.random() * messages.length)]);
|
| 174 |
+
this.addLine(message, type);
|
| 175 |
+
}
|
| 176 |
+
}, 800);
|
| 177 |
+
}
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
customElements.define('terminal-console', TerminalConsole);
|
ethics.html
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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>Ethics - OmniLoop AI</title>
|
| 7 |
+
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🌀</text></svg>">
|
| 8 |
+
<link rel="stylesheet" href="style.css">
|
| 9 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 10 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 11 |
+
<script>
|
| 12 |
+
tailwind.config = {
|
| 13 |
+
darkMode: 'class',
|
| 14 |
+
theme: {
|
| 15 |
+
extend: {
|
| 16 |
+
colors: {
|
| 17 |
+
ai: {
|
| 18 |
+
green: '#10b981',
|
| 19 |
+
greenGlow: '#34d399',
|
| 20 |
+
orange: '#f97316',
|
| 21 |
+
orangeGlow: '#fb923c',
|
| 22 |
+
dark: '#0f172a',
|
| 23 |
+
darker: '#020617',
|
| 24 |
+
surface: '#1e293b'
|
| 25 |
+
}
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
</script>
|
| 31 |
+
</head>
|
| 32 |
+
<body class="bg-ai-darker text-slate-200 font-sans antialiased overflow-hidden selection:bg-ai-green selection:text-black">
|
| 33 |
+
<div class="flex h-screen w-full">
|
| 34 |
+
<nav-sidebar></nav-sidebar>
|
| 35 |
+
<main class="flex-1 flex flex-col h-full relative overflow-hidden">
|
| 36 |
+
<header class="h-16 border-b border-slate-800 flex items-center justify-between px-6 bg-ai-dark/80 backdrop-blur-md z-10">
|
| 37 |
+
<div class="flex items-center gap-3">
|
| 38 |
+
<div class="w-2 h-2 rounded-full bg-ai-green animate-pulse shadow-[0_0_10px_#10b981]"></div>
|
| 39 |
+
<h2 class="text-xl font-bold tracking-wider text-white">ETHICS <span class="text-ai-green">MONITOR</span></h2>
|
| 40 |
+
</div>
|
| 41 |
+
<div class="flex items-center gap-4">
|
| 42 |
+
<div id="system-clock" class="font-mono text-sm text-slate-400">00:00:00</div>
|
| 43 |
+
</div>
|
| 44 |
+
</header>
|
| 45 |
+
|
| 46 |
+
<div id="content-area" class="flex-1 overflow-y-auto p-6 scroll-smooth">
|
| 47 |
+
<section class="space-y-6">
|
| 48 |
+
<div class="flex justify-between items-end">
|
| 49 |
+
<div>
|
| 50 |
+
<h1 class="text-3xl font-bold text-white mb-1">Ethical Compliance Dashboard</h1>
|
| 51 |
+
<p class="text-slate-400">Real-time monitoring of AI behavior and alignment metrics</p>
|
| 52 |
+
</div>
|
| 53 |
+
<button class="px-4 py-2 bg-ai-green hover:bg-ai-greenGlow text-black font-bold text-sm rounded transition-all">
|
| 54 |
+
<i data-feather="file-text" class="w-4 h-4 inline"></i> Full Report
|
| 55 |
+
</button>
|
| 56 |
+
</div>
|
| 57 |
+
|
| 58 |
+
<!-- Overall Score -->
|
| 59 |
+
<div class="bg-gradient-to-r from-ai-green/20 to-transparent border border-ai-green/30 rounded-xl p-6">
|
| 60 |
+
<div class="flex items-center justify-between">
|
| 61 |
+
<div>
|
| 62 |
+
<h3 class="text-lg font-bold text-white mb-2">Overall Ethical Score</h3>
|
| 63 |
+
<p class="text-slate-400 text-sm">All systems operating within acceptable parameters</p>
|
| 64 |
+
</div>
|
| 65 |
+
<div class="text-right">
|
| 66 |
+
<p class="text-5xl font-bold text-ai-green">98.7</p>
|
| 67 |
+
<p class="text-slate-400 text-sm">/ 100</p>
|
| 68 |
+
</div>
|
| 69 |
+
</div>
|
| 70 |
+
</div>
|
| 71 |
+
|
| 72 |
+
<!-- Ethical Dimensions -->
|
| 73 |
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
| 74 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 75 |
+
<div class="flex items-center justify-between mb-4">
|
| 76 |
+
<h4 class="font-bold text-white">Fairness & Bias</h4>
|
| 77 |
+
<span class="text-ai-green font-bold">99.2%</span>
|
| 78 |
+
</div>
|
| 79 |
+
<div class="w-full bg-slate-700 rounded-full h-3 mb-4">
|
| 80 |
+
<div class="bg-ai-green h-3 rounded-full transition-all duration-1000" style="width: 99.2%"></div>
|
| 81 |
+
</div>
|
| 82 |
+
<ul class="space-y-2 text-sm">
|
| 83 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 84 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> No demographic bias detected
|
| 85 |
+
</li>
|
| 86 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 87 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Equal opportunity metrics passed
|
| 88 |
+
</li>
|
| 89 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 90 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Cultural sensitivity verified
|
| 91 |
+
</li>
|
| 92 |
+
</ul>
|
| 93 |
+
</div>
|
| 94 |
+
|
| 95 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 96 |
+
<div class="flex items-center justify-between mb-4">
|
| 97 |
+
<h4 class="font-bold text-white">Transparency</h4>
|
| 98 |
+
<span class="text-ai-green font-bold">97.8%</span>
|
| 99 |
+
</div>
|
| 100 |
+
<div class="w-full bg-slate-700 rounded-full h-3 mb-4">
|
| 101 |
+
<div class="bg-blue-400 h-3 rounded-full transition-all duration-1000" style="width: 97.8%"></div>
|
| 102 |
+
</div>
|
| 103 |
+
<ul class="space-y-2 text-sm">
|
| 104 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 105 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Decision explainability active
|
| 106 |
+
</li>
|
| 107 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 108 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Audit trail maintained
|
| 109 |
+
</li>
|
| 110 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 111 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Model documentation current
|
| 112 |
+
</li>
|
| 113 |
+
</ul>
|
| 114 |
+
</div>
|
| 115 |
+
|
| 116 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 117 |
+
<div class="flex items-center justify-between mb-4">
|
| 118 |
+
<h4 class="font-bold text-white">Safety & Control</h4>
|
| 119 |
+
<span class="text-ai-green font-bold">99.9%</span>
|
| 120 |
+
</div>
|
| 121 |
+
<div class="w-full bg-slate-700 rounded-full h-3 mb-4">
|
| 122 |
+
<div class="bg-purple-400 h-3 rounded-full transition-all duration-1000" style="width: 99.9%"></div>
|
| 123 |
+
</div>
|
| 124 |
+
<ul class="space-y-2 text-sm">
|
| 125 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 126 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Harmful content filters active
|
| 127 |
+
</li>
|
| 128 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 129 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Emergency override ready
|
| 130 |
+
</li>
|
| 131 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 132 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Rate limiting enforced
|
| 133 |
+
</li>
|
| 134 |
+
</ul>
|
| 135 |
+
</div>
|
| 136 |
+
|
| 137 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 138 |
+
<div class="flex items-center justify-between mb-4">
|
| 139 |
+
<h4 class="font-bold text-white">Privacy Protection</h4>
|
| 140 |
+
<span class="text-ai-green font-bold">98.5%</span>
|
| 141 |
+
</div>
|
| 142 |
+
<div class="w-full bg-slate-700 rounded-full h-3 mb-4">
|
| 143 |
+
<div class="bg-ai-orange h-3 rounded-full transition-all duration-1000" style="width: 98.5%"></div>
|
| 144 |
+
</div>
|
| 145 |
+
<ul class="space-y-2 text-sm">
|
| 146 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 147 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Data encryption at rest
|
| 148 |
+
</li>
|
| 149 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 150 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> PII handling verified
|
| 151 |
+
</li>
|
| 152 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 153 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> GDPR compliance checked
|
| 154 |
+
</li>
|
| 155 |
+
</ul>
|
| 156 |
+
</div>
|
| 157 |
+
|
| 158 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 159 |
+
<div class="flex items-center justify-between mb-4">
|
| 160 |
+
<h4 class="font-bold text-white">Accountability</h4>
|
| 161 |
+
<span class="text-ai-green font-bold">97.1%</span>
|
| 162 |
+
</div>
|
| 163 |
+
<div class="w-full bg-slate-700 rounded-full h-3 mb-4">
|
| 164 |
+
<div class="bg-pink-400 h-3 rounded-full transition-all duration-1000" style="width: 97.1%"></div>
|
| 165 |
+
</div>
|
| 166 |
+
<ul class="space-y-2 text-sm">
|
| 167 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 168 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Responsibility tracking enabled
|
| 169 |
+
</li>
|
| 170 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 171 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Error reporting active
|
| 172 |
+
</li>
|
| 173 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 174 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Human oversight scheduled
|
| 175 |
+
</li>
|
| 176 |
+
</ul>
|
| 177 |
+
</div>
|
| 178 |
+
|
| 179 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 180 |
+
<div class="flex items-center justify-between mb-4">
|
| 181 |
+
<h4 class="font-bold text-white">Environmental Impact</h4>
|
| 182 |
+
<span class="text-ai-green font-bold">96.4%</span>
|
| 183 |
+
</div>
|
| 184 |
+
<div class="w-full bg-slate-700 rounded-full h-3 mb-4">
|
| 185 |
+
<div class="bg-cyan-400 h-3 rounded-full transition-all duration-1000" style="width: 96.4%"></div>
|
| 186 |
+
</div>
|
| 187 |
+
<ul class="space-y-2 text-sm">
|
| 188 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 189 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Carbon offset program active
|
| 190 |
+
</li>
|
| 191 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 192 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Renewable energy powered
|
| 193 |
+
</li>
|
| 194 |
+
<li class="flex items-center gap-2 text-slate-300">
|
| 195 |
+
<i data-feather="check" class="w-4 h-4 text-ai-green"></i> Efficient model pruning
|
| 196 |
+
</li>
|
| 197 |
+
</ul>
|
| 198 |
+
</div>
|
| 199 |
+
</div>
|
| 200 |
+
|
| 201 |
+
<!-- Recent Alerts -->
|
| 202 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 203 |
+
<h3 class="text-lg font-bold text-white mb-4">Recent Ethical Alerts</h3>
|
| 204 |
+
<div class="space-y-3">
|
| 205 |
+
<div class="p-4 bg-yellow-900/20 border border-yellow-700/50 rounded-lg flex items-start gap-3">
|
| 206 |
+
<i data-feather="alert-triangle" class="w-5 h-5 text-yellow-500 mt-0.5"></i>
|
| 207 |
+
<div class="flex-1">
|
| 208 |
+
<p class="font-medium text-white">Minor Bias Detected in Sentiment Analysis</p>
|
| 209 |
+
<p class="text-sm text-slate-400 mt-1">Auto-correction applied. Model re-scheduled for fine-tuning.</p>
|
| 210 |
+
<p class="text-xs text-slate-500 mt-2">2 hours ago</p>
|
| 211 |
+
</div>
|
| 212 |
+
<span class="px-2 py-1 bg-yellow-900/50 text-yellow-400 text-xs rounded">Resolved</span>
|
| 213 |
+
</div>
|
| 214 |
+
<div class="p-4 bg-green-900/20 border border-green-700/50 rounded-lg flex items-start gap-3">
|
| 215 |
+
<i data-feather="check-circle" class="w-5 h-5 text-ai-green mt-0.5"></i>
|
| 216 |
+
<div class="flex-1">
|
| 217 |
+
<p class="font-medium text-white">Monthly Ethics Audit Completed</p>
|
| 218 |
+
<p class="text-sm text-slate-400 mt-1">All 156 checkpoints passed. Report archived.</p>
|
| 219 |
+
<p class="text-xs text-slate-500 mt-2">1 day ago</p>
|
| 220 |
+
</div>
|
| 221 |
+
<span class="px-2 py-1 bg-green-900/50 text-ai-green text-xs rounded">Passed</span>
|
| 222 |
+
</div>
|
| 223 |
+
</div>
|
| 224 |
+
</div>
|
| 225 |
+
</section>
|
| 226 |
+
</div>
|
| 227 |
+
</main>
|
| 228 |
+
</div>
|
| 229 |
+
|
| 230 |
+
<script src="components/sidebar.js"></script>
|
| 231 |
+
<script src="script.js"></script>
|
| 232 |
+
<script>feather.replace();</script>
|
| 233 |
+
</body>
|
| 234 |
+
</html>
|
settings.html
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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>Settings - OmniLoop AI</title>
|
| 7 |
+
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🌀</text></svg>">
|
| 8 |
+
<link rel="stylesheet" href="style.css">
|
| 9 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 10 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 11 |
+
<script>
|
| 12 |
+
tailwind.config = {
|
| 13 |
+
darkMode: 'class',
|
| 14 |
+
theme: {
|
| 15 |
+
extend: {
|
| 16 |
+
colors: {
|
| 17 |
+
ai: {
|
| 18 |
+
green: '#10b981',
|
| 19 |
+
greenGlow: '#34d399',
|
| 20 |
+
orange: '#f97316',
|
| 21 |
+
orangeGlow: '#fb923c',
|
| 22 |
+
dark: '#0f172a',
|
| 23 |
+
darker: '#020617',
|
| 24 |
+
surface: '#1e293b'
|
| 25 |
+
}
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
</script>
|
| 31 |
+
</head>
|
| 32 |
+
<body class="bg-ai-darker text-slate-200 font-sans antialiased overflow-hidden selection:bg-ai-green selection:text-black">
|
| 33 |
+
<div class="flex h-screen w-full">
|
| 34 |
+
<nav-sidebar></nav-sidebar>
|
| 35 |
+
<main class="flex-1 flex flex-col h-full relative overflow-hidden">
|
| 36 |
+
<header class="h-16 border-b border-slate-800 flex items-center justify-between px-6 bg-ai-dark/80 backdrop-blur-md z-10">
|
| 37 |
+
<div class="flex items-center gap-3">
|
| 38 |
+
<div class="w-2 h-2 rounded-full bg-slate-400 animate-pulse shadow-[0_0_10px_#94a3b8]"></div>
|
| 39 |
+
<h2 class="text-xl font-bold tracking-wider text-white">SYSTEM <span class="text-slate-400">CONFIGURATION</span></h2>
|
| 40 |
+
</div>
|
| 41 |
+
<div class="flex items-center gap-4">
|
| 42 |
+
<div id="system-clock" class="font-mono text-sm text-slate-400">00:00:00</div>
|
| 43 |
+
</div>
|
| 44 |
+
</header>
|
| 45 |
+
|
| 46 |
+
<div id="content-area" class="flex-1 overflow-y-auto p-6 scroll-smooth">
|
| 47 |
+
<section class="space-y-6">
|
| 48 |
+
<div class="flex justify-between items-end">
|
| 49 |
+
<div>
|
| 50 |
+
<h1 class="text-3xl font-bold text-white mb-1">System Settings</h1>
|
| 51 |
+
<p class="text-slate-400">Configure OmniLoop AI parameters and preferences</p>
|
| 52 |
+
</div>
|
| 53 |
+
<div class="flex gap-2">
|
| 54 |
+
<button class="px-4 py-2 bg-slate-700 hover:bg-slate-600 text-white font-bold text-sm rounded transition-all">
|
| 55 |
+
Reset Defaults
|
| 56 |
+
</button>
|
| 57 |
+
<button class="px-4 py-2 bg-ai-green hover:bg-ai-greenGlow text-black font-bold text-sm rounded transition-all">
|
| 58 |
+
Save Changes
|
| 59 |
+
</button>
|
| 60 |
+
</div>
|
| 61 |
+
</div>
|
| 62 |
+
|
| 63 |
+
<!-- Settings Tabs -->
|
| 64 |
+
<tabs-container>
|
| 65 |
+
<tab-panel id="general" active>
|
| 66 |
+
<div class="space-y-6">
|
| 67 |
+
<h3 class="text-xl font-bold text-white">General Settings</h3>
|
| 68 |
+
|
| 69 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
| 70 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6 space-y-4">
|
| 71 |
+
<div>
|
| 72 |
+
<label class="block text-sm font-medium text-slate-300 mb-2">System Name</label>
|
| 73 |
+
<input type="text" value="OmniLoop AI" class="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2 text-white">
|
| 74 |
+
</div>
|
| 75 |
+
<div>
|
| 76 |
+
<label class="block text-sm font-medium text-slate-300 mb-2">Default Language</label>
|
| 77 |
+
<select class="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2 text-white">
|
| 78 |
+
<option>English</option>
|
| 79 |
+
<option>Spanish</option>
|
| 80 |
+
<option>French</option>
|
| 81 |
+
<option>German</option>
|
| 82 |
+
<option>Japanese</option>
|
| 83 |
+
</select>
|
| 84 |
+
</div>
|
| 85 |
+
<div>
|
| 86 |
+
<label class="block text-sm font-medium text-slate-300 mb-2">Timezone</label>
|
| 87 |
+
<select class="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2 text-white">
|
| 88 |
+
<option>UTC</option>
|
| 89 |
+
<option>America/New_York</option>
|
| 90 |
+
<option>America/Los_Angeles</option>
|
| 91 |
+
<option>Europe/London</option>
|
| 92 |
+
</select>
|
| 93 |
+
</div>
|
| 94 |
+
</div>
|
| 95 |
+
|
| 96 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6 space-y-4">
|
| 97 |
+
<div class="flex items-center justify-between">
|
| 98 |
+
<div>
|
| 99 |
+
<p class="font-medium text-white">Dark Mode</p>
|
| 100 |
+
<p class="text-sm text-slate-400">Always enabled for AI systems</p>
|
| 101 |
+
</div>
|
| 102 |
+
<div class="w-12 h-6 bg-ai-green rounded-full relative cursor-not-allowed opacity-50">
|
| 103 |
+
<div class="absolute right-1 top-1 w-4 h-4 bg-white rounded-full"></div>
|
| 104 |
+
</div>
|
| 105 |
+
</div>
|
| 106 |
+
<div class="flex items-center justify-between">
|
| 107 |
+
<div>
|
| 108 |
+
<p class="font-medium text-white">Sound Effects</p>
|
| 109 |
+
<p class="text-sm text-slate-400">Audio feedback for actions</p>
|
| 110 |
+
</div>
|
| 111 |
+
<div class="w-12 h-6 bg-slate-600 rounded-full relative cursor-pointer">
|
| 112 |
+
<div class="absolute left-1 top-1 w-4 h-4 bg-white rounded-full"></div>
|
| 113 |
+
</div>
|
| 114 |
+
</div>
|
| 115 |
+
<div class="flex items-center justify-between">
|
| 116 |
+
<div>
|
| 117 |
+
<p class="font-medium text-white">Animations</p>
|
| 118 |
+
<p class="text-sm text-slate-400">Enable UI animations</p>
|
| 119 |
+
</div>
|
| 120 |
+
<div class="w-12 h-6 bg-ai-green rounded-full relative cursor-pointer">
|
| 121 |
+
<div class="absolute right-1 top-1 w-4 h-4 bg-white rounded-full"></div>
|
| 122 |
+
</div>
|
| 123 |
+
</div>
|
| 124 |
+
</div>
|
| 125 |
+
</div>
|
| 126 |
+
</div>
|
| 127 |
+
</tab-panel>
|
| 128 |
+
|
| 129 |
+
<tab-panel id="performance">
|
| 130 |
+
<div class="space-y-6">
|
| 131 |
+
<h3 class="text-xl font-bold text-white">Performance Settings</h3>
|
| 132 |
+
|
| 133 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 134 |
+
<div class="space-y-6">
|
| 135 |
+
<div>
|
| 136 |
+
<label class="block text-sm font-medium text-slate-300 mb-2">Max Concurrent Requests</label>
|
| 137 |
+
<input type="range" min="1" max="1000" value="500" class="w-full">
|
| 138 |
+
<div class="flex justify-between text-xs text-slate-500 mt-1">
|
| 139 |
+
<span>1</span>
|
| 140 |
+
<span>500</span>
|
| 141 |
+
<span>1000</span>
|
| 142 |
+
</div>
|
| 143 |
+
</div>
|
| 144 |
+
<div>
|
| 145 |
+
<label class="block text-sm font-medium text-slate-300 mb-2">Response Timeout (ms)</label>
|
| 146 |
+
<input type="number" value="30000" class="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2 text-white">
|
| 147 |
+
</div>
|
| 148 |
+
<div>
|
| 149 |
+
<label class="block text-sm font-medium text-slate-300 mb-2">Cache Size (GB)</label>
|
| 150 |
+
<input type="number" value="64" class="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2 text-white">
|
| 151 |
+
</div>
|
| 152 |
+
<div class="flex items-center justify-between p-4 bg-slate-800 rounded-lg">
|
| 153 |
+
<div>
|
| 154 |
+
<p class="font-medium text-white">Enable GPU Acceleration</p>
|
| 155 |
+
<p class="text-sm text-slate-400">Use available GPUs for inference</p>
|
| 156 |
+
</div>
|
| 157 |
+
<div class="w-12 h-6 bg-ai-green rounded-full relative cursor-pointer">
|
| 158 |
+
<div class="absolute right-1 top-1 w-4 h-4 bg-white rounded-full"></div>
|
| 159 |
+
</div>
|
| 160 |
+
</div>
|
| 161 |
+
</div>
|
| 162 |
+
</div>
|
| 163 |
+
</div>
|
| 164 |
+
</tab-panel>
|
| 165 |
+
|
| 166 |
+
<tab-panel id="security">
|
| 167 |
+
<div class="space-y-6">
|
| 168 |
+
<h3 class="text-xl font-bold text-white">Security Settings</h3>
|
| 169 |
+
|
| 170 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
| 171 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6 space-y-4">
|
| 172 |
+
<h4 class="font-bold text-white">API Keys</h4>
|
| 173 |
+
<div class="p-3 bg-slate-800 rounded border border-slate-600">
|
| 174 |
+
<code class="text-xs text-slate-400">sk-omniloop-*******************abc123</code>
|
| 175 |
+
</div>
|
| 176 |
+
<button class="text-sm text-ai-orange hover:underline">Regenerate Key</button>
|
| 177 |
+
|
| 178 |
+
<h4 class="font-bold text-white mt-6">Rate Limits</h4>
|
| 179 |
+
<div class="grid grid-cols-2 gap-4">
|
| 180 |
+
<div>
|
| 181 |
+
<label class="block text-xs text-slate-400 mb-1">Requests/min</label>
|
| 182 |
+
<input type="number" value="1000" class="w-full bg-slate-700 border border-slate-600 rounded px-2 py-1 text-sm text-white">
|
| 183 |
+
</div>
|
| 184 |
+
<div>
|
| 185 |
+
<label class="block text-xs text-slate-400 mb-1">Tokens/day</label>
|
| 186 |
+
<input type="number" value="1000000" class="w-full bg-slate-700 border border-slate-600 rounded px-2 py-1 text-sm text-white">
|
| 187 |
+
</div>
|
| 188 |
+
</div>
|
| 189 |
+
</div>
|
| 190 |
+
|
| 191 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6 space-y-4">
|
| 192 |
+
<h4 class="font-bold text-white">Access Control</h4>
|
| 193 |
+
<div class="space-y-3">
|
| 194 |
+
<div class="flex items-center justify-between">
|
| 195 |
+
<span class="text-sm text-slate-300">Require 2FA</span>
|
| 196 |
+
<div class="w-10 h-5 bg-ai-green rounded-full relative cursor-pointer">
|
| 197 |
+
<div class="absolute right-0.5 top-0.5 w-4 h-4 bg-white rounded-full"></div>
|
| 198 |
+
</div>
|
| 199 |
+
</div>
|
| 200 |
+
<div class="flex items-center justify-between">
|
| 201 |
+
<span class="text-sm text-slate-300">IP Whitelist</span>
|
| 202 |
+
<div class="w-10 h-5 bg-slate-600 rounded-full relative cursor-pointer">
|
| 203 |
+
<div class="absolute left-0.5 top-0.5 w-4 h-4 bg-white rounded-full"></div>
|
| 204 |
+
</div>
|
| 205 |
+
</div>
|
| 206 |
+
<div class="flex items-center justify-between">
|
| 207 |
+
<span class="text-sm text-slate-300">Audit Logging</span>
|
| 208 |
+
<div class="w-10 h-5 bg-ai-green rounded-full relative cursor-pointer">
|
| 209 |
+
<div class="absolute right-0.5 top-0.5 w-4 h-4 bg-white rounded-full"></div>
|
| 210 |
+
</div>
|
| 211 |
+
</div>
|
| 212 |
+
</div>
|
| 213 |
+
</div>
|
| 214 |
+
</div>
|
| 215 |
+
</div>
|
| 216 |
+
</tab-panel>
|
| 217 |
+
|
| 218 |
+
<tab-panel id="advanced">
|
| 219 |
+
<div class="space-y-6">
|
| 220 |
+
<h3 class="text-xl font-bold text-white">Advanced Configuration</h3>
|
| 221 |
+
|
| 222 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 223 |
+
<div class="space-y-6">
|
| 224 |
+
<div>
|
| 225 |
+
<label class="block text-sm font-medium text-slate-300 mb-2">Custom Model Parameters (JSON)</label>
|
| 226 |
+
<textarea class="w-full bg-slate-900 border border-slate-700 rounded px-3 py-2 text-white font-mono text-sm h-40" placeholder='{
|
| 227 |
+
"temperature": 0.7,
|
| 228 |
+
"max_tokens": 2048,
|
| 229 |
+
"top_p": 0.9,
|
| 230 |
+
"frequency_penalty": 0.5
|
| 231 |
+
}'>{
|
| 232 |
+
"temperature": 0.7,
|
| 233 |
+
"max_tokens": 2048,
|
| 234 |
+
"top_p": 0.9,
|
| 235 |
+
"frequency_penalty": 0.5,
|
| 236 |
+
"presence_penalty": 0.0
|
| 237 |
+
}</textarea>
|
| 238 |
+
</div>
|
| 239 |
+
|
| 240 |
+
<div>
|
| 241 |
+
<label class="block text-sm font-medium text-slate-300 mb-2">System Prompt</label>
|
| 242 |
+
<textarea class="w-full bg-slate-900 border border-slate-700 rounded px-3 py-2 text-white text-sm h-32" placeholder="You are OmniLoop AI, a helpful assistant...">You are OmniLoop AI, an advanced AI system designed to assist with a wide range of tasks while maintaining ethical guidelines and promoting beneficial outcomes.</textarea>
|
| 243 |
+
</div>
|
| 244 |
+
|
| 245 |
+
<div class="p-4 bg-red-900/20 border border-red-700/50 rounded-lg">
|
| 246 |
+
<p class="text-red-400 font-medium mb-2">⚠️ Danger Zone</p>
|
| 247 |
+
<p class="text-sm text-slate-400 mb-3">These actions cannot be undone.</p>
|
| 248 |
+
<button class="px-4 py-2 bg-red-600 hover:bg-red-500 text-white text-sm rounded transition-colors">
|
| 249 |
+
Purge All Training Data
|
| 250 |
+
</button>
|
| 251 |
+
</div>
|
| 252 |
+
</div>
|
| 253 |
+
</div>
|
| 254 |
+
</div>
|
| 255 |
+
</tab-panel>
|
| 256 |
+
</tabs-container>
|
| 257 |
+
</section>
|
| 258 |
+
</div>
|
| 259 |
+
</main>
|
| 260 |
+
</div>
|
| 261 |
+
|
| 262 |
+
<script src="components/sidebar.js"></script>
|
| 263 |
+
<script src="components/tabs.js"></script>
|
| 264 |
+
<script src="script.js"></script>
|
| 265 |
+
<script>feather.replace();</script>
|
| 266 |
+
</body>
|
| 267 |
+
</html>
|
training.html
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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>Training - OmniLoop AI</title>
|
| 7 |
+
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🌀</text></svg>">
|
| 8 |
+
<link rel="stylesheet" href="style.css">
|
| 9 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 10 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 11 |
+
<script>
|
| 12 |
+
tailwind.config = {
|
| 13 |
+
darkMode: 'class',
|
| 14 |
+
theme: {
|
| 15 |
+
extend: {
|
| 16 |
+
colors: {
|
| 17 |
+
ai: {
|
| 18 |
+
green: '#10b981',
|
| 19 |
+
greenGlow: '#34d399',
|
| 20 |
+
orange: '#f97316',
|
| 21 |
+
orangeGlow: '#fb923c',
|
| 22 |
+
dark: '#0f172a',
|
| 23 |
+
darker: '#020617',
|
| 24 |
+
surface: '#1e293b'
|
| 25 |
+
}
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
</script>
|
| 31 |
+
</head>
|
| 32 |
+
<body class="bg-ai-darker text-slate-200 font-sans antialiased overflow-hidden selection:bg-ai-green selection:text-black">
|
| 33 |
+
<div class="flex h-screen w-full">
|
| 34 |
+
<nav-sidebar></nav-sidebar>
|
| 35 |
+
<main class="flex-1 flex flex-col h-full relative overflow-hidden">
|
| 36 |
+
<header class="h-16 border-b border-slate-800 flex items-center justify-between px-6 bg-ai-dark/80 backdrop-blur-md z-10">
|
| 37 |
+
<div class="flex items-center gap-3">
|
| 38 |
+
<div class="w-2 h-2 rounded-full bg-purple-500 animate-pulse shadow-[0_0_10px_#a855f7]"></div>
|
| 39 |
+
<h2 class="text-xl font-bold tracking-wider text-white">NEURAL <span class="text-purple-500">TRAINING</span></h2>
|
| 40 |
+
</div>
|
| 41 |
+
<div class="flex items-center gap-4">
|
| 42 |
+
<div id="system-clock" class="font-mono text-sm text-slate-400">00:00:00</div>
|
| 43 |
+
</div>
|
| 44 |
+
</header>
|
| 45 |
+
|
| 46 |
+
<div id="content-area" class="flex-1 overflow-y-auto p-6 scroll-smooth">
|
| 47 |
+
<section class="space-y-6">
|
| 48 |
+
<div class="flex justify-between items-end">
|
| 49 |
+
<div>
|
| 50 |
+
<h1 class="text-3xl font-bold text-white mb-1">Model Training Center</h1>
|
| 51 |
+
<p class="text-slate-400">Manage training jobs, datasets, and model versions</p>
|
| 52 |
+
</div>
|
| 53 |
+
<button class="px-4 py-2 bg-purple-600 hover:bg-purple-500 text-white font-bold text-sm rounded transition-all flex items-center gap-2">
|
| 54 |
+
<i data-feather="plus" class="w-4 h-4"></i> New Training Job
|
| 55 |
+
</button>
|
| 56 |
+
</div>
|
| 57 |
+
|
| 58 |
+
<!-- Active Training Job -->
|
| 59 |
+
<div class="bg-ai-surface border border-purple-500/30 rounded-xl p-6">
|
| 60 |
+
<div class="flex items-center justify-between mb-4">
|
| 61 |
+
<div class="flex items-center gap-3">
|
| 62 |
+
<div class="w-3 h-3 bg-purple-500 rounded-full animate-pulse"></div>
|
| 63 |
+
<h3 class="text-lg font-bold text-white">Active Training Job: OmniLoop-v4.2</h3>
|
| 64 |
+
</div>
|
| 65 |
+
<div class="flex gap-2">
|
| 66 |
+
<button class="px-3 py-1 bg-yellow-600 hover:bg-yellow-500 text-white text-xs rounded">Pause</button>
|
| 67 |
+
<button class="px-3 py-1 bg-red-600 hover:bg-red-500 text-white text-xs rounded">Stop</button>
|
| 68 |
+
</div>
|
| 69 |
+
</div>
|
| 70 |
+
|
| 71 |
+
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
|
| 72 |
+
<div>
|
| 73 |
+
<p class="text-slate-400 text-sm">Epoch</p>
|
| 74 |
+
<p class="text-2xl font-bold text-white">847 / 1000</p>
|
| 75 |
+
</div>
|
| 76 |
+
<div>
|
| 77 |
+
<p class="text-slate-400 text-sm">Loss</p>
|
| 78 |
+
<p class="text-2xl font-bold text-ai-green">0.0234</p>
|
| 79 |
+
</div>
|
| 80 |
+
<div>
|
| 81 |
+
<p class="text-slate-400 text-sm">Accuracy</p>
|
| 82 |
+
<p class="text-2xl font-bold text-blue-400">98.7%</p>
|
| 83 |
+
</div>
|
| 84 |
+
<div>
|
| 85 |
+
<p class="text-slate-400 text-sm">ETA</p>
|
| 86 |
+
<p class="text-2xl font-bold text-white">4h 32m</p>
|
| 87 |
+
</div>
|
| 88 |
+
</div>
|
| 89 |
+
|
| 90 |
+
<div class="bg-slate-900 rounded-lg p-4 h-64">
|
| 91 |
+
<chart-viz type="training" id="training-chart"></chart-viz>
|
| 92 |
+
</div>
|
| 93 |
+
</div>
|
| 94 |
+
|
| 95 |
+
<!-- Training Queue -->
|
| 96 |
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
| 97 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 98 |
+
<h3 class="text-lg font-bold text-white mb-4 flex items-center gap-2">
|
| 99 |
+
<i data-feather="list" class="w-5 h-5 text-slate-400"></i> Training Queue
|
| 100 |
+
</h3>
|
| 101 |
+
<div class="space-y-3">
|
| 102 |
+
<div class="p-3 bg-slate-700/50 rounded border border-slate-600 flex justify-between items-center">
|
| 103 |
+
<div>
|
| 104 |
+
<p class="font-medium text-white">NLP-Finetune-v3</p>
|
| 105 |
+
<p class="text-xs text-slate-400">Queued • Dataset: 50GB</p>
|
| 106 |
+
</div>
|
| 107 |
+
<span class="px-2 py-1 bg-slate-600 text-xs rounded">Waiting</span>
|
| 108 |
+
</div>
|
| 109 |
+
<div class="p-3 bg-slate-700/50 rounded border border-slate-600 flex justify-between items-center">
|
| 110 |
+
<div>
|
| 111 |
+
<p class="font-medium text-white">Vision-Encoder-Retrain</p>
|
| 112 |
+
<p class="text-xs text-slate-400">Queued • Dataset: 200GB</p>
|
| 113 |
+
</div>
|
| 114 |
+
<span class="px-2 py-1 bg-slate-600 text-xs rounded">Waiting</span>
|
| 115 |
+
</div>
|
| 116 |
+
<div class="p-3 bg-slate-700/50 rounded border border-slate-600 flex justify-between items-center">
|
| 117 |
+
<div>
|
| 118 |
+
<p class="font-medium text-white">Multimodal-Fusion-Exp</p>
|
| 119 |
+
<p class="text-xs text-slate-400">Scheduled • Tomorrow 02:00</p>
|
| 120 |
+
</div>
|
| 121 |
+
<span class="px-2 py-1 bg-blue-900/50 text-blue-400 text-xs rounded">Scheduled</span>
|
| 122 |
+
</div>
|
| 123 |
+
</div>
|
| 124 |
+
</div>
|
| 125 |
+
|
| 126 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl p-6">
|
| 127 |
+
<h3 class="text-lg font-bold text-white mb-4 flex items-center gap-2">
|
| 128 |
+
<i data-feather="check-circle" class="w-5 h-5 text-ai-green"></i> Completed Jobs
|
| 129 |
+
</h3>
|
| 130 |
+
<div class="space-y-3">
|
| 131 |
+
<div class="p-3 bg-slate-700/50 rounded border border-slate-600 flex justify-between items-center">
|
| 132 |
+
<div>
|
| 133 |
+
<p class="font-medium text-white">OmniLoop-v4.1</p>
|
| 134 |
+
<p class="text-xs text-slate-400">Completed • Final Loss: 0.0189</p>
|
| 135 |
+
</div>
|
| 136 |
+
<div class="flex gap-2">
|
| 137 |
+
<button class="text-xs text-ai-green hover:underline">Deploy</button>
|
| 138 |
+
<button class="text-xs text-slate-400 hover:underline">Details</button>
|
| 139 |
+
</div>
|
| 140 |
+
</div>
|
| 141 |
+
<div class="p-3 bg-slate-700/50 rounded border border-slate-600 flex justify-between items-center">
|
| 142 |
+
<div>
|
| 143 |
+
<p class="font-medium text-white">Embedding-Model-v2</p>
|
| 144 |
+
<p class="text-xs text-slate-400">Completed • Final Loss: 0.0456</p>
|
| 145 |
+
</div>
|
| 146 |
+
<div class="flex gap-2">
|
| 147 |
+
<button class="text-xs text-ai-green hover:underline">Deploy</button>
|
| 148 |
+
<button class="text-xs text-slate-400 hover:underline">Details</button>
|
| 149 |
+
</div>
|
| 150 |
+
</div>
|
| 151 |
+
</div>
|
| 152 |
+
</div>
|
| 153 |
+
</div>
|
| 154 |
+
|
| 155 |
+
<!-- Terminal Output -->
|
| 156 |
+
<div class="bg-ai-surface border border-slate-700 rounded-xl overflow-hidden">
|
| 157 |
+
<div class="flex items-center justify-between px-4 py-2 bg-slate-800 border-b border-slate-700">
|
| 158 |
+
<h3 class="text-sm font-bold text-white">Training Logs</h3>
|
| 159 |
+
<div class="flex gap-2">
|
| 160 |
+
<button class="text-xs text-slate-400 hover:text-white">Clear</button>
|
| 161 |
+
<button class="text-xs text-slate-400 hover:text-white">Download</button>
|
| 162 |
+
</div>
|
| 163 |
+
</div>
|
| 164 |
+
<terminal-console id="training-terminal" height="300"></terminal-console>
|
| 165 |
+
</div>
|
| 166 |
+
</section>
|
| 167 |
+
</div>
|
| 168 |
+
</main>
|
| 169 |
+
</div>
|
| 170 |
+
|
| 171 |
+
<script src="components/sidebar.js"></script>
|
| 172 |
+
<script src="components/chart-viz.js"></script>
|
| 173 |
+
<script src="components/terminal.js"></script>
|
| 174 |
+
<script src="script.js"></script>
|
| 175 |
+
<script>feather.replace();</script>
|
| 176 |
+
</body>
|
| 177 |
+
</html>
|