diff --git a/.vscode/settings.json b/.vscode/settings.json index 13214f14..04c24186 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -31,6 +31,7 @@ "i18n-ally.keystyle": "flat", "i18n-ally.preferredDelimiter": "_", "i18n-ally.sortKeys": true, + "i18n-ally.sortCompare": "binary", "i18n-ally.keepFulfilled": true, "i18n-ally.translate.promptSource": true, "i18n-ally.pathMatcher": "{locale}.json", diff --git a/CHANGELOG.md b/CHANGELOG.md index 756c9c78..00d4dc5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,22 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [2.10.0](https://github.com/lokalise/i18n-ally/compare/v2.9.1...v2.10.0) (2023-07-11) + +### ⚡ Features + +* Add i18next-shopify framework ([#949](https://github.com/lokalise/i18n-ally/pull/949), [#970](https://github.com/lokalise/i18n-ally/pull/970)) +* Add extraction support to react-i18next framework ([#951](https://github.com/lokalise/i18n-ally/pull/951)) +* Display first available pluralization string if parent key of nested pluralization keys ([#950](https://github.com/lokalise/i18n-ally/pull/950)) +* Support "Go to Definition" for nested pluralization keys ([#954](https://github.com/lokalise/i18n-ally/pull/954)) + +### 🐞 Bug Fixes + +* implement scopes/namespaces for Transloco ([#684](https://github.com/lokalise/i18n-ally/issues/684)) ([43df97d](https://github.com/lokalise/i18n-ally/commit/43df97db80073230e528b7bf63610c903d886df8)) +* Fixes usage report for non-missing derived keys ([#957](https://github.com/lokalise/i18n-ally/pull/957)) +* Fixes Current File Panel report of not found keys ([Shopify/i18n-ally#7](https://github.com/Shopify/i18n-ally/pull/7)) + + ### [2.9.1](https://github.com/lokalise/i18n-ally/compare/v2.9.0...v2.9.1) (2023-05-15) ### 🐞 Bug Fixes diff --git a/examples/by-features/custom-scope-range/.vscode/i18n-ally-custom-framework.yml b/examples/by-features/custom-scope-range/.vscode/i18n-ally-custom-framework.yml new file mode 100644 index 00000000..aac3d974 --- /dev/null +++ b/examples/by-features/custom-scope-range/.vscode/i18n-ally-custom-framework.yml @@ -0,0 +1,7 @@ +languageIds: + - javascript + - typescript + - javascriptreact + - typescriptreact +scopeRangeRegex: "customScopeRangeFn\\(\\s*\\[?\\s*['\"`](.*?)['\"`]" +monopoly: false diff --git a/examples/by-features/custom-scope-range/.vscode/settings.json b/examples/by-features/custom-scope-range/.vscode/settings.json new file mode 100644 index 00000000..8111f69d --- /dev/null +++ b/examples/by-features/custom-scope-range/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "i18n-ally.localesPaths": "public/locales", + "i18n-ally.enabledFrameworks": ["react", "i18next", "custom"], + "i18n-ally.namespace": true, + "i18n-ally.pathMatcher": "{locale}/{namespaces}.json", + "i18n-ally.keystyle": "nested" +} diff --git a/examples/by-features/custom-scope-range/package.json b/examples/by-features/custom-scope-range/package.json new file mode 100644 index 00000000..b6cbdf89 --- /dev/null +++ b/examples/by-features/custom-scope-range/package.json @@ -0,0 +1,12 @@ +{ + "name": "custom-scope-range", + "version": "0.1.0", + "private": true, + "dependencies": { + "i18next": "20.3.0", + "i18next-xhr-backend": "3.2.2", + "react": "17.0.2", + "react-dom": "17.0.2", + "react-i18next": "11.9.0" + } +} diff --git a/examples/by-features/custom-scope-range/public/index.html b/examples/by-features/custom-scope-range/public/index.html new file mode 100644 index 00000000..018b5a51 --- /dev/null +++ b/examples/by-features/custom-scope-range/public/index.html @@ -0,0 +1,15 @@ + + +
+ + + +src/App.js
and save to reload.
+ src/App.js
and save to reload.
+ {t("translation.count", { count: 1 })}
+{t('description')}
+{t('title')}
+} + +function Test2() { + const t = useTranslations() + return{t('Test.title')}
+} diff --git a/examples/by-frameworks/next-intl/src/middleware.tsx b/examples/by-frameworks/next-intl/src/middleware.tsx new file mode 100644 index 00000000..23f8881a --- /dev/null +++ b/examples/by-frameworks/next-intl/src/middleware.tsx @@ -0,0 +1,11 @@ +import createMiddleware from 'next-intl/middleware' + +export default createMiddleware({ + locales: ['en', 'de'], + defaultLocale: 'en', +}) + +export const config = { + // Skip all paths that should not be internationalized + matcher: ['/((?!api|_next|.*\\..*).*)'], +} diff --git a/examples/by-frameworks/next-intl/tsconfig.json b/examples/by-frameworks/next-intl/tsconfig.json new file mode 100644 index 00000000..2132fd18 --- /dev/null +++ b/examples/by-frameworks/next-intl/tsconfig.json @@ -0,0 +1,37 @@ +{ + "compilerOptions": { + "baseUrl": "src", + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "strict": false, + "forceConsistentCasingInFileNames": true + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/examples/by-frameworks/react-i18next/.vscode/settings.json b/examples/by-frameworks/react-i18next/.vscode/settings.json index 2feedc3e..1bc560e1 100644 --- a/examples/by-frameworks/react-i18next/.vscode/settings.json +++ b/examples/by-frameworks/react-i18next/.vscode/settings.json @@ -1,8 +1,7 @@ { "i18n-ally.localesPaths": "public/locales", "i18n-ally.enabledFrameworks": [ - "react-i18next", - "general" + "react-i18next" ], "i18n-ally.namespace": true, "i18n-ally.pathMatcher": "{locale}/{namespaces}.json", diff --git a/locales/de.json b/locales/de.json index 17d63e98..fbba4850 100644 --- a/locales/de.json +++ b/locales/de.json @@ -37,6 +37,8 @@ "config.annotation_max_length": "Maximale Zeichenlänge für Hinweise die im Text angezeigt werden. Abgeschnitte Zeichen werden als (...) angezeigt", "config.annotations": "Hinweise im Text aktivieren", "config.auto_detection": "Automatische Erkennung von Übersetzung aktivieren", + "config.baidu_app_secret": "", + "config.baidu_appid": "", "config.deepl_api_key": "API key für die DeepL translate engine", "config.deepl_log": "DeepL debug logs anzeigen", "config.deepl_use_free_api_entry": "Kostenlose DeepL Version benutzen", @@ -69,6 +71,9 @@ "config.locale_country_map": "Ein Objekt zur Zuordnung von zwei Buchstaben des Lokalisierungscodes zum Ländercode", "config.locales_paths": "Pfad des Lokalisierungsordners (relative zum Hauptverzeichnes). Glob pattern akzeptiert.", "config.namespace": "Namespace aktivieren. Dokumentation für weitere Details prüfen.", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "Pfad für benutzerdefinierten Namespace. Dokumentation für weitere details prüfen.", "config.preferred_delimiter": "Bevorzugtes Trennzeichen für zusammengesetzte Schlüsse. Standardwert ist \"-\"", "config.prompt_translating_source": "Aufforderung zur Auswahl der Quellsprache bei jeder Verwendung. Wenn false, die Quellsprache wird aus der Konfiguration gelesen.", @@ -90,6 +95,7 @@ "config.target_picking_strategy.file-previous": "Text in die zuvor ausgewählte Sprachdatei der aktuellen Datei extrahieren", "config.target_picking_strategy.global-previous": "Text in die aktuell ausgewähle Datei extrahieren", "config.target_picking_strategy.most-similar": "Automatisches Extrahieren von Text in die Datei, deren Pfad am meisten mit dem Pfad der aktuellen Datei übereinstimmt", + "config.target_picking_strategy.most-similar-by-key": "Füllen Sie die extrahierte Kopie automatisch in die Sprachdatei ein, die am besten zum aktuellen i18n-Schlüssel passt", "config.target_picking_strategy.none": "Benutzer wählt manuell aus, in welche Datei der Text extrahiert werden soll", "config.translate.engines": "Übersetzungsdienste.", "config.translate.fallbackToKey": "Schlüssel selbst zum Übersetzen verwenden, wenn es keine Quellübersetzung für diesen Schlüssel gibt.", diff --git a/locales/en.json b/locales/en.json index d47f879d..68aa64eb 100644 --- a/locales/en.json +++ b/locales/en.json @@ -37,6 +37,8 @@ "config.annotation_max_length": "Max number of characters shown in the inline annotations. Excess characters will display as an ellipses (...)", "config.annotations": "Enable the inline annotations.", "config.auto_detection": "Enable locales auto detection for projects", + "config.baidu_app_secret": "APP Secret to use Baidu translate engine", + "config.baidu_appid": "APP ID to use Baidu translate engine", "config.deepl_api_key": "API key to use DeepL translate engine", "config.deepl_log": "Show DeepL engine debug logs", "config.deepl_use_free_api_entry": "Use DeepL Free API entry point", @@ -69,6 +71,9 @@ "config.locale_country_map": "An object to map two letters locale code to country code", "config.locales_paths": "Path to locales directory (relative to project root). Glob pattern is also acceptable.", "config.namespace": "Enable namespaces. Check out the docs for more details.", + "config.openai_api_key": "OpenAI API key", + "config.openai_api_model": "OpenAI chatgpt model", + "config.openai_api_root": "OpenAI API root URL", "config.path_matcher": "Match path for custom locale/namespace. Check out the docs for more details.", "config.preferred_delimiter": "Preferred delimiter of composed keypath, default to \"-\"(dash)", "config.prompt_translating_source": "Prompt to select source locale on translating every time. If set false, the source language in the config will be used.", @@ -84,12 +89,15 @@ "config.review_username": "Username for reviewing", "config.show_flags": "Show flags along with locale codes", "config.sort_keys": "Sort keys when saving to JSON/YAML", + "config.sort_compare": "Strategy for sorting keys.", + "config.sort_locale": "Locale to with if locale sort is used (will use the file's own locale if not specified)", "config.source_language": "Source language for machine translation", "config.tab_style": "Tab style for locale files", "config.target_picking_strategy": "Strategy dealing with more than one locale files were found.", "config.target_picking_strategy.file-previous": "Extract text to current file's previous selected locale file", "config.target_picking_strategy.global-previous": "Extract text to (current or other) file 's previous selected locale file", "config.target_picking_strategy.most-similar": "Automatically extract text to the file which path most matches to current file's path", + "config.target_picking_strategy.most-similar-by-key": "Automatically fill the extracted copy into the language file that best matches the current i18n key", "config.target_picking_strategy.none": "User manually select which file to extract text to", "config.translate.engines": "Translation services.", "config.translate.fallbackToKey": "Use key itself to translate when there is no source translation for that key.", diff --git a/locales/es.json b/locales/es.json index a15c72e9..fa1d5e48 100644 --- a/locales/es.json +++ b/locales/es.json @@ -37,6 +37,8 @@ "config.annotation_max_length": "Máximo número de caracteres que se mostrarán en las anotaciones en línea. Los restantes se mostrarán como elipses (...)", "config.annotations": "Habilitar las anotaciones en línea.", "config.auto_detection": "", + "config.baidu_app_secret": "", + "config.baidu_appid": "", "config.deepl_api_key": "API key para el traductor DeepL", "config.deepl_log": "Mostrar mensajes de depuración del motor DeepL", "config.deepl_use_free_api_entry": "", @@ -69,6 +71,9 @@ "config.locale_country_map": "Un objeto para relacionar dos letras de código regional a código de país", "config.locales_paths": "Ruta de acceso al directorio de configuración regional (relativa a la raíz del proyecto). Acepta patrón Glob.", "config.namespace": "Habilitar espacios de nombres. Comprueba la documentación para más detalles.", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "Igual el path para configuraciones regionales/espacios de nombres personalizados. Comprueba la documentación para más detalles.", "config.preferred_delimiter": "Delimitador preferido para las rutas de acceso compuestas, por defecto \"-\"(guión)", "config.prompt_translating_source": "Solicitud para seleccionar la configuración regional de origen al traducir. Si se establece en false, se utilizará el idioma de origen en la configuración.", @@ -90,6 +95,7 @@ "config.target_picking_strategy.file-previous": "Extraer el texto al archivo de localización seleccionado anteriormente del archivo actual", "config.target_picking_strategy.global-previous": "Extraer el texto al archivo (actual o de otro tipo) del archivo local previamente seleccionado", "config.target_picking_strategy.most-similar": "Extraer automáticamente el texto al archivo cuya ruta coincida más con la ruta del archivo actual", + "config.target_picking_strategy.most-similar-by-key": "Rellene automáticamente la copia extraída en el archivo de idioma que mejor coincida con la clave i18n actual", "config.target_picking_strategy.none": "El usuario selecciona manualmente a qué archivo extraer el texto", "config.translate.engines": "Servicios de traducción.", "config.translate.fallbackToKey": "Usar la llave en sí para traducir cuando no hay una traducción de origen para esa llave.", diff --git a/locales/fr.json b/locales/fr.json index 445e9f70..b7ec6728 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -3,45 +3,47 @@ "command.config_locales": "Configurer manuellement le chemin de la traduction", "command.config_locales_auto": "Détecter automatiquement le chemin de la traduction", "command.config_source_language": "Changer la langue source", - "command.copy_key": "Copier une Clé i18n", - "command.deepl_usage": "Utilisation de l'API DeepL ", - "command.delete_key": "Supprimer une Clé", - "command.duplicate_key": "Dupliquer une Clé", + "command.copy_key": "Copier une clé i18n", + "command.deepl_usage": "Utilisation de l'API DeepL", + "command.delete_key": "Supprimer une clé", + "command.duplicate_key": "Dupliquer une clé", "command.edit_key": "Modifier la traduction", "command.extract.disable-auto-detect": "Désactiver l'autodétection du texte écrit en dur.", "command.extract.enable-auto-detect": "Valider l'autodétection du texte écrit en dur.", - "command.fulfill_keys": "Remplir les champs vides de Clés", + "command.fulfill_keys": "Remplir les champs vides de clés", "command.go_to_next_usage": "Passer à l'utilisation suivante", "command.go_to_prev_usage": "Passer à l'utilisation précédente", "command.go_to_range": "Aller à la plage", "command.insert_key": "Insérer une clé", "command.locale_visibility_hide": "Cacher le dossier de la locale", - "command.mark_key_as_in_use": "Marquer cette clé comme «en utilisation»", + "command.mark_key_as_in_use": "Marquer cette clé comme « en utilisation »", "command.locale_visibility_show": "Afficher le dossier de la locale", - "command.new_key": "Créer une Clé", + "command.new_key": "Créer une clé", "command.open_editor": "Ouvrir l'éditeur", "command.open_in_editor": "Ouvrir dans l'éditeur", "command.open_key": "Aller à la définition", "command.open_review": "Ouvrir la vérification", "command.open_url": "Ouvrir l'URL", - "command.possible_hard_string": "Possible texte tapé en dur", + "command.possible_hard_string": "Possible texte tapé en brut", "command.refresh_usage": "Rafraîchir le rapport d'utilisation", - "command.rename_key": "Renommer la Clé", + "command.rename_key": "Renommer la clé", "command.set_display_language": "Sélectionner en tant que langue affichée", "command.set_source_language": "Sélectionner en tant que langage source", "command.show_docs": "Montrer la documentation", "command.translate_key": "Traduire", - "command.translate_key_from": "Traduire depuis «{0}»", + "command.translate_key_from": "Traduire depuis « {0} »", "config.annotation_delimiter": "Délimiteur d'annotations", "config.annotation_in_place": "Montrer une annotation sur place au lieu d'ajouter dans la queue", "config.annotation_max_length": "Nombre maximum de caractères à afficher dans les annotations. Le surplus sera affiché sous forme d'ellipse (...)", "config.annotations": "Activer les annotations.", "config.auto_detection": "Activer la détection automatique des langues pour les projets", + "config.baidu_app_secret": "", + "config.baidu_appid": "", "config.deepl_api_key": "Clé API pour utiliser le moteur de traduction DeepL", "config.deepl_log": "Montrer le journal de debug du moteur DeepL", "config.deepl_use_free_api_entry": "Utiliser le point d'entrée gratuite de DeepL", - "config.default_namespace": "Namespace global par défaut", - "config.deprecated": "Déprécié. Utilisez le préfixe «i18n-ally.» directement.", + "config.default_namespace": "Espace de nom global par défaut", + "config.deprecated": "Obsolète. Utilisez le préfixe « i18n-ally. » directement.", "config.derived_keys": "Règles pour marquer les clés dérivées dans le rapport d'utilisation", "config.dir_structure": "Structure de répertoire préféré pour organiser les fichiers de la locale.", "config.disable_path_parsing": "Désactiver la résolution de chemin", @@ -57,7 +59,7 @@ "config.ignored_locales": "Scripts de localisation à ignorer.", "config.include_subfolders": "Recherche récursive dans les répertoires locaux.", "config.indent": "Taille de l'espace d'indentation pour les fichiers locaux.", - "config.keep_fulfill": "Toujours garder les Clés remplies automatiquement.", + "config.keep_fulfill": "Toujours garder les clés remplies automatiquement.", "config.key_max_length": "Si spécifié, la clé générée lors de l'extraction sera tronquée à ce nombre de caractères (à l'exclusion du keyPrefix). Illimitée par défaut.", "config.key_prefix": "Texte à ajouter à la clé d'extraction. Vous pouvez utiliser {fileName} pour le nom de fichier et {fileNameWithoutExt} pour la partie du nom de fichier avant le premier point.", "config.keygen_strategy": "Stratégie de génération de clé", @@ -69,15 +71,18 @@ "config.locale_country_map": "Objet pour mapper le code local de deux lettres au code du pays", "config.locales_paths": "Chemin du répertoire de la locale (par rapport à la racine). Les schémas globaux sont acceptés.", "config.namespace": "Activer les namespaces. Vérifiez la documentation pour plus de détails.", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "Faire correspondre le chemin pour les locales/namespaces personnalisés. Consultez la documentation pour plus de détails.", - "config.preferred_delimiter": "Délimiteur recommandé pour les noms de chemins à trous, par défaut «-»(tiret)", + "config.preferred_delimiter": "Délimiteur recommandé pour les noms de chemins à trous, par défaut « - » (tiret)", "config.prompt_translating_source": "Invite à sélectionner la langue source à chaque fois. Si défini sur False, le langage du système sera automatiquement utilisé.", - "config.readonly": "Mode «Lecture uniquement»", + "config.readonly": "Mode « Lecture uniquement »", "config.refactor_templates": "Tableau (array) de modèles de chaînes. Utilisez `{key}` pour la valeur de remplissage des chemins d'accès.", "config.regex_key": "Chaîne de caractère RegEx", "config.regex_usage_match": "Tableau (array) de chaînes RegEx pour correspondre aux utilisations des clés dans le code. Il remplacera le Regex fourni par les frameworks.", - "config.regex_usage_match_append": "Tableau (array) de chaînes RegEx pour correspondre aux utilisations des clés dans le code. Contrairement à «regex.usageMatch», il s'ajoutera à la liste Regex au lieu de le remplacer.", - "config.review_email": "Email utilisé pour les revues, aussi utilisé comme Gravatar pour l'avatar de profil", + "config.regex_usage_match_append": "Tableau (array) de chaînes RegEx pour correspondre aux utilisations des clés dans le code. Contrairement à « regex.usageMatch », il s'ajoutera à la liste Regex au lieu de le remplacer.", + "config.review_email": "E-mail utilisé pour les revues, aussi utilisé comme Gravatar pour l'avatar de profil", "config.review_enabled": "Activer le système", "config.review_gutters": "Montrer la panneau de revues sur le côté", "config.review_remove_on_resolved": "Supprimez le commentaire au lieu de le marquer comme résolu.", @@ -90,23 +95,24 @@ "config.target_picking_strategy.file-previous": "Extraire le texte dans le fichier locale, précédemment sélectionné, du fichier actuel", "config.target_picking_strategy.global-previous": "Extraire le texte dans le fichier locale, précédemment sélectionné, du fichier actuel (ou autre)", "config.target_picking_strategy.most-similar": "Extraire automatiquement le texte dans le fichier dont le chemin correspond le plus au chemin du fichier actuel", + "config.target_picking_strategy.most-similar-by-key": "Remplissez automatiquement la copie extraite dans le fichier de langue qui correspond le mieux à la clé i18n actuelle", "config.target_picking_strategy.none": "L'utilisateur sélectionne manuellement le fichier dans lequel extraire le texte", "config.translate.engines": "Services de traduction.", "config.translate.fallbackToKey": "Utilisez la clé elle-même pour traduire lorsqu'il n'y a pas de traduction source pour cette clé.", "config.translate.parallels": "Nombre maximum de traducteurs en même temps.", "config.translate_override_existing": "Remplacer les messages existants lors de la traduction", - "config.translate_save_as_candidates": "Sauvegarder les résultats des traductions dans «Candidats de traduction» au lieu d'écrire dans les fichiers locale.", + "config.translate_save_as_candidates": "Sauvegarder les résultats des traductions dans « Candidats de traduction » au lieu d'écrire dans les fichiers locale.", "config.usage.scanning_ignore": "Ignorer les patterns globales pour analyser l'utilisation des clés", "editor.add_description": "Ajouter une description...", "editor.empty": "(vide)", "editor.title": "Éditeur i18n Ally", "editor.translate": "Traduire", - "editor.translate_all_missing": "Traduire Tout ce qui est Manquant", + "editor.translate_all_missing": "Traduire tout ce qui est manquant", "errors.keystyle_not_set": "Le style de clé n'est pas spécifié, opération annulée.", - "errors.translating_empty_source_value": "Traduction source de «{0}» est introuvable. Traduction annulée.", + "errors.translating_empty_source_value": "Traduction source de « {0} » introuvable. Traduction annulée.", "errors.translating_same_locale": "La traduction vers la même locale n'est pas autorisée.", "errors.translating_unknown_error": "Erreur inconnue produite lors de la traduction.", - "errors.unsupported_file_type": "Type de fichier non supporté: {0}", + "errors.unsupported_file_type": "Type de fichier non supporté : {0}", "errors.write_in_readonly_mode": "L'écriture en mode lecture seule est désactivée.", "extname": "i18n Ally", "feedback.document": "Lire la Documentation", @@ -114,25 +120,25 @@ "feedback.report_issues": "Rapport d'issues", "feedback.support": "Nous soutenir", "feedback.twitter_feedback": "Fournir des retours", - "misc.missing_key": "{0} : La Clé i18n «{1}» n'existe pas", - "misc.missing_translation": "{0} : La traduction de «{1}» est manquante", + "misc.missing_key": "{0} : La clé i18n « {1} » n'existe pas", + "misc.missing_translation": "{0} : La traduction de « {1} » est manquante", "notification.migrate": "Migrer", "notification.v2-update": "i18n Ally a été mis à jour à la version 2.0!\n N'hésitez pas à vérifier notre guide de migration.", - "prompt.applying_suggestion": "Appliquer cette suggestion à la clé «{0}»?\n\n{1}", - "prompt.applying_translation_candidate": "Appliquer cette traduction à la clé «{0}»?\n\n{1}", - "prompt.applying_translation_candidate_multiple": "Appliquer l'ensemble des {0} traductions?", + "prompt.applying_suggestion": "Appliquer cette suggestion à la clé « {0} » ?\n\n{1}", + "prompt.applying_translation_candidate": "Appliquer cette traduction à la clé « {0} » ?\n\n{1}", + "prompt.applying_translation_candidate_multiple": "Appliquer l'ensemble des {0} traductions ?", "prompt.button_apply": "Appliquer", "prompt.button_cancel": "Annuler", - "prompt.button_discard": "Jeter", + "prompt.button_discard": "Rejeter", "prompt.button_edit_end_apply": "Éditer", - "prompt.button_override": "Contourner", - "prompt.button_reenter": "Ré-entrer", - "prompt.button_skip": "Continuer sans contourner", + "prompt.button_override": "Remplacer", + "prompt.button_reenter": "Saisir à nouveau", + "prompt.button_skip": "Passer", "prompt.button_yes": "Oui", "prompt.choice_key_to_insert": "Choisissez une clé à insérer", "prompt.choice_key_to_open": "Choisissez une clé à ouvrir dans l'éditeur...", "prompt.choice_locale": "Choisir une locale", - "prompt.config_locales_auto_success": "Chemin de la locale défini automatiquement sur «{0}».", + "prompt.config_locales_auto_success": "Chemin de la locale défini automatiquement sur « {0} ».", "prompt.config_locales_button": "Configurer maintenant", "prompt.config_locales_info": "Configurer le répertoire de la locale pour votre projet.", "prompt.config_locales_success": "Chemin de la locale configurer avec succès.", @@ -140,93 +146,93 @@ "prompt.deepl_api_key_required": "La clé d'API DeepL est requise", "prompt.deepl_error_get_usage": "Erreur lors de l'obtention des données d'usage", "prompt.deepl_usage": "Utilisation de l'API DeepL APı {0} sur {1} caractères traduites", - "prompt.delete_key": "Êtes-vous sûr de supprimer la clé «{0}» de toutes les locales?\n\nCette opération ne peut PAS être annulée.", - "prompt.delete_keys_not_in_use": "Souhaitez-vous réellement supprimer {0} Clé(s) n'étant pas utilisée(s) ?", - "prompt.donate": "Donation", - "prompt.edit_key_in_locale": "{1} | Édition de la Clé «{0}»", - "prompt.enter_file_path_to_store_key": "Entrer le chemin du fichier où stocker la Clé «{0}»", - "prompt.enter_key_path": "Entrer le chemin de la clé pour «{0}»", - "prompt.enter_new_keypath": "Entrer le nouveau chemin des Clés", + "prompt.delete_key": "Êtes-vous sûr de supprimer la clé « {0} » de toutes les locales ?\n\nCette opération ne peut PAS être annulée.", + "prompt.delete_keys_not_in_use": "Souhaitez-vous réellement supprimer {0} clé(s) n'étant pas utilisée(s) ?", + "prompt.donate": "Faire un don", + "prompt.edit_key_in_locale": "{1} | Édition de la clé « {0} »", + "prompt.enter_file_path_to_store_key": "Entrer le chemin du fichier où stocker la clé « {0} »", + "prompt.enter_key_path": "Entrer le chemin de la clé pour « {0} »", + "prompt.enter_new_keypath": "Entrer le nouveau chemin des clés", "prompt.error_on_parse_custom_regex": "Échec de l'analyse de la chaîne d'expression régulière {0}. Vérifiez votre configuration.", "prompt.existing_translation": "Traduction existante", "prompt.extraction_canceled": "Extraction annulée.", - "prompt.failed_to_locate_key": "Échec de la localisation de la Clé «{0}».", - "prompt.frameworks_not_found": "Les Frameworks suivant n'ont pas été trouvés, merci de regarder vos paramètres.\n{0}", - "prompt.fullfill_missing_all_confirm": "Êtes-vous sûr(e) de remplir toutes les Clés vides à travers tous les fichiers de la locale ?\n\nCette opération est irréversible.", - "prompt.fullfill_missing_confirm": "Êtes-vous sûr(e) de remplir {0} Clés vides dans {1} ?\n\nCette opération est irréversible.", + "prompt.failed_to_locate_key": "Échec de la localisation de la clé « {0} ».", + "prompt.frameworks_not_found": "Les frameworks suivant n'ont pas été trouvés, merci de regarder vos paramètres.\n{0}", + "prompt.fullfill_missing_all_confirm": "Êtes-vous sûr(e) de remplir toutes les clés vides à travers tous les fichiers de la locale ?\n\nCette opération est irréversible.", + "prompt.fullfill_missing_confirm": "Êtes-vous sûr(e) de remplir {0} clés vides dans {1} ?\n\nCette opération est irréversible.", "prompt.invalid_keypath": "Chemin invalide !", - "prompt.key_already_exists": "Clé déjà existante. Souhaitez-vous contourner la valeur existante ou ré-entrer la Clé ?", + "prompt.key_already_exists": "Clé déjà existante. Souhaitez-vous contourner la valeur existante ou ré-entrer la clé ?", "prompt.key_copied": "Clé copiée.", - "prompt.keys_removed": "{0} clés retirés", + "prompt.keys_removed": "{0} clés retirées", "prompt.keystyle_flat": "Modèle plat", "prompt.keystyle_flat_example": "par exemple : { \"a.b.c\": \"...\" }", "prompt.keystyle_nested": "Modèle emboîté", - "prompt.keystyle_nested_example": "par exemple : { \"a\": { \"b\": { \"c\": «...» } } }", + "prompt.keystyle_nested_example": "par exemple : { \"a\": { \"b\": { \"c\": « ... » } } }", "prompt.keystyle_select": "Quel modèle souhaitez-vous utiliser pour organiser vos fichiers de la locale ?", "prompt.locales_dir_not_found": "Répertoire de la locale non trouvé. i18n Ally est désactivé.", - "prompt.new_key_path": "Entrez le chemin de la nouvelle Clé.", + "prompt.new_key_path": "Entrez le chemin de la nouvelle clé.", "prompt.no_locale_loaded": "Aucun fichier locale chargé. Quelque chose s'est probablement mal passé avec la configuration de votre projet.", "prompt.replace_text_as": "Remplacer le texte par :", "prompt.select_display_locale": "Choisir la langue d'affichage. ({0})", "prompt.select_file_to_open": "Choisissez le fichier à ouvrir", - "prompt.select_file_to_store_key": "Sélectionnez le fichier pour stocker la clé «{0}»", + "prompt.select_file_to_store_key": "Sélectionnez le fichier pour stocker la clé « {0} »", "prompt.select_source_language_for_translating": "Sélectionnez la langue source pour la traduction. ({0})", "prompt.select_source_locale": "Choisissez la langue source ({0})", "prompt.show_error_log": "Montrer les rapports", "prompt.star_on_github": "Mettre une étoile sur Github", "prompt.support": "i18n Ally est disponible gratuitement pour tous, si vous cette extension utile, considérez que vous nous supportez. Merci ! ❤", "prompt.translate_cancelled_multiple": "Traduction de {0} clés annulé.", - "prompt.translate_done_multiple": "{0} Clé(s) traduite(s).", - "prompt.translate_done_single": "Traduction de «{0}» terminé.", + "prompt.translate_done_multiple": "{0} clé(s) traduite(s).", + "prompt.translate_done_single": "Traduction de « {0} » terminé.", "prompt.translate_edit_translated": "Éditer le résultat", "prompt.translate_failed_multiple": "{0} clés n'ont pu être traduites.", "prompt.translate_failed_single": "{0} ne peut être traduire en {1}", "prompt.translate_in_progress": "Traduire", - "prompt.translate_multiple_confirm": "Êtes-vous sûr de vouloir traduire {0} clés?", + "prompt.translate_multiple_confirm": "Êtes-vous sûr de vouloir traduire {0} clés ?", "prompt.translate_no_jobs": "Aucune traduction requise.", "prompt.writing_js": "Le mode « Écriture » n'est pas disponible pour les fichiers JS/TS.", - "refactor.extract_ignore": "Ignorer globalement la détection de «{0}».", - "refactor.extract_ignore_by_file": "Ignorer la détection de «{0}» pour le fichier en cours.", - "refactor.extract_text": "🌍 Extract text into i18n messages", - "refactor.extracting_not_support_for_lang": "L'extraction pour la langue «{0}» n'est pas supporté", - "refactor.replace_with": "Remplacez le texte par la traduction existante: «{0}»", + "refactor.extract_ignore": "Ignorer globalement la détection de « {0} ».", + "refactor.extract_ignore_by_file": "Ignorer la détection de « {0} » pour le fichier en cours.", + "refactor.extract_text": "🌍 Extraire du texte dans les messages d'i18n", + "refactor.extracting_not_support_for_lang": "L'extraction pour la langue « {0} » n'est pas supporté", + "refactor.replace_with": "Remplacez le texte par la traduction existante : « {0} »", "review.accept_suggestion": "Accepter la Suggestion", "review.apply_suggestion": "Appliquer la suggestion", "review.apply_translation_candidate": "Appliquer la proposition de traduction", "review.approve": "Approuver", "review.comment": "Commenter", "review.edit": "Éditer", - "review.leave_comment": "Laisser un Commentaire", + "review.leave_comment": "Laisser un commentaire", "review.optional": "(Facultatif)", "review.placeholder.approve": "Approuvé", "review.placeholder.comment": "N'a rien dit", "review.placeholder.request_change": "Changement demandé", - "review.request_change": "Demander des Changements", + "review.request_change": "Proposer des changements", "review.request_change_messages": "Changer", "review.resolve": "Résoudre", - "review.resolve_all": "Résoudre tout", - "review.review": "Revue", + "review.resolve_all": "Tout résoudre", + "review.review": "Vérifier", "review.suggestion": "Suggestion", "review.suggestions": "Suggestions", "review.title": "Revue i18n Ally", "review.translation_candidates": "Candidats", "review.unknown_user": "Inconnu", "view.current_file": "Fichier ouvert", - "view.current_file_hard_strings": "Texte entré en dur [beta]", + "view.current_file_hard_strings": "Texte entré en brut [bêta]", "view.current_file_hard_strings_expand_to_detect": "(Développer pour détecter)", "view.current_file_hard_strings_not_supported": "{0} n'est pas supporté pour le moment", "view.current_file_keys_in_use": "Clés en utilisation", - "view.current_file_keys_not_found": "Clés non trouvés", - "view.help_feedback": "Aide & Retours", + "view.current_file_keys_not_found": "Clés non trouvées", + "view.help_feedback": "Aide & retours", "view.i18n_keys": "i18n Ally", - "view.progress": "En progression", + "view.progress": "En cours", "view.progress_submenu.empty_keys": "Vide", "view.progress_submenu.missing_keys": "Aucune traduction", "view.progress_submenu.translated_keys": "Traduites", "view.tree": "Arborescence", "view.usage": "Rapport d'utilisation", - "view.usage_keys_in_use": "{0} Clé(s) en utilisation.", - "view.usage_keys_missing": "{0} Clé(s) manquante(s)", - "view.usage_keys_not_in_use": "{0} Clé(s) NON-utilisée(s).", - "view.usage_report_none": "Appuyez sur rafraîchir pour commencer l'analyse de l'utilisation des Clés." + "view.usage_keys_in_use": "{0} clé(s) en utilisation.", + "view.usage_keys_missing": "{0} clé(s) manquante(s)", + "view.usage_keys_not_in_use": "{0} clé(s) non-utilisée(s).", + "view.usage_report_none": "Appuyez sur rafraîchir pour commencer l'analyse de l'utilisation des clés." } diff --git a/locales/hu.json b/locales/hu.json index bddc8c34..677bd2b5 100644 --- a/locales/hu.json +++ b/locales/hu.json @@ -69,6 +69,9 @@ "config.locale_country_map": "Egy objektum a két karakteres locale-kódokat országkódra képző szolgáltatáshoz.", "config.locales_paths": "Az elérési utak a locale fájlokhoz (a projekt gyökere relativ elérési útvonala). Globális mintát is elfogad.", "config.namespace": "Névterek engedélyezése. További információért lásd a dokumentációt.", +"config.openai_api_key": "", +"config.openai_api_model": "", +"config.openai_api_root": "", "config.path_matcher": "A locale / névterekhez tartozó egyezési út. További információért lásd a dokumentációt.", "config.preferred_delimiter": "Az összetett kulcsú útvonalak preferált határolója, alapértelmezetten az - (kötőjel)", "config.prompt_translating_source": "Mindig kérdezze meg forrás nyelvre fordításkor. Ha hamisra van állítva, a konfigurációban megadott forrásnyelv lesz használva.", diff --git a/locales/ja.json b/locales/ja.json index d8cffcaf..66486405 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -37,6 +37,8 @@ "config.annotation_max_length": "インラインアノテーションの最大文字数です。超過している部分は(...)と表示されます。", "config.annotations": "インラインアノテーションを有効にする.", "config.auto_detection": "", + "config.baidu_app_secret": "", + "config.baidu_appid": "", "config.deepl_api_key": "", "config.deepl_log": "", "config.deepl_use_free_api_entry": "", @@ -69,6 +71,9 @@ "config.locale_country_map": "", "config.locales_paths": "ロケールディレクトリのパス (プロジェクトルートの相対パス), glob pattern が有効です。", "config.namespace": "", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "", "config.preferred_delimiter": "キーパスを構成するデリミタ。デフォルトは\"-\"(ダッシュ)", "config.prompt_translating_source": "", @@ -90,6 +95,7 @@ "config.target_picking_strategy.file-previous": "", "config.target_picking_strategy.global-previous": "", "config.target_picking_strategy.most-similar": "", + "config.target_picking_strategy.most-similar-by-key": "抽出したコピーを、現在のi18nキーに最も一致する言語ファイルに自動的に入力します", "config.target_picking_strategy.none": "", "config.translate.engines": "", "config.translate.fallbackToKey": "", diff --git a/locales/ko.json b/locales/ko.json index 2622d6bd..4c75feb4 100644 --- a/locales/ko.json +++ b/locales/ko.json @@ -69,6 +69,9 @@ "config.locale_country_map": "두 글자인 로케일 코드를 국가 코드에 매핑하는 개체", "config.locales_paths": "로케일 디렉토리 경로(프로젝트 루트 기준). \nGlob 패턴도 허용됩니다.", "config.namespace": "네임스페이스 활성화. \n자세한 내용은 문서를 확인하세요.", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "사용자 정의 로케일/네임스페이스에 대한 일치 경로. \n자세한 내용은 문서를 확인하세요.", "config.preferred_delimiter": "구성된 키 경로의 기본 구분 기호, 기본값은 \"-\"(대시)", "config.prompt_translating_source": "번역할 때마다 소스 로케일을 선택하라는 메시지가 표시됩니다. \nfalse로 설정하면 구성의 소스 언어가 사용됩니다.", diff --git a/locales/nb-NO.json b/locales/nb-NO.json index dd937c13..658020bb 100644 --- a/locales/nb-NO.json +++ b/locales/nb-NO.json @@ -37,6 +37,8 @@ "config.annotation_max_length": "Maksimalt antall tegn vist i hjelpevindu. Resterende del vil bli vist som (...)", "config.annotations": "Slå på hjelpevindu", "config.auto_detection": "", + "config.baidu_app_secret": "", + "config.baidu_appid": "", "config.deepl_api_key": "", "config.deepl_log": "", "config.deepl_use_free_api_entry": "", @@ -69,6 +71,9 @@ "config.locale_country_map": "", "config.locales_paths": "Bane til oversettelsesmappe (relativt til prosjektets rotmappe). Glob-mønster er også akseptabelt.", "config.namespace": "", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "", "config.preferred_delimiter": "Foretrukket skilletegn for komponert nøkkelbane, \"-\"(bindestrek) som standard", "config.prompt_translating_source": "", @@ -90,6 +95,7 @@ "config.target_picking_strategy.file-previous": "", "config.target_picking_strategy.global-previous": "", "config.target_picking_strategy.most-similar": "", + "config.target_picking_strategy.most-similar-by-key": "Fyll automatisk den utpakkede kopien inn i språkfilen som passer best til gjeldende i18n-nøkkel", "config.target_picking_strategy.none": "", "config.translate.engines": "", "config.translate.fallbackToKey": "", diff --git a/locales/nl-NL.json b/locales/nl-NL.json index 2f95a56f..eec160e7 100644 --- a/locales/nl-NL.json +++ b/locales/nl-NL.json @@ -37,6 +37,8 @@ "config.annotation_max_length": "Max. aantal karakters zichtbaar binnen inline annotaties. Overschreden delen worden getoond als ellipses (...)", "config.annotations": "Inline annotaties inschakelen.", "config.auto_detection": "", + "config.baidu_app_secret": "", + "config.baidu_appid": "", "config.deepl_api_key": "", "config.deepl_log": "", "config.deepl_use_free_api_entry": "", @@ -69,6 +71,9 @@ "config.locale_country_map": "", "config.locales_paths": "Pad naar locale folder (relatief aan project root), glob patroon is acceptabel.", "config.namespace": "Schakel in om sleutels te onderscheiden op basis van bestandsnaam. Zie documentatie voor meer uitleg.", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "Pad voor onderscheiding van sleutels op basis van folderstructuur/bestandsnaam. Zie documentatie voor meer uitleg.", "config.preferred_delimiter": "Gewenst scheidingsteken voor sleutel pad, standaard waarde \"-\"(dash)", "config.prompt_translating_source": "Altijd vragen om de bron locale te selectering bij vertalingen. Indien false, dan zal de bron taal in de configuratie gebruikt worden.", @@ -90,6 +95,7 @@ "config.target_picking_strategy.file-previous": "", "config.target_picking_strategy.global-previous": "", "config.target_picking_strategy.most-similar": "", + "config.target_picking_strategy.most-similar-by-key": "Vul de uitgepakte kopie automatisch in het taalbestand dat het beste overeenkomt met de huidige i18n-sleutel", "config.target_picking_strategy.none": "", "config.translate.engines": "", "config.translate.fallbackToKey": "Gebruik de sleutel zelf als vertaling, als er geen originele vertaling bestaat", diff --git a/locales/pt-BR.json b/locales/pt-BR.json index 7e09b8f5..207fa8f1 100644 --- a/locales/pt-BR.json +++ b/locales/pt-BR.json @@ -37,6 +37,8 @@ "config.annotation_max_length": "Número máximo de caracteres exibidos nas anotações inline. O restante será exibido em forma de reticências (...)", "config.annotations": "Habilitar anotações inline", "config.auto_detection": "", + "config.baidu_app_secret": "", + "config.baidu_appid": "", "config.deepl_api_key": "", "config.deepl_log": "", "config.deepl_use_free_api_entry": "", @@ -69,6 +71,9 @@ "config.locale_country_map": "", "config.locales_paths": "Caminho para os arquivos de tradução (relativo à raiz do projeto). O padrão glob também é aceito.", "config.namespace": "", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "", "config.preferred_delimiter": "Delimitador para o caminho da chave, o padrão é \"-\"(hífen)", "config.prompt_translating_source": "Sempre perguntar idioma de origem durante tradução. Se o valor for \"false\", será usado o idioma de origem das configurações.", @@ -90,6 +95,7 @@ "config.target_picking_strategy.file-previous": "", "config.target_picking_strategy.global-previous": "", "config.target_picking_strategy.most-similar": "", + "config.target_picking_strategy.most-similar-by-key": "Preencha automaticamente a cópia extraída no arquivo de idioma que melhor corresponde à chave i18n atual", "config.target_picking_strategy.none": "", "config.translate.engines": "", "config.translate.fallbackToKey": "", diff --git a/locales/ru.json b/locales/ru.json index c7884768..fb3f39b5 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -37,6 +37,8 @@ "config.annotation_max_length": "Максимальное количество символов, отображаемых во встроенных аннотациях. Лишние символы будут отображаться в виде многоточия (...)", "config.annotations": "Включить встроенные аннотации.", "config.auto_detection": "Включить автоматическое определение переводов для проектов", + "config.baidu_app_secret": "", + "config.baidu_appid": "", "config.deepl_api_key": "API ключ для использования DeepL", "config.deepl_log": "Отображать отладочные журналы DeepL", "config.deepl_use_free_api_entry": "Использовать бесплатную версию DeepL API", @@ -69,6 +71,9 @@ "config.locale_country_map": "Объект для сопоставления двухбуквенного кода перевода с кодом страны", "config.locales_paths": "Путь к каталогу переводов (относительно корня проекта). Допускается шаблон соответствия Glob", "config.namespace": "Включить пространства имен. Подробности смотрите в документации.", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "Сопоставить путь для пользовательского перевода/пространства имен. Подробности смотрите в документации.", "config.preferred_delimiter": "Желаемый разделитель пути составного ключа, значение по умолчанию \"-\"(тире)", "config.prompt_translating_source": "Предлагать выбрать исходный перевод при переводе каждый раз. Если установлено false, будет использоваться исходный перевод из конфигурации.", @@ -90,6 +95,7 @@ "config.target_picking_strategy.file-previous": "Извлекать текст в предыдущий выбранный файл перевода текущего файла", "config.target_picking_strategy.global-previous": "Извлекать текст в (текущий или другой) файл предыдущего выбранного файла перевода", "config.target_picking_strategy.most-similar": "Автоматически заполнять извлеченную копию в файл перевода, который лучше всего соответствует текущему пути к файлу", + "config.target_picking_strategy.most-similar-by-key": "Автоматически заполнять извлеченную копию языковым файлом, который лучше всего соответствует текущему ключу i18n.", "config.target_picking_strategy.none": "Пользователь вручную выбирает файл для извлечения текста", "config.translate.engines": "Сервисы перевода.", "config.translate.fallbackToKey": "Использовать сам ключ для перевода, если для этого ключа нет перевода", diff --git a/locales/sv-SE.json b/locales/sv-SE.json index 63174de9..da7c84e9 100644 --- a/locales/sv-SE.json +++ b/locales/sv-SE.json @@ -37,6 +37,8 @@ "config.annotation_max_length": "Max antal bokstävers som visas i insatta anteckningen. Överflödiga bokstäver kommer visas som en ellips (…)", "config.annotations": "Aktivera insatta anteckningar.", "config.auto_detection": "", + "config.baidu_app_secret": "", + "config.baidu_appid": "", "config.deepl_api_key": "", "config.deepl_log": "", "config.deepl_use_free_api_entry": "", @@ -69,6 +71,9 @@ "config.locale_country_map": "Ett objekt för att mappa två-bokstäverskod till landskod", "config.locales_paths": "Sökväg till locale-filer (relativt projektets rot). `glob` mönster är också accepterat.", "config.namespace": "Aktivera \"namespaces\". Se dokumentation för mer detaljer.", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "Matcha sökväg för egna locale-filer/namespace. Se dokumentation för mer detaljer.", "config.preferred_delimiter": "Föredragen avskiljare av sammansatta nyckelsökvägar, som standard satt till \"-\" (bindestreck)", "config.prompt_translating_source": "Fråga om att välja locale-filskälla varje gång vid översättning. Om satt till `false` kommer locale-filskällan i konfigurationen användas.", @@ -90,6 +95,7 @@ "config.target_picking_strategy.file-previous": "Extrahera text till nuvarande fils tidigare valda locale-fil", "config.target_picking_strategy.global-previous": "Extrahera text till (nuvarande elle annan) fils tidigare valda locale-fil", "config.target_picking_strategy.most-similar": "Extrahera text automatiskt till den fil vars sökväg mest stämmer överens med nuvarande filens sökväg", + "config.target_picking_strategy.most-similar-by-key": "Fyll automatiskt i den extraherade kopian i den språkfil som bäst matchar den aktuella i18n-nyckeln", "config.target_picking_strategy.none": "Välj själv vilken fil att extrahera text till", "config.translate.engines": "Översättningstjänster.", "config.translate.fallbackToKey": "Använd nyckeln själv för att översätta när det inte finns någon källspråksöversättning för den nyckeln.", diff --git a/locales/th.json b/locales/th.json index 1dfa78ec..e970fefe 100644 --- a/locales/th.json +++ b/locales/th.json @@ -69,6 +69,9 @@ "config.locale_country_map": "วัตถุที่จะ map รหัสตำแหน่งภาษาตัวอักษรสองตัวกับรหัสประเทศ", "config.locales_paths": "เส้นทางไปยังไดเร็กทอรีภาษา (สัมพันธ์กับเส้นทางแรกสุดโปรเจ็กต์) รูปแบบ Glob ก็เป็นที่ยอมรับเช่นกัน", "config.namespace": "เปิดใช้งาน namespace ตรวจสอบเอกสารสำหรับรายละเอียดเพิ่มเติม", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "จับคู่เส้นทางสำหรับภาษา/namespace ที่กำหนดเอง ตรวจสอบเอกสารสำหรับรายละเอียดเพิ่มเติม", "config.preferred_delimiter": "ตัวคั่นที่ต้องการของเส้นทางที่ประกอบขึ้น ค่าเริ่มต้นคือ \"-\"(เส้นประ)", "config.prompt_translating_source": "พร้อมท์ให้เลือกภาษาต้นทางในการแปลทุกครั้ง หากตั้งค่าเป็นเท็จ ภาษาต้นทางในการกำหนดค่าจะถูกใช้", diff --git a/locales/tr.json b/locales/tr.json index a6c52ab1..f6d53d7a 100644 --- a/locales/tr.json +++ b/locales/tr.json @@ -37,6 +37,8 @@ "config.annotation_max_length": "Satır aralığında gösterilen ek açıklamaların maksimum karakter uzunluğu. Fazladan karakterler noktalı şekilde görüntülenecektir (...)", "config.annotations": "Satır aralığında ek açıklamaları etkinleştir", "config.auto_detection": "Projeler için otomatik çeviri algılamasını etkinleştir", + "config.baidu_app_secret": "", + "config.baidu_appid": "", "config.deepl_api_key": "DeepL çeviri sistemini kullanmak için API anahtarı", "config.deepl_log": "DeepL sisteminin hata ayıklama kayıtlarını göster", "config.deepl_use_free_api_entry": "DeepL'in Bedava API giriş noktasını kullanın", @@ -69,6 +71,9 @@ "config.locale_country_map": "İki harfli yerel kodunu ülke koduyla eşleştirmek için bir 'object'", "config.locales_paths": "Çeviri dosyalarının bulunduğu alan (projenin olduğu yere göre). Global patternler de kabul edilmektedir.", "config.namespace": "Namespace'lerini etkinleştirin. Daha fazla ayrıntı için dokümantasyona göz atın.", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "Dosya yolunu özelleştirilmiş bir dil/namespace'e göre eşleştirin. Daha fazla ayrıntı için dokümantasyona göz atın.", "config.preferred_delimiter": "Bileşik anahtar yolları için ayıran karakter, varsayılan \"-\" (tire)", "config.prompt_translating_source": "Her seferinde çeviride kaynak dili seçmesini isteyin. Eğer false olarak ayarlıysa, yapılandırmadaki kaynak dil kullanılacaktır.", @@ -90,6 +95,7 @@ "config.target_picking_strategy.file-previous": "Metni mevcut dosyanın önceki seçili dil dosyasına çıkartın", "config.target_picking_strategy.global-previous": "Metni (mevcut veya başka) dosyanın önceki seçili yerel ayar dosyasına çıkartın", "config.target_picking_strategy.most-similar": "Geçerli dosyanın bulunduğu alana en çok uyan yolu dosyaya otomatik olarak ayıklayın", + "config.target_picking_strategy.most-similar-by-key": "Çıkarılan kopyayı, geçerli i18n anahtarıyla en iyi eşleşen dil dosyasına otomatik olarak doldurun", "config.target_picking_strategy.none": "Kullanıcı metnin çıkarılacağı dosyayı el ile seçer", "config.translate.engines": "Çeviri hizmetleri.", "config.translate.fallbackToKey": "Bu anahtar için kaynak çevirisi olmadığında çeviri yapmak için anahtarın kendisini kullanın.", diff --git a/locales/uk-UA.json b/locales/uk-UA.json index 3821d85b..038f709f 100644 --- a/locales/uk-UA.json +++ b/locales/uk-UA.json @@ -37,6 +37,8 @@ "config.annotation_max_length": "Максимальна кількість символів, що відображаються у вбудованих анотаціях. Зайві символи будуть відображатися у вигляді трьох крапок (...)", "config.annotations": "Включити вбудовані анотації.", "config.auto_detection": "", + "config.baidu_app_secret": "", + "config.baidu_appid": "", "config.deepl_api_key": "Ключ для використання API DeepL", "config.deepl_log": "Відображати налагоджувальні журнали DeepL", "config.deepl_use_free_api_entry": "", @@ -69,6 +71,9 @@ "config.locale_country_map": "Об'єкт для зіставлення двобуквеного коду мовного стандарту з кодом країни", "config.locales_paths": "Шлях до каталогу перекладів (щодо кореня проекту). Допускається шаблон відповідності Glob", "config.namespace": "Включити `namespace`. Подробиці дивіться в документації.", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "Шлях для розрізнення ключів на основі структури папок/імені файлу. Подробиці дивіться в документації.", "config.preferred_delimiter": "Бажаний роздільник шляху складеного ключа, значення за замовчуванням \"-\"(тире)", "config.prompt_translating_source": "Пропонувати обирати мовний стандарт кожен раз при перекладі. Якщо встановлено false, буде використовуватися мова з конфігурації.", @@ -90,6 +95,7 @@ "config.target_picking_strategy.file-previous": "Автоматично заповнювати обраний файл перекладу при останньому завантаженні з поточного файлу", "config.target_picking_strategy.global-previous": "Автоматично заповнювати обраний файл перекладу при добуванні копії в останньому (поточному/іншому) файлі", "config.target_picking_strategy.most-similar": "Автоматично заповнювати витягнуту копію в файл перекладу, який найкраще відповідає поточному шляху до файлу", + "config.target_picking_strategy.most-similar-by-key": "Автоматично заповнюйте витягнуту копію в мовний файл, який найкраще відповідає поточному ключу i18n", "config.target_picking_strategy.none": "Користувач вручну обирає файл для вилучення тексту", "config.translate.engines": "Сервіс для перекладу.", "config.translate.fallbackToKey": "Використовувати сам ключ для перекладу, якщо для цього ключа нема переводу", diff --git a/locales/zh-CN.json b/locales/zh-CN.json index 1fbcf25a..8097d376 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -37,6 +37,8 @@ "config.annotation_max_length": "内联注释显示的最大字符数。超出的部分将显示为省略号(...)", "config.annotations": "启用内联注释", "config.auto_detection": "", + "config.baidu_app_secret": "百度平台分配的密钥", + "config.baidu_appid": "百度平台APPID", "config.deepl_api_key": "", "config.deepl_log": "", "config.deepl_use_free_api_entry": "", @@ -69,6 +71,9 @@ "config.locale_country_map": "将两个字母的区域设置代码映射到国家/地区代码的对象", "config.locales_paths": "翻译文件夹路径 (相对于项目根目录),你也可以使用Glob匹配模式。", "config.namespace": "启用命名空间。查看文档了解更多详细信息。", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "匹配自定义区域设置/命名空间的路径。查看文档了解更多详细信息。", "config.preferred_delimiter": "组合键路径的默认分隔符,默认为 \"-\"(短划线)", "config.prompt_translating_source": "每次翻译时都会提示选择源语言环境。\n如果设置为false,将使用配置中的源语言。", @@ -90,6 +95,7 @@ "config.target_picking_strategy.file-previous": "自动填入上次抽取当前文件中的文案时选择的语言文件中", "config.target_picking_strategy.global-previous": "自动填入上次抽取(当前/其他)文件中的文案时选择的语言文件中", "config.target_picking_strategy.most-similar": "自动将抽取的文案填入与当前文件路径最匹配的语言文件中", + "config.target_picking_strategy.most-similar-by-key": "自动将抽取的文案填入与当前i18n key最匹配的语言文件中", "config.target_picking_strategy.none": "用户手动选择将文本抽取到哪个语言文件", "config.translate.engines": "翻译服务提供商", "config.translate.fallbackToKey": "当对应路径没有翻译时,使用路径本身进行翻译", diff --git a/locales/zh-TW.json b/locales/zh-TW.json index 9376870e..a1dd5621 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -37,6 +37,8 @@ "config.annotation_max_length": "內聯註釋顯示的最大文字數。超出的部分將顯示為省略號(...)", "config.annotations": "啟用內聯註釋", "config.auto_detection": "", + "config.baidu_app_secret": "", + "config.baidu_appid": "", "config.deepl_api_key": "", "config.deepl_log": "", "config.deepl_use_free_api_entry": "", @@ -69,6 +71,9 @@ "config.locale_country_map": "將兩個字母的區域設置代碼映射到國家/地區代碼的對象", "config.locales_paths": "翻譯資料夾路徑 (相對於專案根目錄),你也可以使用Glob匹配模式。", "config.namespace": "啟用命名空間。\n查看文件了解更多詳細信息。", + "config.openai_api_key": "", + "config.openai_api_model": "", + "config.openai_api_root": "", "config.path_matcher": "匹配自定義區域設置/命名空間的路徑。\n查看文件了解更多詳細信息。", "config.preferred_delimiter": "組合鍵路徑的首選分隔符,默認為 \"-\"(短劃線)", "config.prompt_translating_source": "每次翻譯時都會提示選擇源語言環境。\n如果設置為false,將使用配置中的源語言。", @@ -90,6 +95,7 @@ "config.target_picking_strategy.file-previous": "自動填入上次抽取當前文件中的文案時選擇的語言文件中", "config.target_picking_strategy.global-previous": "自動填入上次抽取(當前/其他)文件中的文案時選擇的語言文件中", "config.target_picking_strategy.most-similar": "自動將抽取的文案填入與當前文件路徑最匹配的語言文件中", + "config.target_picking_strategy.most-similar-by-key": "自動將抽取的文案填入與當前i18n key最匹配的語言文件中", "config.target_picking_strategy.none": "用戶手動選擇將文本抽取到哪個語言文件", "config.translate.engines": "翻譯服務供應商", "config.translate.fallbackToKey": "當對應路徑沒有翻譯時,使用路徑本身進行翻譯", diff --git a/package.json b/package.json index 168afd0a..19c8b613 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "publisher": "lokalise", "name": "i18n-ally", - "version": "2.9.1", + "version": "2.10.0", "displayName": "i18n Ally", "description": "🌍 All in one i18n extension for VS Code", "keywords": [ @@ -65,7 +65,7 @@ "pofile": "^1.1.1", "properties": "^1.2.1", "qs": "^6.10.3", - "semver": "^7.3.5", + "semver": "^7.5.2", "string-similarity": "^4.0.4", "ts-node": "^9.1.1", "typescript": "^4.3.5", @@ -813,6 +813,7 @@ "ngx-translate", "i18next", "react-i18next", + "i18next-shopify", "i18n-tag", "flutter", "vue-sfc", @@ -831,7 +832,8 @@ "lingui", "jekyll", "fluent-vue", - "fluent-vue-sfc" + "fluent-vue-sfc", + "next-intl" ] }, "description": "%config.enabled_frameworks%" @@ -867,6 +869,19 @@ "default": false, "description": "%config.sort_keys%" }, + "i18n-ally.sortCompare": { + "type": "string", + "enum": [ + "binary", + "locale" + ], + "default": "binary", + "description": "%config.sort_compare%" + }, + "i18n-ally.sortLocale": { + "type": "string", + "description": "%config.sort_locale%" + }, "i18n-ally.preferredDelimiter": { "type": "string", "default": "-", @@ -1023,7 +1038,9 @@ "google", "google-cn", "deepl", - "libretranslate" + "libretranslate", + "baidu", + "openai" ] }, "default": [ @@ -1056,6 +1073,16 @@ "default": null, "description": "%config.deepl_api_key%" }, + "i18n-ally.translate.baidu.appid": { + "type": "string", + "default": null, + "description": "%config.baidu_appid%" + }, + "i18n-ally.translate.baidu.apiSecret": { + "type": "string", + "default": null, + "description": "%config.baidu_app_secret%" + }, "i18n-ally.translate.deepl.enableLog": { "type": "boolean", "default": false, @@ -1071,6 +1098,33 @@ "default": "http://localhost:5000", "description": "%config.libretranslate_api_root%" }, + "i18n-ally.translate.openai.apiKey": { + "type": "string", + "default": null, + "description": "%config.openai_api_key%" + }, + "i18n-ally.translate.openai.apiRoot": { + "type": "string", + "default": "https://api.openai.com", + "description": "%config.openai_api_root%" + }, + "i18n-ally.translate.openai.apiModel": { + "type": "string", + "default": "gpt-3.5-turbo", + "enum": [ + "gpt-3.5-turbo", + "gpt-3.5-turbo-16k", + "gpt-3.5-turbo-0301", + "gpt-3.5-turbo-0613", + "gpt-4", + "gpt-4-0314", + "gpt-4-0613", + "gpt-4-32k", + "gpt-4-32k-0314", + "gpt-4-32k-0613" + ], + "description": "%config.openai_api_model%" + }, "i18n-ally.usage.scanningIgnore": { "type": "array", "items": { @@ -1136,7 +1190,8 @@ "enum": [ "slug", "random", - "empty" + "empty", + "source" ], "description": "%config.keygen_strategy%" }, @@ -1169,6 +1224,7 @@ "enum": [ "none", "most-similar", + "most-similar-by-key", "file-previous", "global-previous" ], @@ -1176,7 +1232,8 @@ "%config.target_picking_strategy.none%", "%config.target_picking_strategy.most-similar%", "%config.target_picking_strategy.file-previous%", - "%config.target_picking_strategy.global-previous%" + "%config.target_picking_strategy.global-previous%", + "%config.target_picking_strategy.most-similar-by-key%" ], "description": "%config.target_picking_strategy%" }, @@ -1225,7 +1282,7 @@ "description": "%config.args_suffix%" }, "i18n-ally.derivedKeyRules": { - "deprecationMessage": "Depreacted. Use \"i18n-ally.usage.derivedKeyRules\" instead." + "deprecationMessage": "Deprecated. Use \"i18n-ally.usage.derivedKeyRules\" instead." }, "i18n-ally.filenameMatchRegex": { "deprecationMessage": "Deprecated. Use \"i18n-ally.pathMatcher\" instead." @@ -1234,7 +1291,7 @@ "deprecationMessage": "Deprecated. Use \"i18n-ally.namespace\" instead." }, "i18n-ally.keyMatchRegex": { - "deprecationMessage": "Depreacted. Use \"i18n-ally.regex.key\" instead." + "deprecationMessage": "Deprecated. Use \"i18n-ally.regex.key\" instead." }, "vue-i18n-ally.localesPaths": { "deprecationMessage": "%config.deprecated%" diff --git a/res/flags/es-ca.svg b/res/flags/es-ca.svg new file mode 100644 index 00000000..17b7dbc2 --- /dev/null +++ b/res/flags/es-ca.svg @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/res/flags/es-eu.svg b/res/flags/es-eu.svg new file mode 100644 index 00000000..7a5909bf --- /dev/null +++ b/res/flags/es-eu.svg @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/res/flags/es-gl.svg b/res/flags/es-gl.svg new file mode 100644 index 00000000..7e0427fe --- /dev/null +++ b/res/flags/es-gl.svg @@ -0,0 +1,18 @@ + + + \ No newline at end of file diff --git a/src/commands/manipulations/newKey.ts b/src/commands/manipulations/newKey.ts index baa73db5..74773d84 100644 --- a/src/commands/manipulations/newKey.ts +++ b/src/commands/manipulations/newKey.ts @@ -9,7 +9,7 @@ export async function NewKey(keypath?: string) { try { keypath = await window.showInputBox({ - value: keypath || '', + value: typeof keypath === 'string' ? keypath : '', prompt: i18n.t('prompt.new_key_path'), ignoreFocusOut: true, }) @@ -61,7 +61,7 @@ export async function NewKey(keypath?: string) { }) } } - catch (err) { + catch (err: any) { Log.error(err.toString()) } } diff --git a/src/core/Analyst.ts b/src/core/Analyst.ts index 94be93c1..d60848ba 100644 --- a/src/core/Analyst.ts +++ b/src/core/Analyst.ts @@ -127,7 +127,6 @@ export class Analyst { const allKeys = CurrentFile.loader.keys.map(i => this.normalizeKey(i)) // keys occur in your code const inUseKeys = uniq([...usages.map(i => i.keypath), ...Config.keysInUse].map(i => this.normalizeKey(i))) - // keys in use const activeKeys = inUseKeys.filter(i => allKeys.includes(i)) // keys not in use @@ -135,10 +134,10 @@ export class Analyst { .filter(i => !inUseKeys.includes(i)) .filter(i => !micromatch.isMatch(i, Config.keysInUse)) // keys in use, but actually you don't have them - const missingKeys = inUseKeys.filter(i => !allKeys.includes(i)) + let missingKeys = inUseKeys.filter(i => !allKeys.includes(i)) - // remove dervied keys from idle, if the source key is in use const rules = Global.derivedKeyRules + // remove derived keys from idle, if the source key is in use idleKeys = idleKeys.filter((key) => { for (const r of rules) { const match = r.exec(key) @@ -148,6 +147,25 @@ export class Analyst { return true }) + // for derived keys whose source key is considered missing + // (is actually in use, could be a nested pluralization key scenario) + // - add the source key to active + // - remove the source key from missing + // - remove the derived key from idle + const missingKeysShouldBeActive: string[] = [] + idleKeys = idleKeys.filter((key) => { + for (const r of rules) { + const match = r.exec(key) + if (match && match[1] && missingKeys.includes(match[1])) { + missingKeysShouldBeActive.push(match[1]) + return false + } + } + return true + }) + activeKeys.push(...uniq(missingKeysShouldBeActive)) + missingKeys = missingKeys.filter(i => !missingKeysShouldBeActive.includes(i)) + const report = { active: usages.filter(i => activeKeys.includes(i.keypath)), missing: usages.filter(i => missingKeys.includes(i.keypath)), diff --git a/src/core/Config.ts b/src/core/Config.ts index 1a4fa434..d900a55c 100644 --- a/src/core/Config.ts +++ b/src/core/Config.ts @@ -4,7 +4,7 @@ import { workspace, extensions, ExtensionContext, commands, ConfigurationScope, import { trimEnd, uniq } from 'lodash' import { TagSystems } from '../tagSystems' import { EXT_NAMESPACE, EXT_ID, EXT_LEGACY_NAMESPACE, KEY_REG_DEFAULT, KEY_REG_ALL, DEFAULT_LOCALE_COUNTRY_MAP } from '../meta' -import { KeyStyle, DirStructureAuto, TargetPickingStrategy } from '.' +import { KeyStyle, DirStructureAuto, SortCompare, TargetPickingStrategy } from '.' import i18n from '~/i18n' import { CaseStyles } from '~/utils/changeCase' import { ExtractionBabelOptions, ExtractionHTMLOptions } from '~/extraction/parsers/options' @@ -176,6 +176,14 @@ export class Config { return this.getConfig