Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>PyWeb - Online Python Editor</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> | |
| <style> | |
| .editor-container { | |
| } | |
| .editor { | |
| height: 100%; | |
| font-size: 14px; | |
| line-height: 1.5; | |
| tab-size: 4; | |
| } | |
| .output { | |
| height: 100%; | |
| overflow-y: auto; | |
| white-space: pre-wrap; | |
| background-color: #1e1e1e; | |
| color: #d4d4d4; | |
| font-family: 'Courier New', monospace; | |
| padding: 10px; | |
| } | |
| .sidebar { | |
| transition: all 0.3s ease; | |
| } | |
| .sidebar.collapsed { | |
| width: 50px; | |
| } | |
| .sidebar-item { | |
| transition: all 0.2s ease; | |
| } | |
| .sidebar-item:hover { | |
| background-color: rgba(255, 255, 255, 0.1); | |
| } | |
| .tab { | |
| transition: all 0.2s ease; | |
| } | |
| .tab.active { | |
| border-bottom: 2px solid #3b82f6; | |
| } | |
| .autocomplete-list { | |
| position: absolute; | |
| background: #2d2d2d; | |
| border: 1px solid #444; | |
| max-height: 200px; | |
| overflow-y: auto; | |
| z-index: 100; | |
| width: 200px; | |
| } | |
| .autocomplete-item { | |
| padding: 5px 10px; | |
| cursor: pointer; | |
| } | |
| .autocomplete-item:hover { | |
| background-color: #3b82f6; | |
| } | |
| .line-numbers { | |
| background-color: #1e1e1e; | |
| color: #858585; | |
| text-align: right; | |
| padding-right: 10px; | |
| user-select: none; | |
| } | |
| .python-keyword { | |
| color: #569cd6; | |
| } | |
| .python-string { | |
| color: #ce9178; | |
| } | |
| .python-comment { | |
| color: #6a9955; | |
| } | |
| .python-function { | |
| color: #dcdcaa; | |
| } | |
| .python-number { | |
| color: #b5cea8; | |
| } | |
| .terminal { | |
| height: 100%; | |
| background-color: #1e1e1e; | |
| color: #d4d4d4; | |
| font-family: 'Courier New', monospace; | |
| padding: 10px; | |
| overflow-y: auto; | |
| } | |
| .terminal-input { | |
| background-color: transparent; | |
| border: none; | |
| outline: none; | |
| color: #d4d4d4; | |
| font-family: 'Courier New', monospace; | |
| width: 90%; | |
| } | |
| .terminal-prompt { | |
| color: #4CAF50; | |
| } | |
| .terminal-cursor { | |
| display: inline-block; | |
| width: 10px; | |
| height: 15px; | |
| background-color: #d4d4d4; | |
| animation: blink 1s infinite; | |
| } | |
| @keyframes blink { | |
| 0%, 100% { opacity: 1; } | |
| 50% { opacity: 0; } | |
| } | |
| .terminal-output { | |
| margin-bottom: 10px; | |
| white-space: pre-wrap; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-900 text-white"> | |
| <div class="flex flex-col h-screen"> | |
| <!-- Top Navigation --> | |
| <div class="bg-gray-800 px-4 py-2 flex items-center justify-between border-b border-gray-700"> | |
| <div class="flex items-center space-x-4"> | |
| <div class="flex items-center"> | |
| <i class="fab fa-python text-blue-400 text-2xl mr-2"></i> | |
| <h1 class="text-xl font-bold">PyWeb</h1> | |
| </div> | |
| <div class="hidden md:flex space-x-2"> | |
| <button class="px-3 py-1 rounded hover:bg-gray-700 flex items-center"> | |
| <i class="fas fa-file mr-1"></i> New | |
| </button> | |
| <button class="px-3 py-1 rounded hover:bg-gray-700 flex items-center"> | |
| <i class="fas fa-folder-open mr-1"></i> Open | |
| </button> | |
| <button class="px-3 py-1 rounded hover:bg-gray-700 flex items-center"> | |
| <i class="fas fa-save mr-1"></i> Save | |
| </button> | |
| </div> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <button id="run-btn" class="bg-green-600 hover:bg-green-700 px-4 py-1 rounded flex items-center"> | |
| <i class="fas fa-play mr-1"></i> Run | |
| </button> | |
| <div class="relative"> | |
| <button class="px-3 py-1 rounded hover:bg-gray-700"> | |
| <i class="fas fa-cog"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main Content --> | |
| <div class="flex flex-1 overflow-hidden"> | |
| <!-- Sidebar --> | |
| <div id="sidebar" class="sidebar bg-gray-800 w-64 flex flex-col border-r border-gray-700"> | |
| <div class="p-3 border-b border-gray-700 flex justify-between items-center"> | |
| <h2 class="font-semibold">Explorer</h2> | |
| <button id="sidebar-toggle" class="text-gray-400 hover:text-white"> | |
| <i class="fas fa-chevron-left"></i> | |
| </button> | |
| </div> | |
| <div class="flex-1 overflow-y-auto"> | |
| <div class="py-2"> | |
| <div class="sidebar-item px-4 py-2 flex items-center cursor-pointer"> | |
| <i class="fas fa-folder-open text-blue-400 mr-2"></i> | |
| <span>Project</span> | |
| </div> | |
| <div class="ml-6"> | |
| <div class="sidebar-item px-4 py-2 flex items-center cursor-pointer"> | |
| <i class="fas fa-file-code text-yellow-400 mr-2"></i> | |
| <span>main.py</span> | |
| </div> | |
| <div class="sidebar-item px-4 py-2 flex items-center cursor-pointer"> | |
| <i class="fas fa-file-code text-yellow-400 mr-2"></i> | |
| <span>utils.py</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="py-2 border-t border-gray-700"> | |
| <div class="sidebar-item px-4 py-2 flex items-center cursor-pointer"> | |
| <i class="fas fa-search text-purple-400 mr-2"></i> | |
| <span>Search</span> | |
| </div> | |
| </div> | |
| <div class="py-2 border-t border-gray-700"> | |
| <div id="terminal-tab" class="sidebar-item px-4 py-2 flex items-center cursor-pointer"> | |
| <i class="fas fa-terminal text-green-400 mr-2"></i> | |
| <span>Terminal</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Editor Area --> | |
| <div class="flex-1 flex flex-col overflow-hidden"> | |
| <!-- Tabs --> | |
| <div class="bg-gray-800 border-b border-gray-700 flex overflow-x-auto"> | |
| <div id="editor-tab" class="tab active px-4 py-2 flex items-center border-r border-gray-700 cursor-pointer"> | |
| <i class="fas fa-file-code text-yellow-400 mr-2"></i> | |
| <span>main.py</span> | |
| <i class="fas fa-times ml-2 text-gray-400 hover:text-white"></i> | |
| </div> | |
| <div class="tab px-4 py-2 flex items-center border-r border-gray-700 cursor-pointer"> | |
| <i class="fas fa-file-code text-yellow-400 mr-2"></i> | |
| <span>utils.py</span> | |
| <i class="fas fa-times ml-2 text-gray-400 hover:text-white"></i> | |
| </div> | |
| <div class="px-4 py-2 flex items-center cursor-pointer hover:bg-gray-700"> | |
| <i class="fas fa-plus text-gray-400"></i> | |
| </div> | |
| </div> | |
| <!-- Editor and Output --> | |
| <div id="editor-container" class="editor-container flex flex-col md:flex-row flex-1 overflow-hidden"> | |
| <!-- Editor --> | |
| <div class="flex-1 flex overflow-hidden"> | |
| <div class="line-numbers overflow-y-auto"></div> | |
| <textarea id="editor" class="editor flex-1 bg-gray-900 text-white p-4 outline-none resize-none overflow-auto" spellcheck="false"># Welcome to PyWeb - Python Editor | |
| # Write your Python code here and click Run | |
| def greet(name): | |
| """A simple greeting function""" | |
| return f"Hello, {name}!" | |
| print(greet("World")) | |
| # Try some math | |
| result = 42 + 3.14 * 2 | |
| print(f"The answer is {result}") | |
| # List comprehension example | |
| squares = [x**2 for x in range(10)] | |
| print(f"Squares: {squares}")</textarea> | |
| </div> | |
| <!-- Output --> | |
| <div class="w-full md:w-1/3 bg-gray-800 border-t md:border-t-0 md:border-l border-gray-700 flex flex-col"> | |
| <div class="bg-gray-700 px-4 py-2 flex justify-between items-center"> | |
| <h3 class="font-semibold">Output</h3> | |
| <div class="flex space-x-2"> | |
| <button id="clear-output" class="text-gray-400 hover:text-white"> | |
| <i class="fas fa-trash-alt"></i> | |
| </button> | |
| <button class="text-gray-400 hover:text-white"> | |
| <i class="fas fa-expand"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <pre id="output" class="output flex-1"></pre> | |
| </div> | |
| </div> | |
| <!-- Terminal (hidden by default) --> | |
| <div id="terminal-container" class="editor-container flex flex-col flex-1 overflow-hidden" style="display: none;"> | |
| <div class="terminal flex-1 flex flex-col"> | |
| <div class="bg-gray-700 px-4 py-2 flex justify-between items-center"> | |
| <h3 class="font-semibold">Terminal</h3> | |
| <div class="flex space-x-2"> | |
| <button id="clear-terminal" class="text-gray-400 hover:text-white"> | |
| <i class="fas fa-trash-alt"></i> | |
| </button> | |
| <button id="close-terminal" class="text-gray-400 hover:text-white"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div id="terminal-content" class="flex-1 overflow-y-auto p-2"> | |
| <div class="terminal-output"> | |
| PyWeb Terminal v1.0<br> | |
| Type 'help' for a list of commands<br><br> | |
| </div> | |
| <div class="terminal-line flex items-center"> | |
| <span class="terminal-prompt">user@pyweb:~$ </span> | |
| <input id="terminal-input" class="terminal-input" type="text" autofocus> | |
| <span class="terminal-cursor"></span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Status Bar --> | |
| <div class="bg-gray-800 px-4 py-1 flex justify-between items-center text-sm border-t border-gray-700"> | |
| <div class="flex items-center space-x-4"> | |
| <div class="flex items-center"> | |
| <i class="fab fa-python text-blue-400 mr-1"></i> | |
| <span>Python 3.10</span> | |
| </div> | |
| <div class="hidden md:flex items-center"> | |
| <i class="fas fa-code-branch text-purple-400 mr-1"></i> | |
| <span>main</span> | |
| </div> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <div class="flex items-center"> | |
| <i class="fas fa-memory text-yellow-400 mr-1"></i> | |
| <span>128 MB</span> | |
| </div> | |
| <div class="flex items-center"> | |
| <i class="fas fa-bolt text-green-400 mr-1"></i> | |
| <span id="status-ready">Ready</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // DOM Elements | |
| const editor = document.getElementById('editor'); | |
| const output = document.getElementById('output'); | |
| const runBtn = document.getElementById('run-btn'); | |
| const clearOutputBtn = document.getElementById('clear-output'); | |
| const sidebar = document.getElementById('sidebar'); | |
| const sidebarToggle = document.getElementById('sidebar-toggle'); | |
| const statusReady = document.getElementById('status-ready'); | |
| const terminalTab = document.getElementById('terminal-tab'); | |
| const editorTab = document.getElementById('editor-tab'); | |
| const terminalContainer = document.getElementById('terminal-container'); | |
| const editorContainer = document.getElementById('editor-container'); | |
| const terminalContent = document.getElementById('terminal-content'); | |
| const terminalInput = document.getElementById('terminal-input'); | |
| const clearTerminalBtn = document.getElementById('clear-terminal'); | |
| const closeTerminalBtn = document.getElementById('close-terminal'); | |
| // Terminal state | |
| let terminalHistory = []; | |
| let historyIndex = -1; | |
| let currentDirectory = '~'; | |
| // Initialize line numbers | |
| function updateLineNumbers() { | |
| const lineNumbers = document.querySelector('.line-numbers'); | |
| const lines = editor.value.split('\n'); | |
| lineNumbers.innerHTML = ''; | |
| for (let i = 1; i <= lines.length; i++) { | |
| const lineNumber = document.createElement('div'); | |
| lineNumber.textContent = i; | |
| lineNumbers.appendChild(lineNumber); | |
| } | |
| } | |
| // Syntax highlighting (simplified) | |
| function applySyntaxHighlighting() { | |
| // This is a simplified version - a real implementation would use a proper lexer | |
| const code = editor.value; | |
| // Keywords to highlight | |
| const keywords = ['def', 'return', 'if', 'else', 'elif', 'for', 'while', 'in', 'and', 'or', 'not', 'True', 'False', 'None', 'import', 'from', 'as', 'class', 'try', 'except', 'finally', 'with', 'raise', 'is', 'lambda', 'nonlocal', 'global', 'yield', 'async', 'await']; | |
| // Simple regex-based highlighting | |
| let highlighted = code | |
| .replace(/(".*?"|'.*?')/g, '<span class="python-string">$1</span>') | |
| .replace(/#.*$/gm, '<span class="python-comment">$&</span>') | |
| .replace(/\b\d+\.?\d*\b/g, '<span class="python-number">$&</span>') | |
| .replace(new RegExp(`\\b(${keywords.join('|')})\\b`, 'g'), '<span class="python-keyword">$1</span>') | |
| .replace(/\b(def|class)\s+(\w+)\b/g, '<span class="python-keyword">$1</span> <span class="python-function">$2</span>'); | |
| // Create a temporary div to hold the highlighted code | |
| const tempDiv = document.createElement('div'); | |
| tempDiv.innerHTML = highlighted; | |
| // Get the cursor position | |
| const cursorPos = editor.selectionStart; | |
| // Replace the editor content (this will lose the cursor position) | |
| // In a real implementation, we would use a proper code editor library | |
| // that maintains cursor position during highlighting | |
| // For now, we'll just update the line numbers | |
| updateLineNumbers(); | |
| } | |
| // Run Python code | |
| async function runPythonCode() { | |
| const code = editor.value; | |
| output.textContent = 'Running...'; | |
| statusReady.textContent = 'Running'; | |
| runBtn.disabled = true; | |
| runBtn.classList.remove('bg-green-600', 'hover:bg-green-700'); | |
| runBtn.classList.add('bg-gray-600', 'cursor-not-allowed'); | |
| try { | |
| // In a real implementation, you would send this to a backend service | |
| // that can execute Python code safely. For this demo, we'll simulate | |
| // execution with a timeout and some example output. | |
| // Simulate network delay | |
| await new Promise(resolve => setTimeout(resolve, 500)); | |
| // Simulate execution | |
| const result = simulatePythonExecution(code); | |
| output.textContent = result; | |
| statusReady.textContent = 'Ready'; | |
| } catch (error) { | |
| output.textContent = `Error: ${error.message}`; | |
| statusReady.textContent = 'Error'; | |
| } finally { | |
| runBtn.disabled = false; | |
| runBtn.classList.add('bg-green-600', 'hover:bg-green-700'); | |
| runBtn.classList.remove('bg-gray-600', 'cursor-not-allowed'); | |
| } | |
| } | |
| // Simulate Python execution (for demo purposes) | |
| function simulatePythonExecution(code) { | |
| // This is just for demonstration - in a real app, you'd use a proper Python interpreter | |
| // Check for some common patterns to simulate different outputs | |
| if (code.includes('import os') && code.includes('os.system')) { | |
| return "Error: Restricted system call (os.system)"; | |
| } | |
| if (code.includes('while True:')) { | |
| return "Error: Potential infinite loop detected"; | |
| } | |
| if (code.includes('import sys') && code.includes('sys.exit')) { | |
| return "Process finished with exit code 0"; | |
| } | |
| // Default simulated output | |
| return `Hello, World! | |
| The answer is 48.28 | |
| Squares: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] | |
| Process finished with exit code 0`; | |
| } | |
| // Clear output | |
| function clearOutput() { | |
| output.textContent = ''; | |
| } | |
| // Toggle sidebar | |
| function toggleSidebar() { | |
| sidebar.classList.toggle('collapsed'); | |
| const icon = sidebarToggle.querySelector('i'); | |
| if (sidebar.classList.contains('collapsed')) { | |
| icon.classList.remove('fa-chevron-left'); | |
| icon.classList.add('fa-chevron-right'); | |
| } else { | |
| icon.classList.remove('fa-chevron-right'); | |
| icon.classList.add('fa-chevron-left'); | |
| } | |
| } | |
| // Terminal functions | |
| function showTerminal() { | |
| editorContainer.style.display = 'none'; | |
| terminalContainer.style.display = 'flex'; | |
| terminalInput.focus(); | |
| } | |
| function showEditor() { | |
| terminalContainer.style.display = 'none'; | |
| editorContainer.style.display = 'flex'; | |
| } | |
| function clearTerminal() { | |
| terminalContent.innerHTML = ` | |
| <div class="terminal-output"> | |
| PyWeb Terminal v1.0<br> | |
| Type 'help' for a list of commands<br><br> | |
| </div> | |
| <div class="terminal-line flex items-center"> | |
| <span class="terminal-prompt">user@pyweb:~$ </span> | |
| <input id="terminal-input" class="terminal-input" type="text" autofocus> | |
| <span class="terminal-cursor"></span> | |
| </div> | |
| `; | |
| terminalInput = document.getElementById('terminal-input'); | |
| terminalInput.focus(); | |
| setupTerminalInput(); | |
| } | |
| function setupTerminalInput() { | |
| terminalInput.addEventListener('keydown', function(e) { | |
| if (e.key === 'Enter') { | |
| const command = terminalInput.value.trim(); | |
| if (command) { | |
| terminalHistory.push(command); | |
| historyIndex = terminalHistory.length; | |
| processCommand(command); | |
| } | |
| } else if (e.key === 'ArrowUp') { | |
| if (terminalHistory.length > 0 && historyIndex > 0) { | |
| historyIndex--; | |
| terminalInput.value = terminalHistory[historyIndex]; | |
| e.preventDefault(); | |
| } | |
| } else if (e.key === 'ArrowDown') { | |
| if (terminalHistory.length > 0 && historyIndex < terminalHistory.length - 1) { | |
| historyIndex++; | |
| terminalInput.value = terminalHistory[historyIndex]; | |
| e.preventDefault(); | |
| } else if (historyIndex === terminalHistory.length - 1) { | |
| historyIndex = terminalHistory.length; | |
| terminalInput.value = ''; | |
| e.preventDefault(); | |
| } | |
| } | |
| }); | |
| } | |
| function processCommand(command) { | |
| // Add the command to the terminal output | |
| const outputDiv = document.createElement('div'); | |
| outputDiv.className = 'terminal-output'; | |
| outputDiv.innerHTML = `<span class="terminal-prompt">user@pyweb:~$ </span>${command}`; | |
| terminalContent.insertBefore(outputDiv, terminalContent.lastElementChild); | |
| // Process the command | |
| let response = ''; | |
| const args = command.split(' '); | |
| const cmd = args[0].toLowerCase(); | |
| switch (cmd) { | |
| case 'help': | |
| response = `Available commands:<br> | |
| help - Show this help message<br> | |
| clear - Clear the terminal<br> | |
| ls - List files<br> | |
| cd [dir] - Change directory<br> | |
| run - Run the current Python code<br> | |
| python [code] - Execute Python code<br> | |
| exit - Close the terminal`; | |
| break; | |
| case 'clear': | |
| clearTerminal(); | |
| return; | |
| case 'ls': | |
| response = `main.py<br>utils.py<br>README.md`; | |
| break; | |
| case 'cd': | |
| if (args.length > 1) { | |
| currentDirectory = args[1]; | |
| response = `Changed directory to ${currentDirectory}`; | |
| } else { | |
| response = `Usage: cd [directory]`; | |
| } | |
| break; | |
| case 'run': | |
| runPythonCode(); | |
| response = `Running Python code from editor...`; | |
| break; | |
| case 'python': | |
| if (args.length > 1) { | |
| const pythonCode = args.slice(1).join(' '); | |
| try { | |
| // This is just for demo - in a real app you'd use a proper interpreter | |
| if (pythonCode.includes('print')) { | |
| response = pythonCode.includes('"') ? | |
| pythonCode.match(/"([^"]*)"/)[1] : | |
| pythonCode.match(/'([^']*)'/)[1]; | |
| } else { | |
| response = `Executed: ${pythonCode}`; | |
| } | |
| } catch (e) { | |
| response = `Error: ${e.message}`; | |
| } | |
| } else { | |
| response = `Usage: python [code]`; | |
| } | |
| break; | |
| case 'exit': | |
| showEditor(); | |
| return; | |
| default: | |
| response = `Command not found: ${cmd}. Type 'help' for available commands.`; | |
| } | |
| // Add the response to the terminal | |
| const responseDiv = document.createElement('div'); | |
| responseDiv.className = 'terminal-output'; | |
| responseDiv.innerHTML = response; | |
| terminalContent.insertBefore(responseDiv, terminalContent.lastElementChild); | |
| // Add a new input line | |
| const newInputDiv = document.createElement('div'); | |
| newInputDiv.className = 'terminal-line flex items-center'; | |
| newInputDiv.innerHTML = ` | |
| <span class="terminal-prompt">user@pyweb:${currentDirectory}$ </span> | |
| <input id="terminal-input" class="terminal-input" type="text" autofocus> | |
| <span class="terminal-cursor"></span> | |
| `; | |
| terminalContent.appendChild(newInputDiv); | |
| // Remove the old input | |
| terminalContent.removeChild(terminalContent.lastElementChild.previousElementSibling); | |
| // Set up the new input | |
| terminalInput = document.getElementById('terminal-input'); | |
| setupTerminalInput(); | |
| terminalInput.focus(); | |
| } | |
| // Event Listeners | |
| editor.addEventListener('input', updateLineNumbers); | |
| editor.addEventListener('keydown', function(e) { | |
| if (e.key === 'Tab') { | |
| e.preventDefault(); | |
| const start = this.selectionStart; | |
| const end = this.selectionEnd; | |
| // Insert tab character | |
| this.value = this.value.substring(0, start) + ' ' + this.value.substring(end); | |
| // Move cursor | |
| this.selectionStart = this.selectionEnd = start + 4; | |
| updateLineNumbers(); | |
| } | |
| }); | |
| runBtn.addEventListener('click', runPythonCode); | |
| clearOutputBtn.addEventListener('click', clearOutput); | |
| sidebarToggle.addEventListener('click', toggleSidebar); | |
| terminalTab.addEventListener('click', showTerminal); | |
| editorTab.addEventListener('click', showEditor); | |
| clearTerminalBtn.addEventListener('click', clearTerminal); | |
| closeTerminalBtn.addEventListener('click', showEditor); | |
| // Initialize | |
| updateLineNumbers(); | |
| setupTerminalInput(); | |
| // Auto-resize editor when window resizes | |
| window.addEventListener('resize', function() { | |
| updateLineNumbers(); | |
| }); | |
| </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=ayoubghilmi/ayoub-edit-code" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |