os / index.html
abiyeenzo's picture
change la version totalement mets la bonne version parce queon la deployer et la on update et tout - Follow Up Deployment
2d1912d verified
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ÆOS - Système d'exploitation minimaliste</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
@keyframes boot-animation {
0% { opacity: 0; }
100% { opacity: 1; }
}
.boot-screen {
animation: boot-animation 1.5s ease-out;
}
.window {
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.title-bar {
user-select: none;
}
.cursor-blink {
animation: cursor-blink 1s infinite;
}
@keyframes cursor-blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
</style>
</head>
<body class="bg-gray-100 h-screen overflow-hidden font-mono">
<!-- Écran de démarrage -->
<div id="boot-screen" class="boot-screen fixed inset-0 bg-black text-white flex flex-col items-center justify-center z-50">
<div class="text-4xl mb-8">ÆOS</div>
<div class="text-sm text-gray-400">© Æ Corporation - Développé par Abiye Enzo</div>
<div class="w-64 h-1 bg-gray-700 rounded-full overflow-hidden">
<div id="boot-progress" class="h-full bg-blue-500 rounded-full" style="width: 0%"></div>
</div>
<div class="mt-4 text-gray-400">Chargement du système...</div>
</div>
<!-- Bureau -->
<div id="desktop" class="hidden h-full flex flex-col">
<!-- Barre de tâches -->
<div class="bg-gray-800 text-white p-2 flex justify-between items-center">
<div class="flex items-center">
<button id="menu-btn" class="px-3 py-1 bg-gray-700 hover:bg-gray-600 rounded mr-2">
☰ Menu
</button>
<button id="new-file-btn" class="px-3 py-1 bg-blue-600 hover:bg-blue-700 rounded mr-2">
Éditeur
</button>
<button id="terminal-btn" class="px-3 py-1 bg-purple-600 hover:bg-purple-700 rounded mr-2">
Terminal
</button>
<button id="calculator-btn" class="px-3 py-1 bg-green-600 hover:bg-green-700 rounded mr-2">
Calculatrice
</button>
<button id="game-btn" class="px-3 py-1 bg-red-600 hover:bg-red-700 rounded mr-2">
Snake Game
</button>
<div id="clock" class="px-3 py-1 bg-gray-700 rounded">00:00:00</div>
</div>
<div class="text-sm">ÆOS v1.0</div>
</div>
<!-- Fenêtre de l'éditeur (cachée au début) -->
<div id="editor-window" class="window hidden absolute top-10 left-10 w-3/4 h-3/4 flex flex-col bg-white rounded-lg overflow-hidden border border-gray-300">
<div class="title-bar bg-gray-800 text-white p-2 flex justify-between items-center cursor-move">
<div class="flex items-center">
<span class="ml-2">Éditeur de texte</span>
</div>
<div>
<button class="window-control px-3 py-1 hover:bg-gray-700">_</button>
<button class="window-control px-3 py-1 hover:bg-gray-700"></button>
<button id="close-editor" class="window-control px-3 py-1 hover:bg-red-600">×</button>
</div>
</div>
<div class="flex-1 flex flex-col">
<div class="toolbar bg-gray-100 p-2 flex space-x-2 border-b">
<button id="save-btn" class="px-3 py-1 bg-green-600 text-white rounded hover:bg-green-700">Enregistrer</button>
<button id="open-btn" class="px-3 py-1 bg-blue-600 text-white rounded hover:bg-blue-700">Ouvrir</button>
<input type="file" id="file-input" class="hidden" accept=".txt">
</div>
<div class="flex-1 relative">
<textarea id="text-editor" class="w-full h-full p-4 outline-none resize-none" spellcheck="false"></textarea>
<div id="status-bar" class="absolute bottom-0 left-0 right-0 bg-gray-100 p-1 text-sm text-gray-600 border-t">
Ligne 1, Colonne 1 | UTF-8
</div>
</div>
</div>
</div>
<!-- Calculator Window -->
<div id="calculator-window" class="window hidden absolute top-30 left-30 w-64 h-auto flex flex-col bg-gray-100 rounded-lg overflow-hidden border border-gray-300">
<div class="title-bar bg-gray-800 text-white p-2 flex justify-between items-center cursor-move">
<div class="flex items-center">
<span class="ml-2">Calculatrice</span>
</div>
<div>
<button class="window-control px-3 py-1 hover:bg-gray-700">_</button>
<button class="window-control px-3 py-1 hover:bg-gray-700"></button>
<button id="close-calculator" class="window-control px-3 py-1 hover:bg-red-600">×</button>
</div>
</div>
<div class="p-4">
<input type="text" id="calc-display" class="w-full p-2 mb-2 text-right bg-white border border-gray-300 rounded" readonly>
<div class="grid grid-cols-4 gap-2">
<button class="calc-btn p-2 bg-gray-200 hover:bg-gray-300 rounded">7</button>
<button class="calc-btn p-2 bg-gray-200 hover:bg-gray-300 rounded">8</button>
<button class="calc-btn p-2 bg-gray-200 hover:bg-gray-300 rounded">9</button>
<button class="calc-btn p-2 bg-blue-200 hover:bg-blue-300 rounded">/</button>
<button class="calc-btn p-2 bg-gray-200 hover:bg-gray-300 rounded">4</button>
<button class="calc-btn p-2 bg-gray-200 hover:bg-gray-300 rounded">5</button>
<button class="calc-btn p-2 bg-gray-200 hover:bg-gray-300 rounded">6</button>
<button class="calc-btn p-2 bg-blue-200 hover:bg-blue-300 rounded">*</button>
<button class="calc-btn p-2 bg-gray-200 hover:bg-gray-300 rounded">1</button>
<button class="calc-btn p-2 bg-gray-200 hover:bg-gray-300 rounded">2</button>
<button class="calc-btn p-2 bg-gray-200 hover:bg-gray-300 rounded">3</button>
<button class="calc-btn p-2 bg-blue-200 hover:bg-blue-300 rounded">-</button>
<button class="calc-btn p-2 bg-gray-200 hover:bg-gray-300 rounded">0</button>
<button class="calc-btn p-2 bg-gray-200 hover:bg-gray-300 rounded">.</button>
<button class="calc-btn p-2 bg-green-200 hover:bg-green-300 rounded">=</button>
<button class="calc-btn p-2 bg-blue-200 hover:bg-blue-300 rounded">+</button>
<button class="calc-btn p-2 bg-red-200 hover:bg-red-300 rounded col-span-2">C</button>
<button class="calc-btn p-2 bg-red-200 hover:bg-red-300 rounded col-span-2">CE</button>
</div>
</div>
</div>
<!-- Menu Window -->
<div id="menu-window" class="window hidden absolute top-20 left-20 w-64 h-auto flex flex-col bg-white rounded-lg overflow-hidden border border-gray-300">
<div class="title-bar bg-gray-800 text-white p-2 flex justify-between items-center cursor-move">
<div class="flex items-center">
<span class="ml-2">Menu</span>
</div>
<div>
<button class="window-control px-3 py-1 hover:bg-gray-700">_</button>
<button class="window-control px-3 py-1 hover:bg-gray-700"></button>
<button id="close-menu" class="window-control px-3 py-1 hover:bg-red-600">×</button>
</div>
</div>
<div class="p-2">
<button class="menu-item w-full p-2 text-left hover:bg-gray-100 rounded flex items-center" onclick="openEditor()">
<span class="mr-2">📝</span> Éditeur de texte
</button>
<button class="menu-item w-full p-2 text-left hover:bg-gray-100 rounded flex items-center" onclick="openTerminal()">
<span class="mr-2">💻</span> Terminal
</button>
<button class="menu-item w-full p-2 text-left hover:bg-gray-100 rounded flex items-center" onclick="openCalculator()">
<span class="mr-2">🧮</span> Calculatrice
</button>
<button class="menu-item w-full p-2 text-left hover:bg-gray-100 rounded flex items-center" onclick="openGame()">
<span class="mr-2">🐍</span> Snake Game
</button>
<div class="border-t my-1"></div>
<button id="settings-btn" class="menu-item w-full p-2 text-left hover:bg-gray-100 rounded flex items-center">
<span class="mr-2">⚙️</span> Paramètres
</button>
<button class="menu-item w-full p-2 text-left hover:bg-gray-100 rounded flex items-center" onclick="addTerminalLine('ÆOS v1.0 - Développé par Abiye Enzo')">
<span class="mr-2">ℹ️</span> À propos
</button>
<div class="border-t my-1"></div>
<button class="menu-item w-full p-2 text-left hover:bg-gray-100 rounded flex items-center" onclick="document.getElementById('menu-window').classList.add('hidden')">
<span class="mr-2">🚪</span> Fermer
</button>
</div>
</div>
<!-- Settings Window -->
<div id="settings-window" class="window hidden absolute top-30 left-30 w-96 h-64 flex flex-col bg-white rounded-lg overflow-hidden border border-gray-300">
<div class="title-bar bg-gray-800 text-white p-2 flex justify-between items-center cursor-move">
<div class="flex items-center">
<span class="ml-2">Paramètres</span>
</div>
<div>
<button class="window-control px-3 py-1 hover:bg-gray-700">_</button>
<button class="window-control px-3 py-1 hover:bg-gray-700"></button>
<button id="close-settings" class="window-control px-3 py-1 hover:bg-red-600">×</button>
</div>
</div>
<div class="p-4">
<div class="mb-4">
<label class="block text-sm font-medium mb-1">Thème</label>
<select class="w-full p-2 border rounded">
<option>Clair</option>
<option>Sombre</option>
</select>
</div>
<div class="mb-4">
<label class="block text-sm font-medium mb-1">Langue</label>
<select class="w-full p-2 border rounded">
<option>Français</option>
<option>English</option>
</select>
</div>
</div>
</div>
<!-- Snake Game Window -->
<div id="game-window" class="window hidden absolute top-30 left-30 w-96 h-96 flex flex-col bg-gray-900 rounded-lg overflow-hidden border border-gray-700">
<div class="title-bar bg-gray-800 text-white p-2 flex justify-between items-center cursor-move">
<div class="flex items-center">
<span class="ml-2">Snake Game</span>
</div>
<div>
<button class="window-control px-3 py-1 hover:bg-gray-700">_</button>
<button class="window-control px-3 py-1 hover:bg-gray-700"></button>
<button id="close-game" class="window-control px-3 py-1 hover:bg-red-600">×</button>
</div>
</div>
<div class="flex-1 flex flex-col items-center justify-center p-4">
<canvas id="game-canvas" width="300" height="300" class="bg-black"></canvas>
<div class="mt-4 text-white">
Score: <span id="game-score">0</span>
</div>
<button id="restart-game" class="mt-4 px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700">
Nouvelle partie
</button>
</div>
</div>
<!-- Terminal Window -->
<div id="terminal-window" class="window hidden absolute top-20 left-20 w-3/4 h-3/4 flex flex-col bg-black text-green-400 rounded-lg overflow-hidden border border-gray-700">
<div class="title-bar bg-gray-800 text-white p-2 flex justify-between items-center cursor-move">
<div class="flex items-center">
<span class="ml-2">Terminal</span>
</div>
<div>
<button class="window-control px-3 py-1 hover:bg-gray-700">_</button>
<button class="window-control px-3 py-1 hover:bg-gray-700"></button>
<button id="close-terminal" class="window-control px-3 py-1 hover:bg-red-600">×</button>
</div>
</div>
<div class="flex-1 p-4 overflow-auto font-mono" id="terminal-output">
<div class="text-center mb-2">
<div class="text-2xl text-green-400">Bienvenue sur ÆOS Terminal</div>
<div class="text-sm text-gray-500">v1.0 - Tapez 'help' pour la liste des commandes</div>
</div>
<div class="border-t border-gray-700 my-2"></div>
<div class="mt-2">
<span class="text-green-500">┌──(</span>
<span class="text-yellow-400">user@ÆOS</span>
<span class="text-green-500">)-[</span>
<span class="text-blue-400">~</span>
<span class="text-green-500">]</span>
<br>
<span class="text-green-500">└─$</span>
<span id="command-line" class="inline-flex items-center">
<span id="command-input" contenteditable="true"></span>
<span class="cursor-blink">|</span>
</span>
</div>
</div>
</div>
</div>
<script>
// Simulation du démarrage du système
document.addEventListener('DOMContentLoaded', () => {
const bootScreen = document.getElementById('boot-screen');
const bootProgress = document.getElementById('boot-progress');
const desktop = document.getElementById('desktop');
let progress = 0;
const bootInterval = setInterval(() => {
progress += Math.random() * 10;
if (progress > 100) progress = 100;
bootProgress.style.width = `${progress}%`;
if (progress >= 100) {
clearInterval(bootInterval);
setTimeout(() => {
bootScreen.classList.add('hidden');
desktop.classList.remove('hidden');
updateClock();
setInterval(updateClock, 1000);
setupTerminal();
}, 500);
}
}, 150);
});
// Mise à jour de l'horloge
function updateClock() {
const now = new Date();
const timeString = now.toLocaleTimeString();
document.getElementById('clock').textContent = timeString;
}
// Terminal functionality
const terminalCommands = {
help: () => `
Commandes disponibles:
help - Affiche cette aide
clear - Efface l'écran du terminal
about - Affiche les informations sur ÆOS
echo [text] - Affiche le texte spécifié
ls - Liste les commandes disponibles
date - Affiche la date et l'heure actuelles
calc [expr] - Évalue une expression mathématique
shutdown - Ferme la fenêtre du terminal
sysinfo - Affiche les informations système
neofetch - Affiche le logo et informations système
whoami - Affiche le nom d'utilisateur actuel
pwd - Affiche le répertoire courant
history - Affiche les 10 dernières commandes
color [c] - Change la couleur du texte (rouge, vert, bleu, jaune, violet)
theme [t] - Change le thème du terminal (dark/light)
Pour plus d'informations sur une commande, essayez 'help [commande]'
`,
clear: () => { terminalOutput.innerHTML = ''; return ""; },
about: () => "ÆOS v1.0\nSystème d'exploitation minimaliste\n© Æ Corporation",
echo: (args) => args.join(" "),
date: () => new Date().toLocaleString('fr-FR'),
ls: () => Object.keys(terminalCommands).join(" "),
calc: (args) => {
try {
return eval(args.join(" "));
} catch {
return "Erreur: Expression invalide";
}
},
shutdown: () => {
document.getElementById('terminal-window').classList.add('hidden');
return "Terminal fermé";
},
sysinfo: () => `Système: ÆOS v1.0\nCPU: Virtual CPU @ 2.4GHz\nMémoire: 1024MB\nDisque: 10GB\nRéseau: eth0 (192.168.1.100)`,
neofetch: () => {
const art = `
_____ ______
/ _ \\ / __ \\
/ /_\\ \\| | | |
/ | \\ | | |
\\____|__ /__|__|__|
\\/
`;
return art + "\nÆOS v1.0\nDéveloppé par Abiye Enzo";
},
whoami: () => "user",
pwd: () => "/home/user",
history: () => commandHistory.slice(0, 10).join("\n"),
color: (args) => {
const colors = {
'rouge': 'text-red-400',
'vert': 'text-green-400',
'bleu': 'text-blue-400',
'jaune': 'text-yellow-400',
'violet': 'text-purple-400'
};
const color = args[0];
if (color in colors) {
document.getElementById('terminal-output').className = `flex-1 p-4 overflow-auto font-mono ${colors[color]}`;
return `Couleur changée en ${color}`;
}
return "Couleurs disponibles: rouge, vert, bleu, jaune, violet";
},
theme: (args) => {
const theme = args[0];
if (theme === 'dark') {
document.getElementById('terminal-window').className = 'window hidden absolute top-20 left-20 w-3/4 h-3/4 flex flex-col bg-black text-green-400 rounded-lg overflow-hidden border border-gray-700';
return "Thème changé en sombre";
} else if (theme === 'light') {
document.getElementById('terminal-window').className = 'window hidden absolute top-20 left-20 w-3/4 h-3/4 flex flex-col bg-gray-100 text-gray-800 rounded-lg overflow-hidden border border-gray-300';
return "Thème changé en clair";
}
return "Utilisation: theme [dark/light]";
}
};
function processCommand(command) {
const parts = command.trim().split(/\s+/);
const cmd = parts[0].toLowerCase();
const args = parts.slice(1);
if (cmd === '') return "";
if (cmd in terminalCommands) {
const result = terminalCommands[cmd](args);
if (result === undefined) return "";
if (typeof result === 'string') {
return result.split('\n').map(line => line.trim()).join('\n');
}
return String(result);
}
return `Commande inconnue: ${cmd}\nTapez 'help' pour la liste des commandes`;
}
const terminalOutput = document.getElementById('terminal-output');
function addTerminalLine(text) {
const line = document.createElement('div');
line.textContent = text;
terminalOutput.appendChild(line);
terminalOutput.scrollTop = terminalOutput.scrollHeight;
}
function setupTerminal() {
let currentCommand = '';
let commandHistory = [];
let historyIndex = -1;
function addPrompt() {
const prompt = document.createElement('div');
prompt.innerHTML = `
<span class="text-green-500">┌──(</span>
<span class="text-yellow-400">user@ÆOS</span>
<span class="text-green-500">)-[</span>
<span class="text-blue-400">~</span>
<span class="text-green-500">]</span>
<br>
<span class="text-green-500">└─$</span>
<span id="command-input" contenteditable="true" class="inline-block min-w-[1px]"></span>
<span class="cursor-blink">|</span>
`;
terminalOutput.appendChild(prompt);
return prompt.querySelector('#command-input');
}
function processCommand(cmd) {
if (!cmd) return;
// Add to history
commandHistory.unshift(cmd);
if (commandHistory.length > 20) commandHistory.pop();
// Process command
const result = terminalCommands[cmd] ? terminalCommands[cmd]() : `Commande inconnue: ${cmd}`;
// Display result
if (result) {
const resultDiv = document.createElement('div');
resultDiv.textContent = result;
terminalOutput.appendChild(resultDiv);
}
}
let currentInput = addPrompt();
currentInput.focus();
terminalOutput.addEventListener('keydown', (e) => {
if (e.target.id !== 'command-input') return;
if (e.key === 'Enter') {
e.preventDefault();
const cmd = currentInput.textContent.trim();
// Display the command that was entered
const cmdDisplay = document.createElement('div');
cmdDisplay.innerHTML = `
<span class="text-green-500">┌──(</span>
<span class="text-yellow-400">user@ÆOS</span>
<span class="text-green-500">)-[</span>
<span class="text-blue-400">~</span>
<span class="text-green-500">]</span>
<br>
<span class="text-green-500">└─$</span> ${cmd}
`;
terminalOutput.appendChild(cmdDisplay);
processCommand(cmd);
// Add new prompt
currentInput = addPrompt();
currentInput.focus();
historyIndex = -1;
// Scroll to bottom
terminalOutput.scrollTop = terminalOutput.scrollHeight;
}
else if (e.key === 'ArrowUp') {
e.preventDefault();
if (historyIndex < commandHistory.length - 1) {
historyIndex++;
currentInput.textContent = commandHistory[historyIndex];
placeCaretAtEnd(currentInput);
}
}
else if (e.key === 'ArrowDown') {
e.preventDefault();
if (historyIndex > 0) {
historyIndex--;
currentInput.textContent = commandHistory[historyIndex];
placeCaretAtEnd(currentInput);
} else if (historyIndex === 0) {
historyIndex = -1;
currentInput.textContent = '';
}
}
});
}
function placeCaretAtEnd(el) {
el.focus();
const range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
// Terminal window controls
document.getElementById('terminal-btn').addEventListener('click', () => {
openTerminal();
});
document.getElementById('close-terminal').addEventListener('click', () => {
document.getElementById('terminal-window').classList.add('hidden');
});
function openTerminal() {
const terminalWindow = document.getElementById('terminal-window');
terminalWindow.classList.remove('hidden');
commandInput.focus();
// Position aléatoire pour la fenêtre
const maxX = window.innerWidth - terminalWindow.offsetWidth;
const maxY = window.innerHeight - terminalWindow.offsetHeight;
const randomX = Math.floor(Math.random() * maxX * 0.5);
const randomY = Math.floor(Math.random() * maxY * 0.5);
terminalWindow.style.left = `${randomX}px`;
terminalWindow.style.top = `${randomY}px`;
makeDraggable(terminalWindow);
}
document.getElementById('new-file-btn').addEventListener('click', openEditor);
document.getElementById('close-editor').addEventListener('click', () => {
document.getElementById('editor-window').classList.add('hidden');
});
function openEditor() {
const editorWindow = document.getElementById('editor-window');
editorWindow.classList.remove('hidden');
document.getElementById('home-screen').classList.add('hidden');
document.getElementById('text-editor').focus();
// Position aléatoire pour la fenêtre
const maxX = window.innerWidth - editorWindow.offsetWidth;
const maxY = window.innerHeight - editorWindow.offsetHeight;
const randomX = Math.floor(Math.random() * maxX * 0.5);
const randomY = Math.floor(Math.random() * maxY * 0.5);
editorWindow.style.left = `${randomX}px`;
editorWindow.style.top = `${randomY}px`;
makeDraggable(editorWindow);
}
// Gestion du glisser-déposer pour la fenêtre
function makeDraggable(element) {
const titleBar = element.querySelector('.title-bar');
let isDragging = false;
let offsetX, offsetY;
titleBar.addEventListener('mousedown', (e) => {
isDragging = true;
offsetX = e.clientX - element.getBoundingClientRect().left;
offsetY = e.clientY - element.getBoundingClientRect().top;
element.style.cursor = 'grabbing';
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const x = e.clientX - offsetX;
const y = e.clientY - offsetY;
// Limites pour empêcher la fenêtre de sortir de l'écran
const maxX = window.innerWidth - element.offsetWidth;
const maxY = window.innerHeight - element.offsetHeight;
element.style.left = `${Math.max(0, Math.min(x, maxX))}px`;
element.style.top = `${Math.max(0, Math.min(y, maxY))}px`;
});
document.addEventListener('mouseup', () => {
isDragging = false;
element.style.cursor = '';
});
}
// Gestion des boutons de fenêtre
document.querySelectorAll('.window-control').forEach(btn => {
btn.addEventListener('click', function() {
const editorWindow = document.getElementById('editor-window');
if (this.textContent === '_') {
// Minimiser
editorWindow.classList.add('hidden');
} else if (this.textContent === '×') {
// Fermer
editorWindow.classList.add('hidden');
document.getElementById('home-screen').classList.remove('hidden');
} else if (this.textContent === '□') {
// Maximiser/restaurer
if (editorWindow.classList.contains('maximized')) {
editorWindow.classList.remove('maximized');
editorWindow.style.width = '75%';
editorWindow.style.height = '75%';
editorWindow.style.left = '10%';
editorWindow.style.top = '10%';
} else {
editorWindow.classList.add('maximized');
editorWindow.style.width = '100%';
editorWindow.style.height = 'calc(100% - 40px)';
editorWindow.style.left = '0';
editorWindow.style.top = '0';
}
}
});
});
// Gestion de l'éditeur
const textEditor = document.getElementById('text-editor');
const statusBar = document.getElementById('status-bar');
textEditor.addEventListener('input', updateCursorPosition);
textEditor.addEventListener('click', updateCursorPosition);
textEditor.addEventListener('keyup', updateCursorPosition);
function updateCursorPosition() {
const text = textEditor.value;
const cursorPos = textEditor.selectionStart;
let line = 1;
let column = 1;
for (let i = 0; i < cursorPos; i++) {
if (text[i] === '\n') {
line++;
column = 1;
} else {
column++;
}
}
statusBar.textContent = `Ligne ${line}, Colonne ${column} | UTF-8`;
}
// Menu and Settings functionality
document.getElementById('menu-btn').addEventListener('click', openMenu);
document.getElementById('close-menu').addEventListener('click', () => {
document.getElementById('menu-window').classList.add('hidden');
});
document.getElementById('settings-btn').addEventListener('click', () => {
document.getElementById('menu-window').classList.add('hidden');
openSettings();
});
document.getElementById('close-settings').addEventListener('click', () => {
document.getElementById('settings-window').classList.add('hidden');
});
function openMenu() {
const menuWindow = document.getElementById('menu-window');
menuWindow.classList.remove('hidden');
document.getElementById('home-screen').classList.add('hidden');
// Position aléatoire pour la fenêtre
const maxX = window.innerWidth - menuWindow.offsetWidth;
const maxY = window.innerHeight - menuWindow.offsetHeight;
const randomX = Math.floor(Math.random() * maxX * 0.5);
const randomY = Math.floor(Math.random() * maxY * 0.5);
menuWindow.style.left = `${randomX}px`;
menuWindow.style.top = `${randomY}px`;
makeDraggable(menuWindow);
}
function openSettings() {
const settingsWindow = document.getElementById('settings-window');
settingsWindow.classList.remove('hidden');
// Position aléatoire pour la fenêtre
const maxX = window.innerWidth - settingsWindow.offsetWidth;
const maxY = window.innerHeight - settingsWindow.offsetHeight;
const randomX = Math.floor(Math.random() * maxX * 0.5);
const randomY = Math.floor(Math.random() * maxY * 0.5);
settingsWindow.style.left = `${randomX}px`;
settingsWindow.style.top = `${randomY}px`;
makeDraggable(settingsWindow);
}
// Calculator functionality
document.getElementById('calculator-btn').addEventListener('click', openCalculator);
document.getElementById('close-calculator').addEventListener('click', () => {
document.getElementById('calculator-window').classList.add('hidden');
});
function openCalculator() {
const calculatorWindow = document.getElementById('calculator-window');
calculatorWindow.classList.remove('hidden');
document.getElementById('home-screen').classList.add('hidden');
// Position aléatoire pour la fenêtre
const maxX = window.innerWidth - calculatorWindow.offsetWidth;
const maxY = window.innerHeight - calculatorWindow.offsetHeight;
const randomX = Math.floor(Math.random() * maxX * 0.5);
const randomY = Math.floor(Math.random() * maxY * 0.5);
calculatorWindow.style.left = `${randomX}px`;
calculatorWindow.style.top = `${randomY}px`;
makeDraggable(calculatorWindow);
}
// Calculator logic
let currentInput = '0';
let previousInput = '';
let operation = null;
const display = document.getElementById('calc-display');
document.querySelectorAll('.calc-btn').forEach(button => {
button.addEventListener('click', () => {
const value = button.textContent;
if (value >= '0' && value <= '9') {
if (currentInput === '0') {
currentInput = value;
} else {
currentInput += value;
}
} else if (value === '.') {
if (!currentInput.includes('.')) {
currentInput += value;
}
} else if (value === 'C') {
currentInput = '0';
previousInput = '';
operation = null;
} else if (value === 'CE') {
currentInput = '0';
} else if (value === '+' || value === '-' || value === '*' || value === '/') {
if (operation !== null) calculate();
previousInput = currentInput;
currentInput = '0';
operation = value;
} else if (value === '=') {
if (operation !== null) calculate();
}
display.value = currentInput;
});
});
function calculate() {
let result;
const prev = parseFloat(previousInput);
const current = parseFloat(currentInput);
if (isNaN(prev) || isNaN(current)) return;
switch (operation) {
case '+':
result = prev + current;
break;
case '-':
result = prev - current;
break;
case '*':
result = prev * current;
break;
case '/':
result = prev / current;
break;
default:
return;
}
currentInput = result.toString();
operation = null;
previousInput = '';
}
// Snake Game functionality
document.getElementById('game-btn').addEventListener('click', openGame);
document.getElementById('close-game').addEventListener('click', () => {
document.getElementById('game-window').classList.add('hidden');
clearInterval(gameLoop);
});
function openGame() {
const gameWindow = document.getElementById('game-window');
gameWindow.classList.remove('hidden');
// Position aléatoire pour la fenêtre
const maxX = window.innerWidth - gameWindow.offsetWidth;
const maxY = window.innerHeight - gameWindow.offsetHeight;
const randomX = Math.floor(Math.random() * maxX * 0.5);
const randomY = Math.floor(Math.random() * maxY * 0.5);
gameWindow.style.left = `${randomX}px`;
gameWindow.style.top = `${randomY}px`;
makeDraggable(gameWindow);
initGame();
}
let gameLoop;
function initGame() {
const canvas = document.getElementById('game-canvas');
const ctx = canvas.getContext('2d');
const scoreElement = document.getElementById('game-score');
const gridSize = 20;
const tileCount = canvas.width / gridSize;
let snake = [{x: 10, y: 10}];
let velocityX = 0;
let velocityY = 0;
let foodX = 5;
let foodY = 5;
let score = 0;
let gameSpeed = 100;
function gameUpdate() {
// Move snake
const head = {x: snake[0].x + velocityX, y: snake[0].y + velocityY};
// Wall collision
if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount) {
gameOver();
return;
}
// Self collision
for (let i = 0; i < snake.length; i++) {
if (head.x === snake[i].x && head.y === snake[i].y) {
gameOver();
return;
}
}
snake.unshift(head);
// Food collision
if (head.x === foodX && head.y === foodY) {
score++;
scoreElement.textContent = score;
placeFood();
// Increase speed every 5 points
if (score % 5 === 0) {
gameSpeed = Math.max(50, gameSpeed - 10);
clearInterval(gameLoop);
gameLoop = setInterval(gameUpdate, gameSpeed);
}
} else {
snake.pop();
}
// Draw game
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw snake
ctx.fillStyle = 'lime';
snake.forEach(segment => {
ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize-2, gridSize-2);
});
// Draw food
ctx.fillStyle = 'red';
ctx.fillRect(foodX * gridSize, foodY * gridSize, gridSize-2, gridSize-2);
}
function placeFood() {
foodX = Math.floor(Math.random() * tileCount);
foodY = Math.floor(Math.random() * tileCount);
// Make sure food doesn't spawn on snake
for (let i = 0; i < snake.length; i++) {
if (foodX === snake[i].x && foodY === snake[i].y) {
placeFood();
return;
}
}
}
function gameOver() {
clearInterval(gameLoop);
alert(`Game Over! Score: ${score}`);
initGame();
}
function handleKeyDown(e) {
switch(e.key) {
case 'ArrowUp':
if (velocityY !== 1) {
velocityX = 0;
velocityY = -1;
}
break;
case 'ArrowDown':
if (velocityY !== -1) {
velocityX = 0;
velocityY = 1;
}
break;
case 'ArrowLeft':
if (velocityX !== 1) {
velocityX = -1;
velocityY = 0;
}
break;
case 'ArrowRight':
if (velocityX !== -1) {
velocityX = 1;
velocityY = 0;
}
break;
}
}
// Reset game state
snake = [{x: 10, y: 10}];
velocityX = 0;
velocityY = 0;
score = 0;
scoreElement.textContent = score;
gameSpeed = 100;
// Set up controls
document.removeEventListener('keydown', handleKeyDown);
document.addEventListener('keydown', handleKeyDown);
// Place first food
placeFood();
// Start game loop
clearInterval(gameLoop);
gameLoop = setInterval(gameUpdate, gameSpeed);
// Restart button
document.getElementById('restart-game').addEventListener('click', initGame);
}
// Gestion des fichiers
document.getElementById('save-btn').addEventListener('click', () => {
const text = textEditor.value;
const blob = new Blob([text], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'document.txt';
a.click();
URL.revokeObjectURL(url);
});
document.getElementById('open-btn').addEventListener('click', () => {
document.getElementById('file-input').click();
});
document.getElementById('file-input').addEventListener('change', (e) => {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (event) => {
textEditor.value = event.target.result;
updateCursorPosition();
};
reader.readAsText(file);
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=abiyeenzo/os" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>