Spaces:
Sleeping
Sleeping
| <html lang="zh-TW"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ILRDF 太魯閣語 AI 翻譯助手 | Web 旗艦版</title> | |
| <link rel="stylesheet" href="/static/style.css?v=20260727_3"> | |
| <!-- FontAwesome icons --> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <!-- Google tag (gtag.js) --> | |
| <script async src="https://www.googletagmanager.com/gtag/js?id=G-4M6KQ8KSY5"></script> | |
| <script> | |
| window.dataLayer = window.dataLayer || []; | |
| function gtag(){dataLayer.push(arguments);} | |
| gtag('js', new Date()); | |
| gtag('config', 'G-4M6KQ8KSY5'); | |
| </script> | |
| </head> | |
| <body> | |
| <!-- 導覽列 Navbar --> | |
| <nav class="navbar"> | |
| <div class="brand"> | |
| <i class="fa-solid fa-cube brand-icon"></i> | |
| <span class="brand-title">ILRDF 太魯閣語 AI 翻譯助手</span> | |
| <span class="brand-tag"><i class="fa-solid fa-bolt"></i> Web 旗艦版</span> | |
| </div> | |
| <div class="tribe-selector-container"> | |
| <span class="tribe-selector-label"><i class="fa-solid fa-globe"></i> 選擇目標族語:</span> | |
| <select id="tribeSelect" class="tribe-select" disabled> | |
| <option value="太魯閣語" selected>太魯閣語</option> | |
| </select> | |
| </div> | |
| </nav> | |
| <!-- 主應用內容 App Container --> | |
| <div class="app-container"> | |
| <!-- 功能分頁頁籤 Header Tabs --> | |
| <div class="tabs-header"> | |
| <button class="tab-btn active" data-tab="text-tab"> | |
| <i class="fa-solid fa-language"></i> 文字翻譯 | |
| </button> | |
| <button class="tab-btn" data-tab="audio-tab"> | |
| <i class="fa-solid fa-microphone-lines"></i> 語音辨識與聽寫 | |
| </button> | |
| <button class="tab-btn" data-tab="image-tab"> | |
| <i class="fa-solid fa-image"></i> 圖片 OCR 翻譯 | |
| </button> | |
| <button class="tab-btn" data-tab="video-tab"> | |
| <i class="fa-solid fa-file-video"></i> 影片音軌翻譯 | |
| </button> | |
| <button class="tab-btn" data-tab="feedback-tab"> | |
| <i class="fa-solid fa-comment-dots"></i> 建議與報錯 | |
| </button> | |
| </div> | |
| <!-- 1. 文字翻譯面板 (Text Tab) --> | |
| <div id="text-tab" class="tab-content active"> | |
| <div class="glass-card"> | |
| <!-- 翻譯方向模式選單 --> | |
| <div class="direction-selector-bar"> | |
| <span class="direction-label"><i class="fa-solid fa-right-left"></i> 翻譯方向模式:</span> | |
| <div class="direction-options"> | |
| <button class="dir-btn active" data-mode="zh_to_native"> | |
| 華語 ➔ <span class="current-tribe-label">太魯閣語</span> (華語翻族語) | |
| </button> | |
| <button class="dir-btn" data-mode="native_to_zh"> | |
| <span class="current-tribe-label">太魯閣語</span> ➔ 華語 (族語翻華語) | |
| </button> | |
| <button class="dir-btn" data-mode="auto"> | |
| ⚡ 自動判斷 | |
| </button> | |
| </div> | |
| </div> | |
| <div class="translation-grid"> | |
| <!-- 輸入區 --> | |
| <div class="input-box-wrapper"> | |
| <div class="box-header"> | |
| <span id="inputBoxTitle"><i class="fa-regular fa-pen-to-square"></i> 原文輸入 (華語)</span> | |
| <span id="charCount">0 字</span> | |
| </div> | |
| <textarea id="textInput" class="text-area-styled" placeholder="請在此輸入華語,將自動翻譯為【太魯閣語】..."></textarea> | |
| </div> | |
| <!-- 輸出區 --> | |
| <div class="output-box-wrapper"> | |
| <div class="box-header"> | |
| <span><i class="fa-solid fa-wand-magic-sparkles"></i> AI 翻譯結果 (<span class="current-tribe-label">太魯閣語</span>)</span> | |
| <span id="speedTimer"><i class="fa-regular fa-clock"></i> 耗時: -</span> | |
| </div> | |
| <div id="textOutput" class="output-styled empty"> | |
| 翻譯結果將顯示於此... | |
| </div> | |
| </div> | |
| </div> | |
| <!-- 動作按鈕列 --> | |
| <div class="btn-group"> | |
| <button id="translateBtn" class="btn btn-primary"> | |
| <i class="fa-solid fa-paper-plane"></i> 開始極速翻譯 | |
| </button> | |
| <button id="swapDirectionBtn" class="btn btn-secondary" title="將翻譯結果與原文互相對調並重新翻譯"> | |
| <i class="fa-solid fa-arrows-rotate"></i> ⇄ 雙向對調 (換向) | |
| </button> | |
| <button id="ttsBtn" class="btn btn-secondary" disabled> | |
| <i class="fa-solid fa-volume-high"></i> 🔊 聽發音 | |
| </button> | |
| <button id="deepTranslateBtn" class="btn btn-secondary" disabled> | |
| <i class="fa-solid fa-brain"></i> 🧠 深度文化潤飾 | |
| </button> | |
| <button id="copyBtn" class="btn btn-secondary" disabled> | |
| <i class="fa-regular fa-copy"></i> 複製結果 | |
| </button> | |
| </div> | |
| <!-- 信心值與狀態列 --> | |
| <div class="meta-bar"> | |
| <div id="confidenceBadge" class="badge-confidence" style="display: none;"> | |
| <i class="fa-solid fa-shield-halved"></i> 信心值:<span id="confidenceLevel">高</span> (<span id="confidenceDesc">一般生活簡單句</span>) | |
| </div> | |
| <div style="font-size: 0.85rem; color: var(--text-dim);"> | |
| ● NLLB 深度學術對齊引擎 + Gemini 文化語意雷達 | |
| </div> | |
| </div> | |
| </div> | |
| <!-- 常用單字速查快卡 Section --> | |
| <div class="phrasebook-section"> | |
| <div class="section-title"> | |
| <i class="fa-solid fa-fire-flame-curved" style="color: var(--accent-gold);"></i> 常用 10 句日常生活速查句卡 (點擊代入翻譯) | |
| </div> | |
| <div class="phrases-grid" id="phrasesGrid"> | |
| <!-- JavaScript 動態帶入 --> | |
| </div> | |
| </div> | |
| <!-- 長句測試 Section --> | |
| <div class="phrasebook-section" style="margin-top: 1.5rem;"> | |
| <div class="section-title"> | |
| <i class="fa-solid fa-book-open-reader" style="color: var(--primary-cyan);"></i> 雙語長句測試區 (點擊代入) | |
| </div> | |
| <div style="display: flex; flex-direction: column; gap: 10px;"> | |
| <div class="phrase-card" id="longPhraseZh" style="text-align: left; padding: 15px; width: 100%; max-width: none;"> | |
| <div class="phrase-zh" style="font-size: 1rem; line-height: 1.4;">很久以前,天地間只有黑暗沒有白天,人類的生活很辛苦而且沒有發展。就這樣以松樹的木片點火當作燈來做家事及到田間工作。</div> | |
| <div class="phrase-desc" style="margin-top: 5px;">華語長句測試</div> | |
| </div> | |
| <div class="phrase-card" id="longPhraseNative" style="text-align: left; padding: 15px; width: 100%; max-width: none;"> | |
| <div class="phrase-zh" style="font-size: 1rem; line-height: 1.4;">Mqaras ku bi qmita sunan, Lituk ka hangan mu, ima ka hangan su? Emptgsa ku ka yaku, ga ku tmgsa kari Truku. Gaga su qmpah qpahun manu?</div> | |
| <div class="phrase-desc" style="margin-top: 5px;">太魯閣語長句測試</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- 本地歷史紀錄 Section --> | |
| <div class="phrasebook-section" style="margin-top: 2rem;"> | |
| <div class="section-title" style="display: flex; align-items: center; justify-content: space-between;"> | |
| <span><i class="fa-solid fa-clock-rotate-left"></i> 最近翻譯歷史紀錄</span> | |
| <button id="clearHistoryBtn" onclick="clearHistory()" title="清除全部歷史" style="background: rgba(255,80,80,0.15); border: 1px solid rgba(255,80,80,0.4); color: #ff6b6b; border-radius: 6px; padding: 4px 12px; font-size: 0.78rem; cursor: pointer; transition: all 0.2s; display: flex; align-items: center; gap: 6px;" onmouseover="this.style.background='rgba(255,80,80,0.35)'" onmouseout="this.style.background='rgba(255,80,80,0.15)'"> | |
| <i class="fa-solid fa-trash-can"></i> 清除歷史 | |
| </button> | |
| </div> | |
| <div class="history-list" id="historyList"> | |
| <div style="color: var(--text-dim); font-size: 0.85rem; padding: 10px;">尚未有翻譯紀錄。</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- 2. 語音聽寫面板 (Audio Tab) --> | |
| <div id="audio-tab" class="tab-content"> | |
| <div class="glass-card"> | |
| <div class="section-title"><i class="fa-solid fa-microphone"></i> 麥克風線上錄音或語音檔上傳</div> | |
| <p style="color: var(--text-muted); font-size: 0.9rem; margin-bottom: 1.5rem;"> | |
| 錄下或上傳族語語音 (WAV / MP3 / M4A),原語會 ASR 辨識引擎將自動轉換為文字並翻譯成中文與目標族語。 | |
| </p> | |
| <div class="btn-group" style="margin-bottom: 1.5rem;"> | |
| <button id="startRecordBtn" class="btn btn-primary"> | |
| <i class="fa-solid fa-circle" style="color: #ff4d4d;"></i> 開始錄音 | |
| </button> | |
| <button id="stopRecordBtn" class="btn btn-secondary" disabled> | |
| <i class="fa-solid fa-square"></i> 停止錄音並辨識 | |
| </button> | |
| </div> | |
| <div id="recordingStatus" style="color: var(--primary-cyan); font-weight: 600; margin-bottom: 1rem; display: none;"> | |
| <i class="fa-solid fa-wave-square"></i> 錄音中... 請對麥克風說話 | |
| </div> | |
| <div class="dropzone" id="audioDropzone"> | |
| <i class="fa-solid fa-cloud-arrow-up dropzone-icon"></i> | |
| <p style="font-weight: 600;">拖曳語音檔案至此處,或點擊選擇檔案</p> | |
| <p style="font-size: 0.8rem; color: var(--text-dim); margin-top: 6px;">支援 .wav, .mp3, .m4a 格式</p> | |
| <input type="file" id="audioFileInput" accept="audio/*" style="display: none;"> | |
| </div> | |
| <div id="audioResult" style="margin-top: 1.5rem; display: none;"> | |
| <div class="box-header"><span>ASR 語音辨識與翻譯結果</span></div> | |
| <div id="audioOutput" class="output-styled" style="height: auto; min-height: 100px;"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- 3. 圖片 OCR 翻譯面板 (Image Tab) --> | |
| <div id="image-tab" class="tab-content"> | |
| <div class="glass-card"> | |
| <div class="section-title"><i class="fa-solid fa-camera"></i> 圖片視聽 Vision 多模態 OCR 翻譯</div> | |
| <p style="color: var(--text-muted); font-size: 0.9rem; margin-bottom: 1.5rem;"> | |
| 上傳包含文字的圖片(指標、告示牌、課本圖片),Gemini 視覺模型將自動提取內文並進行族語翻譯。 | |
| </p> | |
| <div class="dropzone" id="imageDropzone"> | |
| <i class="fa-solid fa-file-image dropzone-icon"></i> | |
| <p style="font-weight: 600;">拖曳圖片檔案至此處,或點擊上傳</p> | |
| <p style="font-size: 0.8rem; color: var(--text-dim); margin-top: 6px;">支援 .jpg, .png, .jpeg 格式</p> | |
| <input type="file" id="imageFileInput" accept="image/*" style="display: none;"> | |
| </div> | |
| <div id="imagePreviewContainer" style="margin-top: 15px; display: none; text-align: center;"> | |
| <img id="imagePreview" src="" alt="Image Preview" style="max-width: 100%; max-height: 300px; border-radius: 8px; border: 1px solid var(--border-color); box-shadow: 0 4px 12px rgba(0,0,0,0.3);"> | |
| </div> | |
| <div id="imageResult" style="margin-top: 1.5rem; display: none;"> | |
| <div class="box-header" style="display: flex; justify-content: space-between; align-items: center;"> | |
| <span>圖片文字辨識與翻譯清單</span> | |
| <div class="action-buttons" style="display: flex; gap: 8px;"> | |
| <button id="copyOcrBtn" class="btn btn-primary" style="padding: 4px 12px; font-size: 0.85rem;"><i class="fa-solid fa-copy"></i> 複製全部</button> | |
| <button id="downloadOcrWordBtn" class="btn btn-secondary" style="padding: 4px 12px; font-size: 0.85rem;"><i class="fa-solid fa-file-word"></i> 下載 WORD</button> | |
| </div> | |
| </div> | |
| <div id="imageOutput" style="display: flex; flex-direction: column; gap: 10px; margin-top: 10px;"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- 4. 影片音軌翻譯面板 (Video Tab) --> | |
| <div id="video-tab" class="tab-content"> | |
| <div class="glass-card"> | |
| <div class="section-title"><i class="fa-solid fa-film"></i> 影片音軌提取與逐字稿翻譯</div> | |
| <p style="color: var(--text-muted); font-size: 0.9rem; margin-bottom: 1.5rem;"> | |
| 上傳族語或中文對話影片,後端以 MoviePy 自動提取音軌,並執行 ASR 與文字翻譯。 | |
| </p> | |
| <div class="dropzone" id="videoDropzone"> | |
| <i class="fa-solid fa-file-video dropzone-icon"></i> | |
| <p style="font-weight: 600;">拖曳影片檔案至此處,或點擊上傳</p> | |
| <p style="font-size: 0.8rem; color: var(--text-dim); margin-top: 6px;">支援 .mp4, .mov, .avi 格式</p> | |
| <input type="file" id="videoFileInput" accept="video/*" style="display: none;"> | |
| </div> | |
| <div id="videoPreviewContainer" style="margin-top: 15px; display: none; text-align: center;"> | |
| <video id="videoPreview" controls style="max-width: 100%; max-height: 400px; border-radius: 8px; border: 1px solid var(--border-color); box-shadow: 0 4px 12px rgba(0,0,0,0.3);"></video> | |
| </div> | |
| <div id="videoResult" style="margin-top: 1.5rem; display: none;"> | |
| <div class="box-header" style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px;"> | |
| <span>影片字幕與翻譯對照</span> | |
| <div class="action-buttons" style="display: flex; gap: 8px; flex-wrap: wrap;"> | |
| <button id="downloadAudioBtn" class="btn btn-secondary" style="padding: 4px 12px; font-size: 0.85rem;"><i class="fa-solid fa-music"></i> 下載純音軌</button> | |
| <button id="downloadSrtBtn" class="btn btn-secondary" style="padding: 4px 12px; font-size: 0.85rem;"><i class="fa-solid fa-closed-captioning"></i> 下載 SRT</button> | |
| <button id="copyVideoBtn" class="btn btn-primary" style="padding: 4px 12px; font-size: 0.85rem;"><i class="fa-solid fa-copy"></i> 複製全部</button> | |
| <button id="downloadVideoWordBtn" class="btn btn-secondary" style="padding: 4px 12px; font-size: 0.85rem;"><i class="fa-solid fa-file-word"></i> 下載 WORD</button> | |
| </div> | |
| </div> | |
| <div id="videoOutput" class="output-styled" style="height: auto; min-height: 120px;"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- 5. 報錯與建議面板 (Feedback Tab) --> | |
| <div id="feedback-tab" class="tab-content"> | |
| <div class="glass-card"> | |
| <div class="section-title"><i class="fa-solid fa-paper-plane"></i> 系統回饋與翻譯報錯專區</div> | |
| <p style="color: var(--text-muted); font-size: 0.9rem; margin-bottom: 1.5rem;"> | |
| 發現翻譯不準確或有修改建議?歡迎在此填寫表單,資訊將自動透過加密郵件發送予語料維護團隊。 | |
| </p> | |
| <div style="display: flex; flex-direction: column; gap: 1rem; max-width: 600px;"> | |
| <div> | |
| <label style="font-size: 0.9rem; color: var(--text-muted);">您的暱稱:</label> | |
| <input type="text" id="fbNickname" class="text-area-styled" style="height: 45px;" placeholder="例:張小明"> | |
| </div> | |
| <div> | |
| <label style="font-size: 0.9rem; color: var(--text-muted);">回饋內容 / 建議修飾字句:</label> | |
| <textarea id="fbComment" class="text-area-styled" style="height: 100px;" placeholder="請詳細說明您發生的問題或希望補充的族語單詞..."></textarea> | |
| </div> | |
| <button id="sendFeedbackBtn" class="btn btn-primary" style="width: 200px;"> | |
| <i class="fa-solid fa-envelope"></i> 送出意見回饋 | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- 頁尾 Footer --> | |
| <footer class="footer"> | |
| <p>財團法人原住民族語言研究發展基金會 (ILRDF) AI 實驗室 著作權所有 © 2026</p> | |
| <p style="margin-top: 4px; color: var(--text-dim);">Powered by FastAPI, Gradio Client, NLLB-200 & Google Gemini 3</p> | |
| </footer> | |
| <!-- 深度文化潤飾 Modal --> | |
| <div id="deepTranslateModal" class="modal-overlay" style="display: none;"> | |
| <div class="modal-content"> | |
| <div class="modal-header"> | |
| <h3>🧠 深度文化潤飾結果</h3> | |
| <button class="close-btn" id="closeModalBtn">×</button> | |
| </div> | |
| <div class="modal-body" id="deepTranslateResultBody" style="white-space: pre-wrap; max-height: 60vh; overflow-y: auto; padding: 20px; font-size: 1.05rem; line-height: 1.6; color: var(--text-bright);"> | |
| </div> | |
| <div class="modal-footer" style="display: flex; gap: 10px; justify-content: space-between; align-items: center; padding: 15px 20px; border-top: 1px solid rgba(255,255,255,0.1); flex-wrap: wrap;"> | |
| <button id="changeApiKeyBtn" class="btn" style="background: rgba(245, 158, 11, 0.18); color: #fbbf24; border: 1px solid rgba(245, 158, 11, 0.5); padding: 8px 16px; border-radius: 8px; font-size: 0.95rem; font-weight: 600; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; transition: all 0.2s ease;"> | |
| <i class="fa-solid fa-key"></i> 🔑 更換 API Key | |
| </button> | |
| <div style="display: flex; gap: 10px;"> | |
| <button id="copyDeepResultBtn" class="btn btn-secondary"><i class="fa-regular fa-copy"></i> 複製</button> | |
| <button id="downloadWordBtn" class="btn btn-primary"><i class="fa-solid fa-file-word"></i> 下載 WORD</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- 🔑 Gemini API Key 輸入 Modal --> | |
| <div id="apiKeyModal" class="modal-overlay" style="display: none;"> | |
| <div class="modal-content" style="max-width: 500px;"> | |
| <div class="modal-header"> | |
| <h3>🔑 輸入 Google Gemini API Key</h3> | |
| <button class="close-btn" id="closeApiKeyModalBtn">×</button> | |
| </div> | |
| <div class="modal-body" style="padding: 20px;"> | |
| <p style="color: var(--text-muted); font-size: 0.95rem; margin-bottom: 15px; line-height: 1.5;"> | |
| 「深度文化潤飾」功能需使用 Google Gemini AI 進行多層次語法與文化對齊。請輸入您的 API Key 繼續使用: | |
| </p> | |
| <div style="position: relative; margin-bottom: 12px;"> | |
| <input type="password" id="geminiApiKeyInput" placeholder="請在此貼上您的 API Key (例: AIzaSy...)" | |
| style="width: 100%; padding: 12px 14px; border-radius: 8px; border: 1px solid var(--border-glow); background: rgba(0,0,0,0.3); color: #fff; font-size: 1rem; box-sizing: border-box;" /> | |
| </div> | |
| <div style="font-size: 0.85rem; color: var(--text-dim); display: flex; justify-content: space-between; align-items: center; margin-top: 10px;"> | |
| <a href="https://aistudio.google.com/app/apikey" target="_blank" style="color: var(--primary-cyan); text-decoration: underline;"> | |
| 👉 按此免費申領 Gemini API Key | |
| </a> | |
| <label style="cursor: pointer; display: flex; align-items: center; gap: 5px;"> | |
| <input type="checkbox" id="rememberApiKeyCheckbox" checked /> 記住金鑰 | |
| </label> | |
| </div> | |
| </div> | |
| <div class="modal-footer" style="display: flex; gap: 10px; justify-content: flex-end; padding: 15px; border-top: 1px solid rgba(255,255,255,0.1);"> | |
| <button id="cancelApiKeyBtn" class="btn btn-secondary">取消</button> | |
| <button id="confirmApiKeyBtn" class="btn btn-primary"><i class="fa-solid fa-check"></i> 確認並開始潤飾</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- JavaScript 腳本 --> | |
| <script src="/static/script.js?v=20260727_4"></script> | |
| </body> | |
| </html> | |