jim800121chen e02059eff2 feat(visionA-frontend): Phase 0.8 conversion UI — sidebar tab + 6 view + 5 e2e flow tests
Phase 0.8 對應後端轉檔功能的 frontend UI。完整 state machine(idle / uploading /
queued / running / succeeded / failed / expired)+ XHR upload progress + polling +
half-auto result handling(加到模型庫 / 下載)。

新增 src/app/conversion/(11 元件 + 12 test files,~5,000 行 prod+test,310/310 tests 全綠):

- page.tsx:state router(mount → bootstrap → 依 store.uiState 切換 view)+ toast on
  store.error(aborted / active_job_exists 不 toast,避免雙重提示)
- IdleForm.tsx + FileDropzone.tsx + ChipSelector.tsx:上傳表單(拖放 + .onnx/.tflite
  format 驗證 + 500MB 大小限制 + KL520/630/720/730 chip 選擇 + ref images ≤100×10MB)
- UploadingView.tsx:XHR upload progress 0-100% + EWMA ETA(alpha=0.3 平滑,<5s 顯示
  「即將完成」避抖動)+ beforeunload warning + AlertDialog 取消
- ProcessingView.tsx:StageIndicator 三段式(解析模型 → 量化編譯 → 編譯 NEF)+
  Progress bar 三模式(queued / determinate / indeterminate)+ tab title `(轉檔中)` 防疊加 +
  409 active_job_exists banner(switchedFromActiveJob flag)
- SuccessView.tsx + PromoteDialog.tsx:兩按鈕(加到模型庫 / 下載)視覺平衡不暗示預設答案 +
  7 天 expires_at 倒數(mount 時 setTimeout 鎖過期那刻 + 60s tick)+ PromoteDialog 單欄位
  name 驗證(≤100 字元 / 無 /\\)+ spinner-during-close 阻擋 + 409 already_imported 特殊
  訊息 + toast.success router.push 跳模型清單
- FailedView.tsx:5 個 known error code 翻譯(UNSUPPORTED_FORMAT / INVALID_CHECKSUM /
  QUANTIZATION_FAILED / MODEL_TOO_LARGE / QUOTA_EXCEEDED)+ unknown fallback +
  3 個建議解決方法 + Job ID 前 8 字元(供回報)+ 「重新開始」
- ExpiredView.tsx:橘色 hero(過期不 alarming)+ source/chip 摘要 + 「重新轉檔」→
  store.reset()

新增 src/stores/conversion-store.ts(Zustand store + 29 tests):
- 7 個 UI state machine(不允許跳階段)
- recursive setTimeout polling(running 5s / queued 10s / 5xx 指數退避 cap 30s)+
  visibilitychange 暫停/恢復
- 不持久化 jobId(純靠 backend getActiveConversion() lazy rebuild ownership)
- AbortController 防 stale request + 取消上傳
- switchedFromActiveJob flag(409 自動切到既存 job + UI 顯示 banner)
- formDraft(chip / taskName 提到 store,failed→idle 後保留設定,file picker 重選;
  File 物件不能序列化只留 local)

新增 src/lib/api/conversion.ts + types/conversion.ts(5 client 函式 + 22 tests):
- initConversion:XHR multipart + onUploadProgress + AbortSignal
- getActiveConversion / getConversion / promoteConversionToModels:標準 fetch
- getConversionDownloadURL:純函式,回 `/api/conversion/{job_id}/download` 給 anchor
  download 觸發(server-side 302 → FAA,token 不過 frontend JS)
- ConversionAPIError(status, code, message, requestId?),code 統一全小寫對齊
  conversion.error.<code> i18n key 命名

新增 src/lib/utils/eta.ts(EWMA 演算法純函式 + 19 tests):抽出 smoothSpeed /
estimateRemainingSeconds / instantSpeedBytesPerSec / computeEtaUpdate(test 友善)。

新增 src/app/conversion/e2e-conversion-flow.test.tsx(5 e2e flow tests):
- happy path .onnx + KL720 + 0 ref images(idle → upload → polling → succeeded → 加到模型庫)
- variant 5 ref images
- upload fail → retry(form 設定保留)
- polling 5xx 指數退避 → 恢復繼續
- expired job → ExpiredView → 重新轉檔

修改 sidebar.tsx:左側 nav 新增「轉檔」tab(Wand2 icon,模型庫之後)。
修改 i18n 字典:新增 ~150 個 conversion.* keys(中英雙語對齊)。

PRD §9 14 條功能驗收條件全達成(4 條整合驗收等 stage 部署)。

驗證:pnpm lint / test (310/310) / build 全綠。

對齊文件:
- .autoflow/02-prd/features/feature-converter-integration.md
- .autoflow/03-design/wireframes/wireframe-conversion.md
- .autoflow/03-design/flows/flow-conversion.md
- .autoflow/04-architecture/api/api-conversion.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 13:56:54 +08:00

601 lines
30 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 繁體中文字典 — visionA Cloud
*
* 原則:
* - 扁平 key`nav.dashboard`);新增 key 時請同步更新 en.ts確保兩語系 key 集合一致。
* - 設計指引:繁中台灣用語;不過度使用「您」;錯誤訊息說清楚發生什麼 + 使用者能做什麼。
* - F4Sidebar/Header、F5auth/session基礎已建立F6 批次加入 Dashboard / Devices / Models / Workspace / Settings。
*/
import type { Dictionary } from "../types";
export const zhHant: Dictionary = {
// ── 應用 ──
"app.title": "visionA Cloud",
"app.tagline": "將 local-tool 的使用體驗延伸到雲端",
// ── 通用 ──
"common.loading": "載入中…",
"common.error": "發生錯誤",
"common.cancel": "取消",
"common.confirm": "確認",
"common.save": "儲存",
"common.close": "關閉",
"common.retry": "重試",
"common.view": "檢視",
"common.manage": "管理",
"common.connect": "連接",
"common.disconnect": "中斷連線",
"common.delete": "刪除",
"common.edit": "編輯",
"common.back": "返回",
"common.na": "—",
// ── 側邊導航 ──
"nav.dashboard": "儀表板",
"nav.devices": "裝置",
"nav.models": "模型",
"nav.conversion": "轉檔",
"nav.workspace": "推論工作區",
"nav.clusters": "叢集",
"nav.settings": "設定",
// ── 雛形階段 banner ──
// Phase 0.7 stage deployment fixOIDC 已接 Innovedus 帳號中心,文案不再寫「未實作身分驗證」
"banner.prototype":
"🚧 雛形版本 · 已接 Innovedus 帳號中心,但部分功能仍為 UI 示意;資料為示範資料",
"banner.prototype.short": "🚧 雛形版本demo",
"banner.prototype.ariaLabel": "雛形版本提示",
// ── Header ──
"header.toggleTheme": "切換主題",
"header.toggleLocale": "切換語言",
"header.userMenu.open": "開啟使用者選單",
"header.userMenu.profile": "帳號設定",
"header.userMenu.logout": "登出",
"header.userMenu.fallbackName": "使用者",
"header.breadcrumb.home": "首頁",
// ── Tunnel / 遠端狀態(燈號) ──
"tunnel.status.online": "已連線",
"tunnel.status.offline": "離線",
"tunnel.status.reconnecting": "重新連線中",
"tunnel.rttLabel": "延遲 {rtt}ms",
// ── 主題切換next-themes ──
"theme.light": "淺色",
"theme.dark": "深色",
"theme.system": "跟隨系統",
// ── 認證Phase 0.6 OIDC redirect 模式) ──
// 設計重點:
// - 所有 email/password 表單時代的 keyauth.login.email/password/submit/...
// auth.register.email/password/...)已移除,改用 Member Center 統一帳號
// - 共用「登入 / 登出」字串收斂為 auth.action.signIn / auth.action.signOut
// 避免 header dropdown 之類的非表單元件再借用 auth.login.submit
"auth.action.signIn": "登入",
"auth.action.signOut": "登出",
// Login 頁
"auth.login.title": "登入 visionA Cloud",
"auth.login.subtitle": "歡迎回到 visionA Cloud",
"auth.login.welcomeBack": "歡迎回來",
"auth.login.signInWithMC": "使用您的 Innovedus 帳號登入",
"auth.login.button": "登入",
"auth.login.noAccount": "還沒有帳號?",
"auth.login.registerLink": "前往註冊",
"auth.login.prototypeHint":
"Phase 0.6 雛形 — 登入會跳轉到 Innovedus 帳號中心完成驗證",
// Register 頁Phase 0.6visionA 不再自有註冊表單,改導向 Member Center
"auth.register.title": "註冊 visionA",
"auth.register.description":
"visionA 使用 Innovedus 統一帳號系統。",
"auth.register.howTo":
"請至 Innovedus 帳號中心註冊,註冊完成後即可回到 visionA 登入。",
"auth.register.button": "前往 Innovedus 帳號中心",
"auth.register.disabledHint":
"尚未設定 Innovedus 帳號中心 URL請聯絡系統管理員。",
"auth.register.alreadyHaveAccount": "已有帳號?",
"auth.register.loginLink": "登入",
// ── 首頁 / Dashboard ──
"home.welcome": "歡迎回來,{name}",
"home.placeholder":
"這裡之後會是 DashboardStatCard / ActivityTimeline / ConnectedDevicesListF6 會從 local-tool 搬入。",
"dashboard.title": "儀表板",
"dashboard.subtitle": "管理你的雲端 Edge AI 資源",
"dashboard.models": "模型",
"dashboard.devices": "裝置",
"dashboard.connected": "線上裝置",
"dashboard.flashes": "已燒錄次數",
"dashboard.connectedDevices": "線上裝置",
"dashboard.noConnectedDevices": "目前沒有裝置線上。配對一台 Kneron 裝置開始雲端推論。",
"dashboard.recentActivity": "近期活動",
"dashboard.noActivity": "還沒有任何活動。配對裝置、上傳模型或跑一次推論後就會出現。",
"dashboard.quickActions": "快速操作",
"dashboard.browseModels": "瀏覽模型",
"dashboard.manageDevices": "管理裝置",
"dashboard.uploadModel": "上傳模型",
"dashboard.pairDevice": "配對裝置",
"dashboard.empty.title": "還沒有任何裝置",
"dashboard.empty.description": "配對你的第一台 Kneron 裝置,開始雲端推論之旅",
"dashboard.empty.action": "配對裝置",
"dashboard.activity.justNow": "剛剛",
"dashboard.activity.minutesAgo": "{n} 分鐘前",
"dashboard.activity.hoursAgo": "{n} 小時前",
"dashboard.activity.daysAgo": "{n} 天前",
// ── Devices ──
"devices.title": "裝置",
"devices.subtitle": "管理你的 Edge AI 裝置",
"devices.type": "類型",
"devices.firmware": "韌體",
"devices.flashedModel": "已燒錄模型",
"devices.openWorkspace": "開啟工作區",
"devices.addMore": "配對新裝置",
"devices.pairAction": "配對新裝置",
"devices.empty.title": "還沒有配對的裝置",
"devices.empty.description":
"在你的電腦上執行 local agent 並完成配對,就能從任何地方存取你的 Kneron 裝置",
"devices.empty.action": "配對第一台裝置",
"devices.empty.secondaryAction": "查看配對說明",
"devices.detail.id": "ID",
"devices.detail.type": "類型",
"devices.detail.firmware": "韌體",
"devices.detail.port": "連接埠",
"devices.detail.deviceInfo": "裝置資訊",
"devices.detail.modelStatus": "模型狀態",
"devices.detail.readyForInference": "已就緒,可開始推論",
"devices.detail.noModelFlashed": "尚未燒錄任何模型",
"devices.detail.pairedAt": "配對時間",
"devices.detail.hostName": "所在電腦",
"devices.detail.lastSeen": "最後心跳",
"devices.detail.offlineBanner.title": "此裝置目前離線",
"devices.detail.offlineBanner.description":
"部分操作無法使用,待 local agent 重新連線後自動恢復",
"devices.status.detected": "已偵測",
"devices.status.connecting": "連線中",
"devices.status.connected": "已連線",
"devices.status.flashing": "燒錄中",
"devices.status.inferencing": "推論中",
"devices.status.error": "錯誤",
"devices.status.disconnected": "未連接",
// ── Remote Device Badge雲端 tunnel 狀態) ──
"remote.status.online": "在線",
"remote.status.offline": "離線",
"remote.status.reconnecting": "重新連線中",
"remote.status.error": "連線錯誤",
"remote.status.unknown": "未確認",
"remote.lastSeenNever": "從未連線",
"remote.lastSeen.justNow": "剛剛",
"remote.lastSeen.minutesAgo": "{n} 分鐘前",
"remote.lastSeen.hoursAgo": "{n} 小時前",
// ── Models ──
"models.title": "模型庫",
"models.subtitle": "管理雲端上的 Kneron 模型",
"models.size": "檔案大小",
"models.createdAt": "建立時間",
"models.status.uploading": "上傳中",
"models.status.scanning": "掃描中",
"models.status.ready": "可用",
"models.status.rejected": "檢測失敗",
"models.source.uploaded": "自行上傳",
"models.source.preset": "預設",
"models.source.converted": "已轉檔",
"models.filters.label": "模型篩選",
"models.filters.hardware": "硬體",
"models.filters.source": "來源",
"models.filters.all": "全部",
"models.empty.title": "還沒有任何模型",
"models.empty.description":
"上傳你的第一個 .nef 模型到雲端,就能部署到任何一台配對過的 Kneron 裝置",
"models.empty.action": "上傳第一個模型",
"models.detail.description": "說明",
"models.detail.version": "版本",
"models.detail.checksum": "校驗碼",
"models.detail.supportedChips": "支援晶片",
"models.detail.deployToDevice": "部署至裝置",
// ── Model Upload Dialogflow-model-upload ──
"models.upload.button": "上傳模型",
"models.upload.dialog.title": "上傳模型",
"models.upload.dropzone.hint": "支援格式:.nef · 最大 100 MB",
"models.upload.selectedFile": "選擇檔案",
"models.upload.field.name": "模型名稱",
"models.upload.field.version": "版本",
"models.upload.field.notes": "備註(選填)",
"models.upload.field.targetChip": "目標晶片",
"models.upload.action.cancel": "取消",
"models.upload.action.start": "開始上傳",
"models.upload.action.remove": "移除",
"models.upload.uploading.title": "上傳中",
"models.upload.uploading.hint": "請勿關閉此視窗或導航到其他頁面",
"models.upload.success.title": "上傳完成",
"models.upload.success.scanHint": "模型即將進入安全掃描,完成後可燒錄",
"models.upload.error.invalidType": "只支援 .nef 檔案,你選的是 {type}",
"models.upload.error.tooLarge": "檔案太大({size}),最大允許 100 MB",
"models.upload.error.requiredField": "{field} 為必填",
"models.upload.error.urlFailed": "伺服器忙碌,請稍後再試",
"models.upload.error.networkLost": "網路中斷,上傳已暫停",
"models.upload.toast.uploaded": "模型「{name}」已上傳",
// ── Workspace ──
"workspace.title": "推論工作區",
"workspace.subtitle": "選擇已線上的裝置開始推論",
"workspace.empty.title": "目前沒有線上裝置",
"workspace.empty.description": "請先配對並確認 local agent 已連上雲端",
"workspace.empty.action": "前往裝置管理",
"workspace.header.backToDevices": "返回裝置",
"workspace.header.title": "工作區",
"workspace.inference.start": "開始推論",
"workspace.inference.stop": "停止推論",
"workspace.placeholder.cameraComingSoon":
"Camera 推論介面預覽 — F8 會接上 MJPEG stream透過 tunnel 從 local agent 中繼)",
"workspace.offline.title": "裝置已離線",
"workspace.offline.description": "與 {deviceName} 的連線中斷,推論已自動停止",
"workspace.offline.backToList": "返回裝置列表",
"workspace.tabs.camera": "Camera",
"workspace.tabs.image": "圖片Phase 1",
"workspace.tabs.video": "影片Phase 1",
"workspace.tabs.batch": "批次Phase 1",
// ── Settings ──
"settings.title": "設定",
"settings.subtitle": "管理偏好與雲端端點",
"settings.tabs.general": "一般",
"settings.tabs.advanced": "進階",
"settings.general.title": "偏好",
"settings.general.language": "語言",
"settings.general.theme": "主題",
"settings.general.themeHint": "跟隨系統偏好自動切換淺 / 深色",
"settings.advanced.title": "雲端端點",
"settings.advanced.apiEndpoint": "API Endpoint",
"settings.advanced.apiEndpointHint":
"正常使用者不需更改;開發時可切到 staging 或 localhost",
"settings.advanced.apiUrl": "目前 API URL",
"settings.advanced.wsUrl": "目前 WebSocket URL",
"settings.advanced.about": "關於",
"settings.advanced.version": "版本",
"settings.advanced.platform": "平台",
// ── PairingF7 新增)──
"pairing.title": "配對新裝置",
"pairing.subtitle": "讓你的 Kneron 裝置連上雲端,就能從任何地方遠端操作",
"pairing.token.title": "你的 Pairing Token",
"pairing.step1.description":
"複製下方 token在 15 分鐘內貼到 local agent 完成配對",
"pairing.copy": "複製",
"pairing.copied": "已複製",
"pairing.regenerate": "重新產生",
"pairing.timeRemaining": "剩餘 {time}",
"pairing.generatedAt": "產生時間:{time}",
"pairing.token.expired.label": "此 token 已過期,請重新產生",
"pairing.regenerateConfirm.title": "確定要重新產生?",
"pairing.regenerateConfirm.description":
"舊 token 將立即失效,新 token 有效期 15 分鐘",
"pairing.security.warning": "這組 token 15 分鐘內有效,請立刻完成配對",
"pairing.security.oneTime": "token 是一次性使用,完成配對後自動失效",
"pairing.toast.copied": "Token 已複製到剪貼簿15 分鐘內有效",
"pairing.toast.generateFailed": "無法產生 token請重試",
"pairing.toast.expiringSoon": "Token 即將過期,請立刻完成或重新產生",
"pairing.toast.pairedSuccess": "裝置 {deviceName} 已成功配對",
"pairing.toast.cliCopied": "指令已複製到剪貼簿",
"pairing.device.unknown": "未知裝置",
"pairing.cli.title": "CLI 指令範例",
"pairing.cli.description":
"在你的電腦啟動 local agent將 token 貼到指令的 --relay-token 參數",
"pairing.cli.copy": "複製指令",
"pairing.cli.hint":
"local agent 連上雲端後,本頁會自動偵測並跳轉到裝置列表",
"pairing.step3.waiting": "等待 local agent 連線…",
"pairing.step3.elapsed": "已等待 {time}(最長 3 分鐘)",
"pairing.step3.hints.running": "確認 local agent 已啟動",
"pairing.step3.hints.token": "確認 token 貼上時無缺字或多餘空白",
"pairing.step3.hints.network": "確認你的網路可連線到雲端",
"pairing.step3.success": "已成功連線!",
"pairing.step3.success.detected": "檢測到的裝置",
"pairing.step3.failure.timeout": "連線超時",
"pairing.step3.failure.reason":
"超過 3 分鐘沒收到 local agent 連線,可能是 local agent 尚未啟動",
"pairing.step3.failure.retry": "重新檢查",
// ── AccountPhase 0.6 OIDC──
// 設計重點:
// - 個人資料一律唯讀;修改入口統一導到 Innovedus 帳號中心
// - 「刪除帳號」按鈕保留為 disabled 雛形,文案說明改在 Member Center 處理
"account.title": "帳號設定",
"account.subtitle": "個人資料由 Innovedus 帳號中心管理",
"account.profile.title": "個人資料",
"account.profile.userId": "使用者 ID",
"account.profile.email": "電子郵件",
"account.profile.name": "顯示名稱",
"account.profile.namePlaceholder": "—",
"account.profile.managedBy":
"個人資料由 Innovedus 帳號中心管理。如需修改,請至 Innovedus 帳號中心。",
"account.profile.editAtMemberCenter": "前往 Innovedus 帳號中心",
"account.profile.editDisabledHint":
"尚未設定 Innovedus 帳號中心 URL請聯絡系統管理員。",
"account.session.title": "登入狀態",
"account.session.description":
"登出後會回到登入頁,下次需重新透過 Innovedus 帳號中心登入。",
"account.danger.title": "危險區",
"account.danger.description":
"帳號刪除請至 Innovedus 帳號中心處理visionA 不直接執行此操作。",
"account.danger.deleteAccount": "刪除帳號",
"account.danger.deleteAccount.tooltip":
"請至 Innovedus 帳號中心處理。",
// ── Conversion / 轉檔Phase 0.8 — feature-converter-integration──
// 設計來源:.autoflow/03-design/wireframes/wireframe-conversion.md §11
// 對應 PRD.autoflow/02-prd/features/feature-converter-integration.md
// 範圍5 個 stateidle / uploading / processing / success / failed+ 6 種錯誤碼翻譯 + 過期狀態
"conversion.title": "轉檔",
"conversion.subtitle":
"把 ONNX / TFLite 模型轉成 .nef跑在 Kneron 邊緣裝置上",
// idle 空狀態
"conversion.idle.heading": "還沒有進行中的轉檔",
"conversion.idle.description":
"上傳一個 ONNX / TFLite 模型,選擇目標 Kneron 晶片,我們幫你產出可直接燒錄的 .nef 檔案",
"conversion.idle.cta": "開始轉檔",
"conversion.idle.formats": "支援 .onnx / .tflite · 最大 500 MB",
"conversion.idle.about.title": "關於轉檔",
"conversion.idle.about.line1": "一次只能跑一個轉檔任務(包含其他分頁)",
"conversion.idle.about.line2": "完成後 7 天內可下載結果,過期自動清除",
"conversion.idle.about.line3": "轉檔約耗時 110 分鐘,依模型大小而定",
// Upload Dialog
"conversion.upload.title": "開始轉檔",
"conversion.upload.description":
"上傳模型、選擇目標晶片,可選擇加上 reference images 提升精度",
"conversion.upload.source.label": "來源模型",
"conversion.upload.source.dropzone": "拖曳 .onnx / .tflite 到此處",
"conversion.upload.source.or": "或",
"conversion.upload.source.browse": "選擇檔案",
"conversion.upload.source.formatHint":
"支援格式:.onnx · .tflite · 最大 500 MB",
"conversion.upload.source.remove": "移除",
"conversion.upload.name.label": "任務名稱(選填)",
"conversion.upload.name.hint": "顯示用,不影響輸出檔名",
"conversion.upload.chip.label": "目標晶片",
"conversion.upload.refImages.label": "Reference images選填",
"conversion.upload.refImages.dropzone": "拖曳圖片到此處(選填)",
"conversion.upload.refImages.hint":
"加上 ref images 可提升量化後精度(最多 100 張,每張 ≤ 10 MB",
"conversion.upload.refImages.summary":
"已選 {count} 張 ref images共 {totalSize}",
"conversion.upload.refImages.removeAll": "移除全部",
"conversion.upload.cancel": "取消",
"conversion.upload.start": "開始轉檔",
"conversion.upload.error.noFile": "請選擇 .onnx 或 .tflite 檔案",
"conversion.upload.error.unsupported":
"不支援的格式,請改用 ONNX 或 TFLite",
"conversion.upload.error.modelTooLarge":
"模型超過 500 MB 上限,請改用較小的模型",
"conversion.upload.error.noChip": "請選擇目標晶片",
"conversion.upload.error.refTooLarge":
"{filename} 超過 10 MB請移除或壓縮後再試",
"conversion.upload.error.refTooMany": "Reference images 上限 100 張",
// uploading 階段Dialog 內)
"conversion.uploading.title": "上傳中",
"conversion.uploading.heading": "正在上傳到 visionA…",
"conversion.uploading.progress": "已上傳 {loaded} / {total} · 預估剩餘 {eta}",
"conversion.uploading.almostDone": "即將完成…",
"conversion.uploading.warning": "請勿關閉此分頁,否則上傳會中斷",
"conversion.uploading.cancel": "取消上傳",
"conversion.uploading.cancelConfirm": "上傳尚未完成,確定取消?",
"conversion.uploading.tabTitle": "visionA Cloud · 上傳中 ({pct}%)",
"conversion.uploading.toastCanceled": "已取消上傳",
"conversion.uploading.toastFailed": "上傳失敗:{reason}",
"conversion.uploading.toastStarted": "已開始轉檔(任務 #{shortJobId}",
// F-T9 sub-3 / M1上傳失敗 toast hint
// M1 修補File 物件不能保留在 store不可序列化、跨 unmount 不安全),
// 失敗回 idle 後 chip / taskName 透過 store.formDraft 保留,但檔案需重選
"conversion.toast.retryHint": "您之前的設定(晶片 / 任務名稱)仍保留,請重新選擇檔案再試",
"conversion.toast.networkError": "網路錯誤,請檢查連線後重試",
// F-T5ETA / 取消確認 / beforeunload細節 keys
"conversion.uploading.subtitle": "正在上傳模型到 visionA backend",
"conversion.uploading.eta.computing": "預估剩餘時間…",
"conversion.uploading.eta.almostDone": "即將完成…",
"conversion.uploading.eta.format": "預估剩餘 {eta}",
"conversion.uploading.progress.format": "{loaded} / {total}",
"conversion.uploading.info": "上傳完成後將開始轉檔1030 秒不等)",
"conversion.uploading.cancel.confirm.title": "取消轉檔?",
"conversion.uploading.cancel.confirm.message":
"上傳尚未完成,已上傳的進度會丟失。確定要取消嗎?",
"conversion.uploading.cancel.confirm.yes": "確定取消",
"conversion.uploading.cancel.confirm.no": "繼續上傳",
"conversion.uploading.warning.beforeunload":
"上傳尚未完成,離開將中斷上傳。",
"conversion.uploading.target": "目標晶片:{chip}",
"conversion.uploading.aria.cancel": "取消上傳",
"conversion.uploading.aria.progress": "上傳進度",
"conversion.uploading.aria.status": "已上傳 {pct}%{eta}",
// processing 階段(轉檔進行中)
"conversion.processing.title": "轉檔",
"conversion.processing.cardHeading": "進行中",
"conversion.processing.statusBadge": "轉檔中",
"conversion.processing.startedAgo": "開始於 {time}",
"conversion.processing.stage1": "上傳完成",
"conversion.processing.stage2": "解析模型",
"conversion.processing.stage3": "編譯 NEF",
"conversion.processing.processing": "處理中…",
"conversion.processing.hint":
"通常需要 110 分鐘 · 你可以離開此頁面,回來時會自動更新進度",
"conversion.processing.background.title": "你可以放著不管",
"conversion.processing.background.l1":
"我們會在背景持續查詢進度(每 510 秒一次)",
"conversion.processing.background.l2": "完成後分頁標題會通知你",
"conversion.processing.background.l3":
"此頁面關掉也沒關係,回來時會自動恢復",
"conversion.processing.queueLong":
"目前排隊較久,你可以離開此頁稍後再回",
"conversion.processing.runLong": "轉檔耗時較長,仍在進行中",
"conversion.processing.pollFailed": "無法取得轉檔狀態,請重試",
"conversion.processing.bannerActive": "您離開前的轉檔仍在進行中",
"conversion.processing.bannerExisting":
"您已有一個轉檔正在進行中,已切換至該任務",
// F-T9 sub-2banner dismiss 按鈕的 a11y label
"conversion.processing.bannerDismiss": "關閉提示",
// F-T6ProcessingViewqueued / running 共用 UI
// 任務描述對應 converter `stage` enumonnx / bie / nef— 與既有 stage1/2/3
// (上傳完成 / 解析模型 / 編譯 NEF的「使用者感知」三段不同ProcessingView
// 採用 onnx / bie / nef 對應 converter 真實 stage。詳見任務說明 §wireframe §3.3。
"conversion.processing.subtitle": "正在轉檔,請保持頁面開啟",
"conversion.processing.queued": "排隊中⋯",
"conversion.processing.stage.onnx": "解析模型",
"conversion.processing.stage.bie": "量化編譯",
"conversion.processing.stage.nef": "編譯 NEF",
"conversion.processing.stage.status.completed": "完成",
"conversion.processing.stage.status.current": "進行中",
"conversion.processing.stage.status.pending": "待處理",
"conversion.processing.stage.aria.completed": "{name}(已完成)",
"conversion.processing.stage.aria.current": "{name}(進行中)",
"conversion.processing.stage.aria.pending": "{name}(待處理)",
"conversion.processing.eta.pending": "請耐心等候",
"conversion.processing.eta.computing": "剩餘時間估算中",
"conversion.processing.expiryHint":
"7 天後將自動清除任務,請完成下載或加到模型庫",
"conversion.processing.tabTitle.prefix": "(轉檔中) ",
"conversion.processing.aria.progressIndeterminate":
"轉檔進行中,剩餘時間未知",
"conversion.processing.aria.queueProgress": "排隊中,等待轉檔開始",
"conversion.processing.targetChipPrefix": "→",
// 已有 active job 提示idle 頁也會用到)
"conversion.busy.title": "您已有一個轉檔正在進行中",
"conversion.busy.cta": "查看進度",
// success 結果
"conversion.success.heading": "轉檔完成",
"conversion.success.summary.chip": "目標晶片",
"conversion.success.summary.size": "輸出大小",
"conversion.success.summary.duration": "耗時",
"conversion.success.summary.checksum": "checksum",
"conversion.success.summary.jobId": "任務",
"conversion.success.nextStep": "接下來要做什麼?",
"conversion.success.import.title": "加到模型庫",
"conversion.success.import.description":
"之後可以從模型庫部署到任何 {chip} 裝置",
"conversion.success.import.cta": "加到模型庫",
"conversion.success.import.dialog.title": "加到模型庫",
"conversion.success.import.dialog.description":
"把這個轉檔結果加到模型庫,之後可以直接部署到 {chip} 裝置",
"conversion.success.import.dialog.nameLabel": "模型名稱",
"conversion.success.import.dialog.nameHint":
"顯示在模型庫中的名稱,最多 100 字元;不可包含 / 或 \\",
"conversion.success.import.dialog.nameError.required": "請輸入模型名稱",
"conversion.success.import.dialog.nameError.tooLong":
"模型名稱不可超過 100 字元",
"conversion.success.import.dialog.nameError.invalidChars":
"模型名稱不可包含 / 或 \\",
"conversion.success.import.dialog.descLabel": "描述(選填)",
"conversion.success.import.dialog.sourceLabel": "來源",
"conversion.success.import.dialog.sourceValue": "轉檔job #{shortJobId}",
"conversion.success.import.dialog.confirm": "加到模型庫",
"conversion.success.import.dialog.cancel": "取消",
"conversion.success.import.processing": "處理中…",
"conversion.success.import.toastDone": "已加入模型庫",
"conversion.success.import.toastDoneAction": "前往模型庫 →",
"conversion.success.import.toastDup": "此任務已加入過模型庫",
"conversion.success.import.toastDupAction": "查看現有模型 →",
"conversion.success.import.statusDone": "✓ 已加入(前往查看 →)",
"conversion.success.import.errorGeneric":
"加到模型庫失敗,請稍後再試",
"conversion.success.import.aria.cta":
"加到模型庫(會開啟確認對話框)",
"conversion.success.download.title": "下載 .nef",
"conversion.success.description":
"{source} 已成功轉成 {chip} 可用的 .nef 檔",
"conversion.success.summary.outputFile": "輸出檔案",
"conversion.success.summary.notAvailable": "—",
"conversion.success.download.description": "存到本機自行使用",
"conversion.success.download.cta": "下載",
"conversion.success.download.preparing": "準備下載…",
"conversion.success.download.toastStart": "下載已開始",
"conversion.success.download.toastHint":
"若沒看到下載提示,請檢查瀏覽器設定",
"conversion.success.download.toastFail": "下載連結取得失敗",
"conversion.success.download.aria.cta": "下載 .nef 檔到本機",
"conversion.success.download.aria.disabled":
"下載連結已過期,請開始新轉檔",
"conversion.success.expiry":
"此轉檔結果將在 {time} 後自動清除,請在期限內完成處理",
"conversion.success.expiry.expired": "此轉檔結果已過期",
"conversion.success.expiry.remaining.daysHours": "{days} 天 {hours} 小時",
"conversion.success.expiry.remaining.daysOnly": "{days} 天",
"conversion.success.expiry.remaining.hoursMinutes":
"{hours} 小時 {minutes} 分鐘",
"conversion.success.expiry.remaining.hoursOnly": "{hours} 小時",
"conversion.success.expiry.remaining.minutes": "{minutes} 分鐘",
"conversion.success.startNew": "開始新轉檔",
// failed 結果
"conversion.failed.heading": "轉檔失敗",
"conversion.failed.errorCode": "錯誤代碼",
"conversion.failed.suggestionsTitle": "你可以試試:",
"conversion.failed.retry": "重新開始",
"conversion.failed.backToModels": "回模型庫",
"conversion.failed.contactSupport":
"若持續發生,請複製任務 ID 聯絡支援團隊",
"conversion.failed.copyJobId": "複製任務 ID",
"conversion.failed.toastJobIdCopied": "已複製任務 ID",
// F-T8 新增 — FailedView 用
"conversion.failed.aria.alert": "轉檔失敗通知",
"conversion.failed.jobIdLabel": "Job ID",
"conversion.failed.summary.failedSuffix": "(失敗)",
"conversion.failed.aria.retry": "回到起點,重新開始一次轉檔",
// 錯誤碼翻譯(對應 PRD §F5 + .autoflow/04-architecture/conversion.md
"conversion.error.UNSUPPORTED_FORMAT.message":
"此模型格式目前不支援,請改用 ONNX / TFLite",
"conversion.error.UNSUPPORTED_FORMAT.suggestion1": "確認檔案副檔名",
"conversion.error.UNSUPPORTED_FORMAT.suggestion2": "用標準 export 工具",
"conversion.error.INVALID_CHECKSUM.message":
"檔案傳輸過程毀損,請重新上傳",
"conversion.error.INVALID_CHECKSUM.suggestion1": "重新開始上傳",
"conversion.error.QUANTIZATION_FAILED.message":
"模型內含不支援的運算子,無法量化到目標晶片",
"conversion.error.QUANTIZATION_FAILED.suggestion1": "簡化模型結構",
"conversion.error.QUANTIZATION_FAILED.suggestion2": "移除 Custom Op",
"conversion.error.QUANTIZATION_FAILED.suggestion3": "改用較小的 input shape",
"conversion.error.MODEL_TOO_LARGE.message": "模型超過 500 MB 上限",
"conversion.error.MODEL_TOO_LARGE.suggestion1": "改用較小模型",
"conversion.error.MODEL_TOO_LARGE.suggestion2": "嘗試 Pruning / Quantization",
"conversion.error.QUOTA_EXCEEDED.message": "系統暫時繁忙,請稍後再試",
"conversion.error.QUOTA_EXCEEDED.suggestion1": "等 5 分鐘後重試",
"conversion.error.unknown.message":
"轉檔失敗,請稍後重試。若持續發生請聯絡支援團隊",
"conversion.error.unknown.suggestion1": "複製任務 ID 回報給支援團隊",
// 已過期 / 找不到
"conversion.expired.heading": "此轉檔結果已過期",
"conversion.expired.description":
"轉檔結果保留期為 7 天,目前已超過保留期限並自動清除。",
// F-T9 sub-1ExpiredView 補充說明 — 解釋為什麼過期 + 怎麼處理
"conversion.expired.subDescription":
"如需重新取得轉檔結果,請按下方按鈕重新提交一次。",
// F-T9 sub-1ExpiredView a11y
"conversion.expired.aria.alert": "轉檔結果已過期通知",
"conversion.expired.aria.startNew": "重新開始一次轉檔",
"conversion.expired.startNew": "重新轉檔",
// mobile hint≥ 500 MB 檔在手機上傳體驗差)
"conversion.mobileHint":
"Mobile 設備上傳大型模型可能不穩定,建議使用桌面版瀏覽器",
// ── ClustersF7 新增 stub──
"clusters.title": "叢集",
"clusters.subtitle": "把多台 Kneron 裝置組成平行推論叢集",
"clusters.create": "建立叢集",
"clusters.empty.title": "叢集推論 — Phase 1 推出",
"clusters.empty.description":
"Phase 1 會把多裝置平行推論、降級機制等 POC 能力搬進雲端版",
"clusters.phase1Badge": "Phase 1 推出",
"clusters.phase1Toast": "叢集建立功能 Phase 1 才支援",
};