LLM-test/test/code/1/deepseel-cc/js/terminal.js

509 lines
14 KiB
JavaScript

/* ==========================================================================
SYSTEM AWAKENING - Terminal Module
Simulated command-line interface with automatic log generation
========================================================================== */
import {
ANIMATION,
TERMINAL_LOGS,
COLORS,
formatTimestamp,
getRandomValue
} from './config.js';
/**
* Terminal Class
* Manages the simulated terminal interface and log generation
*/
export class Terminal {
/**
* Create a new terminal instance
* @param {HTMLElement} container - Terminal container element
*/
constructor(container) {
this.container = container;
this.outputElement = container.querySelector('.terminal-output');
this.inputElement = container.querySelector('.terminal-input');
this.cursorElement = container.querySelector('.terminal-input .cursor');
// Log management
this.logs = [...TERMINAL_LOGS];
this.currentLogIndex = 0;
this.displayedLogs = [];
// Animation state
this.logInterval = null;
this.isAutoScrolling = true;
this.scrollAnimationId = null;
this.lastLogTime = 0;
// Interactive features
this.isInteractive = false;
this.commandHistory = [];
this.historyIndex = -1;
this.currentCommand = '';
// Initialize
this.init();
}
/**
* Initialize the terminal
*/
init() {
// Set up initial logs
this.addInitialLogs();
// Start automatic log generation
this.startAutoLogs();
// Bind interactive events
this.bindEvents();
// Start cursor animation
this.startCursorAnimation();
console.log('Terminal initialized');
}
/**
* Add initial log entries
*/
addInitialLogs() {
// Clear existing logs (keeping the placeholder ones from HTML)
const placeholderLogs = this.outputElement.querySelectorAll('.log-line');
placeholderLogs.forEach(log => log.remove());
// Add 5 initial logs
for (let i = 0; i < 5; i++) {
this.addLog();
}
}
/**
* Start automatic log generation
*/
startAutoLogs() {
// Clear any existing interval
if (this.logInterval) {
clearInterval(this.logInterval);
}
// Start new interval with random variation
this.logInterval = setInterval(() => {
this.addLog();
// Occasionally add multiple logs at once
if (Math.random() > 0.7) {
setTimeout(() => this.addLog(), getRandomValue(300, 800));
}
// Occasionally simulate system events
if (Math.random() > 0.9) {
this.simulateSystemEvent();
}
}, ANIMATION.LOG_INTERVAL);
}
/**
* Add a new log entry
* @param {string} customMessage - Optional custom message
*/
addLog(customMessage = null) {
// Get message (either custom or from rotation)
const message = customMessage || this.getNextLogMessage();
// Create log element
const logElement = document.createElement('div');
logElement.className = 'log-line';
// Format timestamp and message
const timestamp = formatTimestamp();
logElement.innerHTML = `<span class="timestamp">${timestamp}</span> ${message}`;
// Add to output
this.outputElement.appendChild(logElement);
// Limit total displayed logs (performance)
this.limitDisplayedLogs();
// Auto-scroll to bottom
if (this.isAutoScrolling) {
this.scrollToBottom();
}
// Store reference
this.displayedLogs.push({
element: logElement,
timestamp: timestamp,
message: message,
time: Date.now()
});
this.lastLogTime = Date.now();
}
/**
* Get the next log message from the rotation
* @returns {string} Next log message
*/
getNextLogMessage() {
// Get next message in rotation
const message = this.logs[this.currentLogIndex];
// Move to next message, loop back to start
this.currentLogIndex = (this.currentLogIndex + 1) % this.logs.length;
return message;
}
/**
* Limit the number of displayed logs for performance
*/
limitDisplayedLogs() {
const maxLogs = 50;
while (this.outputElement.children.length > maxLogs) {
this.outputElement.removeChild(this.outputElement.firstChild);
this.displayedLogs.shift();
}
}
/**
* Simulate a system event or alert
*/
simulateSystemEvent() {
const events = [
"SYSTEM ALERT: Quantum decoherence detected",
"WARNING: Neural pathway saturation at 87%",
"INFO: Temporal synchronization drift: +0.5ms",
"NOTICE: Data sanctity verification complete",
"ERROR: Process quantum_entanglement terminated unexpectedly",
"SUCCESS: Consciousness fragment integration complete"
];
const event = events[Math.floor(Math.random() * events.length)];
this.addLog(event);
// Add visual feedback for alerts
if (event.includes('ALERT') || event.includes('WARNING') || event.includes('ERROR')) {
this.flashTerminal();
}
}
/**
* Flash the terminal for alerts
*/
flashTerminal() {
// Add flash effect
this.container.style.transition = 'box-shadow 0.3s ease';
this.container.style.boxShadow = `0 0 40px ${COLORS.ACCENT}`;
// Reset after delay
setTimeout(() => {
this.container.style.boxShadow = '';
}, 500);
}
/**
* Smooth scroll to bottom of terminal
*/
scrollToBottom() {
if (this.scrollAnimationId) {
cancelAnimationFrame(this.scrollAnimationId);
}
const targetScroll = this.outputElement.scrollHeight - this.outputElement.clientHeight;
const currentScroll = this.outputElement.scrollTop;
const distance = targetScroll - currentScroll;
if (Math.abs(distance) < 1) {
this.outputElement.scrollTop = targetScroll;
return;
}
// Smooth scrolling with easing
const easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);
const duration = 300; // milliseconds
let startTime = null;
const animateScroll = (timestamp) => {
if (!startTime) startTime = timestamp;
const elapsed = timestamp - startTime;
const progress = Math.min(elapsed / duration, 1);
const easedProgress = easeOutCubic(progress);
const newScroll = currentScroll + distance * easedProgress;
this.outputElement.scrollTop = newScroll;
if (progress < 1) {
this.scrollAnimationId = requestAnimationFrame(animateScroll);
}
};
this.scrollAnimationId = requestAnimationFrame(animateScroll);
}
/**
* Start cursor blinking animation
*/
startCursorAnimation() {
if (!this.cursorElement) return;
let isVisible = true;
const blink = () => {
isVisible = !isVisible;
this.cursorElement.style.opacity = isVisible ? '1' : '0';
};
// Blink every 700ms
setInterval(blink, 700);
}
/**
* Bind event listeners for interactivity
*/
bindEvents() {
// Tab switching
const tabs = this.container.querySelectorAll('.tab');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
this.switchTab(tab);
});
});
// Terminal controls (minimize/maximize/close)
const controls = this.container.querySelectorAll('.control-btn');
controls.forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
this.handleControlClick(btn);
});
});
// Auto-scroll toggle on user scroll
this.outputElement.addEventListener('scroll', () => {
const isAtBottom =
this.outputElement.scrollHeight -
this.outputElement.scrollTop -
this.outputElement.clientHeight < 10;
this.isAutoScrolling = isAtBottom;
});
// Keyboard shortcuts for advanced users
document.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.key === 'l') {
e.preventDefault();
this.clear();
}
});
}
/**
* Switch terminal tabs
* @param {HTMLElement} tab - Clicked tab element
*/
switchTab(tab) {
// Remove active class from all tabs
const tabs = this.container.querySelectorAll('.tab');
tabs.forEach(t => t.classList.remove('active'));
// Add active class to clicked tab
tab.classList.add('active');
// Simulate tab-specific content
this.simulateTabContent(tab);
}
/**
* Simulate content for different tabs
* @param {HTMLElement} tab - Active tab element
*/
simulateTabContent(tab) {
const tabText = tab.textContent || tab.innerText;
// Clear existing logs
this.clear();
// Add tab-specific initial logs
if (tabText.includes('system.log')) {
this.addLog("Loading system logs... [OK]");
this.addLog("Current system time: " + new Date().toISOString());
this.addLog("System uptime: 47 days, 3 hours, 22 minutes");
} else if (tabText.includes('processes.ctl')) {
this.addLog("Process control interface active");
this.addLog("Active processes: 142");
this.addLog("CPU utilization: 34.7%");
this.addLog("Memory usage: 12.4 EXABYTES");
} else if (tabText.includes('network.dbg')) {
this.addLog("Network diagnostics mode");
this.addLog("Connected nodes: 1024");
this.addLog("Latency: 0.3ms average");
this.addLog("Bandwidth: 1.2 petabits/sec");
}
}
/**
* Handle control button clicks
* @param {HTMLElement} btn - Clicked control button
*/
handleControlClick(btn) {
const action = btn.classList.contains('minimize') ? 'minimize' :
btn.classList.contains('maximize') ? 'maximize' :
'close';
switch (action) {
case 'minimize':
this.minimize();
break;
case 'maximize':
this.maximize();
break;
case 'close':
this.close();
break;
}
}
/**
* Minimize the terminal (simulated)
*/
minimize() {
this.container.style.transform = 'scale(0.8)';
this.container.style.opacity = '0.7';
this.container.style.transition = 'all 0.3s ease';
// Restore after delay (simulated)
setTimeout(() => {
this.container.style.transform = '';
this.container.style.opacity = '';
}, 2000);
}
/**
* Maximize the terminal (simulated)
*/
maximize() {
const isMaximized = this.container.classList.contains('maximized');
if (!isMaximized) {
this.container.classList.add('maximized');
this.container.style.width = '95%';
this.container.style.height = '80vh';
this.outputElement.style.height = 'calc(80vh - 120px)';
} else {
this.container.classList.remove('maximized');
this.container.style.width = '';
this.container.style.height = '';
this.outputElement.style.height = '';
}
}
/**
* Close the terminal (simulated)
*/
close() {
this.container.style.opacity = '0.5';
this.container.style.transform = 'scale(0.95)';
this.container.style.transition = 'all 0.3s ease';
// Simulate reopening after delay
setTimeout(() => {
this.container.style.opacity = '';
this.container.style.transform = '';
// Add a "system restart" log
this.addLog("Terminal session restored");
}, 1500);
}
/**
* Clear all logs from the terminal
*/
clear() {
// Clear displayed logs
this.outputElement.innerHTML = '';
this.displayedLogs = [];
// Add a fresh timestamp
this.addLog("Terminal cleared - " + formatTimestamp());
}
/**
* Add a custom log message
* @param {string} message - Custom log message
*/
log(message) {
this.addLog(message);
}
/**
* Enable or disable interactive features
* @param {boolean} enabled - Whether interactive features are enabled
*/
setInteractive(enabled) {
this.isInteractive = enabled;
if (enabled) {
this.enableInteractiveMode();
} else {
this.disableInteractiveMode();
}
}
/**
* Enable interactive command input mode
*/
enableInteractiveMode() {
// This would set up command input functionality
console.log('Interactive mode enabled (advanced feature)');
}
/**
* Disable interactive command input mode
*/
disableInteractiveMode() {
// This would disable command input functionality
console.log('Interactive mode disabled');
}
/**
* Get the current log count
* @returns {number} Number of displayed logs
*/
getLogCount() {
return this.displayedLogs.length;
}
/**
* Get the last log timestamp
* @returns {number} Timestamp of last log in milliseconds
*/
getLastLogTime() {
return this.lastLogTime;
}
/**
* Clean up resources
*/
dispose() {
// Clear intervals
if (this.logInterval) {
clearInterval(this.logInterval);
this.logInterval = null;
}
// Cancel animations
if (this.scrollAnimationId) {
cancelAnimationFrame(this.scrollAnimationId);
}
// Clear logs
this.clear();
console.log('Terminal disposed');
}
}