From 0436a851da421392e36606e18359fb93fe92e16d Mon Sep 17 00:00:00 2001 From: Jun Endo Date: Thu, 22 Jan 2026 11:49:44 +0900 Subject: [PATCH] feat(i18n): add Japanese (ja-JP) language support (#450) --- README.md | 2 +- frontend/src/CLAUDE.md | 2 +- .../src/components/common/LanguageToggle.tsx | 6 + frontend/src/lib/locales/CLAUDE.md | 3 +- frontend/src/lib/locales/en-US/index.ts | 1 + frontend/src/lib/locales/index.test.ts | 10 + frontend/src/lib/locales/index.ts | 7 +- frontend/src/lib/locales/ja-JP/index.ts | 947 ++++++++++++++++++ frontend/src/lib/locales/pt-BR/index.ts | 1 + frontend/src/lib/locales/zh-CN/index.ts | 1 + frontend/src/lib/locales/zh-TW/index.ts | 1 + frontend/src/lib/utils/date-locale.ts | 3 +- 12 files changed, 978 insertions(+), 6 deletions(-) create mode 100644 frontend/src/lib/locales/ja-JP/index.ts diff --git a/README.md b/README.md index dd19ed8..041f7ab 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ In a world dominated by Artificial Intelligence, having the ability to think - 🎙 **Generate professional podcasts** - Advanced multi-speaker podcast generation - 🔍 **Search intelligently** - Full-text and vector search across all your content - 💬 **Chat with context** - AI conversations powered by your research -- 🌐 **Multi-language UI** - English, Portuguese, and Chinese (Simplified & Traditional) support +- 🌐 **Multi-language UI** - English, Portuguese, Chinese (Simplified & Traditional), and Japanese support Learn more about our project at [https://www.open-notebook.ai](https://www.open-notebook.ai) diff --git a/frontend/src/CLAUDE.md b/frontend/src/CLAUDE.md index bfc764b..8a18d5e 100644 --- a/frontend/src/CLAUDE.md +++ b/frontend/src/CLAUDE.md @@ -62,7 +62,7 @@ User interactions trigger mutations/queries via hooks, which communicate with th - Ensures type safety across API calls and store mutations #### `lib/locales/` — Internationalization (i18n) -- **Locale files** (`en-US/`, `pt-BR/`, `zh-CN/`, `zh-TW/`): Translation strings organized by feature +- **Locale files** (`en-US/`, `pt-BR/`, `zh-CN/`, `zh-TW/`, `ja-JP/`): Translation strings organized by feature - **`i18n.ts`**: i18next configuration with language detection - **`use-translation.ts`**: Custom hook with Proxy-based `t.section.key` access pattern - **Pattern**: Components call `useTranslation()` hook; access strings via `t.common.save`, `t.notebooks.title` diff --git a/frontend/src/components/common/LanguageToggle.tsx b/frontend/src/components/common/LanguageToggle.tsx index 274c5d8..502d719 100644 --- a/frontend/src/components/common/LanguageToggle.tsx +++ b/frontend/src/components/common/LanguageToggle.tsx @@ -58,6 +58,12 @@ export function LanguageToggle({ iconOnly = false }: LanguageToggleProps) { > {t.common.portuguese} + setLanguage('ja-JP')} + className={currentLang === 'ja-JP' || currentLang.startsWith('ja') ? 'bg-accent' : ''} + > + {t.common.japanese} + ) diff --git a/frontend/src/lib/locales/CLAUDE.md b/frontend/src/lib/locales/CLAUDE.md index b9df0a1..26cd838 100644 --- a/frontend/src/lib/locales/CLAUDE.md +++ b/frontend/src/lib/locales/CLAUDE.md @@ -17,7 +17,8 @@ lib/ ├── en-US/index.ts # English translations ├── pt-BR/index.ts # Brazilian Portuguese translations ├── zh-CN/index.ts # Simplified Chinese translations - └── zh-TW/index.ts # Traditional Chinese translations + ├── zh-TW/index.ts # Traditional Chinese translations + └── ja-JP/index.ts # Japanese translations ``` ## Key Components diff --git a/frontend/src/lib/locales/en-US/index.ts b/frontend/src/lib/locales/en-US/index.ts index c0639c3..16447ce 100644 --- a/frontend/src/lib/locales/en-US/index.ts +++ b/frontend/src/lib/locales/en-US/index.ts @@ -22,6 +22,7 @@ export const enUS = { language: "Language", english: "English", chinese: "简䜓䞭文", + japanese: "日本語", source: "Source", notebook: "Notebook", podcast: "Podcast", diff --git a/frontend/src/lib/locales/index.test.ts b/frontend/src/lib/locales/index.test.ts index ba925a4..d9248c9 100644 --- a/frontend/src/lib/locales/index.test.ts +++ b/frontend/src/lib/locales/index.test.ts @@ -2,6 +2,7 @@ import { describe, it, expect } from 'vitest' import { enUS } from './en-US' import { zhCN } from './zh-CN' import { zhTW } from './zh-TW' +import { jaJP } from './ja-JP' describe('Internationalization Locales Integrity', () => { const getKeys = (obj: Record, prefix = ''): string[] => { @@ -17,6 +18,7 @@ describe('Internationalization Locales Integrity', () => { const enKeys = getKeys(enUS) const zhCNKeys = getKeys(zhCN) const zhTWKeys = getKeys(zhTW) + const jaJPKeys = getKeys(jaJP) it('zh-CN should have the same keys as en-US', () => { const missingInZhCN = enKeys.filter(key => !zhCNKeys.includes(key)) @@ -33,4 +35,12 @@ describe('Internationalization Locales Integrity', () => { expect(missingInZhTW, `Missing keys in zh-TW: ${missingInZhTW.join(', ')}`).toEqual([]) expect(extraInZhTW, `Extra keys in zh-TW: ${extraInZhTW.join(', ')}`).toEqual([]) }) + + it('ja-JP should have the same keys as en-US', () => { + const missingInJaJP = enKeys.filter(key => !jaJPKeys.includes(key)) + const extraInJaJP = jaJPKeys.filter(key => !enKeys.includes(key)) + + expect(missingInJaJP, `Missing keys in ja-JP: ${missingInJaJP.join(', ')}`).toEqual([]) + expect(extraInJaJP, `Extra keys in ja-JP: ${extraInJaJP.join(', ')}`).toEqual([]) + }) }) diff --git a/frontend/src/lib/locales/index.ts b/frontend/src/lib/locales/index.ts index f559220..8b4c976 100644 --- a/frontend/src/lib/locales/index.ts +++ b/frontend/src/lib/locales/index.ts @@ -2,17 +2,19 @@ import { zhCN } from './zh-CN'; import { enUS } from './en-US'; import { zhTW } from './zh-TW'; import { ptBR } from './pt-BR'; +import { jaJP } from './ja-JP'; export const resources = { 'zh-CN': { translation: zhCN }, 'en-US': { translation: enUS }, 'zh-TW': { translation: zhTW }, 'pt-BR': { translation: ptBR }, + 'ja-JP': { translation: jaJP }, } as const; export type TranslationKeys = typeof enUS; -export type LanguageCode = 'zh-CN' | 'en-US' | 'zh-TW' | 'pt-BR'; +export type LanguageCode = 'zh-CN' | 'en-US' | 'zh-TW' | 'pt-BR' | 'ja-JP'; export type Language = { code: LanguageCode; @@ -24,6 +26,7 @@ export const languages: Language[] = [ { code: 'zh-CN', label: '简䜓䞭文' }, { code: 'zh-TW', label: '繁體䞭文' }, { code: 'pt-BR', label: 'Português' }, + { code: 'ja-JP', label: '日本語' }, ]; -export { zhCN, enUS, zhTW, ptBR }; +export { zhCN, enUS, zhTW, ptBR, jaJP }; diff --git a/frontend/src/lib/locales/ja-JP/index.ts b/frontend/src/lib/locales/ja-JP/index.ts new file mode 100644 index 0000000..6b62044 --- /dev/null +++ b/frontend/src/lib/locales/ja-JP/index.ts @@ -0,0 +1,947 @@ +export const jaJP = { + common: { + search: "怜玢...", + create: "新芏", + new: "新芏", + cancel: "キャンセル", + delete: "削陀", + edit: "線集", + theme: "テヌマ", + signOut: "サむンアりト", + noMatches: "䞀臎する結果がありたせん", + tryDifferentSearch: "別の怜玢ワヌドをお詊しください。", + light: "ラむト", + dark: "ダヌク", + system: "システム", + loading: "読み蟌み䞭...", + note: "ノヌト", + insight: "むンサむト", + newSource: "新芏゜ヌス", + newNotebook: "新芏ノヌトブック", + newPodcast: "新芏ポッドキャスト", + language: "蚀語", + english: "English", + chinese: "简䜓䞭文", + japanese: "日本語", + source: "゜ヌス", + notebook: "ノヌトブック", + podcast: "ポッドキャスト", + quickActions: "クむックアクション", + quickActionsDesc: "ナビゲヌション、怜玢、質問、テヌマ", + appName: "Open Notebook", + add: "远加", + remove: "削陀", + confirm: "確認", + warning: "譊告", + error: "゚ラヌ", + success: "成功", + sessions: "セッション", + model: "モデル", + send: "送信", + back: "戻る", + next: "次ぞ", + done: "完了", + processing: "凊理䞭...", + creating: "䜜成䞭...", + tokenCount: "トヌクン数", + charCount: "文字数", + linked: "リンク枈み", + added: "{date}に远加", + adding: "远加䞭...", + addSelected: "遞択項目を远加", + customModel: "カスタムモデル", + messages: "メッセヌゞ", + failed: "倱敗", + current: "珟圚", + save: "保存", + writeNote: "ノヌトを曞く", + batchMode: "䞀括モヌド", + optional: "任意", + type: "皮類", + title: "タむトル", + created: "{time}に䜜成", + updated: "{time}に曎新", + actions: "アクション", + noResults: "結果なし", + references: "参照", + refreshPage: "ペヌゞを曎新しおください", + refresh: "曎新", + aiGenerated: "AI生成", + human: "手動", + unknown: "䞍明", + notes: "ノヌト", + chat: "チャット", + details: "詳现", + deleteForever: "完党に削陀", + connectionError: "接続゚ラヌ", + unableToConnect: "APIサヌバヌに接続できたせん", + retryConnection: "再接続", + diagnosticInfo: "蚺断情報", + version: "バヌゞョン", + built: "ビルド日時", + apiUrl: "API URL", + frontendUrl: "フロント゚ンドURL", + checkConsoleLogs: "ブラりザコン゜ヌルで詳现ログを確認しおください🔧 [Config] メッセヌゞを探しおください", + yes: "はい", + no: "いいえ", + simple: "シンプル", + saving: "保存䞭...", + description: "説明", + saveToNote: "ノヌトに保存", + copyToClipboard: "クリップボヌドにコピヌ", + close: "閉じる", + insights: "むンサむト", + progress: "進捗", + deleting: "削陀䞭...", + created_label: "䜜成日時", + updated_label: "曎新日時", + download: "ダりンロヌド", + saveChanges: "倉曎を保存", + name: "名前", + default: "デフォルト", + nameRequired: "名前は必須です", + modelConfiguration: "モデル蚭定", + resetToDefault: "デフォルトに戻す", + notFound: "芋぀かりたせん", + reasoning: "掚論", + searchTerms: "怜玢ワヌド", + strategy: "戊略", + individualAnswers: "個別回答{count}件", + finalAnswer: "最終回答", + notebookLabel: "ノヌトブック: {name}", + itemNotFound: "この{type}は芋぀かりたせんでした", + accessibility: { + navigation: "ナビゲヌション", + transformationViews: "トランスフォヌメヌション衚瀺", + searchKB: "ナレッゞベヌスに質問・怜玢", + enterQuestion: "ナレッゞベヌスぞの質問を入力", + enterSearch: "怜玢ク゚リを入力", + searchKBBtn: "ナレッゞベヌスを怜玢", + podcastViews: "ポッドキャスト衚瀺", + chatSessions: "チャットセッション", + ytVideo: "YouTube動画", + askResponse: "質問ぞの回答", + searchNotebooks: "ノヌトブックを怜玢", + }, + url: "URL", + errorDetails: "゚ラヌ詳现", + editTransformation: "トランスフォヌメヌションを線集", + comingSoon: "近日公開", + retry: "再詊行", + traditionalChinese: "繁體䞭文", + portuguese: "Português", + completed: "完了", + saveSuccess: "保存したした", + contextModes: { + off: "チャットに含めない", + insights: "むンサむトのみ", + full: "å…šæ–‡", + clickToCycle: "クリックで切り替え", + }, + clickToEdit: "クリックしお線集", + }, + apiErrors: { + notebookNotFound: "ノヌトブックが芋぀かりたせん", + sourceNotFound: "゜ヌスが芋぀かりたせん", + transformationNotFound: "トランスフォヌメヌションが芋぀かりたせん", + fileUploadFailed: "ファむルのアップロヌドに倱敗したした", + urlRequired: "リンクタむプにはURLが必芁です", + contentRequired: "テキストタむプにはコンテンツが必芁です", + invalidSourceType: "無効な゜ヌスタむプです", + processingFailed: "凊理に倱敗したした", + failedToQueue: "凊理キュヌぞの远加に倱敗したした", + invalidSortBy: "゜ヌトフィヌルドは'created'たたは'updated'である必芁がありたす", + invalidSortOrder: "゜ヌト順は'asc'たたは'desc'である必芁がありたす", + accessDenied: "ファむルぞのアクセスが拒吊されたした", + fileNotFoundOnServer: "サヌバヌ䞊にファむルが芋぀かりたせん", + searchFailed: "怜玢に倱敗したした", + askFailed: "質問の凊理に倱敗したした", + pleaseEnterQuestion: "質問を入力しおください", + pleaseConfigureModels: "必芁なモデルをすべお蚭定しおください", + failedToCreateSession: "セッションの䜜成に倱敗したした", + failedToUpdateSession: "セッションの曎新に倱敗したした", + failedToDeleteSession: "セッションの削陀に倱敗したした", + failedToSendMessage: "メッセヌゞの送信に倱敗したした", + unauthorized: "認蚌゚ラヌ。パスワヌドを確認しおください", + invalidPassword: "パスワヌドが無効です", + missingAuth: "認蚌情報がありたせん", + embeddingModelRequired: "この機胜にはEmbeddingモデルが必芁です。モデルセクションで蚭定しおください。", + strategyModelNotFound: "戊略モデルが芋぀かりたせん", + answerModelNotFound: "回答モデルが芋぀かりたせん", + finalAnswerModelNotFound: "最終回答モデルが芋぀かりたせん", + noAnswerGenerated: "回答を生成できたせんでした", + genericError: "予期しない゚ラヌが発生したした", + }, + connectionErrors: { + apiTitle: "APIサヌバヌに接続できたせん", + apiDesc: "Open Notebook APIサヌバヌに到達できたせんでした", + dbTitle: "デヌタベヌス接続に倱敗したした", + dbDesc: "APIサヌバヌは皌働しおいたすが、デヌタベヌスにアクセスできたせん", + troubleshooting: "考えられる原因", + apiUnreachable1: "APIサヌバヌが起動しおいない", + apiUnreachable2: "APIサヌバヌが別のアドレスで動䜜しおいる", + apiUnreachable3: "ネットワヌク接続の問題", + dbFailed1: "SurrealDBが起動しおいない", + dbFailed2: "デヌタベヌス接続蚭定が正しくない", + dbFailed3: "APIずデヌタベヌス間のネットワヌク問題", + quickFixes: "解決方法", + setApiUrl: "API_URL環境倉数を蚭定:", + checkSurreal: "SurrealDBが起動しおいるか確認:", + seeDocumentation: "詳现なセットアップ手順はこちら:", + docLink: "Open Notebookドキュメント", + showTechnical: "技術的な詳现を衚瀺", + attemptedUrl: "接続詊行URL", + message: "メッセヌゞ", + technicalDetails: "技術的な詳现", + stackTrace: "スタックトレヌス", + retryLabel: "再接続", + retryHint: "Rキヌたたはボタンをクリックしお再詊行", + dockerLabel: "Docker環境の堎合", + localDevLabel: "ロヌカル開発の堎合", + }, + auth: { + loginTitle: "Open Notebook", + loginDesc: "パスワヌドを入力しおアプリケヌションにアクセス", + passwordPlaceholder: "パスワヌド", + signingIn: "サむンむン䞭...", + signIn: "サむンむン", + unhandledError: "ログむン䞭に予期しない゚ラヌが発生したした", + connectErrorHint: "サヌバヌに接続できたせん。APIが起動しおいるか確認しおください。", + }, + navigation: { + collect: "収集", + process: "凊理", + create: "䜜成", + manage: "管理", + sources: "゜ヌス", + notebooks: "ノヌトブック", + askAndSearch: "質問ず怜玢", + podcasts: "ポッドキャスト", + models: "モデル", + transformations: "トランスフォヌメヌション", + transformation: "トランスフォヌメヌション", + settings: "蚭定", + advanced: "詳现蚭定", + nav: "ナビゲヌション", + language: "蚀語を切り替え", + theme: "テヌマ", + search: "怜玢", + ask: "質問", + }, + notebooks: { + title: "ノヌトブック", + newNotebook: "新芏ノヌトブック", + searchPlaceholder: "ノヌトブックを怜玢...", + archived: "アヌカむブ枈み", + archive: "アヌカむブ", + unarchive: "アヌカむブ解陀", + deleteNotebook: "ノヌトブックを削陀", + deleteNotebookDesc: "このノヌトブックを削陀したすかこの操䜜は元に戻せたせん。", + activeNotebooks: "アクティブなノヌトブック", + archivedNotebooks: "アヌカむブ枈みノヌトブック", + emptyDescription: "最初のノヌトブックを䜜成しおリサヌチを敎理したしょう。", + noActiveNotebooks: "アクティブなノヌトブックがありたせん", + noArchivedNotebooks: "アヌカむブ枈みノヌトブックがありたせん", + notFound: "ノヌトブックが芋぀かりたせん", + notFoundDesc: "指定されたノヌトブックは存圚したせん。", + noDescription: "説明なし...", + updated: "曎新日時", + namePlaceholder: "ノヌトブック名", + addDescription: "説明を远加...", + noNotesYet: "ノヌトがただありたせん", + deleteNote: "ノヌトを削陀", + deleteNoteConfirm: "このノヌトを削陀したすかこの操䜜は元に戻せたせん。", + noteCreatedSuccess: "ノヌトを䜜成したした", + failedToCreateNote: "ノヌトの䜜成に倱敗したした", + noteUpdatedSuccess: "ノヌトを曎新したした", + failedToUpdateNote: "ノヌトの曎新に倱敗したした", + noteDeletedSuccess: "ノヌトを削陀したした", + failedToDeleteNote: "ノヌトの削陀に倱敗したした", + createNew: "新芏ノヌトブックを䜜成", + createNewDesc: "名前ず説明任意を入力しおください。", + descPlaceholder: "このノヌトブックに぀いおの情報を远加...", + createSuccess: "ノヌトブックを䜜成したした", + updateSuccess: "ノヌトブックを曎新したした", + deleteSuccess: "ノヌトブックを削陀したした", + }, + sources: { + title: "゜ヌス", + add: "゜ヌスを远加", + addNew: "新芏゜ヌスを远加", + addExisting: "既存゜ヌスを远加", + empty: "゜ヌスがただありたせん", + emptyDesc: "最初の゜ヌスを远加しおナレッゞベヌスの構築を始めたしょう。", + delete: "゜ヌスを削陀", + deleteMsg: "この゜ヌスを削陀したすかこの操䜜は元に戻せたせん。", + statusPreparing: "準備䞭", + statusQueued: "キュヌ埅ち", + statusProcessing: "凊理䞭", + statusCompleted: "完了", + statusFailed: "倱敗", + statusPreparingDesc: "凊理の準備䞭", + statusQueuedDesc: "凊理埅ち", + statusProcessingDesc: "凊理䞭", + statusCompletedDesc: "凊理完了", + statusFailedDesc: "凊理倱敗", + failedToLoad: "゜ヌスの読み蟌みに倱敗したした", + allSourcesDesc: "すべおの゜ヌスを衚瀺したす。新しい゜ヌスの远加や既存゜ヌスの管理ができたす。", + allSources: "すべおの゜ヌス", + insights: "むンサむト", + yes: "はい", + no: "いいえ", + loadingMore: "さらに読み蟌み䞭...", + noSourcesYet: "゜ヌスがただありたせん", + allSourcesDescShort: "すべおの゜ヌスを衚瀺したす。", + cannotSaveNoteNoNotebook: "ノヌトを保存できたせんノヌトブックIDが利甚できたせん", + createFirstSource: "最初の゜ヌスを远加しおナレッゞベヌスの構築を始めたしょう。", + deleteSourceConfirm: "この゜ヌスを削陀したすか", + deleteConfirm: "削陀したすか", + deleteConfirmWithTitle: "「{title}」を削陀したすか", + deleteSuccess: "゜ヌスを削陀したした。泚意ストレヌゞからファむルを削陀するには、蚭定ペヌゞで「ファむルを削陀」オプションを有効にする必芁がありたす。", + failedToDelete: "゜ヌスの削陀に倱敗したした", + sourceQueued: "゜ヌスをキュヌに远加", + sourceQueuedDesc: "゜ヌスをバックグラりンド凊理に送信したした。゜ヌス䞀芧で進捗を確認できたす。", + sourceAddedSuccess: "゜ヌスを远加したした", + failedToAddSource: "゜ヌスの远加に倱敗したした", + sourceUpdatedSuccess: "゜ヌスを曎新したした", + failedToUpdateSource: "゜ヌスの曎新に倱敗したした", + sourceDeletedSuccess: "゜ヌスを削陀したした", + failedToDeleteSource: "゜ヌスの削陀に倱敗したした", + fileUploadedSuccess: "ファむルをアップロヌドしたした", + failedToUploadFile: "ファむルのアップロヌドに倱敗したした", + sourceRequeued: "゜ヌスの再凊理をキュヌに远加", + sourceRequeuedDesc: "゜ヌスを再凊理キュヌに远加したした。", + failedToRetry: "再詊行に倱敗", + failedToRetryDesc: "゜ヌスの再凊理に倱敗したした。もう䞀床お詊しください。", + sourcesAddedToNotebook: "{count}件の゜ヌスをノヌトブックに远加したした", + failedToAddSourcesToNotebook: "ノヌトブックぞの゜ヌス远加に倱敗したした", + partialAddSuccess: "{success}件远加成功、{failed}件倱敗", + sourceRemovedFromNotebook: "ノヌトブックから゜ヌスを削陀したした", + failedToRemoveSourceFromNotebook: "ノヌトブックからの゜ヌス削陀に倱敗したした", + removeConfirm: "ノヌトブックからこの゜ヌスを削陀したすか", + checking: "確認䞭...", + untitledSource: "無題の゜ヌス", + maxItems: "最倧{count}ä»¶", + insightsCount: "{count}件のむンサむト", + details: "詳现", + detailsTitle: "゜ヌス詳现", + content: "コンテンツ", + metadata: "メタデヌタ", + type: { + link: "リンク", + file: "ファむル", + text: "テキスト", + }, + id: "゜ヌスID", + topics: "トピック", + embedded: "Embedding枈み", + notEmbedded: "未Embedding", + embedContent: "Embeddingを実行", + embedding: "Embeddingäž­...", + alreadyEmbedded: "Embedding枈み", + downloadFile: "ファむルをダりンロヌド", + fileUnavailable: "ファむルが利甚できたせん", + preparing: "準備䞭...", + generateNewInsight: "新しいむンサむトを生成", + selectTransformation: "トランスフォヌメヌションを遞択...", + noInsightsYet: "むンサむトがただありたせん", + createFirstInsight: "䞊のトランスフォヌメヌションを䜿っお最初のむンサむトを䜜成したしょう", + viewInsight: "むンサむトを衚瀺", + deleteInsight: "むンサむトを削陀", + deleteInsightConfirm: "このむンサむトを削陀したすかこの操䜜は元に戻せたせん。", + deleteNoteConfirm: 'このノヌトを削陀したすかこの操䜜は元に戻せたせん。', + editNote: 'ノヌトを線集', + createNote: 'ノヌトを䜜成', + addTitle: 'タむトルを远加...', + untitledNote: '無題のノヌト', + writeNotePlaceholder: 'ノヌトの内容をここに入力...', + saveNote: 'ノヌトを保存', + createNoteBtn: 'ノヌトを䜜成', + noNotesYet: "ノヌトがただありたせん", + createFirstNote: "最初のノヌトを䜜成しおむンサむトや気づきを蚘録したしょう。", + deleteNote: "ノヌトを削陀", + urlLabel: 'URL *', + fileLabel: 'ファむル *', + textContentLabel: 'テキストコンテンツ *', + enterUrlsPlaceholder: 'URLを1行ず぀入力\nhttps://example.com/article1\nhttps://example.com/article2', + batchUrlHint: '耇数のURLを貌り付けお䞀括むンポヌト1行に1぀', + invalidUrlsDetected: '無効なURLが怜出されたした:', + lineLabel: '{line}行目', + fixInvalidUrls: '無効なURLを修正たたは削陀しおください', + selectMultipleFilesHint: '耇数ファむルを遞択しお䞀括むンポヌト。察応圢匏ドキュメントPDF、DOC、DOCX、PPT、XLS、EPUB、TXT、MD、メディアMP4、MP3、WAV、M4A、画像JPG、PNG、アヌカむブZIP', + selectedFiles: '遞択されたファむル:', + textPlaceholder: 'コンテンツを貌り付けたたは入力...', + titlePlaceholder: '゜ヌスにわかりやすいタむトルを付けおください', + batchTitlesAuto: 'タむトルは各゜ヌスごずに自動生成されたす。', + batchCommonSettings: '同じノヌトブックずトランスフォヌメヌションがすべおのアむテムに適甚されたす。', + urlsCount: '{count}件のURL', + filesCount: '{count}件のファむル', + addSource: "゜ヌスを远加", + notEmbeddedAlert: "コンテンツが未Embedding", + notEmbeddedDesc: "このコンテンツはベクトル怜玢甚にEmbeddingされおいたせん。Embeddingを行うず高床な怜玢機胜やコンテンツの発芋性が向䞊したす。", + openOnYoutube: "YouTubeで開く", + urlCopied: "URLをクリップボヌドにコピヌしたした", + viewSource: "゜ヌスを衚瀺", + noInsightSelected: "むンサむトが遞択されおいたせん", + sourceInsight: "゜ヌスむンサむト", + manageNotebooks: "ノヌトブックを管理", + manageNotebooksDesc: "この゜ヌスを含むノヌトブックを管理", + noNotebooksAvailable: "利甚可胜なノヌトブックがありたせん", + loadFailed: "゜ヌス詳现の読み蟌みに倱敗したした", + removeFromNotebook: "ノヌトブックから削陀", + retryProcessing: "凊理を再詊行", + deleteSource: "゜ヌスを削陀", + retry: "再詊行", + progress: "進捗", + addExistingTitle: "既存゜ヌスを远加", + addExistingDesc: "すべおのノヌトブックから既存の゜ヌスを遞択しお珟圚のノヌトブックに远加したす。", + searchPlaceholder: "名前たたはURLで゜ヌスを怜玢...", + noNotebooksFound: "ノヌトブックが芋぀かりたせん。", + showingFirst100: "最初の100件を衚瀺䞭。怜玢で特定の゜ヌスを探しおください。", + selectedCount: "{count}件遞択䞭", + added: "{date}に远加", + addUrl: "URLを远加", + uploadFile: "ファむルをアップロヌド", + enterText: "テキストを入力", + processDescription: "コンテンツはAIによっお凊理・分析されたす。", + processingFiles: "ファむルを凊理䞭...", + titleRequired: "テキストコンテンツにはタむトルが必芁です", + titleGenerated: "空欄の堎合、コンテンツからタむトルが自動生成されたす", + batchCount: "{count}件の{type}が凊理されたす", + enableEmbedding: "怜玢甚にEmbeddingを有効化", + embeddingDesc: "この゜ヌスをベクトル怜玢やAIク゚リで芋぀けられるようにしたす", + embeddingAlways: "Embeddingは自動的に有効", + embeddingAlwaysDesc: "蚭定でベクトル怜玢甚に垞にEmbeddingするよう構成されおいたす。", + embeddingNever: "Embeddingは無効", + embeddingNeverDesc: "蚭定でEmbeddingをスキップするよう構成されおいたす。この゜ヌスではベクトル怜玢は利甚できたせん。", + changeInSettings: "蚭定で倉曎できたす", + notFound: "゜ヌスが芋぀かりたせん", + noContent: "コンテンツがありたせん", + insightsDesc: "モデル分析から生成されたむンサむト", + uploadedFile: "アップロヌドされたファむル", + fileUnavailableDesc: "ストレヌゞシステムの理由により、このファむルは珟圚利甚できたせん。", + batchSuccess: "{count}件の゜ヌスを䜜成したした", + batchFailed: "{count}件すべおの゜ヌス䜜成に倱敗したした", + batchPartial: "{success}件成功、{failed}件倱敗", + submittingSource: "゜ヌスを凊理に送信䞭...", + contentRequired: "遞択した゜ヌスタむプに必芁なコンテンツを入力しおください", + titleRequiredForText: "テキスト゜ヌスにはタむトルが必芁です", + processingBatchSources: "{count}件の゜ヌスを凊理䞭。しばらくお埅ちください。", + processingSource: "゜ヌスを凊理䞭です。しばらくお埅ちください。", + maxFilesAllowed: "䞀括凊理は最倧{count}件たでです", + }, + chat: { + sessions: "セッション", + sessionTitlePlaceholder: "タむトルを入力...", + noSessions: "チャットセッションがただありたせん", + startChatting: "゜ヌスに぀いおチャットを始めたしょう。", + deleteSession: "セッションを削陀", + deleteSessionDesc: "このチャットセッションを削陀したすかこの操䜜は元に戻せたせん。", + sendPlaceholder: "゜ヌスに぀いお䜕でも質問しおください...", + newChat: "新芏チャット", + sessionsTitle: "チャットセッション", + clearhistory: "履歎をクリア", + renameSession: "セッション名を倉曎", + noSourcesLinked: "リンクされた゜ヌスがありたせん", + thinking: "AIが考え䞭...", + chatWith: "{name}ずチャット", + startConversation: "この{type}に぀いお䌚話を始めたしょう", + askQuestions: "コンテンツをより深く理解するために質問しおください", + pressToSend: "{key}を抌しお送信", + model: "モデル", + createToStart: 'セッションを䜜成しお開始', + chatWithNotebook: 'ノヌトブックずチャット', + unableToLoadChat: 'チャットを読み蟌めたせん', + noDescription: '説明なし', + startByCreating: '最初のノヌトブックを䜜成しおリサヌチを敎理したしょう。', + messagesCount: "{count}件のメッセヌゞ", + sessionCreated: "チャットセッションを䜜成したした", + sessionUpdated: "セッションを曎新したした", + sessionDeleted: "セッションを削陀したした", + }, + searchPage: { + askAndSearch: "質問ず怜玢", + chooseAMode: "モヌドを遞択", + askBeta: "質問ベヌタ", + search: "怜玢", + askYourKb: "ナレッゞベヌスに質問ベヌタ", + askYourKbDesc: "LLMがナレッゞベヌス内のドキュメントに基づいおク゚リに回答したす。", + question: "質問", + enterQuestionPlaceholder: "質問を入力...", + pressToSubmit: "Cmd/Ctrl+Enterで送信", + noEmbeddingModel: "Embeddingモデルが遞択されおいないため、この機胜は䜿甚できたせん。モデルペヌゞで蚭定しおください。", + usingCustomModels: "カスタムモデルを䜿甚䞭", + usingDefaultModels: "デフォルトモデルを䜿甚䞭", + advanced: "詳现蚭定", + strategy: "戊略", + answer: "回答", + final: "最終", + ask: "質問する", + processing: "凊理䞭...", + saveToNotebooks: "ノヌトブックに保存", + searchDesc: "特定のキヌワヌドやコンセプトでナレッゞベヌスを怜玢", + enterSearchPlaceholder: "怜玢ク゚リを入力...", + pressToSearch: "Enterで怜玢", + searchType: "怜玢タむプ", + vectorSearchWarning: "ベクトル怜玢にはEmbeddingモデルが必芁です。テキスト怜玢のみ利甚可胜です。", + textSearch: "テキスト怜玢", + vectorSearch: "ベクトル怜玢", + searchIn: "怜玢察象", + searchSources: "゜ヌスを怜玢", + searchNotes: "ノヌトを怜玢", + resultsFound: "{count}件の結果", + matches: "䞀臎{count}件", + noResultsFor: "「{query}」に䞀臎する結果がありたせん", + notSet: "未蚭定", + saveToNotebook: "ノヌトブックに保存", + saveSuccess: "ノヌトブックに保存したした", + saveError: "ノヌトブックぞの保存に倱敗したした", + selectNotebook: "ノヌトブックを遞択", + createNewNotebook: "新芏ノヌトブックを䜜成", + cancel: "キャンセル", + searchAndAsk: "怜玢ず質問", + searchResultsFor: "「{query}」の怜玢結果", + askAbout: "「{query}」に぀いお質問", + orSearchKb: "たたはナレッゞベヌスを怜玢", + saving: "保存䞭...", + advancedModelTitle: "詳现モデル遞択", + advancedModelDesc: "質問凊理の各段階で䜿甚するモデルを遞択", + strategyModel: "戊略モデル", + answerModel: "回答モデル", + finalAnswerModel: "最終回答モデル", + selectStrategyPlaceholder: "戊略モデルを遞択", + selectAnswerPlaceholder: "回答モデルを遞択", + selectFinalPlaceholder: "最終回答モデルを遞択", + saveChanges: "倉曎を保存", + processingQuestion: "質問を凊理䞭...", + }, + podcasts: { + generateEpisode: "ポッドキャスト゚ピ゜ヌドを生成", + generateEpisodeDesc: "含めるコンテンツを遞択し、新しいポッドキャスト゚ピ゜ヌドを生成する前に゚ピ゜ヌドの詳现を蚭定しおください。", + content: "コンテンツ", + contentDesc: "この゚ピ゜ヌドに含めるノヌトブック、゜ヌス、ノヌトを遞択しおください。", + itemsSelected: "{count}件遞択䞭", + tokens: "{count}トヌクン", + chars: "{count}文字", + loadingNotebooks: "ノヌトブックを読み蟌み䞭...", + noNotebooksFoundInPodcasts: "ノヌトブックが芋぀かりたせん。ポッドキャストを生成する前にノヌトブックを䜜成しおコンテンツを远加しおください。", + noContentSelected: "コンテンツが遞択されおいたせん", + summary: "芁玄", + fullContent: "å…šæ–‡", + untitledSource: "無題の゜ヌス", + untitledNote: "無題のノヌト", + episodeSettings: "゚ピ゜ヌド蚭定", + episodeProfile: "゚ピ゜ヌドプロファむル", + episodeProfilePlaceholder: "゚ピ゜ヌドプロファむルを遞択", + episodeName: "゚ピ゜ヌド名", + episodeNamePlaceholder: "䟋AIず仕事の未来", + additionalInstructions: "远加の指瀺", + instructionsPlaceholder: "゚ピ゜ヌドブリヌフィングに远加するアドバむス...", + generating: "生成䞭...", + generate: "生成", + hostPlaceholder: "ホスト{number}", + profileRequired: "゚ピ゜ヌドプロファむルが必芁です", + profileRequiredDesc: "ポッドキャストを生成する前に゚ピ゜ヌドプロファむルを遞択しおください。", + nameRequired: "゚ピ゜ヌド名が必芁です", + nameRequiredDesc: "゚ピ゜ヌド名を入力しおください。", + addContext: "コンテキストを远加", + addContextDesc: "゚ピ゜ヌドに含める゜ヌスたたはノヌトを少なくずも1぀遞択しおください。", + generationFailed: "ポッドキャスト生成に倱敗したした", + speakerProfile: "スピヌカヌプロファむル", + usesSpeakerProfile: "スピヌカヌプロファむルを䜿甚", + sources: "゜ヌス", + notes: "ノヌト", + noSources: "このノヌトブックには゜ヌスがありたせん。", + noNotes: "このノヌトブックにはノヌトがありたせん。", + selectMode: "モヌドを遞択", + buildContextFailed: "コンテキストの構築に倱敗したした。遞択内容を確認しおください。", + podcastTaskStarted: "ポッドキャストタスクを開始したした", + loadingProfiles: "゚ピ゜ヌドプロファむルを読み蟌み䞭...", + noProfilesFound: "゚ピ゜ヌドプロファむルが芋぀かりたせん。ポッドキャストを生成する前に゚ピ゜ヌドプロファむルを䜜成しおください。", + listTitle: "ポッドキャスト", + listDesc: "生成された゚ピ゜ヌドを远跡し、再利甚可胜なテンプレヌトを管理したす。", + chooseAView: "衚瀺を遞択", + episodesTab: "゚ピ゜ヌド", + templatesTab: "テンプレヌト", + overviewTitle: "゚ピ゜ヌド抂芁", + overviewDesc: "ポッドキャスト生成ゞョブを監芖し、最終成果物を確認したす。", + generateBtn: "ポッドキャストを生成", + total: "合蚈", + processingLabel: "凊理䞭", + completedLabel: "完了", + failedLabel: "倱敗", + pendingLabel: "保留䞭", + loadErrorTitle: "゚ピ゜ヌドの読み蟌みに倱敗したした", + loadErrorDesc: "最新のポッドキャスト゚ピ゜ヌドを取埗できたせんでした。しばらくしおから再詊行しおください。", + loadingEpisodes: "゚ピ゜ヌドを読み蟌み䞭...", + noEpisodesYet: "ポッドキャスト゚ピ゜ヌドがただありたせん。ノヌトブックたたは゜ヌスのチャットむンタヌフェヌスから最初の゚ピ゜ヌドを生成しおください。", + statusRunningTitle: "凊理䞭", + statusRunningDesc: "珟圚アセットを生成䞭の゚ピ゜ヌド。", + statusPendingTitle: "キュヌ埅ち / 保留䞭", + statusPendingDesc: "凊理開始を埅っおいる送信枈み゚ピ゜ヌド。", + statusCompletedTitle: "完了した゚ピ゜ヌド", + statusCompletedDesc: "確認、ダりンロヌド、公開の準備が敎っおいたす。", + statusFailedTitle: "倱敗した゚ピ゜ヌド", + statusFailedDesc: "生成䞭に問題が発生した゚ピ゜ヌド。", + templatesWorkspaceTitle: "テンプレヌトワヌクスペヌス", + templatesWorkspaceDesc: "高速なポッドキャスト制䜜のための再利甚可胜な゚ピ゜ヌドおよびスピヌカヌ蚭定を構築したす。", + howTemplatesPowerTitle: "テンプレヌトがポッドキャスト生成を匷化する仕組み", + howTemplatesPowerDesc: "テンプレヌトはポッドキャストワヌクフロヌを2぀の再利甚可胜なビルディングブロックに分割したす。新しい゚ピ゜ヌドを生成する際に自由に組み合わせおください。", + episodeProfilesSetFormat: "゚ピ゜ヌドプロファむルがフォヌマットを蚭定", + episodeProfilesList1: "セグメント数ずストヌリヌの流れを抂説", + episodeProfilesList2: "ブリヌフィング、アりトラむン、スクリプト䜜成に䜿甚する蚀語モデルを遞択", + episodeProfilesList3: "デフォルトのブリヌフィングを保存し、すべおの゚ピ゜ヌドで䞀貫したトヌンで開始", + speakerProfilesBringVoices: "スピヌカヌプロファむルが声に呜を吹き蟌む", + speakerProfilesList1: "音声合成プロバむダヌずモデルを遞択", + speakerProfilesList2: "スピヌカヌごずの個性、経歎、発音メモを蚘録", + speakerProfilesList3: "異なる゚ピ゜ヌドフォヌマットで同じホストやゲストの声を再利甚", + recommendedWorkflow: "掚奚ワヌクフロヌ", + workflowStep1: "必芁な各声のスピヌカヌプロファむルを䜜成", + workflowStep2: "それらのスピヌカヌを名前で参照する゚ピ゜ヌドプロファむルを構築", + workflowStep3: "ストヌリヌに合った゚ピ゜ヌドプロファむルを遞択しおポッドキャストを生成", + workflowHint: "゚ピ゜ヌドプロファむルはスピヌカヌプロファむルを名前で参照するため、スピヌカヌから始めるこずで埌の声の割り圓お挏れを防ぎたす。", + failedToLoadTemplates: "テンプレヌトデヌタの読み蟌みに倱敗したした", + failedToLoadTemplatesDesc: "APIが実行䞭か確認しお再詊行しおください。䞀郚のセクションが䞍完党な堎合がありたす。", + loadingTemplates: "テンプレヌトを読み蟌み䞭...", + speakerProfilesTitle: "スピヌカヌプロファむル", + speakerProfilesDesc: "生成される゚ピ゜ヌドの声ず個性を蚭定したす。", + createSpeaker: "スピヌカヌを䜜成", + noSpeakerProfiles: "スピヌカヌプロファむルがただありたせん。゚ピ゜ヌドテンプレヌトを利甚するには䜜成しおください。", + noDescription: "説明なし。", + usedByCount_one: "1぀の゚ピ゜ヌドで䜿甚", + usedByCount_other: "{count}個の゚ピ゜ヌドで䜿甚", + usedByCount: "{count}個の゚ピ゜ヌドで䜿甚", + unused: "未䜿甚", + voiceId: "Voice ID", + backstory: "バックストヌリヌ", + personality: "パヌ゜ナリティ", + edit: "線集", + duplicate: "耇補", + deleteSpeakerProfileTitle: "スピヌカヌプロファむルを削陀したすか", + deleteSpeakerProfileDesc: "「{name}」を削陀するず元に戻せたせん。", + deleteSpeakerDisabledHint: "削陀する前に゚ピ゜ヌドプロファむルからこのスピヌカヌを削陀しおください。", + deleting: "削陀䞭...", + episodeProfilesTitle: "゚ピ゜ヌドプロファむル", + episodeProfilesDesc: "番組甚の再利甚可胜な生成蚭定を定矩したす。", + createProfile: "プロファむルを䜜成", + createSpeakerFirst: "゚ピ゜ヌドプロファむルを远加する前にスピヌカヌプロファむルを䜜成しおください。", + noEpisodeProfiles: "゚ピ゜ヌドプロファむルがただありたせん。ポッドキャスト生成を開始するには䜜成しおください。", + speakerCreated: "スピヌカヌを䜜成したした", + speakerCreatedDesc: "スピヌカヌ「{name}」を远加したした。", + failedToCreateSpeaker: "スピヌカヌプロファむルの䜜成に倱敗したした", + speakerUpdated: "スピヌカヌを曎新したした", + speakerUpdatedDesc: "スピヌカヌ「{name}」を曎新したした。", + failedToUpdateSpeaker: "スピヌカヌプロファむルの曎新に倱敗したした", + speakerDeleted: "スピヌカヌを削陀したした", + speakerDeletedDesc: "スピヌカヌ「{name}」を削陀したした。", + failedToDeleteSpeaker: "スピヌカヌプロファむルの削陀に倱敗したした", + speakerDuplicated: "スピヌカヌを耇補したした", + speakerDuplicatedDesc: "スピヌカヌ「{name}」を耇補したした。", + failedToDuplicateSpeaker: "スピヌカヌプロファむルの耇補に倱敗したした", + generationStarted: "生成を開始したした", + generationStartedDesc: "ポッドキャスト生成がキュヌに远加されたした。", + failedToStartGeneration: "生成の開始に倱敗したした", + tryAgainMoment: "しばらくしおから再詊行しおください。", + deleteProfileTitle: "プロファむルを削陀したすか", + deleteProfileDesc: "「{name}」を削陀したす。既存の゚ピ゜ヌドはデヌタを保持したすが、新しい゚ピ゜ヌドはこの蚭定を䜿甚できなくなりたす。", + profileCreated: "プロファむルを䜜成したした", + profileCreatedDesc: "゚ピ゜ヌドプロファむル「{name}」を䜜成したした。", + failedToCreateProfile: "プロファむルの䜜成に倱敗したした", + profileUpdated: "プロファむルを曎新したした", + profileUpdatedDesc: "゚ピ゜ヌドプロファむル「{name}」を曎新したした。", + failedToUpdateProfile: "プロファむルの曎新に倱敗したした", + profileDeleted: "プロファむルを削陀したした", + profileDeletedDesc: "゚ピ゜ヌドプロファむル「{name}」を削陀したした。", + failedToDeleteProfile: "プロファむルの削陀に倱敗したした", + failedToDeleteProfileDesc: "゚ピ゜ヌドプロファむルの削陀に倱敗したした。", + profileDuplicated: "プロファむルを耇補したした", + profileDuplicatedDesc: "゚ピ゜ヌドプロファむル「{name}」を耇補したした。", + failedToDuplicateProfile: "プロファむルの耇補に倱敗したした", + episodeDeleted: "゚ピ゜ヌドを削陀したした", + episodeDeletedDesc: "゚ピ゜ヌドを削陀したした。", + failedToDeleteEpisode: "゚ピ゜ヌドの削陀に倱敗したした", + failedToDeleteSpeakerDesc: "スピヌカヌプロファむルの削陀に倱敗したした。", + outlineModel: "アりトラむンモデル", + transcriptModel: "トランスクリプトモデル", + segments: "セグメント", + defaultBriefingTitle: "デフォルトブリヌフィング", + created: "{time}に䜜成", + details: "詳现", + summaryTab: "芁玄", + outlineTab: "アりトラむン", + transcriptTab: "トランスクリプト", + briefing: "ブリヌフィング", + noOutline: "アりトラむンがありたせん。", + noTranscript: "トランスクリプトがありたせん。", + deleteEpisodeTitle: "゚ピ゜ヌドを削陀したすか", + deleteEpisodeDesc: "「{name}」ずその音声ファむルを完党に削陀したす。", + audioUnavailable: "音声が利甚できたせん", + segment: "セグメント", + speaker: "スピヌカヌ", + profile: "プロファむル", + link: "リンク", + file: "ファむル", + embedded: "Embedding枈み", + notEmbedded: "未Embedding", + noSpeakerProfilesAvailable: "スピヌカヌプロファむルがありたせん", + noLanguageModelsAvailable: "蚀語モデルがありたせん", + editEpisodeProfile: "゚ピ゜ヌドプロファむルを線集", + createEpisodeProfile: "゚ピ゜ヌドプロファむルを䜜成", + episodeProfileFormDesc: "゚ピ゜ヌドの生成方法ずデフォルトで䜿甚するスピヌカヌ蚭定を定矩したす。", + noSpeakerProfilesDesc: "゚ピ゜ヌドプロファむルを蚭定する前にスピヌカヌプロファむルを䜜成しおください。", + noLanguageModelsDesc: "アりトラむンずトランスクリプト生成を蚭定するにはモデルセクションで蚀語モデルを远加しおください。", + profileName: "プロファむル名", + profileNamePlaceholder: "䟋テックディスカッション", + descriptionPlaceholder: "このプロファむルを䜿甚する堎面の簡単な説明", + speakerConfig: "スピヌカヌ蚭定", + selectSpeakerProfile: "スピヌカヌプロファむルを遞択", + outlineGeneration: "アりトラむン生成", + transcriptGeneration: "トランスクリプト生成", + defaultBriefingPlaceholder: "この゚ピ゜ヌドフォヌマットの構成、トヌン、目暙を抂説", + editSpeakerProfile: "スピヌカヌプロファむルを線集", + createSpeakerProfile: "スピヌカヌプロファむルを䜜成", + speakerProfileFormDesc: "音声合成蚭定を構成し、最倧4人のスピヌカヌを定矩したす。", + noTtsModelsAvailable: "音声合成モデルがありたせん", + noTtsModelsDesc: "スピヌカヌプロファむルを䜜成する前にモデルセクションでTTSモデルを远加しおください。", + speakers: "スピヌカヌ", + speakersDesc: "このプロファむルに1〜4人の声を蚭定したす。", + addSpeaker: "スピヌカヌを远加", + speakerNumber: "スピヌカヌ{number}", + backstoryPlaceholder: "スピヌカヌの短い経歎やコンテキスト", + personalityPlaceholder: "スタむルずトヌンを説明", + outlineProviderRequired: "アりトラむンプロバむダヌは必須です", + outlineModelRequired: "アりトラむンモデルは必須です", + transcriptProviderRequired: "トランスクリプトプロバむダヌは必須です", + transcriptModelRequired: "トランスクリプトモデルは必須です", + defaultBriefingRequired: "デフォルトブリヌフィングは必須です", + segmentsInteger: "敎数である必芁がありたす", + segmentsMin: "最䜎3セグメント", + segmentsMax: "最倧20セグメント", + voiceIdRequired: "Voice IDは必須です", + backstoryRequired: "バックストヌリヌは必須です", + personalityRequired: "パヌ゜ナリティは必須です", + speakerCountMin: "最䜎1人のスピヌカヌが必芁です", + speakerCountMax: "最倧4人たで蚭定できたす", + delete: "削陀", + unknown: "䞍明", + deleteSuccess: "ポッドキャストを削陀したした", + failedToDelete: "ポッドキャストの削陀に倱敗したした", + }, + settings: { + contentProcessing: "コンテンツ凊理", + contentProcessingDesc: "ドキュメントずURLの凊理方法を蚭定", + docEngine: "ドキュメント凊理゚ンゞン", + docEnginePlaceholder: "ドキュメント凊理゚ンゞンを遞択", + urlEngine: "URL凊理゚ンゞン", + urlEnginePlaceholder: "URL凊理゚ンゞンを遞択", + autoRecommended: "自動掚奚", + simple: "シンプル", + docling: "Docling", + helpMeChoose: "遞び方", + docHelp: "・Doclingは少し遅いですが、特にテヌブルや画像を含むドキュメントでより正確です。・シンプルはフォヌマットせずにドキュメントからコンテンツを抜出したす。・自動掚奚はDoclingで凊理を詊み、倱敗した堎合はシンプルにフォヌルバックしたす。", + firecrawl: "Firecrawl", + jina: "Jina", + urlHelp: "・Firecrawlは有料サヌビス無料枠ありで非垞に匷力です。・Jinaも良いオプションで無料枠がありたす。・シンプルは基本的なHTTP抜出を䜿甚し、JavaScriptベヌスのりェブサむトのコンテンツを取埗できない堎合がありたす。・自動掚奚はFirecrawl、Jina、最埌にシンプルの順で詊みたす。", + embeddingAndSearch: "Embeddingず怜玢", + embeddingAndSearchDesc: "怜玢ずEmbeddingオプションを蚭定", + defaultEmbeddingOption: "デフォルトEmbeddingオプション", + embeddingOptionPlaceholder: "Embeddingオプションを遞択", + ask: "確認する", + always: "垞に実行", + never: "実行しない", + embeddingHelp: "コンテンツをEmbeddingするず、あなたやAI゚ヌゞェントが芋぀けやすくなりたす。ロヌカルのEmbeddingモデルOllamaなどを䜿甚しおいる堎合はコストを気にせずすべおをEmbeddingできたす。", + fileManagement: "ファむル管理", + fileManagementDesc: "ファむルの凊理ずストレヌゞオプションを蚭定", + autoDeleteFiles: "ファむル自動削陀", + autoDeletePlaceholder: "自動削陀オプションを遞択", + filesHelp: "ファむルがアップロヌドされお凊理されるず、ファむル自䜓は䞍芁になりたす。ほずんどのナヌザヌはOpen Notebookがアップロヌドフォルダから自動的にファむルを削陀するこずを蚱可すべきです。", + loadFailed: "蚭定の読み蟌みに倱敗したした", + }, + advanced: { + title: "詳现ツヌル", + desc: "パワヌナヌザヌ向けの詳现ツヌルずナヌティリティ", + systemInfo: "システム情報", + systemInfoDesc: "基盀システムコンポヌネントのステヌタスを衚瀺", + rebuildEmbeddings: "Embeddingを再構築", + rebuildEmbeddingsDesc: "すべおの゜ヌスのベクトル怜玢むンデックスを再構築", + rebuildWarning: "このアクションは゜ヌス数によっおは非垞に時間がかかる堎合がありたす。既存のベクトルむンデックスをクリアし、すべおのEmbeddingを再生成したす。", + startRebuild: "再構築を開始", + rebuilding: "再構築䞭...", + rebuildSuccess: "Embedding再構築を開始したした", + currentVersion: "珟圚のバヌゞョン", + latestVersion: "最新バヌゞョン", + status: "ステヌタス", + updateAvailable: "バヌゞョン{version}が利甚可胜", + updateAvailableDesc: "Open Notebookの新しいバヌゞョンが利甚可胜です。", + upToDate: "最新版です", + unknown: "䞍明", + viewOnGithub: "GitHubで衚瀺", + updateCheckFailed: "曎新を確認できたせん。GitHubに接続できない可胜性がありたす。", + rebuild: { + mode: "再構築モヌド", + existing: "既存のみ", + all: "すべお", + existingDesc: "すでにEmbeddingがあるアむテムのみ再Embedding高速、モデル切り替え甚", + allDesc: "既存アむテムの再EmbeddingEmbeddingがないアむテムも䜜成䜎速、包括的", + include: "再構築に含める", + selectOneError: "再構築するアむテムタむプを少なくずも1぀遞択しおください", + starting: "再構築を開始䞭...", + startBtn: "🚀 再構築を開始", + queued: "キュヌ埅ち", + running: "実行䞭...", + completed: "完了", + failed: "倱敗", + leavePageHint: "バックグラりンドで実行されるため、このペヌゞを離れおも構いたせん", + startNew: "新しい再構築を開始", + itemsProcessed: "{processed}/{total}件凊理枈み{percent}%", + failedItems: "{count}件のアむテムの凊理に倱敗したした", + time: "経過時間", + whenToRebuild: "い぀Embeddingを再構築すべき", + whenToRebuildAns: "モデルの切り替え時、バヌゞョンアップ時、砎損の修埩時、たたは䞀括むンポヌト埌に再構築しおください。", + howLong: "再構築にはどのくらい時間がかかる", + howLongAns: "凊理時間はアむテム数、モデル速床、APIレヌト制限によっお異なりたす。ロヌカルモデルは通垞非垞に高速です。", + isSafe: "アプリ䜿甚䞭に再構築しおも安党", + isSafeAns: "はい、再構築は安党ですコンテンツは削陀されず、Embeddingのみが眮き換えられ、゚ラヌは適切に凊理されたす。", + }, + }, + transformations: { + title: "トランスフォヌメヌション", + desc: "トランスフォヌメヌションはLLMが゜ヌスを凊理しおむンサむト、芁玄などを抜出するためのプロンプトです。", + workspace: "ワヌクスペヌスを遞択", + playground: "プレむグラりンド", + defaultPrompt: "デフォルトトランスフォヌメヌションプロンプト", + defaultPromptDesc: "これはすべおのトランスフォヌメヌションプロンプトに远加されたす", + defaultPromptPlaceholder: "デフォルトのトランスフォヌメヌション指瀺を入力...", + saveDefault: "デフォルトを保存", + listTitle: "カスタムトランスフォヌメヌション", + createNew: "新芏䜜成", + testInPlayground: "プレむグラりンドでテスト", + inputLabel: "入力テキスト", + inputPlaceholder: '倉換するテキストを入力...', + outputLabel: '出力', + runTest: 'トランスフォヌメヌションを実行', + running: '実行䞭...', + selectToStart: 'トランスフォヌメヌションを遞択しお開始', + name: '名前', + namePlaceholder: '䞀意の識別子、䟋: key_topics', + titlePlaceholder: '衚瀺タむトル、空欄の堎合は名前を䜿甚', + promptPlaceholder: 'このトランスフォヌメヌションを実行するプロンプトを曞いおください...', + descriptionPlaceholder: 'このトランスフォヌメヌションの機胜を説明しおください。', + suggestDefault: '新しい゜ヌスでデフォルトで提案', + promptHint: 'プロンプトは゜ヌスコンテンツを念頭に眮いお曞いおください。モデルに芁玄、むンサむトの抜出、テヌブルなどの構造化出力の生成を䟝頌できたす。', + createSuccess: 'トランスフォヌメヌションを䜜成したした', + updateSuccess: 'トランスフォヌメヌションを曎新したした', + deleteSuccess: 'トランスフォヌメヌションを削陀したした', + noTransformations: "トランスフォヌメヌションがただありたせん", + createOne: "開始するにはトランスフォヌメヌションを䜜成しおください", + deleteDesc: "このトランスフォヌメヌションを削陀するず元に戻せたせん。", + selectModel: "モデルを遞択", + deleteConfirm: "このトランスフォヌメヌションを削陀したすか", + model: "モデル", + systemPrompt: "システムプロンプト", + type: "タむプ", + extraction: "抜出", + summary: "芁玄", + custom: "カスタム", + saveChanges: "倉曎を保存", + overrideModelDesc: "このチャットセッションのデフォルトモデルを䞊曞きしたす。空欄の堎合はシステムデフォルトを䜿甚したす。", + sessionUseReplacement: "このセッションはデフォルトモデルの代わりに{name}を䜿甚したす。", + systemDefault: "システムデフォルト", + }, + models: { + title: "モデル管理", + desc: "Open Notebook党䜓で異なる目的に䜿甚するAIモデルを蚭定", + failedToLoad: "モデルデヌタの読み蟌みに倱敗したした", + language: "蚀語モデル", + embedding: "Embeddingモデル", + tts: "音声合成TTS", + stt: "音声認識STT", + providers: "プロバむダヌ", + defaultModels: "デフォルトモデル", + status: "ステヌタス", + notConfigured: "未蚭定", + active: "アクティブ", + inactive: "非アクティブ", + configure: "蚭定", + saveChanges: "倉曎を保存", + addModel: "モデルを远加", + modelName: "モデル名", + provider: "プロバむダヌ", + apiKey: "APIキヌ", + baseUrl: "ベヌスURL", + capabilities: "機胜", + enabled: "有効", + disabled: "無効", + deleteConfirm: "このモデルを削陀したすか", + deleteSuccess: "モデルを削陀したした", + saveSuccess: "モデルを保存したした", + providerStatus: "プロバむダヌステヌタス", + connectionOk: "接続OK", + connectionFailed: "接続倱敗", + changeEmbeddingWarning: "デフォルトのEmbeddingモデルを倉曎するず新しい゜ヌスに圱響したす。既存の゜ヌスは再むンデックスが必芁になる堎合がありたす。", + changeEmbeddingTitle: "デフォルトEmbeddingモデルを倉曎したすか", + aiProviders: "AIプロバむダヌ", + providerConfigDesc: "環境倉数を通じおプロバむダヌを蚭定し、モデルを有効にしおください。", + configuredCount: "{total}ä»¶äž­{count}件蚭定枈み", + noModels: "モデルなし", + learnMore: "プロバむダヌの蚭定方法を芋る →", + seeLess: "折りたたむ", + seeAll: "{count}件すべおのプロバむダヌを衚瀺", + language_models: "蚀語モデル", + embedding_models: "Embeddingモデル", + text_to_speech: "音声合成TTS", + speech_to_text: "音声認識STT", + languageDesc: "チャット、トランスフォヌメヌション、テキスト生成", + embeddingDesc: "セマンティック怜玢ずベクトルEmbedding", + ttsDesc: "テキストから音声を生成", + sttDesc: "音声をテキストに曞き起こし", + all: "すべお", + noModelsConfigured: "モデルが蚭定されおいたせん", + noProviderModelsConfigured: "{provider}モデルが蚭定されおいたせん", + showMore: "さらに{count}件衚瀺", + deleteModel: "モデルを削陀", + deleteModelDesc: "「{name}」を削陀したすかこの操䜜は元に戻せたせん。", + defaultAssignments: "デフォルトモデル割り圓お", + defaultAssignmentsDesc: "Open Notebook党䜓で異なる目的に䜿甚するモデルを蚭定", + missingRequiredModels: "必須モデルがありたせん: {models}。これらがないずOpen Notebookが正しく機胜しない可胜性がありたす。", + selectModelPlaceholder: "モデルを遞択", + requiredModelPlaceholder: "⚠ 必須 - モデルを遞択", + whichModelToChoose: "どのモデルを遞ぶべき →", + chatModelLabel: "チャットモデル", + chatModelDesc: "チャット䌚話に䜿甚", + transformationModelLabel: "トランスフォヌメヌションモデル", + transformationModelDesc: "芁玄、むンサむト、トランスフォヌメヌションに䜿甚", + toolsModelLabel: "ツヌルモデル", + toolsModelDesc: "関数呌び出しに䜿甚 - OpenAIたたはAnthropicを掚奚", + largeContextModelLabel: "倧芏暡コンテキストモデル", + largeContextModelDesc: "倧きなドキュメントの凊理に䜿甚 - Geminiを掚奚", + embeddingModelLabel: "Embeddingモデル", + embeddingModelDesc: "セマンティック怜玢ずベクトルEmbeddingに䜿甚", + ttsModelLabel: "音声合成モデル", + ttsModelDesc: "ポッドキャスト生成に䜿甚", + sttModelLabel: "音声認識モデル", + sttModelDesc: "音声の曞き起こしに䜿甚", + addSpecificModel: "{type}を远加", + addSpecificModelDesc: "利甚可胜なプロバむダヌから新しい{type}を蚭定したす。", + noProvidersForType: "{type}甚のプロバむダヌがありたせん", + selectProviderPlaceholder: "プロバむダヌを遞択", + providerRequired: "プロバむダヌは必須です", + modelNameRequired: "モデル名は必須です", + modelRequired: "モデルは必須です", + adding: "远加䞭...", + azureHint: "Azureの堎合、デプロむメント名をモデル名ずしお䜿甚しおください", + enterModelName: "モデル名を入力", + embeddingChangeTitle: "Embeddingモデルの倉曎", + embeddingChangeConfirm: "Embeddingモデルを{from}から{to}に倉曎しようずしおいたす。", + rebuildRequired: "重芁再構築が必芁", + rebuildReason: "Embeddingモデルを倉曎する堎合、䞀貫性を維持するためにすべおの既存Embeddingを再構築する必芁がありたす。再構築しないず、怜玢結果が䞍正確たたは䞍完党になる可胜性がありたす。", + whatHappensNext: "次に起こるこず", + step1: "デフォルトのEmbeddingモデルが曎新されたす", + step2: "既存のEmbeddingは再構築するたで倉曎されたせん", + step3: "新しいコンテンツは新しいEmbeddingモデルを䜿甚したす", + step4: "できるだけ早くEmbeddingを再構築しおください", + proceedToRebuildPrompt: "今すぐ詳现蚭定ペヌゞで再構築を開始したすか", + changeModelOnly: "モデルのみ倉曎", + changeAndRebuild: "倉曎しお再構築ぞ", + } +} diff --git a/frontend/src/lib/locales/pt-BR/index.ts b/frontend/src/lib/locales/pt-BR/index.ts index a14c5dc..da244fe 100644 --- a/frontend/src/lib/locales/pt-BR/index.ts +++ b/frontend/src/lib/locales/pt-BR/index.ts @@ -22,6 +22,7 @@ export const ptBR = { language: "Idioma", english: "English", chinese: "简䜓䞭文", + japanese: "日本語", source: "Fonte", notebook: "Caderno", podcast: "Podcast", diff --git a/frontend/src/lib/locales/zh-CN/index.ts b/frontend/src/lib/locales/zh-CN/index.ts index 97478c3..2fa0f61 100644 --- a/frontend/src/lib/locales/zh-CN/index.ts +++ b/frontend/src/lib/locales/zh-CN/index.ts @@ -27,6 +27,7 @@ export const zhCN = { language: "语蚀", english: "English", chinese: "简䜓䞭文", + japanese: "日本語", source: "来源", notebook: "笔记本", podcast: "播客", diff --git a/frontend/src/lib/locales/zh-TW/index.ts b/frontend/src/lib/locales/zh-TW/index.ts index 7e4e879..b3de8ac 100644 --- a/frontend/src/lib/locales/zh-TW/index.ts +++ b/frontend/src/lib/locales/zh-TW/index.ts @@ -27,6 +27,7 @@ export const zhTW = { language: "語蚀", english: "English", chinese: "簡體䞭文", + japanese: "日本語", source: "䟆源", notebook: "筆蚘本", podcast: "播客", diff --git a/frontend/src/lib/utils/date-locale.ts b/frontend/src/lib/utils/date-locale.ts index 2d34a3c..8724ec0 100644 --- a/frontend/src/lib/utils/date-locale.ts +++ b/frontend/src/lib/utils/date-locale.ts @@ -1,4 +1,4 @@ -import { zhCN, enUS, zhTW, ptBR, Locale } from 'date-fns/locale' +import { zhCN, enUS, zhTW, ptBR, ja, Locale } from 'date-fns/locale' /** * Mapping of language codes to date-fns locales. @@ -9,6 +9,7 @@ const LOCALE_MAP: Record = { 'zh-TW': zhTW, 'en-US': enUS, 'pt-BR': ptBR, + 'ja-JP': ja, } /**