| <!DOCTYPE html> |
| <html lang="bn"> |
| <head> |
| <meta charset="UTF-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"/> |
| <title>DAA — ডাক্তার অ্যাপয়েন্টমেন্ট সহকারী</title> |
| <link rel="preconnect" href="https://fonts.googleapis.com"> |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> |
| <link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=JetBrains+Mono:wght@300;400&family=Hind+Siliguri:wght@300;400;500;600&display=swap" rel="stylesheet"> |
| <link rel="stylesheet" href="style.css" /> |
| </head> |
| <body> |
|
|
| |
| <div class="bg-orb orb-1"></div> |
| <div class="bg-orb orb-2"></div> |
| <div class="bg-orb orb-3"></div> |
|
|
| |
| |
| |
| |
| <div id="init-overlay" class="init-overlay"> |
| <div class="init-card"> |
| <div class="init-logo"> |
| <svg width="56" height="56" viewBox="0 0 56 56" fill="none"> |
| <circle cx="28" cy="28" r="26" stroke="url(#g1)" stroke-width="2"/> |
| <path d="M18 28 Q28 16 38 28 Q28 40 18 28Z" fill="url(#g2)" opacity="0.9"/> |
| <defs> |
| <linearGradient id="g1" x1="0" y1="0" x2="56" y2="56"> |
| <stop offset="0%" stop-color="#22d3ee"/><stop offset="100%" stop-color="#818cf8"/> |
| </linearGradient> |
| <linearGradient id="g2" x1="0" y1="0" x2="56" y2="56"> |
| <stop offset="0%" stop-color="#22d3ee"/><stop offset="100%" stop-color="#818cf8"/> |
| </linearGradient> |
| </defs> |
| </svg> |
| </div> |
| <h2 class="init-title">AI Voice Assistant</h2> |
| <p class="init-subtitle">বাংলা ভয়েস সহকারী</p> |
|
|
| <div class="init-stages"> |
| <div class="stage" id="stage-1"> |
| <div class="stage-dot"></div> |
| <span>AI Engine শুরু হচ্ছে…</span> |
| <div class="stage-check">✓</div> |
| </div> |
| <div class="stage" id="stage-2"> |
| <div class="stage-dot"></div> |
| <span>Speech Recognition মডেল লোড হচ্ছে…</span> |
| <div class="stage-check">✓</div> |
| </div> |
| <div class="stage" id="stage-3"> |
| <div class="stage-dot"></div> |
| <span>GPU Warmup চলছে…</span> |
| <div class="stage-check">✓</div> |
| </div> |
| <div class="stage" id="stage-4"> |
| <div class="stage-dot"></div> |
| <span>Voice Pipeline প্রস্তুত হচ্ছে…</span> |
| <div class="stage-check">✓</div> |
| </div> |
| </div> |
|
|
| <div class="init-bar-wrap"> |
| <div class="init-bar" id="init-bar"></div> |
| </div> |
| <p class="init-status" id="init-status">সংযোগ স্থাপন করা হচ্ছে…</p> |
| </div> |
| </div> |
|
|
| |
| |
| |
| |
| |
| <div class="app" id="app"> |
|
|
| |
| <aside class="sidebar" id="sidebar"> |
| <div class="sidebar-header"> |
| <div class="brand"> |
| <svg width="28" height="28" viewBox="0 0 56 56" fill="none"> |
| <circle cx="28" cy="28" r="26" stroke="url(#gs1)" stroke-width="2"/> |
| <path d="M18 28 Q28 16 38 28 Q28 40 18 28Z" fill="url(#gs2)" opacity="0.9"/> |
| <defs> |
| <linearGradient id="gs1" x1="0" y1="0" x2="56" y2="56"> |
| <stop offset="0%" stop-color="#22d3ee"/><stop offset="100%" stop-color="#818cf8"/> |
| </linearGradient> |
| <linearGradient id="gs2" x1="0" y1="0" x2="56" y2="56"> |
| <stop offset="0%" stop-color="#22d3ee"/><stop offset="100%" stop-color="#818cf8"/> |
| </linearGradient> |
| </defs> |
| </svg> |
| <span>DAA Assistant</span> |
| </div> |
| <button class="sidebar-toggle" id="sidebar-toggle" title="Toggle sidebar">‹</button> |
| </div> |
|
|
| |
| <div class="status-panel"> |
| <div class="status-row"> |
| <span class="status-label">System</span> |
| <span class="status-badge badge-green" id="sys-status">Ready</span> |
| </div> |
| <div class="status-row"> |
| <span class="status-label">STT</span> |
| <span class="status-badge badge-green" id="stt-status">Online</span> |
| </div> |
| <div class="status-row"> |
| <span class="status-label">LLM</span> |
| <span class="status-badge badge-green" id="llm-status">Gemini 2.0</span> |
| </div> |
| <div class="status-row"> |
| <span class="status-label">TTS</span> |
| <span class="status-badge badge-green" id="tts-status">Edge TTS</span> |
| </div> |
| </div> |
|
|
| <div class="sidebar-divider"></div> |
|
|
| |
| <div class="dash-section"> |
| <div class="dash-title">⚡ Latency Dashboard</div> |
| <div class="metric-grid"> |
| <div class="metric-card"> |
| <div class="metric-val" id="m-stt">—</div> |
| <div class="metric-label">STT (ms)</div> |
| </div> |
| <div class="metric-card"> |
| <div class="metric-val" id="m-llm">—</div> |
| <div class="metric-label">LLM (ms)</div> |
| </div> |
| <div class="metric-card"> |
| <div class="metric-val" id="m-tts">—</div> |
| <div class="metric-label">TTS (ms)</div> |
| </div> |
| <div class="metric-card"> |
| <div class="metric-val" id="m-total">—</div> |
| <div class="metric-label">Total (ms)</div> |
| </div> |
| </div> |
| </div> |
|
|
| <div class="sidebar-divider"></div> |
|
|
| |
| <div class="dash-section"> |
| <div class="dash-title">🎛️ Voice Settings</div> |
| <div class="setting-row"> |
| <label>Silence Threshold</label> |
| <div class="slider-wrap"> |
| <input type="range" id="s-threshold" min="-60" max="-20" value="-32" step="1"> |
| <span id="s-threshold-val">-32 dB</span> |
| </div> |
| </div> |
| <div class="setting-row"> |
| <label>Silence Timeout</label> |
| <div class="slider-wrap"> |
| <input type="range" id="s-timeout" min="300" max="2000" value="900" step="50"> |
| <span id="s-timeout-val">900 ms</span> |
| </div> |
| </div> |
| <div class="setting-row"> |
| <label>TTS Voice</label> |
| <select id="s-voice" class="setting-select"> |
| <option value="bn-BD-NabanitaNeural">Nabanita (Female)</option> |
| <option value="bn-BD-PradeepNeural">Pradeep (Male)</option> |
| <option value="bn-IN-BashkarNeural">Bashkar (IN Male)</option> |
| <option value="bn-IN-TanishaaNeural">Tanishaa (IN Female)</option> |
| </select> |
| </div> |
| </div> |
|
|
| <div class="sidebar-divider"></div> |
|
|
| |
| <div class="dash-section"> |
| <div class="dash-title">📊 Audio Stream</div> |
| <div class="queue-vis" id="queue-vis"> |
| <div class="queue-bar" style="height:4px"></div> |
| <div class="queue-bar" style="height:4px"></div> |
| <div class="queue-bar" style="height:4px"></div> |
| <div class="queue-bar" style="height:4px"></div> |
| <div class="queue-bar" style="height:4px"></div> |
| <div class="queue-bar" style="height:4px"></div> |
| <div class="queue-bar" style="height:4px"></div> |
| <div class="queue-bar" style="height:4px"></div> |
| </div> |
| <div class="queue-label">Chunks in flight: <span id="chunks-count">0</span></div> |
| </div> |
| </aside> |
|
|
| |
| <main class="main"> |
|
|
| |
| <header class="topbar"> |
| <div class="topbar-left"> |
| <button class="mobile-menu-btn" id="mobile-menu-btn">☰</button> |
| <div class="topbar-state"> |
| <div class="state-dot" id="state-dot"></div> |
| <span id="state-label">প্রস্তুত</span> |
| </div> |
| </div> |
| <div class="topbar-center"> |
| <span class="topbar-title">🏥 ডাক্তার অ্যাপয়েন্টমেন্ট সহকারী</span> |
| </div> |
| <div class="topbar-right"> |
| <button class="clear-btn" id="clear-btn" title="Clear conversation">↺ Clear</button> |
| </div> |
| </header> |
|
|
| |
| <div id="chat-box"></div> |
|
|
| |
| <div class="voice-visualizer" id="voice-viz"> |
| <div class="viz-bar"></div><div class="viz-bar"></div><div class="viz-bar"></div> |
| <div class="viz-bar"></div><div class="viz-bar"></div><div class="viz-bar"></div> |
| <div class="viz-bar"></div><div class="viz-bar"></div><div class="viz-bar"></div> |
| <div class="viz-bar"></div><div class="viz-bar"></div><div class="viz-bar"></div> |
| <div class="viz-bar"></div><div class="viz-bar"></div><div class="viz-bar"></div> |
| </div> |
|
|
| |
| <footer class="controls"> |
| <div class="text-row"> |
| |
| |
| <input |
| type="text" |
| id="text-input" |
| placeholder="বার্তা লিখুন… (Enter পাঠান · Shift+Enter নতুন লাইন)" |
| autocomplete="off" |
| /> |
| <button id="send-btn" title="Send"> |
| <svg width="20" height="20" viewBox="0 0 24 24" fill="none" |
| stroke="currentColor" stroke-width="2"> |
| <line x1="22" y1="2" x2="11" y2="13"/> |
| <polygon points="22 2 15 22 11 13 2 9 22 2"/> |
| </svg> |
| </button> |
| </div> |
| <div class="voice-row"> |
| <button id="mic-btn" class="mic-btn mic-off"> |
| <span class="mic-icon">🎤</span> |
| <span class="mic-label">Voice শুরু করুন</span> |
| </button> |
| <button id="stop-btn" class="stop-btn" title="Stop AI speech"> |
| <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"> |
| <rect x="4" y="4" width="16" height="16" rx="2"/> |
| </svg> |
| Stop |
| </button> |
| </div> |
| </footer> |
| </main> |
| </div> |
|
|
| <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> |
| <script src="script.js"></script> |
| </body> |
| </html> |
|
|