2026-07-10 05:10:31 +00:00
import type { AppLocale } from "./types" ;
/** 扁平 key → 字串;{name} 可插值 */
export type MessageDict = Record < string , string > ;
export const zhTW : MessageDict = {
"app.name" : "巡樓" ,
"app.nameEn" : "Lapras" ,
"app.nameZh" : "巡樓" ,
"app.tagline" : "Threads 海巡好幫手" ,
"app.taglineEn" : "Patrol Threads with ease" ,
"nav.today" : "今日" ,
"nav.crew" : "帳號" ,
"nav.studio" : "創作" ,
"nav.scout" : "海巡" ,
"nav.outbox" : "發送" ,
"nav.jobs" : "任務" ,
"nav.brands" : "品牌" ,
"nav.more" : "更多" ,
"nav.moreTitle" : "更多功能" ,
"nav.users" : "島民管理" ,
"nav.usage" : "用量與方案" ,
"nav.profile" : "會員資料" ,
2026-07-10 12:54:45 +00:00
"nav.invite" : "邀請關係" ,
2026-07-10 05:10:31 +00:00
"nav.settings" : "系統設定" ,
"nav.logout" : "登出" ,
"nav.navigate" : "導覽" ,
"common.save" : "儲存" ,
"common.cancel" : "取消" ,
"common.loading" : "載入中…" ,
"common.back" : "返回" ,
"common.delete" : "刪除" ,
"common.edit" : "編輯" ,
"common.search" : "搜尋" ,
"common.confirm" : "確定" ,
"common.optional" : "選填" ,
"common.success" : "已儲存" ,
"common.error" : "發生錯誤" ,
"common.yes" : "是" ,
"common.no" : "否" ,
2026-07-10 12:54:45 +00:00
// 後端 envelope code( apps/backend response + middleware)
"api.err.unknown" : "操作失敗,請稍後再試" ,
"api.err.network" : "無法連線後端,請確認網路或服務是否啟動" ,
"api.err.400001" : "請求格式不正確" ,
// 與後端 400003 / ValidatePasswordPolicy 同一句(勿各寫各的)
"api.err.400003" : "密碼須至少 12 碼,且含大寫、小寫、數字與符號" ,
"password.policy.hint" : "密碼須至少 12 碼,且含大寫、小寫、數字與符號" ,
"password.policy.minLen" : "密碼須至少 12 碼,且含大寫、小寫、數字與符號" ,
"password.policy.needUpper" : "密碼須至少 12 碼,且含大寫、小寫、數字與符號" ,
"password.policy.needLower" : "密碼須至少 12 碼,且含大寫、小寫、數字與符號" ,
"password.policy.needDigit" : "密碼須至少 12 碼,且含大寫、小寫、數字與符號" ,
"password.policy.needSymbol" : "密碼須至少 12 碼,且含大寫、小寫、數字與符號" ,
"api.err.400004" : "驗證碼無效或已過期" ,
"api.err.400020" : "不能停權自己的帳號" ,
"api.err.400021" : "不能移除或停權最後一位管理員" ,
"api.err.401001" : "請先登入" ,
"api.err.401002" : "登入已失效,請重新登入" ,
"api.err.401003" : "找不到會員資料,請重新登入" ,
"api.err.401010" : "Email 或密碼錯誤" ,
"api.err.403001" : "帳號已停權" ,
"api.err.403002" : "需要管理員權限" ,
"api.err.404001" : "找不到資料" ,
"api.err.404002" : "查無此信箱,請確認後再試" ,
"api.err.409001" : "此 Email 已被註冊" ,
"api.err.500000" : "伺服器發生錯誤,請稍後再試" ,
"api.err.501000" : "此功能尚未實作" ,
// 後端 data.message 成功文案
"api.ok.verifySent" : "驗證碼已寄出,請查收信箱" ,
"api.ok.verifyIssued" : "驗證碼已產生" ,
"api.ok.resetSent" : "重設信已寄出,請查收信箱" ,
"api.ok.passwordUpdated" : "密碼已更新" ,
"api.ok.loggedOut" : "已登出" ,
"api.ok.unbound" : "已解除綁定" ,
2026-07-10 05:10:31 +00:00
"topbar.notifications" : "通知" ,
"topbar.unread" : "{n} 未讀" ,
"topbar.markAllRead" : "全已讀" ,
"topbar.noNotifications" : "目前沒有通知" ,
"topbar.jobsCenter" : "任務中心" ,
"topbar.moreOlder" : "還有 {n} 則較舊" ,
"topbar.account" : "帳號選單" ,
"role.admin" : "管理員" ,
"role.member" : "一般會員" ,
"role.verified" : "已驗證" ,
"role.unverified" : "未驗證" ,
"login.title" : "登入巡樓" ,
"login.email" : "Email" ,
"login.password" : "密碼" ,
"login.submit" : "登入" ,
"login.submitting" : "登入中…" ,
"login.forgot" : "忘記密碼?" ,
"login.mockHint" : "管理員 demo@harbor.local / demo · 一般會員 alice@harbor.local / alice" ,
2026-07-10 12:54:45 +00:00
"login.liveHint" : "Live 後端: admin@haixun.local / admin123( gateway :8888) " ,
2026-07-10 05:10:31 +00:00
"forgot.title" : "忘記密碼" ,
"forgot.submit" : "寄送重設連結" ,
"forgot.submitting" : "送出中…" ,
"forgot.back" : "返回登入" ,
2026-07-10 12:54:45 +00:00
"forgot.hint" : "輸入註冊用 Email, 我們會寄送重設連結與驗證碼。" ,
2026-07-10 05:10:31 +00:00
"forgot.mockMail" : "重設信" ,
2026-07-10 12:54:45 +00:00
"forgot.openReset" : "前往輸入驗證碼/重設密碼" ,
2026-07-10 05:10:31 +00:00
"forgot.retry" : "再試一次" ,
2026-07-10 12:54:45 +00:00
"forgot.nextStep" : "請查收信箱中的驗證碼或連結,再到重設頁完成新密碼。" ,
2026-07-10 05:10:31 +00:00
"reset.title" : "設定新密碼" ,
2026-07-10 12:54:45 +00:00
"reset.hint" : "請輸入信箱、驗證碼(信內 6 碼或連結參數)與新密碼。" ,
"reset.code" : "驗證碼" ,
"reset.codePh" : "信內 6 位數字" ,
"reset.needEmail" : "請輸入 Email" ,
"reset.needCode" : "請輸入驗證碼" ,
2026-07-10 05:10:31 +00:00
"reset.newPassword" : "新密碼" ,
"reset.confirm" : "確認新密碼" ,
"reset.submit" : "更新密碼" ,
"reset.submitting" : "更新中…" ,
"reset.missingToken" : "連結缺少 token。請從「忘記密碼」重新申請。" ,
"verify.title" : "驗證信箱" ,
"verify.pending" : "尚未驗證" ,
"verify.body" : "帳號已開通登入,但信箱未驗證前無法使用功能。請輸入寄到你信箱的 6 位驗證碼。" ,
"verify.code" : "驗證碼" ,
"verify.submit" : "完成驗證" ,
"verify.submitting" : "驗證中…" ,
"verify.resend" : "重新寄送驗證碼" ,
"verify.sending" : "寄送中…" ,
"verify.logout" : "登出" ,
"verify.mockMail" : "驗證信" ,
"verify.mockHint" : "請輸入驗證碼:" ,
"verify.after" : "驗證完成後即可使用今日、創作、海巡等功能。" ,
"settings.title" : "設定" ,
"settings.localeCurrency" : "語言與幣別" ,
"settings.locale" : "介面語言" ,
"settings.currency" : "顯示幣別" ,
"settings.currencyHint" : "" ,
"settings.localeSaved" : "語言與幣別已更新" ,
"settings.appearance" : "外觀" ,
"settings.theme" : "主題" ,
"settings.themeLight" : "淺色" ,
"settings.themeDark" : "深色" ,
"settings.themeSystem" : "跟隨系統" ,
"settings.themeHint" : "" ,
"settings.themeSaved" : "主題已更新" ,
"settings.themeToLight" : "切換成淺色" ,
"settings.themeToDark" : "切換成深色" ,
"settings.dataSource" : "資料來源" ,
2026-07-10 12:54:45 +00:00
"settings.dataSourceHint" :
"mock = 瀏覽器本機假資料; live = 打 apps/backend gateway。切 live 後請重新登入。" ,
"settings.dataSourceMock" : "Mock( 本機) " ,
"settings.dataSourceLive" : "Live( 後端 API) " ,
"settings.dataSourceCurrent" : "目前" ,
"settings.dataSourceSwitchedLive" : "已切到 Live — 請用後端帳號重新登入( admin@haixun.local / admin123) " ,
"settings.dataSourceSwitchedMock" : "已切回 Mock" ,
"settings.dataSourceLiveNeedGateway" : "需 gateway 在 :8888( 或 Vite proxy /api) " ,
2026-07-10 05:10:31 +00:00
"settings.ai" : "AI" ,
"settings.search" : "搜尋" ,
"settings.member" : "會員與登入" ,
"settings.usageCard" : "AI/ 搜尋額度" ,
"settings.usageCardHint" : "" ,
"settings.viewUsage" : "查看用量" ,
"settings.editProfile" : "編輯會員資料" ,
"settings.mockLogin" : "demo@harbor.local / demo" ,
"settings.memberHint" : "" ,
"usage.title" : "用量與方案" ,
"usage.desc" : "" ,
"usage.creditsUsed" : "本月已用點數" ,
"usage.remaining" : "剩餘 {n} 點" ,
"usage.percentUsed" : "{n}% 已使用" ,
"usage.breakdown" : "分項用量" ,
"usage.plans" : "方案" ,
"usage.current" : "目前" ,
"usage.inUse" : "使用中" ,
"usage.switchMock" : "切換方案" ,
"usage.perMonth" : "點/月" ,
"usage.ledger" : "最近使用紀錄" ,
"usage.emptyTitle" : "本月還沒有扣點" ,
"usage.emptyDesc" : "" ,
"usage.planNote" : "" ,
"usage.switched" : "已切換為 {name}" ,
"usage.meter.times" : "{count} 次 · {credits} 點" ,
"usage.meter.cap" : "單項參考上限 {count}/{cap} 次" ,
"usage.plan.free.blurb" : "試用與個人輕量經營" ,
"usage.plan.starter.blurb" : "小團隊日常發文與海巡" ,
"usage.plan.pro.blurb" : "多帳、重度 AI 與研究" ,
"profile.title" : "會員資料" ,
"profile.desc" : "" ,
"profile.accountStatus" : "帳號開通狀態" ,
"profile.basic" : "基本資料" ,
"profile.avatar" : "頭像" ,
"profile.avatarUpload" : "上傳頭像" ,
"profile.avatarRemove" : "移除頭像" ,
2026-07-10 12:54:45 +00:00
"profile.avatarHint" : "JPG/ PNG/ WebP, 5MB 內。選圖後按「儲存基本資料」寫入;「移除頭像」會立刻清除。" ,
2026-07-10 05:10:31 +00:00
"profile.avatarSaved" : "頭像已更新" ,
"profile.avatarCleared" : "已移除頭像" ,
"profile.avatarFail" : "無法讀取圖片" ,
"profile.displayName" : "顯示名稱" ,
"profile.bio" : "簡介(選填)" ,
"profile.timezone" : "時區" ,
"profile.notifyEmail" : "Email 通知" ,
"profile.password" : "變更密碼(選填)" ,
"profile.currentPassword" : "目前密碼" ,
"profile.newPassword" : "新密碼" ,
"profile.confirmPassword" : "確認新密碼" ,
"profile.emailVerified" : "信箱已驗證" ,
"profile.emailUnverified" : "信箱未驗證" ,
"profile.roleAdmin" : "管理員" ,
"profile.roleMember" : "一般會員" ,
"profile.loginEmail" : "登入信箱:{email}" ,
"profile.verifiedAt" : " · 驗證於 {time}" ,
"profile.goVerify" : "去驗證信箱" ,
"profile.roleTags" : "權限標籤:{labels}" ,
"profile.roleNote" : "角色由系統指派;改信箱後需重新驗證。" ,
"profile.saveBasic" : "儲存基本資料" ,
"profile.updatePassword" : "更新密碼" ,
"profile.saved" : "會員資料已儲存" ,
"profile.savedUnverified" : "資料已儲存。信箱尚未驗證或已變更,請完成驗證後才能繼續使用功能。" ,
"profile.saveFail" : "儲存失敗" ,
"profile.needNewPassword" : "請輸入新密碼" ,
"profile.passwordMismatch" : "兩次新密碼不一致" ,
"profile.needCurrentPassword" : "請輸入目前密碼" ,
2026-07-10 12:54:45 +00:00
"profile.wrongCurrentPassword" : "目前密碼不正確" ,
2026-07-10 05:10:31 +00:00
"profile.passwordUpdated" : "密碼已更新" ,
"profile.passwordFail" : "變更密碼失敗" ,
"profile.listJoin" : "、" ,
"profile.tenantUid" : " · tenant {tenant} · uid {uid}" ,
2026-07-10 12:54:45 +00:00
"profile.inviteBadge" : "邀請碼" ,
"profile.inviteHint" : "分享給朋友加入;日後活動可依邀請關係計算。" ,
"profile.gotoInvite" : "查看邀請關係" ,
"invite.title" : "邀請關係" ,
"invite.desc" : "邀請碼與邀請關係;管理端為樹狀結構。" ,
"invite.tabs" : "邀請檢視" ,
"invite.tab.mine" : "我的邀請" ,
"invite.tab.tree" : "關係樹" ,
"invite.myCode" : "我的邀請碼" ,
"invite.codeLabel" : "邀請碼" ,
"invite.copyCode" : "複製" ,
"invite.copied" : "已複製" ,
"invite.copyFail" : "複製失敗" ,
"invite.stats" : "直邀 {direct} · 延伸 {total}" ,
"invite.upline" : "邀請人" ,
"invite.downlines" : "直邀成員 · {n}" ,
"invite.noUpline" : "無邀請人" ,
"invite.noDownline" : "尚無直邀" ,
"invite.directN" : "直邀 {n}" ,
"invite.claimHint" : "若註冊時沒填,可在此補上邀請人的邀請碼(綁定後不可自行更改)。" ,
"invite.claimLabel" : "邀請碼" ,
"invite.claimPh" : "例如 HX-DEMO01" ,
"invite.claimSubmit" : "確認綁定" ,
"invite.claimOk" : "已綁定邀請人:{name}" ,
"invite.claimOkGeneric" : "已綁定邀請人" ,
"invite.claimFail" : "綁定失敗" ,
"invite.claimLocked" : "已綁定,如需調整請聯絡管理員。" ,
"invite.loadFail" : "載入失敗" ,
"invite.treeEmpty" : "尚無資料" ,
"invite.treeSearch" : "搜尋" ,
"invite.treeSearchPh" : "名稱 / Email / 邀請碼" ,
"invite.treeCount" : "{n} 人" ,
"invite.treeMatchCount" : "命中 {n} · 共 {total}" ,
"invite.treeNoMatch" : "沒有符合的島民" ,
"invite.treeNoMatchHint" : "換個關鍵字試試" ,
"invite.clearSearch" : "清除" ,
"invite.moveTitle" : "調整歸屬" ,
"invite.newParent" : "邀請人" ,
"invite.root" : "(無 · 獨立)" ,
"invite.confirmMove" : "確認" ,
"invite.moved" : "已調整「{name}」→「{parent}」" ,
"invite.moveFail" : "調整失敗" ,
"invite.openFromAdmin" : "邀請關係" ,
"invite.parentField" : "邀請人" ,
"invite.orgPickRoot" : "選一個起點(含無人邀請、自己進來的)" ,
"invite.orgRoots" : "起點" ,
"invite.orgPath" : "路徑" ,
"invite.orgChainN" : "延伸 {n}" ,
"invite.orgFocusStats" : "直邀 {direct} · 延伸 {total}" ,
"invite.orgDirects" : "直邀成員 · {n}" ,
"invite.orgNoDirects" : "沒有直邀成員" ,
"invite.err.notFound" : "找不到會員" ,
"invite.err.notLoggedIn" : "尚未登入" ,
"invite.err.needAdmin" : "需要管理員權限" ,
"invite.err.memberNotFound" : "找不到島民" ,
"invite.err.selfParent" : "不能把自己設為邀請人" ,
"invite.err.parentNotFound" : "找不到指定的邀請人" ,
"invite.err.cycle" : "不可掛到自己邀請鏈的下層(會形成環)" ,
"invite.err.repoMissing" : "邀請資料層尚未載入,請重新整理頁面" ,
"invite.err.alreadyBound" : "你已有邀請人,無法再補填" ,
"invite.err.codeRequired" : "請輸入邀請碼" ,
"invite.err.codeNotFound" : "找不到此邀請碼" ,
"invite.err.codeSelf" : "不能填自己的邀請碼" ,
2026-07-10 05:10:31 +00:00
"admin.users.title" : "島民管理" ,
"admin.users.desc" : "" ,
"admin.users.needAdmin" : "需要管理員權限" ,
"admin.users.list" : "島民列表 · {n}" ,
"admin.users.detail" : "島民詳情" ,
"admin.users.pick" : "選擇島民" ,
"admin.users.search" : "搜尋名稱 / uid" ,
"admin.users.searchPh" : "島民名稱、Email 或 uid" ,
"admin.users.create" : "新增島民" ,
"admin.users.suspend" : "停權" ,
"admin.users.unsuspend" : "復權" ,
"admin.users.suspended" : "已停權" ,
"admin.users.active" : "正常" ,
"crew.title" : "帳號" ,
"crew.tab.accounts" : "帳號" ,
"crew.tab.personas" : "人設" ,
"crew.connect" : "連接帳號" ,
"crew.connecting" : "新增中…" ,
"crew.refreshAll" : "全部刷新 session" ,
"crew.refreshing" : "刷新中…" ,
"crew.empty" : "尚無帳號" ,
"crew.unusable" : "不可用" ,
"crew.expires" : "過期 {time}" ,
"crew.lastRefresh" : "上次更新 {time}" ,
"crew.refreshSession" : "刷新 session" ,
"crew.session.ok" : "session 有效" ,
"crew.session.soon" : "即將到期" ,
"crew.session.expired" : "session 過期" ,
"crew.session.unknown" : "session 未知" ,
"crew.msg.refreshed" : "@{user} session 已刷新(延長約 30 天)" ,
"crew.msg.refreshedAll" : "已刷新 {n} 個帳號 session" ,
"crew.msg.refreshFail" : "刷新失敗" ,
"crew.confirmDelete" : "確定刪除帳號 @{user}? \n刪除後無法再選為 lead / cast。" ,
"today.findTopic" : "找話題" ,
"today.pendingReplies" : "待回覆" ,
"today.pendingRepliesN" : "待回覆 · {n}" ,
"today.newThread" : "開新串" ,
"today.metricsAria" : "今日數值" ,
"today.metric.pending" : "待回" ,
"today.metric.pendingHint" : "海巡佇列" ,
"today.metric.doneGoal" : "已回/目標" ,
"today.metric.sentToday" : "今日已發" ,
"today.metric.running" : "進行中 {n}" ,
"today.metric.sentDone" : "完成的發送" ,
"today.metric.failed" : "發送異常" ,
"today.metric.needAction" : "需處理" ,
"today.metric.ok" : "正常" ,
"today.pending.title" : "待回覆 · {n}" ,
"today.pending.empty" : "目前沒有待回" ,
"today.goScout" : "去海巡" ,
"today.pending.more" : "還有 {n} 則 →" ,
"today.pending.handle" : "海巡處理" ,
"today.pending.start" : "開始處理" ,
"today.topics.title" : "找話題" ,
"today.topics.empty" : "還沒有話題" ,
"today.goStudio" : "去創作" ,
"today.heat" : "熱度 {n}" ,
"today.topicAngle" : "可當開場角度" ,
"today.moreInspire" : "更多靈感" ,
"today.useTopic" : "用話題開串" ,
"today.outbox.title" : "今日發送" ,
"today.outbox.empty" : "還沒有今日發送。可先" ,
"today.outbox.emptyMid" : ",完成後會出現在" ,
"today.outbox.emptyEnd" : "。" ,
"today.outbox.summary" : "已完成 {sent} · 進行中 {running} · 異常 {failed}" ,
"today.badge.failed" : "失敗" ,
"today.badge.scheduling" : "排程" ,
"today.badge.sending" : "發送中" ,
"today.openOutbox" : "開啟發送" ,
"today.accounts.title" : "帳號成效" ,
"today.accounts.empty" : "尚無成效" ,
"today.postsCount" : "{n} 則貼文" ,
"today.views" : "瀏覽" ,
"today.likes" : "讚" ,
"today.repliesShort" : "回" ,
"today.fullInsights" : "完整成效 · 月比圖" ,
"today.viewPosts" : "看已發文" ,
"today.manageAccounts" : "管理帳號" ,
"outbox.title" : "發送" ,
"outbox.tabsAria" : "發送分頁" ,
"outbox.tab.active" : "進行中" ,
"outbox.tab.history" : "歷史" ,
"outbox.empty" : "尚無發送" ,
"outbox.activeEmpty" : "進行中是空的" ,
"outbox.historyEmpty" : "尚無歷史" ,
"outbox.historyN" : "歷史({n}) " ,
"outbox.backActive" : "回進行中({n}) " ,
"outbox.progress" : "進度 {progress}" ,
"outbox.detail" : "詳情" ,
"outbox.deleting" : "刪除中…" ,
"outbox.confirmDelete" : "刪除發送項目「{title}」?\n無法復原。" ,
"outbox.deleted" : "已刪除「{title}」" ,
"outbox.deleteFail" : "刪除失敗" ,
"outbox.status.scheduling" : "排程中" ,
"outbox.status.active" : "發送中" ,
"outbox.status.completed" : "已完成" ,
"outbox.status.partial_failed" : "部分失敗" ,
"outbox.status.cancelled" : "已取消" ,
"outbox.detail.missingId" : "缺少 id" ,
"outbox.detail.notFound" : "找不到發送" ,
"outbox.detail.markAllOk" : "標記全部成功" ,
"outbox.detail.markRootFail" : "標記主貼失敗" ,
"outbox.detail.processing" : "處理中…" ,
"outbox.detail.delete" : "刪除這筆" ,
"outbox.detail.back" : "返回列表" ,
"outbox.detail.root" : "主貼" ,
"outbox.detail.replyN" : "回覆 {n}" ,
"outbox.detail.retry" : "重試" ,
"outbox.detail.opFail" : "操作失敗" ,
"studio.title" : "創作" ,
"studio.account" : "帳號" ,
"studio.persona" : "人設" ,
"studio.personaReady" : "人設 ready" ,
"studio.personaNotReady" : "人設未就緒" ,
"studio.tab.posts" : "我的貼文" ,
"studio.tab.mentions" : "提及 @" ,
"studio.tab.compose" : "寫一則" ,
"studio.tab.plays" : "互回方案" ,
"studio.tab.inspire" : "靈感" ,
"studio.tab.insights" : "成效" ,
"mentions.hint" : "誰 @ 你。待回 {n} 則。每則可改帳號/人設(預設用頂部)。" ,
"mentions.scoutLink" : "海巡外展" ,
"mentions.empty" : "尚無提及" ,
"mentions.status.pending" : "待回" ,
"mentions.status.replied" : "已回" ,
"mentions.status.skipped" : "略過" ,
"mentions.reply" : "回覆" ,
"mentions.skip" : "略過" ,
"mentions.draftLabel" : "回覆草稿" ,
"mentions.repliedPrefix" : "已回:{text}" ,
"mentions.needPersona" : "請選 ready 人設再 AI 產文" ,
"mentions.fail" : "失敗" ,
"mentions.marked" : "已標記回覆(帳號 @{user}) " ,
"mentions.withImages" : " · 附圖 {n}" ,
"compose.hint" : "單篇發文(非串場)。互回請用" ,
"compose.hintEnd" : "。" ,
"compose.playsLink" : "串場" ,
"compose.personaOff" : "人設未 ready: 仿寫/ 分析等 AI 工具停用。" ,
"compose.title" : "標題(選填)" ,
"compose.titlePh" : "方便在 Outbox 辨識" ,
"compose.body" : "正文" ,
"compose.bodyPh" : "寫下這則貼文…" ,
"compose.tool.mimic" : "仿寫" ,
"compose.tool.viral" : "爆紅分析" ,
"compose.tool.research" : "上網補資料" ,
"compose.tool.image" : "產圖" ,
"compose.mimic.title" : "仿寫別人貼文" ,
"compose.mimic.source" : "參考全文" ,
"compose.mimic.sourcePh" : "貼上想仿寫的貼文…" ,
"compose.mimic.running" : "仿寫中…" ,
"compose.mimic.run" : "依人設仿寫到正文" ,
"compose.mimic.done" : "仿寫完成,可再改" ,
"compose.viral.title" : "爆紅分析" ,
"compose.viral.hint" : "分析參考文或目前正文的鉤子/結構/可複製點。" ,
"compose.viral.source" : "分析對象(可空=用正文)" ,
"compose.viral.running" : "分析中…" ,
"compose.viral.run" : "開始分析" ,
"compose.viral.result" : "分析結果" ,
"compose.viral.done" : "爆紅分析完成" ,
"compose.viral.needText" : "請貼參考文或先寫正文" ,
"compose.research.title" : "上網補專業資料" ,
"compose.research.q" : "關鍵字" ,
"compose.research.qPh" : "例如:無香洗劑 敏感肌" ,
"compose.research.running" : "搜尋中…" ,
"compose.research.insert" : "插入勾選內容到正文" ,
"compose.research.inserted" : "已插入 {n} 條補充" ,
"compose.image.title" : "產圖" ,
"compose.image.prompt" : "畫面描述" ,
"compose.image.promptPh" : "可空=從正文摘要" ,
"compose.image.running" : "產圖中…" ,
"compose.image.run" : "產生圖片" ,
"compose.image.done" : "已產圖" ,
2026-07-10 12:54:45 +00:00
"compose.scheduleAt" : "預計發送時間" ,
"compose.scheduleHint" : "到點後由 Outbox 依序送出;可選現在。" ,
"compose.scheduleNow" : "設為現在" ,
2026-07-10 05:10:31 +00:00
"compose.publish" : "送出到 Outbox" ,
"compose.publishing" : "送出中…" ,
"compose.publishFail" : "送出失敗" ,
"compose.fail" : "失敗" ,
"compose.attachN" : "附圖 {n}" ,
"compose.personaStatus" : "人設:{status}" ,
"compose.ready" : "ready" ,
"compose.notReady" : "未就緒" ,
"posts.sync" : "重新同步 Threads" ,
"posts.syncing" : "同步中…" ,
"posts.syncedAt" : "同步 {time}" ,
"posts.notSynced" : "未同步" ,
"posts.syncDone" : "已同步 Threads 成效(讚/回/轉發/引用/瀏覽/分享)" ,
"posts.empty" : "尚無貼文" ,
"posts.openThreads" : "開 Threads" ,
"posts.insight" : "分析洞察:{text}" ,
"posts.review" : "覆盤:{text}" ,
"posts.formulaResult" : "結構分析結果" ,
"posts.collapseReplies" : "收合留言" ,
"posts.repliesBtn" : "留言({total})· 未回 {pending}" ,
"posts.replyRoot" : "回主貼" ,
"posts.analyzing" : "分析中…" ,
"posts.reanalyze" : "重新分析結構" ,
"posts.analyze" : "分析結構" ,
"posts.mimicThis" : "仿寫這則" ,
"posts.rootDraft" : "回主貼草稿" ,
"posts.filter.pending" : "未回覆({n}) " ,
"posts.filter.replied" : "已回覆({n}) " ,
"posts.filter.all" : "全部({n}) " ,
"posts.noPending" : "沒有未回覆留言" ,
"posts.noReplied" : "還沒有已回覆留言" ,
"posts.noReplies" : "尚無留言" ,
"posts.status.pending" : "未回覆" ,
"posts.status.replied" : "已回覆" ,
"posts.likesN" : "讚 {n}" ,
"posts.childCount" : "{n} 則子留言" ,
"posts.mine" : "我方" ,
"posts.replyThis" : "回這則" ,
"posts.replyAgain" : "再回一則" ,
"posts.replyTo" : "回 @{user}" ,
"posts.replyAgainTo" : "再回 @{user}" ,
"posts.needPersona" : "請先選 ready 人設再 AI 產文" ,
"posts.genFail" : "生成失敗" ,
"posts.needText" : "請先產生或輸入回覆" ,
"posts.sent" : "已用 @{user} 發送" ,
"posts.sentImages" : "(附圖 {n}) " ,
"posts.accountFallback" : "帳號" ,
"posts.sendFail" : "發送失敗" ,
"posts.analyzeDone" : "結構分析完成(手動觸發)" ,
"posts.analyzeFail" : "分析失敗" ,
"wizard.newTitle" : "編互回劇本" ,
"wizard.editTitle" : "編輯互回劇本" ,
"wizard.prev" : "上一步" ,
"wizard.next" : "下一步" ,
"wizard.err.topic" : "請填主題" ,
"wizard.err.lead" : "請選擇主帳號" ,
"wizard.err.leadUnusable" : "主帳號不可用" ,
"wizard.submitFail" : "提交失敗" ,
"wizard.unnamedPlay" : "未命名串場" ,
"wizard.step.topic" : "聊什麼" ,
"wizard.step.crew" : "誰出場" ,
"wizard.step.script" : "誰說什麼" ,
"wizard.step.preview" : "預覽" ,
"wizard.step.schedule" : "何時發" ,
"wizard.step.submit" : "送出" ,
"wizard.stepperAria" : "wizard 步驟" ,
"wizard.topic.title" : "1. 這串要聊什麼" ,
"wizard.topic.name" : "標題(可選)" ,
"wizard.topic.namePh" : "例如:週末咖啡" ,
"wizard.topic.topic" : "主題一句話" ,
"wizard.topic.topicPh" : "這串文想聊什麼?" ,
"wizard.topic.aiView" : "AI 視角" ,
"wizard.topic.personaNotReady" : "人設未就緒" ,
"wizard.topic.generating" : "生成中…" ,
"wizard.topic.aiSuggest" : "AI 幫我想" ,
"wizard.topic.quickFill" : "快速填入" ,
"wizard.topic.sampleTitle" : "週末咖啡話題" ,
"wizard.topic.sampleTopic" : "週末想找間不踩雷的咖啡店,插座要多、能坐久。" ,
"wizard.topic.aiTitle" : "AI 主題" ,
"wizard.topic.personaOpen" : "{name}開場" ,
"wizard.crew.title" : "2. 出場" ,
"wizard.crew.lead" : "主帳" ,
"wizard.crew.noUsable" : "尚無可用帳號" ,
"wizard.crew.unusable" : "不可用" ,
"wizard.crew.cast" : "配角" ,
"wizard.script.title" : "3. 台詞" ,
"wizard.script.persona" : "人設" ,
"wizard.script.personaNotReady" : "人設未就緒" ,
"wizard.script.root" : "主貼" ,
"wizard.script.replyN" : "回覆 {n}" ,
"wizard.script.generating" : "生成中…" ,
"wizard.script.ai" : "AI 產文" ,
"wizard.script.account" : "帳號:{name}" ,
"wizard.script.noLead" : "(未選 lead) " ,
"wizard.script.speaker" : "發言帳號" ,
"wizard.script.leadTag" : "( lead) " ,
"wizard.script.text" : "文案" ,
"wizard.script.rootPh" : "主貼內容…" ,
"wizard.script.replyPh" : "回覆內容…" ,
"wizard.script.addReply" : "新增回覆步驟" ,
"wizard.preview.title" : "4. 預覽這段對話" ,
"wizard.preview.unknown" : "未知" ,
"wizard.preview.unknownAccount" : "未知帳號" ,
"wizard.preview.root" : "主貼" ,
"wizard.preview.leadTalk" : "lead 接話" ,
"wizard.preview.empty" : "(空白)" ,
"wizard.schedule.title" : "5. 何時發出去" ,
"wizard.schedule.start" : "第一則(主貼)時間" ,
"wizard.schedule.interval" : "回覆間隔(分鐘)" ,
"wizard.schedule.intervalHint" : "相對上一步" ,
"wizard.submit.title" : "6. 送出排程" ,
"wizard.submit.body" : "確認後會把「{title}」這串互回(共 {n} 步)送進 Outbox, 依序用各帳號發出。" ,
"wizard.submit.unnamed" : "未命名" ,
"wizard.submit.root" : "主貼" ,
"wizard.submit.replyN" : "回覆 {n}" ,
"wizard.submit.submitting" : "提交中…" ,
"wizard.submit.run" : "提交到 Outbox" ,
"reply.account" : "用哪個帳號回" ,
"reply.persona" : "用人設" ,
"reply.notReady" : "此人設未 ready, 無法 AI 產文(仍可手打後發送)。" ,
"reply.draft" : "回覆草稿" ,
"reply.attach" : "附圖" ,
"reply.generating" : "生成中…" ,
"reply.ai" : "AI 產文" ,
"reply.sending" : "發送中…" ,
"reply.send" : "發送" ,
"image.attach" : "附圖" ,
"image.attachFail" : "附圖失敗" ,
"image.attachedAria" : "已附圖片" ,
"image.alt" : "附圖" ,
"image.named" : "附圖 {n}" ,
"image.remove" : "移除圖片" ,
"image.full" : "已滿 {max} 張" ,
"image.more" : "再附圖({n}/{max}) " ,
"metrics.aria" : "貼文成效" ,
"metrics.like" : "讚" ,
"metrics.reply" : "回覆" ,
"metrics.repost" : "轉發" ,
"metrics.quote" : "引用" ,
"metrics.view" : "瀏覽" ,
"metrics.share" : "分享" ,
"metrics.type.quote" : "引用貼" ,
"metrics.type.reply" : "回覆貼" ,
"metrics.type.image" : "圖片" ,
"metrics.type.video" : "影片" ,
"metrics.type.carousel" : "輪播" ,
"metrics.type.repost" : "轉發" ,
"metrics.type.text" : "文字" ,
"metrics.type.post" : "貼文" ,
"jobs.title" : "任務" ,
"jobs.startDemo" : "啟動任務" ,
"jobs.empty" : "尚無任務" ,
"jobs.total" : "共 {n} 筆" ,
"jobs.showing" : " · 顯示前 {n}" ,
"jobs.detail" : "詳情" ,
"jobs.loadMore" : "載入更多(還有 {n}) " ,
"jobs.notFound" : "找不到任務" ,
"jobs.progress" : "進度 {n}%" ,
"jobs.updated" : "更新 {time}" ,
"jobs.backList" : "返回列表" ,
"plans.title" : "變更方案" ,
"plans.current" : "目前方案" ,
"plans.perMonth" : "/月" ,
"plans.monthlyCredits" : "每月 {n} 點" ,
"plans.usageLink" : "用量" ,
"plans.inUse" : "使用中" ,
"plans.recommended" : "推薦" ,
"plans.creditsPerMonth" : "每月 {n} 點" ,
"plan.cta.current" : "目前方案" ,
"plan.cta.upgrade" : "升級" ,
"plan.cta.downgrade" : "降級" ,
"plan.cta.switch" : "切換" ,
"plan.free.headline" : "試用與個人輕量經營" ,
"plan.free.bullet1" : "每月 {n} 點 AI/ 搜尋" ,
"plan.free.bullet2" : "完整功能:創作、海巡、發送" ,
"plan.free.bullet3" : "適合先熟悉流程" ,
"plan.free.bullet4" : "可隨時升級" ,
"plan.free.right1" : "可使用完整功能:帳號、創作、海巡、發送、任務與靈感。" ,
"plan.free.right2" : "每月固定點數,用在文案、研究、搜尋與生圖。" ,
"plan.free.right3" : "達上限後需等下月或升級(除非管理員開不擋額度)。" ,
"plan.free.quota1" : "每月配給 {n} 點。" ,
"plan.free.quota2" : "參考:文案 {copy}、研究 {research}、搜尋 {search}、生圖 {image} 次。" ,
"plan.free.note1" : "無需付款,確認即切換。" ,
"plan.free.note2" : "正式金流後的發票規則另訂。" ,
"plan.starter.headline" : "小團隊日常發文與海巡" ,
"plan.starter.bullet1" : "每月 {n} 點(約 6× Free) " ,
"plan.starter.bullet2" : "穩定發文、回覆、海巡" ,
"plan.starter.bullet3" : "適合 1~ 3 人節奏" ,
"plan.starter.bullet4" : "付款成功立即生效" ,
"plan.starter.right1" : "付款成功後本帳改為 Starter, 當月依新額度計算。" ,
"plan.starter.right2" : "點數支撐固定發文、回覆草稿與定期海巡。" ,
"plan.starter.right3" : "功能與 Free 相同,差在能用多久。" ,
"plan.starter.quota1" : "每月 {n} 點 · {price}。" ,
"plan.starter.quota2" : "參考:文案 {copy}、研究 {research}、搜尋 {search}、生圖 {image} 次。" ,
"plan.starter.note1" : "需付款成功才變更方案。" ,
"plan.starter.note2" : "自然月重置,未用完點數不累積至下月。" ,
"plan.pro.headline" : "多帳、重度 AI 與研究" ,
"plan.pro.bullet1" : "每月 {n} 點(約 4× Starter) " ,
"plan.pro.bullet2" : "高頻文案/研究/生圖" ,
"plan.pro.bullet3" : "適合代理與多品牌" ,
"plan.pro.bullet4" : "付款成功立即生效" ,
"plan.pro.right1" : "付款成功後本帳改為 Pro, 當月依 Pro 額度計算。" ,
"plan.pro.right2" : "適合多帳、大量回覆與深研究,減少中途額度見底。" ,
"plan.pro.right3" : "功能相同;買的是容量與節奏。" ,
"plan.pro.quota1" : "每月 {n} 點 · {price}。" ,
"plan.pro.quota2" : "參考:文案 {copy}、研究 {research}、搜尋 {search}、生圖 {image} 次。" ,
"plan.pro.note1" : "付款失敗不會改方案。" ,
"plan.pro.note2" : "付款完成後可於帳務紀錄查詢收據。" ,
"checkout.title" : "確認方案" ,
"checkout.pickFirst" : "請先選擇方案。" ,
"checkout.viewPlans" : "看方案" ,
"checkout.cardLast4Required" : "請填卡號末四碼" ,
"checkout.cardNameRequired" : "請填持卡人" ,
"checkout.fail" : "無法完成" ,
"checkout.confirmFree" : "確認切換至 Free" ,
"checkout.payAndAction" : "{action}並付款 {price}" ,
"checkout.subscribe" : "訂閱" ,
"checkout.perMonth" : "/月" ,
"checkout.monthlyCredits" : "每月 {n} 點" ,
"checkout.youGet" : "你會得到" ,
"checkout.quota" : "額度" ,
"checkout.notes" : "注意" ,
"checkout.cardholder" : "持卡人" ,
"checkout.cardLast4" : "卡號末四碼" ,
"checkout.amountDue" : "應付金額" ,
"checkout.billedMonthly" : "{name} · 按月計費" ,
"checkout.already" : "已是此方案" ,
"checkout.processing" : "處理中…" ,
"checkout.currentPlan" : "目前方案" ,
"checkout.pickOther" : "改選其他方案" ,
"checkout.cancel" : "取消" ,
"usage.widget.titleUsed" : "{name} · 已用 {used}/ {cap} 點" ,
"usage.widget.titleUnlimited" : "{name} · 不擋額度" ,
"usage.widget.ariaUsed" : "已用 {used} 點,共 {cap} 點" ,
"usage.widget.dialog" : "方案與用量" ,
"usage.widget.currentPlan" : "目前方案" ,
"usage.widget.unlimited" : "不擋額度" ,
"usage.widget.perMonth" : "/月" ,
"usage.widget.monthUsage" : "本月用量" ,
"usage.widget.remaining" : "還剩 {n} 點" ,
"usage.widget.leftShort" : "還剩 {n}" ,
"usage.widget.overShort" : "已超額" ,
"usage.widget.upgradeShort" : "升級" ,
"usage.widget.upgrade" : "升級方案" ,
"usage.widget.includes" : "這個方案包含" ,
"usage.widget.nudge" : "本月額度快用完了,升級可立刻加大點數。" ,
"usage.widget.changePlan" : "變更方案" ,
"usage.widget.usageDetail" : "用量明細" ,
"usage.meter.ai_copy" : "AI 文案" ,
"usage.meter.ai_research" : "AI 研究" ,
"usage.meter.web_search" : "搜尋" ,
"usage.meter.ai_image" : "AI 生圖" ,
"usage.meter.barAria" : "{label} {count} 次 {credits} 點,上限 {cap}" ,
"usage.ledger.costAria" : "消耗 {n} 點" ,
"usage.chart.period" : "區間" ,
"usage.chart.allocated" : "配給" ,
"usage.chart.consumed" : "消耗" ,
"usage.chart.pctTitle" : "消耗佔配給比例" ,
"usage.chart.aria" : "配給與消耗" ,
"usage.chart.colAria" : "{label} 配給 {purchased} 消耗 {consumed}" ,
2026-07-10 12:54:45 +00:00
"settings.provider" : "Provider" ,
"settings.model" : "模型" ,
"settings.aiUnifiedHint" : "文案、研究、延伸全部使用同一 provider 與模型。" ,
2026-07-10 05:10:31 +00:00
"settings.fetchModels" : "取得模型" ,
"settings.fetchingModels" : "讀取中…" ,
2026-07-10 12:54:45 +00:00
"settings.apiKey" : "API Key" ,
2026-07-10 05:10:31 +00:00
"settings.configured" : "已設定" ,
"settings.notConfigured" : "未設定" ,
"settings.modelsLoaded" : "已取得 {provider} 模型清單" ,
"settings.aiSaved" : "AI 設定已儲存" ,
"settings.searchSaved" : "搜尋設定已儲存" ,
2026-07-10 12:54:45 +00:00
"settings.searchProvider" : "搜尋 Provider" ,
"settings.expand" : "延伸策略" ,
"settings.exaKey" : "Exa API Key" ,
"settings.devMode" : "開發模式(爬蟲測試海巡)" ,
"settings.devModeHint" : "開啟後測試海巡可走 Chrome 爬蟲;正式發文/留言仍走 API。請下載擴充以同步 Threads 登入態。" ,
"settings.ext.title" : "Chrome 擴充套件" ,
"settings.ext.desc" : "開發模式需安裝此擴充,才能從 Chrome 同步 Threads session 到巡樓。" ,
"settings.ext.step1" : "下載並解壓縮 ZIP, 得到 haixun-threads-sync 資料夾" ,
"settings.ext.step2" : "Chrome 開啟 chrome://extensions, 開啟「開發人員模式」" ,
"settings.ext.step3" : "點「載入未封裝項目」,選擇解壓後的資料夾" ,
"settings.ext.step4" : "在擴充選項填入此站網址,再重新整理巡樓頁" ,
"settings.ext.download" : "下載擴充套件( ZIP) " ,
2026-07-10 05:10:31 +00:00
"forgot.fail" : "送出失敗" ,
"forgot.mockHint" : "正式環境會寄到信箱;此處直接給連結:" ,
2026-07-10 12:54:45 +00:00
"forgot.checkInbox" : "請檢查信箱(含垃圾郵件)。" ,
2026-07-10 05:10:31 +00:00
"reset.mismatch" : "兩次密碼不一致" ,
"reset.fail" : "重設失敗" ,
"reset.cardTitle" : "重設密碼" ,
"reset.redirecting" : "即將前往登入頁…" ,
"reset.loginNow" : "立即登入" ,
2026-07-10 12:54:45 +00:00
"reset.passwordPh" : "密碼須至少 12 碼,且含大寫、小寫、數字與符號" ,
"reset.forgotLink" : "重新申請重設" ,
2026-07-10 05:10:31 +00:00
"verify.sendFail" : "寄送失敗" ,
"verify.fail" : "驗證失敗" ,
"verify.success" : "信箱已驗證,可以使用巡樓了。" ,
"verify.codePh" : "6 位數字" ,
"verify.currentAccount" : "目前帳號:{email}" ,
"login.brandTitle" : "巡樓 · Lapras" ,
"common.listSep" : "、" ,
"common.dash" : "—" ,
"scout.title" : "海巡" ,
"scout.today" : "今日" ,
"scout.purposeValue" : "痛點回覆" ,
"scout.purposeActivity" : "活躍短回" ,
"scout.goal" : "今日目標(則)" ,
"scout.progress" : "進度 {done}/{goal}" ,
"scout.intent" : "我想找/回應" ,
"scout.keyword" : "關鍵字" ,
"scout.intentPh" : "例:換季頭皮刺癢、真的無香、週末有插座" ,
"scout.keywordPh" : "例:週末 咖啡 遠端" ,
"scout.productOptional" : "產品(選填)" ,
"scout.noProduct" : "不帶產品" ,
"scout.brandFallback" : "品牌" ,
"scout.placement" : "置入:{label}" ,
"scout.painPart" : " · 痛點「{pain}」" ,
"scout.noProductsBefore" : "尚無產品,可到" ,
"scout.noProductsAfter" : "新增。" ,
"scout.start" : "開始" ,
"scout.startMore" : "再撈一批" ,
"scout.fetching" : "撈取中…" ,
"scout.runs" : "海巡批次" ,
"scout.runCount" : "批次({n}) " ,
"scout.runSelectAria" : "切換海巡批次" ,
"scout.runPending" : "待回 {n} · " ,
"scout.runDone" : "已清完 · " ,
"scout.runTotal" : "( {n} 則)" ,
"scout.deleteRun" : "刪除這一批" ,
"scout.deleting" : "刪除中…" ,
"scout.now" : "現在這一則" ,
"scout.emptyBatch" : "這一批沒有待回" ,
"scout.draft" : "回覆草稿" ,
"scout.draftPhActivity" : "短回…" ,
"scout.draftPhValue" : "共感 → 建議…" ,
"scout.sendAccount" : "用哪個帳號送" ,
"scout.noAccount" : "無可用帳號" ,
"scout.personaForRegen" : "人設(再產用)" ,
"scout.notReady" : "(未就緒)" ,
"scout.skip" : "略過" ,
"scout.regen" : "再產" ,
"scout.send" : "發送" ,
"scout.sending" : "發送中…" ,
"scout.needAccountBefore" : "請先到" ,
"scout.needAccountAfter" : "連線可用帳號。" ,
"scout.knowledge" : "周邊知識" ,
"scout.knowledgeWithLabel" : "周邊知識 · {label}" ,
"scout.knowledgeLearn" : "周邊知識 · 可學" ,
"scout.collapseKnowledge" : "收合知識" ,
"scout.expandLearn" : "展開學習 · {n} 則" ,
"scout.expandKnowledge" : "展開知識" ,
"scout.deleteKnowledgeRun" : "刪除此批知識與命中" ,
"scout.loadingKnowledge" : "正在整理周邊知識…" ,
"scout.notesCount" : "{n} 則" ,
"scout.noKnowledge" : "尚無周邊知識" ,
"scout.product" : "產品" ,
"scout.painsSolved" : "能解的痛" ,
"scout.focus" : "焦點" ,
"scout.all" : "全部" ,
"scout.noWebSummary" : "尚無網頁摘要" ,
"scout.queue" : "佇列 · {n}" ,
"scout.collapseQueue" : "收合佇列" ,
"scout.expandQueue" : "展開佇列" ,
"scout.noOtherPending" : "沒有其他待回" ,
"scout.learnPoints" : "學習重點" ,
"scout.replyHooks" : "回帖可借" ,
"scout.badgeCore" : "最貼主題" ,
"scout.unnamedRun" : "未命名批次" ,
"scout.thisRun" : "此批次" ,
"scout.confirmDeleteRun" : "刪除海巡批次「{label}」?\\n會一併刪除這批命中與周邊知識, 無法復原。" ,
"scout.deletedRun" : "已刪除批次「{label}」" ,
"scout.deleteRunFail" : "刪除批次失敗" ,
"scout.needKeyword" : "先填關鍵字" ,
"scout.needIntent" : "先寫這次要找什麼" ,
"scout.productMissing" : "所選產品不在列表中,請重新選擇" ,
"scout.defaultLabel" : "海巡" ,
"scout.newRunActivity" : "新批次「{label}」· {n} 則待回" ,
"scout.newRunValue" : "新批次「{label}」· {n} 則 · 請處理「現在這一則」" ,
"scout.knowledgeReady" : "「{label}」周邊知識已備好 · {n} 則可學" ,
"scout.patrolFail" : "這輪海巡失敗" ,
"scout.draftFail" : "產草稿失敗" ,
"scout.skipped" : "已略過" ,
"scout.noDraft" : "沒有可發送的草稿" ,
"scout.accountFallback" : "帳號" ,
"scout.sent" : "已發送(@{who})· 今日 {done}/{goal}" ,
"scout.sendFail" : "發送失敗" ,
"scout.confirmDeletePost" : "刪除這則命中?" ,
"scout.stanceActivity" : "短回 · 養活躍" ,
"scout.stanceProduct" : "共感 · 可輕帶產品" ,
"scout.stanceRelation" : "接話 · 建關係" ,
"scout.tier.core" : "最貼主題" ,
"scout.tier.coreHint" : "直接對準痛點/關鍵語,優先讀" ,
"scout.tier.adjacent" : "相關周邊" ,
"scout.tier.adjacentHint" : "鄰近情境,擴搜尋面" ,
"scout.tier.broad" : "最廣泛" ,
"scout.tier.broadHint" : "背景與對照,選讀即可" ,
"scout.relation.solves_pain" : "對準痛點" ,
"scout.relation.nearby_scene" : "鄰近場景" ,
"scout.relation.myth" : "迷思澄清" ,
"scout.relation.contrast" : "對照選購" ,
"scout.relation.background" : "背景脈絡" ,
"brands.title" : "品牌" ,
"brands.railAria" : "品牌列表" ,
"brands.railLabel" : "你的牌子" ,
"brands.add" : "新增" ,
"brands.brandName" : "品牌名稱" ,
"brands.brandNamePh" : "例如:自家品牌" ,
"brands.creating" : "建立中…" ,
"brands.createBrand" : "建立品牌" ,
"brands.searchAria" : "搜尋品牌" ,
"brands.searchPh" : "搜尋品牌…" ,
"brands.empty" : "尚無品牌" ,
"brands.noMatch" : "無符合" ,
"brands.selectAria" : "選擇品牌" ,
"brands.pickOne" : "選一個品牌" ,
"brands.inUseHint" : "使用中 · 海巡與創作會套用此牌" ,
"brands.inUse" : "使用中" ,
"brands.tabInfo" : "牌子資料" ,
"brands.tabProducts" : "產品" ,
"brands.tabProductsN" : "產品({n}) " ,
"brands.displayName" : "名稱" ,
"brands.brief" : "摘要" ,
"brands.briefPh" : "一句話說明這個牌子" ,
"brands.audience" : "受眾" ,
"brands.audiencePh" : "誰會在意、為什麼" ,
"brands.goals" : "目標" ,
"brands.goalsPh" : "想在 Threads 達成什麼" ,
"brands.saving" : "儲存中…" ,
"brands.deleteBrand" : "刪除品牌" ,
"brands.searchProductAria" : "搜尋產品" ,
"brands.searchProductPh" : "搜尋產品…" ,
"brands.addProduct" : "新增產品" ,
"brands.noProducts" : "尚無產品" ,
"brands.hasLink" : "有連結" ,
"brands.painLabel" : "痛點 " ,
"brands.editProduct" : "編輯產品" ,
"brands.newProduct" : "新增產品" ,
"brands.importFromUrl" : "從商品連結帶入" ,
"brands.fetching" : "抓取中…" ,
"brands.fetch" : "抓取" ,
"brands.pains" : "痛點" ,
"brands.painsPh" : "一列一個" ,
"brands.tags" : "標籤" ,
"brands.tagsPh" : "逗號分隔" ,
"brands.intro" : "介紹" ,
"brands.link" : "連結" ,
"brands.update" : "更新" ,
"brands.createItem" : "新增" ,
"brands.needName" : "請輸入名稱" ,
"brands.created" : "已建立「{name}」" ,
"brands.createFail" : "建立失敗" ,
"brands.saved" : "已儲存" ,
"brands.saveFail" : "儲存失敗" ,
"brands.confirmDelete" : "確定刪除「{name}」?" ,
"brands.deleted" : "已刪除" ,
"brands.deleteFail" : "刪除失敗" ,
"brands.fetchFail" : "抓取失敗" ,
"brands.needLabelContext" : "名稱與介紹為必填" ,
"brands.productUpdated" : "已更新" ,
"brands.productAdded" : "已新增" ,
"brands.confirmDeleteProduct" : "刪除此產品?" ,
"insights.title" : "帳號成效" ,
"insights.account" : "帳號" ,
"insights.noAccount" : "尚無帳號" ,
"insights.syncing" : "同步中…" ,
"insights.syncPosts" : "同步貼文" ,
"insights.myPosts" : "我的貼文" ,
"insights.pickAccount" : "選擇帳號" ,
"insights.goAccounts" : "帳號" ,
"insights.kpiMonth" : "本月指標" ,
"insights.monthViews" : "本月瀏覽" ,
"insights.monthLikes" : "本月讚" ,
"insights.monthReplies" : "本月回覆" ,
"insights.engRate" : "互動率" ,
"insights.vsPrev" : "vs 上月" ,
"insights.avgNear" : "近帖均 {rate}" ,
"insights.trendTitle" : "趨勢與分析 · @{user}" ,
"insights.metricViews" : "瀏覽" ,
"insights.metricLikes" : "讚" ,
"insights.metricReplies" : "回覆" ,
"insights.metricPosts" : "貼文" ,
"insights.metricPostsFull" : "貼文數" ,
"insights.chartMetrics" : "圖表指標" ,
"insights.barsAria" : "近月{metric},點柱查看該月分析" ,
"insights.barsLabel" : "{metric} · 近 {n} 個月" ,
"insights.clickBar" : " · 點柱看分析" ,
"insights.pickMonthAria" : "選擇月份" ,
"insights.barTitle" : "{label}: {value}{est} · 點看分析" ,
"insights.est" : "(估)" ,
"insights.monthSuffix" : "{m}月" ,
"insights.sparkAria" : "趨勢折線,點節點可選月" ,
"insights.analysisOf" : "{label} 分析" ,
"insights.producedAt" : "產出於 {time}" ,
"insights.hasEstimate" : " · 含估測數據" ,
"insights.viewsVsPrev" : " · 瀏覽 vs 前月 {delta}" ,
"insights.statPosts" : "貼文" ,
"insights.statViews" : "瀏覽" ,
"insights.statLikes" : "讚" ,
"insights.statReplies" : "回" ,
"insights.conclusions" : "結論" ,
"insights.recommendations" : "建議" ,
"insights.highlights" : "當月亮點" ,
"insights.findTopics" : "找話題" ,
"insights.goScout" : "去探查" ,
"insights.selectMonth" : "選擇月份" ,
"insights.topPosts" : "表現較佳貼文" ,
"insights.noPosts" : "尚無貼文" ,
"insights.postStats" : "瀏覽 {views} · 讚 {likes} · 回 {replies}" ,
"insights.openThreads" : "開啟 Threads" ,
"insights.zeroPct" : "0%" ,
"plays.tabOwn" : "我的貼文" ,
"plays.tabLink" : "Threads 連結" ,
"plays.noPosts" : "尚無貼文" ,
"plays.targetPost" : "目標貼文" ,
"plays.likesSuffix" : " (讚{n}) " ,
"plays.linkCard" : "貼 Threads 連結" ,
"plays.postLink" : "貼文連結" ,
"plays.resolving" : "解析中…" ,
"plays.resolve" : "解析連結" ,
"plays.resolveHint" : "解析後可排自家帳號在該則下面回覆。" ,
"plays.targetOwn" : "目標貼文(自己的)" ,
"plays.openThreads" : "開 Threads" ,
"plays.external" : "外站貼" ,
"plays.addScheme" : "新增方案" ,
"plays.schemeCount" : "此目標目前 {n} 個方案" ,
"plays.noSchemes" : "尚無方案" ,
"plays.replyCount" : "{n} 則留言" ,
"plays.editTitle" : "編輯:{title}" ,
"plays.schemeName" : "方案名稱" ,
"plays.schemeNamePh" : "例如:方案 A · 溫和接話" ,
"plays.speakersOwn" : "可出場帳號(貼主帳固定可回)" ,
"plays.speakers" : "可出場帳號" ,
"plays.postOwner" : "(貼文主帳)" ,
"plays.noAccounts" : "沒有可用帳號,請先到設定連線 Threads。" ,
"plays.interval" : "間隔(分)" ,
"plays.applyInterval" : "套用間隔" ,
"plays.aiEmpty" : "空白則 AI" ,
"plays.aiBusy" : "產文中…" ,
"plays.replies" : "留言({n}) " ,
"plays.stepN" : "第 {n} 則" ,
"plays.who" : "誰留" ,
"plays.personaOpt" : "人設(選填)" ,
"plays.brandOpt" : "品牌(選填)" ,
"plays.reply" : "留言" ,
"plays.attach" : "附圖" ,
"plays.addOne" : "加一則" ,
"plays.saving" : "儲存中…" ,
"plays.saveScheme" : "儲存方案" ,
"plays.submitting" : "送出中…" ,
"plays.submitOutbox" : "送出到 Outbox" ,
"plays.closeEdit" : "關閉編輯" ,
"plays.noTarget" : "還沒有目標貼文" ,
"plays.resolved" : "已解析連結" ,
"plays.resolveFail" : "解析失敗" ,
"plays.filled" : "已產 {n} 則" ,
"plays.needTarget" : "請先選定目標貼文" ,
"plays.saved" : "方案已儲存" ,
"plays.saveFail" : "儲存失敗" ,
"plays.submitted" : "已送進 Outbox" ,
"plays.submitFail" : "送出失敗" ,
"plays.confirmDelete" : "刪除此方案?" ,
"plays.accountFallback" : "帳號" ,
"inspire.loading" : "載入中…" ,
"inspire.trendsAria" : "最近 Threads 夯什麼" ,
"inspire.trendsLabel" : "最近 Threads 夯" ,
"inspire.refresh" : "刷新" ,
"inspire.clearChat" : "清空對話" ,
"inspire.pinAsElement" : "套用為元素" ,
"inspire.you" : "你" ,
"inspire.ai" : "AI" ,
"inspire.system" : "系統" ,
"inspire.useDraft" : "用這則寫" ,
"inspire.openPlay" : "開串場" ,
"inspire.generating" : "產文中…" ,
"inspire.thinking" : "思考中…" ,
"inspire.pinnedAria" : "本輪已套用" ,
"inspire.pinned" : "已套用" ,
"inspire.pickRight" : "右側點選元素" ,
"inspire.unpinTitle" : "點擊取消套用" ,
"inspire.inputAria" : "跟 AI 說" ,
"inspire.inputPh" : "想寫什麼?或改短一點、更口語…" ,
"inspire.send" : "送出" ,
"inspire.generate" : "產文" ,
"inspire.library" : "元素庫" ,
"inspire.addNew" : "+ 新增" ,
"inspire.kind" : "類型" ,
"inspire.kindRole" : "角色指令" ,
"inspire.kindSnippet" : "片段" ,
"inspire.kindTrendNote" : "熱點備註" ,
"inspire.kindBrand" : "品牌" ,
"inspire.kindTrend" : "熱點" ,
"inspire.name" : "名稱" ,
"inspire.namePh" : "例如:專業 Threads 寫手" ,
"inspire.body" : "內容(會進 prompt) " ,
"inspire.bodyPh" : "你是一位…" ,
"inspire.saveElement" : "存進元素庫" ,
"inspire.citeBrand" : "引用品牌" ,
"inspire.applied" : "已套用" ,
"inspire.clickApply" : "點擊套用" ,
"inspire.noBrands" : "尚無品牌" ,
"inspire.appliedToggle" : "已套用 · 再點取消" ,
"inspire.deleteAria" : "刪除" ,
"inspire.needInput" : "先輸入一句,或直接產文" ,
"inspire.fail" : "失敗" ,
"inspire.wantWrite" : "想寫關於 {label}: {summary}" ,
"inspire.trendBody" : "主題:{label}。{summary}" ,
"inspire.pinnedTrend" : "已套用熱點 {label}" ,
"inspire.needTitleBody" : "請填名稱與內容" ,
"inspire.added" : "已加入元素庫" ,
"inspire.addFail" : "新增失敗" ,
"inspire.confirmRemove" : "從元素庫移除此項?" ,
"inspire.confirmClear" : "清空對話?(元素庫保留)" ,
"inspire.genMessage" : "請依已套用元素寫一則 Threads" ,
"persona.add" : "新增人設" ,
"persona.empty" : "尚無人設" ,
"persona.emptyDesc" : "新增後做分析即可用於產文。" ,
"persona.statusReady" : "ready" ,
"persona.statusAnalyzing" : "分析中" ,
"persona.statusPending" : "待分析" ,
"persona.default" : "預設" ,
"persona.backList" : "← 人設列表" ,
"persona.tabOverview" : "概要" ,
"persona.tabAnalyze" : "分析" ,
"persona.tabFingerprint" : "指紋" ,
"persona.tabPreview" : "試產" ,
"persona.name" : "名稱" ,
"persona.brief" : "定位 brief" ,
"persona.briefPh" : "是誰、對誰說、核心訊息…" ,
"persona.avoid" : "護欄 · 禁止詞(逗號分隔)" ,
"persona.guardChars" : "{n} 字" ,
"persona.banAi" : " · 禁 AI 腔" ,
"persona.notReadySuffix" : " · 未就緒" ,
"persona.setDefault" : "設為預設" ,
"persona.modeAccount" : "公開帳號" ,
"persona.modeText" : "貼文字" ,
"persona.username" : "Threads username" ,
"persona.fromBound" : "從已綁帳號帶入" ,
"persona.select" : "選擇…" ,
"persona.crawlAnalyze" : "爬公開貼文並分析" ,
"persona.crawlBusy" : "爬取/分析中…" ,
"persona.refText" : "參考文字(--- 分隔多篇)" ,
"persona.refTextPh" : "第一段…\n\n---\n\n第二段…" ,
"persona.sourceLabel" : "來源說明(選填)" ,
"persona.sourcePh" : "自己的舊文" ,
"persona.analyzeText" : "從文字分析" ,
"persona.analyzeBusy" : "分析中…" ,
"persona.sampleMeta" : "樣本 {n}" ,
"persona.sourceManual" : "貼文" ,
"persona.analyzeHint" : "完成分析後會顯示 8D 摘要。" ,
"persona.fingerprintHint" : "產文主體。可改口頭禪、節奏、禁忌;儲存後 Studio/ 回覆會吃這份。" ,
"persona.fingerprint" : "語言指紋" ,
"persona.fingerprintPh" : "分析後自動填入…" ,
"persona.saveFingerprint" : "儲存指紋" ,
"persona.tryGen" : "試產主貼 + 回覆" ,
"persona.notReadyMsg" : "人設未就緒" ,
"persona.rootPost" : "主貼" ,
"persona.reply" : "回覆" ,
"persona.hidePrompt" : "隱藏 prompt block" ,
"persona.showPrompt" : "顯示注入的 prompt" ,
"persona.promptBlock" : "prompt block( post) " ,
"persona.pickOne" : "選一個人設" ,
"persona.pickDesc" : "或按新增開始分析。" ,
"persona.created" : "已建立,請到「分析」完成帳號爬取或貼文字" ,
"persona.saved" : "已儲存" ,
"persona.textDone" : "文字分析完成 · {n} 段 → ready" ,
"persona.analyzeFail" : "分析失敗" ,
"persona.reading" : "正在讀取公開貼文…" ,
"persona.accountDone" : "@{user} · {n} 則 → ready" ,
"persona.setDefaultMsg" : "「{name}」已設為預設" ,
"persona.confirmDelete" : "確定刪除人設「{name}」?" ,
"persona.deleted" : "人設已刪除" ,
"persona.needReady" : "請先完成分析( ready) " ,
"persona.dim.d1Tone" : "D1 語氣人格" ,
"persona.dim.d2Structure" : "D2 結構模板" ,
"persona.dim.d3Interaction" : "D3 互動方式" ,
"persona.dim.d4Topics" : "D4 主題分布" ,
"persona.dim.d5Rhythm" : "D5 發文節奏" ,
"persona.dim.d6Visual" : "D6 視覺語法" ,
"persona.dim.d7Conversion" : "D7 轉換方式" ,
"persona.dim.d8Risk" : "D8 風險紅線" ,
"admin.users.loadFail" : "載入失敗" ,
"admin.users.created" : "已新增島民「{name}」· 請複製下方密碼" ,
"admin.users.createFail" : "新增失敗" ,
"admin.users.unlimitedOn" : "「{name}」已設不擋額度(用量仍計算)" ,
"admin.users.unlimitedOff" : "「{name}」已改回依方案擋額度" ,
"admin.users.updateFail" : "更新失敗" ,
"admin.users.planSet" : "「{name}」方案 → {plan}" ,
"admin.users.confirmSuspend" : "確定停權「{name}」?\\n停權後無法登入。" ,
"admin.users.confirmUnsuspend" : "確定復權「{name}」?\\n復權後可重新登入。" ,
"admin.users.didSuspend" : "已停權「{name}」" ,
"admin.users.didUnsuspend" : "已復權「{name}」" ,
"admin.users.suspendFail" : "停權失敗" ,
"admin.users.unsuspendFail" : "復權失敗" ,
"admin.users.markedVerified" : "已將 {name} 標為信箱已驗證" ,
"admin.users.markedUnverified" : "已將 {name} 標為未驗證" ,
"admin.users.rolesUpdated" : "已更新 {name} 的權限:{roles}" ,
"admin.users.rolesFail" : "權限更新失敗" ,
"admin.users.confirmReset" : "確定幫「{name}」重設密碼?\\n臨時密碼會固定顯示直到你按關閉( 可重整) 。" ,
"admin.users.resetDone" : "已重設 {name} 的密碼(下方可持續顯示,請複製後再關閉)" ,
"admin.users.resetFail" : "重設失敗" ,
"admin.users.copied" : "已複製到剪貼簿" ,
"admin.users.copyFail" : "複製失敗,請手動選取密碼" ,
"admin.users.confirmDismissTemp" : "關閉後此頁將不再顯示這組臨時密碼(若尚未複製請先複製)。確定關閉?" ,
"admin.users.tempPwNew" : "新島民臨時密碼" ,
"admin.users.tempPw" : "臨時密碼" ,
"admin.users.tempPwPersist" : "(持續顯示 · 可重整)" ,
"admin.users.copyPw" : "複製密碼" ,
"admin.users.close" : "關閉" ,
"admin.users.createTitle" : "新增島民" ,
"admin.users.memberName" : "島民名稱" ,
"admin.users.displayNamePh" : "顯示名稱" ,
"admin.users.email" : "Email" ,
"admin.users.initPassword" : "初始密碼(選填)" ,
2026-07-10 12:54:45 +00:00
"admin.users.initPasswordPh" : "空白則自動產生;若填寫須符合密碼政策" ,
2026-07-10 05:10:31 +00:00
"admin.users.markVerifiedCheck" : "信箱標為已驗證(可直接使用)" ,
"admin.users.alsoAdmin" : "同時設為管理員" ,
"admin.users.creating" : "建立中…" ,
"admin.users.createSubmit" : "建立島民" ,
"admin.users.clear" : "清除" ,
"admin.users.searchActive" : "搜尋「{query}」· 可匹配名稱、Email、uid" ,
"admin.users.noMatch" : "無符合" ,
"admin.users.none" : "尚無島民" ,
"admin.users.you" : "這是你" ,
"admin.users.status" : "狀態" ,
"admin.users.role" : "角色" ,
"admin.users.emailVerify" : "信箱驗證" ,
"admin.users.bio" : "簡介" ,
"admin.users.timezone" : "時區" ,
"admin.users.notifyEmail" : "Email 通知" ,
"admin.users.on" : "開" ,
"admin.users.off" : "關" ,
"admin.users.createdAt" : "建立" ,
"admin.users.updatedAt" : "更新" ,
"admin.users.accountStatus" : "帳號狀態" ,
"admin.users.updating" : "更新中…" ,
"admin.users.usageTitle" : "用量與方案" ,
2026-07-10 12:54:45 +00:00
"admin.users.usageLiveSkip" : "方案/額度屬 Usage 域, live 後端尚未接上( M3) ; 此區僅 mock 可改。" ,
2026-07-10 05:10:31 +00:00
"admin.users.plan" : "方案" ,
"admin.users.planOption" : "{name}( {credits} 點/月)" ,
"admin.users.unlimited" : "不擋額度" ,
"admin.users.byPlan" : "依方案" ,
"admin.users.setUnlimited" : "設為不擋額度" ,
"admin.users.setLimited" : "改回擋額度" ,
"admin.users.unlimitedHint" : "不擋額度: 達方案上限仍可繼續用; AI/ Search 次數與點數照樣計算。" ,
"admin.users.loadingUsage" : "載入用量設定…" ,
"admin.users.assignRoles" : "指派權限" ,
"admin.users.memberBase" : "{role}(基底,不可關閉)" ,
"admin.users.adminDesc" : "{role} — 可管理島民與系統" ,
"admin.users.saving" : "儲存中…" ,
"admin.users.saveRoles" : "儲存權限" ,
"admin.users.markUnverifiedBtn" : "標為未驗證" ,
"admin.users.markVerifiedBtn" : "標為已驗證" ,
"admin.users.resetting" : "重設中…" ,
"admin.users.resetTemp" : "重設密碼(產生臨時)" ,
"admin.users.customPw" : "或指定新密碼(選填)" ,
2026-07-10 12:54:45 +00:00
"admin.users.customPwPh" : "密碼須至少 12 碼,且含大寫、小寫、數字與符號" ,
2026-07-10 05:10:31 +00:00
"admin.users.resetWithCustom" : "用指定密碼重設" ,
"usage.tabMine" : "我的用量" ,
"usage.tabTenant" : "全體用量" ,
"usage.currentPlan" : "目前方案" ,
"usage.planMeta" : "/月 · 每月 {n} 點額度" ,
"usage.changePlan" : "變更方案" ,
"usage.usedThisMonth" : "本月已用" ,
"usage.remainLabel" : "剩餘" ,
"usage.ledgerToggle" : "使用紀錄" ,
"usage.collapse" : "收合" ,
"usage.eventsCount" : "{n} 筆" ,
"usage.granularity" : "粒度" ,
"usage.day" : "日" ,
"usage.monthUnit" : "月" ,
"usage.year" : "年" ,
"usage.from" : "起" ,
"usage.to" : "迄" ,
"usage.callCounts" : "呼叫次數" ,
"usage.noMembers" : "尚無會員" ,
"usage.planAria" : "{name} 方案" ,
"usage.unlimitedTitle" : "不擋額度" ,
"usage.setLimited" : "改回擋額度" ,
"usage.setUnlimited" : "設為不擋額度" ,
"usage.limitShort" : "擋" ,
"usage.subscribed" : "已訂閱 {name}" ,
"usage.unlimitedSet" : "已設不擋額度" ,
"usage.limitedSet" : "已改回擋額度" ,
"usage.planUpdated" : "已更新方案 {name}" ,
"usage.fail" : "失敗" ,
"currency.TWD" : "新台幣 (TWD)" ,
"currency.USD" : "美元 (USD)" ,
"currency.JPY" : "日圓 (JPY)" ,
"currency.EUR" : "歐元 (EUR)" ,
"currency.HKD" : "港幣 (HKD)" ,
"locale.zh-TW" : "繁體中文" ,
"locale.en" : "English" ,
"pager.nav" : "分頁" ,
"pager.pageSize" : "每頁筆數" ,
"pager.perPage" : "{n}/頁" ,
"pager.prev" : "上一頁" ,
"pager.next" : "下一頁" ,
"plays.defaultTitle" : "新方案" ,
"plays.topicOnPost" : "掛在:{snippet}" ,
"plays.topicOnExternal" : "掛在:{label} · {snippet}" ,
"plays.externalFallback" : "外站貼" ,
"persona.newName" : "新人設" ,
"persona.previewTopic" : "週末想找能坐久的咖啡店" ,
"persona.previewReplySample" : "大安那間還行但人很多" ,
"inspire.playTitle" : "靈感串場" ,
"wizard.topic.fallbackTopic" : "生活小題" ,
"play.err.needLead" : "請選擇主帳號" ,
"play.err.needRoot" : "請至少有一則主貼" ,
"play.err.firstMustRoot" : "第一則必須是主貼" ,
"play.err.rootMustLead" : "主貼必須使用主帳" ,
"play.err.rootEmpty" : "主貼文案不可空白" ,
"play.err.replyAccount" : "回覆只能用主帳或已選配角" ,
"play.err.replyEmpty" : "回覆文案不可空白" ,
"play.err.needTarget" : "請選擇自己的貼文,或貼上 Threads 連結" ,
"play.err.needReplies" : "請至少排 1 則留言" ,
"play.err.needReplyAccounts" : "請至少選一個可回覆帳號" ,
"play.err.stepAccount" : "每則留言都要指定可用帳號" ,
"play.err.stepEmpty" : "留言內容不可空白" ,
"play.err.notFound" : "找不到互回方案" ,
"time.justNow" : "剛剛" ,
"time.minAgo" : "{n} 分前" ,
"time.hourAgo" : "{n} 小時前" ,
"time.dayAgo" : "{n} 天前" ,
"time.min" : "{n} 分鐘" ,
"time.hour" : "{n} 小時" ,
"time.day" : "{n} 天" ,
"time.expired" : "已過期 {span}" ,
"time.remaining" : "剩餘 {span}" ,
"time.sessionUnknown" : "Session 未記錄" ,
"time.sessionExpired" : "Session 已過期 · {absolute}" ,
"time.sessionSoon" : "Session 即將到期 · {relative}( {absolute}) " ,
"time.sessionOk" : "Session 有效 · {relative}( {absolute}) " ,
} ;
export const en : MessageDict = {
"app.name" : "Lapras" ,
"app.nameEn" : "Lapras" ,
"app.nameZh" : "巡樓" ,
"app.tagline" : "Patrol Threads with ease" ,
"app.taglineEn" : "Patrol Threads with ease" ,
"nav.today" : "Today" ,
"nav.crew" : "Accounts" ,
"nav.studio" : "Studio" ,
"nav.scout" : "Patrol" ,
"nav.outbox" : "Outbox" ,
"nav.jobs" : "Jobs" ,
"nav.brands" : "Brands" ,
"nav.more" : "More" ,
"nav.moreTitle" : "More" ,
"nav.users" : "Islanders" ,
"nav.usage" : "Usage & plans" ,
"nav.profile" : "Profile" ,
2026-07-10 12:54:45 +00:00
"nav.invite" : "Invites" ,
2026-07-10 05:10:31 +00:00
"nav.settings" : "Settings" ,
"nav.logout" : "Log out" ,
"nav.navigate" : "Navigate" ,
"common.save" : "Save" ,
"common.cancel" : "Cancel" ,
"common.loading" : "Loading…" ,
"common.back" : "Back" ,
"common.delete" : "Delete" ,
"common.edit" : "Edit" ,
"common.search" : "Search" ,
"common.confirm" : "Confirm" ,
"common.optional" : "Optional" ,
"common.success" : "Saved" ,
"common.error" : "Something went wrong" ,
"common.yes" : "Yes" ,
"common.no" : "No" ,
2026-07-10 12:54:45 +00:00
"api.err.unknown" : "Something went wrong. Please try again." ,
"api.err.network" : "Cannot reach the server. Check your network or if the API is running." ,
"api.err.400001" : "Invalid request" ,
// Same sentence as backend 400003 / ValidatePasswordPolicy
"api.err.400003" : "Password must be at least 12 characters with upper, lower, digit, and symbol" ,
"password.policy.hint" : "Password must be at least 12 characters with upper, lower, digit, and symbol" ,
"password.policy.minLen" : "Password must be at least 12 characters with upper, lower, digit, and symbol" ,
"password.policy.needUpper" : "Password must be at least 12 characters with upper, lower, digit, and symbol" ,
"password.policy.needLower" : "Password must be at least 12 characters with upper, lower, digit, and symbol" ,
"password.policy.needDigit" : "Password must be at least 12 characters with upper, lower, digit, and symbol" ,
"password.policy.needSymbol" : "Password must be at least 12 characters with upper, lower, digit, and symbol" ,
"api.err.400004" : "Invalid or expired verification code" ,
"api.err.400020" : "You cannot suspend your own account" ,
"api.err.400021" : "Cannot demote or suspend the last active admin" ,
"api.err.401001" : "Please sign in" ,
"api.err.401002" : "Session expired. Please sign in again." ,
"api.err.401003" : "Account not found. Please sign in again." ,
"api.err.401010" : "Invalid email or password" ,
"api.err.403001" : "Account suspended" ,
"api.err.403002" : "Admin access required" ,
"api.err.404001" : "Not found" ,
"api.err.404002" : "This email is not registered" ,
"api.err.409001" : "This email is already registered" ,
"api.err.500000" : "Server error. Please try again later." ,
"api.err.501000" : "This feature is not implemented yet" ,
"api.ok.verifySent" : "Verification code sent. Please check your email." ,
"api.ok.verifyIssued" : "Verification code issued" ,
"api.ok.resetSent" : "Reset email sent. Please check your inbox." ,
"api.ok.passwordUpdated" : "Password updated" ,
"api.ok.loggedOut" : "Signed out" ,
"api.ok.unbound" : "Unbound" ,
2026-07-10 05:10:31 +00:00
"topbar.notifications" : "Notifications" ,
"topbar.unread" : "{n} unread" ,
"topbar.markAllRead" : "Mark all read" ,
"topbar.noNotifications" : "No notifications" ,
"topbar.jobsCenter" : "Job center" ,
"topbar.moreOlder" : "{n} older" ,
"topbar.account" : "Account menu" ,
"role.admin" : "Admin" ,
"role.member" : "Member" ,
"role.verified" : "Verified" ,
"role.unverified" : "Unverified" ,
"login.title" : "Sign in to Lapras" ,
"login.email" : "Email" ,
"login.password" : "Password" ,
"login.submit" : "Sign in" ,
"login.submitting" : "Signing in…" ,
"login.forgot" : "Forgot password?" ,
"login.mockHint" : "Admin demo@harbor.local / demo · member alice@harbor.local / alice" ,
2026-07-10 12:54:45 +00:00
"login.liveHint" : "Live backend: admin@haixun.local / admin123 (gateway :8888)" ,
2026-07-10 05:10:31 +00:00
"forgot.title" : "Forgot password" ,
"forgot.submit" : "Send reset link" ,
"forgot.submitting" : "Sending…" ,
"forgot.back" : "Back to sign in" ,
2026-07-10 12:54:45 +00:00
"forgot.hint" : "Enter your registered email. We'll send a reset link and code." ,
2026-07-10 05:10:31 +00:00
"forgot.mockMail" : "Reset email" ,
2026-07-10 12:54:45 +00:00
"forgot.openReset" : "Enter code / reset password" ,
2026-07-10 05:10:31 +00:00
"forgot.retry" : "Try again" ,
2026-07-10 12:54:45 +00:00
"forgot.nextStep" : "Check your email for the code or link, then open the reset page to set a new password." ,
2026-07-10 05:10:31 +00:00
"reset.title" : "Set new password" ,
2026-07-10 12:54:45 +00:00
"reset.hint" : "Enter email, verification code (from the email), and a new password." ,
"reset.code" : "Verification code" ,
"reset.codePh" : "6-digit code from email" ,
"reset.needEmail" : "Email is required" ,
"reset.needCode" : "Verification code is required" ,
2026-07-10 05:10:31 +00:00
"reset.newPassword" : "New password" ,
"reset.confirm" : "Confirm password" ,
"reset.submit" : "Update password" ,
"reset.submitting" : "Updating…" ,
"reset.missingToken" : "Missing token. Please request a new reset link." ,
"verify.title" : "Verify email" ,
"verify.pending" : "Not verified" ,
"verify.body" : "You're signed in, but features stay locked until you verify your email with the 6-digit code." ,
"verify.code" : "Verification code" ,
"verify.submit" : "Verify" ,
"verify.submitting" : "Verifying…" ,
"verify.resend" : "Resend code" ,
"verify.sending" : "Sending…" ,
"verify.logout" : "Log out" ,
"verify.mockMail" : "Verification email" ,
"verify.mockHint" : "Enter the code:" ,
"verify.after" : "After verification you can use Today, Studio, Patrol, and more." ,
"settings.title" : "Settings" ,
"settings.localeCurrency" : "Language & currency" ,
"settings.locale" : "Interface language" ,
"settings.currency" : "Display currency" ,
"settings.currencyHint" : "" ,
"settings.localeSaved" : "Language and currency updated" ,
"settings.appearance" : "Appearance" ,
"settings.theme" : "Theme" ,
"settings.themeLight" : "Light" ,
"settings.themeDark" : "Dark" ,
"settings.themeSystem" : "System" ,
"settings.themeHint" : "" ,
"settings.themeSaved" : "Theme updated" ,
"settings.themeToLight" : "Switch to light" ,
"settings.themeToDark" : "Switch to dark" ,
"settings.dataSource" : "Data source" ,
2026-07-10 12:54:45 +00:00
"settings.dataSourceHint" :
"mock = in-browser fake data; live = apps/backend gateway. Re-login after switching to live." ,
"settings.dataSourceMock" : "Mock (local)" ,
"settings.dataSourceLive" : "Live (backend API)" ,
"settings.dataSourceCurrent" : "Current" ,
"settings.dataSourceSwitchedLive" :
"Switched to Live — re-login with backend account (admin@haixun.local / admin123)" ,
"settings.dataSourceSwitchedMock" : "Switched back to Mock" ,
"settings.dataSourceLiveNeedGateway" : "Requires gateway on :8888 (or Vite proxy /api)" ,
2026-07-10 05:10:31 +00:00
"settings.ai" : "AI" ,
"settings.search" : "Search" ,
"settings.member" : "Account & sign-in" ,
"settings.usageCard" : "AI / search quota" ,
"settings.usageCardHint" : "" ,
"settings.viewUsage" : "View usage" ,
"settings.editProfile" : "Edit profile" ,
"settings.mockLogin" : "demo@harbor.local / demo" ,
"settings.memberHint" : "" ,
"usage.title" : "Usage & plans" ,
"usage.desc" : "" ,
"usage.creditsUsed" : "Credits used this month" ,
"usage.remaining" : "{n} left" ,
"usage.percentUsed" : "{n}% used" ,
"usage.breakdown" : "Breakdown" ,
"usage.plans" : "Plans" ,
"usage.current" : "Current" ,
"usage.inUse" : "Active" ,
"usage.switchMock" : "Switch plan" ,
"usage.perMonth" : "credits / mo" ,
"usage.ledger" : "Recent usage" ,
"usage.emptyTitle" : "No usage this month" ,
"usage.emptyDesc" : "" ,
"usage.planNote" : "" ,
"usage.switched" : "Switched to {name}" ,
"usage.meter.times" : "{count} runs · {credits} credits" ,
"usage.meter.cap" : "Soft cap {count}/{cap} runs" ,
"usage.plan.free.blurb" : "Trial and light personal use" ,
"usage.plan.starter.blurb" : "Small teams posting and patrolling daily" ,
"usage.plan.pro.blurb" : "Multi-account, heavy AI and research" ,
"profile.title" : "Profile" ,
"profile.desc" : "" ,
"profile.accountStatus" : "Account status" ,
"profile.basic" : "Basics" ,
"profile.avatar" : "Avatar" ,
"profile.avatarUpload" : "Upload avatar" ,
"profile.avatarRemove" : "Remove avatar" ,
2026-07-10 12:54:45 +00:00
"profile.avatarHint" : "JPG / PNG / WebP, up to 5MB. Pick a file then Save basic info; Remove clears immediately." ,
2026-07-10 05:10:31 +00:00
"profile.avatarSaved" : "Avatar updated" ,
"profile.avatarCleared" : "Avatar removed" ,
"profile.avatarFail" : "Could not read image" ,
"profile.displayName" : "Display name" ,
"profile.bio" : "Bio (optional)" ,
"profile.timezone" : "Timezone" ,
"profile.notifyEmail" : "Email notifications" ,
"profile.password" : "Change password (optional)" ,
"profile.currentPassword" : "Current password" ,
"profile.newPassword" : "New password" ,
"profile.confirmPassword" : "Confirm new password" ,
"profile.emailVerified" : "Email verified" ,
"profile.emailUnverified" : "Email not verified" ,
"profile.roleAdmin" : "Admin" ,
"profile.roleMember" : "Member" ,
"profile.loginEmail" : "Sign-in email: {email}" ,
"profile.verifiedAt" : " · verified {time}" ,
"profile.goVerify" : "Verify email" ,
"profile.roleTags" : "Role tags: {labels}" ,
"profile.roleNote" : "Roles are assigned by the system; re-verify after changing email." ,
"profile.saveBasic" : "Save profile" ,
"profile.updatePassword" : "Update password" ,
"profile.saved" : "Profile saved" ,
"profile.savedUnverified" : "Saved. Verify your email before using features." ,
"profile.saveFail" : "Could not save" ,
"profile.needNewPassword" : "Enter a new password" ,
"profile.passwordMismatch" : "New passwords do not match" ,
"profile.needCurrentPassword" : "Enter your current password" ,
2026-07-10 12:54:45 +00:00
"profile.wrongCurrentPassword" : "Current password is incorrect" ,
2026-07-10 05:10:31 +00:00
"profile.passwordUpdated" : "Password updated" ,
"profile.passwordFail" : "Could not change password" ,
"profile.listJoin" : ", " ,
"profile.tenantUid" : " · tenant {tenant} · uid {uid}" ,
2026-07-10 12:54:45 +00:00
"profile.inviteBadge" : "Invite code" ,
"profile.inviteHint" : "Share with friends to join; later events can use invite relations." ,
"profile.gotoInvite" : "View invites" ,
"invite.title" : "Invites" ,
"invite.desc" : "Invite codes and relations; admin view is a tree." ,
"invite.tabs" : "Invite views" ,
"invite.tab.mine" : "My invites" ,
"invite.tab.tree" : "Tree" ,
"invite.myCode" : "My invite code" ,
"invite.codeLabel" : "Invite code" ,
"invite.copyCode" : "Copy" ,
"invite.copied" : "Copied" ,
"invite.copyFail" : "Copy failed" ,
"invite.stats" : "{direct} direct · {total} in chain" ,
"invite.upline" : "Invited by" ,
"invite.downlines" : "Direct invites · {n}" ,
"invite.noUpline" : "No inviter" ,
"invite.noDownline" : "None yet" ,
"invite.directN" : "{n} direct" ,
"invite.claimHint" : "If you didn’ t enter a code at signup, add your inviter’ s code here (cannot change later)." ,
"invite.claimLabel" : "Invite code" ,
"invite.claimPh" : "e.g. HX-DEMO01" ,
"invite.claimSubmit" : "Bind" ,
"invite.claimOk" : "Bound to {name}" ,
"invite.claimOkGeneric" : "Inviter bound" ,
"invite.claimFail" : "Could not bind" ,
"invite.claimLocked" : "Already bound. Contact an admin to change." ,
"invite.loadFail" : "Failed to load" ,
"invite.treeEmpty" : "No data" ,
"invite.treeSearch" : "Search" ,
"invite.treeSearchPh" : "Name / email / code" ,
"invite.treeCount" : "{n} people" ,
"invite.treeMatchCount" : "{n} matches · {total} total" ,
"invite.treeNoMatch" : "No matches" ,
"invite.treeNoMatchHint" : "Try another keyword" ,
"invite.clearSearch" : "Clear" ,
"invite.moveTitle" : "Reassign" ,
"invite.newParent" : "Inviter" ,
"invite.root" : "(None · standalone)" ,
"invite.confirmMove" : "Confirm" ,
"invite.moved" : "Reassigned “{name}” → “{parent}”" ,
"invite.moveFail" : "Failed" ,
"invite.openFromAdmin" : "Invites" ,
"invite.parentField" : "Invited by" ,
"invite.orgPickRoot" : "Pick a starting root (includes self-joined)" ,
"invite.orgRoots" : "Roots" ,
"invite.orgPath" : "Path" ,
"invite.orgChainN" : "{n} in chain" ,
"invite.orgFocusStats" : "{direct} direct · {total} in chain" ,
"invite.orgDirects" : "Direct invites · {n}" ,
"invite.orgNoDirects" : "No direct invites" ,
"invite.err.notFound" : "Member not found" ,
"invite.err.notLoggedIn" : "Not signed in" ,
"invite.err.needAdmin" : "Admin access required" ,
"invite.err.memberNotFound" : "Islander not found" ,
"invite.err.selfParent" : "Cannot set yourself as inviter" ,
"invite.err.parentNotFound" : "Inviter not found" ,
"invite.err.cycle" : "Cannot place under your own invite chain (would create a cycle)" ,
"invite.err.repoMissing" : "Invite data layer not loaded — please refresh the page" ,
"invite.err.alreadyBound" : "You already have an inviter" ,
"invite.err.codeRequired" : "Enter an invite code" ,
"invite.err.codeNotFound" : "Invite code not found" ,
"invite.err.codeSelf" : "You can’ t use your own code" ,
2026-07-10 05:10:31 +00:00
"admin.users.title" : "Islanders" ,
"admin.users.desc" : "" ,
"admin.users.needAdmin" : "Admin access required" ,
"admin.users.list" : "Islanders · {n}" ,
"admin.users.detail" : "Islander detail" ,
"admin.users.pick" : "Select an islander" ,
"admin.users.search" : "Search name / uid" ,
"admin.users.searchPh" : "Name, email, or uid" ,
"admin.users.create" : "Add islander" ,
"admin.users.suspend" : "Suspend" ,
"admin.users.unsuspend" : "Restore" ,
"admin.users.suspended" : "Suspended" ,
"admin.users.active" : "Active" ,
"crew.title" : "Accounts" ,
"crew.tab.accounts" : "Accounts" ,
"crew.tab.personas" : "Personas" ,
"crew.connect" : "Connect account" ,
"crew.connecting" : "Adding…" ,
"crew.refreshAll" : "Refresh all sessions" ,
"crew.refreshing" : "Refreshing…" ,
"crew.empty" : "No accounts yet" ,
"crew.unusable" : "Unavailable" ,
"crew.expires" : "Expires {time}" ,
"crew.lastRefresh" : "Last refresh {time}" ,
"crew.refreshSession" : "Refresh session" ,
"crew.session.ok" : "Session valid" ,
"crew.session.soon" : "Expiring soon" ,
"crew.session.expired" : "Session expired" ,
"crew.session.unknown" : "Session unknown" ,
"crew.msg.refreshed" : "@{user} session refreshed (~30 days)" ,
"crew.msg.refreshedAll" : "Refreshed {n} account sessions" ,
"crew.msg.refreshFail" : "Refresh failed" ,
"crew.confirmDelete" : "Delete account @{user}?\nIt can no longer be used as lead / cast." ,
"today.findTopic" : "Find topics" ,
"today.pendingReplies" : "Pending replies" ,
"today.pendingRepliesN" : "Pending · {n}" ,
"today.newThread" : "New thread" ,
"today.metricsAria" : "Today metrics" ,
"today.metric.pending" : "Pending" ,
"today.metric.pendingHint" : "Patrol queue" ,
"today.metric.doneGoal" : "Done / goal" ,
"today.metric.sentToday" : "Sent today" ,
"today.metric.running" : "{n} in progress" ,
"today.metric.sentDone" : "Completed sends" ,
"today.metric.failed" : "Send issues" ,
"today.metric.needAction" : "Needs action" ,
"today.metric.ok" : "All good" ,
"today.pending.title" : "Pending replies · {n}" ,
"today.pending.empty" : "Nothing pending" ,
"today.goScout" : "Go patrol" ,
"today.pending.more" : "{n} more →" ,
"today.pending.handle" : "Handle in patrol" ,
"today.pending.start" : "Start handling" ,
"today.topics.title" : "Find topics" ,
"today.topics.empty" : "No topics yet" ,
"today.goStudio" : "Go to Studio" ,
"today.heat" : "Heat {n}" ,
"today.topicAngle" : "Good opening angle" ,
"today.moreInspire" : "More inspiration" ,
"today.useTopic" : "Start from topic" ,
"today.outbox.title" : "Today's outbox" ,
"today.outbox.empty" : "No sends today. Try" ,
"today.outbox.emptyMid" : ", then check" ,
"today.outbox.emptyEnd" : "." ,
"today.outbox.summary" : "Done {sent} · In progress {running} · Issues {failed}" ,
"today.badge.failed" : "Failed" ,
"today.badge.scheduling" : "Scheduled" ,
"today.badge.sending" : "Sending" ,
"today.openOutbox" : "Open outbox" ,
"today.accounts.title" : "Account performance" ,
"today.accounts.empty" : "No stats yet" ,
"today.postsCount" : "{n} posts" ,
"today.views" : "Views" ,
"today.likes" : "Likes" ,
"today.repliesShort" : "Replies" ,
"today.fullInsights" : "Full insights · MoM charts" ,
"today.viewPosts" : "View posts" ,
"today.manageAccounts" : "Manage accounts" ,
"outbox.title" : "Outbox" ,
"outbox.tabsAria" : "Outbox tabs" ,
"outbox.tab.active" : "Active" ,
"outbox.tab.history" : "History" ,
"outbox.empty" : "No outbox items" ,
"outbox.activeEmpty" : "Nothing in progress" ,
"outbox.historyEmpty" : "No history yet" ,
"outbox.historyN" : "History ({n})" ,
"outbox.backActive" : "Back to active ({n})" ,
"outbox.progress" : "Progress {progress}" ,
"outbox.detail" : "Details" ,
"outbox.deleting" : "Deleting…" ,
"outbox.confirmDelete" : "Delete outbox item “{title}”?\nThis cannot be undone." ,
"outbox.deleted" : "Deleted “{title}”" ,
"outbox.deleteFail" : "Delete failed" ,
"outbox.status.scheduling" : "Scheduling" ,
"outbox.status.active" : "Sending" ,
"outbox.status.completed" : "Completed" ,
"outbox.status.partial_failed" : "Partial failure" ,
"outbox.status.cancelled" : "Cancelled" ,
"outbox.detail.missingId" : "Missing id" ,
"outbox.detail.notFound" : "Outbox item not found" ,
"outbox.detail.markAllOk" : "Mark all success" ,
"outbox.detail.markRootFail" : "Mark root failed" ,
"outbox.detail.processing" : "Working…" ,
"outbox.detail.delete" : "Delete this" ,
"outbox.detail.back" : "Back to list" ,
"outbox.detail.root" : "Root post" ,
"outbox.detail.replyN" : "Reply {n}" ,
"outbox.detail.retry" : "Retry" ,
"outbox.detail.opFail" : "Action failed" ,
"studio.title" : "Studio" ,
"studio.account" : "Account" ,
"studio.persona" : "Persona" ,
"studio.personaReady" : "Persona ready" ,
"studio.personaNotReady" : "Persona not ready" ,
"studio.tab.posts" : "My posts" ,
"studio.tab.mentions" : "Mentions @" ,
"studio.tab.compose" : "Compose" ,
"studio.tab.plays" : "Plays" ,
"studio.tab.inspire" : "Inspire" ,
"studio.tab.insights" : "Insights" ,
"mentions.hint" : "Who @ you. {n} pending. You can change account/persona per item (defaults from top bar)." ,
"mentions.scoutLink" : "Patrol outreach" ,
"mentions.empty" : "No mentions" ,
"mentions.status.pending" : "Pending" ,
"mentions.status.replied" : "Replied" ,
"mentions.status.skipped" : "Skipped" ,
"mentions.reply" : "Reply" ,
"mentions.skip" : "Skip" ,
"mentions.draftLabel" : "Reply draft" ,
"mentions.repliedPrefix" : "Replied: {text}" ,
"mentions.needPersona" : "Pick a ready persona before AI draft" ,
"mentions.fail" : "Failed" ,
"mentions.marked" : "Marked replied (@{user})" ,
"mentions.withImages" : " · {n} images" ,
"compose.hint" : "Single post (not a play). For multi-account threads use" ,
"compose.hintEnd" : "." ,
"compose.playsLink" : "Plays" ,
"compose.personaOff" : "Persona not ready: AI tools (mimic / analyze) disabled." ,
"compose.title" : "Title (optional)" ,
"compose.titlePh" : "Helps identify in Outbox" ,
"compose.body" : "Body" ,
"compose.bodyPh" : "Write your post…" ,
"compose.tool.mimic" : "Mimic" ,
"compose.tool.viral" : "Viral analysis" ,
"compose.tool.research" : "Research" ,
"compose.tool.image" : "Image" ,
"compose.mimic.title" : "Mimic another post" ,
"compose.mimic.source" : "Source text" ,
"compose.mimic.sourcePh" : "Paste the post to mimic…" ,
"compose.mimic.running" : "Mimicking…" ,
"compose.mimic.run" : "Mimic into body" ,
"compose.mimic.done" : "Mimic done — edit as needed" ,
"compose.viral.title" : "Viral analysis" ,
"compose.viral.hint" : "Hooks, structure, and copyable patterns from source or body." ,
"compose.viral.source" : "Target (empty = use body)" ,
"compose.viral.running" : "Analyzing…" ,
"compose.viral.run" : "Analyze" ,
"compose.viral.result" : "Analysis" ,
"compose.viral.done" : "Viral analysis done" ,
"compose.viral.needText" : "Paste a reference or write the body first" ,
"compose.research.title" : "Research notes" ,
"compose.research.q" : "Keywords" ,
"compose.research.qPh" : "e.g. fragrance-free detergent sensitive skin" ,
"compose.research.running" : "Searching…" ,
"compose.research.insert" : "Insert selected into body" ,
"compose.research.inserted" : "Inserted {n} notes" ,
"compose.image.title" : "Generate image" ,
"compose.image.prompt" : "Scene description" ,
"compose.image.promptPh" : "Empty = summarize from body" ,
"compose.image.running" : "Generating…" ,
"compose.image.run" : "Generate image" ,
"compose.image.done" : "Image added" ,
2026-07-10 12:54:45 +00:00
"compose.scheduleAt" : "Publish at" ,
"compose.scheduleHint" : "Outbox will send at this time. Use “Now” for ASAP." ,
"compose.scheduleNow" : "Now" ,
2026-07-10 05:10:31 +00:00
"compose.publish" : "Send to Outbox" ,
"compose.publishing" : "Sending…" ,
"compose.publishFail" : "Send failed" ,
"compose.fail" : "Failed" ,
"compose.attachN" : "{n} images" ,
"compose.personaStatus" : "Persona: {status}" ,
"compose.ready" : "ready" ,
"compose.notReady" : "not ready" ,
"posts.sync" : "Resync Threads" ,
"posts.syncing" : "Syncing…" ,
"posts.syncedAt" : "Synced {time}" ,
"posts.notSynced" : "Not synced" ,
"posts.syncDone" : "Synced Threads metrics (likes / replies / reposts / quotes / views / shares)" ,
"posts.empty" : "No posts yet" ,
"posts.openThreads" : "Open Threads" ,
"posts.insight" : "Insight: {text}" ,
"posts.review" : "Review: {text}" ,
"posts.formulaResult" : "Structure analysis" ,
"posts.collapseReplies" : "Collapse replies" ,
"posts.repliesBtn" : "Replies ({total}) · pending {pending}" ,
"posts.replyRoot" : "Reply to post" ,
"posts.analyzing" : "Analyzing…" ,
"posts.reanalyze" : "Re-analyze structure" ,
"posts.analyze" : "Analyze structure" ,
"posts.mimicThis" : "Mimic this" ,
"posts.rootDraft" : "Root reply draft" ,
"posts.filter.pending" : "Pending ({n})" ,
"posts.filter.replied" : "Replied ({n})" ,
"posts.filter.all" : "All ({n})" ,
"posts.noPending" : "No pending replies" ,
"posts.noReplied" : "No replied items yet" ,
"posts.noReplies" : "No replies yet" ,
"posts.status.pending" : "Pending" ,
"posts.status.replied" : "Replied" ,
"posts.likesN" : "{n} likes" ,
"posts.childCount" : "{n} child replies" ,
"posts.mine" : "Ours" ,
"posts.replyThis" : "Reply" ,
"posts.replyAgain" : "Reply again" ,
"posts.replyTo" : "Reply to @{user}" ,
"posts.replyAgainTo" : "Reply again to @{user}" ,
"posts.needPersona" : "Pick a ready persona before AI draft" ,
"posts.genFail" : "Generate failed" ,
"posts.needText" : "Generate or type a reply first" ,
"posts.sent" : "Sent as @{user}" ,
"posts.sentImages" : " ({n} images)" ,
"posts.accountFallback" : "account" ,
"posts.sendFail" : "Send failed" ,
"posts.analyzeDone" : "Structure analysis done (manual)" ,
"posts.analyzeFail" : "Analyze failed" ,
"wizard.newTitle" : "New play" ,
"wizard.editTitle" : "Edit play" ,
"wizard.prev" : "Back" ,
"wizard.next" : "Next" ,
"wizard.err.topic" : "Enter a topic" ,
"wizard.err.lead" : "Select a lead account" ,
"wizard.err.leadUnusable" : "Lead account unavailable" ,
"wizard.submitFail" : "Submit failed" ,
"wizard.unnamedPlay" : "Untitled play" ,
"wizard.step.topic" : "Topic" ,
"wizard.step.crew" : "Cast" ,
"wizard.step.script" : "Script" ,
"wizard.step.preview" : "Preview" ,
"wizard.step.schedule" : "Schedule" ,
"wizard.step.submit" : "Submit" ,
"wizard.stepperAria" : "Wizard steps" ,
"wizard.topic.title" : "1. What is this thread about?" ,
"wizard.topic.name" : "Title (optional)" ,
"wizard.topic.namePh" : "e.g. Weekend coffee" ,
"wizard.topic.topic" : "One-line topic" ,
"wizard.topic.topicPh" : "What should this thread discuss?" ,
"wizard.topic.aiView" : "AI persona view" ,
"wizard.topic.personaNotReady" : "Persona not ready" ,
"wizard.topic.generating" : "Generating…" ,
"wizard.topic.aiSuggest" : "AI suggest" ,
"wizard.topic.quickFill" : "Quick fill" ,
"wizard.topic.sampleTitle" : "Weekend coffee chat" ,
"wizard.topic.sampleTopic" : "Looking for a reliable café this weekend — lots of outlets, stay-all-day friendly." ,
"wizard.topic.aiTitle" : "AI topic" ,
"wizard.topic.personaOpen" : "{name} opens" ,
"wizard.crew.title" : "2. Cast" ,
"wizard.crew.lead" : "Lead" ,
"wizard.crew.noUsable" : "No usable accounts" ,
"wizard.crew.unusable" : "Unavailable" ,
"wizard.crew.cast" : "Supporting" ,
"wizard.script.title" : "3. Lines" ,
"wizard.script.persona" : "Persona" ,
"wizard.script.personaNotReady" : "Persona not ready" ,
"wizard.script.root" : "Root post" ,
"wizard.script.replyN" : "Reply {n}" ,
"wizard.script.generating" : "Generating…" ,
"wizard.script.ai" : "AI draft" ,
"wizard.script.account" : "Account: {name}" ,
"wizard.script.noLead" : "(no lead)" ,
"wizard.script.speaker" : "Speaker" ,
"wizard.script.leadTag" : "(lead)" ,
"wizard.script.text" : "Copy" ,
"wizard.script.rootPh" : "Root post text…" ,
"wizard.script.replyPh" : "Reply text…" ,
"wizard.script.addReply" : "Add reply step" ,
"wizard.preview.title" : "4. Preview the thread" ,
"wizard.preview.unknown" : "Unknown" ,
"wizard.preview.unknownAccount" : "Unknown account" ,
"wizard.preview.root" : "Root" ,
"wizard.preview.leadTalk" : "lead reply" ,
"wizard.preview.empty" : "(empty)" ,
"wizard.schedule.title" : "5. When to send" ,
"wizard.schedule.start" : "First post (root) time" ,
"wizard.schedule.interval" : "Reply interval (minutes)" ,
"wizard.schedule.intervalHint" : "Relative to previous step" ,
"wizard.submit.title" : "6. Submit schedule" ,
"wizard.submit.body" : "Confirm to send “{title}” ({n} steps) to Outbox and publish in order." ,
"wizard.submit.unnamed" : "Untitled" ,
"wizard.submit.root" : "Root" ,
"wizard.submit.replyN" : "Reply {n}" ,
"wizard.submit.submitting" : "Submitting…" ,
"wizard.submit.run" : "Submit to Outbox" ,
"reply.account" : "Reply as" ,
"reply.persona" : "Persona" ,
"reply.notReady" : "This persona is not ready for AI draft (you can still type and send)." ,
"reply.draft" : "Reply draft" ,
"reply.attach" : "Attach" ,
"reply.generating" : "Generating…" ,
"reply.ai" : "AI draft" ,
"reply.sending" : "Sending…" ,
"reply.send" : "Send" ,
"image.attach" : "Attach" ,
"image.attachFail" : "Attach failed" ,
"image.attachedAria" : "Attached images" ,
"image.alt" : "Attachment" ,
"image.named" : "Image {n}" ,
"image.remove" : "Remove image" ,
"image.full" : "Full ({max})" ,
"image.more" : "Add more ({n}/{max})" ,
"metrics.aria" : "Post metrics" ,
"metrics.like" : "Likes" ,
"metrics.reply" : "Replies" ,
"metrics.repost" : "Reposts" ,
"metrics.quote" : "Quotes" ,
"metrics.view" : "Views" ,
"metrics.share" : "Shares" ,
"metrics.type.quote" : "Quote" ,
"metrics.type.reply" : "Reply" ,
"metrics.type.image" : "Image" ,
"metrics.type.video" : "Video" ,
"metrics.type.carousel" : "Carousel" ,
"metrics.type.repost" : "Repost" ,
"metrics.type.text" : "Text" ,
"metrics.type.post" : "Post" ,
"jobs.title" : "Jobs" ,
"jobs.startDemo" : "Start demo job" ,
"jobs.empty" : "No jobs yet" ,
"jobs.total" : "{n} total" ,
"jobs.showing" : " · showing first {n}" ,
"jobs.detail" : "Details" ,
"jobs.loadMore" : "Load more ({n} more)" ,
"jobs.notFound" : "Job not found" ,
"jobs.progress" : "Progress {n}%" ,
"jobs.updated" : "Updated {time}" ,
"jobs.backList" : "Back to list" ,
"plans.title" : "Change plan" ,
"plans.current" : "Current plan" ,
"plans.perMonth" : "/mo" ,
"plans.monthlyCredits" : "{n} credits / month" ,
"plans.usageLink" : "Usage" ,
"plans.inUse" : "Active" ,
"plans.recommended" : "Recommended" ,
"plans.creditsPerMonth" : "{n} credits / month" ,
"plan.cta.current" : "Current plan" ,
"plan.cta.upgrade" : "Upgrade" ,
"plan.cta.downgrade" : "Downgrade" ,
"plan.cta.switch" : "Switch" ,
"plan.free.headline" : "Trial and light personal use" ,
"plan.free.bullet1" : "{n} AI/search credits per month" ,
"plan.free.bullet2" : "Full product: Studio, Patrol, Outbox" ,
"plan.free.bullet3" : "Good for learning the flow" ,
"plan.free.bullet4" : "Upgrade anytime" ,
"plan.free.right1" : "Full access to accounts, Studio, Patrol, Outbox, jobs, and inspiration." ,
"plan.free.right2" : "Fixed monthly credits for copy, research, search, and images." ,
"plan.free.right3" : "After the cap, wait for next month or upgrade (unless an admin turns off limits)." ,
"plan.free.quota1" : "{n} credits allocated each month." ,
"plan.free.quota2" : "Reference: copy {copy}, research {research}, search {search}, image {image} runs." ,
"plan.free.note1" : "No payment required; confirms immediately." ,
"plan.free.note2" : "Invoice rules will be defined when billing goes live." ,
"plan.starter.headline" : "Small teams posting and patrolling daily" ,
"plan.starter.bullet1" : "{n} credits / month (about 6× Free)" ,
"plan.starter.bullet2" : "Steady posting, replies, and patrol" ,
"plan.starter.bullet3" : "Fits a 1– 3 person cadence" ,
"plan.starter.bullet4" : "Takes effect right after payment" ,
"plan.starter.right1" : "After payment this account becomes Starter; the month uses the new quota." ,
"plan.starter.right2" : "Credits support regular posts, reply drafts, and scheduled patrol." ,
"plan.starter.right3" : "Same features as Free; you buy more headroom." ,
"plan.starter.quota1" : "{n} credits / month · {price}." ,
"plan.starter.quota2" : "Reference: copy {copy}, research {research}, search {search}, image {image} runs." ,
"plan.starter.note1" : "Plan changes only after successful payment." ,
"plan.starter.note2" : "Resets on calendar month; unused credits do not roll over." ,
"plan.pro.headline" : "Multi-account, heavy AI and research" ,
"plan.pro.bullet1" : "{n} credits / month (about 4× Starter)" ,
"plan.pro.bullet2" : "High-volume copy, research, and images" ,
"plan.pro.bullet3" : "Built for agencies and multi-brand work" ,
"plan.pro.bullet4" : "Takes effect right after payment" ,
"plan.pro.right1" : "After payment this account becomes Pro; the month uses Pro quota." ,
"plan.pro.right2" : "Fits multi-account replies and deep research with less risk of running out mid-month." ,
"plan.pro.right3" : "Same features; you buy capacity and pace." ,
"plan.pro.quota1" : "{n} credits / month · {price}." ,
"plan.pro.quota2" : "Reference: copy {copy}, research {research}, search {search}, image {image} runs." ,
"plan.pro.note1" : "Failed payment does not change your plan." ,
"plan.pro.note2" : "After payment you can find receipts in billing history." ,
"checkout.title" : "Confirm plan" ,
"checkout.pickFirst" : "Please choose a plan first." ,
"checkout.viewPlans" : "View plans" ,
"checkout.cardLast4Required" : "Enter the last 4 digits of your card" ,
"checkout.cardNameRequired" : "Enter the cardholder name" ,
"checkout.fail" : "Could not complete" ,
"checkout.confirmFree" : "Confirm switch to Free" ,
"checkout.payAndAction" : "{action} and pay {price}" ,
"checkout.subscribe" : "Subscription" ,
"checkout.perMonth" : "/mo" ,
"checkout.monthlyCredits" : "{n} credits per month" ,
"checkout.youGet" : "What you get" ,
"checkout.quota" : "Quota" ,
"checkout.notes" : "Notes" ,
"checkout.cardholder" : "Cardholder" ,
"checkout.cardLast4" : "Last 4 digits" ,
"checkout.amountDue" : "Amount due" ,
"checkout.billedMonthly" : "{name} · billed monthly" ,
"checkout.already" : "Already on this plan" ,
"checkout.processing" : "Processing…" ,
"checkout.currentPlan" : "Current plan" ,
"checkout.pickOther" : "Choose another plan" ,
"checkout.cancel" : "Cancel" ,
"usage.widget.titleUsed" : "{name} · used {used}/{cap} credits" ,
"usage.widget.titleUnlimited" : "{name} · unlimited" ,
"usage.widget.ariaUsed" : "Used {used} of {cap} credits" ,
"usage.widget.dialog" : "Plan and usage" ,
"usage.widget.currentPlan" : "Current plan" ,
"usage.widget.unlimited" : "Unlimited" ,
"usage.widget.perMonth" : "/mo" ,
"usage.widget.monthUsage" : "This month" ,
"usage.widget.remaining" : "{n} credits left" ,
"usage.widget.leftShort" : "{n} left" ,
"usage.widget.overShort" : "Over" ,
"usage.widget.upgradeShort" : "Upgrade" ,
"usage.widget.upgrade" : "Upgrade" ,
"usage.widget.includes" : "This plan includes" ,
"usage.widget.nudge" : "You're running low this month. Upgrade for more credits right away." ,
"usage.widget.changePlan" : "Change plan" ,
"usage.widget.usageDetail" : "Usage details" ,
"usage.meter.ai_copy" : "AI copy" ,
"usage.meter.ai_research" : "AI research" ,
"usage.meter.web_search" : "Search" ,
"usage.meter.ai_image" : "AI image" ,
"usage.meter.barAria" : "{label} {count} runs, {credits} credits, cap {cap}" ,
"usage.ledger.costAria" : "Used {n} credits" ,
"usage.chart.period" : "Period" ,
"usage.chart.allocated" : "Allocated" ,
"usage.chart.consumed" : "Used" ,
"usage.chart.pctTitle" : "Usage as share of allocation" ,
"usage.chart.aria" : "Allocation and usage" ,
"usage.chart.colAria" : "{label}: allocated {purchased}, used {consumed}" ,
2026-07-10 12:54:45 +00:00
"settings.provider" : "Provider" ,
"settings.model" : "Model" ,
"settings.aiUnifiedHint" : "Copy, research, and expand all share one provider and model." ,
2026-07-10 05:10:31 +00:00
"settings.fetchModels" : "Fetch models" ,
"settings.fetchingModels" : "Loading…" ,
2026-07-10 12:54:45 +00:00
"settings.apiKey" : "API key" ,
2026-07-10 05:10:31 +00:00
"settings.configured" : "Configured" ,
"settings.notConfigured" : "Not set" ,
"settings.modelsLoaded" : "Loaded models for {provider}" ,
"settings.aiSaved" : "AI settings saved" ,
"settings.searchSaved" : "Search settings saved" ,
2026-07-10 12:54:45 +00:00
"settings.searchProvider" : "Search provider" ,
"settings.expand" : "Expand strategy" ,
"settings.exaKey" : "Exa API key" ,
"settings.devMode" : "Developer mode (crawler test patrol)" ,
"settings.devModeHint" : "When on, test patrol can use the Chrome crawler; live publish/replies still use the API. Download the extension to sync Threads session." ,
"settings.ext.title" : "Chrome extension" ,
"settings.ext.desc" : "Developer mode needs this extension to sync Threads session from Chrome into Lapras." ,
"settings.ext.step1" : "Download and unzip to get the haixun-threads-sync folder" ,
"settings.ext.step2" : "Open chrome://extensions and enable Developer mode" ,
"settings.ext.step3" : "Click Load unpacked and select the unzipped folder" ,
"settings.ext.step4" : "Set this site’ s URL in the extension options, then refresh Lapras" ,
"settings.ext.download" : "Download extension (ZIP)" ,
2026-07-10 05:10:31 +00:00
"forgot.fail" : "Request failed" ,
"forgot.mockHint" : "In production this goes to email; here is a direct link:" ,
2026-07-10 12:54:45 +00:00
"forgot.checkInbox" : "Please check your inbox (and spam)." ,
2026-07-10 05:10:31 +00:00
"reset.mismatch" : "Passwords do not match" ,
"reset.fail" : "Reset failed" ,
"reset.cardTitle" : "Reset password" ,
"reset.redirecting" : "Redirecting to sign in…" ,
"reset.loginNow" : "Sign in now" ,
2026-07-10 12:54:45 +00:00
"reset.passwordPh" : "Password must be at least 12 characters with upper, lower, digit, and symbol" ,
"reset.forgotLink" : "Request a new reset" ,
2026-07-10 05:10:31 +00:00
"verify.sendFail" : "Could not send" ,
"verify.fail" : "Verification failed" ,
"verify.success" : "Email verified. You can use Lapras now." ,
"verify.codePh" : "6-digit code" ,
"verify.currentAccount" : "Account: {email}" ,
"login.brandTitle" : "巡樓 · Lapras" ,
"common.listSep" : ", " ,
"common.dash" : "—" ,
"scout.title" : "Patrol" ,
"scout.today" : "Today" ,
"scout.purposeValue" : "Pain-point replies" ,
"scout.purposeActivity" : "Activity short replies" ,
"scout.goal" : "Daily goal (posts)" ,
"scout.progress" : "Progress {done}/{goal}" ,
"scout.intent" : "What to find / reply to" ,
"scout.keyword" : "Keywords" ,
"scout.intentPh" : "e.g. seasonal scalp itch, truly fragrance-free, outlets on weekends" ,
"scout.keywordPh" : "e.g. weekend coffee remote" ,
"scout.productOptional" : "Product (optional)" ,
"scout.noProduct" : "No product" ,
"scout.brandFallback" : "Brand" ,
"scout.placement" : "Placement: {label}" ,
"scout.painPart" : " · pain “{pain}”" ,
"scout.noProductsBefore" : "No products yet. Add some under" ,
"scout.noProductsAfter" : "." ,
"scout.start" : "Start" ,
"scout.startMore" : "Fetch more" ,
"scout.fetching" : "Fetching…" ,
"scout.runs" : "Patrol batches" ,
"scout.runCount" : "Batch ({n})" ,
"scout.runSelectAria" : "Switch patrol batch" ,
"scout.runPending" : "{n} pending · " ,
"scout.runDone" : "Cleared · " ,
"scout.runTotal" : " ({n} posts)" ,
"scout.deleteRun" : "Delete this batch" ,
"scout.deleting" : "Deleting…" ,
"scout.now" : "Now this post" ,
"scout.emptyBatch" : "Nothing pending in this batch" ,
"scout.draft" : "Reply draft" ,
"scout.draftPhActivity" : "Short reply…" ,
"scout.draftPhValue" : "Empathize → suggest…" ,
"scout.sendAccount" : "Send from account" ,
"scout.noAccount" : "No usable accounts" ,
"scout.personaForRegen" : "Persona (for regen)" ,
"scout.notReady" : " (not ready)" ,
"scout.skip" : "Skip" ,
"scout.regen" : "Regen" ,
"scout.send" : "Send" ,
"scout.sending" : "Sending…" ,
"scout.needAccountBefore" : "Connect a usable account under" ,
"scout.needAccountAfter" : "first." ,
"scout.knowledge" : "Related knowledge" ,
"scout.knowledgeWithLabel" : "Related · {label}" ,
"scout.knowledgeLearn" : "Related · to learn" ,
"scout.collapseKnowledge" : "Collapse knowledge" ,
"scout.expandLearn" : "Expand · {n} notes" ,
"scout.expandKnowledge" : "Expand knowledge" ,
"scout.deleteKnowledgeRun" : "Delete this batch's knowledge & hits" ,
"scout.loadingKnowledge" : "Preparing related knowledge…" ,
"scout.notesCount" : "{n} notes" ,
"scout.noKnowledge" : "No related knowledge yet" ,
"scout.product" : "Product" ,
"scout.painsSolved" : "Pains we solve" ,
"scout.focus" : "Focus" ,
"scout.all" : "All" ,
"scout.noWebSummary" : "No web summaries yet" ,
"scout.queue" : "Queue · {n}" ,
"scout.collapseQueue" : "Collapse queue" ,
"scout.expandQueue" : "Expand queue" ,
"scout.noOtherPending" : "No other pending" ,
"scout.learnPoints" : "Key takeaways" ,
"scout.replyHooks" : "Reply hooks" ,
"scout.badgeCore" : "Closest to topic" ,
"scout.unnamedRun" : "Unnamed batch" ,
"scout.thisRun" : "this batch" ,
"scout.confirmDeleteRun" : "Delete patrol batch “{label}”?\\nHits and related knowledge will be removed. This cannot be undone." ,
"scout.deletedRun" : "Deleted batch “{label}”" ,
"scout.deleteRunFail" : "Failed to delete batch" ,
"scout.needKeyword" : "Enter keywords first" ,
"scout.needIntent" : "Write what you're looking for" ,
"scout.productMissing" : "Selected product is not in the list. Please reselect." ,
"scout.defaultLabel" : "Patrol" ,
"scout.newRunActivity" : "New batch “{label}” · {n} pending" ,
"scout.newRunValue" : "New batch “{label}” · {n} posts · handle “Now this post”" ,
"scout.knowledgeReady" : "“{label}” knowledge ready · {n} notes" ,
"scout.patrolFail" : "This patrol failed" ,
"scout.draftFail" : "Draft failed" ,
"scout.skipped" : "Skipped" ,
"scout.noDraft" : "No draft to send" ,
"scout.accountFallback" : "account" ,
"scout.sent" : "Sent (@{who}) · today {done}/{goal}" ,
"scout.sendFail" : "Send failed" ,
"scout.confirmDeletePost" : "Delete this hit?" ,
"scout.stanceActivity" : "Short reply · activity" ,
"scout.stanceProduct" : "Empathy · soft product" ,
"scout.stanceRelation" : "Engage · build rapport" ,
"scout.tier.core" : "Closest" ,
"scout.tier.coreHint" : "Directly on the pain/keywords — read first" ,
"scout.tier.adjacent" : "Adjacent" ,
"scout.tier.adjacentHint" : "Nearby context, broaden search" ,
"scout.tier.broad" : "Broad" ,
"scout.tier.broadHint" : "Background & contrast — optional" ,
"scout.relation.solves_pain" : "Hits the pain" ,
"scout.relation.nearby_scene" : "Nearby scene" ,
"scout.relation.myth" : "Myth-busting" ,
"scout.relation.contrast" : "Contrast shopping" ,
"scout.relation.background" : "Background" ,
"brands.title" : "Brands" ,
"brands.railAria" : "Brand list" ,
"brands.railLabel" : "Your brands" ,
"brands.add" : "Add" ,
"brands.brandName" : "Brand name" ,
"brands.brandNamePh" : "e.g. your brand" ,
"brands.creating" : "Creating…" ,
"brands.createBrand" : "Create brand" ,
"brands.searchAria" : "Search brands" ,
"brands.searchPh" : "Search brands…" ,
"brands.empty" : "No brands yet" ,
"brands.noMatch" : "No matches" ,
"brands.selectAria" : "Select brand" ,
"brands.pickOne" : "Pick a brand" ,
"brands.inUseHint" : "Active · used for patrol and studio" ,
"brands.inUse" : "Active" ,
"brands.tabInfo" : "Brand info" ,
"brands.tabProducts" : "Products" ,
"brands.tabProductsN" : "Products ({n})" ,
"brands.displayName" : "Name" ,
"brands.brief" : "Summary" ,
"brands.briefPh" : "One line about this brand" ,
"brands.audience" : "Audience" ,
"brands.audiencePh" : "Who cares and why" ,
"brands.goals" : "Goals" ,
"brands.goalsPh" : "What you want on Threads" ,
"brands.saving" : "Saving…" ,
"brands.deleteBrand" : "Delete brand" ,
"brands.searchProductAria" : "Search products" ,
"brands.searchProductPh" : "Search products…" ,
"brands.addProduct" : "Add product" ,
"brands.noProducts" : "No products yet" ,
"brands.hasLink" : "Has link" ,
"brands.painLabel" : "Pains " ,
"brands.editProduct" : "Edit product" ,
"brands.newProduct" : "New product" ,
"brands.importFromUrl" : "Import from product URL" ,
"brands.fetching" : "Fetching…" ,
"brands.fetch" : "Fetch" ,
"brands.pains" : "Pain points" ,
"brands.painsPh" : "One per line" ,
"brands.tags" : "Tags" ,
"brands.tagsPh" : "Comma-separated" ,
"brands.intro" : "Description" ,
"brands.link" : "Link" ,
"brands.update" : "Update" ,
"brands.createItem" : "Add" ,
"brands.needName" : "Enter a name" ,
"brands.created" : "Created “{name}”" ,
"brands.createFail" : "Create failed" ,
"brands.saved" : "Saved" ,
"brands.saveFail" : "Save failed" ,
"brands.confirmDelete" : "Delete “{name}”?" ,
"brands.deleted" : "Deleted" ,
"brands.deleteFail" : "Delete failed" ,
"brands.fetchFail" : "Fetch failed" ,
"brands.needLabelContext" : "Name and description are required" ,
"brands.productUpdated" : "Updated" ,
"brands.productAdded" : "Added" ,
"brands.confirmDeleteProduct" : "Delete this product?" ,
"insights.title" : "Account performance" ,
"insights.account" : "Account" ,
"insights.noAccount" : "No accounts" ,
"insights.syncing" : "Syncing…" ,
"insights.syncPosts" : "Sync posts" ,
"insights.myPosts" : "My posts" ,
"insights.pickAccount" : "Select an account" ,
"insights.goAccounts" : "Accounts" ,
"insights.kpiMonth" : "This month" ,
"insights.monthViews" : "Views this month" ,
"insights.monthLikes" : "Likes this month" ,
"insights.monthReplies" : "Replies this month" ,
"insights.engRate" : "Engagement" ,
"insights.vsPrev" : "vs last month" ,
"insights.avgNear" : "Recent avg {rate}" ,
"insights.trendTitle" : "Trends & analysis · @{user}" ,
"insights.metricViews" : "Views" ,
"insights.metricLikes" : "Likes" ,
"insights.metricReplies" : "Replies" ,
"insights.metricPosts" : "Posts" ,
"insights.metricPostsFull" : "Posts" ,
"insights.chartMetrics" : "Chart metric" ,
"insights.barsAria" : "Recent months {metric}; click a bar for analysis" ,
"insights.barsLabel" : "{metric} · last {n} months" ,
"insights.clickBar" : " · click bar for analysis" ,
"insights.pickMonthAria" : "Select month" ,
"insights.barTitle" : "{label}: {value}{est} · click for analysis" ,
"insights.est" : " (est.)" ,
"insights.monthSuffix" : "{m}" ,
"insights.sparkAria" : "Trend line; click a node to select month" ,
"insights.analysisOf" : "{label} analysis" ,
"insights.producedAt" : "Generated {time}" ,
"insights.hasEstimate" : " · includes estimates" ,
"insights.viewsVsPrev" : " · views vs prev {delta}" ,
"insights.statPosts" : "Posts" ,
"insights.statViews" : "Views" ,
"insights.statLikes" : "Likes" ,
"insights.statReplies" : "Replies" ,
"insights.conclusions" : "Takeaways" ,
"insights.recommendations" : "Recommendations" ,
"insights.highlights" : "Month highlights" ,
"insights.findTopics" : "Find topics" ,
"insights.goScout" : "Go patrol" ,
"insights.selectMonth" : "Select a month" ,
"insights.topPosts" : "Top posts" ,
"insights.noPosts" : "No posts yet" ,
"insights.postStats" : "Views {views} · likes {likes} · replies {replies}" ,
"insights.openThreads" : "Open Threads" ,
"insights.zeroPct" : "0%" ,
"plays.tabOwn" : "My posts" ,
"plays.tabLink" : "Threads link" ,
"plays.noPosts" : "No posts yet" ,
"plays.targetPost" : "Target post" ,
"plays.likesSuffix" : " ({n} likes)" ,
"plays.linkCard" : "Paste Threads link" ,
"plays.postLink" : "Post URL" ,
"plays.resolving" : "Resolving…" ,
"plays.resolve" : "Resolve link" ,
"plays.resolveHint" : "After resolve, schedule your accounts to reply under that post." ,
"plays.targetOwn" : "Target post (yours)" ,
"plays.openThreads" : "Open Threads" ,
"plays.external" : "External post" ,
"plays.addScheme" : "New scheme" ,
"plays.schemeCount" : "{n} schemes for this target" ,
"plays.noSchemes" : "No schemes yet" ,
"plays.replyCount" : "{n} replies" ,
"plays.editTitle" : "Edit: {title}" ,
"plays.schemeName" : "Scheme name" ,
"plays.schemeNamePh" : "e.g. Scheme A · soft engage" ,
"plays.speakersOwn" : "Accounts (post owner always included)" ,
"plays.speakers" : "Accounts" ,
"plays.postOwner" : " (post owner)" ,
"plays.noAccounts" : "No usable accounts. Connect Threads first." ,
"plays.interval" : "Interval (min)" ,
"plays.applyInterval" : "Apply interval" ,
"plays.aiEmpty" : "AI fill empty" ,
"plays.aiBusy" : "Generating…" ,
"plays.replies" : "Replies ({n})" ,
"plays.stepN" : "Reply {n}" ,
"plays.who" : "Who" ,
"plays.personaOpt" : "Persona (optional)" ,
"plays.brandOpt" : "Brand (optional)" ,
"plays.reply" : "Reply" ,
"plays.attach" : "Images" ,
"plays.addOne" : "Add one" ,
"plays.saving" : "Saving…" ,
"plays.saveScheme" : "Save scheme" ,
"plays.submitting" : "Submitting…" ,
"plays.submitOutbox" : "Submit to Outbox" ,
"plays.closeEdit" : "Close editor" ,
"plays.noTarget" : "No target post yet" ,
"plays.resolved" : "Link resolved" ,
"plays.resolveFail" : "Resolve failed" ,
"plays.filled" : "Generated {n}" ,
"plays.needTarget" : "Select a target post first" ,
"plays.saved" : "Scheme saved" ,
"plays.saveFail" : "Save failed" ,
"plays.submitted" : "Sent to Outbox" ,
"plays.submitFail" : "Submit failed" ,
"plays.confirmDelete" : "Delete this scheme?" ,
"plays.accountFallback" : "account" ,
"inspire.loading" : "Loading…" ,
"inspire.trendsAria" : "What's hot on Threads" ,
"inspire.trendsLabel" : "Hot on Threads" ,
"inspire.refresh" : "Refresh" ,
"inspire.clearChat" : "Clear chat" ,
"inspire.pinAsElement" : "Apply as element" ,
"inspire.you" : "You" ,
"inspire.ai" : "AI" ,
"inspire.system" : "System" ,
"inspire.useDraft" : "Use this draft" ,
"inspire.openPlay" : "Open play" ,
"inspire.generating" : "Generating…" ,
"inspire.thinking" : "Thinking…" ,
"inspire.pinnedAria" : "Applied this round" ,
"inspire.pinned" : "Applied" ,
"inspire.pickRight" : "Pick elements on the right" ,
"inspire.unpinTitle" : "Click to unapply" ,
"inspire.inputAria" : "Talk to AI" ,
"inspire.inputPh" : "What to write? Or shorter, more casual…" ,
"inspire.send" : "Send" ,
"inspire.generate" : "Generate" ,
"inspire.library" : "Element library" ,
"inspire.addNew" : "+ Add" ,
"inspire.kind" : "Type" ,
"inspire.kindRole" : "Role prompt" ,
"inspire.kindSnippet" : "Snippet" ,
"inspire.kindTrendNote" : "Trend note" ,
"inspire.kindBrand" : "Brand" ,
"inspire.kindTrend" : "Trend" ,
"inspire.name" : "Name" ,
"inspire.namePh" : "e.g. pro Threads writer" ,
"inspire.body" : "Content (goes into prompt)" ,
"inspire.bodyPh" : "You are a…" ,
"inspire.saveElement" : "Save to library" ,
"inspire.citeBrand" : "Cite brand" ,
"inspire.applied" : "Applied" ,
"inspire.clickApply" : "Click to apply" ,
"inspire.noBrands" : "No brands yet" ,
"inspire.appliedToggle" : "Applied · click again to remove" ,
"inspire.deleteAria" : "Delete" ,
"inspire.needInput" : "Type a line first, or generate directly" ,
"inspire.fail" : "Failed" ,
"inspire.wantWrite" : "Want to write about {label}: {summary}" ,
"inspire.trendBody" : "Topic: {label}. {summary}" ,
"inspire.pinnedTrend" : "Applied trend {label}" ,
"inspire.needTitleBody" : "Name and content required" ,
"inspire.added" : "Added to library" ,
"inspire.addFail" : "Add failed" ,
"inspire.confirmRemove" : "Remove this from the library?" ,
"inspire.confirmClear" : "Clear chat? (library kept)" ,
"inspire.genMessage" : "Write a Threads post from the applied elements" ,
"persona.add" : "New persona" ,
"persona.empty" : "No personas yet" ,
"persona.emptyDesc" : "Add one and analyze it for drafting." ,
"persona.statusReady" : "ready" ,
"persona.statusAnalyzing" : "analyzing" ,
"persona.statusPending" : "pending" ,
"persona.default" : "Default" ,
"persona.backList" : "← Personas" ,
"persona.tabOverview" : "Overview" ,
"persona.tabAnalyze" : "Analyze" ,
"persona.tabFingerprint" : "Fingerprint" ,
"persona.tabPreview" : "Preview" ,
"persona.name" : "Name" ,
"persona.brief" : "Brief" ,
"persona.briefPh" : "Who, for whom, core message…" ,
"persona.avoid" : "Guardrails · banned words (comma-separated)" ,
"persona.guardChars" : "{n} chars" ,
"persona.banAi" : " · ban AI tone" ,
"persona.notReadySuffix" : " · not ready" ,
"persona.setDefault" : "Set as default" ,
"persona.modeAccount" : "Public account" ,
"persona.modeText" : "Paste text" ,
"persona.username" : "Threads username" ,
"persona.fromBound" : "From linked account" ,
"persona.select" : "Select…" ,
"persona.crawlAnalyze" : "Crawl public posts & analyze" ,
"persona.crawlBusy" : "Crawling / analyzing…" ,
"persona.refText" : "Reference text (--- separates posts)" ,
"persona.refTextPh" : "First post…\n\n---\n\nSecond post…" ,
"persona.sourceLabel" : "Source note (optional)" ,
"persona.sourcePh" : "My old posts" ,
"persona.analyzeText" : "Analyze from text" ,
"persona.analyzeBusy" : "Analyzing…" ,
"persona.sampleMeta" : "Samples {n}" ,
"persona.sourceManual" : "Pasted" ,
"persona.analyzeHint" : "After analysis, 8D summaries appear here." ,
"persona.fingerprintHint" : "Main voice for drafting. Edit catchphrases, rhythm, bans; Studio/replies use this." ,
"persona.fingerprint" : "Language fingerprint" ,
"persona.fingerprintPh" : "Filled after analysis…" ,
"persona.saveFingerprint" : "Save fingerprint" ,
"persona.tryGen" : "Preview root + reply" ,
"persona.notReadyMsg" : "Persona not ready" ,
"persona.rootPost" : "Root post" ,
"persona.reply" : "Reply" ,
"persona.hidePrompt" : "Hide prompt block" ,
"persona.showPrompt" : "Show injected prompt" ,
"persona.promptBlock" : "prompt block (post)" ,
"persona.pickOne" : "Pick a persona" ,
"persona.pickDesc" : "Or add one to start analyzing." ,
"persona.created" : "Created — finish account crawl or paste text under Analyze" ,
"persona.saved" : "Saved" ,
"persona.textDone" : "Text analysis done · {n} segments → ready" ,
"persona.analyzeFail" : "Analysis failed" ,
"persona.reading" : "Reading public posts…" ,
"persona.accountDone" : "@{user} · {n} posts → ready" ,
"persona.setDefaultMsg" : "“{name}” set as default" ,
"persona.confirmDelete" : "Delete persona “{name}”?" ,
"persona.deleted" : "Persona deleted" ,
"persona.needReady" : "Finish analysis first (ready)" ,
"persona.dim.d1Tone" : "D1 Tone" ,
"persona.dim.d2Structure" : "D2 Structure" ,
"persona.dim.d3Interaction" : "D3 Interaction" ,
"persona.dim.d4Topics" : "D4 Topics" ,
"persona.dim.d5Rhythm" : "D5 Rhythm" ,
"persona.dim.d6Visual" : "D6 Visual" ,
"persona.dim.d7Conversion" : "D7 Conversion" ,
"persona.dim.d8Risk" : "D8 Risk" ,
"admin.users.loadFail" : "Load failed" ,
"admin.users.created" : "Added islander “{name}” · copy the password below" ,
"admin.users.createFail" : "Create failed" ,
"admin.users.unlimitedOn" : "“{name}” set to unlimited (usage still counted)" ,
"admin.users.unlimitedOff" : "“{name}” back to plan limits" ,
"admin.users.updateFail" : "Update failed" ,
"admin.users.planSet" : "“{name}” plan → {plan}" ,
"admin.users.confirmSuspend" : "Suspend “{name}”?\\nThey will not be able to sign in." ,
"admin.users.confirmUnsuspend" : "Restore “{name}”?\\nThey can sign in again." ,
"admin.users.didSuspend" : "Suspended “{name}”" ,
"admin.users.didUnsuspend" : "Restored “{name}”" ,
"admin.users.suspendFail" : "Suspend failed" ,
"admin.users.unsuspendFail" : "Restore failed" ,
"admin.users.markedVerified" : "Marked {name} as email verified" ,
"admin.users.markedUnverified" : "Marked {name} as unverified" ,
"admin.users.rolesUpdated" : "Updated roles for {name}: {roles}" ,
"admin.users.rolesFail" : "Role update failed" ,
"admin.users.confirmReset" : "Reset password for “{name}”?\\nTemp password stays visible until you close it (survives refresh)." ,
"admin.users.resetDone" : "Reset password for {name} (shown below — copy then close)" ,
"admin.users.resetFail" : "Reset failed" ,
"admin.users.copied" : "Copied to clipboard" ,
"admin.users.copyFail" : "Copy failed — select the password manually" ,
"admin.users.confirmDismissTemp" : "After close, this temp password won't show again (copy first if needed). Close?" ,
"admin.users.tempPwNew" : "New islander temp password" ,
"admin.users.tempPw" : "Temp password" ,
"admin.users.tempPwPersist" : "(stays visible · survives refresh)" ,
"admin.users.copyPw" : "Copy password" ,
"admin.users.close" : "Close" ,
"admin.users.createTitle" : "Add islander" ,
"admin.users.memberName" : "Display name" ,
"admin.users.displayNamePh" : "Display name" ,
"admin.users.email" : "Email" ,
"admin.users.initPassword" : "Initial password (optional)" ,
2026-07-10 12:54:45 +00:00
"admin.users.initPasswordPh" : "Leave blank to auto-generate; if set, must meet policy" ,
2026-07-10 05:10:31 +00:00
"admin.users.markVerifiedCheck" : "Mark email verified (usable immediately)" ,
"admin.users.alsoAdmin" : "Also make admin" ,
"admin.users.creating" : "Creating…" ,
"admin.users.createSubmit" : "Create islander" ,
"admin.users.clear" : "Clear" ,
"admin.users.searchActive" : "Search “{query}” · matches name, email, uid" ,
"admin.users.noMatch" : "No matches" ,
"admin.users.none" : "No islanders yet" ,
"admin.users.you" : "You" ,
"admin.users.status" : "Status" ,
"admin.users.role" : "Roles" ,
"admin.users.emailVerify" : "Email verification" ,
"admin.users.bio" : "Bio" ,
"admin.users.timezone" : "Timezone" ,
"admin.users.notifyEmail" : "Email notifications" ,
"admin.users.on" : "On" ,
"admin.users.off" : "Off" ,
"admin.users.createdAt" : "Created" ,
"admin.users.updatedAt" : "Updated" ,
"admin.users.accountStatus" : "Account status" ,
"admin.users.updating" : "Updating…" ,
"admin.users.usageTitle" : "Usage & plan" ,
2026-07-10 12:54:45 +00:00
"admin.users.usageLiveSkip" : "Plan/quota are Usage domain — not on live backend yet (M3). Editable in mock only." ,
2026-07-10 05:10:31 +00:00
"admin.users.plan" : "Plan" ,
"admin.users.planOption" : "{name} ({credits} credits / mo)" ,
"admin.users.unlimited" : "Unlimited" ,
"admin.users.byPlan" : "By plan" ,
"admin.users.setUnlimited" : "Set unlimited" ,
"admin.users.setLimited" : "Enforce plan limits" ,
"admin.users.unlimitedHint" : "Unlimited: can keep using past plan cap; AI/Search counts and credits still track." ,
"admin.users.loadingUsage" : "Loading usage prefs…" ,
"admin.users.assignRoles" : "Assign roles" ,
"admin.users.memberBase" : "{role} (base, always on)" ,
"admin.users.adminDesc" : "{role} — manage islanders and system" ,
"admin.users.saving" : "Saving…" ,
"admin.users.saveRoles" : "Save roles" ,
"admin.users.markUnverifiedBtn" : "Mark unverified" ,
"admin.users.markVerifiedBtn" : "Mark verified" ,
"admin.users.resetting" : "Resetting…" ,
"admin.users.resetTemp" : "Reset password (temp)" ,
"admin.users.customPw" : "Or set a password (optional)" ,
2026-07-10 12:54:45 +00:00
"admin.users.customPwPh" : "Password must be at least 12 characters with upper, lower, digit, and symbol" ,
2026-07-10 05:10:31 +00:00
"admin.users.resetWithCustom" : "Reset with this password" ,
"usage.tabMine" : "My usage" ,
"usage.tabTenant" : "All usage" ,
"usage.currentPlan" : "Current plan" ,
"usage.planMeta" : "/ mo · {n} credits monthly" ,
"usage.changePlan" : "Change plan" ,
"usage.usedThisMonth" : "Used this month" ,
"usage.remainLabel" : "Remaining" ,
"usage.ledgerToggle" : "Usage log" ,
"usage.collapse" : "Collapse" ,
"usage.eventsCount" : "{n} events" ,
"usage.granularity" : "Granularity" ,
"usage.day" : "Day" ,
"usage.monthUnit" : "Month" ,
"usage.year" : "Year" ,
"usage.from" : "From" ,
"usage.to" : "To" ,
"usage.callCounts" : "Call counts" ,
"usage.noMembers" : "No members yet" ,
"usage.planAria" : "{name} plan" ,
"usage.unlimitedTitle" : "Unlimited" ,
"usage.setLimited" : "Enforce limits" ,
"usage.setUnlimited" : "Set unlimited" ,
"usage.limitShort" : "Cap" ,
"usage.subscribed" : "Subscribed to {name}" ,
"usage.unlimitedSet" : "Set unlimited" ,
"usage.limitedSet" : "Limits enforced" ,
"usage.planUpdated" : "Plan updated to {name}" ,
"usage.fail" : "Failed" ,
"currency.TWD" : "New Taiwan Dollar (TWD)" ,
"currency.USD" : "US Dollar (USD)" ,
"currency.JPY" : "Japanese Yen (JPY)" ,
"currency.EUR" : "Euro (EUR)" ,
"currency.HKD" : "Hong Kong Dollar (HKD)" ,
"locale.zh-TW" : "繁體中文" ,
"locale.en" : "English" ,
"pager.nav" : "Pagination" ,
"pager.pageSize" : "Items per page" ,
"pager.perPage" : "{n}/page" ,
"pager.prev" : "Previous" ,
"pager.next" : "Next" ,
"plays.defaultTitle" : "New play" ,
"plays.topicOnPost" : "On: {snippet}" ,
"plays.topicOnExternal" : "On: {label} · {snippet}" ,
"plays.externalFallback" : "External post" ,
"persona.newName" : "New persona" ,
"persona.previewTopic" : "Looking for a café I can sit in for hours" ,
"persona.previewReplySample" : "The one in Da’ an is fine but crowded" ,
"inspire.playTitle" : "Inspired thread" ,
"wizard.topic.fallbackTopic" : "Everyday topic" ,
"play.err.needLead" : "Pick a lead account" ,
"play.err.needRoot" : "Add at least one root post" ,
"play.err.firstMustRoot" : "The first step must be the root post" ,
"play.err.rootMustLead" : "Root post must use the lead account" ,
"play.err.rootEmpty" : "Root post text cannot be empty" ,
"play.err.replyAccount" : "Replies can only use lead or selected cast accounts" ,
"play.err.replyEmpty" : "Reply text cannot be empty" ,
"play.err.needTarget" : "Pick one of your posts, or paste a Threads link" ,
"play.err.needReplies" : "Add at least one reply" ,
"play.err.needReplyAccounts" : "Pick at least one reply account" ,
"play.err.stepAccount" : "Every reply needs a usable account" ,
"play.err.stepEmpty" : "Reply text cannot be empty" ,
"play.err.notFound" : "Play not found" ,
"time.justNow" : "Just now" ,
"time.minAgo" : "{n}m ago" ,
"time.hourAgo" : "{n}h ago" ,
"time.dayAgo" : "{n}d ago" ,
"time.min" : "{n} min" ,
"time.hour" : "{n} hr" ,
"time.day" : "{n} day" ,
"time.expired" : "Expired {span}" ,
"time.remaining" : "{span} left" ,
"time.sessionUnknown" : "Session not recorded" ,
"time.sessionExpired" : "Session expired · {absolute}" ,
"time.sessionSoon" : "Session expiring · {relative} ({absolute})" ,
"time.sessionOk" : "Session OK · {relative} ({absolute})" ,
} ;
const catalogs : Record < AppLocale , MessageDict > = {
"zh-TW" : zhTW ,
en ,
} ;
export function getCatalog ( locale : AppLocale ) : MessageDict {
return catalogs [ locale ] || zhTW ;
}
export function translate (
locale : AppLocale ,
key : string ,
params? : Record < string , string | number > ,
) : string {
const dict = getCatalog ( locale ) ;
let s = dict [ key ] ? ? zhTW [ key ] ? ? key ;
if ( params ) {
for ( const [ k , v ] of Object . entries ( params ) ) {
s = s . replace ( new RegExp ( ` \\ { ${ k } \\ } ` , "g" ) , String ( v ) ) ;
}
}
return s ;
}