aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-16 00:21:07 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-16 00:21:07 +0200
commit3b2d03a919e56d14f8097844b97b844ddf526cd6 (patch)
tree31b222fedf6d608809eb47c45c5f431d7001d87a /packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
parent75065cc1ed5d9cd733871d478dc4f915663d795c (diff)
downloadmeshbay-3b2d03a919e56d14f8097844b97b844ddf526cd6.tar.gz
feat(hub): translate the web client into nine more languages
French, Spanish, Brazilian Portuguese, Simplified Chinese, Japanese, German, Italian, Dutch and Polish, all in the formal register. `hub`, `node` and `GEK` stay in English: they name the CLI, node.toml and the docs, and translating them would cut the interface off from everything an operator reads and types. Catalogues move out of i18n.js into locales/, one file per language, fetched with a dynamic import. A visitor downloads their language plus English as a fallback — about 36 KB rather than the ~180 KB that ten inlined catalogues would have cost everyone. i18n.js keeps only the loader, so the first render now waits for initLocale(). Three things the old code got wrong, none of them visible until there was a second language: - Resolution trimmed a tag to its base before matching, so a browser reporting pt-BR looked for a `pt` catalogue that does not exist and fell back to English. Matching is now exact first, then by base language. - Counted strings were single strings, so Polish could not express 1 plik / 2 pliki / 5 plików at all. t() selects through Intl.PluralRules; en.js gains the same treatment, which incidentally fixes "1 files". - Interpolation used String.replace, which reads `$&` in the replacement. A file named rap$&sody.mp3 rendered corrupted in its own delete dialog. Five strings were still hardcoded in app.js — the group name placeholder and the four visibility/join-policy descriptions — and are now keyed. test_locales.py holds the nine translations to the shape of en.js: same keys, a counted string stays counted everywhere, every plural entry covers each category Intl actually produces for that language, and the {placeholders} survive translation. Verified failing first, against a catalogue with a key removed, a placeholder dropped and the Polish `few` form deleted. The language menu also grew from one entry to ten, which overran a short viewport inside a dropdown that clipped instead of scrolling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js407
1 files changed, 407 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
new file mode 100644
index 0000000..845e7ce
--- /dev/null
+++ b/packages/meshbay-hub/src/meshbay_hub/static/locales/fr.js
@@ -0,0 +1,407 @@
+/**
+ * French — translated from locales/en.js.
+ *
+ * Register: formal (vouvoiement).
+ * `hub`, `node` and `GEK` are left in English: they name the CLI
+ * (`meshbay-node`), node.toml and the docs, which are English throughout.
+ */
+
+export default {
+ // Nav
+ 'nav.toggle_menu': 'Afficher le menu',
+ 'nav.light_mode': 'Thème clair',
+ 'nav.dark_mode': 'Thème sombre',
+ 'nav.logout': 'Déconnexion',
+ 'nav.login': 'Connexion',
+
+ // Sidebar
+ 'sidebar.my_groups': 'Mes groupes',
+ 'sidebar.no_groups': 'Aucun groupe pour le moment',
+ 'sidebar.discover': 'Découvrir',
+ 'sidebar.public_groups': 'Groupes publics',
+
+ // Login
+ 'login.title': 'Connexion',
+ 'login.username': "Nom d'utilisateur",
+ 'login.password': 'Mot de passe',
+ 'login.submit': 'Se connecter',
+ 'login.loading': 'Connexion en cours...',
+ 'login.no_account': 'Pas encore de compte ?',
+ 'login.register_link': 'Créer un compte',
+
+ // Register
+ 'register.title': 'Créer un compte',
+ 'register.username': "Nom d'utilisateur",
+ 'register.email': 'Adresse e-mail',
+ 'register.password': 'Phrase secrète (12 caractères minimum)',
+ 'register.confirm': 'Confirmer le mot de passe',
+ 'register.submit': 'Créer le compte',
+ 'register.loading': 'Création du compte...',
+ 'register.has_account': 'Vous avez déjà un compte ?',
+ 'register.login_link': 'Se connecter',
+ 'register.success_title': 'Compte créé',
+ 'register.success_msg': 'Vous pouvez maintenant vous connecter avec vos identifiants.',
+ 'register.go_login': 'Aller à la connexion',
+ 'register.err_mismatch': 'Les mots de passe ne correspondent pas',
+ 'register.err_min_len': {
+ one: 'Utilisez au moins {n} caractère',
+ other: 'Utilisez au moins {n} caractères',
+ },
+ 'register.err_too_weak': 'Trop facile à deviner. Votre phrase secrète est ce qui '
+ + 'protège vos clés là où elles sont stockées — quelques mots sans rapport entre '
+ + 'eux font très bien l’affaire.',
+ 'register.strength': 'Robustesse : environ {bits} bits. Elle protège la copie de '
+ + 'vos clés conservée sur les nodes que vous rejoignez, cela vaut donc la peine '
+ + 'de la soigner.',
+
+ // Home
+ 'home.welcome': 'Bienvenue sur MeshBay',
+ 'home.no_groups': "Vous n'êtes membre d'aucun groupe pour le moment.",
+ 'home.browse_prefix': 'Parcourez les ',
+ 'home.browse_link': 'groupes publics',
+ 'home.browse_suffix': " ou demandez à l'administrateur d'un groupe de vous inviter.",
+ 'home.my_groups': 'Mes groupes',
+
+ // Explore
+ 'explore.title': 'Groupes publics',
+ 'explore.search': 'Rechercher un groupe...',
+ 'explore.loading': 'Chargement...',
+ 'explore.empty': 'Aucun groupe public disponible.',
+ 'explore.create_group': 'Créer un groupe',
+ 'explore.join': 'Rejoindre',
+ 'explore.member': 'Membre',
+
+ // Group page
+ 'group.default_name': 'Groupe',
+ 'group.tab_files': 'Fichiers',
+ 'group.tab_chat': 'Discussion',
+ 'group.tab_members': 'Membres',
+ 'group.filter': 'Filtrer les fichiers...',
+ 'group.col_name': 'Nom',
+ 'group.col_size': 'Taille',
+ 'group.col_type': 'Type',
+ 'group.col_date': 'Date',
+ 'group.empty_filter': 'Aucun fichier ne correspond au filtre',
+ 'group.empty_dir': 'Ce dossier est vide',
+ 'group.download': 'Télécharger',
+ 'group.play': 'Lire',
+ 'group.offline_title': "Aucun node n'est actuellement en ligne pour ce groupe.",
+ 'group.offline_hint': 'Les fichiers apparaîtront dès qu’un node hébergeant ce '
+ + 'groupe se connectera.',
+ 'group.upload': 'Envoyer',
+ 'group.mkdir': 'Nouveau dossier',
+ 'group.mkdir_prompt': 'Nom du nouveau dossier :',
+ 'group.view': 'Afficher',
+ 'group.delete': 'Supprimer',
+ 'group.delete_confirm': 'Supprimer {name} ?',
+ 'group.delete_group': 'Supprimer le groupe',
+ 'group.delete_group_confirm': 'Supprimer définitivement « {name} » et en retirer '
+ + 'tous les membres ? Les fichiers présents sur le node sont conservés.',
+ 'group.err_transport': 'Module de transport non chargé',
+
+ // Status
+ 'status.idle': 'Inactif',
+ 'status.discovering': 'Recherche de nodes...',
+ 'status.connecting': 'Connexion via WebRTC...',
+ 'status.fetching': "Récupération de l'index...",
+ 'status.files': {
+ one: '{n} fichier',
+ other: '{n} fichiers',
+ },
+ 'status.offline': 'Aucun node en ligne',
+ 'status.error': 'Échec de la connexion',
+
+ // Chat
+ 'chat.empty': 'Aucun message pour le moment. Lancez la conversation !',
+ 'chat.placeholder': 'Écrivez un message...',
+ 'chat.send': 'Envoyer',
+ 'chat.attach': 'Joindre un fichier',
+
+ // Video player
+ 'video.loading': 'Chargement de {name}...',
+ 'video.buffering': 'Mise en mémoire tampon...',
+ 'video.close': 'Fermer (Échap)',
+ 'preview.pdf_fallback': 'Ce navigateur n’affichera pas le PDF directement. '
+ + 'Téléchargez-le plutôt — il a été déchiffré ici dans les deux cas.',
+ 'group.upload_indexing': 'indexation…',
+ 'video.err_transport': 'Transport non connecté',
+ 'video.err_mse': 'Codec non pris en charge pour la diffusion : {codec}',
+
+ // Settings
+ 'settings.title': 'Paramètres',
+ 'settings.coming_soon': 'Bientôt disponible.',
+ 'settings.downloads': 'Téléchargements',
+ 'settings.dl_auto': 'Enregistrer automatiquement',
+ 'settings.dl_auto_hint': 'Les fichiers vont directement dans le dossier choisi '
+ + 'ci-dessous, sans boîte de dialogue. Télécharger vingt fichiers en dépose vingt.',
+ 'settings.dl_ask': 'Demander à chaque fois',
+ 'settings.dl_ask_hint': 'Une boîte de dialogue « Enregistrer sous » par fichier — '
+ + 'un par fichier, y compris lorsque vous téléchargez une sélection.',
+ 'settings.dl_folder': 'Dossier : {name}',
+ 'settings.dl_no_folder': 'Aucun dossier choisi — les téléchargements vont là où '
+ + 'votre navigateur les place',
+ 'settings.dl_choose': 'Choisir un dossier',
+ 'settings.dl_change': 'Changer',
+ 'settings.dl_forget': 'Oublier',
+ 'settings.dl_path_note': 'On ne peut pas indiquer un chemin à une page web, il n’y '
+ + 'a donc rien à saisir ici : votre navigateur donne accès au dossier que vous '
+ + 'désignez, et MeshBay n’écrit jamais ailleurs qu’à l’intérieur. Une '
+ + 'confirmation peut vous être demandée une fois par session.',
+ 'settings.dl_unsupported': 'Ce navigateur ne sait pas écrire dans un dossier de '
+ + 'votre choix (pas de File System Access API) ; les téléchargements vont donc '
+ + 'dans son propre dossier de téléchargement. Chrome et Edge permettent d’en '
+ + 'choisir un.',
+ 'settings.profile': 'Profil',
+ 'settings.username': "Nom d'utilisateur",
+ 'settings.node_pins': 'Identités des nodes',
+ 'settings.node_pins_hint': "La clé d'identité de chaque node est mémorisée lors de "
+ + 'la première connexion. Si elle change, la connexion est refusée — ce qui n’est '
+ + 'normal que lorsqu’un opérateur réinstalle un node. Vérifiez auprès de lui '
+ + 'avant d’effacer.',
+ 'settings.node_pins_count': {
+ one: '{n} épinglée',
+ other: '{n} épinglées',
+ },
+ 'settings.node_pins_clear': 'Effacer les identités épinglées',
+ 'settings.danger': 'Supprimer le compte',
+ 'settings.delete_hint': 'Supprime votre compte, vos adhésions aux groupes et vos '
+ + 'notifications du hub, et libère votre nom d’utilisateur. Cela n’atteint pas '
+ + 'ce qui se trouve sur les nodes : les fichiers que vous avez envoyés restent là '
+ + 'où leur opérateur les conserve, et chaque node garde l’identité qu’il a '
+ + 'épinglée pour vous jusqu’à ce que son opérateur la retire. Les journaux de '
+ + 'connexion sont conservés un an, comme la loi l’exige.',
+ 'settings.delete_account': 'Supprimer mon compte',
+ 'settings.delete_confirm': 'Saisissez votre phrase secrète pour confirmer. '
+ + 'Cette action est irréversible.',
+ 'settings.delete_confirm_btn': 'Supprimer définitivement',
+ 'settings.cancel': 'Annuler',
+ 'settings.appearance': 'Apparence',
+ 'settings.theme': 'Thème',
+ 'settings.theme_light': 'Clair',
+ 'settings.theme_dark': 'Sombre',
+ 'settings.theme_system': 'Système',
+ 'settings.language': 'Langue',
+ 'settings.about': 'À propos',
+ 'settings.version': 'Version',
+ 'settings.protocol': 'Protocole',
+ 'settings.role': 'Rôle',
+ 'settings.groups': 'Notifications de groupe',
+ 'settings.notifications': 'Notifications',
+ 'settings.node_key': 'Associer un node',
+ 'settings.node_key_desc': 'Si vous exploitez un node MeshBay, collez ici sa clé '
+ + 'publique Ed25519 pour l’associer à votre compte. Vous trouverez cette clé '
+ + 'dans le tableau de bord d’administration de votre node.',
+ 'settings.node_key_placeholder': 'Collez la clé publique Ed25519 du node (base64)',
+ 'settings.node_key_submit': 'Associer le node',
+ 'settings.node_key_success': 'Node associé avec succès',
+ 'settings.node_key_current': 'Clé du node associé',
+
+ // Sidebar
+ 'sidebar.create_group': 'Créer un groupe',
+ 'sidebar.settings': 'Paramètres',
+ 'sidebar.admin': 'Administration',
+
+ // User menu
+ 'usermenu.language': 'Langue',
+ 'usermenu.settings': 'Paramètres',
+ 'usermenu.theme_light': 'Thème clair',
+ 'usermenu.theme_dark': 'Thème sombre',
+ 'usermenu.logout': 'Déconnexion',
+
+ // Admin panel
+ 'admin.title': 'Administration',
+ 'admin.tab_stats': 'Statistiques',
+ 'admin.tab_users': 'Utilisateurs',
+ 'admin.tab_groups': 'Groupes',
+ 'admin.tab_nodes': 'Nodes',
+ 'admin.tab_logs': 'Journaux',
+ 'admin.col_observed_ip': 'Vu depuis',
+ 'admin.col_hint': 'Adresse annoncée',
+ 'admin.col_last_seen': 'Dernière annonce',
+ 'admin.node_online': 'en ligne',
+ 'admin.node_offline': 'hors ligne',
+ 'admin.no_nodes': 'Aucun node enregistré',
+ 'admin.nodes_hint': '« Vu depuis » est l’adresse d’où l’annonce nous est '
+ + 'parvenue, sur une requête signée avec la clé du node — c’est celle sur '
+ + 'laquelle s’appuyer pour répondre à une réquisition. L’adresse annoncée est '
+ + 'celle que le node croit être la sienne, apprise d’un serveur STUN puis '
+ + 'transmise ; elle sert à joindre le node et ne prouve rien.',
+ 'admin.tab_blocklist': 'Liste de blocage',
+
+ // Admin stats
+ 'admin.stat_users': 'Utilisateurs',
+ 'admin.stat_groups': 'Groupes',
+ 'admin.stat_nodes': 'Nodes',
+ 'admin.stat_online': 'Nodes en ligne',
+
+ // Admin users
+ 'admin.users_search': 'Rechercher un utilisateur...',
+ 'admin.col_username': "Nom d'utilisateur",
+ 'admin.col_role': 'Rôle',
+ 'admin.col_status': 'Statut',
+ 'admin.col_created': 'Création',
+ 'admin.col_actions': 'Actions',
+ 'admin.col_email': 'E-mail',
+ 'admin.col_groups': 'Groupes',
+ 'admin.no_users': 'Aucun utilisateur trouvé',
+ 'admin.btn_suspend': 'Suspendre',
+ 'admin.btn_unsuspend': 'Réactiver',
+ 'admin.btn_details': 'Détails',
+ 'admin.btn_delete': 'Supprimer',
+ 'admin.delete_confirm': 'Supprimer le compte « {user} » ? Cette action est '
+ + 'irréversible. Les fichiers qu’il a envoyés restent sur les nodes qui les '
+ + 'hébergent, et chaque node conserve l’identité qu’il a épinglée jusqu’à ce '
+ + 'que son opérateur la retire. La suspension est l’option réversible.',
+ 'admin.user_detail': "Détails de l'utilisateur",
+ 'admin.btn_close': 'Fermer',
+ 'admin.self_note': '(vous)',
+
+ // Admin groups
+ 'admin.col_name': 'Nom',
+ 'admin.col_visibility': 'Visibilité',
+ 'admin.col_members': 'Membres',
+ 'admin.no_groups': 'Aucun groupe trouvé',
+
+ // Admin logs
+ 'admin.col_time': 'Horodatage',
+ 'admin.col_event': 'Événement',
+ 'admin.col_user': 'Utilisateur',
+ 'admin.col_ip': 'IP',
+ 'admin.col_detail': 'Détail',
+ 'admin.filter_all': 'Tous les événements',
+ 'admin.no_logs': 'Aucun journal trouvé',
+ 'admin.btn_load_more': 'Charger plus',
+
+ // Admin blocklist
+ 'admin.col_hash': 'Empreinte',
+ 'admin.col_reason': 'Motif',
+ 'admin.col_date': 'Date',
+ 'admin.col_added_by': 'Ajoutée par',
+ 'admin.no_blocked': 'Aucune empreinte bloquée',
+ 'admin.add_hash': 'Ajouter une empreinte à la liste de blocage',
+ 'admin.hash_placeholder': 'empreinte blake3 (64 caractères hexadécimaux)',
+ 'admin.reason_placeholder': 'Motif',
+ 'admin.btn_block': 'Bloquer',
+ 'admin.btn_unblock': 'Débloquer',
+
+ // Notifications
+ // Create group
+ 'create_group.title': 'Créer un groupe',
+ 'create_group.name': 'Nom du groupe',
+ 'create_group.name_placeholder': 'ex. Photos de famille, Documents du projet...',
+ 'create_group.visibility': 'Visibilité',
+ 'create_group.private': 'Privé',
+ 'create_group.private_desc': 'Seuls les membres invités voient les fichiers et y accèdent',
+ 'create_group.public': 'Public',
+ 'create_group.public_desc': 'Tout le monde peut découvrir et parcourir ce groupe',
+ 'create_group.join_policy': "Politique d'adhésion",
+ 'create_group.invite': 'Sur invitation',
+ 'create_group.invite_desc': 'Les membres doivent être invités par un administrateur',
+ 'create_group.open': 'Ouvert (tout le monde peut rejoindre)',
+ 'create_group.open_desc': 'Tout le monde peut rejoindre sans validation',
+ 'create_group.description': 'Description',
+ 'create_group.description_hint': 'De quoi parle ce groupe ? (facultatif)',
+ 'create_group.submit': 'Créer',
+ 'create_group.hint': 'Un groupe a besoin d’un node pour héberger les fichiers. '
+ + 'Vous pouvez créer le groupe maintenant et connecter un node plus tard.',
+ 'create_group.creating': 'Création...',
+
+ // Members
+ 'members.col_role': 'Rôle',
+ 'members.group_role': 'Rôle dans le groupe',
+ 'members.admin': 'Administrateur',
+ 'members.group_admin': 'Administrateur du groupe',
+ 'members.owner': 'Propriétaire',
+ 'members.member': 'Membre',
+ 'members.invite_title': 'Inviter un membre',
+ 'members.username_placeholder': "Nom d'utilisateur",
+ 'members.invite_btn': 'Inviter',
+ 'members.invite_needs_pairing': 'Les invitations sont signées avec la clé que ce '
+ + 'node a épinglée pour votre navigateur : appairez-le ci-dessous avant '
+ + 'd’inviter qui que ce soit.',
+ 'members.invite_ask_operator': 'Seul l’opérateur du node qui héberge ce groupe '
+ + 'peut inviter, depuis un navigateur appairé avec lui.',
+ 'members.remove': 'Retirer',
+ 'members.remove_confirm': 'Retirer {user} de ce groupe ? Son compte, ses autres '
+ + 'groupes et les fichiers qu’il a envoyés ne sont pas affectés.',
+ 'members.remove_hint': 'Retirer quelqu’un lui ôte son adhésion et empêche le node '
+ + 'de lui remettre la clé du groupe. Cela ne supprime pas son compte, et cela ne '
+ + 'reprend pas la clé qu’il détient déjà — faites-la tourner sur le node '
+ + '(meshbay-node gek-init) si cela compte.',
+ 'members.pair_title': 'Appairer ce navigateur avec votre node',
+ 'members.pair_hint': 'Votre node n’accepte les actions d’opérateur — invitations, '
+ + 'suppression de fichiers — que depuis un navigateur avec lequel il a été '
+ + 'appairé. Lancez `meshbay-node operator pair` sur le node et saisissez le code '
+ + 'ici. Le code ne transite jamais par le hub.',
+ 'members.pair_btn': 'Appairer',
+ 'members.pair_success': 'Ce navigateur est désormais appairé avec le node.',
+ 'members.invite_code_ready': 'Code d’invitation pour {user} — transmettez-le-lui '
+ + 'par le moyen dont vous avez l’habitude. Il ne fonctionne qu’une fois, et ne '
+ + 'transite jamais par le hub.',
+ 'members.invite_code_hint': 'La personne le saisit la première fois qu’elle ouvre '
+ + 'ce groupe. Vous n’avez pas besoin d’être en ligne à ce moment-là.',
+ 'transfers.title': 'Transferts',
+ 'transfers.clear': 'Effacer les terminés',
+ 'transfers.cancel': 'Annuler',
+ 'transfers.open': 'Ouvrir',
+ 'transfers.done': 'Terminé',
+ 'transfers.cancelled': 'Annulé',
+ 'transfers.failed': 'Échec',
+ 'group.select': 'Sélectionner',
+ 'group.select_done': 'Terminé',
+ 'group.actions': 'Actions ({n})',
+ 'group.download_n': 'Télécharger ({n})',
+ 'group.download_zip_n': 'Télécharger les dossiers en zip ({n})',
+ 'group.delete_n': 'Supprimer ({n})',
+ 'group.delete_n_confirm': {
+ one: 'Supprimer {n} élément ? {names}',
+ other: 'Supprimer {n} éléments ? {names}',
+ },
+ 'group.download_zip': {
+ one: 'Télécharger en zip ({n} fichier)',
+ other: 'Télécharger en zip ({n} fichiers)',
+ },
+ 'group.zip_empty': 'Ce dossier ne contient rien à télécharger.',
+ 'group.zip_no_stream': 'Ce navigateur ne sait pas écrire un téléchargement '
+ + 'directement sur le disque : {name} ({size}) doit donc être assemblé en mémoire '
+ + 'au préalable. Sur une archive volumineuse, cela peut échouer. Continuer ?',
+ 'group.rmdir': 'Supprimer le dossier',
+ 'group.rmdir_confirm': 'Supprimer le dossier « {name} » ? Il doit être vide.',
+ 'group.rmdir_not_empty': 'Ce dossier n’est pas vide. Supprimez d’abord ce qu’il '
+ + 'contient — rien ici ne supprime des fichiers que vous ne voyez pas.',
+ 'group.desc_edit': 'Modifier la description',
+ 'group.desc_add': 'Ajouter une description',
+ 'group.desc_save': 'Enregistrer',
+ 'group.desc_cancel': 'Annuler',
+ 'group.desc_placeholder': 'À quoi sert ce groupe — les membres le voient sur leur '
+ + 'page d’accueil.',
+ 'group.join_code_title': 'Ce node doit vous reconnaître',
+ 'group.join_code_hint': 'Demandez son code à usage unique à la personne qui vous a '
+ + 'invité, et saisissez-le ici. Ensuite, ce navigateur est reconnu et la question '
+ + 'ne vous sera plus posée.',
+ 'group.join_code_btn': 'Rejoindre',
+
+ 'notif.purge': 'Tout effacer',
+ 'notif.title': 'Notifications',
+ 'notif.empty': 'Aucune notification',
+ 'notif.mark_all_read': 'Tout marquer comme lu',
+
+ // Sidebar
+ 'sidebar.search': 'Rechercher des fichiers',
+
+ // Status
+
+ // Search
+ 'search.title': 'Rechercher des fichiers',
+ 'search.placeholder': 'Rechercher dans tous les groupes...',
+ 'search.no_results': 'Aucun fichier ne correspond à votre recherche.',
+ 'search.synced': 'synchronisé {ago}',
+ 'search.cache_note': 'La recherche s’appuie sur l’état de chaque groupe lors de '
+ + 'votre dernière visite. Ouvrez un groupe pour mettre ses fichiers à jour ici.',
+ 'search.col_group': 'Groupe',
+ 'search.result_count': {
+ one: '{n} fichier trouvé',
+ other: '{n} fichiers trouvés',
+ },
+ 'search.hint': 'Recherche les noms de fichiers dans tous les index de groupe en cache.',
+};