{
  "common": {
    "cancel": "Annuler",
    "delete": "Supprimer",
    "save": "Enregistrer",
    "create": "Cr\u00e9er",
    "next": "Suivant",
    "back": "Retour",
    "import": "Importer",
    "saving": "Enregistrement...",
    "loading": "Chargement...",
    "edit": "Modifier",
    "download": "T\u00e9l\u00e9charger",
    "retry": "R\u00e9essayer",
    "failedToSave": "\u00c9chec de l'enregistrement de la voix"
  },
  "generate": {
    "title": "G\u00e9n\u00e9rer",
    "subtitle": "S\u00e9lectionnez une voix, entrez du texte et g\u00e9n\u00e9rez de la parole.",
    "placeholder": "Entrez le texte \u00e0 synth\u00e9tiser...",
    "chars": "{{count}} caract\u00e8res",
    "failed": "\u00c9chec de la g\u00e9n\u00e9ration",
    "noGenerations": "Aucune g\u00e9n\u00e9ration. G\u00e9n\u00e9rez de l'audio ci-dessus !",
    "speedSlow": "Lent",
    "speedFast": "Rapide",
    "speedXFast": "Tr\u00e8s rapide",
    "toneAngry": "En col\u00e8re",
    "toneSad": "Triste",
    "toneHappy": "Heureux",
    "toneExcited": "Excit\u00e9",
    "toneEmbarrassed": "G\u00ean\u00e9",
    "toneWhispering": "Chuchotant",
    "toneSoft": "Doux",
    "toneBreathy": "Souffl\u00e9",
    "effectPause": "pause",
    "effectLongPause": "longue pause",
    "effectLaughing": "rires",
    "effectChuckling": "gloussement",
    "effectSighing": "soupir",
    "effectCrying": "pleurs",
    "effectMoaning": "g\u00e9missement",
    "effectGroaning": "grognement"
  },
  "voice": {
    "editTitle": "Modifier la voix",
    "createTitle": "Cr\u00e9er une voix",
    "deleteTitle": "Supprimer la voix",
    "deleteConfirm": "\u00cates-vous s\u00fbr de vouloir supprimer \u00ab {{name}} \u00bb ? Cette action est irr\u00e9versible.",
    "name": "Nom",
    "namePlaceholder": "Nom de la voix",
    "description": "Description",
    "descriptionPlaceholder": "Description optionnelle",
    "language": "Langue",
    "model": "Mod\u00e8le",
    "audioSamples": "\u00c9chantillons audio",
    "audioSamplesHint": "Ajoutez de courts extraits audio de la voix \u00e0 cloner. Le mod\u00e8le utilisera ces \u00e9chantillons comme r\u00e9f\u00e9rence pour reproduire la voix. Glissez pour r\u00e9ordonner, activez ou d\u00e9sactivez un \u00e9chantillon.",
    "totalDuration": "{{duration}}s / {{max}}s",
    "addAudioSample": "Ajouter un \u00e9chantillon audio",
    "noModels": "Aucun mod\u00e8le install\u00e9.",
    "installModel": "Installer un mod\u00e8le",
    "preset": "Pr\u00e9d\u00e9fini",
    "cloud": "Cloud",
    "cloning": "Clonage",
    "voiceDesign": "Design vocal",
    "voice": "Voix",
    "loadingVoices": "Chargement des voix...",
    "noVoices": "Aucune voix disponible.",
    "failedToLoadVoices": "\u00c9chec du chargement des voix",
    "idCopied": "ID de la voix copi\u00e9",
    "copyId": "Copier l'ID",
    "exportFailed": "\u00c9chec de l'export de la voix",
    "importTitle": "Importer une voix",
    "importDescription": "Importez une voix depuis une archive .zip pr\u00e9c\u00e9demment export\u00e9e depuis Sirene.",
    "importSelectZip": "Veuillez s\u00e9lectionner un fichier .zip",
    "importSuccess": "Voix \u00ab {{name}} \u00bb import\u00e9e",
    "importFailed": "\u00c9chec de l'import",
    "dropZipHere": "D\u00e9posez un fichier .zip ici",
    "orClickBrowse": "ou cliquez pour parcourir",
    "importing": "Import en cours...",
    "unknownVoice": "Voix inconnue",
    "transcript": "Transcription",
    "transcriptPlaceholder": "Transcription de l'audio...",
    "pendingTranscriptPlaceholder": "Transcription...",
    "auto": "Auto",
    "uploadSample": "Envoyer l'\u00e9chantillon",
    "addSample": "Ajouter un \u00e9chantillon",
    "transcriptionFailed": "\u00c9chec de la transcription",
    "new": "Nouveau",
    "newVoice": "Nouvelle voix",
    "importVoice": "Importer une voix",
    "design": "Designer",
    "designVoice": "Designer une voix",
    "searchPlaceholder": "Rechercher des voix...",
    "all": "Toutes",
    "noMatch": "Aucune voix ne correspond \u00e0 vos filtres.",
    "add": "Ajouter",
    "tags": "Tags",
    "tagsPlaceholder": "Ajouter un tag...",
    "visibility": "Visibilit\u00e9",
    "mine": "Mes voix",
    "public": "Publiques",
    "emptyNoModel": "Installez un modèle TTS avant de pouvoir ajouter une voix.",
    "needModelHint": "Installez d'abord un mod\u00e8le TTS depuis la page Mod\u00e8les",
    "needInstructHint": "Installez un modèle avec support instruct depuis la page Modèles",
    "variant": "Variante",
    "manage": "Gérer les voix",
    "pageSubtitle": "Créez, importez et gérez vos voix.",
    "selectVoice": "Sélectionner une voix",
    "emptyGoManage": "Aucune voix. Rendez-vous sur la page Voix pour en créer une."
  },
  "voiceDesigner": {
    "title": "Designer de voix",
    "describe": "D\u00e9crire",
    "preview": "Aper\u00e7u",
    "save": "Enregistrer",
    "voiceDescription": "Description de la voix",
    "descriptionPlaceholder": "D\u00e9crivez la voix que vous souhaitez cr\u00e9er. Ex : \u00ab Une voix masculine chaleureuse et profonde, avec un l\u00e9ger accent britannique, calme et rassurante. \u00bb",
    "gender": "Genre",
    "male": "Masculin",
    "female": "F\u00e9minin",
    "sampleText": "Texte d'exemple",
    "sampleTextPlaceholder": "Entrez le texte que la voix doit prononcer pour l'aper\u00e7u.",
    "generating": "G\u00e9n\u00e9ration en cours...",
    "regenerate": "Reg\u00e9n\u00e9rer",
    "generatePreview": "G\u00e9n\u00e9rer l'aper\u00e7u",
    "voiceName": "Nom de la voix",
    "voiceNamePlaceholder": "Nommez votre voix",
    "descriptionLabel": "Description :",
    "languageLabel": "Langue :",
    "saveVoice": "Enregistrer la voix",
    "created": "Voix \u00ab {{name}} \u00bb cr\u00e9\u00e9e",
    "saveFailed": "\u00c9chec de l'enregistrement de la voix"
  },
  "model": {
    "title": "Mod\u00e8les",
    "subtitle": "Installez et g\u00e9rez les mod\u00e8les. Les mod\u00e8les sont t\u00e9l\u00e9charg\u00e9s \u00e0 la demande.",
    "tts": "TTS",
    "stt": "STT",
    "cloudApi": "API Cloud",
    "hfToken": "Token HF",
    "hfTokenTooltip": "N\u00e9cessite un token HuggingFace (HF_TOKEN)",
    "exported": "Mod\u00e8le export\u00e9",
    "exportFailed": "\u00c9chec de l'export",
    "removeFailed": "\u00c9chec de la suppression du mod\u00e8le",
    "importPiperTitle": "Importer une voix Piper",
    "importPiperDescription": "Importez un mod\u00e8le Piper ONNX personnalis\u00e9 avec son fichier de configuration.",
    "modelName": "Nom du mod\u00e8le",
    "modelNamePlaceholder": "ex : ma-voix-personnalisee",
    "modelId": "ID : {{id}}",
    "onnxFile": "Fichier ONNX du mod\u00e8le",
    "dropOnnx": "D\u00e9posez le fichier .onnx ici",
    "configFile": "Fichier de config (.onnx.json)",
    "dropConfig": "D\u00e9posez le fichier .onnx.json ici",
    "speakers": "{{count}} locuteurs",
    "installOn": "Installer sur",
    "alreadyInstalled": "Déjà installé",
    "importPiperSuccess_one": "Import du modèle Piper « {{id}} » mis en file d'attente - suivez la progression dans les notifications.",
    "importPiperSuccess_other": "Import du modèle Piper « {{id}} » mis en file d'attente sur {{count}} serveurs - suivez la progression dans les notifications.",
    "allBackends": "Tous les backends",
    "status_installed": "Installés",
    "status_available": "Disponibles",
    "installedOn": "Installé sur {{count}}/{{total}} serveurs",
    "manage": "Gérer par serveur",
    "perServer": "Par serveur",
    "installOnAll": "Installer sur les {{count}} serveurs",
    "installOnAllMissing": "Installer sur les {{count}} serveurs restants",
    "removeFromAll": "Supprimer de tous les serveurs",
    "noMatch": "Aucun modèle ne correspond à vos filtres.",
    "actionInstall": "Installer le modèle",
    "actionInstallNoServer": "Aucun serveur d'inférence en ligne - vérifiez les paramètres",
    "actionInstalling": "Installation en cours",
    "actionRemove": "Supprimer le modèle",
    "actionInstallOnServer": "Installer sur {{name}}",
    "actionRemoveFromServer": "Supprimer de {{name}}",
    "removeFromAllConfirmTitle": "Supprimer de tous les serveurs ?",
    "removeFromAllConfirmDescription": "Cela supprimera « {{name}} » des {{count}} serveurs où il est installé. Cette action est irréversible."
  },
  "notifications": {
    "title": "Activité",
    "empty": "Aucun job en cours.",
    "running": "En cours",
    "completed": "Terminé",
    "failed": "Échec",
    "dismiss": "Ignorer",
    "open": "Ouvrir les notifications"
  },
  "history": {
    "title": "Historique",
    "subtitle": "Parcourez toutes les g\u00e9n\u00e9rations pass\u00e9es.",
    "empty": "Aucune g\u00e9n\u00e9ration. Rendez-vous sur la page G\u00e9n\u00e9rer pour cr\u00e9er la premi\u00e8re.",
    "noMatch": "Aucune génération ne correspond à ce filtre.",
    "deleteAll": "Tout supprimer",
    "deleteAllTitle": "Supprimer toutes les générations ?",
    "deleteAllDescription": "{{count}} génération(s) pour la voix « {{voice}} » seront définitivement supprimées. Cette action est irréversible."
  },
  "nav": {
    "appName": "Sirene",
    "appSubtitle": "TTS Open Router",
    "navigation": "Navigation",
    "sessions": "Sessions",
    "studio": "Studio",
    "voices": "Voix",
    "models": "Mod\u00e8les",
    "history": "Historique",
    "toggleTheme": "Changer de th\u00e8me",
    "theme": "Th\u00e8me",
    "language": "Langue",
    "settings": "Param\u00e8tres"
  },
  "studio": {
    "breadcrumbStudio": "Studio",
    "breadcrumbSession": "Session",
    "pageSubtitle": "Écrivez, vocalisez et affinez vos prises audio.",
    "untitledSession": "Sans titre",
    "emptyTitle": "Votre studio est pr\u00eat",
    "emptyHint": "\u00c9crivez une phrase, choisissez une voix et g\u00e9n\u00e9rez. Ajoutez des prises pour composer un dialogue.",
    "noVoicesTitle": "Cr\u00e9ez votre premi\u00e8re voix",
    "noVoicesHint": "Vous avez besoin d'au moins une voix pour g\u00e9n\u00e9rer de l'audio. Cr\u00e9ez-la, importez-la ou designez-la depuis la page Voix.",
    "noVoicesCta": "Cr\u00e9er une voix",
    "composerPlaceholder": "Entrez le texte \u00e0 synth\u00e9tiser...",
    "generate": "G\u00e9n\u00e9rer",
    "regenerate": "R\u00e9g\u00e9n\u00e9rer",
    "regenerateWithTuning": "R\u00e9g\u00e9n\u00e9rer avec l'affinage",
    "addTake": "Ajouter une prise",
    "addTakeHint": "enchaîner une suite",
    "changeVoice": "Changer de voix",
    "draftHint": "Ctrl/Cmd + Entr\u00e9e pour g\u00e9n\u00e9rer",
    "play": "Lecture",
    "pause": "Pause",
    "tuning": "Affinage",
    "quickTuning": "Affinage rapide",
    "timeline": "Timeline",
    "timelineTitle": "Affinage",
    "timelineStubbedHint": "Timestamps estimés - aucun alignement forcé disponible pour le moment.",
    "timelineSelectedWord": "sélectionné",
    "timelineNoData": "Aucun mot aligné pour cette prise.",
    "laneWords": "Mots",
    "lanePitch": "Pitch",
    "laneSpeed": "Vitesse",
    "pitch": "Pitch",
    "pitchUnit": "demi-tons",
    "speed": "Vitesse",
    "variation": "Variation",
    "tuningGlobal": "Global",
    "tuningPerWord": "Par mot",
    "tuningUnsupported": "Non supporté par ce modèle",
    "emphasis": "Emphase",
    "wordCountSingular": "mot",
    "wordCountPlural": "mots",
    "toolbarPause": "Pause",
    "toolbarSlow": "Lent",
    "toolbarFast": "Rapide",
    "toolbarEmphasis": "Emphase",
    "stateDraft": "Brouillon",
    "stateReady": "Pr\u00eate",
    "stateTuned": "Affin\u00e9e",
    "saving": "Enregistrement...",
    "saved": "Enregistr\u00e9",
    "share": "Partager",
    "export": "Exporter",
    "bankTitle": "Banque de prises",
    "bankEmpty": "Aucune prise pour l'instant",
    "bankEmptyHint": "Vos g\u00e9n\u00e9rations appara\u00eetront ici et pourront \u00eatre gliss\u00e9es vers le document.",
    "bankAddHint": "Ajouter \u00e0 la session en cours",
    "allSessions": "Toutes les sessions",
    "noSessions": "Aucune session pour l'instant.",
    "takeCountSingular": "{{count}} prise",
    "takeCountPlural": "{{count}} prises",
    "deleteSessionTitle": "Supprimer la session ?",
    "deleteSessionDescription": "« {{name}} » sera supprimée. Les prises restent dans la banque - seul le regroupement est supprimé.",
    "shareTitle": "Partager la session",
    "shareDescription": "Rendre cette session visible à toute personne disposant du lien.",
    "sharePrivate": "Privée",
    "sharePublic": "Publique",
    "sharePrivateHint": "Seul vous voyez cette session.",
    "shareFailed": "Échec de la mise à jour du partage",
    "copy": "Copier",
    "copied": "Copié",
    "copyFailed": "Échec de la copie",
    "rename": "Renommer",
    "exportZip": "Exporter en ZIP",
    "exportStarted": "Export en cours",
    "exportFailed": "Échec de l'export",
    "moreActions": "Plus d'actions",
    "more": "Plus",
    "toggleBank": "Afficher/masquer la banque",
    "waveformAriaLabel": "Forme d'onde audio",
    "relativeJustNow": "à l'instant",
    "relativeMinutes": "{{count}} min",
    "relativeHours": "{{count}} h",
    "relativeDays": "{{count}} j",
    "playing": "Lecture...",
    "tapToPlay": "Cliquer pour écouter",
    "noAudio": "Pas d'audio",
    "notAuthenticated": "Non authentifié",
    "failedToSaveSession": "Échec de l'enregistrement de la session",
    "failedToDeleteTake": "Échec de la suppression de la prise",
    "failedToAddTake": "Échec de l'ajout de la prise",
    "failedToCreateSession": "Échec de la création de la session",
    "failedToDeleteSession": "Échec de la suppression de la session",
    "failedToLoadAlignment": "Échec du chargement de l'alignement",
    "publicSessionTitle": "Session publique",
    "publicSessionHint": "Vous consultez une session publique en lecture seule.",
    "publicSessionNotFound": "Cette session n'est pas disponible.",
    "openSirene": "Ouvrir Sirene",
    "sessionNotFoundTitle": "Session introuvable",
    "sessionNotFoundHint": "Cette session n'existe pas ou a été supprimée.",
    "backToStudio": "Retour au Studio"
  },
  "inferenceServers": {
    "title": "Serveurs d'inf\u00e9rence",
    "description": "Configurez les serveurs o\u00f9 s'ex\u00e9cutent les g\u00e9n\u00e9rations TTS et les t\u00e9l\u00e9chargements de mod\u00e8les. Plusieurs serveurs servent de failover ; le serveur en ligne avec la plus haute priorit\u00e9 est utilis\u00e9.",
    "name": "Nom",
    "namePlaceholder": "ex : Local",
    "url": "URL",
    "urlPlaceholder": "http://localhost:8000",
    "priority": "Priorit\u00e9",
    "priorityHint": "Plus le nombre est \u00e9lev\u00e9, plus il est prioritaire",
    "addServer": "Ajouter un serveur",
    "enabled": "Activé",
    "test": "Tester",
    "statusOnline": "En ligne",
    "statusOffline": "Hors ligne",
    "statusUnknown": "V\u00e9rification...",
    "lastChecked": "V\u00e9rifi\u00e9 {{when}}",
    "neverChecked": "Pas encore v\u00e9rifi\u00e9",
    "empty": "Aucun serveur d'inf\u00e9rence configur\u00e9. Ajoutez-en un pour commencer.",
    "deleteTitle": "Supprimer le serveur ?",
    "deleteDescription": "\u00ab {{name}} \u00bb sera supprim\u00e9 du registre. Les mod\u00e8les install\u00e9s dessus ne seront plus accessibles.",
    "saveFailed": "\u00c9chec de l'enregistrement",
    "removeFailed": "\u00c9chec de la suppression",
    "testFailed": "\u00c9chec du test",
    "testFailedStatus": "\u00c9chec du test ({{status}})",
    "authToken": "Token d'auth",
    "authTokenPlaceholder": "Collez le token affich\u00e9 par le script d'installation",
    "authTokenEditPlaceholder": "Laissez vide pour conserver le token actuel",
    "authTokenHint": "Optionnel. Requis si vous avez d\u00e9marr\u00e9 le serveur d'inf\u00e9rence avec INFERENCE_AUTH_TOKEN.",
    "authTokenEditHint": "Laissez vide pour conserver le token actuel. Saisissez une nouvelle valeur pour le faire tourner ; soumettez vide pour le supprimer.",
    "addDialog": {
      "title": "Ajouter un serveur d'inf\u00e9rence",
      "description": "Pointez Sirene vers un serveur d'inf\u00e9rence. Si vous n'en avez pas encore, lancez la commande ci-dessous sur une machine Linux \u2014 elle affiche l'URL et le token d'auth \u00e0 la fin.",
      "installLabel": "Installation rapide",
      "installHint": "Tourne sur Ubuntu/Debian. D\u00e9tecte le GPU NVIDIA automatiquement. Affiche l'URL et le token d'auth \u00e0 la fin."
    }
  },
  "settings": {
    "title": "Param\u00e8tres",
    "subtitle": "G\u00e9rez les serveurs d'inf\u00e9rence, les cl\u00e9s API et les int\u00e9grations cloud.",
    "tabs": {
      "inferenceServers": "Serveurs d'inf\u00e9rence",
      "apiKeys": "Cl\u00e9s API",
      "cloudKeys": "Int\u00e9grations cloud"
    },
    "cloudKeys": {
      "title": "Int\u00e9grations cloud",
      "description": "Cl\u00e9s pour les fournisseurs tiers (OpenAI, ElevenLabs, HuggingFace). Stock\u00e9es de mani\u00e8re s\u00e9curis\u00e9e et jamais affich\u00e9es en entier apr\u00e8s enregistrement."
    },
    "openAIKey": "Cl\u00e9 API OpenAI",
    "elevenLabsKey": "Cl\u00e9 API ElevenLabs",
    "hfToken": "Token HuggingFace",
    "removed": "{{key}} supprim\u00e9",
    "saved": "{{key}} enregistr\u00e9",
    "removeFailed": "\u00c9chec de la suppression",
    "saveFailed": "\u00c9chec de l'enregistrement"
  },
  "cliAuth": {
    "title": "Autoriser le CLI",
    "subtitle": "Saisissez le code \u00e0 usage unique affich\u00e9 dans votre terminal.",
    "codeLabel": "Code \u00e0 usage unique",
    "continue": "Continuer",
    "loading": "Recherche de la session...",
    "invalidTitle": "Code non reconnu",
    "invalidDescription": "Le code est invalide ou a expir\u00e9. Relancez `sirene login` pour en obtenir un nouveau.",
    "tryAgain": "Essayer un autre code",
    "alreadyDoneTitle": "Cette session a d\u00e9j\u00e0 \u00e9t\u00e9 utilis\u00e9e",
    "alreadyDoneDescription": "Vous pouvez fermer cet onglet et retourner au terminal.",
    "confirmTitle": "Autoriser la session CLI {{code}} ?",
    "confirmDescription": "Une nouvelle cl\u00e9 API sera cr\u00e9\u00e9e pour le CLI sur cet appareil.",
    "nameLabel": "Nom de la cl\u00e9",
    "namePlaceholder": "ex. CLI laptop",
    "nameHint": "Utilis\u00e9 pour identifier la cl\u00e9 dans Param\u00e8tres > Cl\u00e9s API.",
    "authorize": "Autoriser",
    "successTitle": "C'est bon !",
    "successDescription": "Vous pouvez fermer cet onglet et retourner au terminal.",
    "backHome": "Retour \u00e0 Sirene",
    "approveFailed": "\u00c9chec de l'autorisation du CLI",
    "scopesRequestedHint": "Le CLI a demand\u00e9 un ensemble de permissions sp\u00e9cifique. Vous pouvez d\u00e9cocher pour restreindre davantage ; vous ne pouvez pas accorder plus que ce qui a \u00e9t\u00e9 demand\u00e9."
  },
  "apiKeys": {
    "title": "Cl\u00e9s API",
    "description": "Cl\u00e9s longue dur\u00e9e pour le CLI et les int\u00e9grations externes. Utilisez l'en-t\u00eate `Authorization: Bearer <cl\u00e9>`.",
    "empty": "Aucune cl\u00e9 API. Cr\u00e9ez-en une pour utiliser le CLI ou appeler l'API depuis une autre application.",
    "create": "Cr\u00e9er une cl\u00e9",
    "createTitle": "Nouvelle cl\u00e9 API",
    "createDescription": "Donnez un nom m\u00e9morable \u00e0 la cl\u00e9 (par ex. \u00ab laptop \u00bb, \u00ab n8n prod \u00bb). Le secret complet ne s'affiche qu'une fois.",
    "createFailed": "\u00c9chec de la cr\u00e9ation de la cl\u00e9",
    "name": "Nom",
    "namePlaceholder": "ex. CLI laptop",
    "revealTitle": "Copiez la cl\u00e9 maintenant",
    "revealDescription": "C'est la seule fois que le secret est affich\u00e9. Conservez-le dans un endroit s\u00fbr.",
    "copy": "Copier",
    "copyFailed": "Impossible de copier dans le presse-papier",
    "copiedDone": "C'est sauvegard\u00e9",
    "revoke": "R\u00e9voquer",
    "revokeTitle": "R\u00e9voquer la cl\u00e9 ?",
    "revokeDescription": "\u00ab {{name}} \u00bb cessera de fonctionner imm\u00e9diatement. Action irr\u00e9versible.",
    "revoked": "Cl\u00e9 r\u00e9voqu\u00e9e",
    "revokeFailed": "\u00c9chec de la r\u00e9vocation",
    "loadFailed": "\u00c9chec du chargement des cl\u00e9s API",
    "created": "Cr\u00e9\u00e9e",
    "lastUsed": "Derni\u00e8re utilisation",
    "never": "jamais",
    "fullAccess": "Acc\u00e8s complet",
    "fullAccessHint": "Donne acc\u00e8s \u00e0 toutes les fonctionnalit\u00e9s. Recommand\u00e9 pour le CLI sur une machine de confiance.",
    "scopesHint": "Choisissez le minimum n\u00e9cessaire. Les appels aux autres endpoints renverront 403.",
    "scopes": {
      "generate": "G\u00e9n\u00e9rer de l'audio",
      "transcribe": "Transcrire de l'audio",
      "voices:read": "Lire les voix",
      "voices:write": "Cr\u00e9er, modifier, supprimer des voix",
      "models:read": "Lire les mod\u00e8les",
      "models:write": "Installer, modifier, supprimer des mod\u00e8les",
      "generations:read": "Lire les g\u00e9n\u00e9rations pass\u00e9es",
      "generations:write": "Supprimer des g\u00e9n\u00e9rations",
      "sessions:read": "Lire les sessions",
      "sessions:write": "Cr\u00e9er, modifier, supprimer des sessions",
      "inference-servers:read": "Lire les serveurs d'inf\u00e9rence",
      "inference-servers:write": "G\u00e9rer les serveurs d'inf\u00e9rence",
      "settings:read": "Lire les param\u00e8tres",
      "settings:write": "Modifier les param\u00e8tres"
    }
  },
  "deleteGeneration": {
    "title": "Supprimer la g\u00e9n\u00e9ration ?",
    "description": "Cette action est irr\u00e9versible. Le fichier audio sera d\u00e9finitivement supprim\u00e9."
  },
  "validators": {
    "required": "Ce champ est requis",
    "minLength": "Doit contenir au moins {{count}} caractères",
    "emailInvalid": "Adresse email invalide",
    "passwordMismatch": "Les mots de passe ne correspondent pas"
  },
  "login": {
    "title": "Bon retour parmi nous",
    "subtitle": "Connectez-vous à votre compte pour continuer",
    "email": "Email",
    "emailPlaceholder": "Votre email",
    "password": "Mot de passe",
    "submit": "Connexion",
    "failed": "Échec de la connexion",
    "invalidCredentials": "Email ou mot de passe invalide",
    "noAccount": "Vous n'avez pas de compte ?",
    "register": "Créer un compte"
  },
  "register": {
    "title": "Créer un compte",
    "subtitle": "Commencez avec votre propre espace de voix",
    "name": "Nom",
    "namePlaceholder": "Jean Dupont",
    "email": "Email",
    "emailPlaceholder": "Votre email",
    "password": "Mot de passe",
    "passwordConfirm": "Confirmer le mot de passe",
    "submit": "Inscription",
    "failed": "Échec de l'inscription",
    "hasAccount": "Vous avez déjà un compte ?",
    "login": "Connexion"
  },
  "auth": {
    "logout": "Déconnexion",
    "public": "Publique",
    "heroTitle": "Votre voix, amplifiée.",
    "heroSubtitle": "Créez, clonez et gérez des voix IA avec une plateforme TTS open-source.",
    "feature1": "TTS multi-moteur avec Kokoro, F5, Piper, ElevenLabs et plus",
    "feature2": "Clonage de voix à partir d'échantillons audio",
    "feature3": "Conception de voix assistée par IA"
  },
  "errors": {
    "internal": "Erreur interne",
    "voice.notFound": "Voix introuvable",
    "voice.zipRequired": "Un fichier .zip est requis",
    "voice.audioRequired": "Un fichier audio est requis",
    "voice.noModel": "Aucun modèle n'est associé à cette voix",
    "voice.elevenLabsPresetRequired": "Une voix ElevenLabs nécessite un voice ID prédéfini. Éditez la voix pour en sélectionner un.",
    "voice.openAiPresetRequired": "Une voix OpenAI TTS nécessite un voice ID prédéfini. Éditez la voix pour en sélectionner un.",
    "voice.cloningRequiresSample": "Le clonage vocal nécessite au moins un échantillon audio activé. Éditez la voix pour en ajouter ou en activer un.",
    "voice.archiveMissing": "Archive invalide : voice.json manquant",
    "voice.archiveInvalidJson": "Archive invalide : voice.json n'est pas un JSON valide",
    "voice.archiveMissingName": "Archive invalide : voice.json n'a pas de champ name",
    "model.notFound": "Modèle introuvable",
    "model.notInstalled": "Le modèle n'est pas installé",
    "model.notInstalledOnServer": "Le modèle n'est pas installé sur le serveur demandé",
    "model.notInCatalog": "Modèle absent du catalogue",
    "model.customNotFound": "Modèle personnalisé introuvable",
    "model.piperFieldsRequired": "Les champs onnx, config et name sont requis",
    "model.configInvalidJson": "Le fichier config n'est pas un JSON valide",
    "model.configNotPiper": "La config doit être au format Piper",
    "model.invalidName": "Nom de modèle invalide",
    "model.nameConflict": "Ce nom est déjà utilisé par un modèle du catalogue",
    "model.deleteFailed": "Échec de la suppression sur un ou plusieurs serveurs",
    "model.exportFailed": "Échec de l'export",
    "model.whisperNotInstalled": "Aucun modèle Whisper installé. Installez-en un depuis la page Modèles.",
    "model.noOnlineServer": "Aucun serveur d'inférence en ligne disponible",
    "model.invalidServerSelection": "Sélection de serveur invalide",
    "model.alreadyInstalled": "Le modèle est déjà installé",
    "model.serverIdsNotJson": "serverIds doit être un tableau JSON de chaînes",
    "model.serverIdsInvalid": "serverIds doit être un tableau JSON de chaînes non vides",
    "user.notFound": "Utilisateur introuvable",
    "apiKey.notFound": "Clé API introuvable",
    "apiKey.unknownScope": "Scope inconnu ou non autorisé",
    "auth.missingScope": "Cette clé API n'est pas autorisée à effectuer cette opération",
    "generation.notFound": "Génération introuvable",
    "session.notFound": "Session introuvable",
    "inferenceServer.notFound": "Serveur d'inférence introuvable",
    "settings.invalidKey": "Clé de paramètre invalide",
    "openai.keyNotConfigured": "Clé API OpenAI non configurée. Allez dans Paramètres pour l'ajouter.",
    "elevenlabs.keyNotConfigured": "Clé API ElevenLabs non configurée. Allez dans Paramètres pour l'ajouter.",
    "upstream.failed": "Échec d'un service upstream",
    "upstream.inference": "Erreur du worker d'inférence",
    "upstream.elevenlabs": "Erreur de l'API ElevenLabs",
    "upstream.openai": "Erreur de l'API OpenAI",
    "transcribe.timeout": "Transcription expirée",
    "transcribe.audioRequired": "Un fichier audio est requis",
    "auth.invalidToken": "Token invalide ou expiré",
    "auth.required": "Authentification requise",
    "auth.invalidCredentials": "Email ou mot de passe invalide",
    "auth.registrationFailed": "Échec de l'inscription",
    "cliAuth.sessionNotFound": "Session CLI introuvable ou expirée",
    "cliAuth.sessionAlreadyUsed": "Session CLI déjà utilisée",
    "voiceDesigner.nameAudioRequired": "Le nom et l'audio sont requis",
    "voiceDesigner.textFieldsExpected": "description, language, model et transcript doivent être des champs texte"
  }
}
