planche 0.8.13 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/app/assets/1p4z4GHT.js +2 -0
  2. package/app/assets/{DkPnEF-y.js → 6NUleTnS.js} +1 -1
  3. package/app/assets/ANL7Od0T.js +1 -0
  4. package/app/assets/B7zF7RU4.js +2 -0
  5. package/app/assets/B8zpsP_u.js +959 -0
  6. package/app/assets/B9DHeSQH.js +1 -0
  7. package/app/assets/B9NCreMu.js +1 -0
  8. package/app/assets/{CjoKIEBz.js → B9dhM8vw.js} +1 -1
  9. package/app/assets/BFw3KCAr.js +1 -0
  10. package/app/assets/BGuDcBB_.js +1 -0
  11. package/app/assets/BHe42P9W.js +1 -0
  12. package/app/assets/BJFk0Zzq.js +2 -0
  13. package/app/assets/BMGo7X_N.js +2 -0
  14. package/app/assets/BRZhVXRC.js +1 -0
  15. package/app/assets/BVwlLPu6.js +1 -0
  16. package/app/assets/BYWnKgIY.js +3 -0
  17. package/app/assets/BYvM8E39.js +1 -0
  18. package/app/assets/B_1rFijd.js +1 -0
  19. package/app/assets/Bgu3teFB.js +11 -0
  20. package/app/assets/BgvMpmFj.js +1 -0
  21. package/app/assets/BhPOHTk7.js +7 -0
  22. package/app/assets/BiyRPyXV.js +1 -0
  23. package/app/assets/Bkq2aetC.js +1 -0
  24. package/app/assets/BnI4D_rY.js +1 -0
  25. package/app/assets/BniymiMs.js +2 -0
  26. package/app/assets/Br4335vw.js +1 -0
  27. package/app/assets/BsYZ-U7K.js +1 -0
  28. package/app/assets/BvEGx3Si.js +4 -0
  29. package/app/assets/Bvu_eiyU.js +3 -0
  30. package/app/assets/C1gqjEN3.js +1 -0
  31. package/app/assets/C2S2GXdP.js +1 -0
  32. package/app/assets/C3w9xAkk.js +1 -0
  33. package/app/assets/C4QyqQoa.js +1 -0
  34. package/app/assets/C5Yv1gpQ.js +1 -0
  35. package/app/assets/CCQ6oQgi.js +1 -0
  36. package/app/assets/{Bajzqc8D.js → CDfSdkjY.js} +1 -1
  37. package/app/assets/CIIDOG9Y.js +1 -0
  38. package/app/assets/CP2U-viH.js +1 -0
  39. package/app/assets/CVZ3Bw6o.js +1 -0
  40. package/app/assets/CWb3a6Xp.js +1 -0
  41. package/app/assets/CWota0kb.js +1 -0
  42. package/app/assets/{B1pia_Rg.js → CYz610vE.js} +1 -1
  43. package/app/assets/Cdop6jK1.js +2 -0
  44. package/app/assets/CgQ0qqq4.js +1 -0
  45. package/app/assets/CiL8zoYm.js +1 -0
  46. package/app/assets/CkIm3SJy.js +1 -0
  47. package/app/assets/ClytWHSf.js +1 -0
  48. package/app/assets/CnoXRrek.js +1 -0
  49. package/app/assets/CqTgU2vp.css +2 -0
  50. package/app/assets/Cu_sGzNJ.js +1 -0
  51. package/app/assets/CwsH45Wr.js +2 -0
  52. package/app/assets/D3_CBO8-.js +1 -0
  53. package/app/assets/D4l4mWtD.js +1 -0
  54. package/app/assets/D6oRJsd8.js +1 -0
  55. package/app/assets/D8_hwGjG.js +1 -0
  56. package/app/assets/{CEtGUZGE.js → D8dVzi6I.js} +1 -1
  57. package/app/assets/DDeeBXtX.js +1 -0
  58. package/app/assets/DDjCZLb0.js +1 -0
  59. package/app/assets/DFeHpd8Y.js +1 -0
  60. package/app/assets/DKf3DkR6.js +1 -0
  61. package/app/assets/DO0W14Ho.js +1 -0
  62. package/app/assets/DPnYgSl3.js +1 -0
  63. package/app/assets/DU-Eln5x.js +1 -0
  64. package/app/assets/DY1k-USH.js +1 -0
  65. package/app/assets/DeNEO8HN.js +1 -0
  66. package/app/assets/DkqeIq13.js +1 -0
  67. package/app/assets/DnRoHgQS.js +1 -0
  68. package/app/assets/Dy6-E_uL.js +1 -0
  69. package/app/assets/DyQ8cEic.js +1 -0
  70. package/app/assets/DzRyVlxz.js +41 -0
  71. package/app/assets/FAouNaq9.js +1 -0
  72. package/app/assets/Nro86Y63.js +1 -0
  73. package/app/assets/Q6DQerac.js +8 -0
  74. package/app/assets/S7HbowYz.js +373 -0
  75. package/app/assets/UX-csQNt.js +2 -0
  76. package/app/assets/Udlj1Cgf.js +1 -0
  77. package/app/assets/{C0bzfYFC.js → XCH_yrJ8.js} +1 -1
  78. package/app/assets/_zaonxnw.js +1 -0
  79. package/app/assets/f6MhVR01.js +27 -0
  80. package/app/assets/tQiLT0zv.js +2 -0
  81. package/app/index.html +35 -27
  82. package/app/landing.css +17 -0
  83. package/dist/{chunk-XAI7WLQN.js → chunk-SDRLD5PK.js} +995 -121
  84. package/dist/embed.js +1 -1
  85. package/dist/index.js +1 -1
  86. package/package.json +6 -2
  87. package/app/assets/8RmjiG1u.js +0 -1
  88. package/app/assets/9kM6GVHV.js +0 -7
  89. package/app/assets/B2csuorb.js +0 -1
  90. package/app/assets/BCmzDvBt.js +0 -1
  91. package/app/assets/BHsXOlR9.js +0 -2
  92. package/app/assets/BO_H_8D-.js +0 -1
  93. package/app/assets/BRc4Nt6e.js +0 -1
  94. package/app/assets/BW4K9UH-.js +0 -1
  95. package/app/assets/BbdU8Zop.js +0 -2
  96. package/app/assets/BgkATqP8.js +0 -1
  97. package/app/assets/Bhquh17w.js +0 -959
  98. package/app/assets/Bjm-okwb.js +0 -1
  99. package/app/assets/Bs-p2SdN.js +0 -1
  100. package/app/assets/CF6jyexg.js +0 -41
  101. package/app/assets/CMoC9sLj.js +0 -1
  102. package/app/assets/COfwwXGO.js +0 -3
  103. package/app/assets/CS2mpWDL.js +0 -1
  104. package/app/assets/CUK2WAdf.js +0 -1
  105. package/app/assets/CVpOAP2j.js +0 -1
  106. package/app/assets/CVpzA8TC.js +0 -8
  107. package/app/assets/CZoj-eMm.js +0 -1
  108. package/app/assets/CbmIWIww.js +0 -1
  109. package/app/assets/CeXMO4BR.js +0 -1
  110. package/app/assets/Cf8o-5U6.js +0 -2
  111. package/app/assets/CiFkP-9S.js +0 -1
  112. package/app/assets/CpSudzcZ.js +0 -1
  113. package/app/assets/CqK9ewb_.js +0 -1
  114. package/app/assets/CrT26gRf.js +0 -1
  115. package/app/assets/D0jMUNSI.js +0 -2
  116. package/app/assets/D6kbK-ng.js +0 -1
  117. package/app/assets/DEEGN6UG.js +0 -6
  118. package/app/assets/DIJgEIiP.js +0 -27
  119. package/app/assets/DMRY-PmY.js +0 -1
  120. package/app/assets/DPdwSUSw.js +0 -1
  121. package/app/assets/DSmKDd5u.js +0 -1
  122. package/app/assets/DTDWV2fP.js +0 -2
  123. package/app/assets/DW8BZVdB.js +0 -1
  124. package/app/assets/DWMVPRon.js +0 -1
  125. package/app/assets/DbqogdCK.js +0 -356
  126. package/app/assets/Dc12Sye0.js +0 -1
  127. package/app/assets/DzVnJu74.js +0 -2
  128. package/app/assets/KuSp3gJs.css +0 -2
  129. package/app/assets/OjAiMU9J.js +0 -2
  130. package/app/assets/SFsWRs4-.js +0 -1
  131. package/app/assets/bgQ-QVd7.js +0 -1
  132. package/app/assets/fI8KJgQa.js +0 -1
  133. package/app/assets/hrOpaTVU.js +0 -1
  134. package/app/assets/p4yYbMPY.js +0 -2
  135. package/app/assets/pjlgs2cl.js +0 -1
  136. package/app/assets/pneb1la9.js +0 -1
  137. package/app/assets/qXWuX5B-.js +0 -1
  138. package/app/assets/useqs8Jk.js +0 -1
  139. package/app/assets/y4cmNs6-.js +0 -1
  140. package/app/assets/y664aOTm.js +0 -1
  141. package/app/assets/zspOy9D_.js +0 -2
@@ -1,2 +0,0 @@
1
- var e={reconnecting:`Reconnexion…`,dropSqlite:`Déposez pour ouvrir le fichier SQLite`,dropSqliteHint:`Ouvert dans votre navigateur via WebAssembly — le fichier reste sur votre ordinateur. Déposez le fichier -wal avec lui s'il existe.`,dropFailedTitle:`Impossible d'ouvrir le fichier déposé`,dropNotSqlite:`{{name}} n'est pas un fichier de base de données SQLite.`,crashTitle:`Un problème est survenu`,crashBody:`L'application a rencontré une erreur inattendue. Recharger restaure les connexions et les onglets ; les modifications de grille non enregistrées sont perdues.`,crashReload:`Recharger`},t={auto:`Langue du système ({{name}})`,en:`English`,ko:`한국어`,zh:`中文(简体)`,ja:`日本語`,de:`Deutsch`,fr:`Français`},n={title:`Sécurité`,description:`Garde-fous contre la perte accidentelle de données. Le mode lecture seule, la couleur d'environnement et le mode de transaction se règlent par connexion.`,language:`Langue`,languageHint:`S'applique immédiatement. « Langue du système » suit votre navigateur.`,resetDefaults:`Rétablir les valeurs par défaut`,done:`Terminé`,analytics:`Partager des statistiques d'utilisation anonymes`,analyticsHint:`Envoie des événements d'utilisation anonymes (moteur, fonctionnalité, type d'instruction) à Google Analytics. Jamais le texte SQL, les noms d'hôte, de table ou d'utilisateur.`,analyticsUnavailableHint:`Inactif dans cette version (aucun identifiant de mesure configuré).`,persistHistory:`Conserver l'historique des requêtes après rechargement`,persistHistoryHint:`Le texte des instructions est stocké dans ce navigateur (les mots de passe littéraux sont masqués ; les onglets d'éditeur ouverts sont toujours conservés). Désactivé : l'historique et les instantanés ne vivent que jusqu'à la fermeture de l'onglet.`,ai:{intro:`Planche peut demander à un modèle pourquoi une instruction a échoué ou un plan est lent. La question est assemblée ici dans l'app et envoyée par votre agent local au fournisseur ci-dessous — ni votre SQL ni votre schéma n'atteint planche.dev.`,provider:`Fournisseur`,openaiCompatible:`Compatible OpenAI`,model:`Modèle`,baseUrl:`URL de base`,baseUrlHint:`Laissez vide pour le point d'accès du fournisseur. Tout serveur compatible OpenAI convient — Azure, OpenRouter, un Ollama local.`,key:`Clé API`,keyHint:`Transmise à l'agent local et utilisée là-bas. Elle n'est jamais conservée dans ce navigateur ni envoyée à planche.dev.`,remember:`Mémoriser cette clé sur cette machine`,rememberHint:`L'écrit dans {{path}}, lisible par vous seul. Sans cela, la clé ne vit que dans l'agent en cours et disparaît à son arrêt.`,save:`Enregistrer`,forget:`Oublier la clé`,saved:`Enregistré.`,none:`Aucune clé définie.`,configuredSession:`Une clé est définie pour cette session d'agent seulement.`,configuredFile:`Une clé est stockée dans {{path}}.`,configuredEnv:`Les réglages IA de cet agent viennent de son environnement et ne sont pas modifiables ici.`,unreachable:`L'agent est injoignable, les réglages IA ne peuvent pas être modifiés.`,title:`Explications IA`,description:`Quel modèle explique un échec ou un plan, et avec la clé de qui.`,cli:`CLI locale (sans clé)`,cliCommand:`Commande`,cliHint:`Exécute une CLI d'agent déjà installée et connectée sur cette machine : aucune clé à saisir. Elle explique les échecs et les plans ; le panneau IA a besoin d'un provider capable d'appeler des outils.`,cliNone:`Aucune CLI d'agent trouvée sur cette machine. Installez Claude Code ou Codex, ou choisissez un autre provider.`,profile:`Anthropic (connexion de cette machine)`,profileHint:"Utilise les identifiants avec lesquels cette machine est déjà connectée — après `ant auth login`, le SDK les trouve seul. Rien à coller, et contrairement à une CLI locale c'est la vraie API, donc le panneau IA fonctionne aussi.",profileNone:"Aucun identifiant Anthropic trouvé sur cette machine. Lancez `ant auth login`, ou renseignez une clé.",configuredChoice:`{{provider}} utilisé — aucune clé conservée ; le choix est enregistré dans {{path}}.`},query:{title:`Requête`,description:`Comment une instruction s'exécute : ce que lance F9, combien de lignes reviennent, ce qui est prévisualisé.`},general:{title:`Général`,description:`La langue, ce qui survit à un rechargement, et ce qui quitte cette machine.`}},r={settings:{safety:`Sécurité…`,language:`Langue`,title:`Paramètres`,theme:`Thème`,query:`Requête…`,general:`Général…`,ai:`IA…`},help:{gettingStarted:`Premiers pas`,about:`À propos de Planche`,title:`Aide`,documentation:`Documentation`,learn:`Apprendre le SQL`,terms:`Conditions d’utilisation`,license:`Licence`,support:`Contacter le support`,mcp:`Connecter un agent IA (MCP)…`,privacy:`Confidentialité`},connection:{title:`Connexion`,connect:`Se connecter`,disconnect:`Se déconnecter`,readOnly:`Lecture seule`,manualTransactions:`Transactions manuelles`,saveDatabaseFile:`Enregistrer le fichier de base de données`,saveDatabaseFileBlocked:`Enregistrer le fichier de base de données (charger d'abord le -wal)`,exit:`Quitter`,sync:`Synchronisation des connexions`},query:{title:`Requête`,execute:`Exécuter`,executeStatementAtCursor:`Exécuter l'instruction au curseur`,executeWholeScript:`Exécuter tout le script`,newQueryTab:`Nouvel onglet de requête`,findReplace:`Rechercher et remplacer`,localHistory:`Historique local…`,explainPlan:`Afficher le plan d'exécution`,explainAnalyze:`Mesurer le plan d'exécution (exécute l'instruction)`,structure:`Structure de la requête`},edit:{title:`Édition`,undo:`Annuler`,redo:`Rétablir`,cut:`Couper`,copy:`Copier`,paste:`Coller`,selectAll:`Tout sélectionner`},database:{title:`Base de données`,create:`Créer une base de données`,alter:`Modifier la base de données`,drop:`Supprimer la base de données`,copy:`Copier la base de données`,compare:`Comparer les schémas…`,truncate:`Tronquer la base de données`,compareData:`Comparer les données…`,groupBy:`Grouper et compter…`},table:{title:`Table`,create:`Créer une table`,alter:`Modifier la table`,drop:`Supprimer la table`,rename:`Renommer la table`,truncate:`Tronquer la table`,duplicateStructure:`Dupliquer la structure de la table`},export:{title:`Exporter`,csv:`Télécharger en CSV`,tsv:`Télécharger en TSV`,schemaHtml:`Schéma en HTML`,links:`Exporter les liens de colonnes…`,importLinks:`Importer les liens de colonnes…`},tools:{title:`Outils`,userManager:`Gestion des utilisateurs`,processList:`Liste des processus`,variables:`Variables`,status:`État`,flush:`Flush`,quickCommand:`Commande rapide`,viewErd:`Afficher l'ERD`,scratchpad:`Bloc-notes (SQLite dans le navigateur)`,federated:`Requête fédérée (jointure entre connexions)…`,federatedTab:`Fédérée {{n}}`,ai:`Assistant IA`},messages:{databaseFileSaved:`Fichier de base de données enregistré`,databaseExported:`Base de données exportée en téléchargement`,databaseExportedWithReason:`Base de données exportée en téléchargement — {{reason}}`,errorSavingDatabase:`Erreur lors de l'enregistrement de la base de données : {{message}}`,noDatabaseSelected:`Aucune base de données sélectionnée`,noTableSelected:`Aucune table sélectionnée`,noActiveConnection:`Aucune connexion active`,databaseDropped:`Base de données « {{database}} » supprimée`,errorDroppingDatabase:`Erreur lors de la suppression de la base de données : {{message}}`,noTablesInDatabase:`Aucune table trouvée dans la base de données « {{database}} »`,databaseTruncated_one:`{{count}} table de « {{database}} » tronquée`,databaseTruncated_other:`Les {{count}} tables de « {{database}} » ont été tronquées`,errorTruncatingDatabase:`Erreur lors du tronquage de la base de données : {{message}}`,tableDropped:`Table « {{table}} » supprimée`,errorDroppingTable:`Erreur lors de la suppression de la table : {{message}}`,tableTruncated:`Table « {{table}} » tronquée`,errorTruncatingTable:`Erreur lors du tronquage de la table : {{message}}`,renameTablePrompt:`Renommer la table « {{table}} » en :`,tableRenamed:`Table « {{table}} » renommée en « {{newName}} »`,errorRenamingTable:`Erreur lors du renommage de la table : {{message}}`,truncateDatabaseTitle:`Vider toutes les tables de "{{name}}" ?`,truncateDatabaseDescription:`Toutes les lignes des {{count}} table(s) de "{{name}}" seront supprimées. La structure des tables est conservée. Cette action est irréversible.`,truncateDatabaseConfirm:`Vider toutes les tables`,renameTableTitle:`Renommer la table`,renameTableConfirm:`Renommer`,noLinksToExport:`Aucun lien de colonne à exporter.`,linksExported:`{{count}} liens de colonnes exportés.`,linksImported:`{{count}} liens de colonnes importés.`,linksImportedPartial:`{{count}} liens de colonnes importés ; aucun profil correspondant pour : {{profiles}}`,linksImportFailed:`Impossible d'importer les liens de colonnes : {{reason}}`}},i={title:`À propos de Planche`,tagline:`Un client de base de données pour MySQL, MariaDB, PostgreSQL et SQLite.`,version:`Version`,website:`Site web`,licenses:`Licences`,licensesLink:`Mentions des tiers`,disclaimer:`Planche est fourni « tel quel », sans garantie d'aucune sorte. Les auteurs ne sauraient être tenus responsables des dommages ou pertes de données découlant de son utilisation. Sauvegardez vos données avant d'exécuter des instructions destructrices.`,rights:`Tous droits réservés.`,legal:`Mentions légales`,terms:`Conditions`,privacy:`Confidentialité`,refund:`Remboursement`},a=JSON.parse(`{"dialog":{"title":"Se connecter à une base de données","firstQueryTab":"Requête 1","colHostName":"Nom de l'hôte","colTarget":"Cible","colDbms":"SGBD","noSaved":"Aucune connexion enregistrée","unnamed":"(sans nom)","pickOnConnect":"(choisir à la connexion)","noFile":"(aucun fichier)","selectPrompt":"Sélectionnez une connexion ou ajoutez-en une nouvelle","addNew":"Ajouter","delete":"Supprimer","testConnection":"Tester la connexion","connect":"Se connecter","close":"Fermer","unknownError":"Erreur inconnue","browserTestHint":"Les connexions SQLite dans le navigateur ouvrent un fichier local lorsque vous cliquez sur Se connecter.","testSuccess":"Connexion réussie","restoredUnsaved":"{{file}} : modifications non enregistrées restaurées depuis la copie en cache","restoredUnsavedDiskChanged":"{{file}} : modifications non enregistrées restaurées depuis la copie en cache — attention, le fichier sur le disque a changé depuis","walPending":"{{file}} est en mode WAL : des modifications récentes peuvent encore se trouver dans son fichier -wal. Utilisez « Charger le fichier -wal » ci-dessus pour les inclure.","walApplied":"{{file}} ouvert avec ses modifications -wal appliquées","connectFailedTitle":"Échec de la connexion","testSuccessDescription":"Le serveur a accepté les identifiants.","testFailedTitle":"Échec du test de connexion","privacy":"Rien de ce que vous saisissez ici n'est envoyé ni stocké sur les serveurs de planche.dev. Les profils de connexion restent uniquement dans le stockage local de ce navigateur ; les requêtes vont directement de l'agent local à votre base de données.","hostKeyTitle":"Clé d'hôte SSH inconnue","hostKeyDescription":"{{host}}:{{port}} a présenté une clé {{type}} d'empreinte {{fingerprint}}. Comparez-la avec l'empreinte fournie par l'administrateur du serveur ; accepter une mauvaise clé permet à un attaquant de lire votre trafic.","hostKeyAccept":"Faire confiance à cet hôte","gatewayTitle":"Profils de la passerelle","gatewayAdd":"Ajouter","gatewayAdded":"Profil de passerelle {{name}} ajouté.","gatewayReadOnly":"lecture seule","gatewayWritable":"modifiable","gatewayProfileHint":"Cette connexion utilise le profil « {{name}} » détenu par la passerelle ; rien à configurer ici.","gatewayLoadFailed":"Impossible de charger les profils de la passerelle : {{error}}","export":"Exporter…","exportWithoutSecrets":"Sans mot de passe","exportWithSecrets":"Avec mot de passe et clés","import":"Importer…","exported":"Connexion « {{name}} » exportée.","imported":"Connexion « {{name}} » importée.","importFailedTitle":"Impossible d'importer la connexion"},"form":{"hostName":"Nom de l'hôte","hostNamePlaceholder":"Ma connexion","dataSource":"Source de données","openVia":"Ouvrir via","viaBrowser":"Navigateur (fichier local)","viaAgent":"Agent local","viaBrowserHint":"Rien à installer. Idéal pour les fichiers qu'aucun autre programme n'utilise : le navigateur travaille sur une copie en mémoire et ne peut pas verrouiller le fichier ; les modifications faites ailleurs pendant qu'il est ouvert ne sont pas vues et Enregistrer les écrase.","viaAgentHint":"Ouvre le fichier avec SQLite lui-même via npx planche — verrouillage et WAL corrects, sûr même si d'autres programmes utilisent la même base de données.","databaseFile":"Fichier de base de données","changeFile":"Changer de fichier","filePickerHint":"Un sélecteur de fichier s'ouvre lorsque vous cliquez sur Se connecter (astuce : ⌘⇧. affiche les fichiers cachés, ⌘⇧G permet de saisir un chemin).","fileRememberedHint":"Le fichier choisi est mémorisé (Chromium), la reconnexion ne demande donc que l'autorisation. Utilisez Connexion > Enregistrer le fichier de base de données pour écrire les modifications.","authToken":"Jeton d'authentification","authTokenPlaceholder":"Laisser vide pour utiliser le jeton de l'agent appairé","filePathPlaceholder":"/chemin/vers/database.sqlite ou :memory:","createIfMissing":"Créer si absent","createIfMissingHint":"Le chemin est résolu sur l'hôte du serveur de tunnel","host":"Hôte","port":"Port","database":"Base de données","serviceName":"Nom du service","user":"Utilisateur","password":"Mot de passe","savePassword":"Enregistrer le mot de passe","savePasswordHint":"Désactivé : le mot de passe n'est conservé que pour cette session du navigateur et n'est jamais écrit sur le disque.","charset":"Jeu de caractères","autoConnection":"Connexion automatique","safety":"Sécurité","environment":"Environnement","environmentHint":"colore l'onglet et l'espace de travail","readOnly":"Lecture seule","readOnlyHint":"Refuser les instructions qui modifient les données ou le schéma","transactions":"Transactions","txAuto":"Auto-commit","txManual":"Manuel — Commit / Rollback depuis la barre d'outils","ssh":"SSH","sshTunnel":"Tunnel SSH","sshTunnelHint":"Atteindre la base via un hôte de rebond SSH (le tunnel est ouvert par l'agent local)","sshHost":"Hôte SSH","sshPort":"Port SSH","sshUser":"Utilisateur SSH","sshAuth":"Auth SSH","sshAuthKey":"Clé privée","sshAuthPassword":"Mot de passe","sshAuthAgent":"ssh-agent","sshAuthAgentHint":"Utilise les clés chargées dans le ssh-agent de la machine qui exécute npx planche (SSH_AUTH_SOCK).","sshPassword":"Mot de passe SSH","sshKey":"Clé privée","sshKeyPick":"Choisir un fichier de clé…","sshKeyLoaded":"Clé chargée","sshKeyHint":"Laisser vide pour utiliser l'IdentityFile de ~/.ssh/config (ou ~/.ssh/id_*) sur la machine de l'agent ; une clé choisie est enregistrée avec ce profil","sshPassphrase":"Phrase secrète","sshPassphrasePlaceholder":"Laisser vide si la clé n'en a pas","sshSecretsHint":"Le mot de passe SSH, la clé privée et la phrase de passe suivent le réglage « Enregistrer le mot de passe » ci-dessus. Les clés d'hôte inconnues sont affichées pour vérification avant la première connexion et enregistrées dans ~/.planche/known_hosts sur la machine de l'agent.","sshHostPlaceholder":"bastion.example.com ou un alias Host de ~/.ssh/config","sshUserPlaceholder":"Laisser vide pour utiliser ~/.ssh/config","sshTargetHint":"L'hôte et le port de la base sont résolus sur l'hôte de rebond — indiquez l'adresse réelle de la base (ex. le point de terminaison RDS), pas localhost ni une redirection de port locale.","connectionString":"Chaîne de connexion","connectionStringApplied":"Reportée dans les champs ci-dessous. La chaîne elle-même n'est pas enregistrée, seuls les champs le sont.","connectionStringInvalid":"Ce n'est pas un URI PostgreSQL (attendu : postgresql://user:password@host/database).","neonHint":"Collez l'URI de la console Neon (Connect > Connection string) ; les champs ci-dessous sont remplis à partir de celui-ci.","supabaseHint":"Collez l'URI de Supabase (Connect > Session pooler ou Direct connection) ; les champs ci-dessous sont remplis à partir de celui-ci.","supabasePoolerWarning":"Le port 6543 est le pooler en mode transaction : chaque instruction peut s'exécuter sur un backend différent, donc le changement de schéma, les tables temporaires, les prepared statements et les transactions manuelles ne fonctionnent pas. Utilisez le pooler de session (port 5432) ou la connexion directe.","managedTlsHint":"TLS est toujours activé pour ce service ; la connexion va directement de l'agent local au service (pas de tunnel SSH).","d1AccountId":"Account ID","d1DatabaseId":"Database ID","d1ApiToken":"Jeton API","d1Hint":"Account ID : tableau de bord Cloudflare, à droite de l'accueil du compte. Database ID : Storage & Databases > D1 > votre base. Jeton : My Profile > API Tokens > Create Token avec la permission « D1 Edit » (ou « D1 Read » en lecture seule). L'agent local appelle l'API Cloudflare avec ce jeton.","d1LimitsHint":"D1 exécute chaque requête isolément avec validation automatique : les transactions manuelles sont indisponibles ; la base apparaît comme l'unique schéma « main ».","doDevUrl":"URL wrangler dev","doHint":"Lancez \`wrangler dev\` dans votre projet Worker et collez l'URL affichée (port 8787 par défaut). L'agent local lit les Durable Objects de cette session, y compris ceux des autres sessions \`wrangler dev\` en cours d'exécution.","doLimitsHint":"Développement local uniquement : les Durable Objects déployés ne sont accessibles que depuis un Worker, Cloudflare ne propose donc aucune API pour les interroger. Chaque objet apparaît comme une base nommée « <espace de noms>/<objet> » ; chaque requête est validée automatiquement, les transactions manuelles sont donc indisponibles.","tls":"TLS","tlsEnable":"Chiffrer la connexion","tlsVerify":"Vérifier le certificat du serveur","tlsVerifyHint":"Désactivé : les certificats auto-signés sont acceptés (chiffré, mais le serveur n'est pas authentifié). Indisponible via un tunnel SSH.","d1DevUrl":"URL de dev locale","d1DevUrlHint":"Laissez vide pour passer par un compte Cloudflare. Renseignée, Planche lit la base que \`wrangler dev\` exécute sur cette machine — sans compte ni jeton d’API, et les champs de compte ci-dessous sont ignorés. Laissez le Database ID vide si le serveur de dev n’en expose qu’une.","d1PickDatabase":"Choisir une base"},"agent":{"copy":"Copier","looking":"Recherche de l'agent Planche…","online":"L'agent <b>v{{version}}</b> est en cours d'exécution sur <mono>{{url}}</mono>","outdated":"L'agent v{{version}} utilise le protocole {{protocol}}, mais cette application en requiert un plus récent. Redémarrez-le avec <cmd/>","unauthorized":"L'agent <b>v{{version}}</b> est en cours d'exécution sur <mono>{{url}}</mono>, mais cette application n'est pas appairée avec lui (le jeton change à chaque démarrage). Ouvrez le lien affiché dans le terminal de l'agent, ou collez le jeton sous Configurer.","offline":"Aucun agent à <mono>{{url}}</mono>. Lancez-le dans un terminal — il ouvre cette application déjà appariée.","close":"Fermer","configure":"Configurer","checkAgain":"Vérifier à nouveau","urlLabel":"URL de l'agent","urlPlaceholder":"http://127.0.0.1:8888 (par défaut)","tokenLabel":"Jeton","tokenPlaceholder":"Affiché par l'agent","reset":"Réinitialiser","save":"Enregistrer","remoteWarning":"Cet agent n'est pas sur votre ordinateur ({{host}}) : chaque connexion y envoie ses mots de passe et clés SSH.","remoteRefusedTitle":"Agent distant refusé","remoteRefused":"L'agent doit tourner sur cet ordinateur (127.0.0.1 ou localhost). Pour un agent sur une autre machine, redirigez son port avec \`ssh -L 8888:127.0.0.1:8888 user@host\` et gardez l'URL http://127.0.0.1:8888.","gateway":"Passerelle « {{name}} » : {{count}} profils côté serveur. Les identifiants restent sur la passerelle ; choisissez un profil ci-dessous."},"tab":{"noConnections":"Aucune connexion ouverte. Cliquez sur Se connecter pour commencer.","theSqliteFile":"le fichier SQLite","reopened":"{{file}} rouvert","reopenFailed":"Impossible de rouvrir le fichier : {{message}}","reopenPrompt":"Le navigateur a de nouveau besoin de votre autorisation pour lire <b>{{file}}</b>.","reopenFile":"Rouvrir le fichier","closeConnection":"Fermer la connexion","reconnected":"{{file}} reconnecté","accessNotGranted":"L'accès au fichier n'a pas été accordé ; Enregistrer exportera un téléchargement à la place.","detachedPrompt":"Travail sur une copie en cache de <b>{{file}}</b>. Reconnectez le fichier pour enregistrer les modifications sur place.","reconnectFile":"Reconnecter le fichier","detachedHide":"Masquer (Enregistrer demandera le fichier si nécessaire)","walFramesApplied_one":"{{count}} trame WAL appliquée depuis {{file}}-wal","walFramesApplied_other":"{{count}} trames WAL appliquées depuis {{file}}-wal","walNoChanges":"Le fichier -wal ne contenait aucune modification validée","walLoadFailed":"Impossible de charger le fichier -wal : {{message}}","walPrompt":"<b>{{file}}</b> est en mode WAL : il peut ne pas afficher les données les plus récentes tant que son fichier <mono>{{file}}-wal</mono> n'est pas chargé, et l'enregistrement est désactivé jusque-là. Si aucun fichier de ce type n'existe à côté (la base de données a été fermée proprement), confirmez-le plutôt. Si un autre programme utilise encore cette base de données, ouvrez-la plutôt via l'agent local (<mono>npx planche</mono>) : le navigateur ne peut pas partager le fichier en toute sécurité.","loadWal":"Charger le fichier -wal","noWalHint":"J'ai vérifié : il n'y a pas de fichier -wal à côté de la base de données","noWal":"Pas de fichier -wal","dismiss":"Ignorer","walHide":"Masquer (l'enregistrement reste désactivé)","readOnlyBadge":"lecture seule"}}`),o={connect:`Se connecter (Alt+N)`,disconnect:`Se déconnecter`,newQueryTab:`Nouvel onglet de requête (Alt+T)`,execute:`Exécuter (F9)`,executeStatement:`Exécuter l'instruction au curseur / la sélection (Ctrl+Enter)`,commit:`Commit`,commitHint:`Valider la transaction ouverte`,noOpenTransaction:`Aucune transaction ouverte`,rollback:`Rollback`,rollbackHint:`Annuler la transaction ouverte`,readOnlyBadge:`lecture seule`,readOnlyHint:`Cette connexion refuse les instructions qui modifient les données ou le schéma`,userManager:`Gestion des utilisateurs (Alt+U)`,quickCommand:`Commande rapide`,processList:`Liste des processus`,variables:`Variables`,status:`État`,flush:`Flush`,fullscreen:`Plein écran`},s={readOnly:`lecture seule`,txOpen:`tx ouverte`,manualTx:`tx manuelle`},c={title:`Commande rapide`,description:`Rechercher une commande à exécuter...`,inputPlaceholder:`Saisissez une commande ou recherchez...`,empty:`Aucune commande trouvée.`,groups:{connection:`Connexion`,query:`Requête`,database:`Base de données`,table:`Table`,tools:`Outils`},commands:{connect:`Se connecter`,disconnect:`Se déconnecter`,executeQuery:`Exécuter la requête`,newQueryTab:`Nouvel onglet de requête`,createDatabase:`Créer une base de données`,dropDatabase:`Supprimer la base de données`,createTable:`Créer une table`,alterTable:`Modifier la table`,dropTable:`Supprimer la table`,processList:`Liste des processus`,serverVariables:`Variables du serveur`,serverStatus:`État du serveur`,flush:`Flush`,userManager:`Gestion des utilisateurs`}},l={title:`Bienvenue dans Planche`,intro:`Un client SQL qui s'exécute dans votre navigateur. Vos bases de données sont accessibles via un petit agent sur votre machine : identifiants et données ne quittent jamais votre ordinateur.`,skip:`Passer`,skipTitle:`Masquer cet écran (Aide > Premiers pas le fait réapparaître)`,copy:`Copier`,copied:`Copié`,sampleOpenFailed:`Impossible d'ouvrir la base de données d'exemple : {{message}}`,steps:{agent:{title:`Lancer l'agent local`,body:`Lancez l’une de ces commandes dans un terminal. Elle démarre l’agent et l’apparie avec cette page.`},connection:{title:`Ajouter une connexion`,body:`Choisissez votre base de données pour ouvrir le formulaire de connexion avec les bons réglages par défaut.`},sample:{title:`Pas de base de données sous la main ? Essayez l'exemple`,body:`Chargez une base de données d'exemple de boutique en ligne (24 tables, ~50 k lignes, vues et déclencheurs) dans le navigateur pour essayer l'éditeur, la grille et l'arborescence du schéma.`,loading:`Chargement de l'exemple…`,button:`Essayer la base de données d'exemple`}},terms:{title:`Avant de commencer`,local:`Tout s’exécute localement : identifiants, requêtes et résultats restent sur votre machine et ne nous sont jamais envoyés.`,asIs:`Planche est fourni en l’état, sans garantie. Les garde-fous (confirmation des opérations destructives, mode lecture seule) sont des commodités, pas des garanties.`,dataLoss:`Vous êtes responsable de chaque instruction exécutée via Planche. Sauvegardez vos données avant toute opération destructive.`,agree:`J’ai lu et j’accepte les conditions d’utilisation.`,accepted:`Vous avez accepté les conditions d’utilisation.`,readFull:`Lire les conditions complètes`}},u={treeLabel:`Schéma`,unreachableHint:`Ce n'est pas la base de données à laquelle cette connexion est liée ; créez un profil pour elle afin de la parcourir`,objectType:{table:`Table`,view:`Vue`,procedure:`Procédure`,function:`Fonction`,trigger:`Déclencheur`,event:`Événement`},menu:{showCreate:`Afficher CREATE {{type}}`,alter:`Modifier {{type}}`,drop:`Supprimer {{type}}`,create:`Créer {{type}}`,refresh:`Actualiser`,unreachable:`Connectez-vous avec un profil lié à cette base de données pour la parcourir`,openDatabase:`Ouvrir la base de données`,createSchema:`Créer un schéma…`,createTable:`Créer une table`,dropDatabase:`Supprimer la base de données`,openSchema:`Ouvrir le schéma`,dropSchema:`Supprimer le schéma`,newQueryTab:`Nouvel onglet de requête`,generateSql:`Générer du SQL`,openTable:`Ouvrir la table`,alterTable:`Modifier la table`,showCreateTable:`Afficher CREATE TABLE`,duplicateStructure:`Dupliquer la structure`,copyTable:`Copier la table vers…`,compare:`Comparer {{type}}…`,truncateTable:`Tronquer la table`,dropTable:`Supprimer la table`,exportCsv:`Exporter en CSV`,exportTsv:`Exporter en TSV…`,openView:`Ouvrir la vue`,alterView:`Modifier la vue`,showCreateView:`Afficher CREATE VIEW`,dropView:`Supprimer la vue`,compareData:`Comparer les données…`,groupBy:`Grouper et compter…`},actions:{createStatementUnavailable:`-- Impossible de récupérer l'instruction CREATE pour {{type}} {{name}}`,getCreateFailed:`Échec de la récupération de CREATE {{type}} : {{message}}`,createTabTitle:`Créer {{type}}`,createSchemaTabTitle:`Créer un schéma`,generateSqlFailed:`Impossible de générer le SQL : {{message}}`,dropTableTitle:`Supprimer la table « {{name}} » ?`,dropTableDescription:`Cela supprime définitivement la table et toutes ses lignes{{from}}. Cette action est irréversible.`,dropTableConfirm:`Supprimer la table`,dropObjectTitle:`Supprimer {{type}} « {{name}} » ?`,dropObjectDescription:`La définition de {{type}} sera supprimée{{from}}. Cette action est irréversible.`,dropObjectConfirm:`Supprimer {{type}}`,fromDatabase:` de la base de données « {{database}} »`,dropped:`{{type}} {{name}} supprimé`,dropFailed:`Échec de la suppression de {{type}}`,dropDatabaseTitle:`Supprimer la base de données « {{name}} » ?`,dropDatabaseDescription:`Cela supprime définitivement la base de données avec toutes ses tables et données. Cette action est irréversible.`,dropDatabaseConfirm:`Supprimer la base de données`,droppedDatabase:`Base de données {{name}} supprimée`,dropDatabaseFailed:`Échec de la suppression de la base de données`,dropSchemaTitle:`Supprimer le schéma « {{name}} » ?`,dropSchemaDescription:`Cela supprime définitivement le schéma avec toutes ses tables et données. Cette action est irréversible.`,dropSchemaConfirm:`Supprimer le schéma`,droppedSchema:`Schéma {{name}} supprimé`,dropSchemaFailed:`Échec de la suppression du schéma`,truncateTitle:`Tronquer la table « {{name}} » ?`,truncateDescription:`Toutes les lignes de « {{name}} » seront supprimées. La structure de la table est conservée. Cette action est irréversible.`,truncateConfirm:`Tronquer la table`,truncated:`{{name}} tronquée`,truncateFailed:`Échec du tronquage`},tree:{loadDatabasesFailed:`Échec du chargement des bases de données : {{message}}`}},d={editor:{destructiveMarker:`Destructeur : {{action}} {{names}}`,readOnlyMarker:`La connexion est en lecture seule ; cette instruction modifie les données ou le schéma`,actionExecute:`Exécuter (selon les paramètres)`,actionExecuteStatement:`Exécuter l'instruction au curseur / la sélection`,actionExecuteScript:`Exécuter tout le script`,actionExplainPlan:`Afficher le plan d'exécution`,actionQueryStructure:`Structure de la requête`},tabs:{newQuery:`Nouvelle requête`,queryTitle:`Requête {{n}}`,erdViewer:`Visionneuse ERD`,close:`Fermer`,closeOthers:`Fermer les autres`,closeLeft:`Fermer les onglets à gauche`,closeRight:`Fermer les onglets à droite`,closeAll:`Tout fermer`},executor:{noActiveConnection:`Aucune connexion active`,uncommittedTitle:`Transaction non validée`,uncommittedDescription:`Cette connexion a une transaction ouverte. La déconnexion annulera ses modifications.`,uncommittedConfirm:`Annuler (rollback) et se déconnecter`,unsavedTitle:`Modifications non enregistrées`,unsavedDescription:`{{file}} contient des modifications qui n'ont pas été enregistrées dans son fichier. La déconnexion les abandonne (utilisez d'abord Connexion > Enregistrer le fichier de base de données pour les conserver).`,theSqliteDatabase:`La base de données SQLite`,unsavedConfirm:`Abandonner et se déconnecter`}},f=JSON.parse(`{"tabs":{"message":"Message","info":"Infos","history":"Historique","result":"Résultat","resultN":"Résultat {{n}}","plan":"Plan","structure":"Structure","structureN":"Structure {{n}}"},"message":{"executing":"Exécution de la requête...","error":"Erreur : {{message}}","total":" (Total : {{ms}} ms)","ready":"Prêt.","log":"Journal d'exécution","statementN":"Instruction {{n}}","limitedBadge":"limite atteinte","insertId":"insert id {{id}}","failed":"Échec","failedStatement":"Instruction en échec","summary":"{{ok}} réussies · {{failed}} échouées · {{ms}} au total","copy":"Copier","copied":"Copié","showSql":"Afficher le SQL","hideSql":"Masquer le SQL"},"hints":{"title":"Indice","unknownColumn":"Aucune colonne nommée {{name}}. Vouliez-vous dire {{suggestions}} ?","unknownTable":"Aucune table nommée {{name}}. Vouliez-vous dire {{suggestions}} ?","syntaxSwap":"{{engine}} écrit {{expected}} et non {{found}}.","doubleQuotedLiteral":"{{engine}} lit \\"{{value}}\\" comme un nom de colonne, pas comme du texte. Pour une chaîne, écrivez '{{value}}'."},"ai":{"title":"Explication IA","explain":"Expliquer avec l'IA","thinking":"Lecture de l'échec…","by":"par {{model}}","applyFix":"Ouvrir la correction dans un nouvel onglet","failed":"Impossible d'expliquer : {{message}}","noFailure":"Aucune instruction en échec à expliquer.","noPack":"Le prompt n'a pas pu être récupéré depuis planche.dev.","badShape":"Le modèle n'a pas répondu dans le format attendu.","noPlan":"Il n'y a pas encore de plan à expliquer.","explainPlan":"Expliquer ce plan"},"info":{"empty":"Aucune information de requête disponible.","resultN":"Résultat {{n}}","metadata":"Métadonnées de la requête","executionTime":"Temps d'exécution","notAvailable":"N/D","affectedRows":"Lignes affectées","fields":"Champs","fieldDetails":"Détails des champs","colName":"Nom","colType":"Type","colTable":"Table","resultSets":"Jeux de résultats","rowsReturned":"Lignes renvoyées","insertId":"Dernier ID inséré","lastQuery":"Dernière instruction exécutée","copy":"Copier","copied":"Copié","colOrigin":"Origine","primaryKey":"Clé primaire","rowsAndFields":"{{rows}} lignes × {{fields}} champs","noFields":"Cette instruction n'a renvoyé aucune colonne."},"rowForm":{"colColumn":"Colonne","colValue":"Valeur","insertTitle":"Insérer une ligne","editTitle":"Modifier la ligne","loading":"Chargement des colonnes...","preview":"Instruction","nothingToWrite":"Rien à écrire","insert":"Insérer","update":"Mettre à jour","stageInsert":"Ajouter comme ligne en attente","stageEdit":"Appliquer à la grille","stageHint":"Place les valeurs dans la grille sans rien exécuter ; validez plus tard avec les autres modifications.","inserted":"Ligne insérée dans {{table}}","updated":"Ligne mise à jour dans {{table}}","confirmInsertTitle":"Insérer une ligne dans {{table}} ?","confirmUpdateTitle":"Mettre à jour une ligne de {{table}} ?","inTransaction":"S'exécute dans la transaction ouverte","pickDate":"Choisir une date","now":"Maintenant","formatJson":"Formater","binaryUnsupported":"Les colonnes binaires ne sont pas modifiables ici ; laissez NULL/DEFAULT ou utilisez du SQL.","generateUuid":"Générer un UUID","defaultValue":"Valeur par défaut","clickToChange":"Cliquer pour modifier","empty":"(vide)","autoHint":"Généré par le serveur","mode":{"keep":"Conserver","auto":"Auto","value":"Valeur"},"invalid":{"integer":"Saisissez un entier","unsigned":"Cette colonne n'accepte pas les nombres négatifs","number":"Saisissez un nombre","json":"JSON invalide","date":"Utilisez YYYY-MM-DD","datetime":"Utilisez YYYY-MM-DD HH:MM:SS","time":"Utilisez HH:MM:SS","length":"{{max}} caractères maximum"}},"history":{"copied":"Copié dans le presse-papiers","searchPlaceholder":"Rechercher dans l'historique...","all":"Tous","success":"Réussies","failed":"Échouées","thisTab":"Cet onglet seulement","noMatch":"Aucune entrée ne correspond.","count":"{{count}} entrées","clear":"Effacer","clearTitle":"Effacer l'historique des requêtes ?","clearDescription":"Les {{count}} entrées de cette connexion seront supprimées. Cette action est irréversible.","clearConfirm":"Effacer l'historique","insert":"Insérer dans l'éditeur","inserted":"Inséré dans l'éditeur","copy":"Copier","rows":"{{count}} lignes","affected":"{{count}} affectées","today":"Aujourd'hui","yesterday":"Hier","empty":"Aucun historique de requêtes."},"json":{"arrayLength":"Array[{{count}}]","keys_one":"{{count}} clé","keys_other":"{{count}} clés","invalid":"JSON invalide","clickToView":"Cliquer pour afficher le JSON","expandAll":"Tout déplier","collapseAll":"Tout replier","edit":"Modifier","view":"Afficher","copied":"Copié","copy":"Copier","shortcutHint":"{{mod}}+Enter pour enregistrer · Esc pour annuler","cancel":"Annuler","save":"Enregistrer"},"text":{"clickToView":"Cliquer pour afficher le texte","size":"{{chars}} caractères · {{lines}} lignes","wrap":"Retour à la ligne"},"grid":{"readOnlyConnection":"Connexion en lecture seule","readOnlyWal":"Lecture seule : fichier -wal non chargé","readOnlyNoPk":"Lecture seule : la table n'a pas de clé primaire","commitTitle":"Valider {{count}} modification(s) dans {{table}} ?","commitDescription":"Les instructions suivantes seront exécutées.","commitConfirm":"Commit","rowPrefix":"Ligne {{row}} :","cancelled":"annulé","commitFailed":"Échec du commit : {{message}}","executedInTransaction":"{{count}} modification(s) exécutée(s) dans la transaction ouverte — cliquez sur Commit dans la barre d'outils pour les rendre permanentes (un rechargement les annule)","committed":"{{count}} modification(s) validée(s) dans {{table}}","noData":"Aucune donnée à afficher.","commit":"Commit","discard":"Abandonner","addRow":"Ajouter une ligne","removeNewRow":"Annuler cette nouvelle ligne","addRowForm":"Ajouter via un formulaire","addRowFormHint":"Ouvre un formulaire avec un champ par colonne (validé en INSERT)","editRowForm":"Modifier cette ligne dans un formulaire","addRowHint":"Ajouter une nouvelle ligne (validée par INSERT)","delete":"Supprimer","deleteCount":"Supprimer ({{count}})","deleteHint":"Supprimer les lignes sélectionnées (validé par DELETE). Sélectionnez les lignes avec la colonne des numéros de ligne.","field":"Champ","searchPlaceholder":"Rechercher...","orderBy":"Trier par","none":"Aucun","refresh":"Actualiser","dismiss":"Ignorer","clearSelection":"Effacer la sélection","columns":"Colonnes","showAllColumns":"Tout afficher","hideAllColumns":"Tout masquer","resetWidths":"Réinit. largeurs","selectAll":"Sélectionner toutes les lignes","emptyTable":"Cette table ne contient aucune ligne.","noRows":"Aucune ligne renvoyée.","addARow":"Ajouter une ligne","markedForDeletion":"Marquée pour suppression — cliquez pour restaurer","newRow":"Nouvelle ligne","clickToSelect":"Cliquez pour sélectionner ; Maj/Ctrl pour une sélection multiple","rows":"Lignes : {{count}}","rowsWithNew":"Lignes : {{count}} (+{{added}})","sortedBy":"Trié par : {{column}} {{direction}}","pageRange":"Lignes {{from}}–{{to}}","firstPage":"Première page","prevPage":"Page précédente","nextPage":"Page suivante","lastPage":"Dernière page","pagingBlocked":"Validez ou annulez vos modifications avant de changer de page","selected":"{{count}} sélectionnée(s)","cellsModified":"{{count}} cellule(s) modifiée(s)","newCount":"{{count}} nouvelle(s)","toDelete":"{{count}} à supprimer","searchMode":"Mode de correspondance","contains":"contient","equals":"égal à","followLink":"Ouvrir {{table}} où {{column}} = valeur","linkColumn":"Lier « {{column}} » à une autre table…","editLink":"Modifier le lien de « {{column}} »…","removeLink":"Supprimer le lien","copyValue":"Copier la valeur","filterByValue":"Filtrer : {{column}} = cette valeur","clearFilter":"Effacer le filtre","copyColumnName":"Copier le nom de la colonne","editCell":"Modifier la cellule","setNull":"Mettre à NULL","setEmpty":"Mettre une chaîne vide","restoreRow":"Restaurer la ligne","hideColumn":"Masquer la colonne « {{column}} »","copyRowsTsv_one":"Copier la ligne en TSV (avec en-tête)","copyRowsTsv_other":"Copier {{count}} lignes en TSV (avec en-tête)","copyRowsCsv_one":"Copier la ligne en CSV","copyRowsCsv_other":"Copier {{count}} lignes en CSV","copyRowsJson_one":"Copier la ligne en JSON","copyRowsJson_other":"Copier {{count}} lignes en JSON","copyRowsInsert_one":"Copier la ligne en INSERT","copyRowsInsert_other":"Copier {{count}} lignes en INSERT","deleteRowsPending_one":"Supprimer la ligne (en attente du Commit)","deleteRowsPending_other":"Supprimer {{count}} lignes (en attente du Commit)","sendRowsToScratchpad_one":"Envoyer la ligne au bloc-notes","sendRowsToScratchpad_other":"Envoyer {{count}} lignes au bloc-notes","sendAllToScratchpad":"Envoyer les {{count}} lignes chargées au bloc-notes","sentToScratchpad":"{{count}} lignes copiées dans la table {{table}} du bloc-notes.","changesSince":"Depuis le dernier chargement : {{changed}} modifiées · {{added}} nouvelles · {{gone}} disparues","changesToggle":"Afficher/masquer ce qui a changé depuis le chargement précédent","changesDismiss":"Oublier ces changements","previousValue":"Valeur précédente : {{value}}","groupByValue":"Grouper et compter par {{column}}"},"link":{"title":"Lier la colonne à une autre table","source":"Colonne","hint":"Les valeurs de cette colonne deviennent des liens : un clic ouvre la table cible filtrée sur les lignes correspondantes. Les vraies clés étrangères sont liées automatiquement.","targetDatabase":"Base cible","targetTable":"Table cible","targetColumn":"Colonne cible","pickTable":"Choisir une table","pickColumn":"Choisir une colonne","remove":"Supprimer le lien","cancel":"Annuler","save":"Enregistrer le lien","targetConnection":"Connexion cible","targetNotConnected":"La connexion liée n'est pas ouverte. Connectez-la d'abord."},"running":{"label":"Requête en cours…","elapsed":"{{seconds}} s","stop":"Arrêter","stopping":"Arrêt…","cannotCancel":"Ce moteur ne peut pas interrompre une instruction en cours.","agentOutdated":"L'agent local est trop ancien pour arrêter une requête. Mettez-le à jour avec \`npx planche@latest\` (ou \`planche upgrade\`) puis reconnectez-vous.","cancelFailed":"L'agent est injoignable ; la requête n'a pas été arrêtée.","abandoned":"L'attente de la requête a été interrompue. Ce moteur n'a pas d'annulation propre : la requête peut aller à son terme côté serveur."},"plan":{"empty":"Lancez « Afficher le plan d'exécution » (Ctrl+Maj+E) pour voir comment le moteur traitera l'instruction sous le curseur.","unreadable":"Le plan n'a pas pu être lu sous forme d'arbre ; la sortie du moteur est affichée telle quelle.","estimated":"Estimé","analyzed":"Mesuré","estimatedHint":"Estimations de l'optimiseur. L'instruction n'a pas été exécutée.","analyzedHint":"L'instruction a été exécutée ; les nombres de lignes et les temps sont réels.","totalCost":"Coût de nœud le plus élevé","totalTime":"Nœud le plus lent","rows":"Lignes estimées","actualRows":"Lignes réelles","cost":"Coût","time":"Temps","showRaw":"Sortie brute","showTree":"Arbre du plan","selectNode":"Sélectionnez un nœud pour voir ce que le moteur en a rapporté.","noDetails":"Le moteur n'a rien rapporté d'autre sur ce nœud.","warnings":{"fullScan":"Balayage complet","noIndex":"Aucun index","estimateOff":"Estimation erronée","temporary":"Table temporaire","filesort":"Tri"},"hints":{"fullScan":"Toutes les lignes de la table sont lues. Un index sur les colonnes filtrées l'éviterait.","noIndex":"Le moteur n'a trouvé aucun index utilisable pour cet accès.","estimateOff":"L'optimiseur attendait un nombre de lignes très différent. Rafraîchir les statistiques corrige souvent le plan.","temporary":"Les lignes sont matérialisées dans une table temporaire avant l'étape suivante.","filesort":"Tri effectué hors index. Un index correspondant à l'ORDER BY supprimerait ce tri."}},"structure":{"empty":"Afficher la structure (Ctrl+Maj+G) montre d'où viennent les lignes de l'instruction au curseur.","notQuery":"Seules les instructions SELECT ont un graphe de structure.","unsupported":"Les instructions {{engine}} ne peuvent pas être lues comme un graphe de structure.","parseError":"L'instruction n'a pas pu être analysée : {{message}}","columns_one":"{{count}} colonne","columns_other":"{{count}} colonnes","columnsUnknown":"largeur inconnue","fit":"Ajuster","reveal":"Sélectionner dans l'éditeur","notDrawn":"Non dessiné : {{what}}","kindTable":"TABLE","kindCte":"CTE","kindCteRef":"RÉF","kindDerived":"SOUS-REQUÊTE","kindScalar":"SCALAIRE","kindSetop":"ENSEMBLE","kindResult":"RÉSULTAT","fullscreen":"Plein écran","exitFullscreen":"Quitter le plein écran"}}`),p={defaultDescription:`Cette action est irréversible.`,typeToConfirm:`Saisissez <name/> pour confirmer`,cancel:`Annuler`,confirm:`Confirmer`,ok:`OK`},m={dialog:{createTitle:`Créer une table`,alterTitle:`Modifier la table`,duplicateTitle:`Dupliquer la structure de la table`,create:`Créer`,alter:`Modifier`,cancel:`Annuler`,tableName:`Nom de la table`,tableNamePlaceholder:`Saisissez le nom de la table...`,loading:`Chargement du schéma de la table...`,tabSchema:`Schéma`,tabIndexes:`Index`,tabProperties:`Propriétés`,applying:`Application…`,cannotAlterColumns:`{{engine}} ne peut pas modifier une colonne existante ({{columns}}). Ajouter, supprimer et renommer des colonnes ainsi que modifier les index fonctionnent ; pour changer une définition de colonne, recréez la table.`},schema:{colField:`Nom du champ`,colType:`Type de données`,colLength:`Longueur`,colDefault:`Par défaut`,colPk:`PK`,colNotNull:`Not Null`,colUnsigned:`Unsigned`,colAutoIncrement:`Auto Incr`,colZerofill:`Zerofill`,colComment:`Commentaire`,empty:`Aucune colonne définie. Cliquez sur « Ajouter une colonne » pour en ajouter une.`,add:`Ajouter une colonne`,remove:`Supprimer la colonne`},indexes:{colName:`Nom de l'index`,colType:`Type d'index`,colColumns:`Colonnes`,empty:`Aucun index défini. Cliquez sur « Ajouter un index » pour en ajouter un.`,add:`Ajouter un index`,remove:`Supprimer l'index`},index:{addTitle:`Ajouter un index`,editTitle:`Modifier l'index`,name:`Nom de l'index`,namePlaceholder:`Saisissez le nom de l'index`,type:`Type d'index`,columns:`Colonnes`,noColumns:`Aucune colonne disponible. Définissez d'abord des colonnes dans l'onglet Schéma.`,unnamed:`(sans nom)`,cancel:`Annuler`,ok:`OK`},properties:{engine:`Moteur`,charset:`Jeu de caractères`,collation:`Collation`,autoIncrement:`Auto-incrément`,autoIncrementPlaceholder:`Par défaut`,comment:`Commentaire`},info:{engine:`Moteur`,version:`Version`,rowFormat:`Format des lignes`,rows:`Lignes`,avgRowLength:`Longueur moyenne des lignes`,dataLength:`Taille des données`,createTime:`Date de création`,updateTime:`Date de mise à jour`,collation:`Collation`,comment:`Commentaire`},copy:{title:`Copier la table`,source:`Source`,targetConnection:`Connexion cible`,targetDatabase:`Base cible`,targetTable:`Nom de la table cible`,what:`Copier`,structureAndData:`Structure et données`,structureOnly:`Structure seule`,ifExists:`Si la table cible existe`,abort:`Abandonner (par défaut)`,dropAndRecreate:`Supprimer et recréer (le nom devra être ressaisi)`,preview:`CREATE TABLE sur la cible (modifiable)`,crossEngineHint:`La cible est {{engine}} : vérifiez les types ci-dessous, les attributs propres à MySQL ont été retirés.`,readOnly:`lecture seule`,loading:`Chargement…`,progressCreate:`Création de la table…`,progressCount:`Comptage des lignes…`,progressRows:`{{copied}} lignes copiées sur {{total}}`,progressDone:`Terminé`,doneTitle:`Table copiée`,doneRows:`{{count}} lignes copiées dans {{table}}.`,doneStructure:`Structure de {{table}} créée.`,noColumns:`La table source n'a aucune colonne.`,exists:`La table {{table}} existe déjà dans la cible. Choisissez un autre nom ou « Supprimer et recréer ».`,dropTitle:`Supprimer la table existante {{table}} ?`,dropDescription:`La table cible et toutes ses lignes seront supprimées avant la copie. Cette action est irréversible.`,dropConfirm:`Supprimer et copier`,cancelled:`Copie annulée.`,stop:`Arrêter`,cancel:`Annuler`,copy:`Copier`}},h={copy:{title:`Copier la base de données`,source:`Base de données source`,target:`Nom de la base de données cible`,targetPlaceholder:`Saisissez le nom de la base de données cible`,options:`Options`,structureAndData:`Structure et données`,structureOnly:`Structure uniquement`,cancel:`Annuler`,copy:`Copier`,creating:`Création de {{database}}…`,copying:`Copie de {{table}} ({{index}} sur {{total}})…`},diff:{title:`Comparer les schémas`,source:`Source`,target:`Cible`,pickConnection:`Connexion`,pickDatabase:`Base de données`,crossEngineHint:`Moteurs différents : les noms de types varient selon le dialecte, la plupart des colonnes apparaîtront comme modifiées.`,sameSide:`La source et la cible sont la même base.`,summary:`{{changed}} modifiées, {{missingTarget}} absentes de la cible, {{missingSource}} uniquement dans la cible, {{identical}} identiques`,showIdentical:`Afficher les tables identiques`,identicalAll:`Les tables sont identiques.`,column:`Colonne`,index:`Index`,object:`Objet`,selectTable:`Sélectionnez une table pour voir ses différences.`,missingInTarget:`{{table}} n'existe pas dans la cible ; le script la crée.`,missingInSource:`{{table}} n'existe que dans la cible ; le script la supprime (en commentaire sauf si les DROP sont inclus).`,includeDrops:`Inclure les instructions DROP en SQL exécutable (par défaut : en commentaire)`,tabTitle:`Sync {{database}}`,close:`Fermer`,compare:`Comparer`,comparing:`Comparaison…`,openScript:`Ouvrir le script dans l'éditeur`,noDefinition:`Aucune instruction CREATE disponible`},create:{title:`Créer une base de données`,name:`Nom de la base de données`,namePlaceholder:`Saisissez le nom de la base de données`,charset:`Jeu de caractères`,collation:`Collation`,cancel:`Annuler`,create:`Créer`},csv:{title:`Télécharger en {{format}}`,target:`Cible`,targetQueryResult:`Résultat de la requête actuelle`,targetTableData:`Données de la table`,tableName:`Nom de la table`,tableNamePlaceholder:`Saisissez le nom de la table`,delimiter:`Délimiteur`,delimiterComma:`Virgule (,)`,delimiterTab:`Tabulation (\\t)`,delimiterSemicolon:`Point-virgule (;)`,delimiterPipe:`Barre verticale (|)`,includeHeaders:`Inclure les en-têtes`,cancel:`Annuler`,download:`Télécharger`,downloading:`Téléchargement...`,progress:`{{loaded}} lignes sur {{total}} écrites`,progressUnknown:`{{loaded}} lignes écrites`,stop:`Arrêter`,done:`{{count}} lignes de {{table}} exportées en {{format}}.`,database:`Base de données`,databasePlaceholder:`Choisir une base`},html:{title:`Schéma en HTML`,database:`Base de données`,selectDatabase:`Sélectionner une base de données`,tables:`Tables à inclure`,selectAll:`Tout sélectionner`,deselectAll:`Tout désélectionner`,noTables:`Aucune table disponible.`,include:`Inclure`,includeColumns:`Colonnes`,includeIndexes:`Index`,includeProperties:`Propriétés`,cancel:`Annuler`,generate:`Générer`,generating:`Génération...`,sectionColumns:`Colonnes`,sectionIndexes:`Index`,sectionProperties:`Propriétés`,docTitle:`Schéma : {{database}}`,heading:`Base de données : {{database}}`,summary:`Tables : {{count}} | Généré le : {{date}}`,footer:`Généré par Planche 2026`},dataDiff:{title:`Comparer les données`,pickTable:`Table`,hint:`Les lignes sont associées par la clé primaire de la table source et comparées en texte. Jusqu'à {{cap}} lignes par côté sont chargées ; filtrez d'abord les grandes tables.`,sameSide:`La source et la cible sont la même table.`,noPrimaryKey:`{{table}} n'a pas de clé primaire ; la comparaison en a besoin pour associer les lignes.`,keyMissingInTarget:`La table cible n'a pas la ou les colonnes clés : {{columns}}`,summary:`Clé : {{key}} — {{added}} absentes de la cible, {{changed}} différentes, {{removed}} uniquement dans la cible, {{identical}} identiques`,capped:`Seules les {{cap}} premières lignes de chaque côté ont été comparées.`,ignoredColumns:`Colonnes ignorées (un seul côté) : {{columns}}`,added_one:`{{count}} absente de la cible`,added_other:`{{count}} absentes de la cible`,changed_one:`{{count}} différente`,changed_other:`{{count}} différentes`,removed_one:`{{count}} uniquement dans la cible`,removed_other:`{{count}} uniquement dans la cible`,none:`Rien dans ce groupe.`,more:`… {{count}} de plus non listées`,includeDeletes:`Inclure les instructions DELETE en SQL exécutable (par défaut : en commentaire)`,tabTitle:`Sync données {{table}}`,loading:`Chargement des lignes — source : {{source}}, cible : {{target}}`},schema:{createTitle:`Créer un schéma`,name:`Nom du schéma`,namePlaceholder:`Saisir le nom du schéma`,create:`Créer`,cancel:`Annuler`},groupBy:{title:`Grouper et compter`,description:`Compter les lignes de {{table}} selon les colonnes choisies.`,columns:`Grouper par`,aggregate:`Agrégat supplémentaire`,countOnly:`Nombre seulement`,column:`Colonne`,minCount:`Lignes minimum par groupe`,useFilter:`Appliquer le filtre actuel de la grille`,noIndexWarning:`Aucune colonne choisie n'est en tête d'un index : la base doit lire et trier toute la table. Cela peut être long sur une grande table.`,preview:`Requête`,pickColumn:`Choisissez au moins une colonne de regroupement.`,openInTab:`Ouvrir dans un nouvel onglet`,run:`Exécuter`,tabTitle:`Grouper {{table}}`,indexed:`En tête d'un index`,connection:`Connexion`,database:`Base de données`,table:`Table`}},g={manager:{title:`Gestion des utilisateurs`,addUser:`Ajouter un utilisateur`,removeUser:`Supprimer l'utilisateur`,noUsers:`Aucun utilisateur chargé`,grantScope:`Portée des privilèges`,apply:`Appliquer`,close:`Fermer`,removed:`Utilisateur '{{user}}'@'{{host}}' supprimé`,selectUserFirst:`Veuillez d'abord sélectionner un utilisateur`,applied:`Modifications appliquées`,noChanges:`Aucune modification de privilèges à appliquer.`},add:{title:`Ajouter un utilisateur`,username:`Nom d'utilisateur`,usernamePlaceholder:`Saisissez le nom d'utilisateur`,host:`Hôte`,password:`Mot de passe`,passwordPlaceholder:`Saisissez le mot de passe`,confirmPassword:`Confirmer le mot de passe`,confirmPasswordPlaceholder:`Confirmez le mot de passe`,plugin:`Plugin`,cancel:`Annuler`,add:`Ajouter`,usernameRequired:`Le nom d'utilisateur est requis`,passwordMismatch:`Les mots de passe ne correspondent pas`,added:`Utilisateur '{{user}}'@'{{host}}' ajouté`},privileges:{globalTitle:`Privilèges globaux`,databaseTitle:`Privilèges sur la base de données`,tableTitle:`Privilèges sur la table`,checkAll:`Tout cocher`,uncheckAll:`Tout décocher`,categoryData:`Données`,categoryStructure:`Structure`,categoryAdministration:`Administration`},grantTree:{globalPrivileges:`Privilèges globaux`}},_={close:`Fermer`,noActiveConnection:`Aucune connexion active`,variableName:`Nom de la variable`,value:`Valeur`,scope:{session:`Session`,global:`Global`},findReplace:{findPlaceholder:`Rechercher`,replacePlaceholder:`Remplacer`,found:`{{count}} trouvé(s)`,noResults:`Aucun résultat`,previous:`Précédent`,next:`Suivant`,close:`Fermer`,replace:`Remplacer`,all:`Tout`,caseSensitive:`Respecter la casse`,regex:`Regex`,wholeWord:`Mot entier`},flush:{title:`Flush`,executed:`Exécuté : {{command}}`,executeError:`Erreur lors de l'exécution de {{command}} : {{message}}`},localHistory:{title:`Historique local`,description:`Versions du texte de l'éditeur pour cette connexion : à chaque exécution, après une pause de saisie et à la fermeture d'un onglet.`,empty:`Aucune version enregistrée pour l'instant.`,noMatch:`Aucune version ne correspond à cette recherche.`,notPersisted:`« Conserver l'historique des requêtes après rechargement » est désactivé dans Paramètres > Sécurité ; les versions ne sont conservées que pour cette session.`,searchPlaceholder:`Rechercher des versions`,scopeTab:`Cet onglet`,scopeAll:`Tous les onglets`,compareCurrent:`avec l'actuel`,comparePrevious:`avec la précédente`,diffAgainstCurrent:`Comparé au texte actuel de l'éditeur`,diffAgainstPrevious:`Comparé à la version du {{time}}`,noPrevious:`Aucune version antérieure de cet onglet à comparer`,restored:`Contenu de l'éditeur restauré depuis l'historique local`,restore:`Restaurer cette version`,openInNewTab:`Ouvrir dans un nouvel onglet`,openedInTab:`Version ouverte dans un nouvel onglet`,delete:`Supprimer cette version`,clearAll:`Effacer l'historique`,chars:`{{count}} caractères`,reason:{execute:`avant l'exécution`,edit:`pendant la modification`,replaced:`avant l'écrasement`,restore:`avant la restauration`,close:`avant la fermeture`}},processList:{title:`Liste des processus`,refresh:`Actualiser`,autoRefresh:`Actualisation auto`,empty:`Aucun processus à afficher`,kill:`Tuer`,killProcess:`Tuer le processus`,selectToKill:`Veuillez sélectionner un processus à tuer`,killed:`Processus {{id}} tué`,killError:`Erreur lors de l'arrêt du processus : {{message}}`,loadError:`Erreur lors du chargement de la liste des processus : {{message}}`,updatedAt:`mis à jour à {{time}}`,filterPlaceholder:`Filtrer par utilisateur, hôte, base, SQL...`,hideIdle:`Masquer les inactifs`,noMatch:`Aucun processus ne correspond au filtre`,self:`moi`,selfHint:`Il s'agit de la session de Planche`,statementOf:`Instruction de #{{id}}`,noStatement:`Aucune instruction`,copy:`Copier`,copied:`Copié`,killConfirmTitle:`Terminer le processus {{id}} ?`,killConfirmDescription:`La session de {{user}}@{{host}} sera fermée et l'instruction en cours interrompue. Une transaction ouverte sera annulée.`,stats:{total:`Total`,active:`Actifs`,idle:`Inactifs`,longest:`Plus longue exécution`},columns:{id:`Id`,user:`Utilisateur`,host:`Hôte`,db:`db`,command:`Commande`,time:`Temps`,state:`État`,info:`Infos`,action:`Action`}},status:{title:`État du serveur`,filterPlaceholder:`Filtrer les variables d'état...`,empty:`Aucune variable d'état à afficher`,loadError:`Erreur lors du chargement de l'état : {{message}}`},variables:{title:`Variables du serveur`,filterPlaceholder:`Filtrer les variables...`,empty:`Aucune variable à afficher`,loadError:`Erreur lors du chargement des variables : {{message}}`}},v={empty:{title:`Ouvrez un fichier de schéma Prisma (.prisma) pour afficher l'ERD`,description:`Les modèles, énumérations et relations seront analysés automatiquement`,openFile:`Ouvrir un fichier .prisma`,dropHint:`ou glissez-déposez un fichier dans cette zone`},entity:{enumBadge:`ENUM`,modelBadge:`MODEL`,columns:{value:`Valeur`,comment:`Commentaire`,type:`Type`,column:`Colonne`},linkBadge:`LIEN`,externalTitle:`Table liée sur {{location}} (lien de colonne, pas une vraie clé étrangère)`,nullable:`Colonne acceptant NULL`},toolbar:{refresh:`Actualiser`,zoomIn:`Zoom avant`,zoomOut:`Zoom arrière`,resetView:`Réinitialiser la vue`,center:`Centrer`,fitAll:`Tout ajuster`,spreadAll:`Désempiler`,resetLayout:`Réinitialiser la disposition`,legendOneToMany:`1:N (FK)`,tables:`Tables :`,relations:`Relations :`,columns:`Colonnes :`,fullscreen:`Plein écran`,exitFullscreen:`Quitter le plein écran`},viewer:{noServerConnection:`Aucune connexion serveur active`,loading:`Chargement du schéma depuis {{database}}...`,loadFailed:`Échec du chargement de l'ERD`,noDatabase:`Aucune base de données sélectionnée.`,selectDatabaseHint:`Sélectionnez une base de données dans l'arborescence du schéma, puis ouvrez Afficher l'ERD.`}},y={runAnyway:`Exécuter quand même`,query:{rowsReturned:`{{count}} ligne(s) renvoyée(s)`,rowsAffected:`{{count}} ligne(s) affectée(s)`,rowsReturnedLimited:`{{count}} ligne(s) renvoyée(s) (limité à {{limit}} ; ajoutez LIMIT pour en récupérer davantage)`,notConnected:`Non connecté`,fileNotOpen:`Le fichier SQLite n'est pas encore ouvert — cliquez sur « Rouvrir le fichier » ci-dessus pour accorder à nouveau l'accès.`,failed:`Échec de la requête`,nothingToExecute:`Rien à exécuter`,dryRunMismatch:`L'aperçu prévoyait {{predicted}} lignes, {{actual}} ont été modifiées. Les données ont pu changer depuis l'aperçu ; sinon, l'aperçu ne correspondait pas à cette instruction.`},destructive:{title_one:`Exécuter l'instruction destructrice ?`,title_other:`Exécuter {{count}} instructions destructrices ?`,description:`Les instructions suivantes modifieront ou supprimeront définitivement des données. Cette action est irréversible.`,unknownTarget:`(inconnu)`,deleteAll:`DELETE de toutes les lignes de {{target}}`,updateAll:`UPDATE de toutes les lignes de {{target}}`,alterDrop:`DROP COLUMN/PARTITION sur {{target}}`},readOnly:{refused:`La connexion « {{label}} » est en lecture seule. {{count}} instruction(s) modifieraient les données ou le schéma.`,title:`« {{label}} » est en lecture seule`,description:`Ces instructions modifient les données ou le schéma. Les exécuter quand même sur cette connexion ?`},transaction:{startFailed:`Impossible de démarrer la transaction`,started:`Transaction démarrée — Commit ou Rollback une fois terminé`,implicitCommit:`{{kind}} a provoqué un COMMIT implicite de la transaction ouverte`,committed:`Transaction validée`,rolledBack:`Transaction annulée`,commandFailed:`Échec de {{name}}`,commandFailedWith:`Échec de {{name}} : {{message}}`},save:{notBrowserSqlite:`Ce n'est pas une connexion SQLite dans le navigateur.`,inMemory:`Base de données en mémoire : elle ne peut être exportée qu'en téléchargement.`,noFileSystemAccess:`Ce navigateur ne dispose pas de l'API File System Access (Chrome/Edge uniquement) : la base de données est exportée en téléchargement au lieu d'être écrite sur place.`,noWritableHandle:`Le fichier a été ouvert sans descripteur en écriture : il est exporté en téléchargement.`},agent:{devProxyUrl:`{{url}} (via le proxy de dev)`,notPlanche:`Quelque chose a répondu, mais ce n'est pas un agent Planche`,unreachable:"Agent Planche injoignable sur {{url}} — exécutez `npx planche` ({{message}})",httpError:`Erreur HTTP : {{status}} {{statusText}}`,emptyResponse:`Le serveur de tunnel a renvoyé une réponse vide`,reconnected:`Reconnecté à {{name}} — l'agent avait abandonné la connexion (redémarrage ou délai d'inactivité).`},sample:{profileName:`Boutique d'exemple (dans le navigateur)`,downloadFailed:`Impossible de télécharger la base de données d'exemple ({{status}})`,tabTitle:`Requête 1`},sqliteFile:{tooSmall:`Le fichier est trop petit pour être une base de données SQLite.`,notSqlite:`Ce n'est pas une base de données SQLite (ou elle est chiffrée, p. ex. SQLCipher). L'en-tête de 16 octets ne contient pas « SQLite format 3 ».`,badPageSize:`En-tête SQLite corrompu : taille de page invalide {{size}}.`,unreadable:`SQLite n'a pas pu lire le fichier : {{message}}`,pickerDescription:`Base de données SQLite`,walNotLoaded:`Cette base de données est en mode WAL et son fichier -wal n'a pas été chargé. Chargez-le, ou confirmez dans la bannière qu'aucun fichier -wal n'existe, avant d'enregistrer.`,changedOnDisk:`{{name}} a changé sur le disque après son chargement (un autre programme y a écrit). Enregistrer écraserait ces modifications — rouvrez le fichier et refaites vos modifications, ou utilisez le serveur de tunnel.`,walHasChanges:`{{name}}-wal contient de nouvelles modifications ; chargez-le avant d'enregistrer.`,walChangedOnDisk:`{{name}}-wal a été écrit par un autre programme après son chargement ; rouvrez le fichier avant d'enregistrer.`,writeDenied:`L'accès en écriture à {{name}} n'a pas été accordé. Autorisez-le dans l'invite du navigateur, ou exportez en téléchargement à la place.`},environment:{none:`Aucun`,green:`Vert (dev)`,blue:`Bleu`,yellow:`Jaune (staging)`,orange:`Orange`,red:`Rouge (production)`,purple:`Violet`},scratchpad:{profileName:`Bloc-notes`,namePromptTitle:`Nom de la table du bloc-notes`,namePromptDescription:`Une table nommée {{table}} existe déjà dans le bloc-notes. Choisissez un autre nom.`,nameTaken:`La table {{table}} existe déjà.`},federated:{pulling:`Récupération de {{table}} depuis {{connection}}…`,capped:`{{table}} : seules les {{limit}} premières lignes ont été récupérées.`,templateLine1:`Référencez une table de n'importe quelle connexion ouverte comme "Nom de connexion".database.table ; elle est copiée dans ce bloc-notes avant l'exécution.`,templateLine2:`Les tables sont limitées à {{limit}} lignes. La requête elle-même s'exécute dans SQLite (dans votre navigateur).`,templateConnections:`Connexions ouvertes : {{names}}`,templateNone:`Aucune autre connexion n'est ouverte. Connectez-en une, puis référencez-la ici.`,done:`{{rows}} lignes récupérées depuis {{tables}} tables distantes vers le bloc-notes.`,pullingProgress:`Récupération de {{table}} depuis {{connection}} : {{loaded}} / {{total}} lignes…`},paged:{noColumns:`{{table}} n'a aucune colonne.`,cancelled:`Annulé.`}},b={title:`Conditions d’utilisation`,version:`Version {{version}}`,englishOnly:`Les conditions sont fournies en anglais. Le résumé de l’écran d’accueil est disponible dans votre langue.`,privacyLink:`Politique de confidentialité`,refundLink:`Politique de remboursement`,online:`Lire sur planche.dev`,updated:`Dernière mise à jour : {{date}}`},x={title:`{{kind}} toucherait {{count}} lignes`,titleUnknown:`{{kind}} — lignes affectées inconnues`,description:`Voici les lignes que l'instruction toucherait maintenant, lues avec un SELECT. Rien n'a encore été écrit.`,previewFailed:`La requête d'aperçu a échoué : {{error}}
2
- Vous pouvez quand même exécuter l'instruction.`,noRows:`Aucune ligne ne correspond — l'instruction ne changerait rien.`,truncated:`Affichage des {{shown}} premières lignes sur {{count}}.`,previewQuery:`Requête d'aperçu`,run:`Exécuter {{kind}} ({{count}} lignes)`,runAnyway:`Exécuter quand même`},S={badge:`PRO`,tooltip:`Nécessite une licence Pro.`,noticeTitle:`Fonctionnalités Pro`,notice:`Les fonctions marquées PRO nécessitent une licence Pro.`,licenseTitle:`Planche Pro`,licenseDescription:`Collez la clé de licence reçue par e-mail. Elle est vérifiée sur cet ordinateur ; rien n’est envoyé nulle part.`,blocked:`{{feature}} nécessite une licence Pro.`,keyLabel:`Clé de licence`,activate:`Activer`,remove:`Retirer la licence`,active:`Pro est actif.`,licensedTo:`Sous licence de {{email}}`,validUntil:`Valable jusqu’au {{date}}`,expiredOn:`Cette licence a expiré le {{date}}. Renouvelez-la pour continuer à utiliser Pro.`,invalidKey:`Ce n’est pas une clé de licence Planche.`,notConfigured:`Cette version ne peut pas vérifier les clés de licence. Merci de le signaler.`,noWebcrypto:`Ce navigateur ne peut pas vérifier les clés de licence.`,pricing:`Voir les tarifs`,features:{ssh_tunnel:`Tunnels SSH`,compare_schemas:`Comparaison de schémas`,compare_data:`Comparaison de données`,copy_table:`Copie de table`,dry_run:`Dry run`,federated:`Requêtes fédérées`,scratchpad:`Bloc-notes`,column_link:`Liens de colonnes`,sync:`Synchronisation des connexions`,ai_explain:`Explications IA`},included:`Inclus dans Pro`,haveKey:`Vous avez déjà une clé de licence ?`,perMonth:`/ mois`,priceNote:`{{annual}} une fois par an. Au mois, c’est {{monthly}}.`,featureDetails:{sync:`Vos profils sur chaque ordinateur, chiffrés dans le navigateur avant d’en sortir`,ssh_tunnel:`Atteindre une base derrière un rebond avec un mot de passe, une clé ou ssh-agent`,compare_schemas:`Comparer deux connexions ouvertes et obtenir le script ALTER`,compare_data:`Comparer les lignes de deux tables et obtenir le script INSERT et UPDATE`,copy_table:`Reconstruire une table sur une autre connexion, ou un autre moteur`,dry_run:`Voir combien de lignes un UPDATE ou un DELETE modifie, et lesquelles, avant exécution`,federated:`Joindre des tables situées dans des connexions différentes`,scratchpad:`Une base SQLite locale pour vos données de travail`,column_link:`Des clés étrangères virtuelles à suivre depuis la grille`,ai_explain:`Demander à un modèle pourquoi une instruction a échoué ou un plan est lent — avec votre schéma`}},C={npxNote:`Nécessite Node.js 22 ou plus récent. Rien n’est installé durablement : npx exécute l’agent directement depuis le registre npm.`,installNote:`Pas besoin de Node.js. L’installation se fait dans votre dossier personnel sans droits d’administrateur ; ensuite la commande planche le démarre à tout moment.`},w={unsupported:`{{engine}} ne fournit pas de plan d'exécution.`,oneStatement:`Le plan porte sur une seule instruction. Placez le curseur dans l'instruction ou sélectionnez-la.`},T={title:`Assistant IA`,intro:`Demande une requête ou dis quoi faire — il lit le schéma, écrit du SQL dans un onglet et l'exécute. Il travaille sur la connexion ouverte, et chacune garde sa propre conversation.`,privacy:`Ce que lisent les outils — y compris des lignes d'exemple — est envoyé à votre provider. Rien n'atteint planche.dev.`,placeholder:`ex. construire une requête de chiffre d'affaires mensuel sur la base de démo`,send:`Envoyer`,stop:`Arrêter`,clear:`Nouvelle conversation`,working:`En cours…`,tabTitle:`Requête IA`,approvalTitle:`Cette étape écrit. L'exécuter ?`,approve:`Exécuter`,reject:`Passer`,rejected:`L'utilisateur a refusé l'exécution.`,notConfigured:`Aucune clé IA n'est définie sur l'agent. Ajoutez-en une dans Paramètres ▸ IA.`,needsAgent:`Cet agent local ne sait pas encore exécuter d'outils. Mettez-le à jour et réappairez.`,failed:`Échec`,empty:`Rien demandé pour l'instant.`,steps:`{{count}} étapes`,tooManySteps:`Arrêté après {{count}} étapes sans réponse.`,collapse:`Réduire`,planWarningTitle:`Cette requête fait un balayage complet. L’exécuter quand même ?`,interrupted:`Interrompu par un rechargement.`,external:`Demandé depuis l'extérieur de Planche`},E={title:`Connecter un agent IA (MCP)`,description:`Laisser un agent IA compatible MCP utiliser les outils de Planche.`,readsLabel:`Lecture`,reads:`Il lit la base ouverte, et les résultats partent vers ce programme.`,writesLabel:`Écriture`,writes:`Une instruction qui écrit demande votre accord. DROP et TRUNCATE, il ne peut pas.`,needsLabel:`Requis`,needs:`Le panneau IA doit être ouvert.`,tokenLabel:`Jeton`,token:`Un seul jeton, partagé par tous les programmes. Le révoquer les coupe tous.`,command:`Ajouter à Claude Code`,json:`Configurer à la main`,stored:`Stocké dans {{path}}.`,revoke:`Révoquer le jeton`,revoked:`Révoqué. Rouvrez ceci pour en émettre un nouveau.`},D={title:`Synchronisation des connexions`,description:`Vos profils de connexion, chiffrés dans ce navigateur et conservés sur planche.dev pour que vos autres ordinateurs les retrouvent.`,stored:`Le service ne conserve qu’un bloc chiffré. Il ne peut lire ni vos hôtes, ni vos utilisateurs, ni vos mots de passe, ni vos clés SSH.`,unavailable:`La synchronisation ne fonctionne que sur planche.dev. Cette copie de Planche est servie par votre agent local, à qui l’accès à Internet est interdit.`,signIn:`Se connecter avec GitHub`,signedInAs:`Connecté en tant que {{email}}`,signOut:`Se déconnecter`,createTitle:`Choisir une phrase secrète`,createHint:`Cette phrase secrète chiffre vos profils. Elle n’atteint jamais le serveur : si vous la perdez, la copie conservée est irrécupérable et devra être recréée depuis un ordinateur qui a encore vos profils.`,passphrase:`Phrase secrète`,confirm:`Confirmer la phrase secrète`,mismatch:`Les deux phrases secrètes diffèrent.`,tooShort:`Au moins {{count}} caractères.`,enable:`Activer la synchronisation`,unlockTitle:`Déverrouiller vos profils`,unlockHint:`Saisissez la phrase secrète choisie lors de l’activation.`,unlock:`Déverrouiller`,wrongPassphrase:`Phrase secrète incorrecte, ou copie conservée endommagée.`,syncNow:`Synchroniser maintenant`,lastSynced:`Dernière synchronisation {{when}}`,neverSynced:`Pas encore synchronisé`,profiles_one:`{{count}} profil`,profiles_other:`{{count}} profils`,changePassphrase:`Changer la phrase secrète`,deleteVault:`Supprimer du serveur`,deleteVaultConfirm:`Supprimer la copie chiffrée de planche.dev ? Les profils de cet ordinateur ne sont pas touchés.`,offline:`planche.dev est injoignable.`,working:`En cours…`,serverError:`planche.dev n’a pas pu terminer l’opération. Réessayez dans un instant.`,signInShort:`Se connecter`,needsPro:`Vous êtes connecté. La synchronisation des profils nécessite une licence Pro et fonctionnera dès que vous en aurez une.`,deleteAccount:`Supprimer le compte`,deleteAccountConfirm:`Supprimer votre compte ? La copie conservée et votre connexion disparaissent avec lui. Les profils de cet ordinateur ne sont pas touchés.`,notDeployed:`La synchronisation des connexions n’est pas encore activée sur ce site.`},O={closeTitle:`Fermer Planche ?`,closeDescription:`Il reste du travail non enregistré : une transaction ouverte, des modifications non validées ou une requête en cours. Fermer l'abandonne et annule la transaction.`,closeAnyway:`Fermer quand même`},k={app:e,language:t,settings:n,menu:r,about:i,connection:a,toolbar:o,footer:s,palette:c,welcome:l,schema:u,query:d,result:f,confirm:p,table:m,database:h,user:g,command:_,erd:v,services:y,terms:b,dryRun:x,pro:S,install:C,explain:w,ai:T,mcp:E,sync:D,desktop:O};export{i as about,T as ai,e as app,_ as command,p as confirm,a as connection,h as database,k as default,O as desktop,x as dryRun,v as erd,w as explain,s as footer,C as install,t as language,E as mcp,r as menu,c as palette,S as pro,d as query,f as result,u as schema,y as services,n as settings,D as sync,m as table,b as terms,o as toolbar,g as user,l as welcome};
@@ -1 +0,0 @@
1
- import{r as e}from"./hePW80VL.js";import{h as t}from"./B1pia_Rg.js";import{b as n,l as r,o as i,p as a,s as o,u as s}from"./pjlgs2cl.js";import{r as c,t as l}from"./bgQ-QVd7.js";import{S as u,_ as d,b as f,d as p,f as m,g as h,h as g,m as _,p as v,u as y,v as b,x,y as S}from"./CF6jyexg.js";import{n as C,t as w}from"./CEtGUZGE.js";import{t as T}from"./CZoj-eMm.js";import{Lt as E,Qt as D,Rt as O,Xt as k,Yt as A,Zt as j}from"./Bhquh17w.js";var M=e(n(),1),N=e(t(),1),P=Object.defineProperty,ee=(e,t)=>P(e,`name`,{value:t,configurable:!0});function F(e){let t=N.useRef({value:e,previous:e});return N.useMemo(()=>(t.current.value!==e&&(t.current.previous=t.current.value,t.current.value=e),t.current.previous),[e])}ee(F,`usePrevious`);var I=r(),L=Object.defineProperty,R=(e,t)=>L(e,`name`,{value:t,configurable:!0}),z=[` `,`Enter`,`ArrowUp`,`ArrowDown`],B=[` `,`Enter`],V=`Select`,[H,U,W]=l(V),[G,te]=u(V,[W,D]),K=D(),[ne,q]=G(V),[re,ie]=G(V);function J(e){let{__scopeSelect:t,children:n,open:r,defaultOpen:i,onOpenChange:a,value:o,defaultValue:s,onValueChange:c,dir:l,name:u,autoComplete:f,disabled:p,required:m,form:h,internal_do_not_use_render:g}=e,_=K(t),[v,y]=N.useState(null),[b,x]=N.useState(null),[w,T]=N.useState(!1),E=C(l),[D,O]=S({prop:r,defaultProp:i??!1,onChange:a,caller:V}),[k,A]=S({prop:o,defaultProp:s,onChange:c,caller:V}),M=N.useRef(null),P=N.useRef(k);N.useEffect(()=>{let e=h?v?.ownerDocument.getElementById(h):v?.form;if(e instanceof HTMLFormElement){let t=R(()=>A(P.current),`reset`);return e.addEventListener(`reset`,t),()=>e.removeEventListener(`reset`,t)}},[h,v,A]);let ee=!v||!!h||!!v.closest(`form`),[F,L]=N.useState(new Set),z=d(),B=Array.from(F).map(e=>e.props.value).join(`;`),U=N.useCallback(e=>{L(t=>new Set(t).add(e))},[]),W=N.useCallback(e=>{L(t=>{let n=new Set(t);return n.delete(e),n})},[]),G={required:m,trigger:v,onTriggerChange:y,valueNode:b,onValueNodeChange:x,valueNodeHasChildren:w,onValueNodeHasChildrenChange:T,contentId:z,value:k,onValueChange:A,open:D,onOpenChange:O,dir:E,triggerPointerDownPosRef:M,disabled:p,name:u,autoComplete:f,form:h,nativeOptions:F,nativeSelectKey:B,isFormControl:ee};return(0,I.jsx)(j,{..._,children:(0,I.jsx)(ne,{scope:t,...G,children:(0,I.jsx)(H.Provider,{scope:t,children:(0,I.jsx)(re,{scope:t,onNativeOptionAdd:U,onNativeOptionRemove:W,children:Ve(g)?g(G):n})})})})}R(J,`SelectProvider`);var ae=R(e=>{let{__scopeSelect:t,children:n,...r}=e;return(0,I.jsx)(J,{__scopeSelect:t,...r,internal_do_not_use_render:({isFormControl:e})=>(0,I.jsxs)(I.Fragment,{children:[n,e?(0,I.jsx)(Be,{__scopeSelect:t}):null]})})},`Select`),oe=`SelectTrigger`,se=N.forwardRef(R(function(e,t){let{__scopeSelect:n,disabled:r=!1,...i}=e,s=K(n),c=q(oe,n),l=c.disabled||r,u=a(t,c.onTriggerChange),d=U(n),f=N.useRef(`touch`),[p,m,h]=He(e=>{let t=d().filter(e=>!e.disabled),n=Ue(t,e,t.find(e=>e.value===c.value));n!==void 0&&c.onValueChange(n.value)}),g=R(e=>{l||(c.onOpenChange(!0),h()),e&&(c.triggerPointerDownPosRef.current={x:Math.round(e.pageX),y:Math.round(e.pageY)})},`handleOpen`);return(0,I.jsx)(A,{asChild:!0,...s,children:(0,I.jsx)(o.button,{type:`button`,role:`combobox`,"aria-controls":c.open?c.contentId:void 0,"aria-expanded":c.open,"aria-required":c.required,"aria-autocomplete":`none`,dir:c.dir,"data-state":c.open?`open`:`closed`,disabled:l,"data-disabled":l?``:void 0,"data-placeholder":$(c.value)?``:void 0,...i,ref:u,onClick:x(i.onClick,e=>{e.currentTarget.focus(),f.current!==`mouse`&&g(e)}),onPointerDown:x(i.onPointerDown,e=>{f.current=e.pointerType;let t=e.target;t.hasPointerCapture(e.pointerId)&&t.releasePointerCapture(e.pointerId),e.button===0&&e.ctrlKey===!1&&e.pointerType===`mouse`&&(g(e),e.preventDefault())}),onKeyDown:x(i.onKeyDown,e=>{let t=p.current!==``;!(e.ctrlKey||e.altKey||e.metaKey)&&e.key.length===1&&m(e.key),!(t&&e.key===` `)&&z.includes(e.key)&&(g(),e.preventDefault())})})})},`SelectTrigger`)),ce=`SelectValue`,le=N.forwardRef(R(function(e,t){let{__scopeSelect:n,className:r,style:i,children:s,placeholder:c=``,...l}=e,u=q(ce,n),{onValueNodeHasChildrenChange:d}=u,p=s!==void 0,m=a(t,u.onValueNodeChange);f(()=>{d(p)},[d,p]);let h=$(u.value);return(0,I.jsx)(o.span,{...l,asChild:!h&&l.asChild,ref:m,style:{pointerEvents:`none`},children:(0,I.jsx)(N.Fragment,{children:h?c:s},h?`placeholder`:`value`)})},`SelectValue`)),ue=N.forwardRef(R(function(e,t){let{__scopeSelect:n,children:r,...i}=e;return(0,I.jsx)(o.span,{"aria-hidden":!0,...i,ref:t,children:r||`▼`})},`SelectIcon`)),[de,fe]=G(`SelectPortal`,{forceMount:void 0}),pe=R(e=>{let{__scopeSelect:t,forceMount:n,...r}=e;return(0,I.jsx)(de,{scope:e.__scopeSelect,forceMount:n,children:(0,I.jsx)(v,{asChild:!0,...r})})},`SelectPortal`),Y=`SelectContent`,me=N.forwardRef(R(function(e,t){let n=fe(Y,e.__scopeSelect),{forceMount:r=n.forceMount,...i}=e,a=q(Y,e.__scopeSelect),[o,s]=N.useState();return f(()=>{s(new DocumentFragment)},[]),(0,I.jsx)(b,{present:r||a.open,children:({present:e})=>e?(0,I.jsx)(ve,{...i,ref:t}):(0,I.jsx)(he,{...i,fragment:o})})},`SelectContent`)),he=N.forwardRef(R(function(e,t){let{__scopeSelect:n,children:r,fragment:i}=e;return i?M.createPortal((0,I.jsx)(ge,{scope:n,children:(0,I.jsx)(H.Slot,{scope:n,children:(0,I.jsx)(`div`,{ref:t,children:r})})}),i):null},`SelectContentFragment`)),X=10,[ge,Z]=G(Y),_e=s(`SelectContent.RemoveScroll`),ve=N.forwardRef(R(function(e,t){let{__scopeSelect:n}=e,{position:r=`item-aligned`,onCloseAutoFocus:i,onEscapeKeyDown:o,onPointerDownOutside:s,side:c,sideOffset:l,align:u,alignOffset:d,arrowPadding:f,collisionBoundary:h,collisionPadding:v,sticky:b,hideWhenDetached:S,avoidCollisions:C,...w}=e,T=q(Y,n),[E,D]=N.useState(null),[O,k]=N.useState(null),A=a(t,D),[j,M]=N.useState(null),[P,ee]=N.useState(null),F=U(n),[L,z]=N.useState(!1),B=N.useRef(!1);N.useEffect(()=>{if(E)return y(E)},[E]),m();let V=N.useCallback(e=>{let[t,...n]=F().map(e=>e.ref.current),[r]=n.slice(-1),i=document.activeElement;for(let n of e)if(n===i||(n?.scrollIntoView({block:`nearest`}),n===t&&O&&(O.scrollTop=0),n===r&&O&&(O.scrollTop=O.scrollHeight),n?.focus(),document.activeElement!==i))return},[F,O]),H=N.useCallback(()=>V([j,E]),[V,j,E]);N.useEffect(()=>{L&&H()},[L,H]);let{onOpenChange:W,triggerPointerDownPosRef:G}=T;N.useEffect(()=>{if(E){let e={x:0,y:0},t=R(t=>{e={x:Math.abs(Math.round(t.pageX)-(G.current?.x??0)),y:Math.abs(Math.round(t.pageY)-(G.current?.y??0))}},`handlePointerMove`),n=R(n=>{e.x<=10&&e.y<=10?n.preventDefault():n.composedPath().includes(E)||W(!1),document.removeEventListener(`pointermove`,t),G.current=null},`handlePointerUp`);return G.current!==null&&(document.addEventListener(`pointermove`,t),document.addEventListener(`pointerup`,n,{capture:!0,once:!0})),()=>{document.removeEventListener(`pointermove`,t),document.removeEventListener(`pointerup`,n,{capture:!0})}}},[E,W,G]),N.useEffect(()=>{let e=R(()=>W(!1),`close`);return window.addEventListener(`blur`,e),window.addEventListener(`resize`,e),()=>{window.removeEventListener(`blur`,e),window.removeEventListener(`resize`,e)}},[W]);let[te,K]=He(e=>{let t=F().filter(e=>!e.disabled),n=Ue(t,e,t.find(e=>e.ref.current===document.activeElement));n&&setTimeout(()=>n.ref.current?.focus())}),ne=N.useCallback((e,t,n)=>{let r=!B.current&&!n;(T.value!==void 0&&T.value===t||r)&&(M(e),r&&(B.current=!0))},[T.value]),re=N.useCallback(()=>E?.focus(),[E]),ie=N.useCallback((e,t,n)=>{let r=!B.current&&!n;(T.value!==void 0&&T.value===t||r)&&ee(e)},[T.value]),J=r===`popper`?be:ye,ae=J===be?{side:c,sideOffset:l,align:u,alignOffset:d,arrowPadding:f,collisionBoundary:h,collisionPadding:v,sticky:b,hideWhenDetached:S,avoidCollisions:C}:{};return(0,I.jsx)(ge,{scope:n,content:E,viewport:O,onViewportChange:k,itemRefCallback:ne,selectedItem:j,onItemLeave:re,itemTextRefCallback:ie,focusSelectedItem:H,selectedItemText:P,position:r,isPositioned:L,searchRef:te,children:(0,I.jsx)(p,{as:_e,allowPinchZoom:!0,children:(0,I.jsx)(_,{asChild:!0,trapped:T.open,onMountAutoFocus:e=>{e.preventDefault()},onUnmountAutoFocus:x(i,e=>{T.trigger?.focus({preventScroll:!0}),e.preventDefault()}),children:(0,I.jsx)(g,{asChild:!0,disableOutsidePointerEvents:!0,onEscapeKeyDown:o,onPointerDownOutside:s,onFocusOutside:e=>e.preventDefault(),onDismiss:()=>T.onOpenChange(!1),children:(0,I.jsx)(J,{role:`listbox`,id:T.contentId,"data-state":T.open?`open`:`closed`,dir:T.dir,onContextMenu:e=>e.preventDefault(),...w,...ae,onPlaced:()=>z(!0),ref:A,style:{display:`flex`,flexDirection:`column`,outline:`none`,...w.style},onKeyDown:x(w.onKeyDown,e=>{let t=e.ctrlKey||e.altKey||e.metaKey;if(e.key===`Tab`&&e.preventDefault(),!t&&e.key.length===1&&K(e.key),[`ArrowUp`,`ArrowDown`,`Home`,`End`].includes(e.key)){let t=F().filter(e=>!e.disabled).map(e=>e.ref.current);if([`ArrowUp`,`End`].includes(e.key)&&(t=t.slice().reverse()),[`ArrowUp`,`ArrowDown`].includes(e.key)){let n=e.target,r=t.indexOf(n);t=t.slice(r+1)}setTimeout(()=>V(t)),e.preventDefault()}})})})})})})},`SelectContentImpl`)),ye=N.forwardRef(R(function(e,t){let{__scopeSelect:n,onPlaced:r,...i}=e,s=q(Y,n),c=Z(Y,n),[l,u]=N.useState(null),[d,p]=N.useState(null),m=a(t,p),h=U(n),g=N.useRef(!1),_=N.useRef(!0),{viewport:v,selectedItem:y,selectedItemText:b,focusSelectedItem:x}=c,S=N.useCallback(()=>{if(s.trigger&&s.valueNode&&l&&d&&v&&y&&b){let e=s.trigger.getBoundingClientRect(),t=d.getBoundingClientRect(),n=s.valueNode.getBoundingClientRect(),i=b.getBoundingClientRect();if(s.dir!==`rtl`){let r=i.left-t.left,a=n.left-r,o=e.left-a,s=e.width+o,c=Math.max(s,t.width),u=window.innerWidth-X,d=w(a,[X,Math.max(X,u-c)]);l.style.minWidth=s+`px`,l.style.left=d+`px`}else{let r=t.right-i.right,a=window.innerWidth-n.right-r,o=window.innerWidth-e.right-a,s=e.width+o,c=Math.max(s,t.width),u=window.innerWidth-X,d=w(a,[X,Math.max(X,u-c)]);l.style.minWidth=s+`px`,l.style.right=d+`px`}let a=h(),o=window.innerHeight-X*2,c=v.scrollHeight,u=window.getComputedStyle(d),f=parseInt(u.borderTopWidth,10),p=parseInt(u.paddingTop,10),m=parseInt(u.borderBottomWidth,10),_=parseInt(u.paddingBottom,10),x=f+p+c+_+m,S=Math.min(y.offsetHeight*5,x),C=window.getComputedStyle(v),T=parseInt(C.paddingTop,10),E=parseInt(C.paddingBottom,10),D=e.top+e.height/2-X,O=o-D,k=y.offsetHeight/2,A=y.offsetTop+k,j=f+p+A,M=x-j;if(j<=D){let e=a.length>0&&y===a[a.length-1].ref.current;l.style.bottom=`0px`;let t=d.clientHeight-v.offsetTop-v.offsetHeight,n=j+Math.max(O,k+(e?E:0)+t+m);l.style.height=n+`px`}else{let e=a.length>0&&y===a[0].ref.current;l.style.top=`0px`;let t=Math.max(D,f+v.offsetTop+(e?T:0)+k)+M;l.style.height=t+`px`,v.scrollTop=j-D+v.offsetTop}l.style.margin=`${X}px 0`,l.style.minHeight=S+`px`,l.style.maxHeight=o+`px`,r?.(),requestAnimationFrame(()=>g.current=!0)}},[h,s.trigger,s.valueNode,l,d,v,y,b,s.dir,r]);f(()=>S(),[S]);let[C,T]=N.useState();f(()=>{d&&T(window.getComputedStyle(d).zIndex)},[d]);let E=N.useCallback(e=>{e&&_.current===!0&&(S(),x?.(),_.current=!1)},[S,x]);return(0,I.jsx)(xe,{scope:n,contentWrapper:l,shouldExpandOnScrollRef:g,onScrollButtonChange:E,children:(0,I.jsx)(`div`,{ref:u,style:{display:`flex`,flexDirection:`column`,position:`fixed`,zIndex:C},children:(0,I.jsx)(o.div,{...i,ref:m,style:{boxSizing:`border-box`,maxHeight:`100%`,...i.style}})})})},`SelectItemAlignedPosition`)),be=N.forwardRef(R(function(e,t){let{__scopeSelect:n,align:r=`start`,collisionPadding:i=X,...a}=e,o=K(n);return(0,I.jsx)(k,{...o,...a,ref:t,align:r,collisionPadding:i,style:{boxSizing:`border-box`,...a.style,"--radix-select-content-transform-origin":`var(--radix-popper-transform-origin)`,"--radix-select-content-available-width":`var(--radix-popper-available-width)`,"--radix-select-content-available-height":`var(--radix-popper-available-height)`,"--radix-select-trigger-width":`var(--radix-popper-anchor-width)`,"--radix-select-trigger-height":`var(--radix-popper-anchor-height)`}})},`SelectPopperPosition`)),[xe,Se]=G(Y,{}),Ce=`SelectViewport`,we=N.forwardRef(R(function(e,t){let{__scopeSelect:n,nonce:r,...i}=e,s=Z(Ce,n),c=Se(Ce,n),l=a(t,s.onViewportChange),u=N.useRef(0);return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`style`,{dangerouslySetInnerHTML:{__html:`[data-radix-select-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-select-viewport]::-webkit-scrollbar{display:none}`},nonce:r}),(0,I.jsx)(H.Slot,{scope:n,children:(0,I.jsx)(o.div,{"data-radix-select-viewport":``,role:`presentation`,...i,ref:l,style:{position:`relative`,flex:1,overflow:`hidden auto`,...i.style},onScroll:x(i.onScroll,e=>{let t=e.currentTarget,{contentWrapper:n,shouldExpandOnScrollRef:r}=c;if(r?.current&&n){let e=Math.abs(u.current-t.scrollTop);if(e>0){let r=window.innerHeight-X*2,i=parseFloat(n.style.minHeight),a=parseFloat(n.style.height),o=Math.max(i,a);if(o<r){let i=o+e,a=Math.min(r,i),s=i-a;n.style.height=a+`px`,n.style.bottom===`0px`&&(t.scrollTop=s>0?s:0,n.style.justifyContent=`flex-end`)}}}u.current=t.scrollTop})})})]})},`SelectViewport`)),[Te,Ee]=G(`SelectGroup`),De=`SelectItem`,[Oe,ke]=G(De),Ae=N.forwardRef(R(function(e,t){let{__scopeSelect:n,value:r,disabled:i=!1,textValue:s,...c}=e,l=q(De,n),u=Z(De,n),f=l.value===r,[p,m]=N.useState(s??``),[g,_]=N.useState(!1),v=h(e=>u.itemRefCallback?.(e,r,i)),y=a(t,v),b=d(),S=N.useRef(`touch`),C=R(()=>{i||(l.onValueChange(r),l.onOpenChange(!1))},`handleSelect`);return(0,I.jsx)(Oe,{scope:n,value:r,disabled:i,textId:b,isSelected:f,onItemTextChange:N.useCallback(e=>{m(t=>t||(e?.textContent??``).trim())},[]),children:(0,I.jsx)(H.ItemSlot,{scope:n,value:r,disabled:i,textValue:p,children:(0,I.jsx)(o.div,{role:`option`,"aria-labelledby":b,"data-highlighted":g?``:void 0,"aria-selected":f&&g,"data-state":f?`checked`:`unchecked`,"aria-disabled":i||void 0,"data-disabled":i?``:void 0,tabIndex:i?void 0:-1,...c,ref:y,onFocus:x(c.onFocus,()=>_(!0)),onBlur:x(c.onBlur,()=>_(!1)),onClick:x(c.onClick,()=>{S.current!==`mouse`&&C()}),onPointerUp:x(c.onPointerUp,()=>{S.current===`mouse`&&C()}),onPointerDown:x(c.onPointerDown,e=>{S.current=e.pointerType}),onPointerMove:x(c.onPointerMove,e=>{S.current=e.pointerType,i?u.onItemLeave?.():S.current===`mouse`&&e.currentTarget.focus({preventScroll:!0})}),onPointerLeave:x(c.onPointerLeave,e=>{e.currentTarget===document.activeElement&&u.onItemLeave?.()}),onKeyDown:x(c.onKeyDown,e=>{i||e.target!==e.currentTarget||(u.searchRef?.current===``||e.key!==` `)&&(B.includes(e.key)&&C(),e.key===` `&&e.preventDefault())})})})})},`SelectItem`)),Q=`SelectItemText`,je=N.forwardRef(R(function(e,t){let{__scopeSelect:n,className:r,style:i,...s}=e,c=q(Q,n),l=Z(Q,n),u=ke(Q,n),d=ie(Q,n),[p,m]=N.useState(null),g=h(e=>l.itemTextRefCallback?.(e,u.value,u.disabled)),_=a(t,m,u.onItemTextChange,g),v=p?.textContent,y=N.useMemo(()=>(0,I.jsx)(`option`,{value:u.value,disabled:u.disabled,children:v},u.value),[u.disabled,u.value,v]),{onNativeOptionAdd:b,onNativeOptionRemove:x}=d;return f(()=>(b(y),()=>x(y)),[b,x,y]),(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(o.span,{id:u.textId,...s,ref:_}),u.isSelected&&c.valueNode&&!c.valueNodeHasChildren&&!$(c.value)?M.createPortal(s.children,c.valueNode):null]})},`SelectItemText`)),Me=`SelectItemIndicator`,Ne=N.forwardRef(R(function(e,t){let{__scopeSelect:n,...r}=e;return ke(Me,n).isSelected?(0,I.jsx)(o.span,{"aria-hidden":!0,...r,ref:t}):null},`SelectItemIndicator`)),Pe=`SelectScrollUpButton`,Fe=N.forwardRef(R(function(e,t){let n=Z(Pe,e.__scopeSelect),r=Se(Pe,e.__scopeSelect),[i,o]=N.useState(!1),s=a(t,r.onScrollButtonChange);return f(()=>{if(n.viewport&&n.isPositioned){let e=function(){let e=t.scrollTop>0;o(e)};R(e,`handleScroll`);let t=n.viewport;return e(),t.addEventListener(`scroll`,e),()=>t.removeEventListener(`scroll`,e)}},[n.viewport,n.isPositioned]),i?(0,I.jsx)(Re,{...e,ref:s,onAutoScroll:()=>{let{viewport:e,selectedItem:t}=n;e&&t&&(e.scrollTop-=t.offsetHeight)}}):null},`SelectScrollUpButton`)),Ie=`SelectScrollDownButton`,Le=N.forwardRef(R(function(e,t){let n=Z(Ie,e.__scopeSelect),r=Se(Ie,e.__scopeSelect),[i,o]=N.useState(!1),s=a(t,r.onScrollButtonChange);return f(()=>{if(n.viewport&&n.isPositioned){let e=function(){let e=t.scrollHeight-t.clientHeight,n=Math.ceil(t.scrollTop)<e;o(n)};R(e,`handleScroll`);let t=n.viewport;return e(),t.addEventListener(`scroll`,e),()=>t.removeEventListener(`scroll`,e)}},[n.viewport,n.isPositioned]),i?(0,I.jsx)(Re,{...e,ref:s,onAutoScroll:()=>{let{viewport:e,selectedItem:t}=n;e&&t&&(e.scrollTop+=t.offsetHeight)}}):null},`SelectScrollDownButton`)),Re=N.forwardRef(R(function(e,t){let{__scopeSelect:n,onAutoScroll:r,...i}=e,a=Z(`SelectScrollButton`,n),s=N.useRef(null),c=U(n),l=N.useCallback(()=>{s.current!==null&&(window.clearInterval(s.current),s.current=null)},[]);return N.useEffect(()=>()=>l(),[l]),f(()=>{c().find(e=>e.ref.current===document.activeElement)?.ref.current?.scrollIntoView({block:`nearest`})},[c]),(0,I.jsx)(o.div,{"aria-hidden":!0,...i,ref:t,style:{flexShrink:0,...i.style},onPointerDown:x(i.onPointerDown,()=>{s.current===null&&(s.current=window.setInterval(r,50))}),onPointerMove:x(i.onPointerMove,()=>{a.onItemLeave?.(),s.current===null&&(s.current=window.setInterval(r,50))}),onPointerLeave:x(i.onPointerLeave,()=>{l()})})},`SelectScrollButtonImpl`)),ze=`SelectBubbleInput`,Be=N.forwardRef(R(function({__scopeSelect:e,...t},n){let r=q(ze,e),{value:i,onValueChange:s,required:l,disabled:u,name:d,autoComplete:f,form:p}=r,{nativeOptions:m,nativeSelectKey:h}=r,g=N.useRef(null),_=a(n,g),v=i??``,y=F(v),b=Array.from(m).some(e=>(e.props.value??``)===``);return N.useEffect(()=>{let e=g.current;if(!e)return;let t=window.HTMLSelectElement.prototype,n=Object.getOwnPropertyDescriptor(t,`value`).set;if(y!==v&&n){let t=new Event(`change`,{bubbles:!0});n.call(e,v),e.dispatchEvent(t)}},[y,v]),(0,I.jsxs)(o.select,{"aria-hidden":!0,required:l,tabIndex:-1,name:d,autoComplete:f,disabled:u,form:p,onChange:e=>s(e.target.value),...t,style:{...c,...t.style},ref:_,defaultValue:v,children:[$(i)&&!b?(0,I.jsx)(`option`,{value:``}):null,Array.from(m)]},h)},`SelectBubbleInput`));function Ve(e){return typeof e==`function`}R(Ve,`isFunction`);function $(e){return e===``||e===void 0}R($,`shouldShowPlaceholder`);function He(e){let t=h(e),n=N.useRef(``),r=N.useRef(0),i=N.useCallback(e=>{let i=n.current+e;t(i),R((function e(t){n.current=t,window.clearTimeout(r.current),t!==``&&(r.current=window.setTimeout(()=>e(``),1e3))}),`updateSearch`)(i)},[t]),a=N.useCallback(()=>{n.current=``,window.clearTimeout(r.current)},[]);return N.useEffect(()=>()=>window.clearTimeout(r.current),[]),[n,i,a]}R(He,`useTypeaheadSearch`);function Ue(e,t,n){let r=t.length>1&&Array.from(t).every(e=>e===t[0])?t[0]:t,i=n?e.indexOf(n):-1,a=We(e,Math.max(i,0));r.length===1&&(a=a.filter(e=>e!==n));let o=a.find(e=>e.textValue.toLowerCase().startsWith(r.toLowerCase()));return o===n?void 0:o}R(Ue,`findNextItem`);function We(e,t){return e.map((n,r)=>e[(t+r)%e.length])}R(We,`wrapArray`);function Ge({...e}){return(0,I.jsx)(ae,{"data-slot":`select`,...e})}function Ke({...e}){return(0,I.jsx)(le,{"data-slot":`select-value`,...e})}function qe({className:e,size:t=`default`,children:n,...r}){return(0,I.jsxs)(se,{"data-slot":`select-trigger`,"data-size":t,className:i(`flex w-fit items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground`,e),...r,children:[n,(0,I.jsx)(ue,{asChild:!0,children:(0,I.jsx)(E,{className:`size-4 opacity-50`})})]})}function Je({className:e,children:t,position:n=`item-aligned`,align:r=`center`,...a}){return(0,I.jsx)(pe,{children:(0,I.jsxs)(me,{"data-slot":`select-content`,className:i(`relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95`,n===`popper`&&`data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1`,e),position:n,align:r,...a,children:[(0,I.jsx)(Xe,{}),(0,I.jsx)(we,{className:i(`p-1`,n===`popper`&&`h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1`),children:t}),(0,I.jsx)(Ze,{})]})})}function Ye({className:e,children:t,...n}){return(0,I.jsxs)(Ae,{"data-slot":`select-item`,className:i(`relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2`,e),...n,children:[(0,I.jsx)(`span`,{"data-slot":`select-item-indicator`,className:`absolute right-2 flex size-3.5 items-center justify-center`,children:(0,I.jsx)(Ne,{children:(0,I.jsx)(O,{className:`size-4`})})}),(0,I.jsx)(je,{children:t})]})}function Xe({className:e,...t}){return(0,I.jsx)(Fe,{"data-slot":`select-scroll-up-button`,className:i(`flex cursor-default items-center justify-center py-1`,e),...t,children:(0,I.jsx)(T,{className:`size-4`})})}function Ze({className:e,...t}){return(0,I.jsx)(Le,{"data-slot":`select-scroll-down-button`,className:i(`flex cursor-default items-center justify-center py-1`,e),...t,children:(0,I.jsx)(E,{className:`size-4`})})}export{Ke as a,qe as i,Je as n,Ye as r,Ge as t};
@@ -1 +0,0 @@
1
- import{a as e,n as t}from"./B1pia_Rg.js";import{l as n,m as r,t as i}from"./pjlgs2cl.js";import{r as a,t as o}from"./D0jMUNSI.js";import{a as s,i as c,n as l,r as u,t as d}from"./CiFkP-9S.js";import{n as f}from"./D6kbK-ng.js";import{a as p,i as m,n as h,o as g,r as _,t as v}from"./BgkATqP8.js";import{t as y}from"./DkPnEF-y.js";var b=n();function x(){let n=t(e=>e.activeDialog),x=t(e=>e.closeDialog),S=f(),{t:C}=r();return(0,b.jsx)(v,{open:n===`general-settings`,onOpenChange:e=>{e||x()},children:(0,b.jsxs)(h,{className:`sm:max-w-[560px]`,children:[(0,b.jsxs)(p,{children:[(0,b.jsx)(g,{children:C(`settings.general.title`)}),(0,b.jsx)(_,{children:C(`settings.general.description`)})]}),(0,b.jsxs)(`div`,{className:`grid gap-2`,children:[(0,b.jsx)(y,{id:`s-history`,checked:S.persistQueryHistory,onChange:e=>S.setPersistQueryHistory(e),label:C(`settings.persistHistory`),hint:C(`settings.persistHistoryHint`)}),(0,b.jsxs)(`div`,{className:`grid grid-cols-[1fr_200px] items-center gap-3 rounded-md border p-3`,children:[(0,b.jsxs)(`div`,{className:`grid gap-0.5`,children:[(0,b.jsx)(`span`,{className:`text-sm font-medium`,children:C(`settings.language`)}),(0,b.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:C(`settings.languageHint`)})]}),(0,b.jsxs)(d,{value:S.locale,onValueChange:e=>S.setLocale(e),children:[(0,b.jsx)(c,{children:(0,b.jsx)(s,{})}),(0,b.jsxs)(l,{children:[(0,b.jsx)(u,{value:`auto`,children:C(`language.auto`,{name:C(`language.${a()}`)})}),o.map(e=>(0,b.jsx)(u,{value:e,children:C(`language.${e}`)},e))]})]})]}),(0,b.jsx)(y,{id:`s-analytics`,checked:S.analyticsEnabled,onChange:S.setAnalyticsEnabled,label:C(`settings.analytics`),hint:e()?C(`settings.analyticsHint`):C(`settings.analyticsUnavailableHint`)})]}),(0,b.jsx)(m,{children:(0,b.jsx)(i,{onClick:x,children:C(`settings.done`)})})]})})}export{x as GeneralSettingsDialog};
@@ -1 +0,0 @@
1
- import{r as e}from"./hePW80VL.js";import{h as t,n}from"./B1pia_Rg.js";import{l as r,m as i,t as a}from"./pjlgs2cl.js";import{F as o,L as s,N as c,P as l,c as u,jt as d,l as f,nt as p}from"./Bhquh17w.js";import{a as m,i as h,n as g,o as _,r as v,t as y}from"./BgkATqP8.js";import{t as b}from"./Bajzqc8D.js";var x=e(t(),1);function S(){let e=s(e=>e.status.state===`valid`);return!o()||e}var C=r(),w={offline:`sync.offline`,server:`sync.serverError`,unauthorized:`sync.serverError`,conflict:`sync.serverError`,"bad-passphrase":`sync.wrongPassphrase`,malformed:`sync.wrongPassphrase`,unsupported:`sync.serverError`};function T(){let e=n(e=>e.activeDialog),t=n(e=>e.closeDialog),{phase:r,user:o,busy:s,error:T,lastSyncedAt:E,vault:D,refresh:O,createVault:k,unlock:A,push:j,signOut:M,forgetVault:N,closeAccount:P,setError:F}=c(),{t:I}=i(),L=S(),[R,z]=(0,x.useState)(``),[B,V]=(0,x.useState)(``),[H,U]=(0,x.useState)(!1),[W,G]=(0,x.useState)(!1);(0,x.useEffect)(()=>{O()},[O]);let K=R.length>0&&R.length<10,q=B.length>0&&R!==B,J=R.length>=10&&R===B,Y=T?I(w[T]??`sync.serverError`):null,X=D?Object.keys(D.profiles).length:0,Z=()=>{z(``),V(``),F(null)};return(0,C.jsx)(y,{open:e===`sync`,onOpenChange:e=>{e||t()},children:(0,C.jsxs)(g,{className:`max-h-[85vh] overflow-y-auto sm:max-w-[560px]`,onOpenAutoFocus:e=>e.preventDefault(),children:[(0,C.jsxs)(m,{children:[(0,C.jsx)(_,{children:I(`sync.title`)}),(0,C.jsxs)(v,{children:[I(`sync.description`),o&&(0,C.jsx)(`span`,{className:`mt-1 block text-xs`,children:I(`sync.signedInAs`,{email:o.email??o.id})})]})]}),(0,C.jsxs)(`div`,{className:`grid gap-3 text-sm`,children:[(0,C.jsx)(`p`,{className:`rounded-md border bg-muted/40 p-3 text-xs text-muted-foreground`,children:I(`sync.stored`)}),r===`unavailable`&&(0,C.jsx)(`p`,{className:`rounded-md border border-amber-500/40 bg-amber-500/5 p-3 text-xs text-amber-600 dark:text-amber-400`,children:p()?I(`sync.unavailable`):I(`sync.notDeployed`)}),r===`signed-out`&&(0,C.jsxs)(a,{onClick:()=>{window.location.href=l(`github`,window.location.href)},children:[(0,C.jsx)(d,{className:`size-4`}),I(`sync.signIn`)]}),o&&!L&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:I(`sync.needsPro`)}),(0,C.jsx)(b,{highlight:`sync`})]}),L&&r===`no-vault`&&(0,C.jsxs)(`div`,{className:`grid gap-2`,children:[(0,C.jsx)(`p`,{className:`text-sm font-medium`,children:I(`sync.createTitle`)}),(0,C.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:I(`sync.createHint`)}),(0,C.jsx)(u,{htmlFor:`sync-pass`,children:I(`sync.passphrase`)}),(0,C.jsx)(f,{id:`sync-pass`,type:`password`,autoComplete:`new-password`,value:R,onChange:e=>{z(e.target.value),F(null)}}),(0,C.jsx)(u,{htmlFor:`sync-confirm`,children:I(`sync.confirm`)}),(0,C.jsx)(f,{id:`sync-confirm`,type:`password`,autoComplete:`new-password`,value:B,onChange:e=>{V(e.target.value),F(null)}}),K&&(0,C.jsx)(`p`,{className:`text-xs text-destructive`,children:I(`sync.tooShort`,{count:10})}),q&&(0,C.jsx)(`p`,{className:`text-xs text-destructive`,children:I(`sync.mismatch`)}),(0,C.jsx)(a,{disabled:!J||s,onClick:()=>{k(R).then(Z)},children:I(`sync.enable`)})]}),L&&r===`locked`&&(0,C.jsxs)(`div`,{className:`grid gap-2`,children:[(0,C.jsx)(`p`,{className:`text-sm font-medium`,children:I(`sync.unlockTitle`)}),(0,C.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:I(`sync.unlockHint`)}),(0,C.jsx)(u,{htmlFor:`sync-unlock`,children:I(`sync.passphrase`)}),(0,C.jsx)(f,{id:`sync-unlock`,type:`password`,autoComplete:`current-password`,value:R,onChange:e=>{z(e.target.value),F(null)}}),(0,C.jsx)(a,{disabled:!R||s,onClick:()=>{A(R).then(Z)},children:I(`sync.unlock`)})]}),L&&r===`ready`&&(0,C.jsxs)(`div`,{className:`grid gap-2`,children:[(0,C.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[E?I(`sync.lastSynced`,{when:new Date(E).toLocaleString()}):I(`sync.neverSynced`),` · `,I(`sync.profiles`,{count:X})]}),(0,C.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,C.jsx)(a,{variant:`secondary`,disabled:s,onClick:()=>{U(!1),j()},children:I(`sync.syncNow`)}),(0,C.jsx)(a,{variant:`ghost`,disabled:s,onClick:()=>{c.getState().lock(),Z()},children:I(`sync.changePassphrase`)})]}),H?(0,C.jsxs)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/5 p-3`,children:[(0,C.jsx)(`p`,{className:`mb-2 text-xs`,children:I(`sync.deleteVaultConfirm`)}),(0,C.jsxs)(`div`,{className:`flex gap-2`,children:[(0,C.jsx)(a,{variant:`destructive`,disabled:s,onClick:()=>{N().then(()=>U(!1))},children:I(`sync.deleteVault`)}),(0,C.jsx)(a,{variant:`ghost`,onClick:()=>U(!1),children:I(`settings.done`)})]})]}):(0,C.jsx)(a,{variant:`ghost`,className:`justify-start px-0 text-destructive`,onClick:()=>U(!0),children:I(`sync.deleteVault`)})]}),o&&(W?(0,C.jsxs)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/5 p-3`,children:[(0,C.jsx)(`p`,{className:`mb-2 text-xs`,children:I(`sync.deleteAccountConfirm`)}),(0,C.jsxs)(`div`,{className:`flex gap-2`,children:[(0,C.jsx)(a,{variant:`destructive`,disabled:s,onClick:()=>{P().then(()=>G(!1))},children:I(`sync.deleteAccount`)}),(0,C.jsx)(a,{variant:`ghost`,onClick:()=>G(!1),children:I(`settings.done`)})]})]}):(0,C.jsx)(`button`,{type:`button`,onClick:()=>G(!0),className:`w-fit rounded-sm text-xs text-muted-foreground underline underline-offset-2 hover:text-destructive focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring`,children:I(`sync.deleteAccount`)})),s&&(0,C.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:I(`sync.working`)}),Y&&(0,C.jsx)(`p`,{className:`text-xs text-destructive`,children:Y})]}),(0,C.jsxs)(h,{children:[o&&(0,C.jsx)(a,{variant:`ghost`,disabled:s,onClick:()=>{M().then(Z)},children:I(`sync.signOut`)}),(0,C.jsx)(a,{onClick:t,children:I(`settings.done`)})]})]})})}export{T as SyncDialog};
@@ -1 +0,0 @@
1
- import{r as e}from"./hePW80VL.js";import{h as t,n}from"./B1pia_Rg.js";import{i as r,l as i,m as a,t as o}from"./pjlgs2cl.js";import{t as s}from"./CZoj-eMm.js";import{t as c}from"./BCmzDvBt.js";import{n as l}from"./BO_H_8D-.js";import{n as u,o as d,s as f,t as p}from"./DAFA-E1-.js";import{Lt as m,c as h,it as g,l as _}from"./Bhquh17w.js";var v=e(t(),1),y=i();function b(){let{t:e}=a(),{activeDialog:t,closeDialog:i}=n(),[b,x]=(0,v.useState)(``),[S,C]=(0,v.useState)(``),[w,T]=(0,v.useState)(!1),[E,D]=(0,v.useState)(!1),[O,k]=(0,v.useState)(!1),[A,j]=(0,v.useState)(0),M=c(e=>e.activeConnectionId)??``,N=l(e=>M?e.activeTabId[M]:void 0)??``;if(t!==`find-replace`)return null;let P={query:b,caseSensitive:w,regex:E,wholeWord:O},F=M!==``&&N!==``&&b!==``;function I(){i()}function L(){j(F?u(M,N,P,`next`):0)}function R(){j(F?u(M,N,P,`prev`):0)}function z(){F&&j(f(M,N,P,S))}function B(){F&&(d(M,N,P,S),j(p(M,N,P)))}return(0,y.jsxs)(`div`,{className:`fixed top-12 right-4 z-50 bg-background border rounded-md shadow-lg p-3 w-[400px] space-y-2`,children:[(0,y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,y.jsx)(_,{placeholder:e(`command.findReplace.findPlaceholder`),value:b,onChange:e=>x(e.target.value),onKeyDown:e=>{g(e)||(e.key===`Enter`&&(e.shiftKey?R():L()),e.key===`Escape`&&I())},className:`flex-1 h-7 text-sm`,autoFocus:!0}),(0,y.jsx)(`span`,{className:`text-xs text-muted-foreground whitespace-nowrap min-w-[60px] text-center`,children:A>0?e(`command.findReplace.found`,{count:A}):e(`command.findReplace.noResults`)}),(0,y.jsx)(o,{variant:`ghost`,size:`sm`,className:`h-7 w-7 p-0`,onClick:R,title:e(`command.findReplace.previous`),children:(0,y.jsx)(s,{className:`h-4 w-4`})}),(0,y.jsx)(o,{variant:`ghost`,size:`sm`,className:`h-7 w-7 p-0`,onClick:L,title:e(`command.findReplace.next`),children:(0,y.jsx)(m,{className:`h-4 w-4`})}),(0,y.jsx)(o,{variant:`ghost`,size:`sm`,className:`h-7 w-7 p-0`,onClick:I,title:e(`command.findReplace.close`),children:(0,y.jsx)(r,{className:`h-4 w-4`})})]}),(0,y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,y.jsx)(_,{placeholder:e(`command.findReplace.replacePlaceholder`),value:S,onChange:e=>C(e.target.value),onKeyDown:e=>{e.key===`Escape`&&I()},className:`flex-1 h-7 text-sm`}),(0,y.jsx)(o,{variant:`outline`,size:`sm`,className:`h-7 text-xs`,onClick:z,children:e(`command.findReplace.replace`)}),(0,y.jsx)(o,{variant:`outline`,size:`sm`,className:`h-7 text-xs`,onClick:B,children:e(`command.findReplace.all`)})]}),(0,y.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,y.jsxs)(h,{className:`flex items-center gap-1.5 text-xs font-normal cursor-pointer`,children:[(0,y.jsx)(`input`,{type:`checkbox`,checked:w,onChange:e=>T(e.target.checked),className:`rounded border-input`}),e(`command.findReplace.caseSensitive`)]}),(0,y.jsxs)(h,{className:`flex items-center gap-1.5 text-xs font-normal cursor-pointer`,children:[(0,y.jsx)(`input`,{type:`checkbox`,checked:E,onChange:e=>D(e.target.checked),className:`rounded border-input`}),e(`command.findReplace.regex`)]}),(0,y.jsxs)(h,{className:`flex items-center gap-1.5 text-xs font-normal cursor-pointer`,children:[(0,y.jsx)(`input`,{type:`checkbox`,checked:O,onChange:e=>k(e.target.checked),className:`rounded border-input`}),e(`command.findReplace.wholeWord`)]})]})]})}export{b as FindReplaceDialog};
@@ -1,2 +0,0 @@
1
- import{d as e,p as t}from"./B1pia_Rg.js";var n=e=>typeof e==`string`,r=()=>{let e,t,n=new Promise((n,r)=>{e=n,t=r});return n.resolve=e,n.reject=t,n},i=e=>e==null?``:String(e),a=(e,t,n)=>{e.forEach(e=>{t[e]&&(n[e]=t[e])})},o=/###/g,s=e=>e&&e.includes(`###`)?e.replace(o,`.`):e,c=e=>!e||n(e),l=(e,t,r)=>{let i=n(t)?t.split(`.`):t,a=0;for(;a<i.length-1;){if(c(e))return{};let t=s(i[a]);!e[t]&&r&&(e[t]=new r),e=Object.prototype.hasOwnProperty.call(e,t)?e[t]:{},++a}return c(e)?{}:{obj:e,k:s(i[a])}},u=(e,t,n)=>{let{obj:r,k:i}=l(e,t,Object);if(r!==void 0||t.length===1){r[i]=n;return}let a=t[t.length-1],o=t.slice(0,t.length-1),s=l(e,o,Object);for(;s.obj===void 0&&o.length;)a=`${o[o.length-1]}.${a}`,o=o.slice(0,o.length-1),s=l(e,o,Object),s?.obj&&s.obj[`${s.k}.${a}`]!==void 0&&(s.obj=void 0);s.obj[`${s.k}.${a}`]=n},d=(e,t,n,r)=>{let{obj:i,k:a}=l(e,t,Object);i[a]=i[a]||[],i[a].push(n)},f=(e,t)=>{let{obj:n,k:r}=l(e,t);if(n&&Object.prototype.hasOwnProperty.call(n,r))return n[r]},p=(e,t,n)=>{let r=f(e,n);return r===void 0?f(t,n):r},m=(e,t,r)=>{for(let i in t)i!==`__proto__`&&i!==`constructor`&&(Object.prototype.hasOwnProperty.call(e,i)?n(e[i])||e[i]instanceof String||n(t[i])||t[i]instanceof String?r&&(e[i]=t[i]):m(e[i],t[i],r):e[i]=t[i]);return e},h=e=>e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,`\\$&`),g={"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`,"/":`&#x2F;`},_=e=>n(e)?e.replace(/[&<>"'\/]/g,e=>g[e]):e,v=class{constructor(e){this.capacity=e,this.regExpMap=new Map,this.regExpQueue=[]}getRegExp(e){let t=this.regExpMap.get(e);if(t!==void 0)return t;let n=new RegExp(e);return this.regExpQueue.length===this.capacity&&this.regExpMap.delete(this.regExpQueue.shift()),this.regExpMap.set(e,n),this.regExpQueue.push(e),n}},y=[` `,`,`,`?`,`!`,`;`],b=new v(20),x=(e,t,n)=>{t||=``,n||=``;let r=y.filter(e=>!t.includes(e)&&!n.includes(e));if(r.length===0)return!0;let i=b.getRegExp(`(${r.map(e=>e===`?`?`\\?`:e).join(`|`)})`),a=!i.test(e);if(!a){let t=e.indexOf(n);t>0&&!i.test(e.substring(0,t))&&(a=!0)}return a},S=(e,t,n=`.`)=>{if(!e)return;if(e[t])return Object.prototype.hasOwnProperty.call(e,t)?e[t]:void 0;let r=t.split(n),i=e;for(let e=0;e<r.length;){if(!i||typeof i!=`object`)return;let t,a=``;for(let o=e;o<r.length;++o)if(o!==e&&(a+=n),a+=r[o],t=i[a],t!==void 0){if([`string`,`number`,`boolean`].includes(typeof t)&&o<r.length-1)continue;e+=o-e+1;break}i=t}return i},C=e=>e?.replace(/_/g,`-`),w={type:`logger`,log(e){this.output(`log`,e)},warn(e){this.output(`warn`,e)},error(e){this.output(`error`,e)},output(e,t){console?.[e]?.apply?.(console,t)}},T=new class e{constructor(e,t={}){this.init(e,t)}init(e,t={}){this.prefix=t.prefix||`i18next:`,this.logger=e||w,this.options=t,this.debug=t.debug}log(...e){return this.forward(e,`log`,``,!0)}warn(...e){return this.forward(e,`warn`,``,!0)}error(...e){return this.forward(e,`error`,``)}deprecate(...e){return this.forward(e,`warn`,`WARNING DEPRECATED: `,!0)}forward(e,t,r,i){return i&&!this.debug?null:(e=e.map(e=>n(e)?e.replace(/[\r\n\x00-\x1F\x7F]/g,` `):e),n(e[0])&&(e[0]=`${r}${this.prefix} ${e[0]}`),this.logger[t](e))}create(t){return new e(this.logger,{prefix:`${this.prefix}:${t}:`,...this.options})}clone(t){return t||=this.options,t.prefix=t.prefix||this.prefix,new e(this.logger,t)}},E=class{constructor(){this.observers={}}on(e,t){return e.split(` `).forEach(e=>{this.observers[e]||(this.observers[e]=new Map);let n=this.observers[e].get(t)||0;this.observers[e].set(t,n+1)}),this}off(e,t){if(this.observers[e]){if(!t){delete this.observers[e];return}this.observers[e].delete(t)}}once(e,t){let n=(...r)=>{t(...r),this.off(e,n)};return this.on(e,n),this}emit(e,...t){this.observers[e]&&Array.from(this.observers[e].entries()).forEach(([e,n])=>{for(let r=0;r<n;r++)e(...t)}),this.observers[`*`]&&Array.from(this.observers[`*`].entries()).forEach(([n,r])=>{for(let i=0;i<r;i++)n(e,...t)})}},D=class extends E{constructor(e,t={ns:[`translation`],defaultNS:`translation`}){super(),this.data=e||{},this.options=t,this.options.keySeparator===void 0&&(this.options.keySeparator=`.`),this.options.ignoreJSONStructure===void 0&&(this.options.ignoreJSONStructure=!0)}addNamespaces(e){this.options.ns.includes(e)||this.options.ns.push(e)}removeNamespaces(e){let t=this.options.ns.indexOf(e);t>-1&&this.options.ns.splice(t,1)}getResource(e,t,r,i={}){let a=i.keySeparator===void 0?this.options.keySeparator:i.keySeparator,o=i.ignoreJSONStructure===void 0?this.options.ignoreJSONStructure:i.ignoreJSONStructure,s;e.includes(`.`)?s=e.split(`.`):(s=[e,t],r&&(Array.isArray(r)?s.push(...r):n(r)&&a?s.push(...r.split(a)):s.push(r)));let c=f(this.data,s);return!c&&!t&&!r&&e.includes(`.`)&&(e=s[0],t=s[1],r=s.slice(2).join(`.`)),c||!o||!n(r)?c:S(this.data?.[e]?.[t],r,a)}addResource(e,t,n,r,i={silent:!1}){let a=i.keySeparator===void 0?this.options.keySeparator:i.keySeparator,o=[e,t];n&&(o=o.concat(a?n.split(a):n)),e.includes(`.`)&&(o=e.split(`.`),r=t,t=o[1]),this.addNamespaces(t),u(this.data,o,r),i.silent||this.emit(`added`,e,t,n,r)}addResources(e,t,r,i={silent:!1}){for(let i in r)(n(r[i])||Array.isArray(r[i]))&&this.addResource(e,t,i,r[i],{silent:!0});i.silent||this.emit(`added`,e,t,r)}addResourceBundle(e,t,n,r,i,a={silent:!1,skipCopy:!1}){let o=[e,t];e.includes(`.`)&&(o=e.split(`.`),r=n,n=t,t=o[1]),this.addNamespaces(t);let s=f(this.data,o)||{};a.skipCopy||(n=JSON.parse(JSON.stringify(n))),r?m(s,n,i):s={...s,...n},u(this.data,o,s),a.silent||this.emit(`added`,e,t,n)}removeResourceBundle(e,t){this.hasResourceBundle(e,t)&&delete this.data[e][t],this.removeNamespaces(t),this.emit(`removed`,e,t)}hasResourceBundle(e,t){return this.getResource(e,t)!==void 0}getResourceBundle(e,t){return t||=this.options.defaultNS,this.getResource(e,t)}getDataByLanguage(e){return this.data[e]}hasLanguageSomeTranslations(e){let t=this.getDataByLanguage(e);return!!(t&&Object.keys(t)||[]).find(e=>t[e]&&Object.keys(t[e]).length>0)}toJSON(){return this.data}},O={processors:{},addPostProcessor(e){this.processors[e.name]=e},handle(e,t,n,r,i){return e.forEach(e=>{t=this.processors[e]?.process(t,n,r,i)??t}),t}},k=Symbol(`i18next/PATH_KEY`);function A(){let e=[],t=Object.create(null),n;return t.get=(r,i)=>(n?.revoke?.(),i===k?e:(e.push(i),n=Proxy.revocable(r,t),n.proxy)),Proxy.revocable(Object.create(null),t).proxy}function j(e,t){let{[k]:n}=e(A()),r=t?.keySeparator??`.`,i=t?.nsSeparator??`:`,a=t?.enableSelector===`strict`;if(n.length>1&&i){let e=t?.ns,o=a?Array.isArray(e)?e:e?[e]:null:Array.isArray(e)?e:null;if(o&&(a?o:o.length>1?o.slice(1):[]).includes(n[0]))return`${n[0]}${i}${n.slice(1).join(r)}`}return n.join(r)}var M=e=>!n(e)&&typeof e!=`boolean`&&typeof e!=`number`,N=class e extends E{constructor(e,t={}){super(),a([`resourceStore`,`languageUtils`,`pluralResolver`,`interpolator`,`backendConnector`,`i18nFormat`,`utils`],e,this),this.options=t,this.options.keySeparator===void 0&&(this.options.keySeparator=`.`),this.logger=T.create(`translator`),this.checkedLoadedFor={}}changeLanguage(e){e&&(this.language=e)}exists(e,t={interpolation:{}}){let n={...t};if(e==null)return!1;let r=this.resolve(e,n);if(r?.res===void 0)return!1;let i=M(r.res);return!(n.returnObjects===!1&&i)}extractFromKey(e,t){let r=t.nsSeparator===void 0?this.options.nsSeparator:t.nsSeparator;r===void 0&&(r=`:`);let i=t.keySeparator===void 0?this.options.keySeparator:t.keySeparator,a=t.ns||this.options.defaultNS||[],o=r&&e.includes(r),s=!this.options.userDefinedKeySeparator&&!t.keySeparator&&!this.options.userDefinedNsSeparator&&!t.nsSeparator&&!x(e,r,i);if(o&&!s){let t=e.match(this.interpolator.nestingRegexp);if(t&&t.length>0)return{key:e,namespaces:n(a)?[a]:a};let o=e.split(r);(r!==i||r===i&&this.options.ns.includes(o[0]))&&(a=o.shift()),e=o.join(i)}return{key:e,namespaces:n(a)?[a]:a}}translate(t,r,i){let a=typeof r==`object`?{...r}:r;if(typeof a!=`object`&&this.options.overloadTranslationOptionHandler&&(a=this.options.overloadTranslationOptionHandler(arguments)),typeof a==`object`&&(a={...a}),a||={},t==null)return``;typeof t==`function`&&(t=j(t,{...this.options,...a})),Array.isArray(t)||(t=[String(t)]),t=t.map(e=>typeof e==`function`?j(e,{...this.options,...a}):String(e));let o=a.returnDetails===void 0?this.options.returnDetails:a.returnDetails,s=a.keySeparator===void 0?this.options.keySeparator:a.keySeparator,{key:c,namespaces:l}=this.extractFromKey(t[t.length-1],a),u=l[l.length-1],d=a.nsSeparator===void 0?this.options.nsSeparator:a.nsSeparator;d===void 0&&(d=`:`);let f=a.lng||this.language,p=a.appendNamespaceToCIMode||this.options.appendNamespaceToCIMode;if(f?.toLowerCase()===`cimode`)return p?o?{res:`${u}${d}${c}`,usedKey:c,exactUsedKey:c,usedLng:f,usedNS:u,usedParams:this.getUsedParamsDetails(a)}:`${u}${d}${c}`:o?{res:c,usedKey:c,exactUsedKey:c,usedLng:f,usedNS:u,usedParams:this.getUsedParamsDetails(a)}:c;let m=this.resolve(t,a),h=m?.res,g=m?.usedKey||c,_=m?.exactUsedKey||c,v=[`[object Number]`,`[object Function]`,`[object RegExp]`],y=a.joinArrays===void 0?this.options.joinArrays:a.joinArrays,b=!this.i18nFormat||this.i18nFormat.handleAsObject,x=a.count!==void 0&&!n(a.count),S=e.hasDefaultValue(a),C=x?this.pluralResolver.getSuffix(f,a.count,a):``,w=a.ordinal&&x?this.pluralResolver.getSuffix(f,a.count,{ordinal:!1}):``,T=x&&!a.ordinal&&a.count===0,E=T&&a[`defaultValue${this.options.pluralSeparator}zero`]||a[`defaultValue${C}`]||a[`defaultValue${w}`]||a.defaultValue,D=h;b&&!h&&S&&(D=E);let O=M(D),k=Object.prototype.toString.apply(D);if(b&&D&&O&&!v.includes(k)&&!(n(y)&&Array.isArray(D))){if(!a.returnObjects&&!this.options.returnObjects){this.options.returnedObjectHandler||this.logger.warn(`accessing an object - but returnObjects options is not enabled!`);let e=this.options.returnedObjectHandler?this.options.returnedObjectHandler(g,D,{...a,ns:l}):`key '${c} (${this.language})' returned an object instead of string.`;return o?(m.res=e,m.usedParams=this.getUsedParamsDetails(a),m):e}if(s){let e=Array.isArray(D),t=e?[]:{},n=e?_:g;for(let e in D)if(Object.prototype.hasOwnProperty.call(D,e)){let r=`${n}${s}${e}`;t[e]=S&&!h?this.translate(r,{...a,defaultValue:M(E)?E[e]:void 0,joinArrays:!1,ns:l}):this.translate(r,{...a,joinArrays:!1,ns:l}),t[e]===r&&(t[e]=D[e])}h=t}}else if(b&&n(y)&&Array.isArray(h))h=h.join(y),h&&=this.extendTranslation(h,t,a,i);else{let e=!1,n=!1;!this.isValidLookup(h)&&S&&(e=!0,h=E),this.isValidLookup(h)||(n=!0,h=c);let r=(a.missingKeyNoValueFallbackToKey||this.options.missingKeyNoValueFallbackToKey)&&n?void 0:h,o=S&&E!==h&&this.options.updateMissing;if(n||e||o){if(this.logger.log(o?`updateKey`:`missingKey`,f,u,x&&!o?`${c}${this.pluralResolver.getSuffix(f,a.count,a)}`:c,o?E:h),s){let e=this.resolve(c,{...a,keySeparator:!1});e&&e.res&&this.logger.warn(`Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.`)}let e=[],t=this.languageUtils.getFallbackCodes(this.options.fallbackLng,a.lng||this.language);if(this.options.saveMissingTo===`fallback`&&t&&t[0])for(let n=0;n<t.length;n++)e.push(t[n]);else this.options.saveMissingTo===`all`?e=this.languageUtils.toResolveHierarchy(a.lng||this.language):e.push(a.lng||this.language);let n=(e,t,n)=>{let i=S&&n!==h?n:r;this.options.missingKeyHandler?this.options.missingKeyHandler(e,u,t,i,o,a):this.backendConnector?.saveMissing&&this.backendConnector.saveMissing(e,u,t,i,o,a),this.emit(`missingKey`,e,u,t,h)};this.options.saveMissing&&(this.options.saveMissingPlurals&&x?e.forEach(e=>{let t=this.pluralResolver.getSuffixes(e,a);T&&a[`defaultValue${this.options.pluralSeparator}zero`]&&!t.includes(`${this.options.pluralSeparator}zero`)&&t.push(`${this.options.pluralSeparator}zero`),t.forEach(t=>{n([e],c+t,a[`defaultValue${t}`]||E)})}):n(e,c,E))}h=this.extendTranslation(h,t,a,m,i),n&&h===c&&this.options.appendNamespaceToMissingKey&&(h=`${u}${d}${c}`),(n||e)&&this.options.parseMissingKeyHandler&&(h=this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey?`${u}${d}${c}`:c,e?h:void 0,a))}return o?(m.res=h,m.usedParams=this.getUsedParamsDetails(a),m):h}extendTranslation(e,t,r,i,a){if(this.i18nFormat?.parse)e=this.i18nFormat.parse(e,{...this.options.interpolation.defaultVariables,...r},r.lng||this.language||i.usedLng,i.usedNS,i.usedKey,{resolved:i});else if(!r.skipInterpolation){r.interpolation&&this.interpolator.init({...r,interpolation:{...this.options.interpolation,...r.interpolation}});let o=n(e)&&(r?.interpolation?.skipOnVariables===void 0?this.options.interpolation.skipOnVariables:r.interpolation.skipOnVariables),s;if(o){let t=e.match(this.interpolator.nestingRegexp);s=t&&t.length}let c=r.replace&&!n(r.replace)?r.replace:r;if(this.options.interpolation.defaultVariables&&(c={...this.options.interpolation.defaultVariables,...c}),e=this.interpolator.interpolate(e,c,r.lng||this.language||i.usedLng,r),o){let t=e.match(this.interpolator.nestingRegexp),n=t&&t.length;s<n&&(r.nest=!1)}!r.lng&&i&&i.res&&(r.lng=this.language||i.usedLng),r.nest!==!1&&(e=this.interpolator.nest(e,(...e)=>a?.[0]===e[0]&&!r.context?(this.logger.warn(`It seems you are nesting recursively key: ${e[0]} in key: ${t[0]}`),null):this.translate(...e,t),r)),r.interpolation&&this.interpolator.reset()}let o=r.postProcess||this.options.postProcess,s=n(o)?[o]:o;return e!=null&&s?.length&&r.applyPostProcessor!==!1&&(e=O.handle(s,e,t,this.options&&this.options.postProcessPassResolved?{i18nResolved:{...i,usedParams:this.getUsedParamsDetails(r)},...r}:r,this)),e}resolve(e,t={}){let r,i,a,o,s;return n(e)&&(e=[e]),Array.isArray(e)&&(e=e.map(e=>typeof e==`function`?j(e,{...this.options,...t}):e)),e.forEach(e=>{if(this.isValidLookup(r))return;let c=this.extractFromKey(e,t),l=c.key;i=l;let u=c.namespaces;this.options.fallbackNS&&(u=u.concat(this.options.fallbackNS));let d=t.count!==void 0&&!n(t.count),f=d&&!t.ordinal&&t.count===0,p=t.context!==void 0&&(n(t.context)||typeof t.context==`number`)&&t.context!==``,m=t.lngs?t.lngs:this.languageUtils.toResolveHierarchy(t.lng||this.language,t.fallbackLng);u.forEach(e=>{this.isValidLookup(r)||(s=e,!this.checkedLoadedFor[`${m[0]}-${e}`]&&this.utils?.hasLoadedNamespace&&!this.utils?.hasLoadedNamespace(s)&&(this.checkedLoadedFor[`${m[0]}-${e}`]=!0,this.logger.warn(`key "${i}" for languages "${m.join(`, `)}" won't get resolved as namespace "${s}" was not yet loaded`,`This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!`)),m.forEach(n=>{if(this.isValidLookup(r))return;o=n;let i=[l];if(this.i18nFormat?.addLookupKeys)this.i18nFormat.addLookupKeys(i,l,n,e,t);else{let e;d&&(e=this.pluralResolver.getSuffix(n,t.count,t));let r=`${this.options.pluralSeparator}zero`,a=`${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;if(d&&(t.ordinal&&e.startsWith(a)&&i.push(l+e.replace(a,this.options.pluralSeparator)),i.push(l+e),f&&i.push(l+r)),p){let n=`${l}${this.options.contextSeparator||`_`}${t.context}`;i.push(n),d&&(t.ordinal&&e.startsWith(a)&&i.push(n+e.replace(a,this.options.pluralSeparator)),i.push(n+e),f&&i.push(n+r))}}let s;for(;s=i.pop();)this.isValidLookup(r)||(a=s,r=this.getResource(n,e,s,t))}))})}),{res:r,usedKey:i,exactUsedKey:a,usedLng:o,usedNS:s}}isValidLookup(e){return e!==void 0&&!(!this.options.returnNull&&e===null)&&!(!this.options.returnEmptyString&&e===``)}getResource(e,t,n,r={}){return this.i18nFormat?.getResource?this.i18nFormat.getResource(e,t,n,r):this.resourceStore.getResource(e,t,n,r)}getUsedParamsDetails(e={}){let t=[`defaultValue`,`ordinal`,`context`,`replace`,`lng`,`lngs`,`fallbackLng`,`ns`,`keySeparator`,`nsSeparator`,`returnObjects`,`returnDetails`,`joinArrays`,`postProcess`,`interpolation`],r=e.replace&&!n(e.replace),i=r?e.replace:e;if(r&&e.count!==void 0&&(i={...i,count:e.count}),this.options.interpolation.defaultVariables&&(i={...this.options.interpolation.defaultVariables,...i}),!r){i={...i};for(let e of t)delete i[e]}return i}static hasDefaultValue(e){for(let t in e)if(Object.prototype.hasOwnProperty.call(e,t)&&t.startsWith(`defaultValue`)&&e[t]!==void 0)return!0;return!1}},P=class{constructor(e){this.options=e,this.supportedLngs=this.options.supportedLngs||!1,this.logger=T.create(`languageUtils`),this.resolveHierarchyCache={}}clearCache(){this.resolveHierarchyCache={}}getScriptPartFromCode(e){if(e=C(e),!e||!e.includes(`-`))return null;let t=e.split(`-`);return t.length===2||(t.pop(),t[t.length-1].toLowerCase()===`x`)?null:this.formatLanguageCode(t.join(`-`))}getLanguagePartFromCode(e){if(e=C(e),!e||!e.includes(`-`))return e;let t=e.split(`-`);return this.formatLanguageCode(t[0])}formatLanguageCode(e){if(n(e)&&e.includes(`-`)){let t;try{t=Intl.getCanonicalLocales(e)[0]}catch{}return t&&this.options.lowerCaseLng&&(t=t.toLowerCase()),t||(this.options.lowerCaseLng?e.toLowerCase():e)}return this.options.cleanCode||this.options.lowerCaseLng?e.toLowerCase():e}isSupportedCode(e){return(this.options.load===`languageOnly`||this.options.nonExplicitSupportedLngs)&&(e=this.getLanguagePartFromCode(e)),!this.supportedLngs||!this.supportedLngs.length||this.supportedLngs.includes(e)}getBestMatchFromCodes(e){if(!e)return null;let t;return e.forEach(e=>{if(t)return;let n=this.formatLanguageCode(e);(!this.options.supportedLngs||this.isSupportedCode(n))&&(t=n)}),!t&&this.options.supportedLngs&&e.forEach(e=>{if(t)return;let n=this.getScriptPartFromCode(e);if(this.isSupportedCode(n))return t=n;let r=this.getLanguagePartFromCode(e);if(this.isSupportedCode(r))return t=r;t=this.options.supportedLngs.find(e=>e===r?!0:!e.includes(`-`)&&!r.includes(`-`)?!1:!!(e.includes(`-`)&&!r.includes(`-`)&&e.slice(0,e.indexOf(`-`))===r||e.startsWith(r)&&r.length>1))}),t||=this.getFallbackCodes(this.options.fallbackLng)[0],t}getFallbackCodes(e,t){if(!e)return[];if(typeof e==`function`&&(e=e(t)),n(e)&&(e=[e]),Array.isArray(e))return e;if(!t)return e.default||[];let r=e[t];return r||=e[this.getScriptPartFromCode(t)],r||=e[this.formatLanguageCode(t)],r||=e[this.getLanguagePartFromCode(t)],r||=e.default,r||[]}toResolveHierarchy(e,t){let r=this.options.fallbackLng,i=Array.isArray(r)?r.join(`|`):r;i!==this._cachedFallbackLng&&(this.resolveHierarchyCache={},this._cachedFallbackLng=i);let a=t===void 0||t===!1||n(t),o=t===void 0&&typeof this.options.fallbackLng==`function`,s=n(e)&&a&&!o,c=null;if(s){let n;n=t===void 0?`undefined`:t===!1?`boolean:false`:`string:${t}`,c=`${e.length}:${e}|${n}`}if(c!==null){let e=this.resolveHierarchyCache[c];if(e!==void 0)return e.slice()}let l=this.getFallbackCodes((t===!1?[]:t)||this.options.fallbackLng||[],e),u=[],d=e=>{e&&(this.isSupportedCode(e)?u.push(e):this.logger.warn(`rejecting language code not found in supportedLngs: ${e}`))};return n(e)&&(e.includes(`-`)||e.includes(`_`))?(this.options.load!==`languageOnly`&&d(this.formatLanguageCode(e)),this.options.load!==`languageOnly`&&this.options.load!==`currentOnly`&&d(this.getScriptPartFromCode(e)),this.options.load!==`currentOnly`&&d(this.getLanguagePartFromCode(e))):n(e)&&d(this.formatLanguageCode(e)),l.forEach(e=>{u.includes(e)||d(this.formatLanguageCode(e))}),c===null?u:(this.resolveHierarchyCache[c]=u,u.slice())}},F={zero:0,one:1,two:2,few:3,many:4,other:5},I={select:e=>e===1?`one`:`other`,resolvedOptions:()=>({pluralCategories:[`one`,`other`]})},L=class{constructor(e,t={}){this.languageUtils=e,this.options=t,this.logger=T.create(`pluralResolver`),this.pluralRulesCache={}}clearCache(){this.pluralRulesCache={}}getRule(e,t={}){let n=C(e===`dev`?`en`:e),r=t.ordinal?`ordinal`:`cardinal`,i=JSON.stringify({cleanedCode:n,type:r});if(i in this.pluralRulesCache)return this.pluralRulesCache[i];let a;try{a=new Intl.PluralRules(n,{type:r})}catch{if(typeof Intl>`u`)return this.logger.error(`No Intl support, please use an Intl polyfill!`),I;if(!e.match(/-|_/))return I;let n=this.languageUtils.getLanguagePartFromCode(e);a=this.getRule(n,t)}return this.pluralRulesCache[i]=a,a}needsPlural(e,t={}){let n=this.getRule(e,t);return n||=this.getRule(`dev`,t),n?.resolvedOptions().pluralCategories.length>1}getPluralFormsOfKey(e,t,n={}){return this.getSuffixes(e,n).map(e=>`${t}${e}`)}getSuffixes(e,t={}){let n=this.getRule(e,t);return n||=this.getRule(`dev`,t),n?n.resolvedOptions().pluralCategories.sort((e,t)=>F[e]-F[t]).map(e=>`${this.options.prepend}${t.ordinal?`ordinal${this.options.prepend}`:``}${e}`):[]}getSuffix(e,t,n={}){let r=this.getRule(e,n);return r?`${this.options.prepend}${n.ordinal?`ordinal${this.options.prepend}`:``}${r.select(t)}`:(this.logger.warn(`no plural rule found for: ${e}`),this.getSuffix(`dev`,t,n))}},R=(e,t,r,i=`.`,a=!0)=>{let o=p(e,t,r);return!o&&a&&n(r)&&(o=S(e,r,i),o===void 0&&(o=S(t,r,i))),o},ee=e=>e.replace(/\$/g,`$$$$`),z=class{constructor(e={}){this.logger=T.create(`interpolator`),this.options=e,this.format=e?.interpolation?.format||(e=>e),this.init(e)}init(e={}){e.interpolation||={escapeValue:!0};let{escape:t,escapeValue:n,useRawValueToEscape:r,prefix:i,prefixEscaped:a,suffix:o,suffixEscaped:s,formatSeparator:c,unescapeSuffix:l,unescapePrefix:u,nestingPrefix:d,nestingPrefixEscaped:f,nestingSuffix:p,nestingSuffixEscaped:m,nestingOptionsSeparator:g,maxReplaces:v,alwaysFormat:y}=e.interpolation;this.escape=t===void 0?_:t,this.escapeValue=n===void 0||n,this.useRawValueToEscape=r!==void 0&&r,this.prefix=i?h(i):a||`{{`,this.suffix=o?h(o):s||`}}`,this.formatSeparator=c||`,`,this.unescapePrefix=l?``:u?h(u):`-`,this.unescapeSuffix=this.unescapePrefix?``:l?h(l):``,this.nestingPrefix=d?h(d):f||h(`$t(`),this.nestingSuffix=p?h(p):m||h(`)`),this.nestingOptionsSeparator=g||`,`,this.maxReplaces=v||1e3,this.alwaysFormat=y!==void 0&&y,this.resetRegExp()}reset(){this.options&&this.init(this.options)}resetRegExp(){let e=(e,t)=>e?.source===t?(e.lastIndex=0,e):new RegExp(t,`g`);this.regexp=e(this.regexp,`${this.prefix}(.+?)${this.suffix}`),this.regexpUnescape=e(this.regexpUnescape,`${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`),this.nestingRegexp=e(this.nestingRegexp,`${this.nestingPrefix}((?:[^()"']+|"[^"]*"|'[^']*'|\\((?:[^()]|"[^"]*"|'[^']*')*\\))*?)${this.nestingSuffix}`)}interpolate(e,t,r,a){let o,s,c,l=this.options&&this.options.interpolation&&this.options.interpolation.defaultVariables||{},u=e=>{if(!e.includes(this.formatSeparator)){let n=R(t,l,e,this.options.keySeparator,this.options.ignoreJSONStructure);return this.alwaysFormat?this.format(n,void 0,r,{...a,...t,interpolationkey:e}):n}let n=e.split(this.formatSeparator),i=n.shift().trim(),o=n.join(this.formatSeparator).trim();return this.format(R(t,l,i,this.options.keySeparator,this.options.ignoreJSONStructure),o,r,{...a,...t,interpolationkey:i})};this.resetRegExp(),!this.escapeValue&&typeof e==`string`&&/\$t\([^)]*\{[^}]*\{\{/.test(e)&&this.logger.warn(`nesting options string contains interpolated variables with escapeValue: false — if any of those values are attacker-controlled they can inject additional nesting options (e.g. redirect lng/ns). Sanitise untrusted input before passing it to t(), or keep escapeValue: true.`);let d=a?.missingInterpolationHandler||this.options.missingInterpolationHandler,f=a?.interpolation?.skipOnVariables===void 0?this.options.interpolation.skipOnVariables:a.interpolation.skipOnVariables;return[{regex:this.regexpUnescape,safeValue:e=>e},{regex:this.regexp,safeValue:e=>this.escapeValue?this.escape(e):e}].forEach(t=>{for(c=0;o=t.regex.exec(e);){let r=o[1].trim();if(s=u(r),s===void 0){if(typeof d==`function`){let t=d(e,o,a);s=n(t)?t:``}else if(a&&Object.prototype.hasOwnProperty.call(a,r))s=``;else if(f){s=o[0];continue}else this.logger.warn(`missed to pass in variable ${r} for interpolating ${e}`),s=``}else!n(s)&&!this.useRawValueToEscape&&(s=i(s));let l=t.safeValue(s);if(e=e.replace(o[0],ee(l)),f?(t.regex.lastIndex+=l.length,t.regex.lastIndex-=o[0].length):t.regex.lastIndex=0,c++,c>=this.maxReplaces)break}}),e}nest(e,t,r={}){let a,o,s,c=(e,t)=>{let n=this.nestingOptionsSeparator;if(!e.includes(n))return e;let r=e.split(RegExp(`${h(n)}[ ]*{`)),i=`{${r[1]}`;e=r[0],i=this.interpolate(i,s);let a=i.match(/'/g),o=i.match(/"/g);((a?.length??0)%2==0&&!o||(o?.length??0)%2!=0)&&(i=i.replace(/'/g,`"`));try{s=JSON.parse(i),t&&(s={...t,...s})}catch(t){return this.logger.warn(`failed parsing options string in nesting for key ${e}`,t),`${e}${n}${i}`}return s.defaultValue&&s.defaultValue.includes(this.prefix)&&delete s.defaultValue,e};for(;a=this.nestingRegexp.exec(e);){let l=[];s={...r},s=s.replace&&!n(s.replace)?s.replace:s,s.applyPostProcessor=!1,delete s.defaultValue;let u=/{.*}/s.test(a[1])?a[1].lastIndexOf(`}`)+1:a[1].indexOf(this.formatSeparator);if(u!==-1&&(l=a[1].slice(u).split(this.formatSeparator).map(e=>e.trim()).filter(Boolean),a[1]=a[1].slice(0,u)),o=t(c.call(this,a[1].trim(),s),s),o&&a[0]===e&&!n(o))return o;n(o)||(o=i(o)),o||=(this.logger.warn(`missed to resolve ${a[1]} for nesting ${e}`),``),l.length&&(o=l.reduce((e,t)=>this.format(e,t,r.lng,{...r,interpolationkey:a[1].trim()}),o.trim())),e=e.replace(a[0],o),this.regexp.lastIndex=0}return e}},B=e=>{let t=e.toLowerCase().trim(),n={};if(e.includes(`(`)){let r=e.split(`(`);t=r[0].toLowerCase().trim();let i=r[1].slice(0,-1);t===`currency`&&!i.includes(`:`)?n.currency||=i.trim():t===`relativetime`&&!i.includes(`:`)?n.range||=i.trim():i.split(`;`).forEach(e=>{if(e){let[t,...r]=e.split(`:`),i=r.join(`:`).trim().replace(/^'+|'+$/g,``),a=t.trim();n[a]||(n[a]=i),i===`false`&&(n[a]=!1),i===`true`&&(n[a]=!0),isNaN(i)||(n[a]=parseInt(i,10))}})}return{formatName:t,formatOptions:n}},V=e=>{let t={};return(n,r,i)=>{let a=i;i&&i.interpolationkey&&i.formatParams&&i.formatParams[i.interpolationkey]&&i[i.interpolationkey]&&(a={...a,[i.interpolationkey]:void 0});let o=r+JSON.stringify(a),s=t[o];return s||(s=e(C(r),i),t[o]=s),s(n)}},te=e=>(t,n,r)=>e(C(n),r)(t),ne=class{constructor(e={}){this.logger=T.create(`formatter`),this.options=e,this.init(e)}init(e,t={interpolation:{}}){this.formatSeparator=t.interpolation.formatSeparator||`,`;let n=t.cacheInBuiltFormats?V:te;this.formats={number:n((e,t)=>{let n=new Intl.NumberFormat(e,{...t});return e=>n.format(e)}),currency:n((e,t)=>{let n=new Intl.NumberFormat(e,{...t,style:`currency`});return e=>n.format(e)}),datetime:n((e,t)=>{let n=new Intl.DateTimeFormat(e,{...t});return e=>n.format(e)}),relativetime:n((e,t)=>{let n=new Intl.RelativeTimeFormat(e,{...t});return e=>n.format(e,t.range||`day`)}),list:n((e,t)=>{let n=new Intl.ListFormat(e,{...t});return e=>n.format(e)})}}add(e,t){this.formats[e.toLowerCase().trim()]=t}addCached(e,t){this.formats[e.toLowerCase().trim()]=V(t)}format(e,t,n,r={}){if(!t||e==null)return e;let i=t.split(this.formatSeparator),a=[];for(let e=0;e<i.length;e++){let t=i[e];for(;t.indexOf(`(`)>-1&&!t.includes(`)`)&&e+1<i.length;)t=`${t}${this.formatSeparator}${i[++e]}`;a.push(t)}return a.reduce((e,t)=>{let{formatName:i,formatOptions:a}=B(t);if(this.formats[i]){let t=e;try{let o=r?.formatParams?.[r.interpolationkey]||{},s=o.locale||o.lng||r.locale||r.lng||n;t=this.formats[i](e,s,{...a,...r,...o})}catch(e){this.logger.warn(e)}return t}return this.logger.warn(`there was no format function for ${i}`),e},e)}},re=(e,t)=>{e.pending[t]!==void 0&&(delete e.pending[t],e.pendingCount--)},ie=class extends E{constructor(e,t,n,r={}){super(),this.backend=e,this.store=t,this.services=n,this.languageUtils=n.languageUtils,this.options=r,this.logger=T.create(`backendConnector`),this.waitingReads=[],this.maxParallelReads=r.maxParallelReads||10,this.readingCalls=0,this.maxRetries=r.maxRetries>=0?r.maxRetries:5,this.retryTimeout=r.retryTimeout>=1?r.retryTimeout:350,this.state={},this.queue=[],this.backend?.init?.(n,r.backend,r)}queueLoad(e,t,n,r){let i={},a={},o={},s={};return e.forEach(e=>{let r=!0;t.forEach(t=>{let o=`${e}|${t}`;!n.reload&&this.store.hasResourceBundle(e,t)?this.state[o]=2:this.state[o]<0||(this.state[o]===1?a[o]===void 0&&(a[o]=!0):(this.state[o]=1,r=!1,a[o]===void 0&&(a[o]=!0),i[o]===void 0&&(i[o]=!0),s[t]===void 0&&(s[t]=!0)))}),r||(o[e]=!0)}),(Object.keys(i).length||Object.keys(a).length)&&this.queue.push({pending:a,pendingCount:Object.keys(a).length,loaded:{},errors:[],callback:r}),{toLoad:Object.keys(i),pending:Object.keys(a),toLoadLanguages:Object.keys(o),toLoadNamespaces:Object.keys(s)}}loaded(e,t,n){let r=e.split(`|`),i=r[0],a=r[1];t&&this.emit(`failedLoading`,i,a,t),!t&&n&&this.store.addResourceBundle(i,a,n,void 0,void 0,{skipCopy:!0}),this.state[e]=t?-1:2,t&&n&&(this.state[e]=0);let o={};this.queue.forEach(n=>{d(n.loaded,[i],a),re(n,e),t&&n.errors.push(t),n.pendingCount===0&&!n.done&&(Object.keys(n.loaded).forEach(e=>{o[e]||(o[e]={});let t=n.loaded[e];t.length&&t.forEach(t=>{o[e][t]===void 0&&(o[e][t]=!0)})}),n.done=!0,n.errors.length?n.callback(n.errors):n.callback())}),this.emit(`loaded`,o),this.queue=this.queue.filter(e=>!e.done)}read(e,t,n,r=0,i=this.retryTimeout,a){if(!e.length)return a(null,{});if(this.readingCalls>=this.maxParallelReads){this.waitingReads.push({lng:e,ns:t,fcName:n,tried:r,wait:i,callback:a});return}this.readingCalls++;let o=(o,s)=>{if(this.readingCalls--,this.waitingReads.length>0){let e=this.waitingReads.shift();this.read(e.lng,e.ns,e.fcName,e.tried,e.wait,e.callback)}if(o&&s&&r<this.maxRetries){setTimeout(()=>{this.read(e,t,n,r+1,i*2,a)},i);return}a(o,s)},s=this.backend[n].bind(this.backend);if(s.length===2){try{let n=s(e,t);n&&typeof n.then==`function`?n.then(e=>o(null,e)).catch(o):o(null,n)}catch(e){o(e)}return}return s(e,t,o)}prepareLoading(e,t,r={},i){if(!this.backend)return this.logger.warn(`No backend was added via i18next.use. Will not load resources.`),i&&i();n(e)&&(e=this.languageUtils.toResolveHierarchy(e)),n(t)&&(t=[t]);let a=this.queueLoad(e,t,r,i);if(!a.toLoad.length)return a.pending.length||i(),null;a.toLoad.forEach(e=>{this.loadOne(e)})}load(e,t,n){this.prepareLoading(e,t,{},n)}reload(e,t,n){this.prepareLoading(e,t,{reload:!0},n)}loadOne(e,t=``){let n=e.split(`|`),r=n[0],i=n[1];this.read(r,i,`read`,void 0,void 0,(n,a)=>{n&&this.logger.warn(`${t}loading namespace ${i} for language ${r} failed`,n),!n&&a&&this.logger.log(`${t}loaded namespace ${i} for language ${r}`,a),this.loaded(e,n,a)})}saveMissing(e,t,n,r,i,a={},o=()=>{}){if(this.services?.utils?.hasLoadedNamespace&&!this.services?.utils?.hasLoadedNamespace(t)){this.logger.warn(`did not save key "${n}" as the namespace "${t}" was not yet loaded`,`This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!`);return}if(n!=null&&n!==``){if(this.backend?.create){let s={...a,isUpdate:i},c=this.backend.create.bind(this.backend);if(c.length<6)try{let i;i=c.length===5?c(e,t,n,r,s):c(e,t,n,r),i&&typeof i.then==`function`?i.then(e=>o(null,e)).catch(o):o(null,i)}catch(e){o(e)}else c(e,t,n,r,o,s)}!e||!e[0]||this.store.addResource(e[0],t,n,r)}}},H=()=>({debug:!1,initAsync:!0,ns:[`translation`],defaultNS:[`translation`],fallbackLng:[`dev`],fallbackNS:!1,supportedLngs:!1,nonExplicitSupportedLngs:!1,load:`all`,preload:!1,keySeparator:`.`,nsSeparator:`:`,pluralSeparator:`_`,contextSeparator:`_`,enableSelector:!1,partialBundledLanguages:!1,saveMissing:!1,updateMissing:!1,saveMissingTo:`fallback`,saveMissingPlurals:!0,missingKeyHandler:!1,missingInterpolationHandler:!1,postProcess:!1,postProcessPassResolved:!1,returnNull:!1,returnEmptyString:!0,returnObjects:!1,joinArrays:!1,returnedObjectHandler:!1,parseMissingKeyHandler:!1,appendNamespaceToMissingKey:!1,appendNamespaceToCIMode:!1,overloadTranslationOptionHandler:e=>{let t={};if(typeof e[1]==`object`&&(t=e[1]),n(e[1])&&(t.defaultValue=e[1]),n(e[2])&&(t.tDescription=e[2]),typeof e[2]==`object`||typeof e[3]==`object`){let n=e[3]||e[2];Object.keys(n).forEach(e=>{t[e]=n[e]})}return t},interpolation:{escapeValue:!0,prefix:`{{`,suffix:`}}`,formatSeparator:`,`,unescapePrefix:`-`,nestingPrefix:`$t(`,nestingSuffix:`)`,nestingOptionsSeparator:`,`,maxReplaces:1e3,skipOnVariables:!0},cacheInBuiltFormats:!0}),U=e=>(n(e.ns)&&(e.ns=[e.ns]),n(e.fallbackLng)&&(e.fallbackLng=[e.fallbackLng]),n(e.fallbackNS)&&(e.fallbackNS=[e.fallbackNS]),e.supportedLngs&&!e.supportedLngs.includes(`cimode`)&&(e.supportedLngs=e.supportedLngs.concat([`cimode`])),e),W=()=>{},G=e=>{Object.getOwnPropertyNames(Object.getPrototypeOf(e)).forEach(t=>{typeof e[t]==`function`&&(e[t]=e[t].bind(e))})},K=class e extends E{constructor(e={},t){if(super(),this.options=U(e),this.services={},this.logger=T,this.modules={external:[]},G(this),t&&!this.isInitialized&&!e.isClone){if(!this.options.initAsync)return this.init(e,t),this;setTimeout(()=>{this.init(e,t)},0)}}init(e={},t){this.isInitializing=!0,typeof e==`function`&&(t=e,e={}),e.defaultNS==null&&e.ns&&(n(e.ns)?e.defaultNS=e.ns:e.ns.includes(`translation`)||(e.defaultNS=e.ns[0]));let i=H();this.options={...i,...this.options,...U(e)},this.options.interpolation={...i.interpolation,...this.options.interpolation},e.keySeparator!==void 0&&(this.options.userDefinedKeySeparator=e.keySeparator),e.nsSeparator!==void 0&&(this.options.userDefinedNsSeparator=e.nsSeparator),typeof this.options.overloadTranslationOptionHandler!=`function`&&(this.options.overloadTranslationOptionHandler=i.overloadTranslationOptionHandler);let a=e=>e?typeof e==`function`?new e:e:null;if(!this.options.isClone){this.modules.logger?T.init(a(this.modules.logger),this.options):T.init(null,this.options);let e;e=this.modules.formatter?this.modules.formatter:ne;let t=new P(this.options);this.store=new D(this.options.resources,this.options);let n=this.services;n.logger=T,n.resourceStore=this.store,n.languageUtils=t,n.pluralResolver=new L(t,{prepend:this.options.pluralSeparator}),e&&(n.formatter=a(e),n.formatter.init&&n.formatter.init(n,this.options),this.options.interpolation.format=n.formatter.format.bind(n.formatter)),n.interpolator=new z(this.options),n.utils={hasLoadedNamespace:this.hasLoadedNamespace.bind(this)},n.backendConnector=new ie(a(this.modules.backend),n.resourceStore,n,this.options),n.backendConnector.on(`*`,(e,...t)=>{this.emit(e,...t)}),this.modules.languageDetector&&(n.languageDetector=a(this.modules.languageDetector),n.languageDetector.init&&n.languageDetector.init(n,this.options.detection,this.options)),this.modules.i18nFormat&&(n.i18nFormat=a(this.modules.i18nFormat),n.i18nFormat.init&&n.i18nFormat.init(this)),this.translator=new N(this.services,this.options),this.translator.on(`*`,(e,...t)=>{this.emit(e,...t)}),this.modules.external.forEach(e=>{e.init&&e.init(this)})}if(this.format=this.options.interpolation.format,t||=W,this.options.fallbackLng&&!this.services.languageDetector&&!this.options.lng){let e=this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);e.length>0&&e[0]!==`dev`&&(this.options.lng=e[0])}!this.services.languageDetector&&!this.options.lng&&this.logger.warn(`init: no languageDetector is used and no lng is defined`),[`getResource`,`hasResourceBundle`,`getResourceBundle`,`getDataByLanguage`].forEach(e=>{this[e]=(...t)=>this.store[e](...t)}),[`addResource`,`addResources`,`addResourceBundle`,`removeResourceBundle`].forEach(e=>{this[e]=(...t)=>(this.store[e](...t),this)});let o=r(),s=()=>{let e=(e,n)=>{this.isInitializing=!1,this.isInitialized&&!this.initializedStoreOnce&&this.logger.warn(`init: i18next is already initialized. You should call init just once!`),this.isInitialized=!0,this.options.isClone||this.logger.log(`initialized`,this.options),this.emit(`initialized`,this.options),o.resolve(n),t(e,n)};if((this.languages||this.isLanguageChangingTo)&&!this.isInitialized)return e(null,this.t.bind(this));this.changeLanguage(this.options.lng,e)};return this.options.resources||!this.options.initAsync?s():setTimeout(s,0),o}loadResources(e,t=W){let r=t,i=n(e)?e:this.language;if(typeof e==`function`&&(r=e),!this.options.resources||this.options.partialBundledLanguages){if(i?.toLowerCase()===`cimode`&&(!this.options.preload||this.options.preload.length===0))return r();let e=[],t=t=>{t&&t!==`cimode`&&this.services.languageUtils.toResolveHierarchy(t).forEach(t=>{t!==`cimode`&&(e.includes(t)||e.push(t))})};i?t(i):this.services.languageUtils.getFallbackCodes(this.options.fallbackLng).forEach(e=>t(e)),this.options.preload?.forEach?.(e=>t(e)),this.services.backendConnector.load(e,this.options.ns,e=>{!e&&!this.resolvedLanguage&&this.language&&this.setResolvedLanguage(this.language),r(e)})}else r(null)}reloadResources(e,t,n){let i=r();return typeof e==`function`&&(n=e,e=void 0),typeof t==`function`&&(n=t,t=void 0),e||=this.languages,t||=this.options.ns,n||=W,this.services.backendConnector.reload(e,t,e=>{i.resolve(),n(e)}),i}use(e){if(!e)throw Error(`You are passing an undefined module! Please check the object you are passing to i18next.use()`);if(!e.type)throw Error(`You are passing a wrong module! Please check the object you are passing to i18next.use()`);return e.type===`backend`&&(this.modules.backend=e),(e.type===`logger`||e.log&&e.warn&&e.error)&&(this.modules.logger=e),e.type===`languageDetector`&&(this.modules.languageDetector=e),e.type===`i18nFormat`&&(this.modules.i18nFormat=e),e.type===`postProcessor`&&O.addPostProcessor(e),e.type===`formatter`&&(this.modules.formatter=e),e.type===`3rdParty`&&this.modules.external.push(e),this}setResolvedLanguage(e){if(!(!e||!this.languages)&&![`cimode`,`dev`].includes(e)){for(let e=0;e<this.languages.length;e++){let t=this.languages[e];if(![`cimode`,`dev`].includes(t)&&this.store.hasLanguageSomeTranslations(t)){this.resolvedLanguage=t;break}}!this.resolvedLanguage&&!this.languages.includes(e)&&this.store.hasLanguageSomeTranslations(e)&&(this.resolvedLanguage=e,this.languages.unshift(e))}}changeLanguage(e,t){this.isLanguageChangingTo=e;let i=r();this.emit(`languageChanging`,e);let a=e=>{this.language=e,this.languages=this.services.languageUtils.toResolveHierarchy(e),this.resolvedLanguage=void 0,this.setResolvedLanguage(e)},o=(n,r)=>{r?this.isLanguageChangingTo===e&&(a(r),this.translator.changeLanguage(r),this.isLanguageChangingTo=void 0,this.emit(`languageChanged`,r),this.logger.log(`languageChanged`,r)):this.isLanguageChangingTo=void 0,i.resolve((...e)=>this.t(...e)),t&&t(n,(...e)=>this.t(...e))},s=t=>{!e&&!t&&this.services.languageDetector&&(t=[]);let r=n(t)?t:t&&t[0],i=this.store.hasLanguageSomeTranslations(r)?r:this.services.languageUtils.getBestMatchFromCodes(n(t)?[t]:t);i&&(this.language||a(i),this.translator.language||this.translator.changeLanguage(i),this.services.languageDetector?.cacheUserLanguage?.(i)),this.loadResources(i,e=>{o(e,i)})};return!e&&this.services.languageDetector&&!this.services.languageDetector.async?s(this.services.languageDetector.detect()):!e&&this.services.languageDetector&&this.services.languageDetector.async?this.services.languageDetector.detect.length===0?this.services.languageDetector.detect().then(s):this.services.languageDetector.detect(s):s(e),i}getFixedT(e,t,r,i){let a=i?.scopeNs,o=(e,t,...n)=>{let i;i=typeof t==`object`?{...t}:this.options.overloadTranslationOptionHandler([e,t].concat(n)),i.lng=i.lng||o.lng,i.lngs=i.lngs||o.lngs;let s=i.ns!==void 0&&i.ns!==null;i.ns=i.ns||o.ns,i.keyPrefix!==``&&(i.keyPrefix=i.keyPrefix||r||o.keyPrefix);let c={...this.options,...i};Array.isArray(a)&&!s&&(c.ns=a),typeof i.keyPrefix==`function`&&(i.keyPrefix=j(i.keyPrefix,c));let l=this.options.keySeparator||`.`,u;return i.keyPrefix&&Array.isArray(e)?u=e.map(e=>(typeof e==`function`&&(e=j(e,c)),`${i.keyPrefix}${l}${e}`)):(typeof e==`function`&&(e=j(e,c)),u=i.keyPrefix?`${i.keyPrefix}${l}${e}`:e),this.t(u,i)};return n(e)?o.lng=e:o.lngs=e,o.ns=t,o.keyPrefix=r,o}t(...e){return this.translator?.translate(...e)}exists(...e){return this.translator?.exists(...e)}setDefaultNamespace(e){this.options.defaultNS=e}hasLoadedNamespace(e,t={}){if(!this.isInitialized)return this.logger.warn(`hasLoadedNamespace: i18next was not initialized`,this.languages),!1;if(!this.languages||!this.languages.length)return this.logger.warn(`hasLoadedNamespace: i18n.languages were undefined or empty`,this.languages),!1;let n=t.lng||this.resolvedLanguage||this.languages[0],r=this.options?this.options.fallbackLng:!1,i=this.languages[this.languages.length-1];if(n.toLowerCase()===`cimode`)return!0;let a=(e,t)=>{let n=this.services.backendConnector.state[`${e}|${t}`];return n===-1||n===0||n===2};if(t.precheck){let e=t.precheck(this,a);if(e!==void 0)return e}return!!(this.hasResourceBundle(n,e)||!this.services.backendConnector.backend||this.options.resources&&!this.options.partialBundledLanguages||a(n,e)&&(!r||a(i,e)))}loadNamespaces(e,t){let i=r();return this.options.ns?(n(e)&&(e=[e]),e.forEach(e=>{this.options.ns.includes(e)||this.options.ns.push(e)}),this.loadResources(e=>{i.resolve(),t&&t(e)}),i):(t&&t(),Promise.resolve())}loadLanguages(e,t){let i=r();n(e)&&(e=[e]);let a=this.options.preload||[],o=e.filter(e=>!a.includes(e)&&this.services.languageUtils.isSupportedCode(e));return o.length?(this.options.preload=a.concat(o),this.loadResources(e=>{i.resolve(),t&&t(e)}),i):(t&&t(),Promise.resolve())}dir(e){if(e||=this.resolvedLanguage||(this.languages?.length>0?this.languages[0]:this.language),!e)return`rtl`;try{let t=new Intl.Locale(e);if(t&&t.getTextInfo){let e=t.getTextInfo();if(e&&e.direction)return e.direction}}catch{}let t=`ar.shu.sqr.ssh.xaa.yhd.yud.aao.abh.abv.acm.acq.acw.acx.acy.adf.ads.aeb.aec.afb.ajp.apc.apd.arb.arq.ars.ary.arz.auz.avl.ayh.ayl.ayn.ayp.bbz.pga.he.iw.ps.pbt.pbu.pst.prp.prd.ug.ur.ydd.yds.yih.ji.yi.hbo.men.xmn.fa.jpr.peo.pes.prs.dv.sam.ckb`.split(`.`),n=this.services?.languageUtils||new P(H());return e.toLowerCase().indexOf(`-latn`)>1?`ltr`:t.includes(n.getLanguagePartFromCode(e))||e.toLowerCase().indexOf(`-arab`)>1?`rtl`:`ltr`}static createInstance(t={},n){let r=new e(t,n);return r.createInstance=e.createInstance,r}cloneInstance(t={},n=W){let r=t.forkResourceStore;r&&delete t.forkResourceStore;let i={...this.options,...t,isClone:!0},a=new e(i);if((t.debug!==void 0||t.prefix!==void 0)&&(a.logger=a.logger.clone(t)),[`store`,`services`,`language`].forEach(e=>{a[e]=this[e]}),a.services={...this.services},a.services.utils={hasLoadedNamespace:a.hasLoadedNamespace.bind(a)},r&&(a.store=new D(Object.keys(this.store.data).reduce((e,t)=>(e[t]={...this.store.data[t]},e[t]=Object.keys(e[t]).reduce((n,r)=>(n[r]={...e[t][r]},n),e[t]),e),{}),i),a.services.resourceStore=a.store),t.interpolation){let e={...H().interpolation,...this.options.interpolation,...t.interpolation},n={...i,interpolation:e};a.services.interpolator=new z(n)}return a.translator=new N(a.services,i),a.translator.on(`*`,(e,...t)=>{a.emit(e,...t)}),a.init(i,n),a.translator.options=i,a.translator.backendConnector.services.utils={hasLoadedNamespace:a.hasLoadedNamespace.bind(a)},a}toJSON(){return{options:this.options,store:this.store,language:this.language,languages:this.languages,resolvedLanguage:this.resolvedLanguage}}}.createInstance();K.createInstance,K.dir,K.init,K.loadResources,K.reloadResources,K.use,K.changeLanguage,K.getFixedT,K.t,K.exists,K.setDefaultNamespace,K.hasLoadedNamespace,K.loadNamespaces,K.loadLanguages;var q={type:`3rdParty`,init(n){t(n.options.react),e(n)}},J={app:{reconnecting:`Reconnecting…`,dropSqlite:`Drop to open the SQLite file`,dropSqliteHint:`Opened in your browser with WebAssembly — the file stays on your computer. Drop the -wal sidecar together with it if there is one.`,dropFailedTitle:`Could not open the dropped file`,dropNotSqlite:`{{name}} is not a SQLite database file.`,crashTitle:`Something went wrong`,crashBody:`The app hit an unexpected error. Reloading restores your connections and tabs; unsaved grid edits are lost.`,crashReload:`Reload`},language:{auto:`System language ({{name}})`,en:`English`,ko:`한국어`,zh:`中文(简体)`,ja:`日本語`,de:`Deutsch`,fr:`Français`},settings:{title:`Safety`,description:`Guard rails against accidental data loss. Read-only, environment colour and transaction mode are set per connection.`,language:`Language`,languageHint:`Applies immediately. "System language" follows your browser.`,resetDefaults:`Reset to defaults`,done:`Done`,analytics:`Share anonymous usage statistics`,analyticsHint:`Sends anonymous usage events (engine, feature, statement type) to Google Analytics. Never SQL text, host names, table or user names.`,analyticsUnavailableHint:`Not active in this build (no measurement id configured).`,persistHistory:`Keep query history across reloads`,persistHistoryHint:`Statement text is stored in this browser (password literals are masked; the open editor tabs themselves are always kept). Off: history and versions live only until the tab closes.`,ai:{intro:`Planche can ask a model why a statement failed or why a plan is slow. The question is put together here in the app and sent by your local agent to the provider below — nothing about your SQL or your schema reaches planche.dev.`,provider:`Provider`,openaiCompatible:`OpenAI-compatible`,model:`Model`,baseUrl:`Base URL`,baseUrlHint:`Leave empty for the provider's own endpoint. Any OpenAI-compatible server works — Azure, OpenRouter, a local Ollama.`,key:`API key`,keyHint:`Handed to the local agent and used there. It is never kept in this browser and never sent to planche.dev.`,remember:`Remember this key on this machine`,rememberHint:`Writes it to {{path}}, readable only by you. Without this the key lives in the running agent and is gone when it stops.`,save:`Save`,forget:`Forget key`,saved:`Saved.`,none:`No key set.`,configuredSession:`A key is set for this agent session only.`,configuredFile:`A key is stored at {{path}}.`,configuredEnv:`This agent's AI settings come from its environment and cannot be changed here.`,unreachable:`The agent is not reachable, so AI settings cannot be changed.`,title:`AI explanations`,description:`Which model explains a failure or a plan, and whose key pays for it.`,cli:`Local CLI (no key)`,cliCommand:`Command`,cliHint:`Runs an agent CLI already installed and signed in on this machine, so there is no key to enter. It explains failures and plans; the AI panel needs a provider that can call tools.`,cliNone:`No agent CLI was found on this machine. Install Claude Code or Codex, or pick another provider.`,profile:`Anthropic (this machine's login)`,profileHint:"Uses the credential this machine is already signed in with — the SDK finds it on its own after `ant auth login`. Nothing to paste, and unlike a local CLI this is the real API, so the AI panel works too.",profileNone:"No Anthropic credential was found on this machine. Run `ant auth login`, or set a key instead.",configuredChoice:`Using {{provider}} — no key held; the choice is kept in {{path}}.`},query:{title:`Query`,description:`How a statement is run: what F9 executes, how many rows come back, and what is previewed first.`},general:{title:`General`,description:`Language, what survives a reload, and what leaves this machine.`}},menu:{settings:{safety:`Safety…`,language:`Language`,title:`Settings`,theme:`Theme`,query:`Query…`,general:`General…`,ai:`AI…`},help:{gettingStarted:`Getting Started`,about:`About Planche`,title:`Help`,documentation:`Documentation`,learn:`Learn SQL`,terms:`Terms of Use`,license:`Licence`,support:`Contact support`,mcp:`Connect an AI agent (MCP)…`,privacy:`Privacy policy`},connection:{title:`Connection`,connect:`Connect`,disconnect:`Disconnect`,readOnly:`Read-only`,manualTransactions:`Manual Transactions`,saveDatabaseFile:`Save Database File`,saveDatabaseFileBlocked:`Save Database File (load -wal first)`,exit:`Exit`,sync:`Connection sync`},query:{title:`Query`,execute:`Execute`,executeStatementAtCursor:`Execute Statement at Cursor`,executeWholeScript:`Execute Whole Script`,newQueryTab:`New Query Tab`,findReplace:`Find & Replace`,localHistory:`Local History…`,explainPlan:`Explain Plan`,explainAnalyze:`Explain Analyze (runs the statement)`,structure:`Query Structure`},edit:{title:`Edit`,undo:`Undo`,redo:`Redo`,cut:`Cut`,copy:`Copy`,paste:`Paste`,selectAll:`Select All`},database:{title:`Database`,create:`Create Database`,alter:`Alter Database`,drop:`Drop Database`,copy:`Copy Database`,compare:`Compare Schemas…`,truncate:`Truncate Database`,compareData:`Compare Data…`,groupBy:`Group and Count…`},table:{title:`Table`,create:`Create Table`,alter:`Alter Table`,drop:`Drop Table`,rename:`Rename Table`,truncate:`Truncate Table`,duplicateStructure:`Duplicate Table Structure`},export:{title:`Export`,csv:`Download to CSV`,tsv:`Download to TSV`,schemaHtml:`Schema to HTML`,links:`Export column links…`,importLinks:`Import column links…`},tools:{title:`Tools`,userManager:`User Manager`,processList:`Process List`,variables:`Variables`,status:`Status`,flush:`Flush`,quickCommand:`Quick Command`,viewErd:`View ERD`,scratchpad:`Scratchpad (in-browser SQLite)`,federated:`Federated query (join across connections)…`,federatedTab:`Federated {{n}}`,ai:`AI assistant`},messages:{databaseFileSaved:`Database file saved`,databaseExported:`Database exported as download`,databaseExportedWithReason:`Database exported as download — {{reason}}`,errorSavingDatabase:`Error saving database: {{message}}`,noDatabaseSelected:`No database selected`,noTableSelected:`No table selected`,noActiveConnection:`No active connection`,databaseDropped:`Database "{{database}}" dropped successfully`,errorDroppingDatabase:`Error dropping database: {{message}}`,noTablesInDatabase:`No tables found in database "{{database}}"`,databaseTruncated_one:`All {{count}} table in "{{database}}" truncated successfully`,databaseTruncated_other:`All {{count}} tables in "{{database}}" truncated successfully`,errorTruncatingDatabase:`Error truncating database: {{message}}`,tableDropped:`Table "{{table}}" dropped successfully`,errorDroppingTable:`Error dropping table: {{message}}`,tableTruncated:`Table "{{table}}" truncated successfully`,errorTruncatingTable:`Error truncating table: {{message}}`,renameTablePrompt:`Rename table "{{table}}" to:`,tableRenamed:`Table "{{table}}" renamed to "{{newName}}" successfully`,errorRenamingTable:`Error renaming table: {{message}}`,truncateDatabaseTitle:`Truncate all tables in "{{name}}"?`,truncateDatabaseDescription:`Every row in {{count}} table(s) of "{{name}}" will be deleted. Table structures are kept. This cannot be undone.`,truncateDatabaseConfirm:`Truncate all tables`,renameTableTitle:`Rename table`,renameTableConfirm:`Rename`,noLinksToExport:`No column links to export.`,linksExported:`Exported {{count}} column links.`,linksImported:`Imported {{count}} column links.`,linksImportedPartial:`Imported {{count}} column links; no matching profile for: {{profiles}}`,linksImportFailed:`Could not import column links: {{reason}}`}},about:{title:`About Planche`,tagline:`A database client for MySQL, MariaDB, PostgreSQL and SQLite.`,version:`Version`,website:`Website`,licenses:`Licenses`,licensesLink:`Third-party notices`,disclaimer:`Planche is provided "as is", without warranty of any kind. The authors are not liable for any damage or data loss arising from its use. Back up your data before running destructive statements.`,rights:`All rights reserved.`,legal:`Legal`,terms:`Terms`,privacy:`Privacy`,refund:`Refunds`},connection:JSON.parse('{"dialog":{"title":"Connect to Database","firstQueryTab":"Query 1","colHostName":"Host Name","colTarget":"Target","colDbms":"DBMS","noSaved":"No saved connections","unnamed":"(unnamed)","pickOnConnect":"(pick on connect)","noFile":"(no file)","selectPrompt":"Select a connection or add a new one","addNew":"Add New","delete":"Delete","testConnection":"Test Connection","connect":"Connect","close":"Close","unknownError":"Unknown error","browserTestHint":"In-browser SQLite connections open a local file when you click Connect.","testSuccess":"Connection successful","restoredUnsaved":"{{file}}: restored unsaved changes from the cached copy","restoredUnsavedDiskChanged":"{{file}}: restored unsaved changes from the cached copy — note the file on disk changed since","walPending":"{{file}} is in WAL mode: recent changes may still be in its -wal file. Use \\"Load -wal file\\" above to include them.","walApplied":"{{file}} opened with its -wal changes applied","connectFailedTitle":"Connection failed","testSuccessDescription":"The server accepted the credentials.","testFailedTitle":"Connection test failed","privacy":"Nothing you enter here is sent to or stored on planche.dev servers. Connection profiles live only in this browser\'s local storage; queries go straight from the local agent to your database.","hostKeyTitle":"Unknown SSH host key","hostKeyDescription":"{{host}}:{{port}} presented a {{type}} key with fingerprint {{fingerprint}}. Compare it with the fingerprint your server administrator gave you; accepting the wrong key lets an attacker read your traffic.","hostKeyAccept":"Trust this host","gatewayTitle":"Gateway profiles","gatewayAdd":"Add","gatewayAdded":"Added gateway profile {{name}}.","gatewayReadOnly":"read-only","gatewayWritable":"writable","gatewayProfileHint":"This connection uses the profile \\"{{name}}\\" held by the gateway; there is nothing to configure here.","gatewayLoadFailed":"Could not load the gateway profiles: {{error}}","export":"Export…","exportWithoutSecrets":"Without password","exportWithSecrets":"With password and keys","import":"Import…","exported":"Exported connection \\"{{name}}\\".","imported":"Imported connection \\"{{name}}\\".","importFailedTitle":"Could not import the connection"},"form":{"hostName":"Host Name","hostNamePlaceholder":"My Connection","dataSource":"Data Source","openVia":"Open Via","viaBrowser":"Browser (local file)","viaAgent":"Local agent","viaBrowserHint":"Nothing to install. Best for files no other program is using: the browser works on an in-memory copy and cannot lock the file, so edits made elsewhere while it is open are not seen and Save overwrites them.","viaAgentHint":"Opens the file with SQLite itself via npx planche — proper locking and WAL, safe alongside other programs using the same database.","databaseFile":"Database File","changeFile":"Change file","filePickerHint":"A file picker opens when you click Connect (tip: ⌘⇧. shows hidden files, ⌘⇧G lets you type a path).","fileRememberedHint":"The chosen file is remembered (Chromium) so reconnecting only asks for permission. Use Connection > Save Database File to write changes back.","authToken":"Auth Token","authTokenPlaceholder":"Leave empty to use the paired agent token","filePathPlaceholder":"/path/to/database.sqlite or :memory:","createIfMissing":"Create If Missing","createIfMissingHint":"Path is resolved on the tunneling server host","host":"Host","port":"Port","database":"Database","serviceName":"Service name","user":"User","password":"Password","savePassword":"Save password","savePasswordHint":"Off: the password is kept only for this browser session and never written to disk.","charset":"Charset","autoConnection":"Auto Connection","safety":"Safety","environment":"Environment","environmentHint":"tints the tab and workspace","readOnly":"Read-only","readOnlyHint":"Refuse statements that modify data or schema","transactions":"Transactions","txAuto":"Auto-commit","txManual":"Manual — Commit / Rollback from the toolbar","ssh":"SSH","sshTunnel":"SSH tunnel","sshTunnelHint":"Reach the database through an SSH jump host (opened by the local agent)","sshHost":"SSH Host","sshPort":"SSH port","sshUser":"SSH User","sshAuth":"SSH Auth","sshAuthKey":"Private key","sshAuthPassword":"Password","sshAuthAgent":"ssh-agent","sshAuthAgentHint":"Uses the keys loaded in the ssh-agent of the machine running npx planche (SSH_AUTH_SOCK).","sshPassword":"SSH Password","sshKey":"Private Key","sshKeyPick":"Choose key file…","sshKeyLoaded":"Key loaded","sshKeyHint":"Leave empty to use the IdentityFile from ~/.ssh/config (or ~/.ssh/id_*) on the agent\'s machine; a picked key is stored with this profile","sshPassphrase":"Passphrase","sshPassphrasePlaceholder":"Leave empty if the key has none","sshSecretsHint":"The SSH password, private key and passphrase follow the \\"Save password\\" setting above. Unknown host keys are shown for you to verify before the first connection and saved to ~/.planche/known_hosts on the agent\'s machine.","sshHostPlaceholder":"bastion.example.com or a Host alias from ~/.ssh/config","sshUserPlaceholder":"Leave empty to use ~/.ssh/config","sshTargetHint":"The database host and port are resolved on the jump host — use the database\'s real address (e.g. the RDS endpoint), not localhost or a local port forward.","connectionString":"Connection string","connectionStringApplied":"Applied to the fields below. The string itself is not saved — only the fields are.","connectionStringInvalid":"Not a PostgreSQL URI (expected postgresql://user:password@host/database).","neonHint":"Paste the URI from the Neon console (Connect > Connection string); the fields below are filled in from it.","supabaseHint":"Paste the URI from Supabase (Connect > Session pooler or Direct connection); the fields below are filled in from it.","supabasePoolerWarning":"Port 6543 is the transaction-mode pooler: each statement may run on a different backend, so switching schemas, temp tables, prepared statements and manual transactions do not work. Use the session pooler (port 5432) or the direct connection.","managedTlsHint":"TLS is always on for this service; the connection goes straight from the local agent to the service (no SSH tunnel).","d1AccountId":"Account ID","d1DatabaseId":"Database ID","d1ApiToken":"API Token","d1Hint":"Account ID: Cloudflare dashboard, right side of the account home. Database ID: Storage & Databases > D1 > your database. Token: My Profile > API Tokens > Create Token with the \\"D1 Edit\\" permission (or \\"D1 Read\\" for read-only). The local agent calls the Cloudflare API with it.","d1LimitsHint":"D1 runs each request on its own and auto-commits, so manual transactions are unavailable; the database appears as the single schema \\"main\\".","doDevUrl":"wrangler dev URL","doHint":"Start `wrangler dev` in your Worker project and paste the URL it prints (the port is 8787 unless you changed it). The local agent reads the Durable Objects of that session — including other `wrangler dev` sessions running at the same time.","doLimitsHint":"Local development only: deployed Durable Objects are reachable only from a Worker, so Cloudflare offers no API to query them. Each object appears as a database named \\"<namespace>/<object>\\"; every request auto-commits, so manual transactions are unavailable.","tls":"TLS","tlsEnable":"Encrypt the connection","tlsVerify":"Verify server certificate","tlsVerifyHint":"Off: self-signed certificates are accepted (encrypted, but the server is not authenticated). Not available over an SSH tunnel.","d1DevUrl":"Local dev URL","d1DevUrlHint":"Leave empty to use a Cloudflare account. Filled in, Planche reads the database that `wrangler dev` is running on this machine — no account and no API token, and the account fields below are ignored. Leave the Database ID empty when the dev server binds only one.","d1PickDatabase":"Pick a database"},"agent":{"copy":"Copy","looking":"Looking for the Planche agent…","online":"Agent <b>v{{version}}</b> is running at <mono>{{url}}</mono>","outdated":"Agent v{{version}} speaks protocol {{protocol}}, but this app needs a newer one. Restart it with <cmd/>","unauthorized":"Agent <b>v{{version}}</b> is running at <mono>{{url}}</mono>, but this app is not paired with it (the token changes on every start). Open the link printed in the agent\'s terminal, or paste the token under Configure.","offline":"No agent at <mono>{{url}}</mono>. Start it in a terminal — it opens this app already paired.","close":"Close","configure":"Configure","checkAgain":"Check again","urlLabel":"Agent URL","urlPlaceholder":"http://127.0.0.1:8888 (default)","tokenLabel":"Token","tokenPlaceholder":"Printed by the agent","reset":"Reset","save":"Save","remoteWarning":"This agent is not on your computer ({{host}}): every connection sends its passwords and SSH keys there.","remoteRefusedTitle":"Remote agent not allowed","remoteRefused":"The agent must run on this computer (127.0.0.1 or localhost). To use one on another machine, forward its port with `ssh -L 8888:127.0.0.1:8888 user@host` and keep the URL at http://127.0.0.1:8888.","gateway":"Gateway \\"{{name}}\\": {{count}} server-side profiles. Credentials stay on the gateway; pick a profile below."},"tab":{"noConnections":"No connections open. Press Connect to get started.","theSqliteFile":"the SQLite file","reopened":"Reopened {{file}}","reopenFailed":"Could not reopen file: {{message}}","reopenPrompt":"The browser needs your permission again to read <b>{{file}}</b>.","reopenFile":"Reopen file","closeConnection":"Close connection","reconnected":"Reconnected {{file}}","accessNotGranted":"File access was not granted; Save will export a download instead.","detachedPrompt":"Working on a cached copy of <b>{{file}}</b>. Reconnect the file to save changes in place.","reconnectFile":"Reconnect file","detachedHide":"Hide (Save will ask for the file when needed)","walFramesApplied_one":"Applied {{count}} WAL frame from {{file}}-wal","walFramesApplied_other":"Applied {{count}} WAL frames from {{file}}-wal","walNoChanges":"The -wal file had no committed changes","walLoadFailed":"Could not load -wal file: {{message}}","walPrompt":"<b>{{file}}</b> is in WAL mode: it may not show the latest data until its <mono>{{file}}-wal</mono> file is loaded, and saving is disabled until then. If no such file exists next to it (the database was closed cleanly), confirm that instead. If another program is still using this database, open it through the local agent (<mono>npx planche</mono>) instead: the browser cannot share the file safely.","loadWal":"Load -wal file","noWalHint":"I checked: there is no -wal file next to the database","noWal":"No -wal file","dismiss":"Dismiss","walHide":"Hide (saving stays disabled)","readOnlyBadge":"read-only"}}'),toolbar:{connect:`Connect (Alt+N)`,disconnect:`Disconnect`,newQueryTab:`New Query Tab (Alt+T)`,execute:`Execute (F9)`,executeStatement:`Execute statement at cursor / selection (Ctrl+Enter)`,commit:`Commit`,commitHint:`Commit the open transaction`,noOpenTransaction:`No open transaction`,rollback:`Rollback`,rollbackHint:`Discard the open transaction`,readOnlyBadge:`read-only`,readOnlyHint:`This connection refuses statements that modify data or schema`,userManager:`User Manager (Alt+U)`,quickCommand:`Quick Command`,processList:`Process List`,variables:`Variables`,status:`Status`,flush:`Flush`,fullscreen:`Fullscreen`},footer:{readOnly:`read-only`,txOpen:`tx open`,manualTx:`manual tx`},palette:{title:`Quick Command`,description:`Search for a command to run...`,inputPlaceholder:`Type a command or search...`,empty:`No commands found.`,groups:{connection:`Connection`,query:`Query`,database:`Database`,table:`Table`,tools:`Tools`},commands:{connect:`Connect`,disconnect:`Disconnect`,executeQuery:`Execute Query`,newQueryTab:`New Query Tab`,createDatabase:`Create Database`,dropDatabase:`Drop Database`,createTable:`Create Table`,alterTable:`Alter Table`,dropTable:`Drop Table`,processList:`Process List`,serverVariables:`Server Variables`,serverStatus:`Server Status`,flush:`Flush`,userManager:`User Manager`}},welcome:{title:`Welcome to Planche`,intro:`A SQL client that runs in your browser. Your databases are reached through a small agent on your machine, so credentials and data never leave your computer.`,skip:`Skip`,skipTitle:`Hide this screen (Help > Getting Started brings it back)`,copy:`Copy`,copied:`Copied`,sampleOpenFailed:`Could not open the sample database: {{message}}`,steps:{agent:{title:`Run the local agent`,body:`Run one of these in a terminal. It starts the agent and pairs it with this page.`},connection:{title:`Add a connection`,body:`Pick your database to open the connection form with the right defaults.`},sample:{title:`No database at hand? Try the sample`,body:`Load a sample web-shop database (24 tables, ~50k rows, views and triggers) into the browser to try the editor, grid and schema tree.`,loading:`Loading sample…`,button:`Try the sample database`}},terms:{title:`Before you start`,local:`Everything runs locally: credentials, queries and results stay on your machine and are never sent to us.`,asIs:`Planche is provided as is, without warranty. The safeguards (destructive confirms, read-only mode) are conveniences, not guarantees.`,dataLoss:`You are responsible for every statement executed through Planche. Back up your data before running anything destructive.`,agree:`I have read and agree to the Terms of Use.`,accepted:`You accepted the Terms of Use.`,readFull:`Read the full terms`}},schema:{treeLabel:`Schema`,unreachableHint:`Not the database this connection is bound to; create a profile for it to browse it`,objectType:{table:`Table`,view:`View`,procedure:`Procedure`,function:`Function`,trigger:`Trigger`,event:`Event`},menu:{showCreate:`Show Create {{type}}`,alter:`Alter {{type}}`,drop:`Drop {{type}}`,create:`Create {{type}}`,refresh:`Refresh`,unreachable:`Connect with a profile bound to this database to browse it`,openDatabase:`Open Database`,createSchema:`Create Schema…`,createTable:`Create Table`,dropDatabase:`Drop Database`,openSchema:`Open Schema`,dropSchema:`Drop Schema`,newQueryTab:`New Query Tab`,generateSql:`Generate SQL`,openTable:`Open Table`,alterTable:`Alter Table`,showCreateTable:`Show Create Table`,duplicateStructure:`Duplicate Structure`,copyTable:`Copy Table to…`,compare:`Compare {{type}}…`,truncateTable:`Truncate Table`,dropTable:`Drop Table`,exportCsv:`Export to CSV`,exportTsv:`Export to TSV…`,openView:`Open View`,alterView:`Alter View`,showCreateView:`Show Create View`,dropView:`Drop View`,compareData:`Compare Data…`,groupBy:`Group and Count…`},actions:{createStatementUnavailable:`-- Could not retrieve CREATE statement for {{type}} {{name}}`,getCreateFailed:`Failed to get CREATE {{type}}: {{message}}`,createTabTitle:`Create {{type}}`,createSchemaTabTitle:`Create Schema`,generateSqlFailed:`Could not generate SQL: {{message}}`,dropTableTitle:`Drop table "{{name}}"?`,dropTableDescription:`This permanently deletes the table and every row in it{{from}}. This cannot be undone.`,dropTableConfirm:`Drop table`,dropObjectTitle:`Drop {{type}} "{{name}}"?`,dropObjectDescription:`The {{type}} definition will be removed{{from}}. This cannot be undone.`,dropObjectConfirm:`Drop {{type}}`,fromDatabase:` from database "{{database}}"`,dropped:`Dropped {{type}} {{name}}`,dropFailed:`Failed to drop {{type}}`,dropDatabaseTitle:`Drop database "{{name}}"?`,dropDatabaseDescription:`This permanently deletes the database with all of its tables and data. This cannot be undone.`,dropDatabaseConfirm:`Drop database`,droppedDatabase:`Dropped database {{name}}`,dropDatabaseFailed:`Failed to drop database`,dropSchemaTitle:`Drop schema "{{name}}"?`,dropSchemaDescription:`This permanently deletes the schema with all of its tables and data. This cannot be undone.`,dropSchemaConfirm:`Drop schema`,droppedSchema:`Dropped schema {{name}}`,dropSchemaFailed:`Failed to drop schema`,truncateTitle:`Truncate table "{{name}}"?`,truncateDescription:`Every row in "{{name}}" will be deleted. The table structure is kept. This cannot be undone.`,truncateConfirm:`Truncate table`,truncated:`Truncated {{name}}`,truncateFailed:`Failed to truncate`},tree:{loadDatabasesFailed:`Failed to load databases: {{message}}`}},query:{editor:{destructiveMarker:`Destructive: {{action}} {{names}}`,readOnlyMarker:`Connection is read-only; this statement modifies data or schema`,actionExecute:`Execute (per settings)`,actionExecuteStatement:`Execute Statement at Cursor / Selection`,actionExecuteScript:`Execute Whole Script`,actionExplainPlan:`Explain Plan`,actionQueryStructure:`Query Structure`},tabs:{newQuery:`New Query`,queryTitle:`Query {{n}}`,erdViewer:`ERD Viewer`,close:`Close`,closeOthers:`Close Others`,closeLeft:`Close Tabs to the Left`,closeRight:`Close Tabs to the Right`,closeAll:`Close All`},executor:{noActiveConnection:`No active connection`,uncommittedTitle:`Uncommitted transaction`,uncommittedDescription:`This connection has an open transaction. Disconnecting will roll back its changes.`,uncommittedConfirm:`Rollback and disconnect`,unsavedTitle:`Unsaved changes`,unsavedDescription:`{{file}} has changes that were not saved to its file. Disconnecting discards them (use Connection > Save Database File first to keep them).`,theSqliteDatabase:`The SQLite database`,unsavedConfirm:`Discard and disconnect`}},result:JSON.parse('{"tabs":{"message":"Message","info":"Info","history":"History","result":"Result","resultN":"Result {{n}}","plan":"Plan","structure":"Structure","structureN":"Structure {{n}}"},"message":{"executing":"Executing query...","error":"Error: {{message}}","total":" (Total: {{ms}}ms)","ready":"Ready.","log":"Execution log","statementN":"Statement {{n}}","limitedBadge":"limit hit","insertId":"insert id {{id}}","failed":"Failed","failedStatement":"Failed statement","summary":"{{ok}} succeeded · {{failed}} failed · {{ms}} total","copy":"Copy","copied":"Copied","showSql":"Show SQL","hideSql":"Hide SQL"},"hints":{"title":"Hint","unknownColumn":"No column named {{name}} here. Did you mean {{suggestions}}?","unknownTable":"No table named {{name}} here. Did you mean {{suggestions}}?","syntaxSwap":"{{engine}} writes {{expected}} where this uses {{found}}.","doubleQuotedLiteral":"{{engine}} reads \\"{{value}}\\" as a column name, not text. Write \'{{value}}\' for a string."},"ai":{"title":"AI explanation","explain":"Explain with AI","thinking":"Reading the failure…","by":"by {{model}}","applyFix":"Open the fix in a new tab","failed":"Could not explain this: {{message}}","noFailure":"There is no failed statement to explain.","noPack":"The prompt could not be fetched from planche.dev.","badShape":"The model did not answer in the expected shape.","noPlan":"There is no plan to explain yet.","explainPlan":"Explain this plan"},"info":{"empty":"No query information available.","resultN":"Result {{n}}","metadata":"Query Metadata","executionTime":"Execution Time","notAvailable":"N/A","affectedRows":"Affected Rows","fields":"Fields","fieldDetails":"Field Details","colName":"Name","colType":"Type","colTable":"Table","resultSets":"Result Sets","rowsReturned":"Rows Returned","insertId":"Last Insert ID","lastQuery":"Last executed statement","copy":"Copy","copied":"Copied","colOrigin":"Origin","primaryKey":"Primary key","rowsAndFields":"{{rows}} rows × {{fields}} fields","noFields":"This statement returned no columns."},"rowForm":{"colColumn":"Column","colValue":"Value","insertTitle":"Insert row","editTitle":"Edit row","loading":"Loading columns...","preview":"Statement","nothingToWrite":"Nothing to write","insert":"Insert","update":"Update","stageInsert":"Add as pending row","stageEdit":"Apply to grid","stageHint":"Put the values in the grid without running anything; commit later with the other edits.","inserted":"Row inserted into {{table}}","updated":"Row updated in {{table}}","confirmInsertTitle":"Insert a row into {{table}}?","confirmUpdateTitle":"Update a row in {{table}}?","inTransaction":"Runs inside the open transaction","pickDate":"Pick a date","now":"Now","formatJson":"Format","binaryUnsupported":"Binary columns cannot be edited here; leave NULL / DEFAULT or set them with SQL.","generateUuid":"Generate UUID","defaultValue":"Default value","clickToChange":"Click to change","empty":"(empty)","autoHint":"Generated by the server","mode":{"keep":"Keep","auto":"Auto","value":"Value"},"invalid":{"integer":"Enter a whole number","unsigned":"This column does not accept negative numbers","number":"Enter a number","json":"Invalid JSON","date":"Use YYYY-MM-DD","datetime":"Use YYYY-MM-DD HH:MM:SS","time":"Use HH:MM:SS","length":"At most {{max}} characters"}},"history":{"copied":"Copied to clipboard","searchPlaceholder":"Search history...","all":"All","success":"Succeeded","failed":"Failed","thisTab":"This tab only","noMatch":"No entries match.","count":"{{count}} entries","clear":"Clear","clearTitle":"Clear query history?","clearDescription":"All {{count}} entries for this connection will be removed. This cannot be undone.","clearConfirm":"Clear history","insert":"Insert into editor","inserted":"Inserted into the editor","copy":"Copy","rows":"{{count}} rows","affected":"{{count}} affected","today":"Today","yesterday":"Yesterday","empty":"No query history."},"json":{"arrayLength":"Array[{{count}}]","keys_one":"{{count}} key","keys_other":"{{count}} keys","invalid":"Invalid JSON","clickToView":"Click to view JSON","expandAll":"Expand all","collapseAll":"Collapse all","edit":"Edit","view":"View","copied":"Copied","copy":"Copy","shortcutHint":"{{mod}}+Enter to save · Esc to cancel","cancel":"Cancel","save":"Save"},"text":{"clickToView":"Click to view text","size":"{{chars}} chars · {{lines}} lines","wrap":"Wrap"},"grid":{"readOnlyConnection":"Read-only connection","readOnlyWal":"Read-only: -wal file not loaded","readOnlyNoPk":"Read-only: table has no primary key","commitTitle":"Commit {{count}} change(s) to {{table}}?","commitDescription":"The following statements will be executed.","commitConfirm":"Commit","rowPrefix":"Row {{row}}:","cancelled":"cancelled","commitFailed":"Commit failed: {{message}}","executedInTransaction":"Executed {{count}} change(s) inside the open transaction — press Commit in the toolbar to make them permanent (reloading rolls them back)","committed":"Committed {{count}} change(s) to {{table}}","noData":"No data to display.","commit":"Commit","discard":"Discard","addRow":"Add row","removeNewRow":"Cancel this new row","addRowForm":"Add with form","addRowFormHint":"Open a form with an input per column (committed as INSERT)","editRowForm":"Edit this row in a form","addRowHint":"Add a new row (committed as INSERT)","delete":"Delete","deleteCount":"Delete ({{count}})","deleteHint":"Delete the selected rows (committed as DELETE). Select rows with the row-number column.","field":"Field","searchPlaceholder":"Search...","orderBy":"Order by","none":"None","refresh":"Refresh","dismiss":"Dismiss","clearSelection":"Clear selection","columns":"Columns","showAllColumns":"Show all","hideAllColumns":"Hide all","resetWidths":"Reset widths","selectAll":"Select all rows","emptyTable":"This table has no rows.","noRows":"No rows returned.","addARow":"Add a row","markedForDeletion":"Marked for deletion — click to restore","newRow":"New row","clickToSelect":"Click to select; Shift/Ctrl for multiple","rows":"Rows: {{count}}","rowsWithNew":"Rows: {{count}} (+{{added}})","sortedBy":"Sorted by: {{column}} {{direction}}","pageRange":"Rows {{from}}–{{to}}","firstPage":"First page","prevPage":"Previous page","nextPage":"Next page","lastPage":"Last page","pagingBlocked":"Commit or discard your changes before changing page","selected":"{{count}} selected","cellsModified":"{{count}} cell(s) modified","newCount":"{{count}} new","toDelete":"{{count}} to delete","searchMode":"Match mode","contains":"contains","equals":"equals","followLink":"Open {{table}} where {{column}} = value","linkColumn":"Link \\"{{column}}\\" to another table…","editLink":"Edit link of \\"{{column}}\\"…","removeLink":"Remove link","copyValue":"Copy value","filterByValue":"Filter: {{column}} = this value","clearFilter":"Clear filter","copyColumnName":"Copy column name","editCell":"Edit cell","setNull":"Set NULL","setEmpty":"Set empty string","restoreRow":"Restore row","hideColumn":"Hide column \\"{{column}}\\"","copyRowsTsv_one":"Copy row as TSV (with header)","copyRowsTsv_other":"Copy {{count}} rows as TSV (with header)","copyRowsCsv_one":"Copy row as CSV","copyRowsCsv_other":"Copy {{count}} rows as CSV","copyRowsJson_one":"Copy row as JSON","copyRowsJson_other":"Copy {{count}} rows as JSON","copyRowsInsert_one":"Copy row as INSERT","copyRowsInsert_other":"Copy {{count}} rows as INSERT","deleteRowsPending_one":"Delete row (pending until Commit)","deleteRowsPending_other":"Delete {{count}} rows (pending until Commit)","sendRowsToScratchpad_one":"Send row to scratchpad","sendRowsToScratchpad_other":"Send {{count}} rows to scratchpad","sendAllToScratchpad":"Send all {{count}} loaded rows to scratchpad","sentToScratchpad":"{{count}} rows copied into scratchpad table {{table}}.","changesSince":"Since last load: {{changed}} changed · {{added}} new · {{gone}} gone","changesToggle":"Toggle highlighting of what changed since the previous load","changesDismiss":"Forget these changes","previousValue":"Previous value: {{value}}","groupByValue":"Group and count by {{column}}"},"link":{"title":"Link column to another table","source":"Column","hint":"Values of this column become links: clicking one opens the target table filtered to the matching row(s). Real foreign keys are linked automatically.","targetDatabase":"Target database","targetTable":"Target table","targetColumn":"Target column","pickTable":"Choose a table","pickColumn":"Choose a column","remove":"Remove link","cancel":"Cancel","save":"Save link","targetConnection":"Target connection","targetNotConnected":"The linked connection is not open. Connect it first."},"running":{"label":"Querying…","elapsed":"{{seconds}}s","stop":"Stop","stopping":"Stopping…","cannotCancel":"This engine cannot interrupt a statement once it is running.","agentOutdated":"The local agent is too old to stop a query. Update it with `npx planche@latest` (or `planche upgrade`) and reconnect.","cancelFailed":"The agent could not be reached to stop the query.","abandoned":"Stopped waiting for the request. This engine has no cancel of its own, so the query may still finish upstream."},"plan":{"empty":"Run Explain Plan (Ctrl+Shift+E) to see how the engine will execute the statement at the cursor.","unreadable":"The plan could not be read as a tree; the engine output is shown as-is.","estimated":"Estimated","analyzed":"Measured","estimatedHint":"The planner’s estimates. The statement was not executed.","analyzedHint":"The statement was executed; row counts and timings are real.","totalCost":"Highest node cost","totalTime":"Slowest node","rows":"Estimated rows","actualRows":"Actual rows","cost":"Cost","time":"Time","showRaw":"Raw output","showTree":"Plan tree","selectNode":"Select a node to see what the engine reported about it.","noDetails":"The engine reported nothing else about this node.","warnings":{"fullScan":"Full scan","noIndex":"No index","estimateOff":"Estimate off","temporary":"Temp table","filesort":"Sort"},"hints":{"fullScan":"Every row of the table is read. An index on the filtered columns would avoid it.","noIndex":"The engine found no usable index for this access.","estimateOff":"The planner expected a very different number of rows. Refreshing table statistics often fixes the plan.","temporary":"Rows are materialized into a temporary table before the next step.","filesort":"Rows are sorted outside an index. An index matching the ORDER BY would remove the sort."}},"structure":{"empty":"Show Query Structure (Ctrl+Shift+G) to see where the rows of the statement at the cursor come from.","notQuery":"Only SELECT statements have a structure graph.","unsupported":"{{engine}} statements cannot be read as a structure graph.","parseError":"The statement could not be parsed: {{message}}","columns_one":"{{count}} column","columns_other":"{{count}} columns","columnsUnknown":"width unknown","fit":"Fit","reveal":"Select this in the editor","notDrawn":"Not drawn: {{what}}","kindTable":"TABLE","kindCte":"CTE","kindCteRef":"REF","kindDerived":"SUBQUERY","kindScalar":"SCALAR","kindSetop":"SET","kindResult":"RESULT","fullscreen":"Fullscreen","exitFullscreen":"Exit fullscreen"}}'),confirm:{defaultDescription:`This action cannot be undone.`,typeToConfirm:`Type <name/> to confirm`,cancel:`Cancel`,confirm:`Confirm`,ok:`OK`},table:{dialog:{createTitle:`Create Table`,alterTitle:`Alter Table`,duplicateTitle:`Duplicate Table Structure`,create:`Create`,alter:`Alter`,cancel:`Cancel`,tableName:`Table Name`,tableNamePlaceholder:`Enter table name...`,loading:`Loading table schema...`,tabSchema:`Schema`,tabIndexes:`Indexes`,tabProperties:`Properties`,applying:`Applying…`,cannotAlterColumns:`{{engine}} cannot change a column that already exists ({{columns}}). Adding, dropping and renaming columns and changing indexes all work; to change a column definition, recreate the table.`},schema:{colField:`Field Name`,colType:`Datatype`,colLength:`Length`,colDefault:`Default`,colPk:`PK`,colNotNull:`Not Null`,colUnsigned:`Unsigned`,colAutoIncrement:`Auto Incr`,colZerofill:`Zerofill`,colComment:`Comment`,empty:`No columns defined. Click "Add Column" to add one.`,add:`Add Column`,remove:`Remove Column`},indexes:{colName:`Index Name`,colType:`Index Type`,colColumns:`Columns`,empty:`No indexes defined. Click "Add Index" to add one.`,add:`Add Index`,remove:`Remove Index`},index:{addTitle:`Add Index`,editTitle:`Edit Index`,name:`Index Name`,namePlaceholder:`Enter index name`,type:`Index Type`,columns:`Columns`,noColumns:`No columns available. Define columns in the Schema tab first.`,unnamed:`(unnamed)`,cancel:`Cancel`,ok:`OK`},properties:{engine:`Engine`,charset:`Charset`,collation:`Collation`,autoIncrement:`Auto Increment`,autoIncrementPlaceholder:`Default`,comment:`Comment`},info:{engine:`Engine`,version:`Version`,rowFormat:`Row Format`,rows:`Rows`,avgRowLength:`Avg Row Length`,dataLength:`Data Length`,createTime:`Create Time`,updateTime:`Update Time`,collation:`Collation`,comment:`Comment`},copy:{title:`Copy Table`,source:`Source`,targetConnection:`Target connection`,targetDatabase:`Target database`,targetTable:`Target table name`,what:`Copy`,structureAndData:`Structure & data`,structureOnly:`Structure only`,ifExists:`If the target table exists`,abort:`Abort (default)`,dropAndRecreate:`Drop and recreate (asks to retype the name)`,preview:`CREATE TABLE on the target (editable)`,crossEngineHint:`The target is {{engine}}: review the types below, MySQL-specific attributes were dropped.`,readOnly:`read-only`,loading:`Loading…`,progressCreate:`Creating table…`,progressCount:`Counting rows…`,progressRows:`Copied {{copied}} of {{total}} rows`,progressDone:`Done`,doneTitle:`Table copied`,doneRows:`{{count}} rows copied into {{table}}.`,doneStructure:`Structure of {{table}} created.`,noColumns:`The source table has no columns.`,exists:`Table {{table}} already exists in the target. Choose another name or "Drop and recreate".`,dropTitle:`Drop existing table {{table}}?`,dropDescription:`The target table and all of its rows will be dropped before the copy. This cannot be undone.`,dropConfirm:`Drop and copy`,cancelled:`Copy cancelled.`,stop:`Stop`,cancel:`Cancel`,copy:`Copy`}},database:{copy:{title:`Copy Database`,source:`Source Database`,target:`Target Database Name`,targetPlaceholder:`Enter target database name`,options:`Options`,structureAndData:`Structure & Data`,structureOnly:`Structure Only`,cancel:`Cancel`,copy:`Copy`,creating:`Creating {{database}}…`,copying:`Copying {{table}} ({{index}} of {{total}})…`},diff:{title:`Compare Schemas`,source:`Source`,target:`Target`,pickConnection:`Connection`,pickDatabase:`Database`,crossEngineHint:`Different engines: type names differ by dialect, so most columns will show a type change.`,sameSide:`Source and target are the same database.`,summary:`{{changed}} changed, {{missingTarget}} missing in target, {{missingSource}} only in target, {{identical}} identical`,showIdentical:`Show identical tables`,identicalAll:`The tables are identical.`,column:`Column`,index:`Index`,object:`Object`,selectTable:`Select a table to see its differences.`,missingInTarget:`{{table}} does not exist in the target; the script creates it.`,missingInSource:`{{table}} exists only in the target; the script drops it (commented out unless DROPs are included).`,includeDrops:`Include DROP statements as live SQL (default: commented out)`,tabTitle:`Sync {{database}}`,close:`Close`,compare:`Compare`,comparing:`Comparing…`,openScript:`Open script in editor`,noDefinition:`No CREATE statement available`},create:{title:`Create Database`,name:`Database Name`,namePlaceholder:`Enter database name`,charset:`Character Set`,collation:`Collation`,cancel:`Cancel`,create:`Create`},csv:{title:`Download to {{format}}`,target:`Target`,targetQueryResult:`Current Query Result`,targetTableData:`Table Data`,tableName:`Table Name`,tableNamePlaceholder:`Enter table name`,delimiter:`Delimiter`,delimiterComma:`Comma (,)`,delimiterTab:`Tab (\\t)`,delimiterSemicolon:`Semicolon (;)`,delimiterPipe:`Pipe (|)`,includeHeaders:`Include Headers`,cancel:`Cancel`,download:`Download`,downloading:`Downloading...`,progress:`{{loaded}} of {{total}} rows written`,progressUnknown:`{{loaded}} rows written`,stop:`Stop`,done:`Exported {{count}} rows of {{table}} to {{format}}.`,database:`Database`,databasePlaceholder:`Choose a database`},html:{title:`Schema to HTML`,database:`Database`,selectDatabase:`Select database`,tables:`Tables to Include`,selectAll:`Select All`,deselectAll:`Deselect All`,noTables:`No tables available.`,include:`Include`,includeColumns:`Columns`,includeIndexes:`Indexes`,includeProperties:`Properties`,cancel:`Cancel`,generate:`Generate`,generating:`Generating...`,sectionColumns:`Columns`,sectionIndexes:`Indexes`,sectionProperties:`Properties`,docTitle:`Schema: {{database}}`,heading:`Database: {{database}}`,summary:`Tables: {{count}} | Generated: {{date}}`,footer:`Generated by Planche 2026`},dataDiff:{title:`Compare Data`,pickTable:`Table`,hint:`Rows are matched by the source table's primary key and compared as text. Up to {{cap}} rows per side are loaded; narrow big tables with a filter first.`,sameSide:`Source and target are the same table.`,noPrimaryKey:`{{table}} has no primary key; the comparison needs one to match rows.`,keyMissingInTarget:`The target table lacks the key column(s): {{columns}}`,summary:`Key: {{key}} — {{added}} missing in target, {{changed}} different, {{removed}} only in target, {{identical}} identical`,capped:`Only the first {{cap}} rows of each side were compared.`,ignoredColumns:`Columns ignored (one side only): {{columns}}`,added_one:`{{count}} missing in target`,added_other:`{{count}} missing in target`,changed_one:`{{count}} different`,changed_other:`{{count}} different`,removed_one:`{{count}} only in target`,removed_other:`{{count}} only in target`,none:`Nothing in this group.`,more:`… {{count}} more not listed`,includeDeletes:`Include DELETE statements as live SQL (default: commented out)`,tabTitle:`Sync data {{table}}`,loading:`Loading rows — source: {{source}}, target: {{target}}`},schema:{createTitle:`Create Schema`,name:`Schema name`,namePlaceholder:`Enter schema name`,create:`Create`,cancel:`Cancel`},groupBy:{title:`Group and Count`,description:`Count rows of {{table}} by the columns you pick.`,columns:`Group by`,aggregate:`Extra aggregate`,countOnly:`Count only`,column:`Column`,minCount:`Minimum rows per group`,useFilter:`Apply the grid's current filter`,noIndexWarning:`No grouped column leads an index, so the database has to read and sort the whole table. On a large table that can take a while.`,preview:`Query`,pickColumn:`Pick at least one column to group by.`,openInTab:`Open in new tab`,run:`Run`,tabTitle:`Group {{table}}`,indexed:`Leads an index`,connection:`Connection`,database:`Database`,table:`Table`}},user:{manager:{title:`User Manager`,addUser:`Add User`,removeUser:`Remove User`,noUsers:`No users loaded`,grantScope:`Grant Scope`,apply:`Apply`,close:`Close`,removed:`User '{{user}}'@'{{host}}' removed`,selectUserFirst:`Please select a user first`,applied:`Changes applied successfully`,noChanges:`No privilege changes to apply.`},add:{title:`Add User`,username:`Username`,usernamePlaceholder:`Enter username`,host:`Host`,password:`Password`,passwordPlaceholder:`Enter password`,confirmPassword:`Confirm Password`,confirmPasswordPlaceholder:`Confirm password`,plugin:`Plugin`,cancel:`Cancel`,add:`Add`,usernameRequired:`Username is required`,passwordMismatch:`Passwords do not match`,added:`User '{{user}}'@'{{host}}' added`},privileges:{globalTitle:`Global Privileges`,databaseTitle:`Database Privileges`,tableTitle:`Table Privileges`,checkAll:`Check All`,uncheckAll:`Uncheck All`,categoryData:`Data`,categoryStructure:`Structure`,categoryAdministration:`Administration`},grantTree:{globalPrivileges:`Global Privileges`}},command:{close:`Close`,noActiveConnection:`No active connection`,variableName:`Variable Name`,value:`Value`,scope:{session:`Session`,global:`Global`},findReplace:{findPlaceholder:`Find`,replacePlaceholder:`Replace`,found:`{{count}} found`,noResults:`No results`,previous:`Previous`,next:`Next`,close:`Close`,replace:`Replace`,all:`All`,caseSensitive:`Case Sensitive`,regex:`Regex`,wholeWord:`Whole Word`},flush:{title:`Flush`,executed:`Executed: {{command}}`,executeError:`Error executing {{command}}: {{message}}`},localHistory:{title:`Local History`,description:`Versions of the editor text for this connection: on each run, after a pause in typing, and when a tab is closed.`,empty:`No versions recorded yet.`,noMatch:`No version matches this search.`,notPersisted:`“Keep query history across reloads” is off in Settings > Safety, so versions are kept for this session only.`,searchPlaceholder:`Search versions`,scopeTab:`This tab`,scopeAll:`All tabs`,compareCurrent:`vs current`,comparePrevious:`vs previous`,diffAgainstCurrent:`Compared with the current editor text`,diffAgainstPrevious:`Compared with the version from {{time}}`,noPrevious:`No earlier version of this tab to compare with`,restored:`Editor content restored from local history`,restore:`Restore this version`,openInNewTab:`Open in new tab`,openedInTab:`Version opened in a new tab`,delete:`Delete this version`,clearAll:`Clear history`,chars:`{{count}} chars`,reason:{execute:`before run`,edit:`while editing`,replaced:`before overwrite`,restore:`before restore`,close:`before close`}},processList:{title:`Process List`,refresh:`Refresh`,autoRefresh:`Auto-refresh`,empty:`No processes to display`,kill:`Kill`,killProcess:`Kill Process`,selectToKill:`Please select a process to kill`,killed:`Process {{id}} killed successfully`,killError:`Error killing process: {{message}}`,loadError:`Error loading process list: {{message}}`,updatedAt:`updated {{time}}`,filterPlaceholder:`Filter by user, host, db, SQL...`,hideIdle:`Hide idle`,noMatch:`No processes match the filter`,self:`me`,selfHint:`This is Planche's own session`,statementOf:`Statement of #{{id}}`,noStatement:`No statement`,copy:`Copy`,copied:`Copied`,killConfirmTitle:`Kill process {{id}}?`,killConfirmDescription:`The session of {{user}}@{{host}} will be terminated and its running statement aborted. An open transaction is rolled back.`,stats:{total:`Total`,active:`Active`,idle:`Idle`,longest:`Longest running`},columns:{id:`Id`,user:`User`,host:`Host`,db:`db`,command:`Command`,time:`Time`,state:`State`,info:`Info`,action:`Action`}},status:{title:`Server Status`,filterPlaceholder:`Filter status variables...`,empty:`No status variables to display`,loadError:`Error loading status: {{message}}`},variables:{title:`Server Variables`,filterPlaceholder:`Filter variables...`,empty:`No variables to display`,loadError:`Error loading variables: {{message}}`}},erd:{empty:{title:`Open a Prisma schema file (.prisma) to view the ERD`,description:`Models, enums, and relations will be automatically analyzed`,openFile:`Open .prisma File`,dropHint:`or drag and drop a file onto this area`},entity:{enumBadge:`ENUM`,modelBadge:`MODEL`,columns:{value:`Value`,comment:`Comment`,type:`Type`,column:`Column`},linkBadge:`LINK`,externalTitle:`Linked table on {{location}} (column link, not a real foreign key)`,nullable:`Nullable column`},toolbar:{refresh:`Refresh`,zoomIn:`Zoom In`,zoomOut:`Zoom Out`,resetView:`Reset View`,center:`Center`,fitAll:`Fit All`,spreadAll:`Untangle`,resetLayout:`Reset Layout`,legendOneToMany:`1:N (FK)`,tables:`Tables:`,relations:`Relations:`,columns:`Columns:`,fullscreen:`Fullscreen`,exitFullscreen:`Exit fullscreen`},viewer:{noServerConnection:`No active server connection`,loading:`Loading schema from {{database}}...`,loadFailed:`Failed to load ERD`,noDatabase:`No database selected.`,selectDatabaseHint:`Select a database in the Schema Tree, then open View ERD.`}},services:{runAnyway:`Run anyway`,query:{rowsReturned:`{{count}} row(s) returned`,rowsAffected:`{{count}} row(s) affected`,rowsReturnedLimited:`{{count}} row(s) returned (limited to {{limit}}; add LIMIT to fetch more)`,notConnected:`Not connected`,fileNotOpen:`The SQLite file is not open yet — click "Reopen file" above to grant access again.`,failed:`Query failed`,nothingToExecute:`Nothing to execute`,dryRunMismatch:`Dry run expected {{predicted}} rows, {{actual}} were changed. The data may have changed since the preview was read; if it did not, the preview did not match this statement.`},destructive:{title_one:`Run destructive statement?`,title_other:`Run {{count}} destructive statements?`,description:`The following will permanently modify or delete data. This cannot be undone.`,unknownTarget:`(unknown)`,deleteAll:`DELETE all rows from {{target}}`,updateAll:`UPDATE all rows in {{target}}`,alterDrop:`DROP COLUMN/PARTITION on {{target}}`},readOnly:{refused:`Connection "{{label}}" is read-only. {{count}} statement(s) would modify data or schema.`,title:`"{{label}}" is read-only`,description:`These statements modify data or schema. Run them on this connection anyway?`},transaction:{startFailed:`Could not start transaction`,started:`Transaction started — Commit or Rollback when done`,implicitCommit:`{{kind}} caused an implicit COMMIT of the open transaction`,committed:`Transaction committed`,rolledBack:`Transaction rolled back`,commandFailed:`{{name}} failed`,commandFailedWith:`{{name}} failed: {{message}}`},save:{notBrowserSqlite:`Not a browser SQLite connection.`,inMemory:`In-memory database: it can only be exported as a download.`,noFileSystemAccess:`This browser has no File System Access API (Chrome/Edge only): the database is exported as a download instead of written in place.`,noWritableHandle:`The file was opened without a writable handle: it is exported as a download.`},agent:{devProxyUrl:`{{url}} (via dev proxy)`,notPlanche:`Something answered, but it is not a Planche agent`,unreachable:"Planche agent unreachable at {{url}} — run `npx planche` ({{message}})",httpError:`HTTP error: {{status}} {{statusText}}`,emptyResponse:`Tunneling server returned an empty response`,reconnected:`Reconnected to {{name}} — the agent had dropped the connection (restart or idle timeout).`},sample:{profileName:`Sample shop (in-browser)`,downloadFailed:`Could not download the sample database ({{status}})`,tabTitle:`Query 1`},sqliteFile:{tooSmall:`File is too small to be a SQLite database.`,notSqlite:`Not a SQLite database (or an encrypted one, e.g. SQLCipher). The 16-byte header does not read "SQLite format 3".`,badPageSize:`Corrupt SQLite header: invalid page size {{size}}.`,unreadable:`SQLite could not read the file: {{message}}`,pickerDescription:`SQLite database`,walNotLoaded:`This database is in WAL mode and its -wal file was not loaded. Load it, or confirm in the banner that no -wal file exists, before saving.`,changedOnDisk:`{{name}} changed on disk after it was loaded (another program wrote to it). Saving would overwrite those changes — reopen the file and redo your edits, or use the tunneling server.`,walHasChanges:`{{name}}-wal contains new changes; load it before saving.`,walChangedOnDisk:`{{name}}-wal was written by another program after it was loaded; reopen the file before saving.`,writeDenied:`Write access to {{name}} was not granted. Allow it in the browser prompt, or export as a download instead.`},environment:{none:`None`,green:`Green (dev)`,blue:`Blue`,yellow:`Yellow (staging)`,orange:`Orange`,red:`Red (production)`,purple:`Purple`},scratchpad:{profileName:`Scratchpad`,namePromptTitle:`Scratchpad table name`,namePromptDescription:`A table named {{table}} already exists in the scratchpad. Choose another name.`,nameTaken:`Table {{table}} already exists.`},federated:{pulling:`Pulling {{table}} from {{connection}}…`,capped:`{{table}}: only the first {{limit}} rows were pulled.`,templateLine1:`Reference a table of any open connection as "Connection name".database.table; it is copied into this scratchpad before the statement runs.`,templateLine2:`Tables are capped at {{limit}} rows. The query itself runs in SQLite (in your browser).`,templateConnections:`Open connections: {{names}}`,templateNone:`No other connection is open yet. Connect one, then reference it here.`,done:`Pulled {{rows}} rows from {{tables}} remote tables into the scratchpad.`,pullingProgress:`Pulling {{table}} from {{connection}}: {{loaded}} / {{total}} rows…`},paged:{noColumns:`{{table}} has no columns.`,cancelled:`Cancelled.`}},terms:{title:`Terms of Use`,version:`Version {{version}}`,englishOnly:`The terms are provided in English. The summary on the welcome screen is available in your language.`,privacyLink:`Privacy policy`,refundLink:`Refund policy`,online:`Read on planche.dev`,updated:`Last updated {{date}}`},dryRun:{title:`{{kind}} would affect {{count}} rows`,titleUnknown:`{{kind}} — affected rows unknown`,description:`These are the rows the statement would touch right now, read with a SELECT. Nothing has been written yet.`,previewFailed:`The preview query failed: {{error}}
2
- You can still run the statement.`,noRows:`No rows match — the statement would change nothing.`,truncated:`Showing the first {{shown}} of {{count}} rows.`,previewQuery:`Preview query`,run:`Run {{kind}} ({{count}} rows)`,runAnyway:`Run anyway`},pro:{badge:`PRO`,tooltip:`Requires a Pro licence.`,noticeTitle:`Pro features`,notice:`Features marked PRO need a Pro licence.`,licenseTitle:`Planche Pro`,licenseDescription:`Paste the licence key from your purchase email. It is checked on this computer; nothing is sent anywhere.`,blocked:`{{feature}} needs a Pro licence.`,keyLabel:`Licence key`,activate:`Activate`,remove:`Remove licence`,active:`Pro is active.`,licensedTo:`Licensed to {{email}}`,validUntil:`Valid until {{date}}`,expiredOn:`This licence ran out on {{date}}. Renew it to keep using Pro features.`,invalidKey:`That is not a Planche licence key.`,notConfigured:`This build cannot check licence keys. Please report it.`,noWebcrypto:`This browser cannot check licence keys.`,pricing:`See pricing`,features:{ssh_tunnel:`SSH tunnels`,compare_schemas:`Compare Schemas`,compare_data:`Compare Data`,copy_table:`Copy Table`,dry_run:`Dry run`,federated:`Federated queries`,scratchpad:`Scratchpad`,column_link:`Column links`,sync:`Connection sync`,ai_explain:`AI explanations`},included:`Pro includes`,haveKey:`Already have a licence key?`,perMonth:`/ month`,priceNote:`Billed {{annual}} once a year. Month to month is {{monthly}}.`,featureDetails:{sync:`Your profiles on every computer, encrypted in the browser before they leave it`,ssh_tunnel:`Reach a database behind a jump host with a password, a key or ssh-agent`,compare_schemas:`Diff two open connections and get the ALTER script`,compare_data:`Diff rows between two tables and get the INSERT and UPDATE script`,copy_table:`Rebuild a table on another connection, or another engine`,dry_run:`See how many rows an UPDATE or DELETE changes, and which, before it runs`,federated:`Join tables that live in different connections`,scratchpad:`A local SQLite database for working data`,column_link:`Virtual foreign keys you can follow in the grid`,ai_explain:`Ask a model why a statement failed, or why a plan is slow — with your schema attached`}},install:{npxNote:`Needs Node.js 22 or newer. Nothing is installed permanently — npx runs the agent straight from the npm registry.`,installNote:`No Node.js needed. It installs under your home directory without an administrator; afterwards the planche command starts it any time.`},explain:{unsupported:`{{engine}} does not report query plans.`,oneStatement:`Explain works on one statement at a time. Put the cursor in the statement to explain, or select it.`},ai:{title:`AI assistant`,intro:`Ask for a query, or tell it what to do — it reads the schema, writes SQL into a tab and runs it. It works on the connection you have open, and each one keeps its own conversation.`,privacy:`What the tools read — including sample rows — is sent to your provider. Nothing reaches planche.dev.`,placeholder:`e.g. build a monthly revenue query on the demo database`,send:`Send`,stop:`Stop`,clear:`New conversation`,working:`Working…`,tabTitle:`AI query`,approvalTitle:`This one writes. Run it?`,approve:`Run`,reject:`Skip`,rejected:`The user declined to run this.`,notConfigured:`No AI key is set on the agent. Add one in Settings ▸ AI.`,needsAgent:`This local agent cannot run tools yet. Update it and pair again.`,failed:`Failed`,empty:`Nothing asked yet.`,steps:`{{count}} steps`,tooManySteps:`Stopped after {{count}} steps without reaching an answer.`,collapse:`Collapse`,planWarningTitle:`That query is a full scan. Run it anyway?`,interrupted:`Interrupted by a reload.`,external:`Asked for from outside Planche`},mcp:{title:`Connect an AI agent (MCP)`,description:`Let an AI agent that speaks MCP use Planche's tools.`,readsLabel:`Reads`,reads:`It reads the open database, and the results go to that program.`,writesLabel:`Writes`,writes:`A statement that writes data needs your approval. DROP and TRUNCATE it cannot run.`,needsLabel:`Needs`,needs:`The AI panel has to be open.`,tokenLabel:`Token`,token:`One token, shared by every program you give it to. Revoking it disconnects them all.`,command:`Add to Claude Code`,json:`Configure by hand`,stored:`Stored at {{path}}.`,revoke:`Revoke token`,revoked:`Revoked. Open this again to issue a new one.`},sync:{title:`Connection sync`,description:`Your connection profiles, encrypted in this browser and kept on planche.dev so your other computers can use them.`,stored:`The service stores one encrypted blob. It cannot read your hosts, users, passwords or SSH keys.`,unavailable:`Sync runs on planche.dev only. This copy of Planche is served by your local agent, which is not allowed to reach out to the internet.`,signIn:`Sign in with GitHub`,signedInAs:`Signed in as {{email}}`,signOut:`Sign out`,createTitle:`Choose a passphrase`,createHint:`This passphrase is what encrypts your profiles. It never reaches the server, so if you lose it the stored copy cannot be recovered — only re-created from a computer that still has your profiles.`,passphrase:`Passphrase`,confirm:`Confirm passphrase`,mismatch:`The two passphrases do not match.`,tooShort:`Use at least {{count}} characters.`,enable:`Turn on sync`,unlockTitle:`Unlock your profiles`,unlockHint:`Enter the passphrase you chose when you turned sync on.`,unlock:`Unlock`,wrongPassphrase:`Wrong passphrase, or the stored copy is damaged.`,syncNow:`Sync now`,lastSynced:`Last synced {{when}}`,neverSynced:`Not synced yet`,profiles_one:`{{count}} profile`,profiles_other:`{{count}} profiles`,changePassphrase:`Change passphrase`,deleteVault:`Delete from server`,deleteVaultConfirm:`Remove the encrypted copy from planche.dev? The profiles on this computer are not touched.`,offline:`Cannot reach planche.dev.`,working:`Working…`,serverError:`planche.dev could not complete that. Try again in a moment.`,signInShort:`Sign in`,needsPro:`You are signed in. Syncing your profiles needs a Pro licence — it starts working as soon as you have one.`,deleteAccount:`Delete account`,deleteAccountConfirm:`Delete your account? The stored copy and your sign-in go with it. The profiles on this computer are not touched.`,notDeployed:`Connection sync is not switched on for this site yet.`},desktop:{closeTitle:`Close Planche?`,closeDescription:`There is unsaved work: an open transaction, uncommitted edits or a running query. Closing discards it and rolls back.`,closeAnyway:`Close anyway`}},ae=`modulepreload`,Y=function(e){return`/`+e},X={},Z=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=Y(t,n),t=s(t),t in X)return;X[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:ae,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},Q=[`en`,`ko`,`zh`,`ja`,`de`,`fr`];function $(e=navigator.languages??[navigator.language]){for(let t of e){let e=t.toLowerCase().split(`-`)[0];if(Q.includes(e))return e}return`en`}function oe(e){return e===`auto`?$():e}var se={ko:()=>Z(()=>import(`./BHsXOlR9.js`),[]),zh:()=>Z(()=>import(`./zspOy9D_.js`),[]),ja:()=>Z(()=>import(`./p4yYbMPY.js`),[]),de:()=>Z(()=>import(`./BbdU8Zop.js`),[]),fr:()=>Z(()=>import(`./Cf8o-5U6.js`),[])};K.use(q).init({lng:`en`,fallbackLng:`en`,resources:{en:{translation:J}},interpolation:{escapeValue:!1},returnNull:!1});async function ce(e){let t=oe(e);if(t!==`en`&&!K.hasResourceBundle(t,`translation`)){let e=await se[t]();K.addResourceBundle(t,`translation`,e.default,!0,!0)}K.language!==t&&await K.changeLanguage(t),document.documentElement.lang=t}export{K as a,Z as i,ce as n,j as o,$ as r,Q as t};
@@ -1 +0,0 @@
1
- import{c as e,r as t}from"./B1pia_Rg.js";import{i as n,t as r}from"./eFSiW0Lh.js";var i={anthropic:`claude-opus-5`,"anthropic-profile":`claude-opus-5`,openai:`gpt-4o`,gemini:`gemini-2.5-flash`,cli:`claude`};function a(e,t){let n=e.trim();return n===``||Object.values(i).includes(n)?i[t]:e}var o={confirmDestructive:!0,warnInEditor:!0,previewAffectedRows:!0,allowReadOnlyOverride:!0,previewGridCommit:!0,resultRowLimit:500,executeScope:`script`},s=t()(n(t=>({...o,locale:`auto`,onboardingDismissed:!1,termsAcceptedVersion:0,analyticsEnabled:!0,persistQueryHistory:!0,aiPreferences:{provider:`anthropic`,model:i.anthropic,baseUrl:``,remember:!1},update:e=>t(e),setOnboardingDismissed:e=>t({onboardingDismissed:e}),acceptTerms:()=>{e(`terms_accept`,{version:1}),t({termsAcceptedVersion:1})},setLocale:n=>{e(`locale_change`,{locale:n}),t({locale:n})},setAnalyticsEnabled:e=>t({analyticsEnabled:e}),setPersistQueryHistory:e=>t({persistQueryHistory:e}),setAiPreferences:e=>t(t=>({aiPreferences:{...t.aiPreferences,...e}}))}),{name:`planche-settings`,storage:r()})),c=()=>s(e=>e.termsAcceptedVersion>=1);export{a as i,s as n,c as r,o as t};