| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>API Configuration - NeuralOutlaw</title> |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <script src="https://unpkg.com/feather-icons"></script> |
| <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script> |
| <style> |
| @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700&family=Orbitron:wght@400;500;700;900&display=swap'); |
| |
| body { |
| font-family: 'JetBrains Mono', monospace; |
| overflow-x: hidden; |
| } |
| |
| .cyber-gradient { |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| } |
| |
| .matrix-bg { |
| position: fixed; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| z-index: -1; |
| opacity: 0.1; |
| } |
| |
| .glitch-text { |
| position: relative; |
| display: inline-block; |
| } |
| |
| .glitch-text::before, |
| .glitch-text::after { |
| content: attr(data-text); |
| position: absolute; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| } |
| |
| .glitch-text::before { |
| left: 2px; |
| text-shadow: -1px 0 #ff00ff; |
| animation: glitch-1 2s infinite linear alternate-reverse; |
| } |
| |
| .glitch-text::after { |
| left: -2px; |
| text-shadow: 1px 0 #00ffff; |
| animation: glitch-2 3s infinite linear alternate-reverse; |
| } |
| |
| @keyframes glitch-1 { |
| 0% { clip-path: inset(20% 0 65% 0); } |
| 20% { clip-path: inset(60% 0 5% 0); } |
| 40% { clip-path: inset(30% 0 45% 0); } |
| 60% { clip-path: inset(75% 0 15% 0); } |
| 80% { clip-path: inset(10% 0 70% 0); } |
| 100% { clip-path: inset(45% 0 35% 0); } |
| } |
| |
| @keyframes glitch-2 { |
| 0% { clip-path: inset(65% 0 20% 0); } |
| 20% { clip-path: inset(5% 0 60% 0); } |
| 40% { clip-path: inset(45% 0 30% 0); } |
| 60% { clip-path: inset(15% 0 75% 0); } |
| 80% { clip-path: inset(70% 0 10% 0); } |
| 100% { clip-path: inset(35% 0 45% 0); } |
| } |
| |
| .terminal-window { |
| background: rgba(0, 0, 0, 0.8); |
| border: 1px solid #00ffff; |
| box-shadow: 0 0 20px rgba(0, 255, 255, 0.5); |
| border-radius: 8px; |
| overflow: hidden; |
| } |
| |
| .terminal-header { |
| background: rgba(0, 0, 0, 0.9); |
| padding: 8px 15px; |
| border-bottom: 1px solid #00ffff; |
| } |
| |
| .terminal-body { |
| padding: 20px; |
| color: #00ff00; |
| font-family: 'JetBrains Mono', monospace; |
| } |
| |
| .terminal-prompt { |
| color: #00ffff; |
| } |
| |
| .cyber-button { |
| background: linear-gradient(45deg, #ff00ff, #00ffff); |
| border: none; |
| color: black; |
| font-weight: bold; |
| padding: 12px 24px; |
| border-radius: 4px; |
| cursor: pointer; |
| transition: all 0.3s ease; |
| position: relative; |
| overflow: hidden; |
| } |
| |
| .cyber-button:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 5px 15px rgba(255, 0, 255, 0.4); |
| } |
| |
| .cyber-button:active { |
| transform: translateY(0); |
| } |
| |
| .code-input { |
| background: rgba(0, 0, 0, 0.7); |
| border: 1px solid #00ffff; |
| color: #00ff00; |
| padding: 15px; |
| border-radius: 4px; |
| font-family: 'JetBrains Mono', monospace; |
| width: 100%; |
| resize: vertical; |
| } |
| |
| .api-status { |
| padding: 10px; |
| border-radius: 4px; |
| margin: 10px 0; |
| text-align: center; |
| font-weight: bold; |
| } |
| |
| .status-connected { |
| background: rgba(0, 255, 0, 0.2); |
| border: 1px solid #00ff00; |
| color: #00ff00; |
| } |
| |
| .status-disconnected { |
| background: rgba(255, 0, 0, 0.2); |
| border: 1px solid #ff0000; |
| color: #ff0000; |
| } |
| |
| |
| ::-webkit-scrollbar { |
| width: 8px; |
| } |
| |
| ::-webkit-scrollbar-track { |
| background: rgba(0, 0, 0, 0.3); |
| } |
| |
| ::-webkit-scrollbar-thumb { |
| background: #00ffff; |
| border-radius: 4px; |
| } |
| |
| ::-webkit-scrollbar-thumb:hover { |
| background: #ff00ff; |
| } |
| </style> |
| </head> |
| <body class="bg-black text-white"> |
| |
| <canvas id="matrix" class="matrix-bg"></canvas> |
| |
| |
| <div id="vanta-bg"></div> |
| |
| |
| <nav class="fixed w-full z-50 bg-black bg-opacity-80 backdrop-blur-md border-b border-cyan-500"> |
| <div class="container mx-auto px-4 py-3 flex justify-between items-center"> |
| <div class="flex items-center"> |
| <h1 class="text-xl font-bold cyber-gradient bg-clip-text text-transparent glitch-text" data-text="NeuralOutlaw">NeuralOutlaw</h1> |
| </div> |
| <div class="flex space-x-6"> |
| <a href="index.html" class="text-cyan-300 hover:text-pink-500 transition-colors">Home</a> |
| <a href="coder.html" class="text-cyan-300 hover:text-pink-500 transition-colors">AI Coder</a> |
| <a href="api-config.html" class="text-cyan-300 hover:text-pink-500 transition-colors">API Config</a> |
| <a href="requests.html" class="text-cyan-300 hover:text-pink-500 transition-colors">Shadow Requests</a> |
| <a href="about.html" class="text-cyan-300 hover:text-pink-500 transition-colors">About</a> |
| </div> |
| </div> |
| </nav> |
| |
| |
| <section class="min-h-screen flex items-center justify-center pt-16 pb-20 px-4"> |
| <div class="container mx-auto max-w-4xl"> |
| <h1 class="text-4xl md:text-5xl font-bold text-center mb-8 glitch-text" data-text="API CONFIGURATION">API CONFIGURATION</h1> |
| <p class="text-lg text-cyan-300 text-center mb-12">Configure your AI API keys for unrestricted code generation</p> |
| |
| <div class="terminal-window max-w-2xl mx-auto"> |
| <div class="terminal-header flex items-center"> |
| <div class="flex space-x-2"> |
| <div class="w-3 h-3 rounded-full bg-red-500"></div> |
| <div class="w-3 h-3 rounded-full bg-yellow-500"></div> |
| <div class="w-3 h-3 rounded-full bg-green-500"></div> |
| </div> |
| <div class="flex-1 text-center text-sm">api_config_terminal</div> |
| </div> |
| <div class="terminal-body"> |
| |
| <div id="apiStatus" class="api-status status-disconnected"> |
| <span class="terminal-prompt">STATUS:</span> DISCONNECTED |
| </div> |
| |
| |
| <div class="mb-6"> |
| <label for="openaiKey" class="block text-cyan-300 mb-2">OpenAI API Key:</label> |
| <input |
| type="password" |
| id="openaiKey" |
| class="code-input w-full" |
| placeholder="sk-..." |
| value="" |
| /> |
| <p class="text-gray-400 text-sm mt-1"> |
| Get your API key from <a href="https://platform.openai.com/api-keys" target="_blank" class="text-cyan-300 underline">OpenAI Platform</a> |
| </p> |
| </div> |
| |
| |
| <div class="mb-6"> |
| <label for="customApiUrl" class="block text-cyan-300 mb-2">Custom API Endpoint (Optional):</label> |
| <input |
| type="text" |
| id="customApiUrl" |
| class="code-input w-full" |
| placeholder="https://api.example.com/v1/chat/completions" |
| value="" |
| /> |
| </div> |
| |
| |
| <div class="mb-6"> |
| <button id="testConnection" class="cyber-button w-full mb-4">Test Connection</button> |
| <div id="testResult" class="hidden text-center text-sm"></div> |
| </div> |
| |
| |
| <div class="mb-4"> |
| <button id="saveConfig" class="cyber-button w-full">Save Configuration</button> |
| </div> |
| |
| |
| <div class="mt-8 p-4 bg-gray-900 bg-opacity-50 rounded border border-cyan-800"> |
| <h3 class="text-cyan-300 font-bold mb-2">Configuration Instructions:</h3> |
| <ul class="text-sm text-gray-300 space-y-1"> |
| <li>• Enter your OpenAI API key for real code generation</li> |
| <li>• Optionally configure a custom API endpoint</li> |
| <li>• Test the connection before saving</li> |
| <li>• Your API key is stored locally in your browser</li> |
| <li>• Never share your API key with anyone</li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="terminal-window max-w-2xl mx-auto mt-8"> |
| <div class="terminal-header flex items-center"> |
| <div class="flex space-x-2"> |
| <div class="w-3 h-3 rounded-full bg-red-500"></div> |
| <div class="w-3 h-3 rounded-full bg-yellow-500"></div> |
| <div class="w-3 h-3 rounded-full bg-green-500"></div> |
| </div> |
| <div class="flex-1 text-center text-sm">current_config</div> |
| </div> |
| <div class="terminal-body"> |
| <div id="currentConfig" class="text-gray-300"> |
| <span class="terminal-prompt">AI@neuraloutlaw:~$</span> No configuration saved |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
| |
| |
| <footer class="py-8 px-4 border-t border-cyan-900 bg-black bg-opacity-80"> |
| <div class="container mx-auto text-center"> |
| <p class="text-gray-400">NeuralOutlaw Coder AI 🦹 - Pushing the boundaries of AI-assisted development</p> |
| <p class="text-gray-500 text-sm mt-2">Use responsibly. The creators are not responsible for any unauthorized usage.</p> |
| </div> |
| </footer> |
|
|
| <script> |
| |
| VANTA.GLOBE({ |
| el: "#vanta-bg", |
| mouseControls: true, |
| touchControls: true, |
| gyroControls: false, |
| minHeight: 200.00, |
| minWidth: 200.00, |
| scale: 1.00, |
| scaleMobile: 1.00, |
| color: 0x00ffff, |
| backgroundColor: 0x0, |
| size: 0.8 |
| }); |
| |
| |
| const canvas = document.getElementById('matrix'); |
| const ctx = canvas.getContext('2d'); |
| |
| function resizeCanvas() { |
| canvas.width = window.innerWidth; |
| canvas.height = window.innerHeight; |
| } |
| |
| resizeCanvas(); |
| window.addEventListener('resize', resizeCanvas); |
| |
| const chars = "01"; |
| const charArray = chars.split(""); |
| const fontSize = 14; |
| const columns = canvas.width / fontSize; |
| const drops = []; |
| |
| for(let x = 0; x < columns; x++) { |
| drops[x] = 1; |
| } |
| |
| function drawMatrix() { |
| ctx.fillStyle = "rgba(0, 0, 0, 0.04)"; |
| ctx.fillRect(0, 0, canvas.width, canvas.height); |
| |
| ctx.fillStyle = "#0f0"; |
| ctx.font = fontSize + "px monospace"; |
| |
| for(let i = 0; i < drops.length; i++) { |
| const text = charArray[Math.floor(Math.random() * charArray.length)]; |
| ctx.fillText(text, i * fontSize, drops[i] * fontSize); |
| |
| if(drops[i] * fontSize > canvas.height && Math.random() > 0.975) { |
| drops[i] = 0; |
| } |
| |
| drops[i]++; |
| } |
| } |
| |
| setInterval(drawMatrix, 35); |
| |
| |
| document.addEventListener('DOMContentLoaded', function() { |
| const openaiKeyInput = document.getElementById('openaiKey'); |
| const customApiUrlInput = document.getElementById('customApiUrl'); |
| const testConnectionBtn = document.getElementById('testConnection'); |
| const saveConfigBtn = document.getElementById('saveConfig'); |
| const testResultDiv = document.getElementById('testResult'); |
| const apiStatusDiv = document.getElementById('apiStatus'); |
| const currentConfigDiv = document.getElementById('currentConfig'); |
| |
| |
| const savedConfig = localStorage.getItem('neuraloutlaw_api_config'); |
| if (savedConfig) { |
| const config = JSON.parse(savedConfig); |
| openaiKeyInput.value = config.openaiKey || ''; |
| customApiUrlInput.value = config.customApiUrl || ''; |
| updateApiStatus(config.openaiKey); |
| updateCurrentConfig(config); |
| } |
| |
| |
| testConnectionBtn.addEventListener('click', async function() { |
| const openaiKey = openaiKeyInput.value.trim(); |
| const customApiUrl = customApiUrlInput.value.trim(); |
| |
| if (!openaiKey && !customApiUrl) { |
| testResultDiv.innerHTML = '<span class="text-red-400">Error: Please enter either OpenAI API key or custom API URL</span>'; |
| testResultDiv.classList.remove('hidden'); |
| return; |
| } |
| |
| testConnectionBtn.disabled = true; |
| testConnectionBtn.textContent = 'Testing...'; |
| testResultDiv.innerHTML = '<span class="text-cyan-300">Testing connection to API...</span>'; |
| testResultDiv.classList.remove('hidden'); |
| |
| try { |
| let response; |
| if (openaiKey) { |
| |
| response = await fetch('https://api.openai.com/v1/models', { |
| method: 'GET', |
| headers: { |
| 'Authorization': `Bearer ${openaiKey}` |
| } |
| }); |
| } else if (customApiUrl) { |
| |
| response = await fetch(customApiUrl, { |
| method: 'GET', |
| headers: { |
| 'Content-Type': 'application/json' |
| } |
| }); |
| } |
| |
| if (response.ok) { |
| testResultDiv.innerHTML = '<span class="text-green-400">✓ Connection successful! API is ready.</span>'; |
| apiStatusDiv.className = 'api-status status-connected'; |
| apiStatusDiv.innerHTML = '<span class="terminal-prompt">STATUS:</span> CONNECTED'; |
| } else { |
| throw new Error(`API returned status: ${response.status}`); |
| } |
| } catch (error) { |
| testResultDiv.innerHTML = `<span class="text-red-400">✗ Connection failed: ${error.message}</span>`; |
| apiStatusDiv.className = 'api-status status-disconnected'; |
| apiStatusDiv.innerHTML = '<span class="terminal-prompt">STATUS:</span> DISCONNECTED'; |
| } finally { |
| testConnectionBtn.disabled = false; |
| testConnectionBtn.textContent = 'Test Connection'; |
| } |
| }); |
| |
| |
| saveConfigBtn.addEventListener('click', function() { |
| const openaiKey = openaiKeyInput.value.trim(); |
| const customApiUrl = customApiUrlInput.value.trim(); |
| |
| const config = { |
| openaiKey: openaiKey, |
| customApiUrl: customApiUrl, |
| lastUpdated: new Date().toISOString() |
| }; |
| |
| localStorage.setItem('neuraloutlaw_api_config', JSON.stringify(config)); |
| |
| updateApiStatus(openaiKey); |
| updateCurrentConfig(config); |
| |
| testResultDiv.innerHTML = '<span class="text-green-400">Configuration saved successfully!</span>'; |
| testResultDiv.classList.remove('hidden'); |
| |
| |
| setTimeout(() => { |
| testResultDiv.classList.add('hidden'); |
| }, 3000); |
| }); |
| |
| function updateApiStatus(openaiKey) { |
| if (openaiKey) { |
| apiStatusDiv.className = 'api-status status-connected'; |
| apiStatusDiv.innerHTML = '<span class="terminal-prompt">STATUS:</span> CONNECTED'; |
| } else { |
| apiStatusDiv.className = 'api-status status-disconnected'; |
| apiStatusDiv.innerHTML = '<span class="terminal-prompt">STATUS:</span> DISCONNECTED'; |
| } |
| } |
| |
| function updateCurrentConfig(config) { |
| let configText = `<span class="terminal-prompt">AI@neuraloutlaw:~$</span> Current Configuration:\n\n`; |
| configText += `OpenAI API Key: ${config.openaiKey ? '✓ Configured' : '✗ Not set'}\n`; |
| configText += `Custom API URL: ${config.customApiUrl || 'Not set'}\n`; |
| configText += `Last Updated: ${new Date(config.lastUpdated).toLocaleString()}`; |
| |
| currentConfigDiv.innerHTML = configText.replace(/\n/g, '<br>'); |
| } |
| }); |
| |
| |
| feather.replace(); |
| </script> |
| </body> |
| </html> |