mirror of
https://github.com/Retropex/custom-ocean.xyz-dashboard.git
synced 2025-05-12 11:10:44 +02:00
564 lines
25 KiB
HTML
564 lines
25 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Ocean.xyz Pool Miner - Initializing...</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
|
|
<style>
|
|
/* Base Styles with a subtle radial background for extra depth */
|
|
body {
|
|
background: linear-gradient(135deg, #121212, #000000);
|
|
color: #f7931a;
|
|
font-family: 'VT323', monospace;
|
|
font-size: 20px;
|
|
line-height: 1.4;
|
|
margin: 0;
|
|
padding: 10px;
|
|
overflow-x: hidden;
|
|
text-shadow: 0 0 5px rgba(247, 147, 26, 0.4);
|
|
height: calc(100vh - 100px);
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
/* CRT Screen Effect */
|
|
body::before {
|
|
content: " ";
|
|
display: block;
|
|
position: fixed;
|
|
top: 0; left: 0; bottom: 0; right: 0;
|
|
background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.1) 50%),
|
|
linear-gradient(90deg, rgba(255, 0, 0, 0.03), rgba(0, 255, 0, 0.02), rgba(0, 0, 255, 0.03));
|
|
background-size: 100% 2px, 3px 100%;
|
|
pointer-events: none;
|
|
z-index: 2;
|
|
opacity: 0.15;
|
|
}
|
|
/* Flicker Animation */
|
|
@keyframes flicker {
|
|
0% { opacity: 0.97; }
|
|
5% { opacity: 0.95; }
|
|
10% { opacity: 0.97; }
|
|
15% { opacity: 0.94; }
|
|
20% { opacity: 0.98; }
|
|
50% { opacity: 0.95; }
|
|
80% { opacity: 0.96; }
|
|
90% { opacity: 0.94; }
|
|
100% { opacity: 0.98; }
|
|
}
|
|
/* Terminal Window with scrolling enabled */
|
|
#terminal {
|
|
width: 100%;
|
|
max-width: 900px;
|
|
margin: 0 auto;
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
animation: flicker 4s infinite;
|
|
height: 400px;
|
|
overflow-y: auto;
|
|
position: relative;
|
|
flex: 1;
|
|
}
|
|
#terminal-content {
|
|
position: absolute;
|
|
bottom: 0;
|
|
width: 100%;
|
|
}
|
|
.cursor {
|
|
display: inline-block;
|
|
width: 10px;
|
|
height: 16px;
|
|
background-color: #f7931a;
|
|
animation: blink 1s step-end infinite;
|
|
vertical-align: middle;
|
|
box-shadow: 0 0 5px rgba(247, 147, 26, 0.8);
|
|
}
|
|
@keyframes blink {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0; }
|
|
}
|
|
/* Neon-inspired color classes */
|
|
.green {
|
|
color: #39ff14 !important;
|
|
text-shadow: 0 0 10px #39ff14, 0 0 20px #39ff14;
|
|
}
|
|
.blue {
|
|
color: #00dfff !important;
|
|
text-shadow: 0 0 10px #00dfff, 0 0 20px #00dfff;
|
|
}
|
|
.yellow {
|
|
color: #ffd700 !important;
|
|
text-shadow: 0 0 8px #ffd700, 0 0 16px #ffd700;
|
|
}
|
|
.white {
|
|
color: #ffffff !important;
|
|
text-shadow: 0 0 8px #ffffff, 0 0 16px #ffffff;
|
|
}
|
|
.red {
|
|
color: #ff2d2d !important;
|
|
text-shadow: 0 0 10px #ff2d2d, 0 0 20px #ff2d2d;
|
|
}
|
|
.magenta {
|
|
color: #ff2d95 !important;
|
|
text-shadow: 0 0 10px #ff2d95, 0 0 20px #ff2d95;
|
|
}
|
|
/* Bitcoin Logo styling with extra neon border */
|
|
#bitcoin-logo {
|
|
display: block;
|
|
visibility: hidden;
|
|
text-align: center;
|
|
margin: 10px auto;
|
|
font-size: 10px;
|
|
line-height: 1;
|
|
color: #f7931a;
|
|
text-shadow: 0 0 10px rgba(247, 147, 26, 0.8);
|
|
white-space: pre;
|
|
width: 260px;
|
|
padding: 10px;
|
|
border: 2px solid #f7931a;
|
|
background-color: #0a0a0a;
|
|
box-shadow: 0 0 15px rgba(247, 147, 26, 0.5);
|
|
font-family: monospace;
|
|
opacity: 0;
|
|
transition: opacity 1s ease;
|
|
}
|
|
/* Skip Button */
|
|
#skip-button {
|
|
position: fixed;
|
|
bottom: 20px;
|
|
right: 20px;
|
|
background-color: #f7931a;
|
|
color: #000;
|
|
border: none;
|
|
padding: 10px 15px;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
font-family: 'VT323', monospace;
|
|
font-size: 16px;
|
|
box-shadow: 0 0 8px rgba(247, 147, 26, 0.5);
|
|
transition: all 0.2s ease;
|
|
}
|
|
#skip-button:hover {
|
|
background-color: #ffa32e;
|
|
box-shadow: 0 0 12px rgba(247, 147, 26, 0.7);
|
|
}
|
|
/* Prompt Styling */
|
|
#prompt-container {
|
|
display: none;
|
|
white-space: nowrap;
|
|
}
|
|
#prompt-text {
|
|
color: #f7931a;
|
|
margin-right: 5px;
|
|
text-shadow: 0 0 5px rgba(247, 147, 26, 0.8);
|
|
display: inline;
|
|
}
|
|
#user-input {
|
|
background: transparent;
|
|
border: none;
|
|
color: #f7931a;
|
|
font-family: 'VT323', monospace;
|
|
font-size: 20px;
|
|
caret-color: transparent;
|
|
outline: none;
|
|
width: 20px;
|
|
padding: 0;
|
|
margin: 0;
|
|
text-shadow: 0 0 5px rgba(247, 147, 26, 0.8);
|
|
display: inline-block;
|
|
vertical-align: top;
|
|
}
|
|
.prompt-cursor {
|
|
display: inline-block;
|
|
width: 10px;
|
|
height: 16px;
|
|
background-color: #f7931a;
|
|
animation: blink 1s step-end infinite;
|
|
vertical-align: middle;
|
|
box-shadow: 0 0 5px rgba(247, 147, 26, 0.8);
|
|
position: relative;
|
|
top: 1px;
|
|
margin-left: -2px;
|
|
}
|
|
/* Mobile Responsiveness */
|
|
@media (max-width: 600px) {
|
|
body { font-size: 14px; padding: 10px; }
|
|
#terminal { margin: 0; }
|
|
}
|
|
/* Loading and Debug Info */
|
|
#loading-message {
|
|
text-align: center;
|
|
margin-bottom: 10px;
|
|
text-shadow: 0 0 5px rgba(247, 147, 26, 0.8);
|
|
}
|
|
#debug-info {
|
|
position: fixed;
|
|
bottom: 10px;
|
|
left: 10px;
|
|
color: #666;
|
|
font-size: 12px;
|
|
z-index: 100;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<button id="skip-button">SKIP</button>
|
|
<div id="debug-info"></div>
|
|
<div id="loading-message">Loading mining data...</div>
|
|
<div id="bitcoin-logo">
|
|
██████╗ ████████╗ ██████╗ ██████╗ ███████╗
|
|
██╔══██╗╚══██╔══╝██╔════╝ ██╔═══██╗██╔════╝
|
|
██████╔╝ ██║ ██║ ██║ ██║███████╗
|
|
██╔══██╗ ██║ ██║ ██║ ██║╚════██║
|
|
██████╔╝ ██║ ╚██████╗ ╚██████╔╝███████║
|
|
╚═════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝
|
|
v.21
|
|
</div>
|
|
<div id="terminal">
|
|
<div id="terminal-content">
|
|
<span id="output"></span><span class="cursor"></span>
|
|
<span id="prompt-container">
|
|
<span id="prompt-text">Initialize mining dashboard? [Y/N]:
|
|
<span class="prompt-cursor"></span>
|
|
<input type="text" id="user-input" maxlength="1" autocomplete="off" spellcheck="false" autofocus style="font-size: 16px; font-weight: bold;">
|
|
</span>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Debug logging
|
|
function updateDebug(message) {
|
|
document.getElementById('debug-info').textContent = message;
|
|
console.log(message);
|
|
}
|
|
|
|
// Format numbers with commas
|
|
function numberWithCommas(x) {
|
|
if (x == null) return "N/A";
|
|
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
}
|
|
|
|
// Global variables
|
|
let bootMessages = [];
|
|
let dashboardData = null;
|
|
let outputElement = document.getElementById('output');
|
|
const bitcoinLogo = document.getElementById('bitcoin-logo');
|
|
const skipButton = document.getElementById('skip-button');
|
|
const loadingMessage = document.getElementById('loading-message');
|
|
const promptContainer = document.getElementById('prompt-container');
|
|
const userInput = document.getElementById('user-input');
|
|
let messageIndex = 0;
|
|
let timeoutId = null;
|
|
let waitingForUserInput = false;
|
|
let bootComplete = false;
|
|
|
|
// Safety timeout: redirect after 60 seconds if boot not complete
|
|
window.addEventListener('load', function() {
|
|
setTimeout(function() {
|
|
if (!bootComplete && !waitingForUserInput) {
|
|
console.warn("Safety timeout reached - redirecting to dashboard");
|
|
redirectToDashboard();
|
|
}
|
|
}, 60000);
|
|
});
|
|
|
|
// Redirect to dashboard
|
|
function redirectToDashboard() {
|
|
updateDebug("Boot sequence complete, redirecting...");
|
|
const baseUrl = window.location.origin;
|
|
window.location.href = baseUrl + "/dashboard";
|
|
}
|
|
|
|
// Fade in Bitcoin logo
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
setTimeout(function() {
|
|
bitcoinLogo.style.visibility = 'visible';
|
|
setTimeout(function() {
|
|
bitcoinLogo.style.opacity = '1';
|
|
}, 100);
|
|
}, 500);
|
|
});
|
|
|
|
// Post-confirmation messages with retro typing effect
|
|
function showPostConfirmationMessages(response) {
|
|
try {
|
|
outputElement = document.getElementById('output');
|
|
if (!outputElement) {
|
|
setTimeout(redirectToDashboard, 1000);
|
|
return;
|
|
}
|
|
const yesMessages = [
|
|
{ text: "INITIALIZING DASHBOARD...\n", html: true, delay: 400 },
|
|
{ text: "Connecting to real-time data feeds...", speed: 20, delay: 300 },
|
|
{ text: "<span class='green'>CONNECTED</span>\n", html: true, delay: 400 },
|
|
{ text: "Loading blockchain validators...", speed: 15, delay: 300 },
|
|
{ text: "<span class='green'>COMPLETE</span>\n", html: true, delay: 400 },
|
|
{ text: "Starting TX fee calculation module...", speed: 15, delay: 400 },
|
|
{ text: "<span class='green'>ACTIVE</span>\n", html: true, delay: 400 },
|
|
{ text: "Verifying BTC-USD exchange rates...", speed: 15, delay: 200 },
|
|
{ text: "<span class='green'>CURRENT RATE CONFIRMED</span>\n", html: true, delay: 300 },
|
|
{ text: "Calibrating hashrate telemetry...", speed: 15, delay: 200 },
|
|
{ text: "<span class='green'>CALIBRATED</span>\n", html: true, delay: 200 },
|
|
{ text: "Loading historical mining data: [", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>████</span>", html: true, delay: 100 },
|
|
{ text: "<span class='green'>████████</span>", html: true, delay: 100 },
|
|
{ text: "<span class='green'>███████</span>", html: true, delay: 100 },
|
|
{ text: "<span class='green'>████</span>", html: true, delay: 100 },
|
|
{ text: "<span class='green'>██</span>", html: true, delay: 100 },
|
|
{ text: "<span class='green'>█</span>", html: true, delay: 100 },
|
|
{ text: "] <span class='green'>COMPLETE</span>\n", html: true, delay: 400 },
|
|
{ text: "Block reward calculation initialized...", speed: 15, delay: 300 },
|
|
{ text: "<span class='yellow'>HALVING SCHEDULE VERIFIED</span>\n", html: true, delay: 400 },
|
|
{ text: "Satoshi per kWh optimizer: <span class='green'>ENGAGED</span>\n", html: true, delay: 500 },
|
|
{ text: "Launching mining dashboard in 3...", speed: 80, delay: 1000 },
|
|
{ text: " 2...", speed: 80, delay: 1000 },
|
|
{ text: " 1...\n", speed: 80, delay: 1000 },
|
|
{ text: "<span class='green'>STACK SATS MODE: ACTIVATED</span>\n", html: true, delay: 500 }
|
|
];
|
|
const noMessages = [
|
|
{ text: "DASHBOARD INITIALIZATION ABORTED.\n", html: true, delay: 400 },
|
|
{ text: "Mining processes will continue in background.\n", speed: 30, delay: 500 },
|
|
{ text: "Attempting emergency recovery...\n", speed: 30, delay: 1000 },
|
|
{ text: "Bypassing authentication checks...", speed: 20, delay: 300 },
|
|
{ text: "<span class='green'>SUCCESS</span>\n", html: true, delay: 500 },
|
|
{ text: "Initializing fallback ASIC control interface...", speed: 20, delay: 300 },
|
|
{ text: "<span class='green'>ACTIVE</span>\n", html: true, delay: 400 },
|
|
{ text: "<span class='green'>RECOVERY SUCCESSFUL!</span>\n", html: true, delay: 400 },
|
|
{ text: "Loading minimal dashboard in safe mode: [", speed: 15, delay: 100 },
|
|
{ text: "<span class='yellow'>████████</span>", html: true, delay: 100 },
|
|
{ text: "<span class='yellow'>████████</span>", html: true, delay: 100 },
|
|
{ text: "<span class='yellow'>████████</span>", html: true, delay: 100 },
|
|
{ text: "] <span class='white'>READY</span>\n", html: true, delay: 400 },
|
|
{ text: "\nNOTE: REDUCED FUNCTIONALITY IN SAFE MODE\n", html: true, delay: 500 },
|
|
{ text: "Launching minimal dashboard in 3...", speed: 80, delay: 1000 },
|
|
{ text: " 2...", speed: 80, delay: 1000 },
|
|
{ text: " 1...\n", speed: 80, delay: 1000 },
|
|
{ text: "<span class='green'>BITCOIN MINING CONTINUES REGARDLESS! ;)</span>\n", html: true, delay: 500 }
|
|
];
|
|
const messages = response === 'Y' ? yesMessages : noMessages;
|
|
let msgIndex = 0;
|
|
function processNextMessage() {
|
|
if (msgIndex >= messages.length) {
|
|
bootComplete = true;
|
|
setTimeout(redirectToDashboard, 500);
|
|
return;
|
|
}
|
|
const currentMessage = messages[msgIndex];
|
|
if (currentMessage.html) {
|
|
outputElement.innerHTML += currentMessage.text;
|
|
msgIndex++;
|
|
setTimeout(processNextMessage, currentMessage.delay || 300);
|
|
} else {
|
|
let charIndex = 0;
|
|
function typeCharacter() {
|
|
if (charIndex < currentMessage.text.length) {
|
|
outputElement.innerHTML += currentMessage.text.charAt(charIndex);
|
|
charIndex++;
|
|
setTimeout(typeCharacter, currentMessage.speed || 20);
|
|
} else {
|
|
msgIndex++;
|
|
setTimeout(processNextMessage, currentMessage.delay || 300);
|
|
}
|
|
}
|
|
typeCharacter();
|
|
}
|
|
}
|
|
setTimeout(processNextMessage, 500);
|
|
} catch(err) {
|
|
setTimeout(redirectToDashboard, 1000);
|
|
}
|
|
}
|
|
|
|
// Handle Y/N prompt input
|
|
userInput.addEventListener('keydown', function(e) {
|
|
if (waitingForUserInput && e.key === 'Enter') {
|
|
e.preventDefault();
|
|
const response = userInput.value.toUpperCase();
|
|
promptContainer.style.display = 'none';
|
|
waitingForUserInput = false;
|
|
outputElement.innerHTML += response + "\n";
|
|
userInput.value = '';
|
|
showPostConfirmationMessages(response);
|
|
}
|
|
});
|
|
|
|
// Show the prompt
|
|
function showUserPrompt() {
|
|
promptContainer.style.display = 'inline';
|
|
waitingForUserInput = true;
|
|
document.querySelector('.cursor').style.display = 'none';
|
|
userInput.focus();
|
|
}
|
|
|
|
// We disable truncation so all text is visible.
|
|
function manageTerminalContent() { }
|
|
|
|
// Retro typing effect for boot messages
|
|
function typeBootMessages() {
|
|
try {
|
|
if (!outputElement) {
|
|
outputElement = document.getElementById('output');
|
|
if (!outputElement) {
|
|
skipButton.click();
|
|
return;
|
|
}
|
|
}
|
|
console.log("Processing boot message index:", messageIndex);
|
|
if (messageIndex >= bootMessages.length) { return; }
|
|
const currentMessage = bootMessages[messageIndex];
|
|
if (currentMessage.showPrompt) {
|
|
messageIndex++;
|
|
showUserPrompt();
|
|
return;
|
|
}
|
|
if (currentMessage.html) {
|
|
outputElement.innerHTML += currentMessage.text;
|
|
messageIndex++;
|
|
timeoutId = setTimeout(typeBootMessages, currentMessage.delay || 300);
|
|
return;
|
|
}
|
|
if (!currentMessage.typingIndex) { currentMessage.typingIndex = 0; }
|
|
if (currentMessage.typingIndex < currentMessage.text.length) {
|
|
outputElement.innerHTML += currentMessage.text.charAt(currentMessage.typingIndex);
|
|
currentMessage.typingIndex++;
|
|
timeoutId = setTimeout(typeBootMessages, currentMessage.speed || 15);
|
|
} else {
|
|
messageIndex++;
|
|
timeoutId = setTimeout(typeBootMessages, currentMessage.delay || 300);
|
|
}
|
|
} catch(err) {
|
|
messageIndex++;
|
|
timeoutId = setTimeout(typeBootMessages, 500);
|
|
}
|
|
}
|
|
|
|
// Skip button: immediately redirect
|
|
skipButton.addEventListener('click', function() {
|
|
clearTimeout(timeoutId);
|
|
redirectToDashboard();
|
|
});
|
|
|
|
// Start the typing animation (hides loading message)
|
|
function startTyping() {
|
|
loadingMessage.style.display = 'none';
|
|
setTimeout(typeBootMessages, 150);
|
|
}
|
|
|
|
// Fallback messages (used immediately)
|
|
function setupFallbackMessages() {
|
|
bootMessages = [
|
|
{ text: "BITCOIN OS - MINING SYSTEM - v21.000.000\n", speed: 25, delay: 300 },
|
|
{ text: "Copyright (c) 2009-2025 Satoshi Nakamoto\n", speed: 20, delay: 250 },
|
|
{ text: "All rights reserved.\n\n", speed: 25, delay: 300 },
|
|
{ text: "INITIALIZING SYSTEM...\n", speed: 25, delay: 300 },
|
|
{ text: "HARDWARE: ", speed: 25, delay: 100 },
|
|
{ text: "<span class='green'>OK</span>\n", html: true, delay: 300 },
|
|
{ text: "NETWORK: ", speed: 25, delay: 100 },
|
|
{ text: "<span class='green'>OK</span>\n", html: true, delay: 300 },
|
|
{ text: "BLOCKCHAIN: ", speed: 25, delay: 100 },
|
|
{ text: "<span class='green'>SYNCHRONIZED</span>\n", html: true, delay: 300 },
|
|
{ text: "MINING RIG: ", speed: 25, delay: 100 },
|
|
{ text: "<span class='green'>ONLINE</span>\n", html: true, delay: 300 },
|
|
{ text: "\nSystem ready. ", speed: 25, delay: 400 },
|
|
{ showPrompt: true, delay: 0 }
|
|
];
|
|
startTyping();
|
|
}
|
|
|
|
// Initialize with fallback, then try live data
|
|
setupFallbackMessages();
|
|
updateDebug("Fetching dashboard data...");
|
|
fetch('/api/metrics')
|
|
.then(response => {
|
|
if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); }
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
dashboardData = data;
|
|
clearTimeout(timeoutId);
|
|
messageIndex = 0;
|
|
outputElement = document.getElementById('output');
|
|
outputElement.innerHTML = "";
|
|
bootMessages = [
|
|
{ text: "BITCOIN OS - MINING CONTROL SYSTEM - v21.000.000\n", speed: 25, delay: 300 },
|
|
{ text: "Copyright (c) 2009-2025 Satoshi Nakamoto & The Bitcoin Core Developers\n", speed: 20, delay: 250 },
|
|
{ text: "All rights reserved.\n\n", speed: 25, delay: 300 },
|
|
{ text: "INITIALIZING SHA-256 MINING SUBSYSTEMS...\n", speed: 25, delay: 400 },
|
|
{ text: "ASIC CLUSTER STATUS: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>ONLINE</span>\n", html: true, delay: 300 },
|
|
{ text: "CHIP TEMPERATURE: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>62°C - WITHIN OPTIMAL RANGE</span>\n", html: true, delay: 300 },
|
|
{ text: "COOLING SYSTEMS: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>OPERATIONAL</span>\n", html: true, delay: 300 },
|
|
{ text: "POWER SUPPLY HEALTH: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>98.7% - NOMINAL</span>\n", html: true, delay: 300 },
|
|
{ text: "\nCONNECTING TO BITCOIN NETWORK...\n", speed: 20, delay: 400 },
|
|
{ text: "BLOCKCHAIN SYNC STATUS: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>SYNCHRONIZED</span>\n", html: true, delay: 300 },
|
|
{ text: "DIFFICULTY ADJUSTMENT: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='yellow'>CALCULATED</span>\n", html: true, delay: 300 },
|
|
{ text: "MEMPOOL MONITORING: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>ACTIVE</span>\n", html: true, delay: 300 },
|
|
{ text: "\nESTABLISHING POOL CONNECTION...\n", speed: 20, delay: 300 },
|
|
{ text: "CONNECTING TO OCEAN.XYZ...\n", speed: 20, delay: 300 },
|
|
{ text: "STRATUM PROTOCOL v2: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>INITIALIZED</span>\n", html: true, delay: 300 },
|
|
{ text: "POOL HASHRATE: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>VERIFIED</span>\n", html: true, delay: 300 },
|
|
{ text: "WORKER AUTHENTICATION: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>SUCCESSFUL</span>\n", html: true, delay: 300 },
|
|
{ text: "\nINITIALIZING METRICS COLLECTORS...\n", speed: 20, delay: 300 },
|
|
{ text: "HASHRATE MONITOR: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>ACTIVE</span>\n", html: true, delay: 300 },
|
|
{ text: "EARNINGS CALCULATOR: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>CALIBRATED</span>\n", html: true, delay: 300 },
|
|
{ text: "POWER USAGE TRACKING: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>ENABLED</span>\n", html: true, delay: 300 },
|
|
{ text: "PAYOUT THRESHOLD MONITOR: ", speed: 15, delay: 100 },
|
|
{ text: "<span class='green'>ACTIVE</span>\n", html: true, delay: 300 },
|
|
{ text: "\nCURRENT NETWORK METRICS DETECTED\n", speed: 20, delay: 300 },
|
|
{ text: "BTC PRICE: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='yellow'>$" + numberWithCommas((data.btc_price || 0).toFixed(2)) + "</span>\n", html: true, delay: 300 },
|
|
{ text: "NETWORK DIFFICULTY: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='white'>" + numberWithCommas(Math.round(data.difficulty || 0)) + "</span>\n", html: true, delay: 300 },
|
|
{ text: "NETWORK HASHRATE: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='white'>" + (data.network_hashrate ? numberWithCommas(Math.round(data.network_hashrate)) : "N/A") + " EH/s</span>\n", html: true, delay: 300 },
|
|
{ text: "BLOCK HEIGHT: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='white'>" + numberWithCommas(data.block_number || "N/A") + "</span>\n", html: true, delay: 300 },
|
|
{ text: "\nMINER PERFORMANCE DATA\n", speed: 20, delay: 300 },
|
|
{ text: "CURRENT HASHRATE: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='yellow'>" + (data.hashrate_60sec || "N/A") + " " + (data.hashrate_60sec_unit || "TH/s") + "</span>\n", html: true, delay: 300 },
|
|
{ text: "24HR AVG HASHRATE: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='yellow'>" + (data.hashrate_24hr || "N/A") + " " + (data.hashrate_24hr_unit || "TH/s") + "</span>\n", html: true, delay: 300 },
|
|
{ text: "ACTIVE WORKERS: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='yellow'>" + (data.workers_hashing || "0") + "</span>\n", html: true, delay: 300 },
|
|
{ text: "\nFINANCIAL CALCULATIONS\n", speed: 20, delay: 300 },
|
|
{ text: "DAILY MINING REVENUE: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='green'>$" + numberWithCommas((data.daily_revenue || 0).toFixed(2)) + "</span>\n", html: true, delay: 300 },
|
|
{ text: "DAILY POWER COST: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='red'>$" + numberWithCommas((data.daily_power_cost || 0).toFixed(2)) + "</span>\n", html: true, delay: 300 },
|
|
{ text: "DAILY PROFIT: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='green'>$" + numberWithCommas((data.daily_profit_usd || 0).toFixed(2)) + "</span>\n", html: true, delay: 300 },
|
|
{ text: "PROJECTED MONTHLY PROFIT: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='green'>$" + numberWithCommas((data.monthly_profit_usd || 0).toFixed(2)) + "</span>\n", html: true, delay: 300 },
|
|
{ text: "DAILY SATOSHI YIELD: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='yellow'>" + numberWithCommas(data.daily_mined_sats || 0) + " sats</span>\n", html: true, delay: 300 },
|
|
{ text: "UNPAID EARNINGS: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='green'>" + (data.unpaid_earnings || "0") + " BTC</span>\n", html: true, delay: 300 },
|
|
{ text: "ESTIMATED TIME TO PAYOUT: ", speed: 20, delay: 100 },
|
|
{ text: "<span class='yellow'>" + (data.est_time_to_payout || "Unknown") + "</span>\n", html: true, delay: 300 },
|
|
{ text: "\n", speed: 25, delay: 100 },
|
|
{ text: "<span class='green'>ALL MINING PROCESSES OPERATIONAL</span>\n", html: true, delay: 400 },
|
|
{ text: "\nInitialize mining dashboard? ", speed: 25, delay: 400 },
|
|
{ showPrompt: true, delay: 0 }
|
|
];
|
|
startTyping();
|
|
})
|
|
.catch(error => {
|
|
updateDebug(`Error fetching dashboard data: ${error.message}`);
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|