refactor: 完全重构为 Anki 兼容数据结构

- 用 Deck 替换 Folder
- 用 Note + Card 替换 Pair (双向复习)
- 添加 NoteType (卡片模板)
- 添加 Revlog (复习历史)
- 实现 SM-2 间隔重复算法
- 更新所有前端页面
- 添加数据库迁移
This commit is contained in:
2026-03-10 19:20:46 +08:00
parent 9b78fd5215
commit 57ad1b8699
72 changed files with 7107 additions and 2430 deletions

View File

@@ -46,6 +46,15 @@
"unfavorite": "Aus Favoriten entfernen",
"pleaseLogin": "Bitte melden Sie sich zuerst an"
},
"decks": {
"title": "Decks",
"noDecks": "Noch keine Decks",
"deckName": "Deckname",
"totalCards": "Gesamtkarten",
"createdAt": "Erstellt am",
"actions": "Aktionen",
"view": "Anzeigen"
},
"folder_id": {
"unauthorized": "Sie sind nicht der Besitzer dieses Ordners",
"back": "Zurück",
@@ -169,22 +178,46 @@
"resetPasswordSuccessHint": "Ihr Passwort wurde erfolgreich zurückgesetzt. Sie können sich jetzt mit Ihrem neuen Passwort anmelden."
},
"memorize": {
"folder_selector": {
"selectFolder": "Wählen Sie einen Ordner",
"noFolders": "Keine Ordner gefunden",
"folderInfo": "{id}. {name} ({count})"
"deck_selector": {
"selectDeck": "Deck auswählen",
"noDecks": "Keine Decks gefunden",
"goToDecks": "Zu Decks",
"noCards": "Keine Karten",
"new": "Neu",
"learning": "Lernen",
"review": "Wiederholen",
"due": "Fällig"
},
"memorize": {
"answer": "Antwort",
"next": "Weiter",
"reverse": "Umkehren",
"dictation": "Diktat",
"noTextPairs": "Keine Textpaare verfügbar",
"disorder": "Mischen",
"previous": "Zurück"
"review": {
"loading": "Laden...",
"backToDecks": "Zurück zu Decks",
"allDone": "Fertig!",
"allDoneDesc": "Alle fälligen Karten wurden wiederholt.",
"reviewedCount": "{count} Karten wiederholt",
"progress": "{current} / {total}",
"nextReview": "Nächste Wiederholung",
"interval": "Intervall",
"ease": "Leichtigkeit",
"lapses": "Verlernungen",
"showAnswer": "Antwort zeigen",
"again": "Nochmal",
"hard": "Schwer",
"good": "Gut",
"easy": "Leicht",
"now": "jetzt",
"lessThanMinute": "<1 Min",
"inMinutes": "{count} Min",
"inHours": "{count} Std",
"inDays": "{count} Tage",
"inMonths": "{count} Monate",
"minutes": "<1 Min",
"days": "{count} Tage",
"months": "{count} Monate",
"minAbbr": "m",
"dayAbbr": "T"
},
"page": {
"unauthorized": "Sie sind nicht berechtigt, auf diesen Ordner zuzugreifen"
"unauthorized": "Sie sind nicht berechtigt, auf dieses Deck zuzugreifen"
}
},
"navbar": {
@@ -202,10 +235,10 @@
"description": "Laden Sie Screenshots von Vokabeltabellen aus Lehrbüchern hoch, um Wort-Definition-Paare zu extrahieren",
"uploadImage": "Bild hochladen",
"dragDropHint": "Ziehen Sie ein Bild hierher oder klicken Sie zum Auswählen",
"supportedFormats": "Unterstützt: JPG, PNG, WebP",
"selectFolder": "Ordner auswählen",
"chooseFolder": "Wählen Sie einen Ordner zum Speichern der extrahierten Paare",
"noFolders": "Keine Ordner verfügbar. Bitte erstellen Sie zuerst einen Ordner.",
"supportedFormats": "Unterstüt: JPG, PNG, WebP",
"selectDeck": "Deck auswählen",
"chooseDeck": "Wählen Sie einen Deck zum Speichern der extrahierten Paare",
"noDecks": "Keine Decks verfügbar. Bitte create a deck first.",
"languageHints": "Sprachhinweise (Optional)",
"sourceLanguageHint": "Quellsprache (z.B. Englisch)",
"targetLanguageHint": "Ziel-/Übersetzungssprache (z.B. Chinesisch)",
@@ -216,14 +249,14 @@
"word": "Wort",
"definition": "Definition",
"pairsCount": "{count} Paare extrahiert",
"savePairs": "In Ordner speichern",
"savePairs": "In Deck speichern",
"saving": "Speichern...",
"saved": "{count} Paare erfolgreich in {folder} gespeichert",
"saved": "{count} Paare erfolgreich in {deck} gespeichert",
"saveFailed": "Speichern fehlgeschlagen",
"noImage": "Bitte laden Sie zuerst ein Bild hoch",
"noFolder": "Bitte wählen Sie einen Ordner",
"noDeck": "Bitte select a deck",
"processingFailed": "OCR-Verarbeitung fehlgeschlagen",
"tryAgain": "Bitte versuchen Sie es mit einem klareren Bild",
"tryAgain": "Bitte try again with a clearer image",
"detectedLanguages": "Erkannt: {source} → {target}"
},
"profile": {
@@ -385,10 +418,10 @@
"memberSince": "Mitglied seit",
"logout": "Abmelden",
"folders": {
"title": "Ordner",
"noFolders": "Noch keine Ordner",
"folderName": "Ordnername",
"totalPairs": "Gesamtpaare",
"title": "Decks",
"noFolders": "Noch keine Decks",
"folderName": "Deckname",
"totalPairs": "Gesamtkarten",
"createdAt": "Erstellt am",
"actions": "Aktionen",
"view": "Anzeigen"

View File

@@ -169,22 +169,46 @@
"resetPasswordSuccessHint": "Your password has been reset successfully. You can now log in with your new password."
},
"memorize": {
"folder_selector": {
"selectFolder": "Select a folder",
"noFolders": "No folders found",
"folderInfo": "{id}. {name} ({count})"
"deck_selector": {
"selectDeck": "Select a deck",
"noDecks": "No decks found",
"goToDecks": "Go to Decks",
"noCards": "No cards",
"new": "New",
"learning": "Learning",
"review": "Review",
"due": "Due"
},
"memorize": {
"answer": "Answer",
"next": "Next",
"reverse": "Reverse",
"dictation": "Dictation",
"noTextPairs": "No text pairs available",
"disorder": "Disorder",
"previous": "Previous"
"review": {
"loading": "Loading cards...",
"backToDecks": "Back to Decks",
"allDone": "All Done!",
"allDoneDesc": "You've reviewed all due cards.",
"reviewedCount": "Reviewed {count} cards",
"progress": "{current} / {total}",
"nextReview": "Next review",
"interval": "Interval",
"ease": "Ease",
"lapses": "Lapses",
"showAnswer": "Show Answer",
"again": "Again",
"hard": "Hard",
"good": "Good",
"easy": "Easy",
"now": "now",
"lessThanMinute": "<1 min",
"inMinutes": "{count} min",
"inHours": "{count}h",
"inDays": "{count}d",
"inMonths": "{count}mo",
"minutes": "<1 min",
"days": "{count}d",
"months": "{count}mo",
"minAbbr": "m",
"dayAbbr": "d"
},
"page": {
"unauthorized": "You are not authorized to access this folder"
"unauthorized": "You are not authorized to access this deck"
}
},
"navbar": {
@@ -200,31 +224,45 @@
"ocr": {
"title": "OCR Vocabulary Extractor",
"description": "Upload vocabulary table screenshots from textbooks to extract word-definition pairs",
"uploadSection": "Upload Image",
"uploadImage": "Upload Image",
"dragDropHint": "Drag and drop an image here, or click to select",
"dropOrClick": "Drag and drop an image here, or click to select",
"changeImage": "Click to change image",
"supportedFormats": "Supports: JPG, PNG, WebP",
"selectFolder": "Select Folder",
"chooseFolder": "Choose a folder to save extracted pairs",
"noFolders": "No folders available. Please create a folder first.",
"deckSelection": "Select Deck",
"selectDeck": "Select a deck",
"chooseDeck": "Choose a deck to save extracted pairs",
"noDecks": "No decks available. Please create a deck first.",
"languageHints": "Language Hints (Optional)",
"sourceLanguageHint": "Source language (e.g., English)",
"targetLanguageHint": "Target/Translation language (e.g., Chinese)",
"sourceLanguagePlaceholder": "Source language (e.g., English)",
"targetLanguagePlaceholder": "Target/Translation language (e.g., Chinese)",
"process": "Process Image",
"processButton": "Process Image",
"processing": "Processing...",
"preview": "Preview",
"extractedPairs": "Extracted Pairs",
"resultsPreview": "Results Preview",
"extractedPairs": "Extracted {count} pairs",
"word": "Word",
"definition": "Definition",
"pairsCount": "{count} pairs extracted",
"savePairs": "Save to Folder",
"savePairs": "Save to Deck",
"saveButton": "Save",
"saving": "Saving...",
"saved": "Successfully saved {count} pairs to {folder}",
"saved": "Successfully saved {count} pairs to {deck}",
"ocrSuccess": "Successfully extracted {count} pairs to {deck}",
"savedToDeck": "Saved to {deckName}",
"saveFailed": "Failed to save pairs",
"noImage": "Please upload an image first",
"noFolder": "Please select a folder",
"noDeck": "Please select a deck",
"noResultsToSave": "No results to save",
"processingFailed": "OCR processing failed",
"tryAgain": "Please try again with a clearer image",
"detectedLanguages": "Detected: {source} → {target}"
"detectedLanguages": "Detected: {source} → {target}",
"detectedSourceLanguage": "Detected source language",
"detectedTargetLanguage": "Detected target language"
},
"profile": {
"myProfile": "My Profile",
@@ -338,11 +376,11 @@
},
"explore": {
"title": "Explore",
"subtitle": "Discover public folders",
"searchPlaceholder": "Search public folders...",
"subtitle": "Discover public decks",
"searchPlaceholder": "Search public decks...",
"loading": "Loading...",
"noFolders": "No public folders found",
"folderInfo": "{userName} • {totalPairs} pairs",
"noDecks": "No public decks found",
"deckInfo": "{userName} • {cardCount} cards",
"unknownUser": "Unknown User",
"favorite": "Favorite",
"unfavorite": "Unfavorite",
@@ -351,10 +389,10 @@
"sortByFavoritesActive": "Undo sort by favorites"
},
"exploreDetail": {
"title": "Folder Details",
"title": "Deck Details",
"createdBy": "Created by: {name}",
"unknownUser": "Unknown User",
"totalPairs": "Total Pairs",
"totalCards": "Total Cards",
"favorites": "Favorites",
"createdAt": "Created At",
"viewContent": "View Content",
@@ -385,11 +423,11 @@
"memberSince": "Member Since",
"joined": "Joined",
"logout": "Logout",
"folders": {
"title": "Folders",
"noFolders": "No folders yet",
"folderName": "Folder Name",
"totalPairs": "Total Pairs",
"decks": {
"title": "Decks",
"noDecks": "No decks yet",
"deckName": "Deck Name",
"totalCards": "Total Cards",
"createdAt": "Created At",
"actions": "Actions",
"view": "View"

View File

@@ -46,6 +46,15 @@
"unfavorite": "Retirer des favoris",
"pleaseLogin": "Veuillez vous connecter d'abord"
},
"decks": {
"title": "Decks",
"noDecks": "Pas encore de decks",
"deckName": "Nom du deck",
"totalCards": "Total des cartes",
"createdAt": "Créé le",
"actions": "Actions",
"view": "Voir"
},
"folder_id": {
"unauthorized": "Vous n'êtes pas le propriétaire de ce dossier",
"back": "Retour",
@@ -169,22 +178,46 @@
"resetPasswordSuccessHint": "Votre mot de passe a été réinitialisé avec succès. Vous pouvez maintenant vous connecter avec votre nouveau mot de passe."
},
"memorize": {
"folder_selector": {
"selectFolder": "Sélectionner un dossier",
"noFolders": "Aucun dossier trouvé",
"folderInfo": "{id}. {name} ({count})"
"deck_selector": {
"selectDeck": "Sélectionner un deck",
"noDecks": "Aucun deck trouvé",
"goToDecks": "Aller aux decks",
"noCards": "Aucune carte",
"new": "Nouveau",
"learning": "Apprentissage",
"review": "Révision",
"due": "À faire"
},
"memorize": {
"answer": "Réponse",
"next": "Suivant",
"reverse": "Inverser",
"dictation": "Dictée",
"noTextPairs": "Aucune paire de texte disponible",
"disorder": "Désordre",
"previous": "Précédent"
"review": {
"loading": "Chargement...",
"backToDecks": "Retour aux decks",
"allDone": "Terminé !",
"allDoneDesc": "Vous avez révisé toutes les cartes dues.",
"reviewedCount": "{count} cartes révisées",
"progress": "{current} / {total}",
"nextReview": "Prochaine révision",
"interval": "Intervalle",
"ease": "Facilité",
"lapses": "Oublis",
"showAnswer": "Afficher la réponse",
"again": "Encore",
"hard": "Difficile",
"good": "Bien",
"easy": "Facile",
"now": "maintenant",
"lessThanMinute": "<1 min",
"inMinutes": "{count} min",
"inHours": "{count}h",
"inDays": "{count}j",
"inMonths": "{count}mois",
"minutes": "<1 min",
"days": "{count}j",
"months": "{count}mois",
"minAbbr": "m",
"dayAbbr": "j"
},
"page": {
"unauthorized": "Vous n'êtes pas autorisé à accéder à ce dossier"
"unauthorized": "Vous n'êtes pas autorisé à accéder à ce deck"
}
},
"navbar": {
@@ -203,9 +236,9 @@
"uploadImage": "Télécharger une image",
"dragDropHint": "Glissez-déposez une image ici, ou cliquez pour sélectionner",
"supportedFormats": "Supportés : JPG, PNG, WebP",
"selectFolder": "Sélectionner un dossier",
"chooseFolder": "Choisissez un dossier pour sauvegarder les paires extraites",
"noFolders": "Aucun dossier disponible. Veuillez d'abord créer un dossier.",
"selectDeck": "Sélectionner un deck",
"chooseDeck": "Choisissez a deck to save the extracted pairs",
"noDecks": "Aucun deck disponible. Please create a deck first.",
"languageHints": "Indices de langue (Optionnel)",
"sourceLanguageHint": "Langue source (ex : Anglais)",
"targetLanguageHint": "Langue cible/traduction (ex : Chinois)",
@@ -216,14 +249,14 @@
"word": "Mot",
"definition": "Définition",
"pairsCount": "{count} paires extraites",
"savePairs": "Sauvegarder dans le dossier",
"savePairs": "Sauvegarder dans le deck",
"saving": "Sauvegarde...",
"saved": "{count} paires sauvegardées dans {folder}",
"saved": "{count} paires sauvegardées dans {deck}",
"saveFailed": "Échec de la sauvegarde",
"noImage": "Veuillez d'abord télécharger une image",
"noFolder": "Veuillez sélectionner un dossier",
"noImage": "Veuillez first upload an image",
"noDeck": "Please select a deck",
"processingFailed": "Échec du traitement OCR",
"tryAgain": "Veuillez réessayer avec une image plus claire",
"tryAgain": "Please try again with a clearer image",
"detectedLanguages": "Détecté : {source} → {target}"
},
"profile": {
@@ -384,11 +417,11 @@
"notSet": "Non défini",
"memberSince": "Membre depuis",
"logout": "Déconnexion",
"folders": {
"title": "Dossiers",
"noFolders": "Pas encore de dossiers",
"folderName": "Nom du dossier",
"totalPairs": "Total des paires",
"decks": {
"title": "Decks",
"noDecks": "Pas encore de decks",
"deckName": "Nom du deck",
"totalCards": "Total des cartes",
"createdAt": "Créé le",
"actions": "Actions",
"view": "Voir"

View File

@@ -46,6 +46,15 @@
"unfavorite": "Rimuovi dai preferiti",
"pleaseLogin": "Per favore accedi prima"
},
"decks": {
"title": "Mazzi",
"noDecks": "Nessun mazzo ancora",
"deckName": "Nome del mazzo",
"totalCards": "Totale carte",
"createdAt": "Creato il",
"actions": "Azioni",
"view": "Visualizza"
},
"folder_id": {
"unauthorized": "Non sei il proprietario di questa cartella",
"back": "Indietro",
@@ -169,22 +178,46 @@
"resetPasswordSuccessHint": "La tua password è stata reimpostata con successo. Ora puoi accedere con la tua nuova password."
},
"memorize": {
"folder_selector": {
"selectFolder": "Seleziona una cartella",
"noFolders": "Nessuna cartella trovata",
"folderInfo": "{id}. {name} ({count})"
"deck_selector": {
"selectDeck": "Seleziona un mazzo",
"noDecks": "Nessun mazzo trovato",
"goToDecks": "Vai ai mazzi",
"noCards": "Nessuna carta",
"new": "Nuove",
"learning": "In apprendimento",
"review": "Ripasso",
"due": "In scadenza"
},
"memorize": {
"answer": "Risposta",
"next": "Successivo",
"reverse": "Inverti",
"dictation": "Dettatura",
"noTextPairs": "Nessuna coppia di testo disponibile",
"disorder": "Disordina",
"previous": "Precedente"
"review": {
"loading": "Caricamento...",
"backToDecks": "Torna ai mazzi",
"allDone": "Fatto!",
"allDoneDesc": "Hai ripassato tutte le carte in scadenza.",
"reviewedCount": "{count} carte ripassate",
"progress": "{current} / {total}",
"nextReview": "Prossima revisione",
"interval": "Intervallo",
"ease": "Facilità",
"lapses": "Dimenticanze",
"showAnswer": "Mostra risposta",
"again": "Ancora",
"hard": "Difficile",
"good": "Bene",
"easy": "Facile",
"now": "ora",
"lessThanMinute": "<1 min",
"inMinutes": "{count} min",
"inHours": "{count}h",
"inDays": "{count}g",
"inMonths": "{count}mesi",
"minutes": "<1 min",
"days": "{count}g",
"months": "{count}mesi",
"minAbbr": "m",
"dayAbbr": "g"
},
"page": {
"unauthorized": "Non sei autorizzato ad accedere a questa cartella"
"unauthorized": "Non sei autorizzato ad accedere a questo mazzo"
}
},
"navbar": {
@@ -203,9 +236,9 @@
"uploadImage": "Carica immagine",
"dragDropHint": "Trascina e rilascia un'immagine qui, o clicca per selezionare",
"supportedFormats": "Supportati: JPG, PNG, WebP",
"selectFolder": "Seleziona cartella",
"chooseFolder": "Scegli una cartella per salvare le coppie estratte",
"noFolders": "Nessuna cartella disponibile. Crea prima una cartella.",
"selectDeck": "Seleziona un mazzo",
"chooseDeck": "Scegli un mazzo per salvare le coppie estratte",
"noDecks": "Nessun mazzo disponibile. Creane prima un mazzo.",
"languageHints": "Suggerimenti lingua (Opzionale)",
"sourceLanguageHint": "Lingua sorgente (es: Inglese)",
"targetLanguageHint": "Lingua target/traduzione (es: Cinese)",
@@ -216,12 +249,12 @@
"word": "Parola",
"definition": "Definizione",
"pairsCount": "{count} coppie estratte",
"savePairs": "Salva nella cartella",
"savePairs": "Salva nel mazzo",
"saving": "Salvataggio...",
"saved": "{count} coppie salvate in {folder}",
"saved": "{count} coppie salvate in {deck}",
"saveFailed": "Salvataggio fallito",
"noImage": "Carica prima un'immagine",
"noFolder": "Seleziona una cartella",
"noDeck": "Seleziona un mazzo",
"processingFailed": "Elaborazione OCR fallita",
"tryAgain": "Riprova con un'immagine più chiara",
"detectedLanguages": "Rilevato: {source} → {target}"
@@ -384,11 +417,11 @@
"notSet": "Non Impostato",
"memberSince": "Membro Dal",
"logout": "Esci",
"folders": {
"title": "Cartelle",
"noFolders": "Nessuna cartella ancora",
"folderName": "Nome Cartella",
"totalPairs": "Coppie Totali",
"decks": {
"title": "Mazzi",
"noDecks": "Nessun mazzo ancora",
"deckName": "Nome Mazzo",
"totalCards": "Carte Totali",
"createdAt": "Creata Il",
"actions": "Azioni",
"view": "Visualizza"

View File

@@ -169,22 +169,46 @@
"resetPasswordSuccessHint": "パスワードが正常にリセットされました。新しいパスワードでログインできます。"
},
"memorize": {
"folder_selector": {
"selectFolder": "フォルダーを選択",
"noFolders": "フォルダーが見つかりません",
"folderInfo": "{id}. {name} ({count})"
"deck_selector": {
"selectDeck": "デッキを選択",
"noDecks": "デッキが見つかりません",
"goToDecks": "デッキへ移動",
"noCards": "カードなし",
"new": "新規",
"learning": "学習中",
"review": "復習",
"due": "予定"
},
"memorize": {
"answer": "答え",
"next": "次へ",
"reverse": "逆順",
"dictation": "書き取り",
"noTextPairs": "利用可能なテキストペアがありません",
"disorder": "シャッフル",
"previous": "前へ"
"review": {
"loading": "読み込み中...",
"backToDecks": "デッキに戻る",
"allDone": "完了!",
"allDoneDesc": "すべての復習カードが完了しました。",
"reviewedCount": "{count} 枚のカードを復習",
"progress": "{current} / {total}",
"nextReview": "次の復習",
"interval": "間隔",
"ease": "易しさ",
"lapses": "忘回数",
"showAnswer": "答えを表示",
"again": "もう一度",
"hard": "難しい",
"good": "普通",
"easy": "簡単",
"now": "今",
"lessThanMinute": "<1分",
"inMinutes": "{count}分",
"inHours": "{count}時間",
"inDays": "{count}日",
"inMonths": "{count}ヶ月",
"minutes": "<1分",
"days": "{count}日",
"months": "{count}ヶ月",
"minAbbr": "分",
"dayAbbr": "日"
},
"page": {
"unauthorized": "このフォルダーにアクセスする権限がありません"
"unauthorized": "このデッキにアクセスする権限がありません"
}
},
"navbar": {
@@ -203,9 +227,9 @@
"uploadImage": "画像をアップロード",
"dragDropHint": "ここに画像をドラッグ&ドロップ、またはクリックして選択",
"supportedFormats": "対応形式JPG、PNG、WebP",
"selectFolder": "フォルダを選択",
"chooseFolder": "抽出したペアを保存するフォルダを選択",
"noFolders": "フォルダがありません。まずフォルダを作成してください。",
"selectDeck": "デッキを選択",
"chooseDeck": "抽出したペアを保存するデッキを選択",
"noDecks": "デッキがありません。まずデッキを作成してください。",
"languageHints": "言語ヒント(オプション)",
"sourceLanguageHint": "ソース言語(例:英語)",
"targetLanguageHint": "ターゲット/翻訳言語(例:中国語)",
@@ -216,12 +240,12 @@
"word": "単語",
"definition": "定義",
"pairsCount": "{count} ペアを抽出",
"savePairs": "フォルダに保存",
"savePairs": "デッキに保存",
"saving": "保存中...",
"saved": "{count} ペアを {folder} に保存しました",
"saved": "{count} ペアを {deck} に保存しました",
"saveFailed": "保存に失敗しました",
"noImage": "先に画像をアップロードしてください",
"noFolder": "フォルダを選択してください",
"noDeck": "デッキを選択してください",
"processingFailed": "OCR処理に失敗しました",
"tryAgain": "より鮮明な画像でお試しください",
"detectedLanguages": "検出:{source} → {target}"
@@ -384,11 +408,11 @@
"notSet": "未設定",
"memberSince": "登録日",
"logout": "ログアウト",
"folders": {
"title": "フォルダー",
"noFolders": "まだフォルダーがありません",
"folderName": "フォルダー名",
"totalPairs": "合計ペア数",
"decks": {
"title": "デッキ",
"noDecks": "まだデッキがありません",
"deckName": "デッキ名",
"totalCards": "合計カード数",
"createdAt": "作成日",
"actions": "アクション",
"view": "表示"

View File

@@ -46,6 +46,15 @@
"unfavorite": "즐겨찾기 해제",
"pleaseLogin": "먼저 로그인해주세요"
},
"decks": {
"title": "덱",
"noDecks": "덱이 없습니다",
"deckName": "덱 이름",
"totalCards": "총 카드",
"createdAt": "생성일",
"actions": "작업",
"view": "보기"
},
"folder_id": {
"unauthorized": "이 폴더의 소유자가 아닙니다",
"back": "뒤로",
@@ -169,22 +178,46 @@
"resetPasswordSuccessHint": "비밀번호가 성공적으로 재설정되었습니다. 새 비밀번호로 로그인할 수 있습니다."
},
"memorize": {
"folder_selector": {
"selectFolder": "폴더 선택",
"noFolders": "폴더를 찾을 수 없습니다",
"folderInfo": "{id}. {name} ({count})"
"deck_selector": {
"selectDeck": " 선택",
"noDecks": "덱을 찾을 수 없습니다",
"goToDecks": "덱으로 이동",
"noCards": "카드 없음",
"new": "새 카드",
"learning": "학습 중",
"review": "복습",
"due": "예정"
},
"memorize": {
"answer": "정답",
"next": "다음",
"reverse": "반대",
"dictation": "받아쓰기",
"noTextPairs": "사용 가능한 텍스트 쌍이 없습니다",
"disorder": "무작위",
"previous": "이전"
"review": {
"loading": "로딩 중...",
"backToDecks": "덱으로 돌아가기",
"allDone": "완료!",
"allDoneDesc": "모든 복습 카드를 완료했습니다.",
"reviewedCount": "{count}장의 카드 복습함",
"progress": "{current} / {total}",
"nextReview": "다음 복습",
"interval": "간격",
"ease": "난이도",
"lapses": "망각 횟수",
"showAnswer": "정답 보기",
"again": "다시",
"hard": "어려움",
"good": "보통",
"easy": "쉬움",
"now": "지금",
"lessThanMinute": "<1분",
"inMinutes": "{count}분",
"inHours": "{count}시간",
"inDays": "{count}일",
"inMonths": "{count}개월",
"minutes": "<1분",
"days": "{count}일",
"months": "{count}개월",
"minAbbr": "분",
"dayAbbr": "일"
},
"page": {
"unauthorized": "이 폴더에 접근할 권한이 없습니다"
"unauthorized": "이 에 접근할 권한이 없습니다"
}
},
"navbar": {
@@ -199,31 +232,31 @@
},
"ocr": {
"title": "OCR 어휘 추출",
"description": "교과서 어휘표 스크린샷 업로드하여 단어-정의 쌍 추출",
"description": "교과서 어휘표 스크린샷 only어업로드하여 단어-정의 쌍 추출",
"uploadImage": "이미지 업로드",
"dragDropHint": "이미지를 여기에 끌어다 놓거나 클릭하여 선택",
"supportedFormats": "지원 형식: JPG, PNG, WebP",
"selectFolder": "폴더 선택",
"chooseFolder": "추출된 쌍을 저장할 폴더 선택",
"noFolders": "폴더가 없습니다. 먼저 폴더를 만드세요.",
"selectDeck": " 선택",
"chooseDeck": "추출된 쌍을 저장할 선택",
"noDecks": "덱이 없습니다. 먼저 덱을 만드세요.",
"languageHints": "언어 힌트 (선택사항)",
"sourceLanguageHint": "소스 언어 (예: 영어)",
"targetLanguageHint": "대상/번역 언어 (예: 중국어)",
"process": "이미지 처리",
"processing": "처리...",
"processing": "처리...",
"preview": "미리보기",
"extractedPairs": "추출된 쌍",
"word": "단어",
"definition": "정의",
"pairsCount": "{count} 쌍 추출됨",
"savePairs": "폴더에 저장",
"saving": "저장...",
"saved": "{folder}에 {count} 쌍 저장 완료",
"savePairs": "에 저장",
"saving": "저장...",
"saved": "{deck}에 {count} 쌍 저장 완료",
"saveFailed": "저장 실패",
"noImage": "먼저 이미지를 업로드하세요",
"noFolder": "폴더를 선택하세요",
"noDeck": "덱을 선택하세요",
"processingFailed": "OCR 처리 실패",
"tryAgain": "더 선명한 이미지로 다시 시도하세요",
"tryAgain": "더 선晰的图像로 다시 시도하세요",
"detectedLanguages": "감지됨: {source} → {target}"
},
"profile": {
@@ -385,10 +418,10 @@
"memberSince": "가입일",
"logout": "로그아웃",
"folders": {
"title": "폴더",
"noFolders": "아직 폴더가 없습니다",
"folderName": "폴더 이름",
"totalPairs": "총 ",
"title": "",
"noFolders": "아직 덱이 없습니다",
"folderName": " 이름",
"totalPairs": "총 카드 수",
"createdAt": "생성일",
"actions": "작업",
"view": "보기"

View File

@@ -46,6 +46,15 @@
"unfavorite": "يىغىپ ساقلاشنى بىكار قىل",
"pleaseLogin": "ئاۋۋال تىزىمغا كىرىڭ"
},
"decks": {
"title": "دېكلار",
"noDecks": "تېخى دېك يوق",
"deckName": "دېك ئاتى",
"totalCards": "جەمئىي كارتا",
"createdAt": "قۇرۇلغان ۋاقتى",
"actions": "مەشغۇلاتلار",
"view": "كۆرۈش"
},
"folder_id": {
"unauthorized": "بۇ قىسقۇچنىڭ ئىگىسى ئەمەسسىز",
"back": "قايتىش",
@@ -169,22 +178,46 @@
"resetPasswordSuccessHint": "پارولىڭىز مۇۋەپپەقىيەتلىك ئەسلىگە قايتۇرۇلدى. يېڭى پارول بىلەن كىرسىڭىز بولىدۇ."
},
"memorize": {
"folder_selector": {
"selectFolder": "بىر قىسقۇچ تاللاڭ",
"noFolders": "قىسقۇچ تېپىلمىدى",
"folderInfo": "{id}. {name} ({count})"
"deck_selector": {
"selectDeck": "بىر دېك تاللاڭ",
"noDecks": "دېك تېپىلمىدى",
"goToDecks": "دېكلارغا بېرىڭ",
"noCards": "كارتا يوق",
"new": "يېڭى",
"learning": "ئۆگىنىۋاتىدۇ",
"review": "تەكرار",
"due": "ۋاقتى كەلدى"
},
"memorize": {
"answer": "جاۋاب",
"next": "كېيىنكى",
"reverse": ەتۈر",
"dictation": "دىكتات",
"noTextPairs": "تېكىست جۈپى يوق",
"disorder": "قالايمىقانلاشتۇرۇش",
"previous": "ئالدىنقى"
"review": {
"loading": "يۈكلىنىۋاتىدۇ...",
"backToDecks": "دېكلارغا قايتىڭ",
"allDone": امام!",
"allDoneDesc": "بارلىق تەكرارلاش كارتلىرى تاماملاندى.",
"reviewedCount": "{count} كارتا تەكرارلاندى",
"progress": "{current} / {total}",
"nextReview": "كېيىنكى تەكرار",
"interval": "ئارىلىق",
"ease": "ئاسانلىق",
"lapses": "ئۇنتۇش سانى",
"showAnswer": "جاۋابنى كۆرسەت",
"again": "يەنە",
"hard": "قىيىن",
"good": "ياخشى",
"easy": "ئاسان",
"now": "ھازىر",
"lessThanMinute": "<1 مىنۇت",
"inMinutes": "{count} مىنۇت",
"inHours": "{count} سائەت",
"inDays": "{count} كۈن",
"inMonths": "{count} ئاي",
"minutes": "<1 مىنۇت",
"days": "{count} كۈن",
"months": "{count} ئاي",
"minAbbr": "م",
"dayAbbr": "ك"
},
"page": {
"unauthorized": "بۇ قىسقۇچنى زىيارەت قىلىش ھوقۇقىڭىز يوق"
"unauthorized": "بۇ دېكنى زىيارەت قىلىش ھوقۇقىڭىز يوق"
}
},
"navbar": {
@@ -203,9 +236,9 @@
"uploadImage": "سۈرەت يۈكلەش",
"dragDropHint": "سۈرەتنى بۇ يەرگە سۆرەڭ ياكى چېكىپ تاللاڭ",
"supportedFormats": "قوللايدىغان فورماتلار: JPG، PNG، WebP",
"selectFolder": "قىسقۇچ تاللاش",
"chooseFolder": "ئاستىرىلغان جۈپلەرنى ساقلاش ئۈچۈن قىسقۇچ تاللاڭ",
"noFolders": "قىسقۇچ يوق. ئاۋۋال قىسقۇچ قۇرۇڭ.",
"selectDeck": "دېك تاللاش",
"chooseDeck": "ئاستىرىلغان جۈپلەرنى ساقلاش ئۈچۈن دېك تاللاڭ",
"noDecks": "دېك يوق. ئاۋۋال دېك قۇرۇڭ.",
"languageHints": "تىل ئۇچۇرلىرى (ئىختىيارىي)",
"sourceLanguageHint": "مەنبە تىلى (مىسال: ئىنگىلىزچە)",
"targetLanguageHint": "نىشان/تەرجىمە تىلى (مىسال: خەنزۇچە)",
@@ -216,12 +249,12 @@
"word": "سۆز",
"definition": "مەنا",
"pairsCount": "{count} جۈپ ئاستىرىلدى",
"savePairs": "قىسقۇچقا ساقلاش",
"savePairs": "دېككە ساقلاش",
"saving": "ساقلاۋاتىدۇ...",
"saved": "{folder} غا {count} جۈپ ساقلاندى",
"saved": "{deck} غا {count} جۈپ ساقلاندى",
"saveFailed": "ساقلاش مەغلۇپ بولدى",
"noImage": "ئاۋۋال سۈرەت يۈكلەڭ",
"noFolder": "قىسقۇچ تاللاڭ",
"noDeck": "دېك تاللاڭ",
"processingFailed": "OCR بىر تەرەپ قىلىش مەغلۇپ بولدى",
"tryAgain": "تېخىمۇ ئېنىق سۈرەت بىلەن قايتا سىناڭ",
"detectedLanguages": "بايقالدى: {source} → {target}"
@@ -384,11 +417,11 @@
"notSet": "تەڭشەلمىگەن",
"memberSince": "ئەزا بولغاندىن بېرى",
"logout": "چىكىنىش",
"folders": {
"title": "قىسقۇچلار",
"noFolders": "تېخى قىسقۇچ يوق",
"folderName": "قىسقۇچ ئاتى",
"totalPairs": "جەمئىي جۈپ",
"decks": {
"title": "دېكلار",
"noDecks": "تېخى دېك يوق",
"deckName": "دېك ئاتى",
"totalCards": "جەمئىي كارتا",
"createdAt": "قۇرۇلغان ۋاقتى",
"actions": "مەشغۇلاتلار",
"view": "كۆرۈش"

View File

@@ -169,22 +169,46 @@
"resetPasswordSuccessHint": "您的密码已成功重置,现在可以使用新密码登录了。"
},
"memorize": {
"folder_selector": {
"selectFolder": "选择文件夹",
"noFolders": "未找到文件夹",
"folderInfo": "{id}. {name} ({count})"
"deck_selector": {
"selectDeck": "选择牌组",
"noDecks": "未找到牌组",
"goToDecks": "前往牌组",
"noCards": "无卡片",
"new": "新卡片",
"learning": "学习中",
"review": "复习",
"due": "待复习"
},
"memorize": {
"answer": "答案",
"next": "下一个",
"reverse": "反向",
"dictation": "听写",
"noTextPairs": "没有可用的文本对",
"disorder": "乱序",
"previous": "上一个"
"review": {
"loading": "加载中...",
"backToDecks": "返回牌组",
"allDone": "全部完成!",
"allDoneDesc": "您已完成所有待复习卡片。",
"reviewedCount": "已复习 {count} 张卡片",
"progress": "{current} / {total}",
"nextReview": "下次复习",
"interval": "间隔",
"ease": "难度系数",
"lapses": "遗忘次数",
"showAnswer": "显示答案",
"again": "重来",
"hard": "困难",
"good": "良好",
"easy": "简单",
"now": "现在",
"lessThanMinute": "<1 分钟",
"inMinutes": "{count} 分钟",
"inHours": "{count} 小时",
"inDays": "{count} 天",
"inMonths": "{count} 个月",
"minutes": "<1 分钟",
"days": "{count} 天",
"months": "{count} 个月",
"minAbbr": "分",
"dayAbbr": "天"
},
"page": {
"unauthorized": "您无权访问该文件夹"
"unauthorized": "您无权访问该牌组"
}
},
"navbar": {
@@ -200,31 +224,45 @@
"ocr": {
"title": "OCR 词汇提取",
"description": "上传教材词汇表截图,提取单词-释义对",
"uploadSection": "上传图片",
"uploadImage": "上传图片",
"dragDropHint": "拖放图片到此处,或点击选择",
"dropOrClick": "拖放图片到此处,或点击选择",
"changeImage": "点击更换图片",
"supportedFormats": "支持格式JPG、PNG、WebP",
"selectFolder": "选择文件夹",
"chooseFolder": "选择保存提取词汇的文件夹",
"noFolders": "暂无文件夹,请先创建文件夹",
"deckSelection": "选择牌组",
"selectDeck": "选择牌组",
"chooseDeck": "选择保存提取词汇的牌组",
"noDecks": "暂无牌组,请先创建牌组",
"languageHints": "语言提示(可选)",
"sourceLanguageHint": "源语言(如:英语)",
"targetLanguageHint": "目标/翻译语言(如:中文)",
"sourceLanguagePlaceholder": "源语言(如:英语)",
"targetLanguagePlaceholder": "目标/翻译语言(如:中文)",
"process": "处理图片",
"processButton": "处理图片",
"processing": "处理中...",
"preview": "预览",
"extractedPairs": "提取的词汇对",
"resultsPreview": "结果预览",
"extractedPairs": "已提取 {count} 个词汇对",
"word": "单词",
"definition": "释义",
"pairsCount": "已提取 {count} 个词汇对",
"savePairs": "保存到文件夹",
"pairsCount": "{count} 个词汇对",
"savePairs": "保存到牌组",
"saveButton": "保存",
"saving": "保存中...",
"saved": "成功将 {count} 个词汇对保存到 {folder}",
"saved": "成功将 {count} 个词汇对保存到 {deck}",
"ocrSuccess": "成功将 {count} 个词汇对保存到 {deck}",
"savedToDeck": "已保存到 {deckName}",
"saveFailed": "保存失败",
"noImage": "请先上传图片",
"noFolder": "请选择文件夹",
"noDeck": "请选择牌组",
"noResultsToSave": "没有可保存的结果",
"processingFailed": "OCR 处理失败",
"tryAgain": "请尝试上传更清晰的图片",
"detectedLanguages": "检测到:{source} → {target}"
"detectedLanguages": "检测到:{source} → {target}",
"detectedSourceLanguage": "检测到的源语言",
"detectedTargetLanguage": "检测到的目标语言"
},
"profile": {
"myProfile": "我的个人资料",
@@ -338,11 +376,11 @@
},
"explore": {
"title": "探索",
"subtitle": "发现公开文件夹",
"searchPlaceholder": "搜索公开文件夹...",
"subtitle": "发现公开牌组",
"searchPlaceholder": "搜索公开牌组...",
"loading": "加载中...",
"noFolders": "没有找到公开文件夹",
"folderInfo": "{userName} • {totalPairs} 个文本对",
"noDecks": "没有找到公开牌组",
"deckInfo": "{userName} • {cardCount} 张卡片",
"unknownUser": "未知用户",
"favorite": "收藏",
"unfavorite": "取消收藏",
@@ -351,10 +389,10 @@
"sortByFavoritesActive": "取消按收藏数排序"
},
"exploreDetail": {
"title": "文件夹详情",
"title": "牌组详情",
"createdBy": "创建者:{name}",
"unknownUser": "未知用户",
"totalPairs": "词对数量",
"totalCards": "卡片数量",
"favorites": "收藏数",
"createdAt": "创建时间",
"viewContent": "查看内容",
@@ -385,11 +423,11 @@
"memberSince": "注册时间",
"joined": "加入于",
"logout": "登出",
"folders": {
"title": "文件夹",
"noFolders": "还没有文件夹",
"folderName": "文件夹名称",
"totalPairs": "文本对数量",
"decks": {
"title": "牌组",
"noDecks": "还没有牌组",
"deckName": "牌组名称",
"totalCards": "卡片数量",
"createdAt": "创建时间",
"actions": "操作",
"view": "查看"