Buckets:

Sinningai/asitheboy / water-computer-viz.html
boylnwzav1's picture
download
raw
35.6 kB
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; connect-src 'none';">
<title>Ω Hydro-Compute — Water-Based Computer Visualization</title>
<style>
:root {
--water: #00d4ff;
--steam: #ff6b35;
--heat: #ff0044;
--cool: #00ff88;
--dark: #0a0a1a;
--darker: #050510;
--light: #e0e8ff;
--glass: rgba(10, 10, 30, 0.85);
--glass-border: rgba(0, 212, 255, 0.15);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: var(--darker);
color: var(--light);
overflow-x: hidden;
}
.bg {
position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: -1;
background: radial-gradient(ellipse at 30% 70%, rgba(0,212,255,0.08) 0%, transparent 50%),
radial-gradient(ellipse at 70% 30%, rgba(255,0,68,0.06) 0%, transparent 50%),
var(--darker);
}
.container { max-width: 1400px; margin: 0 auto; padding: 20px; }
/* Header */
.header {
text-align: center; padding: 30px 20px;
background: var(--glass); border: 1px solid var(--glass-border);
border-radius: 16px; margin-bottom: 20px;
}
.header h1 {
font-size: clamp(1.5rem, 3vw, 2.5rem);
background: linear-gradient(135deg, var(--water), var(--cool));
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.header .subtitle { color: rgba(224,232,255,0.6); margin-top: 8px; }
/* Controls */
.controls {
display: flex; gap: 15px; flex-wrap: wrap; justify-content: center;
padding: 20px; background: var(--glass); border: 1px solid var(--glass-border);
border-radius: 12px; margin-bottom: 20px;
}
.controls label { color: var(--water); font-size: 0.85rem; font-weight: 600; }
.controls input, .controls select {
background: rgba(0,0,0,0.4); border: 1px solid var(--glass-border);
color: var(--light); padding: 8px 12px; border-radius: 8px; font-size: 0.85rem;
}
.controls button {
background: linear-gradient(135deg, var(--water), #0088cc);
color: white; border: none; padding: 10px 24px; border-radius: 8px;
font-weight: 700; cursor: pointer; font-size: 0.9rem;
}
.controls button:hover { opacity: 0.85; }
.controls button.stop { background: linear-gradient(135deg, var(--heat), #cc0033); }
/* Dashboard Grid */
.dashboard {
display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 20px; margin-bottom: 20px;
}
.card {
background: var(--glass); border: 1px solid var(--glass-border);
border-radius: 12px; padding: 20px; position: relative; overflow: hidden;
}
.card::before {
content: ''; position: absolute; top: 0; left: 0; width: 4px; height: 100%;
background: linear-gradient(180deg, var(--water), var(--cool));
}
.card h3 {
font-size: 0.85rem; color: var(--water); margin-bottom: 12px;
text-transform: uppercase; letter-spacing: 1px;
}
.card .value {
font-size: 2rem; font-weight: 900; font-family: 'Consolas', monospace;
}
.card .unit { font-size: 0.8rem; color: rgba(224,232,255,0.5); }
.card .bar {
height: 6px; background: rgba(0,0,0,0.3); border-radius: 3px;
margin-top: 12px; overflow: hidden;
}
.card .bar-fill {
height: 100%; border-radius: 3px; transition: width 0.3s;
}
/* Canvas */
.canvas-container {
background: var(--glass); border: 1px solid var(--glass-border);
border-radius: 12px; padding: 20px; margin-bottom: 20px;
}
.canvas-container h3 {
color: var(--water); margin-bottom: 15px; font-size: 1rem;
}
canvas {
width: 100%; height: 300px; background: rgba(0,0,0,0.3);
border-radius: 8px; display: block;
}
/* Water Animation */
.water-viz {
background: var(--glass); border: 1px solid var(--glass-border);
border-radius: 12px; padding: 20px; margin-bottom: 20px;
}
.water-viz h3 { color: var(--water); margin-bottom: 15px; }
.water-tank {
position: relative; width: 100%; height: 200px;
background: rgba(0,0,0,0.3); border-radius: 8px; overflow: hidden;
}
.water-level {
position: absolute; bottom: 0; left: 0; width: 100%;
background: linear-gradient(180deg, rgba(0,212,255,0.3), rgba(0,212,255,0.7));
transition: height 0.5s;
}
.water-level::before {
content: ''; position: absolute; top: -10px; left: 0; width: 200%;
height: 20px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 20'%3E%3Cpath d='M0 10 Q25 0 50 10 T100 10 T150 10 T200 10 V20 H0Z' fill='rgba(0,212,255,0.5)'/%3E%3C/svg%3E") repeat-x;
animation: wave 3s linear infinite;
}
@keyframes wave { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.steam-particles {
position: absolute; top: 0; left: 0; width: 100%; height: 100%;
pointer-events: none;
}
.steam {
position: absolute; width: 8px; height: 8px;
background: rgba(255,107,53,0.4); border-radius: 50%;
animation: rise 2s ease-out infinite;
}
@keyframes rise {
0% { transform: translateY(0) scale(1); opacity: 0.6; }
100% { transform: translateY(-150px) scale(0.2); opacity: 0; }
}
/* Status */
.status-bar {
display: flex; gap: 20px; flex-wrap: wrap; justify-content: center;
padding: 15px; background: var(--glass); border: 1px solid var(--glass-border);
border-radius: 12px; margin-bottom: 20px;
}
.status-item {
display: flex; align-items: center; gap: 8px; font-size: 0.85rem;
}
.status-dot {
width: 10px; height: 10px; border-radius: 50%;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
.status-dot.active { background: var(--cool); }
.status-dot.warning { background: #ffaa00; }
.status-dot.danger { background: var(--heat); }
/* Logic Gate Viz */
.logic-gates {
display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px; margin-bottom: 20px;
}
.gate-card {
background: rgba(0,0,0,0.3); border: 1px solid var(--glass-border);
border-radius: 8px; padding: 15px; text-align: center;
}
.gate-card h4 { color: var(--water); font-size: 0.8rem; margin-bottom: 10px; }
.gate-inputs { display: flex; justify-content: center; gap: 15px; margin-bottom: 10px; }
.gate-input {
width: 30px; height: 30px; border-radius: 50%;
display: flex; align-items: center; justify-content: center;
font-size: 0.75rem; font-weight: 700;
}
.gate-input.on { background: var(--cool); color: var(--dark); }
.gate-input.off { background: rgba(255,255,255,0.1); color: rgba(255,255,255,0.3); }
.gate-output {
width: 40px; height: 40px; border-radius: 50%; margin: 0 auto;
display: flex; align-items: center; justify-content: center;
font-weight: 900; font-size: 1rem;
}
.gate-output.on { background: var(--water); color: var(--dark); }
.gate-output.off { background: rgba(255,255,255,0.1); color: rgba(255,255,255,0.3); }
/* Footer */
.footer {
text-align: center; padding: 30px; color: rgba(224,232,255,0.3);
font-size: 0.8rem;
}
@media (max-width: 768px) {
.dashboard { grid-template-columns: 1fr; }
.container { padding: 10px; }
}
</style>
</head>
<body>
<div class="bg"></div>
<div class="container">
<!-- HEADER -->
<div class="header">
<h1>Ω Hydro-Compute Engine</h1>
<p class="subtitle">คอมพิวเตอร์พลังงานน้ำ — ใช้ความร้อนขับเคลื่อนคณิตศาสตร์</p>
</div>
<!-- STATUS BAR -->
<div class="status-bar">
<div class="status-item">
<div class="status-dot active" id="statusDot"></div>
<span id="statusText">พร้อมทำงาน</span>
</div>
<div class="status-item">
<span>รอบ: <strong id="roundDisplay">0</strong></span>
</div>
<div class="status-item">
<span>เวลา: <strong id="timeDisplay">00:00</strong></span>
</div>
<div class="status-item">
<span>สถานะน้ำ: <strong id="waterState">ของเหลว</strong></span>
</div>
</div>
<!-- CONTROLS -->
<div class="controls">
<div>
<label>จำนวนรอบ:</label><br>
<input type="number" id="roundsInput" value="10000" min="100" max="1000000" step="1000">
</div>
<div>
<label>พลังงานเริ่มต้น (W):</label><br>
<input type="number" id="powerInput" value="0.01" min="0.001" max="100" step="0.001">
</div>
<div>
<label>เพิ่มพลังงาน/รอบ:</label><br>
<input type="number" id="incrementInput" value="0.00000001" step="0.00000001">
</div>
<div>
<label>ความเร็วจำลอง:</label><br>
<select id="speedSelect">
<option value="1">ช้า (1x)</option>
<option value="10" selected>ปกติ (10x)</option>
<option value="100">เร็ว (100x)</option>
<option value="1000">เร็วสุด (1000x)</option>
</select>
</div>
<div style="display:flex;align-items:flex-end;gap:10px;">
<button id="startBtn" onclick="startSimulation()">▶ เริ่มจำลอง</button>
<button class="stop" id="stopBtn" onclick="stopSimulation()" disabled>⏹ หยุด</button>
</div>
</div>
<!-- DASHBOARD -->
<div class="dashboard">
<div class="card">
<h3>🔥 อุณหภูมิ</h3>
<div class="value" id="tempValue" style="color:var(--heat)">25.0°C</div>
<div class="unit">เป้าหมาย: 50°C (เหมาะสมที่สุด)</div>
<div class="bar"><div class="bar-fill" id="tempBar" style="width:25%;background:var(--heat)"></div></div>
</div>
<div class="card">
<h3>⚡ พลังงาน</h3>
<div class="value" id="powerValue" style="color:var(--water)">0.010 W</div>
<div class="unit">พลังงานความร้อน → การไหลของน้ำ</div>
<div class="bar"><div class="bar-fill" id="powerBar" style="width:1%;background:var(--water)"></div></div>
</div>
<div class="card">
<h3>💧 การไหลของน้ำ</h3>
<div class="value" id="flowValue" style="color:var(--cool)">0.000</div>
<div class="unit">หน่วย/วินาที</div>
<div class="bar"><div class="bar-fill" id="flowBar" style="width:0%;background:var(--cool)"></div></div>
</div>
<div class="card">
<h3>🧠 ประสิทธิภาพคณิตศาสตร์</h3>
<div class="value" id="effValue" style="color:#ffaa00">1.000</div>
<div class="unit">M(t) = M₀ × e^(-α(T-T_opt)²)</div>
<div class="bar"><div class="bar-fill" id="effBar" style="width:100%;background:#ffaa00"></div></div>
</div>
<div class="card">
<h3>🔢 การดำเนินการทั้งหมด</h3>
<div class="value" id="opsValue" style="color:var(--water)">0</div>
<div class="unit">กิริยาคณิตศาสตร์ (bit flips)</div>
<div class="bar"><div class="bar-fill" id="opsBar" style="width:0%;background:var(--water)"></div></div>
</div>
<div class="card">
<h3>💾 บิตที่ประมวลผล</h3>
<div class="value" id="bitsValue" style="color:var(--cool)">0</div>
<div class="unit">1 จูล = 1 บิต (สมมุติฐาน)</div>
<div class="bar"><div class="bar-fill" id="bitsBar" style="width:0%;background:var(--cool)"></div></div>
</div>
</div>
<!-- WATER TANK VISUALIZATION -->
<div class="water-viz">
<h3>💧 ถังน้ำจำลอง — ระดับน้ำ + ไอน้ำ</h3>
<div class="water-tank" id="waterTank">
<div class="water-level" id="waterLevel" style="height:60%"></div>
<div class="steam-particles" id="steamParticles"></div>
</div>
</div>
<!-- CHART -->
<div class="canvas-container">
<h3>📈 กราฟอุณหภูมิ + ประสิทธิภาพ (Real-time)</h3>
<canvas id="mainChart"></canvas>
</div>
<!-- LOGIC GATES -->
<div class="canvas-container">
<h3>🔧 ประตูตรรกะน้ำ — Water Logic Gates</h3>
<div class="logic-gates">
<div class="gate-card">
<h4>AND Gate</h4>
<div class="gate-inputs">
<div class="gate-input on" id="andA">1</div>
<div class="gate-input on" id="andB">1</div>
</div>
<div class="gate-output on" id="andOut">1</div>
</div>
<div class="gate-card">
<h4>OR Gate</h4>
<div class="gate-inputs">
<div class="gate-input on" id="orA">1</div>
<div class="gate-input off" id="orB">0</div>
</div>
<div class="gate-output on" id="orOut">1</div>
</div>
<div class="gate-card">
<h4>NOT Gate</h4>
<div class="gate-inputs">
<div class="gate-input on" id="notA">1</div>
</div>
<div class="gate-output off" id="notOut">0</div>
</div>
<div class="gate-card">
<h4>XOR Gate</h4>
<div class="gate-inputs">
<div class="gate-input on" id="xorA">1</div>
<div class="gate-input off" id="xorB">0</div>
</div>
<div class="gate-output on" id="xorOut">1</div>
</div>
</div>
</div>
<!-- FOOTER -->
<div class="footer">
<p>Ω Hydro-Compute Engine v1.0 | โดย นายไชยภพ นิลแพทย์ (Chaiyphop Nilpat)</p>
<p>100% Offline — ไม่มีการเชื่อมต่อภายนอก</p>
</div>
</div>
<script>
// ═══════════════════════════════════════════════════════════════════
// OFFLINE ENFORCEMENT
// ═══════════════════════════════════════════════════════════════════
(function() {
window.fetch = function() { return Promise.reject(new Error('Blocked: Offline only')); };
window.XMLHttpRequest = function() { throw new Error('Blocked: Offline only'); };
window.WebSocket = function() { throw new Error('Blocked: Offline only'); };
window.open = function() { return null; };
document.addEventListener('click', function(e) {
if (e.target.tagName === 'A' && e.target.href && e.target.href.startsWith('http')) {
e.preventDefault();
}
});
})();
// ═══════════════════════════════════════════════════════════════════
// PHYSICS CONSTANTS
// ═══════════════════════════════════════════════════════════════════
const CONSTANTS = {
ROOM_TEMP: 25.0,
OPTIMAL_TEMP: 50.0,
ALPHA_TEMP: 0.01,
EFFICIENCY_HEAT: 0.85,
HEAT_TRANSFER: 10.0,
SURFACE_AREA: 0.5,
THERMAL_CAPACITY: 500.0,
FLOW_COEFF: 10.0,
FLOW_RESISTANCE: 0.5,
BITS_PER_FLOW: 1000,
VAPORIZATION_THRESHOLD: 0.226,
MAX_ENERGY: 10000000
};
// ═══════════════════════════════════════════════════════════════════
// SIMULATION STATE
// ═══════════════════════════════════════════════════════════════════
let sim = {
running: false,
round: 0,
power: 0.01,
temperature: 25.0,
totalOps: 0,
totalBits: 0,
history: [],
maxHistory: 500,
startTime: null,
animFrame: null
};
// ═══════════════════════════════════════════════════════════════════
// PHYSICS ENGINE
// ═══════════════════════════════════════════════════════════════════
function thermalStep(power, temp, dt) {
const Q_in = CONSTANTS.EFFICIENCY_HEAT * power;
const Q_out = CONSTANTS.HEAT_TRANSFER * CONSTANTS.SURFACE_AREA * (temp - CONSTANTS.ROOM_TEMP);
const dT = (Q_in - Q_out) / CONSTANTS.THERMAL_CAPACITY * dt;
return Math.max(temp + dT, CONSTANTS.ROOM_TEMP);
}
function flowStep(power, temp, dt) {
const tempFactor = 1.0 / (1.0 + CONSTANTS.FLOW_RESISTANCE * (temp - CONSTANTS.ROOM_TEMP) / 100.0);
return CONSTANTS.FLOW_COEFF * power * tempFactor;
}
function mathActionStep(flow, temp) {
const eff = Math.exp(-CONSTANTS.ALPHA_TEMP * (temp - CONSTANTS.OPTIMAL_TEMP) ** 2);
return { efficiency: eff, operations: flow * eff, bits: flow * eff * CONSTANTS.BITS_PER_FLOW };
}
function decodeEnergy(energy) {
const normalized = Math.min(energy / CONSTANTS.MAX_ENERGY, 1.0);
return {
normalized,
state: normalized >= CONSTANTS.VAPORIZATION_THRESHOLD ? 'ไอ' : 'ของเหลว',
binaryBits: Math.floor(energy)
};
}
// ═══════════════════════════════════════════════════════════════════
// SIMULATION LOOP
// ═══════════════════════════════════════════════════════════════════
function simulationTick() {
if (!sim.running) return;
const speed = parseInt(document.getElementById('speedSelect').value);
const roundsPerTick = speed;
for (let i = 0; i < roundsPerTick; i++) {
sim.round++;
// Physics
sim.temperature = thermalStep(sim.power, sim.temperature, 1.0);
const flow = flowStep(sim.power, sim.temperature, 1.0);
const action = mathActionStep(flow, sim.temperature);
sim.totalOps += action.operations;
sim.totalBits += action.bits;
// Increase power
const increment = parseFloat(document.getElementById('incrementInput').value);
sim.power = Math.min(sim.power + increment, 100.0);
// Record history
if (sim.round % Math.max(1, Math.floor(roundsPerTick / 10)) === 0) {
sim.history.push({
round: sim.round,
temp: sim.temperature,
eff: action.efficiency,
flow: flow,
ops: sim.totalOps,
bits: sim.totalBits,
power: sim.power
});
if (sim.history.length > sim.maxHistory) sim.history.shift();
}
}
updateUI();
drawChart();
updateWaterViz();
updateLogicGates();
sim.animFrame = requestAnimationFrame(simulationTick);
}
// ═══════════════════════════════════════════════════════════════════
// UI UPDATE
// ═══════════════════════════════════════════════════════════════════
function updateUI() {
const action = mathActionStep(flowStep(sim.power, sim.temperature, 1.0), sim.temperature);
const code = decodeEnergy(sim.power);
document.getElementById('roundDisplay').textContent = sim.round.toLocaleString();
document.getElementById('tempValue').textContent = sim.temperature.toFixed(1) + '°C';
document.getElementById('powerValue').textContent = sim.power.toFixed(4) + ' W';
document.getElementById('flowValue').textContent = flowStep(sim.power, sim.temperature, 1.0).toFixed(4);
document.getElementById('effValue').textContent = action.efficiency.toFixed(4);
document.getElementById('opsValue').textContent = Math.floor(sim.totalOps).toLocaleString();
document.getElementById('bitsValue').textContent = Math.floor(sim.totalBits).toLocaleString();
document.getElementById('waterState').textContent = code.state;
// Bars
document.getElementById('tempBar').style.width = Math.min(sim.temperature / 100 * 100, 100) + '%';
document.getElementById('powerBar').style.width = Math.min(sim.power / 100 * 100, 100) + '%';
document.getElementById('flowBar').style.width = Math.min(flowStep(sim.power, sim.temperature, 1.0) * 100, 100) + '%';
document.getElementById('effBar').style.width = (action.efficiency * 100) + '%';
document.getElementById('opsBar').style.width = Math.min(sim.totalOps / 1000000 * 100, 100) + '%';
document.getElementById('bitsBar').style.width = Math.min(sim.totalBits / 1000000000 * 100, 100) + '%';
// Colors
const tempColor = sim.temperature > 70 ? 'var(--heat)' : sim.temperature > 55 ? '#ffaa00' : 'var(--heat)';
document.getElementById('tempValue').style.color = tempColor;
// Status
const statusDot = document.getElementById('statusDot');
const statusText = document.getElementById('statusText');
if (sim.temperature > 70) {
statusDot.className = 'status-dot danger';
statusText.textContent = '⚠️ ร้อนเกิน — ประสิทธิภาพลด';
} else if (Math.abs(sim.temperature - 50) <= 5) {
statusDot.className = 'status-dot active';
statusText.textContent = '✅ อุณหภูมิเหมาะสม';
} else {
statusDot.className = 'status-dot warning';
statusText.textContent = '🔄 กำลังปรับอุณหภูมิ';
}
// Time
if (sim.startTime) {
const elapsed = Math.floor((Date.now() - sim.startTime) / 1000);
const min = Math.floor(elapsed / 60).toString().padStart(2, '0');
const sec = (elapsed % 60).toString().padStart(2, '0');
document.getElementById('timeDisplay').textContent = min + ':' + sec;
}
}
// ═══════════════════════════════════════════════════════════════════
// CHART DRAWING
// ═══════════════════════════════════════════════════════════════════
function drawChart() {
const canvas = document.getElementById('mainChart');
const ctx = canvas.getContext('2d');
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
const w = canvas.width;
const h = canvas.height;
const data = sim.history;
if (data.length < 2) return;
ctx.clearRect(0, 0, w, h);
// Grid
ctx.strokeStyle = 'rgba(0,212,255,0.1)';
ctx.lineWidth = 1;
for (let i = 0; i < 5; i++) {
const y = (h / 5) * i;
ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(w, y); ctx.stroke();
}
// Optimal temp line
const optY = h - (50 / 100) * h;
ctx.strokeStyle = 'rgba(0,255,136,0.3)';
ctx.setLineDash([5, 5]);
ctx.beginPath(); ctx.moveTo(0, optY); ctx.lineTo(w, optY); ctx.stroke();
ctx.setLineDash([]);
ctx.fillStyle = 'rgba(0,255,136,0.5)';
ctx.font = '10px sans-serif';
ctx.fillText('Optimal 50°C', 5, optY - 3);
// Temperature line
ctx.strokeStyle = '#ff0044';
ctx.lineWidth = 2;
ctx.beginPath();
for (let i = 0; i < data.length; i++) {
const x = (i / (data.length - 1)) * w;
const y = h - (Math.min(data[i].temp, 100) / 100) * h;
if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
}
ctx.stroke();
// Efficiency line
ctx.strokeStyle = '#ffaa00';
ctx.lineWidth = 2;
ctx.beginPath();
for (let i = 0; i < data.length; i++) {
const x = (i / (data.length - 1)) * w;
const y = h - data[i].eff * h;
if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
}
ctx.stroke();
// Legend
ctx.fillStyle = '#ff0044';
ctx.fillRect(w - 120, 10, 12, 3);
ctx.fillStyle = 'rgba(224,232,255,0.7)';
ctx.fillText('อุณหภูมิ', w - 104, 14);
ctx.fillStyle = '#ffaa00';
ctx.fillRect(w - 120, 25, 12, 3);
ctx.fillStyle = 'rgba(224,232,255,0.7)';
ctx.fillText('ประสิทธิภาพ', w - 104, 29);
}
// ═══════════════════════════════════════════════════════════════════
// WATER VISUALIZATION
// ═══════════════════════════════════════════════════════════════════
function updateWaterViz() {
const level = Math.max(10, 100 - (sim.temperature - 25) * 1.5);
document.getElementById('waterLevel').style.height = level + '%';
// Steam particles
const container = document.getElementById('steamParticles');
if (sim.temperature > 40 && Math.random() < (sim.temperature - 40) / 100) {
const steam = document.createElement('div');
steam.className = 'steam';
steam.style.left = Math.random() * 100 + '%';
steam.style.bottom = level + '%';
steam.style.animationDuration = (1 + Math.random() * 2) + 's';
container.appendChild(steam);
setTimeout(() => steam.remove(), 3000);
}
}
// ═══════════════════════════════════════════════════════════════════
// LOGIC GATES
// ═══════════════════════════════════════════════════════════════════
function updateLogicGates() {
const flow = flowStep(sim.power, sim.temperature, 1.0);
const threshold = 0.1;
const a = flow > threshold ? 1 : 0;
const b = (flow * 0.7) > threshold ? 1 : 0;
// AND
document.getElementById('andA').className = 'gate-input ' + (a ? 'on' : 'off');
document.getElementById('andA').textContent = a;
document.getElementById('andB').className = 'gate-input ' + (b ? 'on' : 'off');
document.getElementById('andB').textContent = b;
const andOut = (a && b) ? 1 : 0;
document.getElementById('andOut').className = 'gate-output ' + (andOut ? 'on' : 'off');
document.getElementById('andOut').textContent = andOut;
// OR
document.getElementById('orA').className = 'gate-input ' + (a ? 'on' : 'off');
document.getElementById('orA').textContent = a;
document.getElementById('orB').className = 'gate-input ' + (b ? 'on' : 'off');
document.getElementById('orB').textContent = b;
const orOut = (a || b) ? 1 : 0;
document.getElementById('orOut').className = 'gate-output ' + (orOut ? 'on' : 'off');
document.getElementById('orOut').textContent = orOut;
// NOT
document.getElementById('notA').className = 'gate-input ' + (a ? 'on' : 'off');
document.getElementById('notA').textContent = a;
const notOut = a ? 0 : 1;
document.getElementById('notOut').className = 'gate-output ' + (notOut ? 'on' : 'off');
document.getElementById('notOut').textContent = notOut;
// XOR
document.getElementById('xorA').className = 'gate-input ' + (a ? 'on' : 'off');
document.getElementById('xorA').textContent = a;
document.getElementById('xorB').className = 'gate-input ' + (b ? 'on' : 'off');
document.getElementById('xorB').textContent = b;
const xorOut = (a !== b) ? 1 : 0;
document.getElementById('xorOut').className = 'gate-output ' + (xorOut ? 'on' : 'off');
document.getElementById('xorOut').textContent = xorOut;
}
// ═══════════════════════════════════════════════════════════════════
// CONTROLS
// ═══════════════════════════════════════════════════════════════════
function startSimulation() {
if (sim.running) return;
sim.running = true;
sim.round = 0;
sim.power = parseFloat(document.getElementById('powerInput').value);
sim.temperature = CONSTANTS.ROOM_TEMP;
sim.totalOps = 0;
sim.totalBits = 0;
sim.history = [];
sim.startTime = Date.now();
document.getElementById('startBtn').disabled = true;
document.getElementById('stopBtn').disabled = false;
simulationTick();
}
function stopSimulation() {
sim.running = false;
if (sim.animFrame) cancelAnimationFrame(sim.animFrame);
document.getElementById('startBtn').disabled = false;
document.getElementById('stopBtn').disabled = true;
document.getElementById('statusText').textContent = '⏹ หยุดแล้ว';
document.getElementById('statusDot').className = 'status-dot';
}
// Init
updateUI();
</script>
</body>
</html>

Xet Storage Details

Size:
35.6 kB
·
Xet hash:
5475d2c5b1abd0eb6ce889093a69ca7e176ce940ab1a2cdc04f5216159a7f65b

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.