ILRDF-Lowking's picture
feat: Update GA4 tracking (G-4M6KQ8KSY5) and analytics dashboard
5e981a4
Raw
History Blame Contribute Delete
22.6 kB
<!DOCTYPE html>
<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 實驗室 著作權所有 &copy; 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">&times;</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">&times;</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>