Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Hugging Face Space demo</title> | |
| <style> | |
| body { | |
| font-family: Arial, sans-serif; | |
| margin: 0; | |
| padding: 0; | |
| background-color: #f0f2f5; | |
| } | |
| .container { | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| height: 100vh; | |
| } | |
| .login-container { | |
| background-color: #fff; | |
| padding: 40px; | |
| border-radius: 8px; | |
| box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | |
| width: 350px; | |
| text-align: center; | |
| } | |
| .login-container h2 { | |
| margin-bottom: 20px; | |
| color: #333; | |
| } | |
| .login-container input[type="text"], | |
| .login-container input[type="password"] { | |
| width: calc(100% - 20px); | |
| padding: 10px; | |
| margin: 10px 0; | |
| border: 1px solid #ccc; | |
| border-radius: 4px; | |
| } | |
| .login-container .captcha-container { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| margin: 10px 0; | |
| } | |
| .login-container .captcha-container input { | |
| width: 120px; | |
| margin-right: 10px; | |
| } | |
| .login-container .captcha-container #captcha-text { | |
| font-family: 'Courier New', Courier, monospace; | |
| font-size: 24px; | |
| font-style: italic; | |
| text-decoration: line-through; | |
| background-color: #e9e9e9; | |
| padding: 5px 10px; | |
| border-radius: 4px; | |
| user-select: none; | |
| cursor: pointer; | |
| } | |
| .login-container button { | |
| width: 100%; | |
| padding: 12px; | |
| background-color: #007bff; | |
| border: none; | |
| color: white; | |
| font-size: 16px; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| margin-top: 20px; | |
| } | |
| .login-container button:hover { | |
| background-color: #0056b3; | |
| } | |
| #main-system { | |
| display: none; | |
| width: 100vw; | |
| height: 100vh; | |
| } | |
| .system-header { | |
| background-color: #2c3e50; | |
| color: #ecf0f1; | |
| padding: 15px 20px; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); | |
| } | |
| .system-header h1 { | |
| margin: 0; | |
| font-size: 24px; | |
| } | |
| .system-header h2 { | |
| margin: 0; | |
| font-size: 14px; | |
| color: #bdc3c7; | |
| } | |
| .system-header button { | |
| background-color: #e74c3c; | |
| border: none; | |
| color: white; | |
| padding: 8px 15px; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| } | |
| .system-header button:hover { | |
| background-color: #c0392b; | |
| } | |
| .system-content { | |
| display: flex; | |
| height: calc(100vh - 60px); | |
| } | |
| .sidebar { | |
| width: 250px; | |
| background-color: #34495e; | |
| padding: 20px; | |
| box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); | |
| } | |
| .sidebar a { | |
| display: block; | |
| color: #ecf0f1; | |
| text-decoration: none; | |
| padding: 15px; | |
| margin-bottom: 10px; | |
| border-radius: 5px; | |
| transition: background-color 0.3s; | |
| } | |
| .sidebar a:hover, .sidebar a.active { | |
| background-color: #1abc9c; | |
| } | |
| .iframe-container { | |
| flex-grow: 1; | |
| padding: 20px; | |
| background-color: #f9f9f9; | |
| overflow: hidden; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| iframe { | |
| width: 100%; | |
| height: 100%; | |
| border: 1px solid #ccc; | |
| border-radius: 8px; | |
| box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="login-page" class="container"> | |
| <div class="login-container"> | |
| <h2>Hugging Face Space demo</h2> | |
| <p>cjhuang@2025copyright</p> | |
| <input type="text" id="username" placeholder="Username" required> | |
| <input type="password" id="password" placeholder="Password" required> | |
| <div class="captcha-container"> | |
| <input type="text" id="captcha-input" placeholder="Enter CAPTCHA" required> | |
| <span id="captcha-text" onclick="generateCaptcha()"></span> | |
| </div> | |
| <button onclick="handleLogin()">Login</button> | |
| </div> | |
| </div> | |
| <div id="main-system"> | |
| <div class="system-header"> | |
| <div> | |
| <h1>Hugging Face Space demo</h1> | |
| <h2>cjhuang@2025copyright</h2> | |
| </div> | |
| <button onclick="logout()">Logout</button> | |
| </div> | |
| <div class="system-content"> | |
| <div class="sidebar"> | |
| <a href="#" id="api-tab" class="active" onclick="showIframe('iframe01', this)">多模態API</a> | |
| <a href="#" id="webcam-tab" onclick="showIframe('iframe02', this)">WEBCAM_LineBot</a> | |
| </div> | |
| <div class="iframe-container"> | |
| <iframe id="iframe01" src="https://cjian2025-groq-api-gradio.hf.space" frameborder="0"></iframe> | |
| <iframe id="iframe02" src="https://cjian2025-webcam-groq-linebot-application.hf.space" frameborder="0" style="display: none;"></iframe> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| let captchaValue = ''; | |
| // 使用 SHA-256 加密的帳號和密碼 HASH 值 | |
| const USER_HASH = '17721868461f8a846c4f02a6c8e312489c670a418525e98544490f23f03b22b6'; // HASH of 'ROOT2025' | |
| const PASS_HASH = '1e374ffc8b82e2f694a974f07a51ac7a86f1b3e5828de316827038e530664972'; // HASH of '123456' | |
| async function hashString(str) { | |
| const encoder = new TextEncoder(); | |
| const data = encoder.encode(str); | |
| const hashBuffer = await crypto.subtle.digest('SHA-256', data); | |
| const hashArray = Array.from(new Uint8Array(hashBuffer)); | |
| const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); | |
| return hashHex; | |
| } | |
| function generateCaptcha() { | |
| const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; | |
| let result = ''; | |
| for (let i = 0; i < 6; i++) { | |
| result += chars.charAt(Math.floor(Math.random() * chars.length)); | |
| } | |
| captchaValue = result; | |
| document.getElementById('captcha-text').innerText = captchaValue; | |
| } | |
| async function handleLogin() { | |
| const username = document.getElementById('username').value; | |
| const password = document.getElementById('password').value; | |
| const captchaInput = document.getElementById('captcha-input').value; | |
| const hashedUsername = await hashString(username); | |
| const hashedPassword = await hashString(password); | |
| if (hashedUsername === USER_HASH && hashedPassword === PASS_HASH && captchaInput === captchaValue) { | |
| document.getElementById('login-page').style.display = 'none'; | |
| document.getElementById('main-system').style.display = 'block'; | |
| } else { | |
| alert('Invalid username, password, or CAPTCHA. Please try again.'); | |
| generateCaptcha(); | |
| } | |
| } | |
| function logout() { | |
| document.getElementById('main-system').style.display = 'none'; | |
| document.getElementById('login-page').style.display = 'flex'; | |
| document.getElementById('username').value = ''; | |
| document.getElementById('password').value = ''; | |
| document.getElementById('captcha-input').value = ''; | |
| generateCaptcha(); | |
| } | |
| function showIframe(iframeId, element) { | |
| const iframes = document.querySelectorAll('.iframe-container iframe'); | |
| iframes.forEach(iframe => { | |
| iframe.style.display = 'none'; | |
| }); | |
| document.getElementById(iframeId).style.display = 'block'; | |
| const tabs = document.querySelectorAll('.sidebar a'); | |
| tabs.forEach(tab => { | |
| tab.classList.remove('active'); | |
| }); | |
| element.classList.add('active'); | |
| } | |
| // Initialize CAPTCHA on page load | |
| window.onload = generateCaptcha; | |
| </script> | |
| </body> | |
| </html> |