mirror of
https://github.com/callumalpass/tasknotes.git
synced 2026-07-22 12:50:26 +00:00
Complete missing translations for all languages: - de, es, fr: All missing keys translated (100% coverage for existing keys) - ja, ru, zh: Missing keys translated and stale keys updated Add 159 new translation keys for previously hardcoded strings: - modals.deviceCode (12 keys) - modals.icsEventInfo (18 keys) - modals.timeblockInfo (23 keys) - modals.timeblockCreation (20 keys) - modals.icsNoteCreation (16 keys) - views.stats (25 keys) - views.agenda, views.notes, views.kanban (additional keys) - components.dateContextMenu (10 keys) - components.subgroupMenuBuilder (10 keys) - notices (23 keys) Update source files to use i18n: - 5 modal files - 5 view files - 3 component files - OAuthService, FilterBar Translation status: - de, es: 100% (1704/1704) - fr, ja, ru, zh: ~90% of new keys translated
662 lines
45 KiB
JavaScript
662 lines
45 KiB
JavaScript
import fs from 'fs';
|
||
import path from 'path';
|
||
|
||
const RESOURCES_DIR = path.resolve('src/i18n/resources');
|
||
|
||
// Translation mappings
|
||
const translations = {
|
||
fr: {
|
||
"views.agenda.empty.helpText": "Créez des tâches avec des dates d'échéance ou programmées, ou ajoutez des notes pour les voir ici.",
|
||
"views.agenda.contextMenu.showOverdueSection": "Afficher la section en retard",
|
||
"views.agenda.contextMenu.showNotes": "Afficher les notes",
|
||
"views.agenda.contextMenu.calendarSubscriptions": "Abonnements au calendrier",
|
||
"views.agenda.periods.thisWeek": "Cette semaine",
|
||
"views.agenda.tipPrefix": "Astuce : ",
|
||
"views.notes.refreshingButton": "Actualisation...",
|
||
"views.notes.empty.helpText": "Aucune note trouvée pour la date sélectionnée. Essayez de sélectionner une date différente dans la vue Mini Calendrier ou créez quelques notes.",
|
||
"views.notes.loading": "Chargement des notes...",
|
||
"views.notes.refreshButtonAriaLabel": "Actualiser la liste des notes",
|
||
"views.kanban.uncategorized": "Non catégorisé",
|
||
"views.kanban.noProject": "Aucun projet",
|
||
"views.kanban.columnTitle": "Sans titre",
|
||
"notices.icsNoteCreatedSuccess": "Note créée avec succès",
|
||
"notices.icsCreationModalOpenFailed": "Échec de l'ouverture de la modale de création",
|
||
"notices.icsNoteLinkSuccess": "Note \"{fileName}\" liée à l'événement ICS",
|
||
"notices.icsTaskCreatedSuccess": "Tâche créée : {title}",
|
||
"notices.icsRelatedItemsRefreshed": "Notes associées actualisées",
|
||
"notices.icsFileNotFound": "Fichier introuvable ou invalide",
|
||
"notices.icsFileOpenFailed": "Échec de l'ouverture du fichier",
|
||
"notices.timeblockAttachmentExists": "\"{fileName}\" est déjà attaché",
|
||
"notices.timeblockAttachmentAdded": "\"{fileName}\" ajouté comme pièce jointe",
|
||
"notices.timeblockAttachmentRemoved": "\"{fileName}\" retiré des pièces jointes",
|
||
"notices.timeblockFileTypeNotSupported": "Impossible d'ouvrir \"{fileName}\" - type de fichier non pris en charge",
|
||
"notices.timeblockTitleRequired": "Veuillez saisir un titre pour le bloc de temps",
|
||
"notices.timeblockUpdatedSuccess": "Bloc de temps \"{title}\" mis à jour avec succès",
|
||
"notices.timeblockUpdateFailed": "Échec de la mise à jour du bloc de temps. Consultez la console pour plus de détails.",
|
||
"notices.timeblockDeletedSuccess": "Bloc de temps \"{title}\" supprimé avec succès",
|
||
"notices.timeblockDeleteFailed": "Échec de la suppression du bloc de temps. Consultez la console pour plus de détails.",
|
||
"notices.timeblockRequiredFieldsMissing": "Veuillez remplir tous les champs requis",
|
||
"notices.agendaLoadingFailed": "Erreur lors du chargement de l'agenda. Veuillez essayer d'actualiser.",
|
||
"notices.statsLoadingFailed": "Erreur lors du chargement des détails du projet.",
|
||
"modals.deviceCode.title": "Autorisation Google Calendar",
|
||
"modals.deviceCode.instructions.intro": "Pour connecter votre Google Calendar, veuillez suivre ces étapes :",
|
||
"modals.deviceCode.steps.open": "Ouvrir",
|
||
"modals.deviceCode.steps.inBrowser": "dans votre navigateur",
|
||
"modals.deviceCode.steps.enterCode": "Entrez ce code lorsque demandé :",
|
||
"modals.deviceCode.steps.signIn": "Connectez-vous avec votre compte Google et accordez l'accès",
|
||
"modals.deviceCode.steps.returnToObsidian": "Retournez à Obsidian (cette fenêtre se fermera automatiquement)",
|
||
"modals.deviceCode.codeLabel": "Votre code :",
|
||
"modals.deviceCode.copyCodeAriaLabel": "Copier le code",
|
||
"modals.deviceCode.waitingForAuthorization": "En attente d'autorisation...",
|
||
"modals.deviceCode.openBrowserButton": "Ouvrir le navigateur",
|
||
"modals.deviceCode.cancelButton": "Annuler",
|
||
"modals.deviceCode.expiresMinutesSeconds": "Le code expire dans {minutes}m {seconds}s",
|
||
"modals.deviceCode.expiresSeconds": "Le code expire dans {seconds}s",
|
||
"modals.icsEventInfo.calendarEventHeading": "Événement de calendrier",
|
||
"modals.icsEventInfo.titleLabel": "Titre",
|
||
"modals.icsEventInfo.calendarLabel": "Calendrier",
|
||
"modals.icsEventInfo.dateTimeLabel": "Date et heure",
|
||
"modals.icsEventInfo.locationLabel": "Lieu",
|
||
"modals.icsEventInfo.descriptionLabel": "Description",
|
||
"modals.icsEventInfo.urlLabel": "URL",
|
||
"modals.icsEventInfo.relatedNotesHeading": "Notes et tâches associées",
|
||
"modals.icsEventInfo.noRelatedItems": "Aucune note ou tâche associée trouvée pour cet événement.",
|
||
"modals.icsEventInfo.typeTask": "Tâche",
|
||
"modals.icsEventInfo.typeNote": "Note",
|
||
"modals.icsEventInfo.actionsHeading": "Actions",
|
||
"modals.icsEventInfo.createFromEventLabel": "Créer à partir de l'événement",
|
||
"modals.icsEventInfo.createFromEventDesc": "Créer une nouvelle note ou tâche à partir de cet événement de calendrier",
|
||
"modals.icsEventInfo.linkExistingLabel": "Lier existant",
|
||
"modals.icsEventInfo.linkExistingDesc": "Lier une note existante à cet événement de calendrier",
|
||
"modals.timeblockInfo.editHeading": "Modifier le bloc de temps",
|
||
"modals.timeblockInfo.dateTimeLabel": "Date et heure : ",
|
||
"modals.timeblockInfo.titleLabel": "Titre",
|
||
"modals.timeblockInfo.titleDesc": "Titre de votre bloc de temps",
|
||
"modals.timeblockInfo.titlePlaceholder": "ex., Session de travail approfondi",
|
||
"modals.timeblockInfo.descriptionLabel": "Description",
|
||
"modals.timeblockInfo.descriptionDesc": "Description optionnelle du bloc de temps",
|
||
"modals.timeblockInfo.descriptionPlaceholder": "Concentrez-vous sur les nouvelles fonctionnalités, sans interruptions",
|
||
"modals.timeblockInfo.colorLabel": "Couleur",
|
||
"modals.timeblockInfo.colorDesc": "Couleur optionnelle pour le bloc de temps",
|
||
"modals.timeblockInfo.colorPlaceholder": "#3b82f6",
|
||
"modals.timeblockInfo.attachmentsLabel": "Pièces jointes",
|
||
"modals.timeblockInfo.attachmentsDesc": "Fichiers ou notes liés à ce bloc de temps",
|
||
"modals.timeblockInfo.addAttachmentButton": "Ajouter une pièce jointe",
|
||
"modals.timeblockInfo.addAttachmentTooltip": "Sélectionnez un fichier ou une note en utilisant la recherche floue",
|
||
"modals.timeblockInfo.deleteButton": "Supprimer le bloc de temps",
|
||
"modals.timeblockInfo.saveButton": "Enregistrer les modifications",
|
||
"modals.timeblockInfo.deleteConfirmationTitle": "Supprimer le bloc de temps",
|
||
"modals.timeblockCreation.heading": "Créer un bloc de temps",
|
||
"modals.timeblockCreation.dateLabel": "Date : ",
|
||
"modals.timeblockCreation.titleLabel": "Titre",
|
||
"modals.timeblockCreation.titleDesc": "Titre de votre bloc de temps",
|
||
"modals.timeblockCreation.titlePlaceholder": "ex., Session de travail approfondi",
|
||
"modals.timeblockCreation.startTimeLabel": "Heure de début",
|
||
"modals.timeblockCreation.startTimeDesc": "Quand le bloc de temps commence",
|
||
"modals.timeblockCreation.startTimePlaceholder": "09:00",
|
||
"modals.timeblockCreation.endTimeLabel": "Heure de fin",
|
||
"modals.timeblockCreation.endTimeDesc": "Quand le bloc de temps se termine",
|
||
"modals.timeblockCreation.endTimePlaceholder": "11:00",
|
||
"modals.timeblockCreation.descriptionLabel": "Description",
|
||
"modals.timeblockCreation.descriptionDesc": "Description optionnelle du bloc de temps",
|
||
"modals.timeblockCreation.descriptionPlaceholder": "Concentrez-vous sur les nouvelles fonctionnalités, sans interruptions",
|
||
"modals.timeblockCreation.colorLabel": "Couleur",
|
||
"modals.timeblockCreation.colorDesc": "Couleur optionnelle pour le bloc de temps",
|
||
"modals.timeblockCreation.colorPlaceholder": "#3b82f6",
|
||
"modals.timeblockCreation.attachmentsLabel": "Pièces jointes",
|
||
"modals.timeblockCreation.attachmentsDesc": "Fichiers ou notes à lier à ce bloc de temps",
|
||
"modals.timeblockCreation.addAttachmentButton": "Ajouter une pièce jointe",
|
||
"modals.timeblockCreation.addAttachmentTooltip": "Sélectionnez un fichier ou une note en utilisant la recherche floue",
|
||
"modals.timeblockCreation.createButton": "Créer un bloc de temps",
|
||
"modals.icsNoteCreation.heading": "Créer à partir d'un événement ICS",
|
||
"modals.icsNoteCreation.titleLabel": "Titre",
|
||
"modals.icsNoteCreation.titleDesc": "Titre du nouveau contenu",
|
||
"modals.icsNoteCreation.folderLabel": "Dossier",
|
||
"modals.icsNoteCreation.folderDesc": "Dossier de destination (laisser vide pour la racine du coffre)",
|
||
"modals.icsNoteCreation.folderPlaceholder": "dossier/sous-dossier",
|
||
"modals.icsNoteCreation.createButton": "Créer",
|
||
"modals.icsNoteCreation.startLabel": "Début : ",
|
||
"modals.icsNoteCreation.endLabel": "Fin : ",
|
||
"modals.icsNoteCreation.locationLabel": "Lieu : ",
|
||
"modals.icsNoteCreation.calendarLabel": "Calendrier : ",
|
||
"modals.icsNoteCreation.useTemplateLabel": "Utiliser un modèle",
|
||
"modals.icsNoteCreation.useTemplateDesc": "Appliquer un modèle lors de la création du contenu",
|
||
"modals.icsNoteCreation.templatePathLabel": "Chemin du modèle",
|
||
"modals.icsNoteCreation.templatePathDesc": "Chemin vers le fichier de modèle",
|
||
"modals.icsNoteCreation.templatePathPlaceholder": "templates/ics-note-template.md",
|
||
"ui.filterBar.subgroupLabel": "SOUS-GROUPE",
|
||
"components.dateContextMenu.weekdays": "Jours de semaine",
|
||
"components.dateContextMenu.clearDate": "Effacer la date",
|
||
"components.dateContextMenu.today": "Aujourd'hui",
|
||
"components.dateContextMenu.tomorrow": "Demain",
|
||
"components.dateContextMenu.thisWeekend": "Ce week-end",
|
||
"components.dateContextMenu.nextWeek": "La semaine prochaine",
|
||
"components.dateContextMenu.nextMonth": "Le mois prochain",
|
||
"components.dateContextMenu.setDateTime": "Définir la date et l'heure",
|
||
"components.dateContextMenu.dateLabel": "Date",
|
||
"components.dateContextMenu.timeLabel": "Heure (optionnelle)",
|
||
"components.subgroupMenuBuilder.none": "Aucun",
|
||
"components.subgroupMenuBuilder.status": "Statut",
|
||
"components.subgroupMenuBuilder.priority": "Priorité",
|
||
"components.subgroupMenuBuilder.context": "Contexte",
|
||
"components.subgroupMenuBuilder.project": "Projet",
|
||
"components.subgroupMenuBuilder.dueDate": "Date d'échéance",
|
||
"components.subgroupMenuBuilder.scheduledDate": "Date programmée",
|
||
"components.subgroupMenuBuilder.tags": "Étiquettes",
|
||
"components.subgroupMenuBuilder.completedDate": "Date de finalisation",
|
||
"components.subgroupMenuBuilder.subgroup": "SOUS-GROUPE",
|
||
},
|
||
ja: {
|
||
// Japanese translations with polite です/ます form
|
||
"views.agenda.empty.helpText": "期限や予定日を持つタスクを作成するか、ノートを追加してここに表示します。",
|
||
"views.agenda.contextMenu.showOverdueSection": "期限切れセクションを表示",
|
||
"views.agenda.contextMenu.showNotes": "ノートを表示",
|
||
"views.agenda.contextMenu.calendarSubscriptions": "カレンダーサブスクリプション",
|
||
"views.agenda.periods.thisWeek": "今週",
|
||
"views.agenda.tipPrefix": "ヒント:",
|
||
"views.notes.refreshingButton": "更新中...",
|
||
"views.notes.empty.helpText": "選択した日付のノートが見つかりませんでした。ミニカレンダービューで別の日付を選択するか、ノートを作成してください。",
|
||
"views.notes.loading": "ノートを読み込み中...",
|
||
"views.notes.refreshButtonAriaLabel": "ノートリストを更新",
|
||
"views.kanban.uncategorized": "未分類",
|
||
"views.kanban.noProject": "プロジェクトなし",
|
||
"views.kanban.columnTitle": "無題",
|
||
"notices.icsNoteCreatedSuccess": "ノートが正常に作成されました",
|
||
"notices.icsCreationModalOpenFailed": "作成モーダルを開けませんでした",
|
||
"notices.icsNoteLinkSuccess": "ノート「{fileName}」をICSイベントにリンクしました",
|
||
"notices.icsTaskCreatedSuccess": "タスクを作成しました:{title}",
|
||
"notices.icsRelatedItemsRefreshed": "関連ノートを更新しました",
|
||
"notices.icsFileNotFound": "ファイルが見つからないか無効です",
|
||
"notices.icsFileOpenFailed": "ファイルを開けませんでした",
|
||
"notices.timeblockAttachmentExists": "「{fileName}」は既に添付されています",
|
||
"notices.timeblockAttachmentAdded": "「{fileName}」を添付ファイルとして追加しました",
|
||
"notices.timeblockAttachmentRemoved": "「{fileName}」を添付ファイルから削除しました",
|
||
"notices.timeblockFileTypeNotSupported": "「{fileName}」を開けません - ファイルタイプがサポートされていません",
|
||
"notices.timeblockTitleRequired": "タイムブロックのタイトルを入力してください",
|
||
"notices.timeblockUpdatedSuccess": "タイムブロック「{title}」を正常に更新しました",
|
||
"notices.timeblockUpdateFailed": "タイムブロックの更新に失敗しました。詳細はコンソールを確認してください。",
|
||
"notices.timeblockDeletedSuccess": "タイムブロック「{title}」を正常に削除しました",
|
||
"notices.timeblockDeleteFailed": "タイムブロックの削除に失敗しました。詳細はコンソールを確認してください。",
|
||
"notices.timeblockRequiredFieldsMissing": "必須フィールドをすべて入力してください",
|
||
"notices.agendaLoadingFailed": "アジェンダの読み込みエラー。更新をお試しください。",
|
||
"notices.statsLoadingFailed": "プロジェクトの詳細の読み込みエラー。",
|
||
"modals.deviceCode.title": "Google Calendar認証",
|
||
"modals.deviceCode.instructions.intro": "Google Calendarに接続するには、次の手順に従ってください:",
|
||
"modals.deviceCode.steps.open": "開く",
|
||
"modals.deviceCode.steps.inBrowser": "ブラウザで",
|
||
"modals.deviceCode.steps.enterCode": "プロンプトが表示されたら、このコードを入力してください:",
|
||
"modals.deviceCode.steps.signIn": "Googleアカウントでサインインし、アクセスを許可してください",
|
||
"modals.deviceCode.steps.returnToObsidian": "Obsidianに戻る(このウィンドウは自動的に閉じます)",
|
||
"modals.deviceCode.codeLabel": "あなたのコード:",
|
||
"modals.deviceCode.copyCodeAriaLabel": "コードをコピー",
|
||
"modals.deviceCode.waitingForAuthorization": "認証を待機中...",
|
||
"modals.deviceCode.openBrowserButton": "ブラウザを開く",
|
||
"modals.deviceCode.cancelButton": "キャンセル",
|
||
"modals.deviceCode.expiresMinutesSeconds": "コードは{minutes}分{seconds}秒後に期限切れになります",
|
||
"modals.deviceCode.expiresSeconds": "コードは{seconds}秒後に期限切れになります",
|
||
"modals.icsEventInfo.calendarEventHeading": "カレンダーイベント",
|
||
"modals.icsEventInfo.titleLabel": "タイトル",
|
||
"modals.icsEventInfo.calendarLabel": "カレンダー",
|
||
"modals.icsEventInfo.dateTimeLabel": "日時",
|
||
"modals.icsEventInfo.locationLabel": "場所",
|
||
"modals.icsEventInfo.descriptionLabel": "説明",
|
||
"modals.icsEventInfo.urlLabel": "URL",
|
||
"modals.icsEventInfo.relatedNotesHeading": "関連するノートとタスク",
|
||
"modals.icsEventInfo.noRelatedItems": "このイベントに関連するノートまたはタスクが見つかりませんでした。",
|
||
"modals.icsEventInfo.typeTask": "タスク",
|
||
"modals.icsEventInfo.typeNote": "ノート",
|
||
"modals.icsEventInfo.actionsHeading": "アクション",
|
||
"modals.icsEventInfo.createFromEventLabel": "イベントから作成",
|
||
"modals.icsEventInfo.createFromEventDesc": "このカレンダーイベントから新しいノートまたはタスクを作成します",
|
||
"modals.icsEventInfo.linkExistingLabel": "既存をリンク",
|
||
"modals.icsEventInfo.linkExistingDesc": "既存のノートをこのカレンダーイベントにリンクします",
|
||
"modals.timeblockInfo.editHeading": "タイムブロックを編集",
|
||
"modals.timeblockInfo.dateTimeLabel": "日時:",
|
||
"modals.timeblockInfo.titleLabel": "タイトル",
|
||
"modals.timeblockInfo.titleDesc": "タイムブロックのタイトル",
|
||
"modals.timeblockInfo.titlePlaceholder": "例:集中作業セッション",
|
||
"modals.timeblockInfo.descriptionLabel": "説明",
|
||
"modals.timeblockInfo.descriptionDesc": "タイムブロックのオプション説明",
|
||
"modals.timeblockInfo.descriptionPlaceholder": "新機能に集中、中断なし",
|
||
"modals.timeblockInfo.colorLabel": "色",
|
||
"modals.timeblockInfo.colorDesc": "タイムブロックのオプションの色",
|
||
"modals.timeblockInfo.colorPlaceholder": "#3b82f6",
|
||
"modals.timeblockInfo.attachmentsLabel": "添付ファイル",
|
||
"modals.timeblockInfo.attachmentsDesc": "このタイムブロックにリンクされたファイルまたはノート",
|
||
"modals.timeblockInfo.addAttachmentButton": "添付ファイルを追加",
|
||
"modals.timeblockInfo.addAttachmentTooltip": "ファジー検索を使用してファイルまたはノートを選択",
|
||
"modals.timeblockInfo.deleteButton": "タイムブロックを削除",
|
||
"modals.timeblockInfo.saveButton": "変更を保存",
|
||
"modals.timeblockInfo.deleteConfirmationTitle": "タイムブロックを削除",
|
||
"modals.timeblockCreation.heading": "タイムブロックを作成",
|
||
"modals.timeblockCreation.dateLabel": "日付:",
|
||
"modals.timeblockCreation.titleLabel": "タイトル",
|
||
"modals.timeblockCreation.titleDesc": "タイムブロックのタイトル",
|
||
"modals.timeblockCreation.titlePlaceholder": "例:集中作業セッション",
|
||
"modals.timeblockCreation.startTimeLabel": "開始時刻",
|
||
"modals.timeblockCreation.startTimeDesc": "タイムブロックが開始する時刻",
|
||
"modals.timeblockCreation.startTimePlaceholder": "09:00",
|
||
"modals.timeblockCreation.endTimeLabel": "終了時刻",
|
||
"modals.timeblockCreation.endTimeDesc": "タイムブロックが終了する時刻",
|
||
"modals.timeblockCreation.endTimePlaceholder": "11:00",
|
||
"modals.timeblockCreation.descriptionLabel": "説明",
|
||
"modals.timeblockCreation.descriptionDesc": "タイムブロックのオプション説明",
|
||
"modals.timeblockCreation.descriptionPlaceholder": "新機能に集中、中断なし",
|
||
"modals.timeblockCreation.colorLabel": "色",
|
||
"modals.timeblockCreation.colorDesc": "タイムブロックのオプションの色",
|
||
"modals.timeblockCreation.colorPlaceholder": "#3b82f6",
|
||
"modals.timeblockCreation.attachmentsLabel": "添付ファイル",
|
||
"modals.timeblockCreation.attachmentsDesc": "このタイムブロックにリンクするファイルまたはノート",
|
||
"modals.timeblockCreation.addAttachmentButton": "添付ファイルを追加",
|
||
"modals.timeblockCreation.addAttachmentTooltip": "ファジー検索を使用してファイルまたはノートを選択",
|
||
"modals.timeblockCreation.createButton": "タイムブロックを作成",
|
||
"modals.icsNoteCreation.heading": "ICSイベントから作成",
|
||
"modals.icsNoteCreation.titleLabel": "タイトル",
|
||
"modals.icsNoteCreation.titleDesc": "新しいコンテンツのタイトル",
|
||
"modals.icsNoteCreation.folderLabel": "フォルダ",
|
||
"modals.icsNoteCreation.folderDesc": "保存先フォルダ(空欄の場合はVaultルート)",
|
||
"modals.icsNoteCreation.folderPlaceholder": "フォルダ/サブフォルダ",
|
||
"modals.icsNoteCreation.createButton": "作成",
|
||
"modals.icsNoteCreation.startLabel": "開始:",
|
||
"modals.icsNoteCreation.endLabel": "終了:",
|
||
"modals.icsNoteCreation.locationLabel": "場所:",
|
||
"modals.icsNoteCreation.calendarLabel": "カレンダー:",
|
||
"modals.icsNoteCreation.useTemplateLabel": "テンプレートを使用",
|
||
"modals.icsNoteCreation.useTemplateDesc": "コンテンツ作成時にテンプレートを適用",
|
||
"modals.icsNoteCreation.templatePathLabel": "テンプレートパス",
|
||
"modals.icsNoteCreation.templatePathDesc": "テンプレートファイルへのパス",
|
||
"modals.icsNoteCreation.templatePathPlaceholder": "templates/ics-note-template.md",
|
||
"ui.filterBar.subgroupLabel": "サブグループ",
|
||
"components.dateContextMenu.weekdays": "平日",
|
||
"components.dateContextMenu.clearDate": "日付をクリア",
|
||
"components.dateContextMenu.today": "今日",
|
||
"components.dateContextMenu.tomorrow": "明日",
|
||
"components.dateContextMenu.thisWeekend": "今週末",
|
||
"components.dateContextMenu.nextWeek": "来週",
|
||
"components.dateContextMenu.nextMonth": "来月",
|
||
"components.dateContextMenu.setDateTime": "日時を設定",
|
||
"components.dateContextMenu.dateLabel": "日付",
|
||
"components.dateContextMenu.timeLabel": "時刻(オプション)",
|
||
"components.subgroupMenuBuilder.none": "なし",
|
||
"components.subgroupMenuBuilder.status": "ステータス",
|
||
"components.subgroupMenuBuilder.priority": "優先度",
|
||
"components.subgroupMenuBuilder.context": "コンテキスト",
|
||
"components.subgroupMenuBuilder.project": "プロジェクト",
|
||
"components.subgroupMenuBuilder.dueDate": "期限",
|
||
"components.subgroupMenuBuilder.scheduledDate": "予定日",
|
||
"components.subgroupMenuBuilder.tags": "タグ",
|
||
"components.subgroupMenuBuilder.completedDate": "完了日",
|
||
"components.subgroupMenuBuilder.subgroup": "サブグループ",
|
||
},
|
||
ru: {
|
||
// Russian translations with formal address forms
|
||
"views.agenda.empty.helpText": "Создайте задачи с датами выполнения или планирования, или добавьте заметки, чтобы увидеть их здесь.",
|
||
"views.agenda.contextMenu.showOverdueSection": "Показать раздел просроченных",
|
||
"views.agenda.contextMenu.showNotes": "Показать заметки",
|
||
"views.agenda.contextMenu.calendarSubscriptions": "Подписки календаря",
|
||
"views.agenda.periods.thisWeek": "Эта неделя",
|
||
"views.agenda.tipPrefix": "Совет: ",
|
||
"views.notes.refreshingButton": "Обновление...",
|
||
"views.notes.empty.helpText": "Заметки для выбранной даты не найдены. Попробуйте выбрать другую дату в мини-календаре или создайте несколько заметок.",
|
||
"views.notes.loading": "Загрузка заметок...",
|
||
"views.notes.refreshButtonAriaLabel": "Обновить список заметок",
|
||
"views.kanban.uncategorized": "Без категории",
|
||
"views.kanban.noProject": "Без проекта",
|
||
"views.kanban.columnTitle": "Без названия",
|
||
"notices.icsNoteCreatedSuccess": "Заметка успешно создана",
|
||
"notices.icsCreationModalOpenFailed": "Не удалось открыть модальное окно создания",
|
||
"notices.icsNoteLinkSuccess": "Заметка \"{fileName}\" связана с событием ICS",
|
||
"notices.icsTaskCreatedSuccess": "Задача создана: {title}",
|
||
"notices.icsRelatedItemsRefreshed": "Связанные заметки обновлены",
|
||
"notices.icsFileNotFound": "Файл не найден или недействителен",
|
||
"notices.icsFileOpenFailed": "Не удалось открыть файл",
|
||
"notices.timeblockAttachmentExists": "\"{fileName}\" уже прикреплен",
|
||
"notices.timeblockAttachmentAdded": "\"{fileName}\" добавлен как вложение",
|
||
"notices.timeblockAttachmentRemoved": "\"{fileName}\" удален из вложений",
|
||
"notices.timeblockFileTypeNotSupported": "Невозможно открыть \"{fileName}\" - тип файла не поддерживается",
|
||
"notices.timeblockTitleRequired": "Пожалуйста, введите название для временного блока",
|
||
"notices.timeblockUpdatedSuccess": "Временной блок \"{title}\" успешно обновлен",
|
||
"notices.timeblockUpdateFailed": "Не удалось обновить временной блок. Проверьте консоль для подробностей.",
|
||
"notices.timeblockDeletedSuccess": "Временной блок \"{title}\" успешно удален",
|
||
"notices.timeblockDeleteFailed": "Не удалось удалить временной блок. Проверьте консоль для подробностей.",
|
||
"notices.timeblockRequiredFieldsMissing": "Пожалуйста, заполните все обязательные поля",
|
||
"notices.agendaLoadingFailed": "Ошибка при загрузке повестки. Пожалуйста, попробуйте обновить.",
|
||
"notices.statsLoadingFailed": "Ошибка при загрузке деталей проекта.",
|
||
"modals.deviceCode.title": "Авторизация Google Calendar",
|
||
"modals.deviceCode.instructions.intro": "Чтобы подключить ваш Google Calendar, пожалуйста, выполните следующие шаги:",
|
||
"modals.deviceCode.steps.open": "Откройте",
|
||
"modals.deviceCode.steps.inBrowser": "в вашем браузере",
|
||
"modals.deviceCode.steps.enterCode": "Введите этот код при запросе:",
|
||
"modals.deviceCode.steps.signIn": "Войдите с помощью вашего аккаунта Google и предоставьте доступ",
|
||
"modals.deviceCode.steps.returnToObsidian": "Вернитесь в Obsidian (это окно закроется автоматически)",
|
||
"modals.deviceCode.codeLabel": "Ваш код:",
|
||
"modals.deviceCode.copyCodeAriaLabel": "Скопировать код",
|
||
"modals.deviceCode.waitingForAuthorization": "Ожидание авторизации...",
|
||
"modals.deviceCode.openBrowserButton": "Открыть браузер",
|
||
"modals.deviceCode.cancelButton": "Отмена",
|
||
"modals.deviceCode.expiresMinutesSeconds": "Код истекает через {minutes}м {seconds}с",
|
||
"modals.deviceCode.expiresSeconds": "Код истекает через {seconds}с",
|
||
"modals.icsEventInfo.calendarEventHeading": "Событие календаря",
|
||
"modals.icsEventInfo.titleLabel": "Название",
|
||
"modals.icsEventInfo.calendarLabel": "Календарь",
|
||
"modals.icsEventInfo.dateTimeLabel": "Дата и время",
|
||
"modals.icsEventInfo.locationLabel": "Место",
|
||
"modals.icsEventInfo.descriptionLabel": "Описание",
|
||
"modals.icsEventInfo.urlLabel": "URL",
|
||
"modals.icsEventInfo.relatedNotesHeading": "Связанные заметки и задачи",
|
||
"modals.icsEventInfo.noRelatedItems": "Для этого события не найдено связанных заметок или задач.",
|
||
"modals.icsEventInfo.typeTask": "Задача",
|
||
"modals.icsEventInfo.typeNote": "Заметка",
|
||
"modals.icsEventInfo.actionsHeading": "Действия",
|
||
"modals.icsEventInfo.createFromEventLabel": "Создать из события",
|
||
"modals.icsEventInfo.createFromEventDesc": "Создать новую заметку или задачу из этого события календаря",
|
||
"modals.icsEventInfo.linkExistingLabel": "Связать существующее",
|
||
"modals.icsEventInfo.linkExistingDesc": "Связать существующую заметку с этим событием календаря",
|
||
"modals.timeblockInfo.editHeading": "Редактировать временной блок",
|
||
"modals.timeblockInfo.dateTimeLabel": "Дата и время: ",
|
||
"modals.timeblockInfo.titleLabel": "Название",
|
||
"modals.timeblockInfo.titleDesc": "Название вашего временного блока",
|
||
"modals.timeblockInfo.titlePlaceholder": "напр., Сессия глубокой работы",
|
||
"modals.timeblockInfo.descriptionLabel": "Описание",
|
||
"modals.timeblockInfo.descriptionDesc": "Необязательное описание временного блока",
|
||
"modals.timeblockInfo.descriptionPlaceholder": "Сосредоточиться на новых функциях, без прерываний",
|
||
"modals.timeblockInfo.colorLabel": "Цвет",
|
||
"modals.timeblockInfo.colorDesc": "Необязательный цвет для временного блока",
|
||
"modals.timeblockInfo.colorPlaceholder": "#3b82f6",
|
||
"modals.timeblockInfo.attachmentsLabel": "Вложения",
|
||
"modals.timeblockInfo.attachmentsDesc": "Файлы или заметки, связанные с этим временным блоком",
|
||
"modals.timeblockInfo.addAttachmentButton": "Добавить вложение",
|
||
"modals.timeblockInfo.addAttachmentTooltip": "Выберите файл или заметку с помощью нечеткого поиска",
|
||
"modals.timeblockInfo.deleteButton": "Удалить временной блок",
|
||
"modals.timeblockInfo.saveButton": "Сохранить изменения",
|
||
"modals.timeblockInfo.deleteConfirmationTitle": "Удалить временной блок",
|
||
"modals.timeblockCreation.heading": "Создать временной блок",
|
||
"modals.timeblockCreation.dateLabel": "Дата: ",
|
||
"modals.timeblockCreation.titleLabel": "Название",
|
||
"modals.timeblockCreation.titleDesc": "Название вашего временного блока",
|
||
"modals.timeblockCreation.titlePlaceholder": "напр., Сессия глубокой работы",
|
||
"modals.timeblockCreation.startTimeLabel": "Время начала",
|
||
"modals.timeblockCreation.startTimeDesc": "Когда начинается временной блок",
|
||
"modals.timeblockCreation.startTimePlaceholder": "09:00",
|
||
"modals.timeblockCreation.endTimeLabel": "Время окончания",
|
||
"modals.timeblockCreation.endTimeDesc": "Когда заканчивается временной блок",
|
||
"modals.timeblockCreation.endTimePlaceholder": "11:00",
|
||
"modals.timeblockCreation.descriptionLabel": "Описание",
|
||
"modals.timeblockCreation.descriptionDesc": "Необязательное описание временного блока",
|
||
"modals.timeblockCreation.descriptionPlaceholder": "Сосредоточиться на новых функциях, без прерываний",
|
||
"modals.timeblockCreation.colorLabel": "Цвет",
|
||
"modals.timeblockCreation.colorDesc": "Необязательный цвет для временного блока",
|
||
"modals.timeblockCreation.colorPlaceholder": "#3b82f6",
|
||
"modals.timeblockCreation.attachmentsLabel": "Вложения",
|
||
"modals.timeblockCreation.attachmentsDesc": "Файлы или заметки для связи с этим временным блоком",
|
||
"modals.timeblockCreation.addAttachmentButton": "Добавить вложение",
|
||
"modals.timeblockCreation.addAttachmentTooltip": "Выберите файл или заметку с помощью нечеткого поиска",
|
||
"modals.timeblockCreation.createButton": "Создать временной блок",
|
||
"modals.icsNoteCreation.heading": "Создать из события ICS",
|
||
"modals.icsNoteCreation.titleLabel": "Название",
|
||
"modals.icsNoteCreation.titleDesc": "Название нового содержимого",
|
||
"modals.icsNoteCreation.folderLabel": "Папка",
|
||
"modals.icsNoteCreation.folderDesc": "Папка назначения (оставьте пустым для корня хранилища)",
|
||
"modals.icsNoteCreation.folderPlaceholder": "папка/подпапка",
|
||
"modals.icsNoteCreation.createButton": "Создать",
|
||
"modals.icsNoteCreation.startLabel": "Начало: ",
|
||
"modals.icsNoteCreation.endLabel": "Окончание: ",
|
||
"modals.icsNoteCreation.locationLabel": "Место: ",
|
||
"modals.icsNoteCreation.calendarLabel": "Календарь: ",
|
||
"modals.icsNoteCreation.useTemplateLabel": "Использовать шаблон",
|
||
"modals.icsNoteCreation.useTemplateDesc": "Применить шаблон при создании содержимого",
|
||
"modals.icsNoteCreation.templatePathLabel": "Путь к шаблону",
|
||
"modals.icsNoteCreation.templatePathDesc": "Путь к файлу шаблона",
|
||
"modals.icsNoteCreation.templatePathPlaceholder": "templates/ics-note-template.md",
|
||
"ui.filterBar.subgroupLabel": "ПОДГРУППА",
|
||
"components.dateContextMenu.weekdays": "Будние дни",
|
||
"components.dateContextMenu.clearDate": "Очистить дату",
|
||
"components.dateContextMenu.today": "Сегодня",
|
||
"components.dateContextMenu.tomorrow": "Завтра",
|
||
"components.dateContextMenu.thisWeekend": "Эти выходные",
|
||
"components.dateContextMenu.nextWeek": "Следующая неделя",
|
||
"components.dateContextMenu.nextMonth": "Следующий месяц",
|
||
"components.dateContextMenu.setDateTime": "Установить дату и время",
|
||
"components.dateContextMenu.dateLabel": "Дата",
|
||
"components.dateContextMenu.timeLabel": "Время (необязательно)",
|
||
"components.subgroupMenuBuilder.none": "Нет",
|
||
"components.subgroupMenuBuilder.status": "Статус",
|
||
"components.subgroupMenuBuilder.priority": "Приоритет",
|
||
"components.subgroupMenuBuilder.context": "Контекст",
|
||
"components.subgroupMenuBuilder.project": "Проект",
|
||
"components.subgroupMenuBuilder.dueDate": "Срок выполнения",
|
||
"components.subgroupMenuBuilder.scheduledDate": "Запланированная дата",
|
||
"components.subgroupMenuBuilder.tags": "Теги",
|
||
"components.subgroupMenuBuilder.completedDate": "Дата завершения",
|
||
"components.subgroupMenuBuilder.subgroup": "ПОДГРУППА",
|
||
},
|
||
zh: {
|
||
// Simplified Chinese translations
|
||
"views.agenda.empty.helpText": "创建具有截止日期或计划日期的任务,或添加笔记以在此处查看它们。",
|
||
"views.agenda.contextMenu.showOverdueSection": "显示逾期部分",
|
||
"views.agenda.contextMenu.showNotes": "显示笔记",
|
||
"views.agenda.contextMenu.calendarSubscriptions": "日历订阅",
|
||
"views.agenda.periods.thisWeek": "本周",
|
||
"views.agenda.tipPrefix": "提示:",
|
||
"views.notes.refreshingButton": "刷新中...",
|
||
"views.notes.empty.helpText": "未找到所选日期的笔记。请尝试在迷你日历视图中选择其他日期或创建一些笔记。",
|
||
"views.notes.loading": "加载笔记中...",
|
||
"views.notes.refreshButtonAriaLabel": "刷新笔记列表",
|
||
"views.kanban.uncategorized": "未分类",
|
||
"views.kanban.noProject": "无项目",
|
||
"views.kanban.columnTitle": "无标题",
|
||
"notices.icsNoteCreatedSuccess": "笔记创建成功",
|
||
"notices.icsCreationModalOpenFailed": "无法打开创建模态框",
|
||
"notices.icsNoteLinkSuccess": "已将笔记"{fileName}"链接到ICS事件",
|
||
"notices.icsTaskCreatedSuccess": "任务已创建:{title}",
|
||
"notices.icsRelatedItemsRefreshed": "相关笔记已刷新",
|
||
"notices.icsFileNotFound": "文件未找到或无效",
|
||
"notices.icsFileOpenFailed": "无法打开文件",
|
||
"notices.timeblockAttachmentExists": ""{fileName}"已经附加",
|
||
"notices.timeblockAttachmentAdded": "已将"{fileName}"添加为附件",
|
||
"notices.timeblockAttachmentRemoved": "已从附件中移除"{fileName}"",
|
||
"notices.timeblockFileTypeNotSupported": "无法打开"{fileName}" - 不支持的文件类型",
|
||
"notices.timeblockTitleRequired": "请为时间块输入标题",
|
||
"notices.timeblockUpdatedSuccess": "时间块"{title}"更新成功",
|
||
"notices.timeblockUpdateFailed": "无法更新时间块。请查看控制台以获取详细信息。",
|
||
"notices.timeblockDeletedSuccess": "时间块"{title}"删除成功",
|
||
"notices.timeblockDeleteFailed": "无法删除时间块。请查看控制台以获取详细信息。",
|
||
"notices.timeblockRequiredFieldsMissing": "请填写所有必填字段",
|
||
"notices.agendaLoadingFailed": "加载议程时出错。请尝试刷新。",
|
||
"notices.statsLoadingFailed": "加载项目详情时出错。",
|
||
"modals.deviceCode.title": "Google Calendar授权",
|
||
"modals.deviceCode.instructions.intro": "要连接您的Google Calendar,请按照以下步骤操作:",
|
||
"modals.deviceCode.steps.open": "打开",
|
||
"modals.deviceCode.steps.inBrowser": "在您的浏览器中",
|
||
"modals.deviceCode.steps.enterCode": "在提示时输入此代码:",
|
||
"modals.deviceCode.steps.signIn": "使用您的Google帐户登录并授予访问权限",
|
||
"modals.deviceCode.steps.returnToObsidian": "返回Obsidian(此窗口将自动关闭)",
|
||
"modals.deviceCode.codeLabel": "您的代码:",
|
||
"modals.deviceCode.copyCodeAriaLabel": "复制代码",
|
||
"modals.deviceCode.waitingForAuthorization": "等待授权中...",
|
||
"modals.deviceCode.openBrowserButton": "打开浏览器",
|
||
"modals.deviceCode.cancelButton": "取消",
|
||
"modals.deviceCode.expiresMinutesSeconds": "代码将在{minutes}分{seconds}秒后过期",
|
||
"modals.deviceCode.expiresSeconds": "代码将在{seconds}秒后过期",
|
||
"modals.icsEventInfo.calendarEventHeading": "日历事件",
|
||
"modals.icsEventInfo.titleLabel": "标题",
|
||
"modals.icsEventInfo.calendarLabel": "日历",
|
||
"modals.icsEventInfo.dateTimeLabel": "日期和时间",
|
||
"modals.icsEventInfo.locationLabel": "位置",
|
||
"modals.icsEventInfo.descriptionLabel": "描述",
|
||
"modals.icsEventInfo.urlLabel": "URL",
|
||
"modals.icsEventInfo.relatedNotesHeading": "相关笔记和任务",
|
||
"modals.icsEventInfo.noRelatedItems": "未找到此事件的相关笔记或任务。",
|
||
"modals.icsEventInfo.typeTask": "任务",
|
||
"modals.icsEventInfo.typeNote": "笔记",
|
||
"modals.icsEventInfo.actionsHeading": "操作",
|
||
"modals.icsEventInfo.createFromEventLabel": "从事件创建",
|
||
"modals.icsEventInfo.createFromEventDesc": "从此日历事件创建新笔记或任务",
|
||
"modals.icsEventInfo.linkExistingLabel": "链接现有",
|
||
"modals.icsEventInfo.linkExistingDesc": "将现有笔记链接到此日历事件",
|
||
"modals.timeblockInfo.editHeading": "编辑时间块",
|
||
"modals.timeblockInfo.dateTimeLabel": "日期和时间:",
|
||
"modals.timeblockInfo.titleLabel": "标题",
|
||
"modals.timeblockInfo.titleDesc": "您的时间块标题",
|
||
"modals.timeblockInfo.titlePlaceholder": "例如,深度工作会话",
|
||
"modals.timeblockInfo.descriptionLabel": "描述",
|
||
"modals.timeblockInfo.descriptionDesc": "时间块的可选描述",
|
||
"modals.timeblockInfo.descriptionPlaceholder": "专注于新功能,无打扰",
|
||
"modals.timeblockInfo.colorLabel": "颜色",
|
||
"modals.timeblockInfo.colorDesc": "时间块的可选颜色",
|
||
"modals.timeblockInfo.colorPlaceholder": "#3b82f6",
|
||
"modals.timeblockInfo.attachmentsLabel": "附件",
|
||
"modals.timeblockInfo.attachmentsDesc": "链接到此时间块的文件或笔记",
|
||
"modals.timeblockInfo.addAttachmentButton": "添加附件",
|
||
"modals.timeblockInfo.addAttachmentTooltip": "使用模糊搜索选择文件或笔记",
|
||
"modals.timeblockInfo.deleteButton": "删除时间块",
|
||
"modals.timeblockInfo.saveButton": "保存更改",
|
||
"modals.timeblockInfo.deleteConfirmationTitle": "删除时间块",
|
||
"modals.timeblockCreation.heading": "创建时间块",
|
||
"modals.timeblockCreation.dateLabel": "日期:",
|
||
"modals.timeblockCreation.titleLabel": "标题",
|
||
"modals.timeblockCreation.titleDesc": "您的时间块标题",
|
||
"modals.timeblockCreation.titlePlaceholder": "例如,深度工作会话",
|
||
"modals.timeblockCreation.startTimeLabel": "开始时间",
|
||
"modals.timeblockCreation.startTimeDesc": "时间块开始的时间",
|
||
"modals.timeblockCreation.startTimePlaceholder": "09:00",
|
||
"modals.timeblockCreation.endTimeLabel": "结束时间",
|
||
"modals.timeblockCreation.endTimeDesc": "时间块结束的时间",
|
||
"modals.timeblockCreation.endTimePlaceholder": "11:00",
|
||
"modals.timeblockCreation.descriptionLabel": "描述",
|
||
"modals.timeblockCreation.descriptionDesc": "时间块的可选描述",
|
||
"modals.timeblockCreation.descriptionPlaceholder": "专注于新功能,无打扰",
|
||
"modals.timeblockCreation.colorLabel": "颜色",
|
||
"modals.timeblockCreation.colorDesc": "时间块的可选颜色",
|
||
"modals.timeblockCreation.colorPlaceholder": "#3b82f6",
|
||
"modals.timeblockCreation.attachmentsLabel": "附件",
|
||
"modals.timeblockCreation.attachmentsDesc": "要链接到此时间块的文件或笔记",
|
||
"modals.timeblockCreation.addAttachmentButton": "添加附件",
|
||
"modals.timeblockCreation.addAttachmentTooltip": "使用模糊搜索选择文件或笔记",
|
||
"modals.timeblockCreation.createButton": "创建时间块",
|
||
"modals.icsNoteCreation.heading": "从ICS事件创建",
|
||
"modals.icsNoteCreation.titleLabel": "标题",
|
||
"modals.icsNoteCreation.titleDesc": "新内容的标题",
|
||
"modals.icsNoteCreation.folderLabel": "文件夹",
|
||
"modals.icsNoteCreation.folderDesc": "目标文件夹(留空则为库根目录)",
|
||
"modals.icsNoteCreation.folderPlaceholder": "文件夹/子文件夹",
|
||
"modals.icsNoteCreation.createButton": "创建",
|
||
"modals.icsNoteCreation.startLabel": "开始:",
|
||
"modals.icsNoteCreation.endLabel": "结束:",
|
||
"modals.icsNoteCreation.locationLabel": "位置:",
|
||
"modals.icsNoteCreation.calendarLabel": "日历:",
|
||
"modals.icsNoteCreation.useTemplateLabel": "使用模板",
|
||
"modals.icsNoteCreation.useTemplateDesc": "创建内容时应用模板",
|
||
"modals.icsNoteCreation.templatePathLabel": "模板路径",
|
||
"modals.icsNoteCreation.templatePathDesc": "模板文件的路径",
|
||
"modals.icsNoteCreation.templatePathPlaceholder": "templates/ics-note-template.md",
|
||
"ui.filterBar.subgroupLabel": "子组",
|
||
"components.dateContextMenu.weekdays": "工作日",
|
||
"components.dateContextMenu.clearDate": "清除日期",
|
||
"components.dateContextMenu.today": "今天",
|
||
"components.dateContextMenu.tomorrow": "明天",
|
||
"components.dateContextMenu.thisWeekend": "本周末",
|
||
"components.dateContextMenu.nextWeek": "下周",
|
||
"components.dateContextMenu.nextMonth": "下个月",
|
||
"components.dateContextMenu.setDateTime": "设置日期和时间",
|
||
"components.dateContextMenu.dateLabel": "日期",
|
||
"components.dateContextMenu.timeLabel": "时间(可选)",
|
||
"components.subgroupMenuBuilder.none": "无",
|
||
"components.subgroupMenuBuilder.status": "状态",
|
||
"components.subgroupMenuBuilder.priority": "优先级",
|
||
"components.subgroupMenuBuilder.context": "上下文",
|
||
"components.subgroupMenuBuilder.project": "项目",
|
||
"components.subgroupMenuBuilder.dueDate": "截止日期",
|
||
"components.subgroupMenuBuilder.scheduledDate": "计划日期",
|
||
"components.subgroupMenuBuilder.tags": "标签",
|
||
"components.subgroupMenuBuilder.completedDate": "完成日期",
|
||
"components.subgroupMenuBuilder.subgroup": "子组",
|
||
},
|
||
};
|
||
|
||
// Helper to build nested object from dot notation
|
||
function setNestedValue(obj, path, value) {
|
||
const parts = path.split('.');
|
||
const last = parts.pop();
|
||
let current = obj;
|
||
for (const part of parts) {
|
||
if (!current[part]) {
|
||
current[part] = {};
|
||
}
|
||
current = current[part];
|
||
}
|
||
current[last] = value;
|
||
}
|
||
|
||
// Process each locale
|
||
for (const [locale, translationMap] of Object.entries(translations)) {
|
||
console.log(`\nProcessing ${locale}...`);
|
||
|
||
const filePath = path.join(RESOURCES_DIR, `${locale}.ts`);
|
||
let content = fs.readFileSync(filePath, 'utf8');
|
||
|
||
// Parse the existing structure to find insertion points
|
||
const lines = content.split('\n');
|
||
|
||
for (const [key, value] of Object.entries(translationMap)) {
|
||
const parts = key.split('.');
|
||
|
||
// Find where to insert this key
|
||
// Strategy: Find the parent section and insert alphabetically or at the end
|
||
let insertIndex = -1;
|
||
let indent = '';
|
||
|
||
// Build the search pattern for the parent
|
||
const parentPath = parts.slice(0, -1);
|
||
const lastKey = parts[parts.length - 1];
|
||
|
||
// Search for the parent section
|
||
for (let i = 0; i < lines.length; i++) {
|
||
const line = lines[i];
|
||
|
||
// Check if we're in the right nested section
|
||
if (parentPath.length > 0) {
|
||
const parentPattern = parentPath[parentPath.length - 1] + ':';
|
||
if (line.includes(parentPattern) && line.includes('{')) {
|
||
// Found the parent, now find where to insert
|
||
insertIndex = i + 1;
|
||
// Get indentation
|
||
const match = line.match(/^(\s*)/);
|
||
indent = match ? match[1] + '\t' : '\t\t';
|
||
|
||
// Find the closing brace of this section
|
||
let braceCount = 1;
|
||
for (let j = i + 1; j < lines.length; j++) {
|
||
if (lines[j].includes('{')) braceCount++;
|
||
if (lines[j].includes('}')) {
|
||
braceCount--;
|
||
if (braceCount === 0) {
|
||
insertIndex = j;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Escape special characters in value
|
||
const escapedValue = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
||
const newLine = `${indent}${lastKey}: "${escapedValue}",`;
|
||
|
||
// Insert the line
|
||
if (insertIndex > 0) {
|
||
lines.splice(insertIndex, 0, newLine);
|
||
console.log(` Added: ${key}`);
|
||
} else {
|
||
console.warn(` Warning: Could not find insertion point for ${key}`);
|
||
}
|
||
}
|
||
|
||
// Write back
|
||
fs.writeFileSync(filePath, lines.join('\n'));
|
||
console.log(`✓ Completed ${locale}`);
|
||
}
|
||
|
||
console.log('\n✓ All translations added!');
|