@object-ui/i18n 17.6.0 → 18.0.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 (62) hide show
  1. package/CHANGELOG.md +5408 -0
  2. package/README.md +255 -13
  3. package/dist/LocalizationContext.d.ts +32 -9
  4. package/dist/LocalizationContext.js +32 -10
  5. package/dist/builtinAggregateLabels.d.ts +40 -0
  6. package/dist/builtinAggregateLabels.js +23 -0
  7. package/dist/currency.d.ts +27 -3
  8. package/dist/currency.js +28 -4
  9. package/dist/fallbackInterpolation.d.ts +79 -0
  10. package/dist/fallbackInterpolation.js +124 -0
  11. package/dist/i18n.d.ts +27 -1
  12. package/dist/i18n.js +99 -16
  13. package/dist/index.d.ts +8 -13
  14. package/dist/index.js +45 -17
  15. package/dist/locales/ar.d.ts +1504 -188
  16. package/dist/locales/ar.js +1711 -281
  17. package/dist/locales/de.d.ts +1080 -188
  18. package/dist/locales/de.js +1248 -261
  19. package/dist/locales/en.d.ts +1141 -249
  20. package/dist/locales/en.js +1714 -295
  21. package/dist/locales/es.d.ts +1186 -188
  22. package/dist/locales/es.js +1350 -255
  23. package/dist/locales/fr.d.ts +1186 -188
  24. package/dist/locales/fr.js +1351 -258
  25. package/dist/locales/index.d.ts +11940 -2033
  26. package/dist/locales/index.js +48 -9
  27. package/dist/locales/ja.d.ts +1080 -188
  28. package/dist/locales/ja.js +1240 -254
  29. package/dist/locales/ko.d.ts +1080 -188
  30. package/dist/locales/ko.js +1244 -258
  31. package/dist/locales/pt.d.ts +1186 -188
  32. package/dist/locales/pt.js +1350 -255
  33. package/dist/locales/registry.d.ts +102 -0
  34. package/dist/locales/registry.js +220 -0
  35. package/dist/locales/rtl.d.ts +24 -0
  36. package/dist/locales/rtl.js +26 -0
  37. package/dist/locales/ru.d.ts +1292 -188
  38. package/dist/locales/ru.js +1479 -272
  39. package/dist/locales/zh.d.ts +1144 -252
  40. package/dist/locales/zh.js +1245 -259
  41. package/dist/pickLocalized.d.ts +30 -0
  42. package/dist/pickLocalized.js +39 -0
  43. package/dist/provider.d.ts +101 -12
  44. package/dist/provider.js +335 -50
  45. package/dist/translateFn.d.ts +29 -0
  46. package/dist/translateFn.js +8 -0
  47. package/dist/useDisplayLocale.d.ts +11 -0
  48. package/dist/useDisplayLocale.js +11 -0
  49. package/dist/useObjectLabel.d.ts +143 -100
  50. package/dist/useObjectLabel.js +129 -82
  51. package/dist/useSafeTranslation.js +40 -42
  52. package/dist/utils/first-day-of-week.d.ts +71 -0
  53. package/dist/utils/first-day-of-week.js +61 -0
  54. package/dist/utils/formatting.d.ts +23 -1
  55. package/dist/utils/formatting.js +34 -5
  56. package/dist/utils/index.d.ts +1 -0
  57. package/dist/utils/index.js +1 -0
  58. package/dist/utils/spec-formatters.d.ts +13 -23
  59. package/dist/utils/spec-formatters.js +41 -2
  60. package/dist/utils/spec-translations.d.ts +16 -3
  61. package/dist/utils/spec-translations.js +52 -13
  62. package/package.json +12 -6
@@ -13,16 +13,19 @@ const fr = {
13
13
  notRestored: 'Le serveur a accepté la demande mais n’a pas restauré votre session administrateur — vous incarnez toujours {{user}}. Déconnectez-vous puis reconnectez-vous pour y mettre fin.',
14
14
  },
15
15
  },
16
- // objectui#2600 B5 — capability picker scope group headers (labels come from the sys_capability registry).
16
+ // objectui#2600 B5 — capability picker scope group headers (labels come from the capability registry).
17
17
  capability: {
18
18
  label: {
19
19
  manage_users: "Gérer les utilisateurs",
20
20
  manage_org_users: "Gérer les utilisateurs de l'organisation",
21
21
  manage_metadata: "Gérer les métadonnées",
22
+ manage_mailboxes: "Gérer les boîtes aux lettres",
22
23
  manage_platform_settings: "Gérer les paramètres de la plateforme",
23
24
  setup_access: "Accès à la configuration",
24
25
  setup_write: "Écriture des paramètres",
25
26
  studio_access: "Accès à Studio",
27
+ manage_sharing: "Gérer le partage",
28
+ view_all_audit_log: "Voir tout le journal d'audit",
26
29
  },
27
30
  group: {
28
31
  platform: 'Plateforme',
@@ -30,26 +33,6 @@ const fr = {
30
33
  other: 'Autre',
31
34
  },
32
35
  },
33
- // objectui#3546 slice six — le résumé en lecture seule des facettes
34
- // d'autorisation de PermissionFacetLink. Apostrophe droite U+0027 comme dans
35
- // le reste du paquet, et espace avant les deux-points.
36
- perm: {
37
- facet: {
38
- none: "Aucun",
39
- more: "+{{count}} de plus",
40
- objects: "{{count}} objets",
41
- objects_one: "{{count}} objet",
42
- fields: "{{count}} règles de champ",
43
- fields_one: "{{count}} règle de champ",
44
- rls: "{{count}} politiques RLS",
45
- rls_one: "{{count}} politique RLS",
46
- tabs: "{{count}} règles d'onglet",
47
- tabs_one: "{{count}} règle d'onglet",
48
- adminScope: "Administration déléguée configurée",
49
- designInStudio: "Concevoir dans Studio →",
50
- designInStudioHint: "Concevoir dans Studio",
51
- },
52
- },
53
36
  lookup: {
54
37
  recentlyUsed: 'Récemment utilisés',
55
38
  allResults: 'Tous les résultats',
@@ -63,7 +46,9 @@ const fr = {
63
46
  selectFirst: 'Sélectionnez d’abord {{fields}}',
64
47
  selectRecord: 'Sélectionner un enregistrement',
65
48
  recordCount: '{{count}} enregistrements',
66
- recordCountOne: '1 enregistrement',
49
+ recordCount_one: '{{count}} enregistrement',
50
+ recordCount_many: "{{count}} d'enregistrements",
51
+ recordCount_other: '{{count}} enregistrements',
67
52
  pageOf: 'Page {{current}} sur {{total}}',
68
53
  filters: 'Filtres',
69
54
  clear: 'Effacer',
@@ -116,14 +101,27 @@ const fr = {
116
101
  closePanel: "Fermer le panneau",
117
102
  resizeDrawer: "Redimensionner le panneau",
118
103
  itemCount: "{{count}} éléments",
119
- itemCountOne: "{{count}} élément",
104
+ itemCount_one: "{{count}} élément",
105
+ itemCount_many: "{{count}} d'éléments",
106
+ itemCount_other: "{{count}} éléments",
120
107
  toggleSidebar: "Basculer la barre latérale",
108
+ breadcrumb: "Fil d'Ariane",
121
109
  package: "Package",
122
110
  done: "Terminé",
123
111
  editInStudio: "Modifier dans Studio",
124
112
  record: "Enregistrement",
125
113
  retry: "Réessayer",
126
114
  printDialogHint: "Ouvre la boîte de dialogue d'impression de votre navigateur (ce n'est pas un export PDF)",
115
+ // The non-grid row ceiling's footnote (objectui#7210). Two keys because
116
+ // there are two conditions: a reported `total` states the fact with BOTH
117
+ // numbers, a missing one cannot name how many. Kept terse deliberately —
118
+ // this copy is eagerly loaded, and since objectui#7399 these bytes are
119
+ // budgeted by the `i18n-locales` chunk, not `framework`. ⛔ That ceiling's
120
+ // headroom is deliberately NOT restated here — it moves on every
121
+ // re-baseline, and the figure that was here went stale.
122
+ // `pnpm check:eager-closure` prints it.
123
+ rowCeilingNote: "Affichage des {{shown}} premiers enregistrements sur {{total}}. Affinez le filtre.",
124
+ rowCeilingNoteUnknownTotal: "Affichage des {{shown}} premiers enregistrements. Affinez le filtre.",
127
125
  },
128
126
  actions: {
129
127
  decisionOutput: {
@@ -135,6 +133,15 @@ const fr = {
135
133
  acknowledge: 'Je l\'ai enregistrée',
136
134
  copyAll: 'Tout copier',
137
135
  },
136
+ notAvailableHere: '« {{action}} » n\'est pas disponible sur la page actuelle.',
137
+ notAvailableForRecord: 'Non disponible pour cet enregistrement',
138
+ completedSuccessfully: 'Action effectuée avec succès',
139
+ failed: "Échec de l'action",
140
+ parallelFailed: 'Une ou plusieurs actions parallèles ont échoué',
141
+ undo: 'Annuler',
142
+ undone: 'Modification annulée',
143
+ undoneOperation: 'Annuler : {{description}}',
144
+ redoneOperation: 'Rétablir : {{description}}',
138
145
  },
139
146
  validation: {
140
147
  required: "{{field}} est obligatoire",
@@ -152,19 +159,47 @@ const fr = {
152
159
  },
153
160
  form: {
154
161
  noPermissionToSave: "Vous n'avez pas l'autorisation d'enregistrer cet enregistrement.",
162
+ noPermissionToCreate: "Vous n'avez pas l'autorisation de créer des enregistrements {{object}}. Les champs sont en lecture seule.",
163
+ noPermissionToEdit: "Vous n'avez pas l'autorisation de modifier les enregistrements {{object}}. Les champs sont en lecture seule.",
155
164
  submitFailed: "Échec de l'enregistrement. Veuillez réessayer.",
165
+ uploadInFlight: "Attendez la fin du téléversement avant de sauvegarder.",
166
+ clearedOnHide: "Ce qui ne s'applique plus aux valeurs actuelles a été effacé : {{fields}}",
167
+ visibleWhenFaulted: "Envoi impossible : la règle visibleWhen de {{fields}} n'a pas pu être évaluée. La règle doit être corrigée avant que ce formulaire puisse être envoyé.",
156
168
  discardTitle: "Abandonner les modifications ?",
157
169
  discardMessage: "Vous avez des modifications non enregistrées. Si vous fermez ce formulaire maintenant, vos modifications seront perdues.",
158
170
  // objectui#4024 — the create/edit dialog's `sr-only` accessible
159
171
  // description, used when the form declares no `description` of its own.
160
172
  dialogDescriptionFallback: "Remplissez les champs du formulaire, puis envoyez ou annulez.",
173
+ deniedDescription: "Vous n'avez pas l'autorisation de modifier ce champ.",
174
+ serverDefaultHint: "Défini automatiquement lors de l'enregistrement.",
175
+ maxFileSize: "Taille maximale : {{size}}",
176
+ masterDetail: {
177
+ loadingColumns: "Chargement des colonnes…",
178
+ subtotal: "Sous-total",
179
+ tax: "Taxe ({{rate}} %)",
180
+ total: "Total",
181
+ lineItem: "Ligne",
182
+ rowTitle: "{{title}} — ligne {{row}}",
183
+ applyRow: "Appliquer",
184
+ editorDescription: "Saisissez l'enregistrement et ses lignes, puis enregistrez.",
185
+ noChildObject: "Aucun objet enfant n'est configuré pour cette collection : définissez {{property}} sur l'objet dont elle liste les lignes.",
186
+ schemaUnavailable: "Impossible de charger le schéma de {{object}} : cette collection n'a donc aucune colonne à afficher. Vérifiez que l'objet existe et est lisible, puis rechargez.",
187
+ noRelationshipField: "Impossible de déterminer comment {{object}} est lié à {{parent}} : aucun champ lookup ou master_detail de cet objet ne référence le parent. Définissez {{property}} sur cette collection avec le champ qui contient l'enregistrement parent.",
188
+ },
189
+ lineItems: {
190
+ title: "Lignes",
191
+ saveRecordFirst: "Enregistrez d'abord l'enregistrement pour ajouter des lignes.",
192
+ notLoaded: "Les lignes de cet enregistrement n'ont pas été chargées.",
193
+ loadFailed: "Échec du chargement des lignes",
194
+ saveFailed: "Échec de l'enregistrement des lignes",
195
+ noChildObject: "Aucun objet enfant n'est configuré pour ce panneau : définissez {{property}} sur l'objet dont il liste les lignes.",
196
+ },
161
197
  keepEditing: "Continuer l'édition",
162
198
  discard: "Abandonner",
163
199
  conflictTitle: "Conflit d'enregistrement",
164
200
  conflictMessage: "Cet enregistrement a été modifié par quelqu'un d'autre pendant votre édition. L'écrasement remplacera ses modifications par les vôtres.",
165
201
  conflictLatestVersion: "Son enregistrement : {{time}}",
166
202
  conflictOverwrite: "Écraser",
167
- addItem: "Ajouter un élément",
168
203
  removeItem: "Supprimer un élément",
169
204
  fieldRequired: "Ce champ est obligatoire",
170
205
  invalidFormat: "Format invalide",
@@ -182,6 +217,12 @@ const fr = {
182
217
  createSuccess: "{{object}} créé",
183
218
  updateSuccess: "{{object}} mis à jour",
184
219
  deleteSuccess: "{{object}} supprimé",
220
+ created: "Créé",
221
+ saved: "Enregistré",
222
+ savedNamed: "{{title}} enregistré",
223
+ submitted: "Envoyé",
224
+ errorLoading: "Erreur de chargement du formulaire",
225
+ navigateRefused: "La destination `navigateOnSuccess` déclarée pour ce formulaire a été refusée, la navigation n’a donc pas eu lieu.",
185
226
  fullscreen: {
186
227
  title: "Modifier le texte",
187
228
  description: "Modifiez la valeur texte complète, puis enregistrez ou annulez vos modifications.",
@@ -200,12 +241,19 @@ const fr = {
200
241
  remove: "Supprimer l'image {{index}}",
201
242
  enlarge: "Agrandir {{name}}",
202
243
  preview: "Aperçu de l'image",
244
+ cropPreview: "Aperçu du recadrage de l'image",
203
245
  previous: "Image précédente",
204
246
  next: "Image suivante",
205
247
  counter: "{{current}} / {{total}}",
206
248
  },
249
+ percent: {
250
+ slider: "Pourcentage",
251
+ },
207
252
  relativeDate: {
208
253
  overdue: "En retard de {{count}} j",
254
+ overdue_one: "En retard de {{count}} j",
255
+ overdue_many: "En retard de {{count}} j",
256
+ overdue_other: "En retard de {{count}} j",
209
257
  },
210
258
  file: {
211
259
  dragDropHere: 'Glissez-déposez des fichiers ici',
@@ -222,6 +270,9 @@ const fr = {
222
270
  remove: 'Supprimer {{name}}',
223
271
  exceedsMaxSize: '« {{name}} » dépasse la taille maximale ({{max}} Mo)',
224
272
  uploadFailed: 'Échec du téléversement de « {{name}} » : {{error}}',
273
+ uploadIncomplete: 'Le téléversement de « {{name}} » n’a pas abouti : aucun identifiant de fichier n’a été renvoyé, rien n’a été enregistré',
274
+ restricted: 'Fichier restreint',
275
+ restrictedHint: 'Vous n’avez pas accès aux détails de ce fichier',
225
276
  },
226
277
  richText: {
227
278
  format: "Format : {{format}}",
@@ -238,6 +289,10 @@ const fr = {
238
289
  search: "Rechercher des objets…",
239
290
  empty: "Aucun objet trouvé",
240
291
  },
292
+ registryRef: {
293
+ loadFailed: "La liste n'a pas pu être chargée. Vous pouvez toujours saisir le nom.",
294
+ notFound: "{{name}} (introuvable)",
295
+ },
241
296
  recipient: {
242
297
  selectTypeFirst: "Sélectionnez d'abord un type de destinataire.",
243
298
  loading: "Chargement…",
@@ -249,6 +304,9 @@ const fr = {
249
304
  selectBusinessUnit: "Sélectionner une unité opérationnelle",
250
305
  selectPosition: "Sélectionner un poste",
251
306
  selectUnitAndSubordinates: "Sélectionner une unité opérationnelle",
307
+ selectField: "Sélectionner un champ utilisateur",
308
+ noUserFields: "Cet objet n'a aucun champ utilisateur",
309
+ fieldNotUserTyped: "{{name}} — pas un champ utilisateur",
252
310
  },
253
311
  filterCondition: {
254
312
  selectObjectFirst: "Sélectionnez d'abord un objet.",
@@ -259,6 +317,33 @@ const fr = {
259
317
  editAsJson: "Modifier en JSON",
260
318
  useVisualBuilder: "Utiliser le constructeur visuel",
261
319
  },
320
+ object: {
321
+ invalidJson: "JSON invalide",
322
+ },
323
+ location: {
324
+ refusedFormat: "Non enregistré : saisissez une paire latitude, longitude (exemple : 30.2741, 120.1551).",
325
+ refusedRange: "Non enregistré : {{detail}}",
326
+ latitude: "latitude",
327
+ longitude: "longitude",
328
+ refusedResidueOne: "Non enregistré : {{name}} « {{text}} » n'est pas un nombre. Saisissez des décimales simples (exemple : 30.2741, 120.1551).",
329
+ refusedResidue: "Non enregistré : {{name}} « {{text}} » et {{otherName}} « {{otherText}} » ne sont pas des nombres. Saisissez des décimales simples (exemple : 30.2741, 120.1551).",
330
+ },
331
+ date: {
332
+ impossibleDay: "La valeur enregistrée « {{value}} » n’est pas une date réelle. Choisissez une date pour la remplacer.",
333
+ },
334
+ dateTime: {
335
+ impossibleDay: "La valeur enregistrée « {{value}} » n’est pas une date réelle. Choisissez une date et une heure pour la remplacer.",
336
+ },
337
+ datePicker: {
338
+ today: "Aujourd’hui",
339
+ tomorrow: "Demain",
340
+ clear: "Effacer la date",
341
+ openCalendar: "Ouvrir le calendrier",
342
+ invalid: "Non enregistré : « {{value}} » n’est pas une date. Saisissez-la au format {{format}} ou choisissez-la dans le calendrier.",
343
+ },
344
+ number: {
345
+ badInput: "Non enregistré : le texte de ce champ n'est pas un nombre. Saisissez une décimale simple (exemple : {{example}}).",
346
+ },
262
347
  tags: {
263
348
  placeholder: "Saisissez puis appuyez sur Entrée pour ajouter…",
264
349
  },
@@ -270,10 +355,25 @@ const fr = {
270
355
  postalCode: "Code postal",
271
356
  country: "Pays",
272
357
  },
358
+ boolean: {
359
+ offBadge: "{{label}} — Désactivé",
360
+ completed: "Terminé",
361
+ notCompleted: "Non terminé",
362
+ },
273
363
  textarea: {
274
364
  characterCount: "Nombre de caractères : {{count}} sur {{max}}",
275
365
  charactersRemaining: "Caractères restants : {{count}}",
276
366
  },
367
+ grid: {
368
+ addLine: "Ajouter une ligne",
369
+ noItems: "Aucun élément",
370
+ noItemsAddHint: "Aucun élément pour l'instant — cliquez sur « {{label}} » pour commencer.",
371
+ optionalColumns: "Colonnes facultatives",
372
+ computed: "Calculé",
373
+ openRow: "Ouvrir la ligne",
374
+ duplicateRow: "Dupliquer la ligne",
375
+ removeRow: "Supprimer la ligne",
376
+ },
277
377
  },
278
378
  table: {
279
379
  rowsPerPage: "Lignes par page",
@@ -289,10 +389,15 @@ const fr = {
289
389
  selectAllRows: "Sélectionner toutes les lignes",
290
390
  expandRow: "Développer la ligne",
291
391
  collapseRow: "Réduire la ligne",
392
+ rowActions: "Actions de la ligne",
292
393
  hideColumn: "Masquer la colonne",
293
394
  freezeColumn: "Figer la colonne",
294
395
  unfreezeColumn: "Libérer la colonne",
295
396
  pageInfo: "Page {{current}} sur {{total}}",
397
+ firstPage: "Première page",
398
+ previousPage: "Page précédente",
399
+ nextPage: "Page suivante",
400
+ lastPage: "Dernière page",
296
401
  totalRecords: "{{count}} au total",
297
402
  noResults: "Aucun résultat",
298
403
  noResultsHint: "Essayez d'ajuster vos filtres ou vos termes de recherche.",
@@ -302,23 +407,46 @@ const fr = {
302
407
  open: "Ouvrir",
303
408
  search: "Rechercher…",
304
409
  modified: "{{count}} ligne(s) modifiée(s)",
410
+ modified_one: "{{count}} ligne modifiée",
411
+ modified_many: "{{count}} de lignes modifiées",
412
+ modified_other: "{{count}} lignes modifiées",
413
+ saved: "{{count}} ligne(s) enregistrée(s)",
414
+ saved_one: "{{count}} ligne enregistrée",
415
+ saved_many: "{{count}} de lignes enregistrées",
416
+ saved_other: "{{count}} lignes enregistrées",
305
417
  saveFailed: 'Échec de l’enregistrement',
306
418
  selected: "{{count}} sélectionné(s)",
419
+ selected_one: "{{count}} sélectionné",
420
+ selected_many: "{{count}} sélectionnés",
421
+ selected_other: "{{count}} sélectionnés",
307
422
  edit: "Modifier",
308
423
  delete: "Supprimer",
309
424
  },
310
425
  grid: {
311
426
  bulkSelected: "{{count}} sélectionné(s)",
427
+ bulkSelected_one: "{{count}} sélectionné",
428
+ bulkSelected_many: "{{count}} sélectionnés",
429
+ bulkSelected_other: "{{count}} sélectionnés",
312
430
  bulkSelectedAllMatches: "{{count}} sélectionné(s) (tous les résultats)",
313
431
  bulkClear: "Effacer",
314
432
  bulkAllOnPage: "Les {{count}} éléments de cette page sont sélectionnés.",
433
+ bulkAllOnPage_one: "{{count}} enregistrement de cette page est sélectionné.",
434
+ bulkAllOnPage_many: "Les {{count}} éléments de cette page sont sélectionnés.",
435
+ bulkAllOnPage_other: "Les {{count}} éléments de cette page sont sélectionnés.",
315
436
  bulkSelectAllMatching: "Sélectionner les {{count}} correspondances",
316
437
  bulkAllMatchingSelected: "Les {{count}} enregistrements correspondants sont tous sélectionnés.",
438
+ bulkActions: "Actions groupées",
317
439
  bulk: {
318
440
  confirmDefault: "Ceci s'appliquera à {{count}} enregistrement(s).",
441
+ confirmDefault_one: "Ceci s'appliquera à {{count}} enregistrement.",
442
+ confirmDefault_many: "Ceci s'appliquera à {{count}} d'enregistrements.",
443
+ confirmDefault_other: "Ceci s'appliquera à {{count}} enregistrements.",
319
444
  overLimit: "La sélection ({{count}}) dépasse la limite de l'action ({{limit}}). Réduisez la sélection pour continuer.",
320
445
  affectedRecords: "Enregistrements concernés ({{count}}) :",
321
446
  skippedIneligible: '{{count}} des enregistrements sélectionnés ne sont pas éligibles à cette action et seront ignorés.',
447
+ skippedIneligible_one: "{{count}} des enregistrements sélectionnés n'est pas éligible à cette action et sera ignoré.",
448
+ skippedIneligible_many: '{{count}} des enregistrements sélectionnés ne sont pas éligibles à cette action et seront ignorés.',
449
+ skippedIneligible_other: '{{count}} des enregistrements sélectionnés ne sont pas éligibles à cette action et seront ignorés.',
322
450
  rowFallback: "Ligne {{index}}",
323
451
  andMore: "… et {{count}} de plus",
324
452
  processed: "{{count}} / {{total}} traités",
@@ -336,7 +464,6 @@ const fr = {
336
464
  undo: "Annuler",
337
465
  undoing: "Annulation…",
338
466
  done: "Terminé",
339
- selectPlaceholder: "Sélectionner…",
340
467
  loading: "Chargement…",
341
468
  },
342
469
  actions: "Actions",
@@ -349,17 +476,27 @@ const fr = {
349
476
  pullToRefresh: "Tirer pour actualiser",
350
477
  refreshing: "Actualisation…",
351
478
  openRecord: "Ouvrir l'enregistrement",
479
+ recordUnavailable: "{{object}} · enregistrement indisponible",
352
480
  rowHeight: "Hauteur de ligne : {{mode}}",
353
481
  openMenu: "Ouvrir le menu",
354
482
  empty: "Vide",
355
483
  yes: "Oui",
356
484
  no: "Non",
357
485
  systemFields: "Système",
486
+ // objectui#10881 — the grouped grid's two refusals: over a data source
487
+ // that cannot answer the group header query, and over rows a host
488
+ // handed in while declaring them one page of more. `queryGroupHeaders`
489
+ // is the member's name and stays untranslated.
490
+ grouping: {
491
+ needsHeaderQuery: "Cette vue est groupée, mais sa source de données n'implémente pas queryGroupHeaders : les groupes ne peuvent donc pas être comptés. Supprimez le regroupement pour afficher les enregistrements.",
492
+ needsWholeRows: "Le regroupement a besoin de tous les enregistrements, mais cette grille n'en a reçu qu'une page : les groupes ne peuvent donc pas être comptés. Fournissez tous les enregistrements, ou laissez la grille les charger depuis une source de données qui implémente queryGroupHeaders.",
493
+ },
358
494
  // objectui#4024 — column-footer aggregate prefixes, keyed by the spec's
359
495
  // `ColumnSummary` vocabulary. `pattern` owns the label/value join so this
360
496
  // pack controls its own separator and word order.
361
497
  summary: {
362
498
  pattern: "{{label}} : {{value}}",
499
+ pagePattern: "{{label}} (cette page) : {{value}}",
363
500
  count: "Nombre",
364
501
  countEmpty: "Vides",
365
502
  countFilled: "Remplis",
@@ -381,10 +518,15 @@ const fr = {
381
518
  },
382
519
  import: {
383
520
  downloadTemplate: "Télécharger le modèle",
384
- downloadTemplateHint: "Obtenez un CSV avec les bonnes colonnes (les champs obligatoires sont marqués d'un *).",
521
+ downloadTemplateHint: "Obtenez un fichier Excel des colonnes importables (les champs obligatoires sont marqués d'un *), avec des instructions de saisie.",
385
522
  templateFileName: "{{object}}-import-template",
523
+ templateDownloadFailed: "Impossible de télécharger le modèle. Veuillez réessayer.",
524
+ templateNotPermitted: "Vous n'êtes pas autorisé à créer des enregistrements de cet objet, son modèle d'import n'est donc pas disponible.",
386
525
  autoMatched: "Associé automatiquement",
387
526
  autoMatchedSummary: "{{count}} colonne(s) associée(s) automatiquement — vérifiez et ajustez ci-dessous.",
527
+ autoMatchedSummary_one: "{{count}} colonne associée automatiquement — vérifiez et ajustez ci-dessous.",
528
+ autoMatchedSummary_many: "{{count}} de colonnes associées automatiquement — vérifiez et ajustez ci-dessous.",
529
+ autoMatchedSummary_other: "{{count}} colonnes associées automatiquement — vérifiez et ajustez ci-dessous.",
388
530
  confidence: {
389
531
  high: "Confiance élevée",
390
532
  medium: "Confiance moyenne",
@@ -397,8 +539,17 @@ const fr = {
397
539
  cancelImport: "Annuler l'import",
398
540
  importCancelled: "Import annulé",
399
541
  resultsTruncated: "Affichage des {{count}} premiers résultats de lignes (sur {{total}}).",
542
+ resultsTruncated_one: "Affichage du premier résultat de ligne ({{count}} sur {{total}}).",
543
+ resultsTruncated_many: "Affichage des {{count}} premiers résultats de lignes (sur {{total}}).",
544
+ resultsTruncated_other: "Affichage des {{count}} premiers résultats de lignes (sur {{total}}).",
400
545
  createdCount: "{{count}} créé(s)",
546
+ createdCount_one: "{{count}} créé",
547
+ createdCount_many: "{{count}} créés",
548
+ createdCount_other: "{{count}} créés",
401
549
  updatedCount: "{{count}} mis à jour",
550
+ updatedCount_one: "{{count}} mis à jour",
551
+ updatedCount_many: "{{count}} mis à jour",
552
+ updatedCount_other: "{{count}} mis à jour",
402
553
  downloadFailed: "Télécharger les lignes en échec",
403
554
  options: "Options d'import",
404
555
  writeMode: "Lorsqu'une ligne correspond à un enregistrement existant",
@@ -413,9 +564,6 @@ const fr = {
413
564
  needMatchFields: "Sélectionnez au moins un champ de correspondance.",
414
565
  matchOnlyField: "(correspondance seule)",
415
566
  optCreateOptions: "Conserver les valeurs d'option inconnues",
416
- optRunAutomations: "Exécuter les automatisations et déclencheurs",
417
- optTreatHistorical: "Importer comme données historiques",
418
- optTreatHistoricalHint: "(importer les enregistrements terminés tels quels — ignorer les contrôles de la machine à états et conserver leurs horodatages et auteurs d'origine au lieu d'horodater maintenant)",
419
567
  optSkipBlankKey: "Ignorer les lignes dont la valeur de correspondance est vide",
420
568
  optBackground: "Importer en arrière-plan",
421
569
  optBackgroundHint: "(s'exécute comme une tâche annulable)",
@@ -430,6 +578,7 @@ const fr = {
430
578
  invalidBoolean: "« {{value}} » n'est pas une valeur vrai/faux valide",
431
579
  invalidNumber: "« {{value}} » n'est pas un nombre valide",
432
580
  invalidDate: "« {{value}} » n'est pas une date valide",
581
+ invalidTime: "« {{value}} » n'est pas une heure valide",
433
582
  invalidOption: "« {{value}} » ne fait pas partie des options autorisées",
434
583
  requiredValue: "Ce champ est obligatoire",
435
584
  matchAmbiguous: "Correspond à plusieurs enregistrements existants — utilisez une valeur unique ou l'identifiant de l'enregistrement",
@@ -446,10 +595,17 @@ const fr = {
446
595
  historyColResult: "Résultat",
447
596
  historyColTime: "Quand",
448
597
  errorCount: "{{count}} erreurs",
598
+ errorCount_one: "{{count}} erreur",
599
+ errorCount_many: "{{count}} d'erreurs",
600
+ errorCount_other: "{{count}} erreurs",
449
601
  undoImport: "Annuler l'import",
450
602
  undoing: "Annulation…",
451
603
  undoConfirm: "Annuler cet import ? Les enregistrements créés seront supprimés et les enregistrements mis à jour seront rétablis à leurs valeurs précédentes.",
452
604
  reverted: "Annulé",
605
+ undoPartial: "{{count}} lignes n'ont pas été annulées. Annuler à nouveau ne réessaie que ces lignes.",
606
+ undoPartial_one: "{{count}} ligne n'a pas été annulée. Annuler à nouveau ne réessaie que cette ligne.",
607
+ undoPartial_many: "{{count}} de lignes n'ont pas été annulées. Annuler à nouveau ne réessaie que ces lignes.",
608
+ undoPartial_other: "{{count}} lignes n'ont pas été annulées. Annuler à nouveau ne réessaie que ces lignes.",
453
609
  jobStatus: {
454
610
  pending: "En attente",
455
611
  running: "En cours",
@@ -506,19 +662,33 @@ const fr = {
506
662
  mapped: "Mappé",
507
663
  skipped: "Ignoré",
508
664
  rowsWithErrors: "{{count}} ligne(s) avec des erreurs",
665
+ rowsWithErrors_one: "{{count}} ligne avec des erreurs",
666
+ rowsWithErrors_many: "{{count}} de lignes avec des erreurs",
667
+ rowsWithErrors_other: "{{count}} lignes avec des erreurs",
509
668
  rowsCorrected: "{{count}} ligne(s) corrigée(s)",
669
+ rowsCorrected_one: "{{count}} ligne corrigée",
670
+ rowsCorrected_many: "{{count}} de lignes corrigées",
671
+ rowsCorrected_other: "{{count}} lignes corrigées",
510
672
  clickToFix: "— cliquez sur une cellule mise en surbrillance pour modifier en ligne.",
511
673
  showingRows: "Affichage de {{shown}} sur {{total}} lignes",
512
674
  importing: "Importation… {{progress}}%",
513
675
  importComplete: "Importation terminée",
676
+ importPartial: "Importation terminée avec des erreurs",
677
+ importFailed: "Échec de l'importation",
514
678
  imported: "{{count}} importé(s)",
515
679
  skippedCount: "{{count}} ignoré(s)",
516
680
  moreErrors: "…et {{count}} erreur(s) de plus",
681
+ moreErrors_one: "…et {{count}} erreur de plus",
682
+ moreErrors_many: "…et {{count}} d'erreurs de plus",
683
+ moreErrors_other: "…et {{count}} erreurs de plus",
517
684
  cancel: "Annuler",
518
685
  back: "Retour",
519
686
  next: "Suivant",
520
687
  close: "Fermer",
521
688
  importNRows: "Importer {{count}} lignes",
689
+ importNRows_one: "Importer {{count}} ligne",
690
+ importNRows_many: "Importer {{count}} de lignes",
691
+ importNRows_other: "Importer {{count}} lignes",
522
692
  importingProgress: "Importation…",
523
693
  requiredMark: "*",
524
694
  required: "Obligatoire",
@@ -530,17 +700,45 @@ const fr = {
530
700
  month: "Mois",
531
701
  week: "Semaine",
532
702
  day: "Jour",
533
- agenda: "Agenda",
534
703
  allDay: "Toute la journée",
535
- noEvents: "Aucun événement",
536
704
  newEvent: "Nouvel événement",
537
705
  moreEvents: "+{{count}} de plus",
706
+ unscheduled: "Non planifié ({{count}})",
707
+ loading: "Chargement du calendrier…",
708
+ loadError: "Erreur : {{message}}",
709
+ configRequired: "Configuration du calendrier requise. Veuillez indiquer startDateField, la seule clé obligatoire du calendrier ; le titre de l'événement se résout sans titleField.",
710
+ configRequiredHint: "Elle appartient au bloc calendar de la vue. Une page d'interface n'a pas d'emplacement de calendrier propre : pointez son sourceView vers une vue qui en déclare un.",
711
+ eventDetails: "Détails de l'événement",
712
+ pullToRefresh: "Tirer pour actualiser",
713
+ refreshing: "Actualisation…",
714
+ onDate: "Le {{date}}",
715
+ eventTitle: "Titre",
716
+ eventTitlePlaceholder: "De quoi s'agit-il ?",
717
+ creating: "Création…",
718
+ titleRequired: "Le titre est obligatoire",
719
+ a11y: {
720
+ region: "Calendrier",
721
+ grid: "Grille du calendrier",
722
+ goToToday: "Aller à aujourd'hui",
723
+ previousPeriod: "Période précédente",
724
+ nextPeriod: "Période suivante",
725
+ currentDate: "Date actuelle : {{date}}",
726
+ dayCell: "{{date}}, {{count}} événements",
727
+ dayCell_one: "{{date}}, {{count}} événement",
728
+ dayCell_many: "{{date}}, {{count}} d'événements",
729
+ dayCell_other: "{{date}}, {{count}} événements",
730
+ resizeEventEnd: "Modifier la fin de l'événement",
731
+ resizeEventEndHint: "Faites glisser pour modifier la date de fin",
732
+ resizeStart: "Modifier le début",
733
+ resizeEnd: "Modifier la fin",
734
+ },
538
735
  },
539
736
  list: {
540
737
  firstRunTitle: "Rien pour l'instant",
541
738
  firstRunMessage: "Créez votre premier enregistrement pour commencer.",
542
739
  noMatches: "Aucun enregistrement correspondant",
543
740
  noMatchesMessage: "Aucun enregistrement ne correspond à vos filtres ou à votre recherche. Essayez de les ajuster ou de les effacer.",
741
+ viewFilterNoMatchesMessage: "Aucun enregistrement ne correspond au filtre de cette vue.",
544
742
  loadErrorTitle: "Impossible de charger les enregistrements",
545
743
  loadErrorMessage: "Une erreur s'est produite lors du chargement de ces données. Vérifiez votre connexion et réessayez.",
546
744
  loadErrorForbiddenTitle: "Accès refusé",
@@ -577,17 +775,26 @@ const fr = {
577
775
  refresh: "Actualiser",
578
776
  loading: "Chargement des enregistrements…",
579
777
  recordCount: "{{count}} enregistrements",
580
- recordCountOne: "{{count}} enregistrement",
778
+ recordCount_one: "{{count}} enregistrement",
779
+ recordCount_many: "{{count}} d'enregistrements",
780
+ recordCount_other: "{{count}} enregistrements",
581
781
  addRecord: "Ajouter un enregistrement",
782
+ // objectui#12703 — the compact list's footer link to the object's list or the block's view.
783
+ viewAll: "Tout afficher",
582
784
  tabs: "Onglets",
583
785
  allRecords: "Tous les enregistrements",
584
786
  search: "Rechercher",
585
787
  filter: "Filtrer",
586
788
  filterRecords: "Filtrer les enregistrements",
789
+ filterActive: "Filtrer, {{count}} actifs",
790
+ filterActive_one: "Filtrer, {{count}} actif",
791
+ filterActive_many: "Filtrer, {{count}} actifs",
792
+ filterActive_other: "Filtrer, {{count}} actifs",
587
793
  sort: "Trier",
588
794
  sortRecords: "Trier les enregistrements",
589
795
  sortByIdSuffix: "(par ID)",
590
796
  sortRelationalHint: "Les colonnes qui pointent vers un autre enregistrement ne sont pas listées : elles ne peuvent être triées que par l'ID stocké, et non par le nom affiché dans la cellule. Pour trier par ce nom, dénormalisez-le sur cet objet sous la forme d'un champ stocké, écrit à chaque modification de la source, puis triez sur ce champ. Pas un champ de formule : il est virtuel, aucune colonne n'est stockée pour lui et le serveur refuse de trier dessus.",
797
+ sortRelationalPicked: "Une colonne liée est triée par l'ID stocké, et non par le nom affiché.",
591
798
  resetSortToDefault: "Réinitialiser au tri par défaut de la vue",
592
799
  group: "Grouper",
593
800
  groupBy: "Grouper par",
@@ -608,14 +815,15 @@ const fr = {
608
815
  print: "Imprimer",
609
816
  hideFieldsTitle: "Masquer les champs",
610
817
  dataLimitReached: "Les {{limit}} premiers enregistrements sont affichés. Il peut y avoir plus de données disponibles.",
611
- viewSettings: "Paramètres de vue",
612
- viewSettingsHint: "Regroupement, couleur, densité et champs visibles.",
818
+ display: "Affichage",
819
+ layout: "Disposition",
820
+ rowNumbers: "Numéros de ligne",
821
+ resetToViewDefault: "Rétablir les valeurs par défaut de la vue",
613
822
  addGroup: "Ajouter un champ de groupe",
614
823
  collapsedByDefault: "Réduit par défaut",
615
824
  removeGroup: "Supprimer",
616
825
  inlineEditShort: "Édition en ligne",
617
826
  inlineEditLabel: "Modifier les enregistrements en ligne (cliquez sur une cellule pour modifier)",
618
- recordEditingTitle: "Modification des enregistrements",
619
827
  },
620
828
  managedByBadge: {
621
829
  systemWritable: {
@@ -646,6 +854,7 @@ const fr = {
646
854
  },
647
855
  kanban: {
648
856
  uncategorized: "Non catégorisé",
857
+ loadMore: "Charger plus",
649
858
  columns: "colonnes",
650
859
  addCard: "Ajouter une carte",
651
860
  addColumn: "Ajouter une colonne",
@@ -653,13 +862,28 @@ const fr = {
653
862
  deleteCard: "Supprimer la carte",
654
863
  deleteColumn: "Supprimer la colonne",
655
864
  noCards: "Aucune carte",
865
+ columnCards: "Cartes de la colonne {{column}}",
866
+ laneCards: "Cartes de {{column}} - {{lane}}",
656
867
  cardTitlePlaceholder: "Saisir le titre de la carte…",
657
868
  requiredFieldsTitle: "Compléter les champs obligatoires",
658
869
  requiredFieldsDescription: "Ce déplacement rend les champs ci-dessous obligatoires. Remplissez-les pour continuer.",
870
+ dnd: {
871
+ start: "Carte {{card}} saisie dans la colonne {{column}}.",
872
+ overCard: "Carte {{card}} au-dessus de la carte {{target}} dans la colonne {{column}}.",
873
+ overColumn: "Carte {{card}} au-dessus de la colonne {{column}}.",
874
+ overNone: "La carte {{card}} n'est au-dessus d'aucune colonne.",
875
+ moved: "Carte {{card}} déplacée dans la colonne {{column}}.",
876
+ dropped: "Carte {{card}} déposée. Elle reste dans la colonne {{column}}.",
877
+ cancelled: "Déplacement annulé. La carte {{card}} reste dans la colonne {{column}}.",
878
+ untitledCard: "sans titre",
879
+ unnamedColumn: "sans nom",
880
+ instructions: "Pour déplacer cette carte vers une autre colonne, faites-la glisser avec la souris ou au toucher.",
881
+ dragging: "Déplacement de la carte {{card}}",
882
+ },
659
883
  },
660
884
  timeline: {
661
885
  bucket: {
662
- overdue: "En retard",
886
+ earlier: "Plus tôt",
663
887
  today: "Aujourd'hui",
664
888
  tomorrow: "Demain",
665
889
  thisWeek: "Cette semaine",
@@ -674,6 +898,17 @@ const fr = {
674
898
  },
675
899
  gantt: {
676
900
  rowLabel: "Éléments",
901
+ unusableRange: {
902
+ malformedDate: "Plage de dates du gantt inutilisable — {{path}} vaut {{value}}, ce qui n'est pas une date valide. Toutes les dates du gantt doivent être analysables : startDate et endDate de chaque élément de ligne, ainsi que tout minDate / maxDate fixé sur le schéma.",
903
+ malformedRow: "Lignes du gantt inutilisables — {{path}} vaut {{value}}, ce qui n'est pas la forme d'une ligne. Un gantt lit items comme une liste de lignes, chaque ligne comme un objet avec un label et ses propres items, et les items de chaque ligne comme une liste de barres ; un null, un nombre, une chaîne ou un objet simple à l'un de ces emplacements ne peut pas être dessiné.",
904
+ inverted: "Plage de dates du gantt inutilisable — minDate {{minDate}} est postérieur à maxDate {{maxDate}}. Un minDate / maxDate fixé l'emporte sur la plage calculée à partir des lignes ; cet axe n'a donc aucune colonne et aucune barre ne peut y être placée. Intervertissez les deux valeurs.",
905
+ },
906
+ },
907
+ unsupported: {
908
+ objectBoundGantt: "Variante « gantt » non prise en charge — une timeline liée à un objet affiche les variantes de flux ({{variants}}). Gantt nécessite des lignes littérales, chacune avec ses propres items imbriqués ; l'axe gantt (scale) est donc sans effet ici.",
909
+ },
910
+ unconfigured: {
911
+ noDateAxis: "Axe de dates requis pour la timeline — cette vue ne déclare aucun champ de date, et une timeline liée à un objet n'en invente pas. Déclarez l'un de : {{fields}}. Le premier est l'orthographe de la spec, les autres sont des alias hérités.",
677
912
  },
678
913
  },
679
914
  gantt: {
@@ -691,6 +926,7 @@ const fr = {
691
926
  },
692
927
  aria: {
693
928
  taskList: "Liste des tâches",
929
+ refreshing: "Actualisation…",
694
930
  },
695
931
  tooltip: {
696
932
  days: "j",
@@ -736,13 +972,22 @@ const fr = {
736
972
  conflict: {
737
973
  title: "Conflit de planning",
738
974
  body: "Ce déplacement entre en conflit avec les contraintes de dépendance. Replanifier automatiquement {{count}} tâche(s) concernée(s) ?",
975
+ body_one: "Ce déplacement entre en conflit avec les contraintes de dépendance. Replanifier automatiquement {{count}} tâche concernée ?",
976
+ body_many: "Ce déplacement entre en conflit avec les contraintes de dépendance. Replanifier automatiquement {{count}} de tâches concernées ?",
977
+ body_other: "Ce déplacement entre en conflit avec les contraintes de dépendance. Replanifier automatiquement {{count}} tâches concernées ?",
739
978
  confirm: "Replanifier automatiquement",
740
979
  cancel: "Laisser tel quel",
741
980
  },
742
981
  autoScheduleDlg: {
743
982
  title: "Planification automatique",
744
983
  body: "Décaler {{count}} tâche(s) plus tard pour respecter les liens de dépendance ?",
984
+ body_one: "Décaler {{count}} tâche plus tard pour respecter les liens de dépendance ?",
985
+ body_many: "Décaler {{count}} de tâches plus tard pour respecter les liens de dépendance ?",
986
+ body_other: "Décaler {{count}} tâches plus tard pour respecter les liens de dépendance ?",
745
987
  skipped: "{{count}} tâche(s) verrouillée(s) violent aussi les liens et ont été ignorées.",
988
+ skipped_one: "{{count}} tâche verrouillée viole aussi les liens et a été ignorée.",
989
+ skipped_many: "{{count}} de tâches verrouillées violent aussi les liens et ont été ignorées.",
990
+ skipped_other: "{{count}} tâches verrouillées violent aussi les liens et ont été ignorées.",
746
991
  confirm: "Appliquer",
747
992
  cancel: "Annuler",
748
993
  none: "Toutes les dépendances sont respectées — rien à replanifier.",
@@ -821,10 +1066,14 @@ const fr = {
821
1066
  tabActionsFor: "Actions de vue pour {{name}}",
822
1067
  readonlyAriaLabel: "Vue en lecture seule",
823
1068
  readonlyTooltip: "Vue système — définie dans le code, en lecture seule.",
1069
+ malformedFilter: "Le filtre de cette vue est incorrect, aucun enregistrement n’est donc affiché : la condition {{subject}} ne peut pas être appliquée.",
1070
+ noObject: "Aucun objet indiqué : définissez {{property}} ou dataSource.object.",
824
1071
  },
825
1072
  designer: {
826
1073
  undo: "Annuler",
827
1074
  redo: "Rétablir",
1075
+ canvasMinimap: "Mini-carte du canevas",
1076
+ versionHistory: "Historique des versions",
828
1077
  },
829
1078
  detail: {
830
1079
  editInlineHint: "Double-cliquez pour modifier",
@@ -848,7 +1097,9 @@ const fr = {
848
1097
  pageHeaderActions: "Actions de l'en-tête de page",
849
1098
  emojiPicker: "Sélecteur d'émojis",
850
1099
  reactionCount: "{{emoji}} {{count}} réactions",
851
- reactionCountOne: "{{emoji}} {{count}} réaction",
1100
+ reactionCount_one: "{{emoji}} {{count}} réaction",
1101
+ reactionCount_many: "{{emoji}} {{count}} de réactions",
1102
+ reactionCount_other: "{{emoji}} {{count}} réactions",
852
1103
  recordDetail: "Détail de l'enregistrement",
853
1104
  recordDetailWithLabel: "Détail — {{label}}",
854
1105
  openAsFullPage: "Ouvrir en pleine page",
@@ -875,7 +1126,6 @@ const fr = {
875
1126
  viewAll: "Tout afficher",
876
1127
  new: "Nouveau",
877
1128
  add: "Ajouter",
878
- emptyValue: "—",
879
1129
  comments: "Commentaires",
880
1130
  searchComments: "Rechercher des commentaires…",
881
1131
  addCommentPlaceholder: "Ajouter un commentaire… (Ctrl+Entrée pour envoyer)",
@@ -886,11 +1136,22 @@ const fr = {
886
1136
  unpin: "Désépingler",
887
1137
  justNow: "à l'instant",
888
1138
  minutesAgo: "il y a {{count}} min",
1139
+ minutesAgo_one: "il y a {{count}} min",
1140
+ minutesAgo_many: "il y a {{count}} min",
1141
+ minutesAgo_other: "il y a {{count}} min",
889
1142
  hoursAgo: "il y a {{count}} h",
1143
+ hoursAgo_one: "il y a {{count}} h",
1144
+ hoursAgo_many: "il y a {{count}} h",
1145
+ hoursAgo_other: "il y a {{count}} h",
890
1146
  daysAgo: "il y a {{count}} j",
1147
+ daysAgo_one: "il y a {{count}} j",
1148
+ daysAgo_many: "il y a {{count}} j",
1149
+ daysAgo_other: "il y a {{count}} j",
891
1150
  dropFilesToUpload: "Déposez les fichiers ici ou cliquez pour télécharger",
892
1151
  attachmentCount: "{{count}} pièce jointe",
893
- attachmentCountPlural: "{{count}} pièces jointes",
1152
+ attachmentCount_one: "{{count}} pièce jointe",
1153
+ attachmentCount_many: "{{count}} de pièces jointes",
1154
+ attachmentCount_other: "{{count}} pièces jointes",
894
1155
  removeAttachment: "Supprimer la pièce jointe",
895
1156
  // Record Attachments panel (enable.files, objectstack#4358)
896
1157
  attachments: "Pièces jointes",
@@ -899,6 +1160,7 @@ const fr = {
899
1160
  noAttachments: "Aucune pièce jointe pour le moment. Téléversez un fichier pour commencer.",
900
1161
  downloadAttachment: "Télécharger",
901
1162
  deleteAttachment: "Supprimer la pièce jointe",
1163
+ deleteAttachmentConfirm: "Êtes-vous sûr de vouloir supprimer la pièce jointe \"{{name}}\" ?",
902
1164
  attachmentDeleteDenied: "Seule la personne qui l'a téléversée ou une personne pouvant modifier cet enregistrement peut supprimer cette pièce jointe.",
903
1165
  attachmentParentAccessDenied: "Vous n'avez pas accès pour joindre des fichiers à cet enregistrement.",
904
1166
  attachmentDownloadDenied: "Vous n'avez pas accès pour télécharger cette pièce jointe.",
@@ -908,11 +1170,6 @@ const fr = {
908
1170
  attachmentsLoadFailed: "Impossible de charger les pièces jointes de cet enregistrement.",
909
1171
  attachmentsApiUnavailable: "La liste des pièces jointes n'est pas disponible sur cet objet.",
910
1172
  retryLoadAttachments: "Réessayer",
911
- unifiedDiff: "Vue unifiée",
912
- sideBySideDiff: "Vue côte à côte",
913
- noChanges: "Aucune modification",
914
- previousVersion: "Précédent",
915
- currentVersion: "Actuel",
916
1173
  discussion: "Discussion",
917
1174
  showDiscussion: "Afficher la discussion ({{count}})",
918
1175
  hideDiscussion: "Masquer la discussion",
@@ -927,25 +1184,36 @@ const fr = {
927
1184
  writeComment: "Écrire un commentaire…",
928
1185
  subscribedTooltip: "Abonné — cliquez pour vous désabonner",
929
1186
  unsubscribedTooltip: "S'abonner aux notifications",
930
- firstRecord: "Premier enregistrement (Début)",
931
- previousRecordKey: "Enregistrement précédent (←)",
932
- nextRecordKey: "Enregistrement suivant (→)",
933
- lastRecord: "Dernier enregistrement (Fin)",
934
1187
  noRecords: "Aucun enregistrement",
935
- searchWhileNavigating: "Rechercher pendant la navigation",
936
- searchRecords: "Rechercher des enregistrements…",
937
1188
  allActivity: "Toute l'activité",
938
1189
  commentsOnly: "Commentaires uniquement",
939
1190
  fieldChangesFilter: "Modifications de champs",
940
1191
  tasksOnly: "Tâches uniquement",
941
1192
  leaveCommentPlaceholder: "Laisser un commentaire… (Ctrl+Entrée pour envoyer)",
942
1193
  noActivity: "Aucune activité enregistrée",
1194
+ activityAccessDenied: "Vous n'avez pas l'autorisation de consulter l'activité de cet enregistrement.",
1195
+ commentsAccessDenied: "Vous n'avez pas l'autorisation de consulter les commentaires de cet enregistrement.",
1196
+ // objectui#7149 — the rest of `ActivityTimeline`. The four chip labels the
1197
+ // `detail.*` pack did not already name, and the `formatFieldChange`
1198
+ // sentences, which are assembled in code and so need interpolation holes.
1199
+ allFilter: 'Tout',
1200
+ createsFilter: 'Créations',
1201
+ deletesFilter: 'Suppressions',
1202
+ statusChangesFilter: 'Changements de statut',
1203
+ activityEmptyValue: '(vide)',
1204
+ activityFieldChanged: '{{field}} modifié de « {{old}} » à « {{new}} »',
1205
+ activityCreated: 'A créé cet enregistrement',
1206
+ activityDeleted: 'A supprimé cet enregistrement',
1207
+ activityStatusChanged: 'A changé le statut en « {{value}} »',
1208
+ activityUpdated: 'A mis à jour l\'enregistrement',
943
1209
  loadMore: "Charger plus",
944
1210
  edited: "(modifié)",
945
1211
  via: "via {{source}}",
946
1212
  viewSource: "Voir la source",
947
1213
  replyCount: "{{count}} réponse",
948
- replyCountPlural: "{{count}} réponses",
1214
+ replyCount_one: "{{count}} réponse",
1215
+ replyCount_many: "{{count}} de réponses",
1216
+ replyCount_other: "{{count}} réponses",
949
1217
  replyPlaceholder: "Répondre…",
950
1218
  filterActivity: "Filtrer l'activité",
951
1219
  openDiscussion: "Ouvrir le panneau de discussion",
@@ -957,9 +1225,12 @@ const fr = {
957
1225
  lockedByApproval: "Verrouillé pour approbation",
958
1226
  lockedTooltip: "Cet enregistrement a une demande d'approbation en attente ; la modification est verrouillée",
959
1227
  writeStrippedTitle: "Enregistré — mais certains champs n'ont pas été appliqués",
1228
+ writeWarningsTitle: "Enregistré — avec des avertissements",
960
1229
  writeStrippedReadonly: "En lecture seule, donc non appliqué : {{fields}}",
961
1230
  writeStrippedByState: "Non modifiable dans l'état actuel de cet enregistrement, donc non appliqué : {{fields}}",
962
1231
  writeStrippedPrimaryKey: "L'identifiant de l'enregistrement ne peut pas être modifié lors d'un enregistrement, donc non appliqué : {{fields}}",
1232
+ writeStrippedComputed: "Calculé par le serveur à partir d'une formule, donc la valeur envoyée n'a pas été appliquée : {{fields}}",
1233
+ writeStrippedStoredExpression: "Calculé à partir de l'enregistrement, donc la valeur calculée a été enregistrée à la place de celle envoyée : {{fields}}",
963
1234
  writeStrippedUnknownReason: "Non appliqué par le serveur : {{fields}}",
964
1235
  approvalPendingEditable: "En approbation · modifiable",
965
1236
  approvalPendingTooltip: "Cet enregistrement a une demande d'approbation en attente ; cette étape autorise encore la modification",
@@ -981,6 +1252,13 @@ const fr = {
981
1252
  pathStageLostUpcoming: '{{stage}}, perdue, non atteinte',
982
1253
  pathStageWonUpcoming: '{{stage}}, étape objectif, non atteinte',
983
1254
  linkCopied: "Lien copié dans le presse-papiers",
1255
+ commentFailed: "Votre commentaire n'a pas été publié. Rien n'a été enregistré — veuillez réessayer.",
1256
+ reactionFailed: "Votre réaction n'a pas été enregistrée. Veuillez réessayer.",
1257
+ editComment: "Modifier le commentaire",
1258
+ deleteComment: "Supprimer le commentaire",
1259
+ deleteCommentConfirm: "Êtes-vous sûr de vouloir supprimer ce commentaire ?",
1260
+ commentEditFailed: "Votre modification n'a pas été enregistrée. Le commentaire conserve son texte précédent.",
1261
+ commentDeleteFailed: "Le commentaire n'a pas été supprimé. Veuillez réessayer.",
984
1262
  linkCopyFailed: "Impossible de copier le lien",
985
1263
  cancel: "Annuler",
986
1264
  cancelEdit: "Abandonner les modifications",
@@ -1010,39 +1288,68 @@ const fr = {
1010
1288
  sortBy: "Trier par",
1011
1289
  filterPlaceholder: "Filtrer…",
1012
1290
  highlightFields: "Champs clés",
1291
+ highlightsLabel: "Champs clés de l'enregistrement",
1013
1292
  createdBy: "Créé par",
1014
1293
  updatedBy: "Mis à jour par",
1015
- // objectui#3863 — base key. fr has a third category, `many`, which CLDR uses from
1016
- // a million up; the plural form is correct there, so the base repeats `_other`
1017
- // rather than restructuring (unlike ru/ar, whose unenumerated categories cover
1018
- // everyday counts).
1294
+ // objectui#3863 — base key, answering only a call made without a count. fr's
1295
+ // third category, `many` (exact millions), has its own slot since objectui#11432;
1296
+ // here it repeats `_other` because the count governs no noun ("de" goes before a
1297
+ // noun complement, and this label has none).
1019
1298
  showEmptyRelated: "+ {{count}} vides",
1020
1299
  showEmptyRelated_one: "+ {{count}} vide",
1300
+ showEmptyRelated_many: "+ {{count}} vides",
1021
1301
  showEmptyRelated_other: "+ {{count}} vides",
1022
1302
  copyEmail: "Copier l'e-mail",
1023
1303
  copyPhone: "Copier le téléphone",
1024
1304
  copyRecordId: "Copier l'ID",
1025
1305
  showEmptyFields: "Afficher {{count}} champs vides",
1306
+ showEmptyFields_one: "Afficher {{count}} champ vide",
1307
+ showEmptyFields_many: "Afficher {{count}} de champs vides",
1308
+ showEmptyFields_other: "Afficher {{count}} champs vides",
1026
1309
  hideEmptyFields: "Masquer les champs vides",
1027
1310
  noValue: "Aucune valeur",
1311
+ unresolvedReference: "Référence non résolue : {{value}} n'a pas été résolue en utilisateur",
1312
+ unresolvedLookupReference: "Référence non résolue : {{value}} n'a pas été résolue en enregistrement sur cet écran",
1313
+ repeaterItemCount: "{{count}} éléments",
1314
+ repeaterItemCount_one: "{{count}} élément",
1315
+ repeaterItemCount_many: "{{count}} d'éléments",
1316
+ repeaterItemCount_other: "{{count}} éléments",
1317
+ fileCount: "{{count}} fichiers",
1318
+ fileCount_one: "{{count}} fichier",
1319
+ fileCount_many: "{{count}} de fichiers",
1320
+ fileCount_other: "{{count}} fichiers",
1028
1321
  },
1029
1322
  chart: {
1030
- noData: "Aucune donnée de graphique disponible",
1031
1323
  loading: "Chargement du graphique…",
1324
+ refreshing: "Actualisation…",
1032
1325
  nullCategory: "(Non défini)",
1033
- },
1034
- map: {
1035
- searchLocations: "Rechercher des lieux…",
1036
- locationDetails: "Détails du lieu",
1037
- markersCount: "{{count}} marqueurs",
1038
- invalidCoordinates: "{{count}} enregistrement avec des coordonnées manquantes ou invalides exclu de la carte.",
1039
- invalidCoordinatesPlural: "{{count}} enregistrements avec des coordonnées manquantes ou invalides exclus de la carte.",
1326
+ scatterOneMeasure: "Un nuage de points trace une seule mesure. Ne conservez qu’une série :",
1327
+ unconfigured: {
1328
+ noCategoryAxis: "Axe de catégories requis — un graphique lié à un objet n’en invente pas. Déclarez l’un des suivants :",
1329
+ },
1040
1330
  },
1041
1331
  dashboard: {
1042
- noRows: "Aucune ligne",
1332
+ // objectui#7063 — the DEFAULT empty state every dashboard widget renders
1333
+ // when its query SUCCEEDED and returned nothing. It replaced the terse
1334
+ // per-widget `noRows` / `noDataAvailable` fragments at the render site;
1335
+ // objectui#7125 deleted those two keys from all ten packs once nothing
1336
+ // read them. The copy here has to read as a state rather than a failure,
1337
+ // which is why it says the widget loaded. `sourceLabel` carries its own
1338
+ // punctuation so the call site concatenates no separator (see
1339
+ // `WidgetEmptyState`).
1340
+ empty: {
1341
+ title: "Pas encore de données",
1342
+ message: "Ce widget s'est chargé correctement, mais la requête n'a encore renvoyé aucun enregistrement.",
1343
+ sourceLabel: "Source de données :",
1344
+ },
1043
1345
  loading: "Chargement…",
1346
+ refreshing: "Actualisation…",
1347
+ refreshAll: "Tout actualiser",
1348
+ refreshDashboard: "Actualiser le tableau de bord",
1044
1349
  pickMeasures: "Choisissez des mesures (valeurs) pour ce widget de dataset.",
1045
1350
  datasetUnsupported: "Cette source de données ne prend pas en charge les requêtes de dataset.",
1351
+ widgetForbiddenTitle: "Accès refusé",
1352
+ widgetForbiddenMessage: "Vous n’avez pas l’autorisation de voir les données de ce widget.",
1046
1353
  details: "Détails",
1047
1354
  exportCsv: "Exporter en CSV",
1048
1355
  openInList: "Ouvrir dans la liste",
@@ -1070,12 +1377,10 @@ const fr = {
1070
1377
  },
1071
1378
  },
1072
1379
  addWidget: "Ajouter un widget",
1073
- removeWidget: "Supprimer un widget",
1074
1380
  editLayout: "Modifier la mise en page",
1075
1381
  saveLayout: "Enregistrer la mise en page",
1076
1382
  resetLayout: "Réinitialiser la mise en page",
1077
1383
  total: "Total",
1078
- noDataAvailable: "Aucune donnée disponible",
1079
1384
  noDataSourceFor: "Aucune source de données pour",
1080
1385
  config: {
1081
1386
  breadcrumb: {
@@ -1197,10 +1502,6 @@ const fr = {
1197
1502
  appDescription: "Description",
1198
1503
  appIcon: "Icône",
1199
1504
  template: "Modèle",
1200
- layout: "Disposition",
1201
- layoutSidebar: "Barre latérale",
1202
- layoutHeader: "En-tête",
1203
- layoutEmpty: "Vide",
1204
1505
  selectObjects: "Sélectionner des objets",
1205
1506
  searchObjects: "Rechercher des objets…",
1206
1507
  selectAll: "Tout sélectionner",
@@ -1209,7 +1510,6 @@ const fr = {
1209
1510
  addGroup: "Ajouter un groupe",
1210
1511
  addUrl: "Ajouter une URL",
1211
1512
  addSeparator: "Ajouter un séparateur",
1212
- noNavItems: "Aucun élément de navigation pour l'instant.",
1213
1513
  logoUrl: "URL du logo",
1214
1514
  primaryColor: "Couleur principale",
1215
1515
  faviconUrl: "URL du favicon",
@@ -1236,13 +1536,12 @@ const fr = {
1236
1536
  appearance: "Apparence",
1237
1537
  rowHeight: "Hauteur de ligne",
1238
1538
  livePreview: "Aperçu en direct",
1239
- stepBasicDesc: "Nom, titre et mise en page",
1539
+ stepBasicDesc: "Nom, titre et icône",
1240
1540
  stepObjectsDesc: "Sélectionner les objets métier",
1241
1541
  stepNavigationDesc: "Construire l'arbre de navigation",
1242
1542
  stepBrandingDesc: "Logo, couleurs et favicon",
1243
1543
  noObjectsFound: "Aucun objet trouvé.",
1244
1544
  noNavItemsHint: "Pas encore d'éléments de navigation. Sélectionnez des objets à l'étape précédente ou ajoutez-en manuellement.",
1245
- separator: "Séparateur",
1246
1545
  separatorLabel: "— Séparateur —",
1247
1546
  newGroup: "Nouveau groupe",
1248
1547
  newLink: "Nouveau lien",
@@ -1276,6 +1575,7 @@ const fr = {
1276
1575
  navTypeSeparator: "Séparateur",
1277
1576
  navTypeAction: "Action",
1278
1577
  navTypeComponent: "Composant",
1578
+ navTypeDoc: "Document",
1279
1579
  navEditIcon: "Modifier l'icône",
1280
1580
  navToggleVisible: "Basculer la visibilité",
1281
1581
  navHidden: "Masqué",
@@ -1353,11 +1653,8 @@ const fr = {
1353
1653
  defaultValue: "Valeur par défaut",
1354
1654
  placeholder: "Espace réservé",
1355
1655
  referenceTo: "Référence à",
1356
- formula: "Formule",
1357
1656
  options: "Options",
1358
1657
  addOption: "Ajouter une option",
1359
- validationRules: "Règles de validation",
1360
- addRule: "Ajouter une règle",
1361
1658
  systemBadge: "Système",
1362
1659
  ungrouped: "Général",
1363
1660
  deleteConfirmTitle: "Supprimer le champ ?",
@@ -1376,16 +1673,33 @@ const fr = {
1376
1673
  },
1377
1674
  },
1378
1675
  console: {
1676
+ studio: {
1677
+ title: "Studio",
1678
+ accessRequired: "Vous avez besoin de l'accès à Studio pour ouvrir Studio.",
1679
+ },
1379
1680
  saveAdvisoryTitle: "Enregistré — le contrôle de création a signalé {{count}} recommandation(s)",
1681
+ saveAdvisoryTitle_one: "Enregistré — le contrôle de création a signalé {{count}} recommandation",
1682
+ saveAdvisoryTitle_many: "Enregistré — le contrôle de création a signalé {{count}} de recommandations",
1683
+ saveAdvisoryTitle_other: "Enregistré — le contrôle de création a signalé {{count}} recommandations",
1684
+ publishAdvisoryTitle: "Publié — le contrôle de création a signalé {{count}} recommandation(s)",
1685
+ publishAdvisoryTitle_one: "Publié — le contrôle de création a signalé {{count}} recommandation",
1686
+ publishAdvisoryTitle_many: "Publié — le contrôle de création a signalé {{count}} de recommandations",
1687
+ publishAdvisoryTitle_other: "Publié — le contrôle de création a signalé {{count}} recommandations",
1688
+ importMappingsUnavailable: "Impossible de charger les mappages d’import enregistrés pour {{object}}",
1689
+ importMappingsRefused: "Le serveur a refusé cette requête : cette liste est donc vide parce qu’elle n’a pas pu être lue, et non parce que rien n’est enregistré. Reconnectez-vous ou demandez un accès à un administrateur.",
1690
+ importMappingsUnreadable: "Cette liste est vide parce qu’elle n’a pas pu être lue, et non parce que rien n’est enregistré. Réessayez, et signalez le problème s’il persiste.",
1691
+ savedViewsUnavailable: "Impossible de charger les vues enregistrées pour {{object}}",
1692
+ savedViewsRefused: "Le serveur a refusé cette requête : cette liste est donc vide parce qu’elle n’a pas pu être lue, et non parce que cet objet n’aurait aucune vue enregistrée. Reconnectez-vous ou demandez un accès à un administrateur.",
1693
+ savedViewsUnreadable: "Cette liste est vide parce qu’elle n’a pas pu être lue, et non parce que cet objet n’aurait aucune vue enregistrée. Réessayez, et signalez le problème s’il persiste.",
1380
1694
  settingsHub: {
1381
1695
  title: "Paramètres",
1382
- subtitle: "Configurez votre espace de travail, vos intégrations et vos indicateurs de fonctionnalité.",
1696
+ subtitle: "Configurez votre système, vos intégrations et vos indicateurs de fonctionnalité.",
1383
1697
  loadError: "Échec du chargement des paramètres",
1384
1698
  empty: "Aucun paramètre enregistré. Les plugins peuvent enregistrer des manifestes de paramètres via le SettingsService.",
1385
1699
  settingsCount: "{{n}} paramètres",
1386
1700
  beta: "Bêta",
1387
1701
  categories: {
1388
- Workspace: "Espace de travail",
1702
+ Workspace: "Général",
1389
1703
  Communication: "Communication",
1390
1704
  Security: "Sécurité",
1391
1705
  Infrastructure: "Infrastructure",
@@ -1430,13 +1744,20 @@ const fr = {
1430
1744
  },
1431
1745
  usage: {
1432
1746
  title: "Utilisation de l'IA",
1433
- meterBuild: "Créer",
1434
- meterAsk: "Demander",
1747
+ poolUsed: "{{percent}} utilisé",
1435
1748
  statusOk: "Il en reste beaucoup",
1436
1749
  statusLow: "Bientôt épuisé",
1437
1750
  statusFull: "Limite atteinte",
1438
1751
  resetsDaily: "Réinitialisation ce soir",
1439
1752
  resetsMonthly: "Réinitialisation au prochain cycle",
1753
+ resetsWeeklyDays: "Réinitialisation dans {{count}} jours",
1754
+ resetsWeeklyDays_one: "Réinitialisation dans {{count}} jour",
1755
+ resetsWeeklyDays_many: "Réinitialisation dans {{count}} de jours",
1756
+ resetsWeeklyDays_other: "Réinitialisation dans {{count}} jours",
1757
+ resetsWeeklyHours: "Réinitialisation dans {{count}} heures",
1758
+ resetsWeeklyHours_one: "Réinitialisation dans {{count}} heure",
1759
+ resetsWeeklyHours_many: "Réinitialisation dans {{count}} d'heures",
1760
+ resetsWeeklyHours_other: "Réinitialisation dans {{count}} heures",
1440
1761
  ctaUpgrade: "Passer à l'offre supérieure pour continuer",
1441
1762
  ctaTopUp: "Ajouter des crédits pour continuer",
1442
1763
  ariaLabel: "Utilisation de l'IA : {{status}}",
@@ -1449,6 +1770,31 @@ const fr = {
1449
1770
  share: "Partager",
1450
1771
  shareTitle: "Partager cette conversation",
1451
1772
  shareDisabledTitle: "Commencez à discuter pour activer le partage",
1773
+ buildDoctor: "Diagnostic de build",
1774
+ buildDoctorTitle: "Diagnostic de build — qu'est-ce qui a réellement été appliqué ?",
1775
+ buildDoctorDisabledTitle: "Envoyez d'abord un message",
1776
+ buildDoctorDrawer: {
1777
+ description: "Ce que l'agent a annoncé face à ce qui est réellement en ligne. Diagnostic en lecture seule.",
1778
+ reconciling: 'Rapprochement…',
1779
+ notAvailable: "Non disponible — la conversation est introuvable ou vous n'êtes pas autorisé.",
1780
+ untitled: '(sans titre)',
1781
+ summary: '{{turns}} tour(s) · {{messages}} msg · {{tokens}} jetons · {{seconds}} s LLM',
1782
+ allLive: "Les {{count}} modification(s) tentée(s) sont en ligne — rien ne s'est perdu.",
1783
+ discrepancies: '{{count}} écart(s) — ce que le chat a annoncé ne correspond pas à ce qui est en ligne.',
1784
+ orphanedTitle: 'Proposé mais jamais appliqué',
1785
+ orphanedHint: "Une carte de confirmation proposée par l'agent qu'aucun tour ultérieur n'a appliquée — la modification s'est perdue silencieusement.",
1786
+ missingTitle: 'Annoncé mais absent',
1787
+ missingHint: "Un résultat d'outil indiquait une application, mais l'artefact n'est pas en ligne dans sys_metadata.",
1788
+ toolErrorsTitle: "Erreurs d'outils",
1789
+ toolErrorsHint: "Appels d'outils ayant renvoyé une erreur pendant le build.",
1790
+ verifyTitle: 'Vérification du build (verify_build)',
1791
+ yourApp: 'Votre application :',
1792
+ noIssues: '0 problème',
1793
+ issueCount: '{{count}} problème(s)',
1794
+ platformNoise: '{{count}} constat(s) sys_* de la plateforme masqué(s)',
1795
+ pendingActions: 'Actions en attente',
1796
+ timeline: 'Chronologie ({{count}})',
1797
+ },
1452
1798
  newChat: "Nouveau",
1453
1799
  searchChats: "Rechercher des discussions…",
1454
1800
  noChatsYet: "Aucune discussion pour l'instant",
@@ -1471,6 +1817,8 @@ const fr = {
1471
1817
  liveCanvasUnlisted: "Application en direct — {{app}} (non répertoriée jusqu'à publication)",
1472
1818
  loadingAgents: "Chargement des agents…",
1473
1819
  askAnything: "Posez n'importe quelle question…",
1820
+ askOrChangeApp: "Posez une question sur vos données ou demandez-moi de modifier cette app…",
1821
+ describeAppToBuild: "Décrivez l’app que vous voulez créer, ou ce qu’il faut modifier…",
1474
1822
  emptyTitle: "Démarrer une conversation",
1475
1823
  emptyDescription: "Posez n'importe quelle question — l'assistant a accès au contexte de votre application actuelle.",
1476
1824
  switchAssistant: "Changer d'assistant",
@@ -1478,7 +1826,7 @@ const fr = {
1478
1826
  empty: {
1479
1827
  build: {
1480
1828
  title: "Créer avec l'IA",
1481
- description: "Décrivez une application ou un flux de travail en langage courant — je rédige les objets, les écrans et les automatisations, puis vous vérifiez et publiez.",
1829
+ description: "Décrivez une application en langage courant — je rédige les objets, les écrans et les données d'exemple, puis vous vérifiez et publiez.",
1482
1830
  },
1483
1831
  ask: {
1484
1832
  title: "Interroger vos données",
@@ -1487,17 +1835,22 @@ const fr = {
1487
1835
  editApp: {
1488
1836
  title: "Modification de « {{app}} »",
1489
1837
  titleGeneric: "Modifier cette application",
1490
- description: "Que souhaitez-vous changer ? Je modifie cette application sur place — ajouter un champ, un objet, une vue ou une automatisation, ou ajuster l'existant.",
1838
+ description: "Que souhaitez-vous changer ? Je modifie cette application sur place — ajouter un champ, un objet, une vue ou un tableau de bord, ou ajuster l'existant.",
1491
1839
  },
1492
1840
  },
1493
1841
  clearConversation: "Effacer",
1494
1842
  sendHint: "pour envoyer",
1843
+ newlineHint: "pour un retour à la ligne",
1495
1844
  agentActivity: "Activité de l'agent",
1496
1845
  toolCompleted: "Terminé",
1497
1846
  toolRunning: "En cours",
1498
1847
  toolAwaitingApproval: "En attente d'approbation",
1499
1848
  toolFailed: "Échec",
1500
1849
  toolDetailsHidden: "Les entrées des outils et les résultats bruts sont masqués dans cette vue.",
1850
+ toolDenyReason: "Rejeté par l'opérateur depuis le chat",
1851
+ builderHandoffTitle: "Créer dans le constructeur",
1852
+ builderHandoffOpen: "Ouvrir dans le constructeur →",
1853
+ builderHandoffSuperseded: "Une demande plus récente est disponible",
1501
1854
  copy: "Copier",
1502
1855
  copied: "Copié",
1503
1856
  regenerate: "Régénérer",
@@ -1512,7 +1865,7 @@ const fr = {
1512
1865
  publishOk: "Publié — les objets sont maintenant actifs.",
1513
1866
  seedWarn: "Publié, mais certaines données d'exemple n'ont pas pu être chargées.",
1514
1867
  openBuiltApp: "Ouvrir l'application",
1515
- designBuiltApp: "Concevoir dans Studio",
1868
+ viewBuiltAppInStudio: "Voir dans Studio",
1516
1869
  previewDraft: "Aperçu",
1517
1870
  previewApp: "Aperçu de l'application",
1518
1871
  resizeSplit: "Redimensionner la discussion et l'aperçu",
@@ -1540,23 +1893,41 @@ const fr = {
1540
1893
  recentRecords: "Liste les 5 enregistrements créés le plus récemment.",
1541
1894
  recordCounts: "Compte les enregistrements pour chaque objet.",
1542
1895
  },
1896
+ // cloud#1984 — these five chips are the maker's own recommendations, so
1897
+ // they may only ask for what ADR-0112 v1 BUILDS: objects, fields, views
1898
+ // (grid/kanban/calendar/gallery), pages, dashboards and sample data. No
1899
+ // wording that promises autonomous behaviour (alert / remind / notify /
1900
+ // automate / status workflow) — v1 has no flows, actions or schedules, and
1901
+ // the model silently degrades such a request into a board or a filtered
1902
+ // view, so the chip would promise an alert and deliver a page. REVERT to
1903
+ // the automation wording when ADR-0112 v2 re-adds flows and actions.
1543
1904
  metadataAssistant: {
1544
- buildCrm: "Crée un CRM commercial — clients, contacts et un pipeline d'affaires que je peux totaliser par étape.",
1545
- buildApp: "Crée un suivi de projets — projets, tâches avec responsables et échéances, et un tableau par statut.",
1546
- buildFlow: "Conçois un service d'assistance — tickets avec priorité, un flux de statuts et des liens vers les clients.",
1547
- buildInventory: "Crée une application de stock — produits, niveaux de stock, fournisseurs et visibilité des stocks faibles.",
1548
- buildRecruiting: "Crée un suivi de candidatures — candidats, postes ouverts, étapes d'entretien et notes.",
1905
+ buildCrm: "Crée un CRM commercial — clients, contacts et affaires avec un champ étape, plus un tableau de bord qui totalise le montant par étape.",
1906
+ buildApp: "Crée un suivi de projets — projets, tâches avec responsables et échéances, un tableau par statut et un calendrier des échéances.",
1907
+ buildFlow: "Conçois un service d'assistance — tickets avec des champs priorité et statut, un tableau par statut et des liens vers les clients.",
1908
+ buildInventory: "Crée une application de stock — produits, niveaux de stock, fournisseurs et une vue qui filtre les articles sous leur seuil de réapprovisionnement.",
1909
+ buildRecruiting: "Crée un suivi de candidatures — candidats, postes ouverts, un champ étape d'entretien et un tableau par étape.",
1549
1910
  },
1550
1911
  generic: {
1551
1912
  help: "En quoi peux-tu m'aider ?",
1552
1913
  availableObjects: "Liste les objets de données disponibles.",
1553
1914
  recentActivity: "Résume mon activité récente.",
1554
1915
  },
1916
+ // objectui#7709 — the edit-mode starters, shown when the maker is bound
1917
+ // to an EXISTING app (`?package=`). Same rule as the five above: they
1918
+ // may only ask for what ADR-0112 v1 BUILDS. The fourth chip used to be
1919
+ // `addAutomation` ("an approval, a status flow, or a notification") and
1920
+ // every capability it named is refused by v1 (cloud#1956 / PR #1970), so
1921
+ // it now asks for sample data — `seed` IS on v1's whitelist, and having
1922
+ // no data is what an existing app most often lacks. REVERT: when
1923
+ // ADR-0112 v2 re-adds flows and actions, THIS chip's automation wording
1924
+ // comes back as `addAutomation`; the retired string is pinned for every
1925
+ // pack in `packages/i18n/src/__tests__/makerEditChips-v1-scope-7709.test.ts`.
1555
1926
  editApp: {
1556
1927
  addField: "Ajoute un champ à l'un des objets.",
1557
1928
  addObject: "Ajoute un nouvel objet et relie-le à un objet existant.",
1558
1929
  addDashboard: "Ajoute un tableau de bord pour les indicateurs clés.",
1559
- addAutomation: "Ajoute une automatisation — une approbation, un flux de statuts ou une notification.",
1930
+ addSampleData: "Remplis les objets existants avec des données d'exemple réalistes pour que je puisse présenter l'application.",
1560
1931
  },
1561
1932
  },
1562
1933
  changesTitle: "Confirmer les modifications",
@@ -1621,6 +1992,7 @@ const fr = {
1621
1992
  collapse: "Réduire la discussion",
1622
1993
  maximize: "Ouvrir en pleine page",
1623
1994
  open: "Ouvrir l'assistant",
1995
+ planAwaitingApproval: "Un plan proposé attend votre approbation",
1624
1996
  },
1625
1997
  group: {
1626
1998
  today: "Aujourd'hui",
@@ -1631,13 +2003,17 @@ const fr = {
1631
2003
  },
1632
2004
  },
1633
2005
  title: "Console ObjectStack",
1634
- initializing: "Initialisation de l'application…",
1635
- loadingHint: "La configuration d'un nouvel environnement peut prendre quelques instants.",
2006
+ initializing: "Ouverture de votre console…",
2007
+ skipToContent: "Aller au contenu",
1636
2008
  breadcrumb: {
1637
- dashboards: "Tableaux de bord",
1638
- pages: "Pages",
1639
- reports: "Rapports",
1640
2009
  system: "Système",
2010
+ marketplace: "Marketplace",
2011
+ settings: 'Paramètres',
2012
+ apps: 'Applications',
2013
+ profile: 'Profil',
2014
+ approvals: 'Approbations',
2015
+ aiApprovals: 'Approbations IA',
2016
+ auditLog: "Journal d'audit",
1641
2017
  },
1642
2018
  // objectui#4024 — the single-namespace settings screen. Its sibling
1643
2019
  // `settingsHub` above already resolved through this pack; the view was the
@@ -1657,17 +2033,33 @@ const fr = {
1657
2033
  saveChanges: "Enregistrer les modifications",
1658
2034
  unsavedCount: "{{count}} modifications non enregistrées",
1659
2035
  unsavedCount_one: "{{count}} modification non enregistrée",
2036
+ unsavedCount_many: "{{count}} de modifications non enregistrées",
1660
2037
  unsavedCount_other: "{{count}} modifications non enregistrées",
2038
+ fieldErrorsToast: "{{count}} paramètres nécessitent votre attention : {{settings}}",
2039
+ fieldErrorsToast_one: "{{count}} paramètre nécessite votre attention : {{settings}}",
2040
+ fieldErrorsToast_many: "{{count}} de paramètres nécessitent votre attention : {{settings}}",
2041
+ fieldErrorsToast_other: "{{count}} paramètres nécessitent votre attention : {{settings}}",
1661
2042
  cryptoRefusalTitle: "Ce déploiement ne peut pas chiffrer les secrets",
1662
2043
  cryptoRefusalSubjectSuffix: "est déclaré chiffré, aucune écriture n'a donc eu lieu.",
1663
2044
  cryptoRefusalNoSubject: "La valeur déclarée chiffrée a été refusée, aucune écriture n'a donc eu lieu.",
1664
2045
  cryptoRefusalToast: "Impossible de chiffrer les secrets : {{subject}}",
1665
2046
  cryptoRefusalToastNoSubject: "Impossible de chiffrer les secrets",
1666
- },
1667
- loadingSteps: {
1668
- connecting: "Connexion à la source de données",
1669
- loadingConfig: "Chargement de la configuration",
1670
- preparingWorkspace: "Préparation de l'espace de travail",
2047
+ sourceBadgeInherited: "Hérité de {{source}}",
2048
+ sourceBadgeOverrides: "Remplace {{source}}",
2049
+ resetToDefault: "Rétablir la valeur par défaut",
2050
+ envLockBadge: "Verrouillé par l'env.",
2051
+ envLockBadgeTitle: "Fixé par une variable d'environnement — modification impossible depuis l'interface.",
2052
+ deprecatedBadge: "Obsolète",
2053
+ deprecatedBadgeReplacedBy: "Obsolète → {{replacedBy}}",
2054
+ unsupportedSpecifierType: "Type de paramètre non pris en charge : {{type}}",
2055
+ },
2056
+ workspaceTimezonePrompt: {
2057
+ title: "Définir le fuseau horaire du système",
2058
+ description: "Ce système utilise encore le fuseau horaire par défaut de la plateforme, {{current}}. Le fuseau horaire du système détermine ce que signifie « aujourd’hui » dans les formules, la façon dont les rapports regroupent les dates et l’affichage des dates et des heures, pour tous les utilisateurs du système. Le fuseau horaire de votre navigateur est renseigné ci-dessous.",
2059
+ laterHint: "Vous pouvez le modifier à tout moment sur la page Paramètres.",
2060
+ decline: "Conserver la valeur par défaut",
2061
+ confirm: "Définir le fuseau horaire",
2062
+ saved: "Fuseau horaire du système défini sur {{zone}}",
1671
2063
  },
1672
2064
  error: {
1673
2065
  connectionFailed: "Impossible de se connecter au serveur",
@@ -1692,27 +2084,28 @@ const fr = {
1692
2084
  groups: {
1693
2085
  general: "Général",
1694
2086
  navigation: "Navigation",
1695
- dataViews: "Vues de données",
1696
2087
  aiChat: "Assistant IA",
1697
- preferences: "Préférences",
1698
2088
  },
1699
2089
  openCommandPalette: "Ouvrir la palette de commandes",
1700
2090
  showShortcuts: "Afficher les raccourcis clavier",
1701
2091
  closeDialog: "Fermer le dialogue / panneau",
1702
2092
  toggleSidebar: "Basculer la barre latérale",
1703
- focusSearch: "Focus sur la recherche",
1704
- createRecord: "Créer un nouvel enregistrement",
1705
- refreshData: "Actualiser les données",
1706
- editRecord: "Modifier l'enregistrement sélectionné",
1707
2093
  newChat: "Nouvelle discussion",
1708
2094
  toggleChatsList: "Basculer la liste des discussions",
1709
- toggleDarkMode: "Basculer le mode sombre",
2095
+ goHome: "Retour à l'accueil",
2096
+ },
2097
+ reportIndex: {
2098
+ title: "Rapports",
2099
+ emptyTitle: "Aucun rapport",
2100
+ emptyDescription: "Cette application n’a aucun rapport que vous pouvez ouvrir.",
1710
2101
  },
1711
2102
  commandPalette: {
1712
2103
  title: "Palette de commandes",
1713
2104
  placeholder: "Tapez une commande ou recherchez…",
1714
2105
  noResults: "Aucun résultat trouvé.",
1715
2106
  objects: "Objets",
2107
+ packages: "Packages",
2108
+ flows: "Flux",
1716
2109
  dashboards: "Tableaux de bord",
1717
2110
  pages: "Pages",
1718
2111
  reports: "Rapports",
@@ -1729,6 +2122,21 @@ const fr = {
1729
2122
  records: "Enregistrements",
1730
2123
  recentRecords: "Récemment consultés",
1731
2124
  },
2125
+ // objectui#9954 — see the `en` pack for what raises each case.
2126
+ readRate: {
2127
+ ratioTitle: 'Volume de lecture inhabituel dans ce système',
2128
+ ratio: '{{ratio}} lignes sont lues pour chaque ligne écrite. La plateforme signale tout ce qui dépasse {{threshold}}. Rien n’est limité ni bloqué ; il s’agit d’un rapport permettant d’examiner le schéma de lecture.',
2129
+ noWritesTitle: 'Lectures sans aucune écriture dans ce système',
2130
+ noWrites: 'Des lignes sont lues alors qu’aucune n’est écrite, de sorte que le taux de lecture n’a aucune limite supérieure. C’est la mesure la plus grave. La plateforme signale tout ce qui dépasse {{threshold}}. Rien n’est limité ni bloqué ; il s’agit d’un rapport permettant d’examiner le schéma de lecture.',
2131
+ },
2132
+ // objectui#10439 — see the `en` pack for what raises each case.
2133
+ storageUsage: {
2134
+ warningTitle: 'Le stockage est presque plein',
2135
+ warning: '{{used}} Mo sur {{limit}} Mo utilisés. Les envois et les importations sont suspendus dès que le stockage est plein.',
2136
+ blockedTitle: 'Stockage plein : les envois et les importations sont suspendus',
2137
+ blocked: "{{used}} Mo sur {{limit}} Mo utilisés. Les données existantes ne sont pas modifiées, et la lecture, l'export et la modification d'enregistrements individuels fonctionnent toujours.",
2138
+ upgrade: "Passer à l'offre supérieure pour continuer",
2139
+ },
1732
2140
  errors: {
1733
2141
  somethingWentWrong: "Quelque chose s'est mal passé",
1734
2142
  unexpectedError: "Une erreur inattendue est survenue lors du rendu de cette vue.",
@@ -1759,22 +2167,27 @@ const fr = {
1759
2167
  viewNameInvalid: "Utilisez des minuscules, des chiffres et des tirets bas ; commencez par une lettre ou un tiret bas.",
1760
2168
  systemViewReadonly: "Vue système définie dans le code — en lecture seule.",
1761
2169
  cannotEditMetaView: "Cette vue est intégrée et définie dans le code — elle ne peut pas être modifiée.",
2170
+ resetView: "Réinitialiser la vue",
2171
+ resetViewTitle: "Rétablir le tri, les filtres et les largeurs de colonnes propres à cette vue. Seuls vos réglages changent.",
1762
2172
  cannotDeleteMetaView: "Cette vue est intégrée et définie dans le code — elle ne peut pas être supprimée.",
1763
2173
  expandToPage: "Ouvrir en pleine page",
1764
2174
  objectNotFound: "Objet introuvable",
1765
2175
  objectNotFoundDescription: "L'objet « {{objectName}} » n'existe pas dans la configuration actuelle.",
1766
2176
  objectNotFoundHint: "Vérifiez les paramètres de navigation de votre application ou sélectionnez un autre objet dans la barre latérale.",
2177
+ objectPackageDisabled: "L'objet « {{objectName}} » appartient à un package désactivé et n'est donc pas servi.",
1767
2178
  filterOrNotSavable: "Ce filtre relie les conditions par OU, ce qu'une vue enregistrée ne peut pas encore stocker. Il s'applique toujours à cette liste — supprimez le groupement OU pour l'enregistrer dans la vue.",
1768
2179
  filterNestedNotSavable: "Ce filtre utilise des groupes de conditions imbriqués, qu'une vue enregistrée ne peut pas stocker. Aplatissez-le en une seule liste de conditions pour l'enregistrer dans la vue.",
1769
2180
  allRecords: "Tous les enregistrements",
1770
2181
  new: "Nouveau",
1771
2182
  configureView: "Configurer la vue",
1772
- toolbar: "Barre d'outils",
1773
2183
  toolbarEnabledCount: "{{count}} sur {{total}} activés",
1774
2184
  searchFields: "Rechercher des champs…",
1775
2185
  title: "Titre",
1776
2186
  viewType: "Type de vue",
1777
2187
  recordCount: "{{count}} enregistrements",
2188
+ recordCount_one: "{{count}} enregistrement",
2189
+ recordCount_many: "{{count}} d'enregistrements",
2190
+ recordCount_other: "{{count}} enregistrements",
1778
2191
  save: "Enregistrer",
1779
2192
  discard: "Annuler",
1780
2193
  createView: "Créer une vue",
@@ -1786,11 +2199,13 @@ const fr = {
1786
2199
  longitudeField: "Champ de longitude",
1787
2200
  imageField: "Champ d'image",
1788
2201
  selectField: "Sélectionner un champ…",
1789
- groupBy: "Regrouper par",
1790
2202
  endDateField: "Champ de date de fin",
1791
2203
  import: "Importer",
1792
2204
  importTitle: "Importer depuis CSV",
1793
2205
  importedToast: "{{count}} ligne(s) importée(s).",
2206
+ importedToast_one: "{{count}} ligne importée.",
2207
+ importedToast_many: "{{count}} de lignes importées.",
2208
+ importedToast_other: "{{count}} lignes importées.",
1794
2209
  importedWithSkipped: "{{ok}} ligne(s) importée(s) ; {{skipped}} ignorée(s).",
1795
2210
  createViewDesc: "Choisissez un type de vue et donnez-lui un nom. Tous les paramètres peuvent être modifiés ensuite.",
1796
2211
  cancel: "Annuler",
@@ -1799,6 +2214,9 @@ const fr = {
1799
2214
  deleteViewTitle: "Supprimer la vue",
1800
2215
  deleteViewConfirm: "Supprimer la vue \"{{name}}\" ? Ceci est irréversible.",
1801
2216
  bulkDeleteConfirm: "Supprimer {{count}} enregistrements sélectionnés ? Ceci est irréversible.",
2217
+ bulkDeleteConfirm_one: "Supprimer {{count}} enregistrement sélectionné ? Ceci est irréversible.",
2218
+ bulkDeleteConfirm_many: "Supprimer {{count}} d'enregistrements sélectionnés ? Ceci est irréversible.",
2219
+ bulkDeleteConfirm_other: "Supprimer {{count}} enregistrements sélectionnés ? Ceci est irréversible.",
1802
2220
  duplicateViewName: "Une vue avec ce nom existe déjà.",
1803
2221
  viewTypeGrid: "Grille",
1804
2222
  viewTypeGridDesc: "Tableau de type tableur d'enregistrements.",
@@ -1835,14 +2253,22 @@ const fr = {
1835
2253
  chartTypePie: "Graphique circulaire",
1836
2254
  chartTypeArea: "Graphique en aires",
1837
2255
  chartTypeScatter: "Nuage de points",
1838
- xAxisField: "Champ axe X",
1839
- xAxisFieldHelp: "La dimension catégorielle ou temporelle.",
1840
- yAxisField: "Champ axe Y",
1841
- yAxisFieldHelp: "Le champ numérique à agréger.",
2256
+ dataset: "Jeu de données",
2257
+ datasetHelp: "Le graphique lit ses valeurs dans ce jeu de données de l’objet.",
2258
+ chartMeasure: "Mesure",
2259
+ chartMeasureHelp: "La mesure du jeu de données tracée sur l’axe des valeurs.",
2260
+ chartDimension: "Dimension",
2261
+ chartDimensionHelp: "La dimension du jeu de données selon laquelle les valeurs sont regroupées (facultatif).",
2262
+ viewTypeUnavailableDataset: "Cet objet n’expose aucun jeu de données à représenter.",
2263
+ noDatasetMeasure: "Ce jeu de données ne déclare aucune mesure à représenter.",
1842
2264
  ufTabs: "Onglets",
1843
2265
  ufAddField: "+ Ajouter un champ de filtre…",
1844
2266
  ufShowAllRecords: "Afficher l'onglet \"Tous les enregistrements\"",
1845
2267
  },
2268
+ runtimeDraft: {
2269
+ publishFailed: "Échec de la publication",
2270
+ discardFailed: "Échec de l'abandon du brouillon",
2271
+ },
1846
2272
  localeSwitcher: {
1847
2273
  label: "Langue",
1848
2274
  },
@@ -1850,14 +2276,22 @@ const fr = {
1850
2276
  nav: {
1851
2277
  pinItem: "Épingler {{name}}",
1852
2278
  unpinItem: "Désépingler {{name}}",
1853
- dragToReorder: "Glisser pour réorganiser",
1854
2279
  favorites: "Favoris",
2280
+ launcherLabel: "Lanceur d'applications",
2281
+ menuLabel: "Navigation de l'application",
2282
+ menuEmpty: "Cette application n'a aucune entrée de navigation que vous pouvez ouvrir.",
2283
+ itemMenu: "Plus d'actions pour {{name}}",
2284
+ openInNewTab: "Ouvrir dans un nouvel onglet",
2285
+ copyLink: "Copier le lien",
2286
+ linkCopied: "Lien copié dans le presse-papiers",
2287
+ linkCopyFailed: "Impossible de copier le lien",
2288
+ design: "Concevoir",
1855
2289
  },
1856
2290
  },
1857
2291
  auth: {
1858
2292
  setPassword: {
1859
2293
  title: "Définir un mot de passe de secours",
1860
- description: "Vous vous êtes connecté via l'authentification unique. Définissez un mot de passe local afin de pouvoir toujours vous connecter directement à cet environnement si le SSO devenait indisponible.",
2294
+ description: "Vous vous êtes connecté via l'authentification unique. Définissez un mot de passe local afin de pouvoir toujours vous connecter directement si le SSO devenait indisponible.",
1861
2295
  email: "E-mail",
1862
2296
  newPassword: "Nouveau mot de passe",
1863
2297
  confirmPassword: "Confirmer le mot de passe",
@@ -1873,9 +2307,8 @@ const fr = {
1873
2307
  signingIn: "Connexion en cours…",
1874
2308
  ssoHandoff: "Continuer vers {{target}}",
1875
2309
  devAdminHint: {
1876
- title: "Instance de développement",
1877
- body: "Connectez-vous avec l'administrateur de développement prédéfini :",
1878
- dismiss: "Ignorer",
2310
+ title: "Instance de développement locale",
2311
+ signIn: "Se connecter en tant qu'administrateur de développement",
1879
2312
  },
1880
2313
  title: "Connectez-vous à votre compte",
1881
2314
  description: "Entrez votre e-mail et votre mot de passe pour continuer",
@@ -1905,6 +2338,22 @@ const fr = {
1905
2338
  resendOtpCountdownText: "Renvoyer dans {seconds} s",
1906
2339
  usePhoneOtpText: "Se connecter avec un code de vérification",
1907
2340
  usePasswordSignInText: "Se connecter avec un mot de passe à la place",
2341
+ socialButton: "Continuer avec {provider}",
2342
+ orText: "ou continuer avec l'e-mail",
2343
+ ssoButton: "Se connecter avec le SSO",
2344
+ ssoOnlyDescription: "Connectez-vous avec l'authentification unique de votre organisation",
2345
+ usePasswordText: "Utiliser un mot de passe à la place",
2346
+ backToSsoText: "Revenir à l'authentification unique",
2347
+ // objectui#12600 — the console login card's own header, the password
2348
+ // field's reveal toggle, and the footer's legal links.
2349
+ welcomeTitle: "Bon retour",
2350
+ welcomeDescription: "Connectez-vous pour reprendre votre travail",
2351
+ showPasswordText: "Afficher le mot de passe",
2352
+ hidePasswordText: "Masquer le mot de passe",
2353
+ footer: {
2354
+ privacy: "Confidentialité",
2355
+ terms: "Conditions",
2356
+ },
1908
2357
  },
1909
2358
  register: {
1910
2359
  title: "Créer un compte",
@@ -1923,8 +2372,12 @@ const fr = {
1923
2372
  submittingButton: "Création du compte…",
1924
2373
  hasAccountText: "Vous avez déjà un compte ?",
1925
2374
  signInText: "Se connecter",
2375
+ socialButton: "S'inscrire avec {provider}",
2376
+ orText: "ou continuer avec l'e-mail",
1926
2377
  errors: {
1927
2378
  userExists: "Un compte avec cet e-mail existe déjà. Essayez de vous connecter.",
2379
+ selfRegistrationClosed: "L'inscription libre n'est pas ouverte sur ce système. Demandez une invitation à un administrateur.",
2380
+ emailDomainNotAllowed: "Le domaine de cet e-mail n'est pas autorisé à s'inscrire ici. Utilisez l'e-mail de votre organisation ou demandez une invitation à un administrateur.",
1928
2381
  },
1929
2382
  verifyInbox: {
1930
2383
  title: "Vérifiez votre boîte de réception",
@@ -2000,7 +2453,7 @@ const fr = {
2000
2453
  checkSpam: "E-mail non reçu ? Vérifiez votre dossier spam ou contactez le support.",
2001
2454
  or: "Ou",
2002
2455
  // objectui#3546 slice three.
2003
- resendUnavailable: "L'envoi d'e-mails n'est peut-être pas configuré pour cet environnement. Contactez le support si le problème persiste.",
2456
+ resendUnavailable: "L'envoi d'e-mails n'est peut-être pas configuré pour ce système. Contactez le support si le problème persiste.",
2004
2457
  },
2005
2458
  setup: {
2006
2459
  welcomeTitle: "Bienvenue sur ObjectStack",
@@ -2044,7 +2497,7 @@ const fr = {
2044
2497
  disabledDescription: "L'autorisation d'appareil n'est pas activée sur ce déploiement, cet appareil ne peut donc pas être approuvé ici.",
2045
2498
  },
2046
2499
  shell: {
2047
- tenantHostHint: "Vous vous connectez à cet espace de travail",
2500
+ tenantHostHint: "Vous vous connectez à ce système",
2048
2501
  },
2049
2502
  layout: {
2050
2503
  headline: "Créez des applications métier puissantes, plus vite.",
@@ -2054,6 +2507,7 @@ const fr = {
2054
2507
  signOut: "Se déconnecter à la place",
2055
2508
  password: {
2056
2509
  title: "Votre mot de passe a expiré",
2510
+ resetTitle: "Vous devez changer votre mot de passe",
2057
2511
  fallbackMessage: "Veuillez définir un nouveau mot de passe pour continuer.",
2058
2512
  current: "Mot de passe actuel",
2059
2513
  next: "Nouveau mot de passe",
@@ -2079,6 +2533,11 @@ const fr = {
2079
2533
  verifying: "Vérification…",
2080
2534
  invalidCode: "Code invalide. Veuillez réessayer.",
2081
2535
  },
2536
+ impersonation: {
2537
+ passwordTitle: "{{user}} doit changer son mot de passe",
2538
+ mfaTitle: "{{user}} doit configurer l'authentification à deux facteurs",
2539
+ body: "Vous incarnez {{user}}, et seule cette personne peut le faire elle-même. Arrêtez l'usurpation pour revenir à votre propre compte.",
2540
+ },
2082
2541
  },
2083
2542
  },
2084
2543
  // objectui#3546 slice three — the /oauth/consent screen.
@@ -2087,12 +2546,17 @@ const fr = {
2087
2546
  title: "{{appName}} souhaite accéder à votre compte",
2088
2547
  request: "{{appName}} demande une autorisation{{suffix}}.",
2089
2548
  unknownApp: "une application",
2549
+ unidentified: "Cette application n'a pas pu être identifiée.",
2550
+ clientId: "ID client",
2090
2551
  willAllow: "Cette application pourra :",
2091
2552
  scope: {
2092
2553
  openid: "Confirmer votre identité",
2093
2554
  profile: "Lire votre profil de base (nom, photo)",
2094
2555
  email: "Lire votre adresse e-mail",
2095
2556
  offlineAccess: "Rester connecté (renouveler l'accès)",
2557
+ dataRead: "Lire des enregistrements (dans la limite de vos propres autorisations)",
2558
+ dataWrite: "Créer, modifier et supprimer des enregistrements (dans la limite de vos propres autorisations)",
2559
+ actionsExecute: "Exécuter des actions en votre nom (dans la limite de vos propres autorisations)",
2096
2560
  },
2097
2561
  deny: "Refuser",
2098
2562
  authorize: "Autoriser",
@@ -2123,11 +2587,20 @@ const fr = {
2123
2587
  role: "Rôle",
2124
2588
  save: "Enregistrer les modifications",
2125
2589
  },
2590
+ language: {
2591
+ title: "Langue",
2592
+ description: "La langue utilisée pour les notifications et les messages qui vous sont envoyés. La langue de l'interface se choisit séparément, dans le menu du globe.",
2593
+ label: "Langue préférée",
2594
+ systemDefault: "Utiliser la valeur par défaut du déploiement",
2595
+ save: "Enregistrer",
2596
+ saved: "Préférence de langue mise à jour.",
2597
+ readOnly: "La langue de votre compte est gérée par votre administrateur.",
2598
+ },
2126
2599
  password: {
2127
2600
  changeTitle: "Changer le mot de passe",
2128
2601
  setTitle: "Définir un mot de passe local",
2129
- changeDescription: "Mettez à jour le mot de passe que vous utilisez pour vous connecter à cet environnement.",
2130
- setDescription: "Vous vous êtes connecté via l'authentification unique. Définissez un mot de passe local pour pouvoir également vous connecter avec votre e-mail et un mot de passe sur cet environnement.",
2602
+ changeDescription: "Mettez à jour le mot de passe que vous utilisez pour vous connecter.",
2603
+ setDescription: "Vous vous êtes connecté via l'authentification unique. Définissez un mot de passe local pour pouvoir également vous connecter avec votre e-mail et un mot de passe.",
2131
2604
  current: "Mot de passe actuel",
2132
2605
  new: "Nouveau mot de passe",
2133
2606
  password: "Mot de passe",
@@ -2136,7 +2609,7 @@ const fr = {
2136
2609
  mismatch: "Les mots de passe ne correspondent pas",
2137
2610
  enterCurrent: "Saisissez votre mot de passe actuel",
2138
2611
  changed: "Mot de passe modifié.",
2139
- localSet: "Mot de passe local défini. Vous pouvez désormais vous connecter avec votre e-mail et votre mot de passe sur cet environnement.",
2612
+ localSet: "Mot de passe local défini. Vous pouvez désormais vous connecter avec votre e-mail et votre mot de passe.",
2140
2613
  changeAction: "Changer le mot de passe",
2141
2614
  setAction: "Définir le mot de passe",
2142
2615
  },
@@ -2151,22 +2624,21 @@ const fr = {
2151
2624
  unknown: "Une erreur inattendue s'est produite.",
2152
2625
  },
2153
2626
  workspace: {
2154
- label: "Espaces de travail",
2155
- default: "Mon espace de travail",
2156
- switch: "Changer d'espace de travail",
2157
- create: "Créer un espace de travail",
2158
- createTitle: "Créer un espace de travail",
2159
- createDescription: "Un espace de travail est un lieu partagé pour la collaboration de votre équipe.",
2160
- createButton: "Créer un espace de travail",
2161
- nameLabel: "Nom de l'espace de travail",
2627
+ label: "Organisations",
2628
+ default: "Mon organisation",
2629
+ switch: "Changer d'organisation",
2630
+ createTitle: "Créer une organisation",
2631
+ createDescription: "Une organisation est un lieu partagé pour la collaboration de votre équipe.",
2632
+ createButton: "Créer une organisation",
2633
+ nameLabel: "Nom de l'organisation",
2162
2634
  namePlaceholder: "p.ex., Acme Inc",
2163
2635
  slugLabel: "Slug URL",
2164
2636
  slugHint: "Utilisé dans les URL. Uniquement lettres minuscules, chiffres et tirets.",
2165
2637
  invite: "Inviter un membre",
2166
2638
  members: "Membres",
2167
- settings: "Paramètres de l'espace de travail",
2639
+ settings: "Paramètres de l'organisation",
2168
2640
  multiOrgDisabled: "La création de nouvelles organisations est désactivée sur cette instance.",
2169
- createFailed: "Échec de la création de l'espace de travail",
2641
+ createFailed: "Échec de la création de l'organisation",
2170
2642
  },
2171
2643
  help: {
2172
2644
  onThisPage: "Sur cette page",
@@ -2174,12 +2646,17 @@ const fr = {
2174
2646
  appDocs: 'Documentation de cette app',
2175
2647
  allDocs: 'Toute la documentation',
2176
2648
  onlineDocs: 'Documentation en ligne',
2649
+ loadingDocumentation: 'Chargement de la documentation',
2650
+ about: 'À propos',
2651
+ aboutTitle: 'À propos de cette console',
2652
+ aboutDescription: 'Le build à partir duquel cette console a été compilée.',
2653
+ aboutBuild: 'Build de la console',
2654
+ aboutBuildUnknown: 'Build inconnu (aucune version n’a été définie lors de la compilation de cette console)',
2177
2655
  },
2178
2656
  sidebar: {
2179
2657
  packageManagement: "Gestion des packages",
2180
2658
  searchNavigation: "Rechercher dans la navigation…",
2181
2659
  settings: "Paramètres",
2182
- help: "Aide",
2183
2660
  helpTooltip: "Aide et documentation",
2184
2661
  activityFeed: "Flux d'activité",
2185
2662
  notifications: "Notifications",
@@ -2189,18 +2666,16 @@ const fr = {
2189
2666
  area: "Zone",
2190
2667
  scope: "Périmètre",
2191
2668
  recent: "Récent",
2192
- favorites: "Favoris",
2193
2669
  starred: "Étoilés",
2194
2670
  removeFromFavorites: "Retirer {{name}} des favoris",
2671
+ allReports: "Tous les rapports",
2195
2672
  },
2196
2673
  topbar: {
2197
2674
  openAssistant: "Ouvrir l'assistant {{name}}",
2198
2675
  offline: "Hors ligne",
2199
2676
  usersOnline: "Utilisateurs actuellement en ligne",
2200
2677
  switchView: "Changer de vue",
2201
- switchObject: "Changer d'objet",
2202
2678
  connection: {
2203
- connected: "Connecté",
2204
2679
  connecting: "Connexion…",
2205
2680
  reconnecting: "Reconnexion…",
2206
2681
  disconnected: "Déconnecté",
@@ -2213,23 +2688,22 @@ const fr = {
2213
2688
  },
2214
2689
  aiAssistant: "Assistant IA",
2215
2690
  designInStudio: "Concevoir dans Studio",
2691
+ editApp: "Modifier l'application",
2216
2692
  },
2217
2693
  home: {
2218
2694
  build: {
2219
2695
  title: "Créer une application",
2220
- subtitle: "Partir de zéro — concevez les objets, formulaires, automatisations et interfaces.",
2221
- noCapability: "La création d'applications n'est pas disponible dans cet espace de travail : elle requiert l'autorisation « Gérer les métadonnées », que votre compte ne possède pas.",
2696
+ noCapability: "La création d'applications n'est pas disponible dans ce système : elle requiert l'autorisation « Gérer les métadonnées », que votre compte ne possède pas.",
2222
2697
  },
2223
2698
  template: {
2224
2699
  title: "Partir d'un modèle",
2225
- subtitle: "Installez une application modèle depuis la place de marché et personnalisez-la.",
2226
2700
  marketplaceDisabled: "Aucune place de marché d'applications n'est configurée pour ce runtime : il n'y a donc aucun modèle à installer ici.",
2227
2701
  },
2228
2702
  welcomeAdminDescription: "Décrivez votre activité en une phrase — l'IA génère les objets, les écrans, les API et les outils d'agent. Ou configurez tout vous-même depuis le menu de gauche.",
2229
2703
  welcomeAdminDescriptionNoBuild: "Configurez votre première application depuis le menu Administration à gauche. Une fois les données en place, l'assistant IA pourra vous aider à les explorer.",
2230
2704
  welcomeAdminDescriptionNoAi: "Configurez votre première application depuis le menu Administration à gauche.",
2231
2705
  noAppsTitle: "Aucune application pour l'instant",
2232
- noAppsDescription: "Votre espace de travail est en cours de configuration — les applications partagées par votre administrateur apparaîtront ici.",
2706
+ noAppsDescription: "Le système est en cours de configuration — les applications partagées par votre administrateur apparaîtront ici.",
2233
2707
  buildWithAI: "Créer avec l'IA",
2234
2708
  askAI: "Demander à l'IA",
2235
2709
  recoveryReminder: {
@@ -2238,7 +2712,16 @@ const fr = {
2238
2712
  dismiss: "Ignorer",
2239
2713
  },
2240
2714
  pendingDrafts: {
2241
- message: "Vous avez {{count}} modification(s) non publiée(s) — publiez-les pour les activer.",
2715
+ // objectui#12602 — the drafts row in Home's "My work" section: the
2716
+ // count, then the first draft names joined by `nameSeparator`, in
2717
+ // their package when they share one.
2718
+ title: "{{count}} modification(s) non publiée(s)",
2719
+ title_one: "{{count}} modification non publiée",
2720
+ title_many: "{{count}} modifications non publiées",
2721
+ title_other: "{{count}} modifications non publiées",
2722
+ inPackage: "{{names}} en attente de publication dans {{package}}",
2723
+ waiting: "{{names}} en attente de publication",
2724
+ nameSeparator: ", ",
2242
2725
  cta: "Publier",
2243
2726
  publishing: "Publication…",
2244
2727
  published: "Publié ! Vos modifications sont actives.",
@@ -2253,20 +2736,24 @@ const fr = {
2253
2736
  capabilityWarn: "Contrôle de conception : {{count}} référence(s) de capacité ne mènent à rien.",
2254
2737
  },
2255
2738
  title: "Accueil",
2256
- subtitle: "Tableau de bord de votre espace de travail",
2257
2739
  nav: "Accueil",
2258
2740
  allApps: "Toutes les applications",
2259
2741
  yourApps: "Vos applications",
2260
2742
  showMoreApps: "Plus",
2261
2743
  showLess: "Afficher moins",
2262
2744
  continueEmpty: "Les éléments que vous ouvrez apparaîtront ici.",
2263
- actionCenter: {
2264
- title: "Nécessite votre attention",
2265
- empty: "Vous êtes à jour",
2745
+ // objectui#12602 — Home's "My work" section: its heading, the link to the
2746
+ // full inbox, each column's title, "view all" link and empty line.
2747
+ myWork: {
2748
+ title: "Mon travail",
2749
+ openInbox: "Ouvrir la boîte de réception",
2750
+ viewAll: "Tout afficher",
2751
+ approvals: "À approuver",
2752
+ approvalsEmpty: "Rien n'attend votre approbation",
2753
+ notifications: "Notifications",
2754
+ notificationsEmpty: "Aucune notification non lue",
2266
2755
  },
2267
- loading: "Chargement de l'espace de travail…",
2268
- recent: "Récent",
2269
- starred: "Favoris",
2756
+ loading: "Chargement…",
2270
2757
  welcome: "Bienvenue dans ObjectUI",
2271
2758
  welcomeDescription: "Commencez par créer votre première application ou configurer les paramètres système.",
2272
2759
  createFirstApp: "Créez votre première app",
@@ -2274,12 +2761,10 @@ const fr = {
2274
2761
  browseMarketplace: "Parcourir la marketplace d'apps",
2275
2762
  quickActions: {
2276
2763
  title: "Actions rapides",
2277
- createApp: "Créer une app",
2278
- createAppDesc: "Commencez avec une nouvelle application",
2279
2764
  manageObjects: "Gérer les objets",
2280
2765
  manageObjectsDesc: "Configurer les modèles de données",
2281
2766
  systemSettings: "Paramètres système",
2282
- systemSettingsDesc: "Configurez votre espace de travail",
2767
+ systemSettingsDesc: "Configurez votre système",
2283
2768
  },
2284
2769
  appCard: {
2285
2770
  noDescription: "Aucune description",
@@ -2289,20 +2774,30 @@ const fr = {
2289
2774
  greetingAfternoon: "Bon après-midi",
2290
2775
  greetingEvening: "Bonsoir",
2291
2776
  greetingNight: "Travail de nuit",
2292
- heroTagline: "Reprenez là où vous vous êtes arrêté ou découvrez quelque chose de nouveau.",
2777
+ greetingSeparator: ", ",
2778
+ greetingEnd: ".",
2779
+ search: "Rechercher des applications, enregistrements, pages…",
2780
+ summary: {
2781
+ approvals: "{{count}} approbations vous attendent aujourd'hui",
2782
+ approvals_one: "{{count}} approbation vous attend aujourd'hui",
2783
+ approvals_many: "{{count}} approbations vous attendent aujourd'hui",
2784
+ approvals_other: "{{count}} approbations vous attendent aujourd'hui",
2785
+ none: "Rien ne vous attend aujourd'hui",
2786
+ },
2787
+ addApp: "Ajouter une application",
2788
+ appOpened: "{{time}}",
2293
2789
  open: "Ouvrir",
2294
- stats: {
2295
- apps: "Applications",
2296
- starred: "Étoilés",
2297
- recent: "Récents",
2298
- },
2299
2790
  recentApps: {
2300
2791
  title: "Récemment ouverts",
2301
2792
  itemType: {
2302
2793
  object: "Objet",
2303
2794
  dashboard: "Tableau de bord",
2304
2795
  page: "Page",
2796
+ report: "Rapport",
2797
+ package: "Package",
2798
+ view: "Vue de liste",
2305
2799
  record: "Enregistrement",
2800
+ metadata: "Métadonnées",
2306
2801
  },
2307
2802
  },
2308
2803
  starredApps: {
@@ -2324,7 +2819,6 @@ const fr = {
2324
2819
  organizations: "Organisations",
2325
2820
  roles: "Rôles",
2326
2821
  configuration: "Configuration",
2327
- createApp: "Créer une application",
2328
2822
  administration: "Administration",
2329
2823
  datasources: "Sources de données",
2330
2824
  documentation: "Documentation",
@@ -2339,16 +2833,23 @@ const fr = {
2339
2833
  manageAllApps: "Gérer toutes les applications",
2340
2834
  systemConsole: "Console système",
2341
2835
  noAppsConfigured: "Aucune application configurée",
2836
+ allApps: "Toutes les applications",
2837
+ editAppInStudio: "Modifier {{app}} dans Studio",
2838
+ backToHome: "Retour à l'accueil",
2839
+ settings: "Paramètres",
2840
+ productHome: "Accueil {{product}}",
2342
2841
  },
2343
2842
  activityFeed: {
2344
2843
  title: "Activité récente",
2345
2844
  filter: "Filtrer",
2346
2845
  empty: "Aucune activité récente",
2846
+ accessDenied: "Vous n'avez pas l'autorisation de consulter l'activité.",
2347
2847
  ariaLabel: "Fil d'activité",
2348
2848
  typeCreate: "Créer",
2349
2849
  typeUpdate: "Mettre à jour",
2350
2850
  typeDelete: "Supprimer",
2351
2851
  typeComment: "Commentaire",
2852
+ typeSystem: "Système",
2352
2853
  relativeJustNow: "à l'instant",
2353
2854
  relativeSecondsAgo: "il y a {{count}}s",
2354
2855
  relativeMinutesAgo: "il y a {{count}}m",
@@ -2370,8 +2871,13 @@ const fr = {
2370
2871
  placeholder: "Rechercher des objets, tableaux de bord, pages, rapports…",
2371
2872
  inputAriaLabel: "Rechercher des objets, tableaux de bord, pages, rapports",
2372
2873
  resultsCount: "{{count}} résultat pour \"{{query}}\"",
2373
- resultsCountPlural: "{{count}} résultats pour \"{{query}}\"",
2874
+ resultsCount_one: "{{count}} résultat pour \"{{query}}\"",
2875
+ resultsCount_many: "{{count}} de résultats pour \"{{query}}\"",
2876
+ resultsCount_other: "{{count}} résultats pour \"{{query}}\"",
2374
2877
  itemsAvailable: "{{count}} éléments disponibles",
2878
+ itemsAvailable_one: "{{count}} élément disponible",
2879
+ itemsAvailable_many: "{{count}} d'éléments disponibles",
2880
+ itemsAvailable_other: "{{count}} éléments disponibles",
2375
2881
  noResults: "Aucun résultat trouvé",
2376
2882
  noResultsHint: "Essayez d'ajuster vos termes de recherche",
2377
2883
  typeObjects: "Objets",
@@ -2396,26 +2902,38 @@ const fr = {
2396
2902
  noAppsConfigured: "Aucune application configurée",
2397
2903
  noAppsConfiguredDescription: "Aucune application n'est enregistrée. Créez votre première application ou visitez les paramètres système.",
2398
2904
  appNotAvailable: "Application non disponible",
2399
- appNotAvailableDescription: "Cette application n'est pas encore disponible — sa publication est peut-être en cours. Réessayez dans un instant.",
2905
+ appNotAvailableDescription: "Cette application n'est pas disponible — réessayez dans un instant.",
2906
+ appNotFound: "Impossible d'ouvrir cette application",
2907
+ appNotFoundDescription: "Le serveur n'a pas renvoyé cette application pour votre compte.",
2908
+ appUnreachable: "Impossible de joindre le serveur",
2909
+ appUnreachableDescription: "Cette application n'a pas pu être vérifiée. Réessayez dans un instant.",
2400
2910
  appAccessDenied: "Vous n'avez pas accès à cette application",
2401
2911
  appAccessDeniedDescription: "Cette application existe, mais votre compte n'est pas autorisé à l'ouvrir. Demandez l'accès à un administrateur.",
2402
2912
  appAccessDeniedHome: "Retour à l'accueil",
2913
+ appNothingAvailable: "Rien dans {{app}} ne vous est encore accessible",
2914
+ appNothingAvailableDescription: "Cette application ne contient aucune page que votre compte peut ouvrir. Demandez l'accès à un administrateur.",
2915
+ appNothingAvailableGrantDescription: "Cette application ne contient aucune page que votre compte peut ouvrir. Vous pouvez accorder l'accès dans la configuration.",
2916
+ openSetup: "Ouvrir la configuration",
2403
2917
  createFirstApp: "Créer la première application",
2404
2918
  systemSettings: "Paramètres système",
2405
2919
  back: "Retour",
2406
2920
  recordNotFound: "Enregistrement introuvable",
2407
2921
  recordNotFoundDescription: "L'enregistrement que vous recherchez n'existe pas ou a peut-être été supprimé.",
2922
+ recordAccessDenied: "Vous n'avez pas accès aux enregistrements {{object}}",
2923
+ recordAccessDeniedDescription: "Vous n'avez pas la permission de consulter les enregistrements de ce type. Contactez votre administrateur si vous pensez devoir y accéder.",
2924
+ recordLoadFailed: "Impossible de charger cet enregistrement",
2925
+ recordLoadFailedDescription: "Une erreur s'est produite lors du chargement. Vérifiez votre connexion et réessayez.",
2408
2926
  },
2409
2927
  actionDialog: {
2410
2928
  title: "Paramètres d'action",
2411
2929
  description: "Veuillez saisir les informations requises pour continuer.",
2412
2930
  selectPlaceholder: "Sélectionner {{label}}",
2413
2931
  requiredError: "{{label}} est obligatoire",
2932
+ unresolvedParam: 'Ce paramètre ne peut pas être affiché : le champ dont il dépend est absent des métadonnées de l’objet, le contrôle nécessaire ne peut donc pas être construit. Demandez à un administrateur de corriger la définition de l’action.',
2933
+ carryOverHint: 'Repris tel quel (lecture seule)',
2414
2934
  cancel: "Annuler",
2415
2935
  confirm: "Confirmer",
2416
2936
  uploading: "Téléversement…",
2417
- defaultActionTitle: "Action",
2418
- ok: "OK",
2419
2937
  lookupPlaceholder: "ID d'enregistrement pour {{label}}",
2420
2938
  lookupHelpText: "Aucun objet de référence n'est configuré pour ce paramètre, le sélecteur d'enregistrement est donc indisponible. Saisissez un ID d'enregistrement ou demandez à un administrateur de corriger le paramètre d'action.",
2421
2939
  },
@@ -2424,11 +2942,6 @@ const fr = {
2424
2942
  confirm: "Continuer",
2425
2943
  cancel: "Annuler",
2426
2944
  },
2427
- rowAction: {
2428
- openMenu: "Ouvrir le menu",
2429
- edit: "Modifier",
2430
- delete: "Supprimer",
2431
- },
2432
2945
  navigationSync: {
2433
2946
  addedPage: "Navigation mise à jour : page \"{{name}}\" ajoutée",
2434
2947
  addedDashboard: "Navigation mise à jour : tableau de bord \"{{name}}\" ajouté",
@@ -2442,13 +2955,20 @@ const fr = {
2442
2955
  updateFailed: "Impossible de mettre à jour la navigation",
2443
2956
  },
2444
2957
  objectActions: {
2445
- resetPackageSetConfirm: "Ce jeu d'autorisations est fourni avec un package installé et ne peut pas être supprimé. La suppression le réinitialise à la version livrée et abandonne vos personnalisations dans cet environnement. Continuer ?",
2446
- resetPackageSetSuccess: "Jeu d'autorisations réinitialisé à la version livrée",
2447
2958
  deleteSuccess: "{{label}} supprimé avec succès",
2448
2959
  deleteFailed: "Impossible de supprimer {{label}}",
2449
2960
  noRecordId: "Aucun ID d'enregistrement fourni",
2450
2961
  deleteConfirm: "Supprimer cet enregistrement ?",
2962
+ deleteConfirmTitle: "Supprimer {{label}} \"{{name}}\" ?",
2963
+ bulkDeleteConfirmTitle: "Supprimer {{count}} enregistrement(s) {{label}} ?",
2964
+ bulkDeleteConfirmTitle_one: "Supprimer {{count}} enregistrement {{label}} ?",
2965
+ bulkDeleteConfirmTitle_many: "Supprimer {{count}} d'enregistrements {{label}} ?",
2966
+ bulkDeleteConfirmTitle_other: "Supprimer {{count}} enregistrements {{label}} ?",
2967
+ deleteConfirmButton: "Supprimer",
2451
2968
  bulkDeleteSuccess: "{{count}} enregistrement(s) {{label}} supprimé(s)",
2969
+ bulkDeleteSuccess_one: "{{count}} enregistrement {{label}} supprimé",
2970
+ bulkDeleteSuccess_many: "{{count}} d'enregistrements {{label}} supprimés",
2971
+ bulkDeleteSuccess_other: "{{count}} enregistrements {{label}} supprimés",
2452
2972
  bulkDeletePartial: "{{succeeded}} supprimé(s), {{failed}} échoué(s)",
2453
2973
  },
2454
2974
  objectViewActions: {
@@ -2460,15 +2980,6 @@ const fr = {
2460
2980
  exportFailed: "Échec de l'export : {{message}}",
2461
2981
  forecastSoon: "La vue de prévision arrive bientôt",
2462
2982
  },
2463
- recordDetail: {
2464
- viewersTooltip: "Utilisateurs consultant cet enregistrement en ce moment",
2465
- },
2466
- cellRender: {
2467
- empty: "Vide",
2468
- yes: "Oui",
2469
- no: "Non",
2470
- systemFields: "Système",
2471
- },
2472
2983
  user: {
2473
2984
  profile: "Profil",
2474
2985
  settings: "Paramètres",
@@ -2490,6 +3001,7 @@ const fr = {
2490
3001
  loading: "Chargement…",
2491
3002
  failedToLoad: "Échec du chargement de la matrice : {{message}}",
2492
3003
  needsAcross: "Le rapport matriciel nécessite au moins un champ `groupingsAcross`.",
3004
+ forbiddenMessage: "Vous n’avez pas l’autorisation de voir les données de ce rapport.",
2493
3005
  aggregate: {
2494
3006
  count: "Compter",
2495
3007
  countDistinct: "Compter distincts",
@@ -2504,18 +3016,18 @@ const fr = {
2504
3016
  },
2505
3017
  },
2506
3018
  organizations: {
2507
- create: "Créer un espace de travail",
2508
- mine: "Mes espaces de travail",
2509
- title: "Espaces de travail",
2510
- heading: "Vos espaces de travail",
2511
- subtitle: "Sélectionnez un espace de travail pour continuer ou créez-en un nouveau.",
2512
- searchPlaceholder: "Rechercher un espace de travail",
2513
- new: "Nouvel espace de travail",
2514
- current: "Espace de travail actuel",
3019
+ create: "Créer une organisation",
3020
+ mine: "Mes organisations",
3021
+ title: "Organisations",
3022
+ heading: "Vos organisations",
3023
+ subtitle: "Sélectionnez une organisation pour continuer ou créez-en une nouvelle.",
3024
+ searchPlaceholder: "Rechercher une organisation",
3025
+ new: "Nouvelle organisation",
3026
+ current: "Organisation actuelle",
2515
3027
  manage: "Gérer",
2516
- emptyTitle: "Aucun espace de travail pour le moment",
2517
- emptyDescription: "Créez votre premier espace de travail pour commencer.",
2518
- noMatches: "Aucun espace de travail ne correspond à votre recherche.",
3028
+ emptyTitle: "Aucune organisation pour le moment",
3029
+ emptyDescription: "Créez votre première organisation pour commencer.",
3030
+ noMatches: "Aucune organisation ne correspond à votre recherche.",
2519
3031
  },
2520
3032
  organization: {
2521
3033
  roles: {
@@ -2600,6 +3112,7 @@ const fr = {
2600
3112
  readOnlyNote: "Seuls les propriétaires peuvent modifier les paramètres.",
2601
3113
  nameLabel: "Nom de l'organisation",
2602
3114
  slugLabel: "Slug",
3115
+ slugLockedNote: "Cette organisation a des environnements actifs, son slug ne peut donc pas être modifié ici : le renommer déplace aussi leurs sous-domaines.",
2603
3116
  logoLabel: "Logo",
2604
3117
  logoUpload: "Téléverser",
2605
3118
  logoReplace: "Remplacer",
@@ -2658,18 +3171,43 @@ const fr = {
2658
3171
  regionLabel: "Notifications",
2659
3172
  groupCount: "{{count}} notifications",
2660
3173
  groupUnread: "{{count}} non lues",
3174
+ groupUnread_one: "{{count}} non lue",
3175
+ groupUnread_many: "{{count}} non lues",
3176
+ groupUnread_other: "{{count}} non lues",
2661
3177
  groupMarkRead: "Marquer comme lu",
2662
3178
  groupMarkReadTitle: "Tout marquer comme lu pour ce type",
2663
3179
  empty: "Aucune notification",
2664
3180
  markAllRead: "Tout marquer comme lu",
2665
3181
  viewAll: "Voir toutes les notifications",
2666
3182
  approvalsPending: "{{count}} approbations en attente",
3183
+ approvalsPending_one: "{{count}} approbation en attente",
3184
+ approvalsPending_many: "{{count}} d'approbations en attente",
3185
+ approvalsPending_other: "{{count}} approbations en attente",
2667
3186
  viewApprovals: "Voir les approbations",
2668
3187
  noPendingApprovals: "Aucune approbation en attente",
2669
3188
  openApprovalsInbox: "Ouvrir la boîte d'approbations",
2670
3189
  badgeTotal: "{{total}} au total",
2671
- badgeNotifications: "{{unread}} notifications",
2672
- badgeApprovals: "{{approvals}} approbations en attente",
3190
+ badgeNotifications: "{{count}} notifications",
3191
+ badgeNotifications_one: "{{count}} notification",
3192
+ badgeNotifications_many: "{{count}} de notifications",
3193
+ badgeNotifications_other: "{{count}} notifications",
3194
+ badgeApprovals: "{{count}} approbations en attente",
3195
+ badgeApprovals_one: "{{count}} approbation en attente",
3196
+ badgeApprovals_many: "{{count}} d'approbations en attente",
3197
+ badgeApprovals_other: "{{count}} approbations en attente",
3198
+ arrivalMany: "{{count}} nouveaux messages",
3199
+ arrivalMany_one: "{{count}} nouveau message",
3200
+ arrivalMany_many: "{{count}} de nouveaux messages",
3201
+ arrivalMany_other: "{{count}} nouveaux messages",
3202
+ arrivalRepeats: "{{count}} nouveaux messages sur ce sujet",
3203
+ arrivalRepeats_one: "{{count}} nouveau message sur ce sujet",
3204
+ arrivalRepeats_many: "{{count}} de nouveaux messages sur ce sujet",
3205
+ arrivalRepeats_other: "{{count}} nouveaux messages sur ce sujet",
3206
+ arrivalOpen: "Afficher",
3207
+ toastEnabled: "Alertes dans l'application",
3208
+ desktopEnabled: "Notifications du bureau",
3209
+ desktopBlocked: "Bloqué. Autorisez les notifications pour ce site dans les paramètres du navigateur.",
3210
+ desktopUnsupported: "Ce navigateur ne prend pas en charge les notifications du bureau.",
2673
3211
  emptyUnread: "Tout est lu",
2674
3212
  filterUnread: "Non lus",
2675
3213
  filterAll: "Tous",
@@ -2683,12 +3221,14 @@ const fr = {
2683
3221
  thankYouTitle: "Merci !",
2684
3222
  thankYouMessage: "Votre soumission a été reçue avec succès.",
2685
3223
  redirecting: "Redirection dans {{seconds}} seconde(s)…",
3224
+ redirectPending: "Redirection…",
2686
3225
  unavailableTitle: "Formulaire non disponible",
2687
3226
  unavailableDescription: "Aucun formulaire public n'est disponible à cette URL. Assurez-vous que la vue sous-jacente a le partage anonyme activé.",
2688
3227
  tryDemo: "Essayer la démo",
2689
3228
  retry: "Réessayer",
2690
3229
  loading: "Chargement du formulaire…",
2691
3230
  requiredHint: "* Champ obligatoire",
3231
+ requiredFields: "Champs obligatoires : {{fields}}",
2692
3232
  consentLabelDefault: "J'accepte la politique de confidentialité et consens au traitement de mes données pour cette demande.",
2693
3233
  consentLink: "Politique de confidentialité",
2694
3234
  consentRequired: "Veuillez accepter la politique de confidentialité pour continuer.",
@@ -2701,10 +3241,10 @@ const fr = {
2701
3241
  body: 'La surface MCP est désactivée (OS_MCP_SERVER_ENABLED=false). Demandez à votre opérateur de la réactiver.',
2702
3242
  },
2703
3243
  url: {
2704
- title: 'Endpoint MCP de cet environnement',
3244
+ title: 'Endpoint MCP de ce système',
2705
3245
  body: 'Tout client IA compatible MCP se connecte avec cette URL. L’identité est en libre-service : le déploiement est son propre serveur d’autorisation OAuth 2.1 — vous vous connectez en votre nom, et chaque appel s’exécute sous vos permissions et la sécurité au niveau des lignes.',
2706
3246
  downloadSkill: 'Télécharger SKILL.md',
2707
- skillHint: 'La skill d’agent portable : apprend à tout agent compatible à travailler avec cet environnement.',
3247
+ skillHint: 'La skill d’agent portable : apprend à tout agent compatible à travailler avec ce système.',
2708
3248
  },
2709
3249
  claude: {
2710
3250
  body: 'Paramètres → Connecteurs → Ajouter un connecteur personnalisé, collez cette URL puis connectez-vous dans le navigateur.',
@@ -2739,18 +3279,86 @@ const fr = {
2739
3279
  noImportableFields: "Cet objet n'a aucun champ importable.",
2740
3280
  schemaReadFailed: "Impossible de lire le schéma de l'objet.",
2741
3281
  imported: "{{count}} ligne(s) importée(s) dans {{object}}.",
3282
+ imported_one: "{{count}} ligne importée dans {{object}}.",
3283
+ imported_many: "{{count}} de lignes importées dans {{object}}.",
3284
+ imported_other: "{{count}} lignes importées dans {{object}}.",
2742
3285
  importFrom: "Importer les lignes réelles depuis",
2743
3286
  into: "vers",
2744
3287
  opening: "Ouverture…",
2745
3288
  importAction: "Importer",
2746
3289
  dismiss: "Ignorer",
2747
3290
  },
2748
- cloudOnboarding: {
2749
- hintCreate: "Créez votre premier environnement — un espace de travail privé avec sa propre URL, sa base de données et son offre. C'est là que se fait la création.",
2750
- hintReady: "Votre environnement de production est prêt. Ouvrez-le pour créer et exécuter vos applications — tout se passe à l'intérieur.",
2751
- createEnvironment: "Créer votre environnement",
2752
- openProduction: "Ouvrir la production",
2753
- manageEnvironments: "Gérer les environnements",
3291
+ cloudWorkspaceTimezoneNotice: {
3292
+ seeded: "Le fuseau horaire de l’environnement a été défini sur {{zone}} d’après votre navigateur lors de sa création. Vous pouvez le modifier dans Paramètres → Localisation.",
3293
+ },
3294
+ ai: {
3295
+ nlQuery: {
3296
+ placeholder: "Posez une question sur vos données…",
3297
+ ask: "Demander",
3298
+ results: "Résultats",
3299
+ match: "Correspondance : {{percent}}",
3300
+ simulatedSummary: "Résultats pour : {{query}}",
3301
+ noResults: "Aucun enregistrement correspondant",
3302
+ recentQueries: "Requêtes récentes",
3303
+ },
3304
+ formAssist: {
3305
+ title: "Suggestions de l’IA",
3306
+ suggestionCount: "{{count}} suggestions",
3307
+ suggestionCount_one: "{{count}} suggestion",
3308
+ suggestionCount_many: "{{count}} de suggestions",
3309
+ suggestionCount_other: "{{count}} suggestions",
3310
+ applyAll: "Tout appliquer",
3311
+ confidence: "Confiance : {{percent}}",
3312
+ appliedCount: "{{count}} suggestions appliquées",
3313
+ appliedCount_one: "{{count}} suggestion appliquée",
3314
+ appliedCount_many: "{{count}} de suggestions appliquées",
3315
+ appliedCount_other: "{{count}} suggestions appliquées",
3316
+ },
3317
+ recommendations: {
3318
+ title: "Recommandations",
3319
+ generating: "Génération des recommandations…",
3320
+ empty: "Aucune recommandation disponible",
3321
+ },
3322
+ },
3323
+ aiApprovals: {
3324
+ title: "Approbations IA",
3325
+ description: "Actions proposées par un agent IA qui nécessitent une validation humaine avant exécution.",
3326
+ tabPending: "En attente",
3327
+ tabDecided: "Traitées",
3328
+ tabAll: "Toutes",
3329
+ statusPending: "En attente",
3330
+ statusApproved: "Approuvée",
3331
+ statusExecuted: "Exécutée",
3332
+ statusFailed: "Échouée",
3333
+ statusRejected: "Rejetée",
3334
+ colTool: "Outil",
3335
+ colAction: "Action",
3336
+ colObject: "Objet",
3337
+ colStatus: "Statut",
3338
+ colProposed: "Proposée",
3339
+ colDecision: "Décision",
3340
+ emptyTitle: "Aucune action en attente",
3341
+ emptyDescription: "Lorsque l'IA propose une action sensible, elle apparaît ici pour validation.",
3342
+ view: "Voir",
3343
+ approve: "Approuver",
3344
+ reject: "Rejeter",
3345
+ working: "En cours…",
3346
+ approveAndExecute: "Approuver et exécuter",
3347
+ outcomeApprove: "Approbation de {{id}} : {{message}}",
3348
+ outcomeReject: "Rejet de {{id}} : {{message}}",
3349
+ outcomeExecuteFailed: "L'action a échoué pendant son exécution",
3350
+ drawerFallbackTitle: "Action en attente",
3351
+ drawerSubtitle: "Outil {{tool}} sur {{object}}",
3352
+ fieldProposedBy: "Proposée par",
3353
+ fieldDecidedBy: "Décidée par",
3354
+ fieldConversation: "Conversation",
3355
+ fieldToolInput: "Entrée de l'outil",
3356
+ fieldResult: "Résultat",
3357
+ fieldError: "Erreur",
3358
+ fieldRejectionReason: "Motif du rejet",
3359
+ rejectTitle: "Rejeter cette action ?",
3360
+ rejectBody: "Le motif est renvoyé à l'IA pour qu'elle ajuste sa prochaine réponse.",
3361
+ rejectPlaceholder: "Motif facultatif (par ex. « Identifiant d'enregistrement erroné — merci de confirmer d'abord avec l'utilisateur. »)",
2754
3362
  },
2755
3363
  aiModelStatus: {
2756
3364
  summary: "Créer / Demander utilise {{conversational}} ({{conversationalSource}}) ; structuré utilise {{structured}} ({{structuredSource}}).",
@@ -2760,8 +3368,8 @@ const fr = {
2760
3368
  rowConversational: "Modèle Build / Ask",
2761
3369
  rowStructured: "Structuré (blueprint / seed)",
2762
3370
  rowReasoning: "Effort de raisonnement",
2763
- readFailed: "Impossible de lire le modèle d'IA effectif. Cet environnement n'exécute peut-être pas de service d'IA, ou vous n'avez pas la permission ai:read.",
2764
- readFailedWithStatus: "Impossible de lire le modèle d'IA effectif (HTTP {{status}}). Cet environnement n'exécute peut-être pas de service d'IA, ou vous n'avez pas la permission ai:read.",
3371
+ readFailed: "Impossible de lire le modèle d'IA effectif. Ce système n'exécute peut-être pas de service d'IA, ou vous n'avez pas la permission ai:read.",
3372
+ readFailedWithStatus: "Impossible de lire le modèle d'IA effectif (HTTP {{status}}). Ce système n'exécute peut-être pas de service d'IA, ou vous n'avez pas la permission ai:read.",
2765
3373
  overridesInEffect: "Surcharges actives : ",
2766
3374
  noOverrides: "aucune — les valeurs par défaut du code déployé s'appliquent.",
2767
3375
  adapter: "Adaptateur : ",
@@ -2769,6 +3377,181 @@ const fr = {
2769
3377
  sourceInherits: "identique à build/ask",
2770
3378
  sourcePinned: "figé par {{source}}",
2771
3379
  },
3380
+ // objectui#7254 — the AI copilot's tool cards. Three families, all of them
3381
+ // English-only until this landed while every other string on the same screen
3382
+ // was translated:
3383
+ //
3384
+ // `tool.*` — one entry per PLATFORM-PROVIDED tool name
3385
+ // (@objectstack/spec `PLATFORM_TOOLS_BY_PACKAGE`, the
3386
+ // closed registry those runtimes are conformance-tested
3387
+ // against). `humanizeToolName` looks each up as
3388
+ // `chatbot.tool.<tool_name>` and falls back to its English
3389
+ // title-caser for a custom / third-party tool, so a name
3390
+ // missing here is degraded, never broken. Every value, `en`
3391
+ // included, is a short sentence in the pack's language
3392
+ // saying what the step does (cloud#2927 Target 3, ruled
3393
+ // 「同意」; objectui#12724): never the tool id, and never
3394
+ // the title-caser's output for it, which is how the step
3395
+ // reads for a tool the pack has no entry for.
3396
+ // `toolLabels-locale-parity-7481` holds both.
3397
+ // `toolState.*` — the card-header badge + activity-chip vocabulary. ONE
3398
+ // set for both surfaces (they used to carry separate
3399
+ // tables and disagreed on casing).
3400
+ // `plan.*` — the "N objects · N views · N dashboards" strip. Plural
3401
+ // FAMILIES: one slot per CLDR category the pack's language
3402
+ // selects (objectui#11432), plus the base key for a call
3403
+ // made without a count. `all-locales-key-parity.test.ts`
3404
+ // derives the required slots from `Intl.PluralRules`.
3405
+ //
3406
+ // objectui#7481 — five `tool.*` entries are NEWER than the registry above:
3407
+ // `get_authoring_rules` (cloud#1837), `load_tools`, `open_record`, `test_flow`
3408
+ // and `toggle_flow` are registered by cloud `service-ai-studio` but the pinned
3409
+ // `@objectstack/spec` snapshot does not list them yet. They are kept here on
3410
+ // purpose: a step label the user reads must not wait on a pin bump. When the
3411
+ // pin advances, `chatbotToolLabels-locale-parity-7481` starts checking them
3412
+ // against the registry instead of against its own hand-held list.
3413
+ chatbot: {
3414
+ answer: {
3415
+ showFull: 'Afficher toute la réponse',
3416
+ collapse: 'Réduire',
3417
+ expandTable: 'Agrandir',
3418
+ exitExpandedTable: 'Fermer',
3419
+ },
3420
+ tool: {
3421
+ aggregate_data: "Synthétiser les données",
3422
+ get_record: "Lire l’enregistrement",
3423
+ query_data: "Interroger les données nécessaires",
3424
+ query_records: "Rechercher les enregistrements",
3425
+ search_knowledge: "Consulter la base de connaissances",
3426
+ visualize_data: "Représenter les données en graphique",
3427
+ add_field: "Ajouter un champ à l’objet",
3428
+ apply_blueprint: "Construire l’application selon le plan",
3429
+ apply_edit: "Appliquer la modification",
3430
+ create_metadata: "Créer un élément de métadonnées",
3431
+ create_object: "Créer un nouvel objet",
3432
+ create_package: "Créer un nouveau paquet",
3433
+ create_seed: "Générer des données d’exemple pour les objets",
3434
+ delete_field: "Supprimer le champ",
3435
+ describe_metadata: "Examiner les métadonnées",
3436
+ describe_object: "Examiner la structure de l’objet",
3437
+ get_active_package: "Vérifier le paquet actif",
3438
+ get_authoring_rules: "Consulter les règles d’écriture",
3439
+ get_metadata_schema: "Consulter le format des métadonnées",
3440
+ get_package: "Examiner le paquet",
3441
+ list_metadata: "Lister les métadonnées existantes",
3442
+ list_objects: "Lister les objets existants",
3443
+ list_packages: "Lister les paquets existants",
3444
+ load_tools: "Charger d’autres outils",
3445
+ modify_field: "Modifier le champ",
3446
+ open_record: "Ouvrir cette fiche",
3447
+ propose_blueprint: "Rédiger le plan de l’application",
3448
+ set_active_package: "Passer au paquet cible",
3449
+ suggest_builder: "Proposer de construire avec l’IA",
3450
+ test_flow: "Faire un essai du flux",
3451
+ todo_write: "Noter les vérifications à faire",
3452
+ toggle_flow: "Activer ou désactiver ce flux",
3453
+ update_metadata: "Mettre à jour un élément de métadonnées",
3454
+ validate_expression: "Vérifier l’expression",
3455
+ verify_build: "Vérifier le résultat de la construction",
3456
+ },
3457
+ toolState: {
3458
+ agentActivity: "Activité de l’agent",
3459
+ pending: "En attente",
3460
+ running: "En cours",
3461
+ awaitingApproval: "En attente d’approbation",
3462
+ responded: "Répondu",
3463
+ completed: "Terminé",
3464
+ error: "Erreur",
3465
+ denied: "Refusé",
3466
+ failed: "Échec",
3467
+ },
3468
+ phase: {
3469
+ build: "Création",
3470
+ design: "Conception du plan",
3471
+ stepCount: "{{count}} étapes",
3472
+ stepCount_one: "{{count}} étape",
3473
+ stepCount_many: "{{count}} d’étapes",
3474
+ stepCount_other: "{{count}} étapes",
3475
+ expand: "Afficher les étapes",
3476
+ collapse: "Masquer les étapes",
3477
+ },
3478
+ plan: {
3479
+ countObjects: "{{count}} objets",
3480
+ countObjects_one: "{{count}} objet",
3481
+ countObjects_many: "{{count}} d'objets",
3482
+ countObjects_other: "{{count}} objets",
3483
+ countViews: "{{count}} vues",
3484
+ countViews_one: "{{count}} vue",
3485
+ countViews_many: "{{count}} de vues",
3486
+ countViews_other: "{{count}} vues",
3487
+ countDashboards: "{{count}} tableaux de bord",
3488
+ countDashboards_one: "{{count}} tableau de bord",
3489
+ countDashboards_many: "{{count}} de tableaux de bord",
3490
+ countDashboards_other: "{{count}} tableaux de bord",
3491
+ countSeedData: "données d’exemple",
3492
+ extendTarget: "Ajout à l’app existante : {{app}}",
3493
+ awaitingConfirm: "En attente de confirmation",
3494
+ objectsAndFields: "Objets et champs",
3495
+ views: "Vues",
3496
+ suggestedField: "suggéré",
3497
+ nameField: "Nom : {{field}}",
3498
+ },
3499
+ build: {
3500
+ building: "Création de {{app}}…",
3501
+ built: "Création de {{app}} terminée",
3502
+ builtAndLive: "Créée et en ligne · {{app}}",
3503
+ appFallback: "votre application",
3504
+ addingSampleData: "ajout de données d’exemple",
3505
+ group: {
3506
+ object: "Objets",
3507
+ view: "Vues",
3508
+ dashboard: "Tableaux de bord",
3509
+ app: "Application",
3510
+ seed: "Données d’exemple",
3511
+ },
3512
+ moreArtifacts: "+{{n}} autres",
3513
+ verifying: "Vérification de la modification…",
3514
+ verifyStep: "étape {{n}}",
3515
+ verified: "Modification vérifiée",
3516
+ unknownPhase: "Phase de création inconnue",
3517
+ nextStepsLead: "Ensuite, vous pouvez dire : {{steps}}",
3518
+ nextStepQuote: "« {{step}} »",
3519
+ draftPosture: "Les modifications suivantes sont enregistrées comme brouillons, et vous les publiez dans Studio.",
3520
+ checksPassed: "Vérifications réussies {{passed}}/{{total}}",
3521
+ },
3522
+ changes: {
3523
+ planTitle: "Plan de modifications · {{count}} modifications",
3524
+ planTitle_one: "Plan de modifications · {{count}} modification",
3525
+ planTitle_many: "Plan de modifications · {{count}} de modifications",
3526
+ planTitle_other: "Plan de modifications · {{count}} modifications",
3527
+ saveDraft: "Enregistrer comme brouillon",
3528
+ reviewAndPublish: "Vérifier les modifications et publier",
3529
+ undo: "Annuler",
3530
+ undoWithOthers: "Annuler (avec {{count}} autres brouillons)",
3531
+ undoWithOthers_one: "Annuler (avec {{count}} autre brouillon)",
3532
+ undoWithOthers_many: "Annuler (avec {{count}} d'autres brouillons)",
3533
+ undoWithOthers_other: "Annuler (avec {{count}} autres brouillons)",
3534
+ undoConfirm: "Annuler supprime les {{total}} brouillons non publiés de ce package, dont {{count}} qui ne font pas partie de cette modification.",
3535
+ undoConfirm_one: "Annuler supprime les {{total}} brouillons non publiés de ce package, dont {{count}} qui ne fait pas partie de cette modification.",
3536
+ undoConfirm_many: "Annuler supprime les {{total}} brouillons non publiés de ce package, dont {{count}} de brouillons qui ne font pas partie de cette modification.",
3537
+ undoConfirm_other: "Annuler supprime les {{total}} brouillons non publiés de ce package, dont {{count}} qui ne font pas partie de cette modification.",
3538
+ undoConfirmUnknown: "Annuler supprime tous les brouillons non publiés de ce package, pas seulement cette modification.",
3539
+ undoConfirmAction: "Tout annuler",
3540
+ undoCancel: "Conserver",
3541
+ undoing: "Annulation…",
3542
+ undone: "Annulé",
3543
+ undoFailed: "Échec de l'annulation",
3544
+ kind: {
3545
+ field: "Champ",
3546
+ object: "Objet",
3547
+ view: "Vue",
3548
+ dashboard: "Tableau de bord",
3549
+ app: "Application",
3550
+ seed: "Données d'exemple",
3551
+ package: "Package d'application",
3552
+ },
3553
+ },
3554
+ },
2772
3555
  chatbotError: {
2773
3556
  title: "Échec de la réponse",
2774
3557
  fallbackDetail: "Une erreur s'est produite. Veuillez réessayer.",
@@ -2782,10 +3565,13 @@ const fr = {
2782
3565
  buyCredits: "Acheter un pack de crédits",
2783
3566
  upgradePlan: "Changer d'offre",
2784
3567
  },
3568
+ planTier: {
3569
+ teamAndUp: "À partir de l'offre Team",
3570
+ },
2785
3571
  environment: {
2786
- addEnvironment: "Ajouter un environnement",
2787
3572
  setUpProduction: "Configurer votre environnement de production",
2788
3573
  addDevelopment: "Ajouter un environnement de développement",
3574
+ developmentLocked: "Environnements de développement · {{tier}}",
2789
3575
  // Plan/capacity dialog (EnvironmentEntitlementDialog) — cloud#959.
2790
3576
  entitlement: {
2791
3577
  productionLimitTitle: "Vous avez déjà votre environnement de production",
@@ -2833,7 +3619,7 @@ const fr = {
2833
3619
  },
2834
3620
  unbound: {
2835
3621
  title: "Non connecté",
2836
- body: "Connectez ce runtime à un plan de contrôle ObjectStack pour parcourir les paquets privés de votre organisation et les installer ici. L'approbation se fait en un seul clic dans votre compte cloud — aucun identifiant ni justificatif n'est saisi sur cette page.",
3622
+ body: "Ce runtime n'est connecté à aucun plan de contrôle. « Connecter » ouvre votre compte cloud dans une nouvelle fenêtre, où un seul clic approuve la liaison — aucun identifiant ni justificatif n'est saisi sur cette page.",
2837
3623
  connect: "Connecter",
2838
3624
  },
2839
3625
  },
@@ -2846,10 +3632,17 @@ const fr = {
2846
3632
  dismiss: "Ignorer",
2847
3633
  confirmedToast: "« {{set}} » est désormais accordé à {{anchor}}.",
2848
3634
  dismissedToast: "Suggestion pour « {{set}} » ignorée.",
3635
+ guestUnsupported: "Impossible de l'accorder ici : les ensembles de la position Guest ne sont pas dérivés des suggestions acceptées.",
3636
+ acceptedState: "« {{set}} » a été accepté pour tous les utilisateurs connectés (position Everyone).",
3637
+ notInForceState: "« {{set}} » a été accepté, mais n'est pas encore en vigueur : la position Everyone n'a pas changé lors de cette requête. Le journal du serveur indique pourquoi.",
3638
+ dismissedState: "« {{set}} » n'est pas accordé : la suggestion a été ignorée ou révoquée.",
3639
+ revoke: "Révoquer",
3640
+ revoking: "Révocation…",
3641
+ revokedToast: "Acceptation de « {{set}} » révoquée.",
2849
3642
  },
2850
3643
  title: "Marketplace d'applications",
2851
3644
  subtitle: "Parcourez les applications approuvées publiées dans le catalogue ObjectStack. Cliquez sur une application pour voir les détails et l'installer dans l'un de vos environnements.",
2852
- searchPlaceholder: "Rechercher des applications par nom ou ID de manifeste…",
3645
+ searchPlaceholder: "Rechercher des applications par nom ou ID d'application…",
2853
3646
  searchAria: "Rechercher des applications du marketplace",
2854
3647
  installed: "Installé",
2855
3648
  installedCount: "Installées ({{count}})",
@@ -2859,21 +3652,26 @@ const fr = {
2859
3652
  noMatchFilters: "Aucune application ne correspond à vos filtres.",
2860
3653
  noDescription: "Aucune description disponible.",
2861
3654
  back: "Retour au marketplace",
2862
- installedTitle: "Applications installées",
2863
- installedSubtitle: "Paquets du marketplace actuellement installés dans le noyau de ce runtime.",
2864
- installedEmpty: "Aucune application du marketplace installée dans ce runtime pour l'instant.",
2865
3655
  browseLink: "Parcourir le marketplace →",
2866
- installedAdditiveNote: "<strong>Remarque :</strong> L'API du noyau est uniquement additive — la désinstallation supprime le manifeste du disque pour que le paquet ne se charge pas au prochain démarrage, mais le noyau en cours d'exécution maintient l'application enregistrée jusqu'au redémarrage.",
2867
- installedAt: "Installé {{when}}",
2868
- installedBy: "par {{user}}",
2869
- installedPackageId: "Paquet",
2870
- cachedAs: "Mis en cache sous <code>{{path}}</code>",
3656
+ installedAdditiveNote: "La désinstallation retire immédiatement l'application du noyau en cours d'exécution, avec ses jeux d'autorisations et leurs attributions, et supprime le manifeste en cache pour que le paquet ne se charge pas au prochain démarrage. Les enregistrements stockés dans ses objets restent dans la base de données.",
2871
3657
  versionBadge: "v{{version}}",
2872
3658
  installedBadge: "Installé v{{version}}",
3659
+ // objectui#11645 — an install-local entry this runtime refused to load at
3660
+ // startup (the listing's `notLoaded` marker), read on Installed Apps.
3661
+ notLoaded: {
3662
+ badge: "Non chargé",
3663
+ protocolIncompatible: "Ce runtime n'a pas chargé ce paquet : il cible le protocole {{requiredRange}}, que ce runtime ne prend pas en charge.",
3664
+ otherReason: "Ce runtime n'a pas chargé ce paquet ({{code}}).",
3665
+ },
2873
3666
  load: {
2874
3667
  failed: "Impossible de charger le marketplace",
2875
3668
  failedHintConfigured: "Ce runtime accède à la place de marché via le plan de contrôle situé à {{url}}. Vérifiez qu'il est en ligne et joignable depuis ici.",
2876
- failedHintSameOrigin: "Ce runtime sert lui-même le catalogue de la place de marché. Vérifiez qu'il est en ligne.",
3669
+ failedHintSameOrigin: "Le catalogue de la place de marché est accessible via ce runtime. Vérifiez que le runtime est en ligne et qu'il peut joindre le catalogue.",
3670
+ loading: "Chargement du catalogue de la place de marché…",
3671
+ slow: "Chargement en cours — le catalogue de la place de marché tarde à répondre.",
3672
+ retry: "Réessayer",
3673
+ unreachable: "Le catalogue de la place de marché est injoignable.",
3674
+ answeredError: "Le catalogue de la place de marché a répondu par une erreur (HTTP {{status}}).",
2877
3675
  packageFailed: "Impossible de charger le paquet",
2878
3676
  notFound: "Introuvable.",
2879
3677
  },
@@ -2897,10 +3695,17 @@ const fr = {
2897
3695
  purgeSampleData: 'Supprimer les données d\'exemple',
2898
3696
  purgeConfirm: 'Supprimer tous les enregistrements d\'exemple créés par ce paquet ? Les enregistrements ajoutés par l\'utilisateur ne seront PAS touchés.',
2899
3697
  purgeSuccess: '{{count}} enregistrement(s) d\'exemple supprimé(s).',
3698
+ purgeSuccess_one: "{{count}} enregistrement d'exemple supprimé.",
3699
+ purgeSuccess_many: "{{count}} d'enregistrements d'exemple supprimés.",
3700
+ purgeSuccess_other: "{{count}} enregistrements d'exemple supprimés.",
2900
3701
  purgeNoData: 'Aucun enregistrement d\'exemple à supprimer.',
2901
3702
  reseedQueued: 'Les données d\'exemple seront rechargées au prochain accès à l\'environnement.',
2902
3703
  reseedLocalSuccess: 'Données d\'exemple rechargées : {{inserted}} ajoutés, {{updated}} mis à jour.',
2903
3704
  reseedPartialErrors: '({{count}} enregistrement(s) n\'ont pas pu être écrits)',
3705
+ reseedPartialErrors_one: "({{count}} enregistrement n'a pas pu être écrit)",
3706
+ reseedPartialErrors_many: "({{count}} d'enregistrements n'ont pas pu être écrits)",
3707
+ reseedPartialErrors_other: "({{count}} enregistrements n'ont pas pu être écrits)",
3708
+ sampleDataKernelUnavailable: 'Ce plan de contrôle n\'a pas de noyau d\'environnement : les données d\'exemple ne peuvent donc être ni rechargées ni supprimées ici. Faites-le depuis le runtime propre à l\'environnement.',
2904
3709
  updateAvailable: 'Mise à jour disponible',
2905
3710
  },
2906
3711
  action: {
@@ -2910,6 +3715,7 @@ const fr = {
2910
3715
  working: "Traitement…",
2911
3716
  installToCloud: "Installer dans le cloud…",
2912
3717
  installing: "Installation…",
3718
+ updating: "Mise à jour…",
2913
3719
  uninstall: "Désinstaller",
2914
3720
  uninstalling: "Désinstallation…",
2915
3721
  details: "Détails",
@@ -2927,15 +3733,45 @@ const fr = {
2927
3733
  environmentPlaceholder: "Sélectionner un environnement",
2928
3734
  includeSampleData: "Inclure des données d'exemple",
2929
3735
  noEnvs: "Aucun environnement trouvé dans votre organisation active.",
2930
- noPermission: "Vous n'avez pas la permission d'installer des applications dans un environnement. Seuls les propriétaires et administrateurs de l'organisation peuvent installer.",
3736
+ noPermission: "Vous n'avez pas la permission d'installer des applications dans un environnement. Seuls les propriétaires et administrateurs de l'organisation peuvent installer — contactez l'administrateur de votre organisation.",
2931
3737
  signInFirst: "Vous devez d'abord vous connecter à ObjectStack Cloud.",
2932
3738
  success: "Installé avec succès. Ouvrez l'environnement pour voir la nouvelle application.",
2933
3739
  localSuccess: "v{{version}} installé dans ce runtime. \"{{name}}\" devrait maintenant apparaître dans le sélecteur d'applications.",
3740
+ localLoadsAtRestart: "v{{version}} installé dans ce runtime. \"{{name}}\" sera chargé au prochain redémarrage du runtime et n'apparaîtra pas dans le sélecteur d'applications d'ici là.",
2934
3741
  localManifestConflict: "{{message}}\nRemarque : Une application locale possède déjà ce manifest_id. Supprimez-la d'abord de objectstack.config.ts.",
2935
3742
  localUnauthorized: "Connectez-vous d'abord à ce runtime.",
2936
3743
  localMarketplaceUnavailable: "Ce runtime n'a pas de OS_CLOUD_URL configuré.",
2937
3744
  updateTo: "Mettre à jour → v{{version}}",
2938
3745
  installedVersion: "Installé v{{version}}",
3746
+ deploying: "Déploiement de l'application…",
3747
+ deployed: "L'application est déployée et prête.",
3748
+ openApp: "Ouvrir {{name}}",
3749
+ deployTimeout: "L'installation a été enregistrée, mais cet environnement ne sert pas encore l'application. Le déploiement est peut-être encore en cours : vérifiez à nouveau dans un instant. Si elle n'apparaît jamais, le paquet n'a peut-être pas été chargé, ne contient aucune application, ou son application exige une autorisation que vous n'avez pas.",
3750
+ checkAgain: "Vérifier à nouveau",
3751
+ // ADR-0131 D6 — the install modes a package's manifest permits, and
3752
+ // what an unmanaged install answers (MarketplacePackagePage).
3753
+ mode: {
3754
+ label: "Mode d'installation",
3755
+ managed: "Géré",
3756
+ managedHint: "Le paquet reste l'autorité : il est enregistré comme code, reçoit ses mises à niveau, et ses éléments ne sont pas modifiés ici.",
3757
+ unmanaged: "Copie non gérée",
3758
+ unmanagedHint: "Copié une seule fois dans ce runtime comme ses propres métadonnées : chaque élément est modifiable ici, et la copie ne reçoit aucune mise à niveau.",
3759
+ required: "Choisissez un mode d'installation pour installer ce paquet.",
3760
+ },
3761
+ unmanagedSuccess: "v{{version}} de \"{{name}}\" copié dans ce runtime comme ses propres métadonnées, dans la base {{base}}. La copie est modifiable et ne reçoit aucune mise à niveau.",
3762
+ unmanagedStrippedLocks: "Le paquet verrouillait ces éléments. La copie est modifiable, leurs verrous n'ont donc pas été copiés :",
3763
+ unmanagedIgnored: "Ce runtime ne prend pas en charge les installations non gérées : \"{{name}}\" a donc été installé en mode géré (enregistré comme code) au lieu d'être copié. Mettez à niveau le runtime, puis désinstallez le paquet et réinstallez-le comme copie non gérée.",
3764
+ },
3765
+ // objectui#12146 — the install dialog opened as an UPDATE of the copy
3766
+ // this environment holds (MarketplacePackagePage).
3767
+ update: {
3768
+ dialogTitle: "Mettre à jour {{name}}",
3769
+ dialogDescCurrent: "Mettre à jour la copie installée dans cet environnement ({{host}}).",
3770
+ dialogDescPicker: "Choisissez l'environnement dont la copie installée doit être mise à jour. Vous devez être connecté à ObjectStack Cloud.",
3771
+ majorNotice: "Il s'agit d'une mise à jour de version majeure (v{{fromMajor}} → v{{toMajor}}), qui peut comporter des changements incompatibles.",
3772
+ releaseNotes: "Lire les notes de version de la v{{version}}",
3773
+ success: "Mis à jour vers la v{{version}}.",
3774
+ deployTimeout: "La mise à jour a été enregistrée, mais cet environnement ne sert pas encore la v{{version}}. Le déploiement est peut-être encore en cours : vérifiez à nouveau dans un instant.",
2939
3775
  },
2940
3776
  // objectui#3546 — the MarketplacePage "Your organization" strip.
2941
3777
  org: {
@@ -2953,7 +3789,8 @@ const fr = {
2953
3789
  reviewed: "Examiné et approuvé",
2954
3790
  unreviewed: "Pas encore examiné",
2955
3791
  signed: "Signé",
2956
- grantsIntro: "À l'installation, ce paquet obtiendra :",
3792
+ grantsIntro: "Ce paquet demande :",
3793
+ notEnforced: "Cette liste est enregistrée à l'installation et reconfirmée si une version ultérieure en demande davantage, mais l'exécution ne restreint pas encore le paquet à cette liste.",
2957
3794
  services: "Services de la plateforme",
2958
3795
  hooks: "Hooks de cycle de vie",
2959
3796
  network: "Accès réseau",
@@ -2967,9 +3804,11 @@ const fr = {
2967
3804
  },
2968
3805
  },
2969
3806
  uninstall: {
2970
- confirm: "Désinstaller {{manifestId}} v{{version}} de ce runtime ?\n\nLe manifeste en cache sera supprimé.",
2971
- successInList: "{{manifestId}} supprimé. Redémarrez le runtime pour le décharger complètement.",
2972
- successInDetail: "Manifeste en cache pour {{manifestId}} supprimé.",
3807
+ confirm: "Désinstaller {{manifestId}} v{{version}} de ce runtime ?\n\nL'application sera retirée immédiatement du noyau en cours d'exécution, avec ses jeux d'autorisations et leurs attributions, et le manifeste en cache sera supprimé. Les enregistrements stockés dans ses objets restent dans la base de données.",
3808
+ successInList: "{{manifestId}} supprimé : l'application a été retirée du noyau en cours d'exécution, avec ses jeux d'autorisations et leurs attributions. Les enregistrements stockés dans ses objets restent dans la base de données.",
3809
+ successInDetail: "{{manifestId}} et son manifeste en cache supprimés : l'application a été retirée du noyau en cours d'exécution, avec ses jeux d'autorisations et leurs attributions. Les enregistrements stockés dans ses objets restent dans la base de données.",
3810
+ confirmNotLoaded: "Désinstaller {{manifestId}} v{{version}} de ce runtime ?\n\nLe manifeste en cache sera supprimé. Ce runtime n'a pas chargé le paquet, donc aucune partie n'est en cours d'exécution.",
3811
+ successNotLoaded: "{{manifestId}} supprimé. Il n'était pas chargé, aucun redémarrage n'est nécessaire.",
2973
3812
  },
2974
3813
  accessDenied: {
2975
3814
  title: "Marketplace réservé aux administrateurs",
@@ -2992,30 +3831,21 @@ const fr = {
2992
3831
  storage: "Stockage",
2993
3832
  other: "Autre",
2994
3833
  },
2995
- pricing: {
2996
- free: "Gratuit",
2997
- freemium: "Freemium",
2998
- paid: "Payant",
2999
- subscription: "Abonnement",
3000
- "usage-based": "À l'utilisation",
3001
- "contact-sales": "Contacter les ventes",
3002
- },
3003
3834
  relativeTime: {
3004
3835
  today: "aujourd'hui",
3005
3836
  daysAgo: "il y a {{count}}j",
3006
3837
  monthsAgo: "il y a {{count}} mois",
3838
+ monthsAgo_one: "il y a {{count}} mois",
3839
+ monthsAgo_many: "il y a {{count}} mois",
3840
+ monthsAgo_other: "il y a {{count}} mois",
3007
3841
  yearsAgo: "il y a {{count}} ans",
3842
+ yearsAgo_one: "il y a {{count}} an",
3843
+ yearsAgo_many: "il y a {{count}} ans",
3844
+ yearsAgo_other: "il y a {{count}} ans",
3008
3845
  },
3009
3846
  },
3010
- approvals: {
3011
- approve: 'Approuver',
3012
- reject: 'Rejeter',
3013
- comment: 'Commentaire (facultatif)',
3014
- approveSuccess: 'Approuvé',
3015
- rejectSuccess: 'Rejeté',
3016
- rejectConfirm: 'Rejeter cette demande d’approbation ?',
3017
- },
3018
3847
  approvalsInbox: {
3848
+ recordUnresolvable: 'Cet enregistrement ne peut pas être ouvert',
3019
3849
  loadMore: 'Charger plus',
3020
3850
  loadingMore: 'Chargement…',
3021
3851
  loadedOf: '{{loaded}} sur {{total}} chargées',
@@ -3034,6 +3864,9 @@ const fr = {
3034
3864
  requestInfoSent: 'Renvoyée au demandeur pour complément',
3035
3865
  remindBtn: 'Relancer',
3036
3866
  remindSuccess: 'Relance envoyée à {{count}} approbateur(s)',
3867
+ remindSuccess_one: 'Relance envoyée à {{count}} approbateur',
3868
+ remindSuccess_many: "Relance envoyée à {{count}} d'approbateurs",
3869
+ remindSuccess_other: 'Relance envoyée à {{count}} approbateurs',
3037
3870
  remindThrottled: 'Une relance a déjà été envoyée récemment — réessayez plus tard.',
3038
3871
  replyPlaceholder: 'Répondre sur cette demande…',
3039
3872
  slaRemaining: 'SLA : {{dur}} restants',
@@ -3050,8 +3883,12 @@ const fr = {
3050
3883
  progressApprovals: 'Approbations — {{got}} sur {{need}}',
3051
3884
  progressGroups: 'Avancement des visas — {{got}} sur {{need}} groupes',
3052
3885
  progressEligible: '{{count}} approbateur(s) éligible(s)',
3886
+ progressEligible_one: '{{count}} approbateur éligible',
3887
+ progressEligible_many: "{{count}} d'approbateurs éligibles",
3888
+ progressEligible_other: '{{count}} approbateurs éligibles',
3053
3889
  progressBar: 'Avancement de la décision',
3054
3890
  declaredActions: 'Actions',
3891
+ decisionPanelOffRequestPage: 'Le panneau de décision d\'approbation ne fonctionne que sur les pages de demande d\'approbation.',
3055
3892
  attachmentChip: 'Pièce jointe',
3056
3893
  attachmentOpenFailed: "Impossible d'ouvrir la pièce jointe — veuillez réessayer",
3057
3894
  approveOneTitle: 'Approuver « {{title}} » ?',
@@ -3081,6 +3918,9 @@ const fr = {
3081
3918
  filterCount: '{{shown}} sur {{total}}',
3082
3919
  selected: 'sélectionnées',
3083
3920
  actionableCount: '({{count}} actionnables)',
3921
+ actionableCount_one: '({{count}} actionnable)',
3922
+ actionableCount_many: '({{count}} actionnables)',
3923
+ actionableCount_other: '({{count}} actionnables)',
3084
3924
  selectAll: 'Tout sélectionner',
3085
3925
  selectRow: 'Sélectionner la demande',
3086
3926
  colRequest: 'Demande',
@@ -3115,6 +3955,10 @@ const fr = {
3115
3955
  emptyPending: 'Tout est à jour — rien n\'attend votre approbation.',
3116
3956
  emptyOther: 'Rien ici pour l\'instant.',
3117
3957
  emptyViewAll: 'Voir toutes les demandes',
3958
+ waitingOnOthers: "{{count}} demandes attendent d'autres approbateurs",
3959
+ waitingOnOthers_one: "{{count}} demande attend d'autres approbateurs",
3960
+ waitingOnOthers_many: "{{count}} de demandes attendent d'autres approbateurs",
3961
+ waitingOnOthers_other: "{{count}} demandes attendent d'autres approbateurs",
3118
3962
  noMatches: 'Aucun résultat avec les filtres actuels.',
3119
3963
  keyboardHint: 'Clavier : j/k déplacer · Entrée ouvrir · x sélectionner · a approuver · r rejeter',
3120
3964
  drawerTitle: 'Demande d\'approbation',
@@ -3132,12 +3976,12 @@ const fr = {
3132
3976
  overrideActionLabel: '{{action}} (dérogation)',
3133
3977
  overrideNotice: "Vous n'occupez aucun poste d'approbateur à cette étape. En continuant, votre dérogation d'administrateur sera utilisée : l'étape est finalisée immédiatement et tout approbateur n'ayant pas encore statué est contourné. La décision est enregistrée comme une dérogation d'administrateur.",
3134
3978
  overrideNoticeWho: "Vous n'occupez aucun poste d'approbateur à cette étape. En continuant, votre dérogation d'administrateur sera utilisée : l'étape est finalisée immédiatement et les approbateurs n'ayant pas encore statué sont contournés — {{who}}. La décision est enregistrée comme une dérogation d'administrateur.",
3979
+ overrideReassignNotice: "Vous n'occupez aucun poste d'approbateur à cette étape. En continuant, votre dérogation d'administrateur sera utilisée : l'étape passe au nouvel approbateur que vous choisissez, qui remplace tout approbateur n'ayant pas encore statué. La demande reste en attente de la décision du nouvel approbateur. La réattribution est enregistrée comme une dérogation d'administrateur.",
3980
+ overrideReassignNoticeWho: "Vous n'occupez aucun poste d'approbateur à cette étape. En continuant, votre dérogation d'administrateur sera utilisée : l'étape passe au nouvel approbateur que vous choisissez, qui remplace les approbateurs n'ayant pas encore statué — {{who}}. La demande reste en attente de la décision du nouvel approbateur. La réattribution est enregistrée comme une dérogation d'administrateur.",
3981
+ overrideRecallNotice: "Vous n'avez pas soumis cette demande. En continuant, votre dérogation d'administrateur sera utilisée : la demande est retirée, aucun approbateur n'ayant pas encore statué ne pourra plus agir sur elle, et l'enregistrement est déverrouillé.",
3982
+ overrideRecallNoticeWho: "Vous n'avez pas soumis cette demande. En continuant, votre dérogation d'administrateur sera utilisée : la demande est retirée, l'enregistrement est déverrouillé, et les approbateurs n'ayant pas encore statué ne pourront plus agir sur elle — {{who}}.",
3135
3983
  viaOverrideChip: 'Dérogation administrateur',
3136
3984
  viaOverrideHint: "L'auteur n'occupait aucun poste d'approbateur à cette étape — admis par la voie de dérogation administrateur.",
3137
- rawData: 'Données brutes (JSON)',
3138
- copy: 'Copier',
3139
- copied: 'Copié',
3140
- copyFailed: 'Échec de la copie',
3141
3985
  overrideActor: 'Agir sous une autre identité (admin)',
3142
3986
  actor: 'Acteur',
3143
3987
  auto: 'Auto',
@@ -3154,11 +3998,23 @@ const fr = {
3154
3998
  approveN: 'Approuver {{count}}',
3155
3999
  rejectN: 'Rejeter {{count}}',
3156
4000
  bulkApproveTitle: 'Approuver {{count}} demandes ?',
4001
+ bulkApproveTitle_one: 'Approuver {{count}} demande ?',
4002
+ bulkApproveTitle_many: 'Approuver {{count}} de demandes ?',
4003
+ bulkApproveTitle_other: 'Approuver {{count}} demandes ?',
3157
4004
  bulkApproveBody: 'Chaque demande est approuvée avec votre identité et son flux continue sur la branche d\'approbation.',
3158
4005
  bulkRejectTitle: 'Rejeter {{count}} demandes ?',
4006
+ bulkRejectTitle_one: 'Rejeter {{count}} demande ?',
4007
+ bulkRejectTitle_many: 'Rejeter {{count}} de demandes ?',
4008
+ bulkRejectTitle_other: 'Rejeter {{count}} demandes ?',
3159
4009
  bulkRejectBody: 'Les demandes sélectionnées seront rejetées et leurs demandeurs notifiés.',
3160
4010
  bulkApproved: '{{count}} demandes approuvées',
4011
+ bulkApproved_one: '{{count}} demande approuvée',
4012
+ bulkApproved_many: '{{count}} de demandes approuvées',
4013
+ bulkApproved_other: '{{count}} demandes approuvées',
3161
4014
  bulkRejected: '{{count}} demandes rejetées',
4015
+ bulkRejected_one: '{{count}} demande rejetée',
4016
+ bulkRejected_many: '{{count}} de demandes rejetées',
4017
+ bulkRejected_other: '{{count}} demandes rejetées',
3162
4018
  bulkPartial: '{{ok}} réussies, {{fail}} échouées : {{which}}',
3163
4019
  rejectOneTitle: 'Rejeter « {{title}} » ?',
3164
4020
  rejectOneBody: 'La demande sera rejetée et le demandeur notifié.',
@@ -3183,8 +4039,17 @@ const fr = {
3183
4039
  alreadyDecided: 'Cette demande a déjà été traitée. Actualisez la liste.',
3184
4040
  justNow: 'à l\'instant',
3185
4041
  minutesAgo: 'il y a {{count}} min',
4042
+ minutesAgo_one: 'il y a {{count}} min',
4043
+ minutesAgo_many: 'il y a {{count}} min',
4044
+ minutesAgo_other: 'il y a {{count}} min',
3186
4045
  hoursAgo: 'il y a {{count}} h',
4046
+ hoursAgo_one: 'il y a {{count}} h',
4047
+ hoursAgo_many: 'il y a {{count}} h',
4048
+ hoursAgo_other: 'il y a {{count}} h',
3187
4049
  daysAgo: 'il y a {{count}} jours',
4050
+ daysAgo_one: 'il y a {{count}} jour',
4051
+ daysAgo_many: 'il y a {{count}} jours',
4052
+ daysAgo_other: 'il y a {{count}} jours',
3188
4053
  },
3189
4054
  preview: {
3190
4055
  empty: {
@@ -3205,6 +4070,10 @@ const fr = {
3205
4070
  publishing: 'Publication…',
3206
4071
  exit: "Quitter l'aperçu",
3207
4072
  changes: 'Modifications',
4073
+ pendingHere: 'Aperçu du brouillon · {{count}} modifications non publiées sur cette page',
4074
+ pendingHere_one: 'Aperçu du brouillon · {{count}} modification non publiée sur cette page',
4075
+ pendingHere_many: 'Aperçu du brouillon · {{count}} de modifications non publiées sur cette page',
4076
+ pendingHere_other: 'Aperçu du brouillon · {{count}} modifications non publiées sur cette page',
3208
4077
  },
3209
4078
  changes: {
3210
4079
  title: 'Modifications en attente',
@@ -3219,11 +4088,81 @@ const fr = {
3219
4088
  detailNone: 'Aucune différence détectée — le brouillon correspond à la version publiée.',
3220
4089
  detailChangedKeys: 'Également modifié :',
3221
4090
  confirmNote: 'La publication libère atomiquement les {{count}} brouillons en attente de ce paquet.',
4091
+ confirmNote_one: 'La publication libère atomiquement {{count}} brouillon en attente de ce paquet.',
4092
+ confirmNote_many: 'La publication libère atomiquement les {{count}} de brouillons en attente de ce paquet.',
4093
+ confirmNote_other: 'La publication libère atomiquement les {{count}} brouillons en attente de ce paquet.',
4094
+ // objectui#11591 — the package-less sheet: no package to batch, so each
4095
+ // draft publishes by itself and one that fails stays pending.
4096
+ confirmNoteSeparate: 'La publication libère les {{count}} brouillons en attente un par un : celui qui échoue reste en attente, les autres sont publiés quand même.',
4097
+ confirmNoteSeparate_one: 'La publication libère isolément {{count}} brouillon en attente : s’il échoue, il reste en attente.',
4098
+ confirmNoteSeparate_many: 'La publication libère les {{count}} de brouillons en attente un par un : celui qui échoue reste en attente, les autres sont publiés quand même.',
4099
+ confirmNoteSeparate_other: 'La publication libère les {{count}} brouillons en attente un par un : celui qui échoue reste en attente, les autres sont publiés quand même.',
3222
4100
  publishConfirm: 'Tout publier',
3223
- // [objectui#5418] Pre-publish security-posture findings, shown next to
4101
+ summaryItems: '{{count}} éléments',
4102
+ summaryItems_one: '{{count}} élément',
4103
+ summaryItems_many: '{{count}} d’éléments',
4104
+ summaryItems_other: '{{count}} éléments',
4105
+ summaryType: '{{n}} {{type}}',
4106
+ typeCount: {
4107
+ object: '{{count}} objets',
4108
+ object_one: '{{count}} objet',
4109
+ object_many: '{{count}} d’objets',
4110
+ object_other: '{{count}} objets',
4111
+ view: '{{count}} vues',
4112
+ view_one: '{{count}} vue',
4113
+ view_many: '{{count}} de vues',
4114
+ view_other: '{{count}} vues',
4115
+ page: '{{count}} pages',
4116
+ page_one: '{{count}} page',
4117
+ page_many: '{{count}} de pages',
4118
+ page_other: '{{count}} pages',
4119
+ dashboard: '{{count}} tableaux de bord',
4120
+ dashboard_one: '{{count}} tableau de bord',
4121
+ dashboard_many: '{{count}} de tableaux de bord',
4122
+ dashboard_other: '{{count}} tableaux de bord',
4123
+ app: '{{count}} applications',
4124
+ app_one: '{{count}} application',
4125
+ app_many: '{{count}} d’applications',
4126
+ app_other: '{{count}} applications',
4127
+ action: '{{count}} actions',
4128
+ action_one: '{{count}} action',
4129
+ action_many: '{{count}} d’actions',
4130
+ action_other: '{{count}} actions',
4131
+ report: '{{count}} rapports',
4132
+ report_one: '{{count}} rapport',
4133
+ report_many: '{{count}} de rapports',
4134
+ report_other: '{{count}} rapports',
4135
+ flow: '{{count}} flux',
4136
+ flow_one: '{{count}} flux',
4137
+ flow_many: '{{count}} de flux',
4138
+ flow_other: '{{count}} flux',
4139
+ permission: '{{count}} ensembles d’autorisations',
4140
+ permission_one: '{{count}} ensemble d’autorisations',
4141
+ permission_many: '{{count}} d’ensembles d’autorisations',
4142
+ permission_other: '{{count}} ensembles d’autorisations',
4143
+ agent: '{{count}} agents',
4144
+ agent_one: '{{count}} agent',
4145
+ agent_many: '{{count}} d’agents',
4146
+ agent_other: '{{count}} agents',
4147
+ email_template: '{{count}} modèles d’e-mail',
4148
+ email_template_one: '{{count}} modèle d’e-mail',
4149
+ email_template_many: '{{count}} de modèles d’e-mail',
4150
+ email_template_other: '{{count}} modèles d’e-mail',
4151
+ },
4152
+ // objectui#12929 — the unchecked choice under an added object field whose
4153
+ // literal default the batch publish can write into the existing records.
4154
+ backfillOption: 'Renseigner la valeur par défaut ({{count}} enregistrements existants)',
4155
+ backfillOption_one: 'Renseigner la valeur par défaut ({{count}} enregistrement existant)',
4156
+ backfillOption_many: 'Renseigner la valeur par défaut ({{count}} d’enregistrements existants)',
4157
+ backfillOption_other: 'Renseigner la valeur par défaut ({{count}} enregistrements existants)',
4158
+ backfillOptionNoCount: 'Renseigner la valeur par défaut',
4159
+ // [`7a90afdf9`] Pre-publish security-posture findings, shown next to
3224
4160
  // the confirm button so a refusal the door would issue is read BEFORE
3225
4161
  // the click rather than as a toast after the batch rolled back.
3226
4162
  securityBlockTitle: 'La publication sera refusée — {{count}} élément(s) nécessitent d’abord une décision',
4163
+ securityBlockTitle_one: 'La publication sera refusée — {{count}} élément nécessite d’abord une décision',
4164
+ securityBlockTitle_many: 'La publication sera refusée — {{count}} d’éléments nécessitent d’abord une décision',
4165
+ securityBlockTitle_other: 'La publication sera refusée — {{count}} éléments nécessitent d’abord une décision',
3227
4166
  securityBlockWhere: 'Corrigez-le sur l’objet dans Paramètres → Partage d’enregistrements, puis publiez à nouveau.',
3228
4167
  },
3229
4168
  // ADR-0045 — the materialized-but-unlisted app banner
@@ -3248,7 +4187,7 @@ const fr = {
3248
4187
  revertLabel: 'Modification annulée',
3249
4188
  applyLabel: 'Modification de génération',
3250
4189
  revert: 'annulation',
3251
- items: 'éléments',
4190
+ items: 'Éléments : {{count}}',
3252
4191
  revertAction: 'Annuler',
3253
4192
  reverted: 'Annulé — la modification a été retirée.',
3254
4193
  revertFailed: 'Échec de l\'annulation',
@@ -3277,28 +4216,32 @@ const fr = {
3277
4216
  rangeEnd: "À",
3278
4217
  operators: {
3279
4218
  equals: "Égal à",
3280
- notEquals: "Différent de",
4219
+ not_equals: "Différent de",
3281
4220
  contains: "Contient",
3282
- containsCaseInsensitive: "Contient (ignorer la casse)",
3283
- notContains: "Ne contient pas",
3284
- isEmpty: "Est vide",
3285
- isNotEmpty: "N'est pas vide",
3286
- greaterThan: "Supérieur à",
3287
- lessThan: "Inférieur à",
3288
- greaterOrEqual: "Supérieur ou égal",
3289
- lessOrEqual: "Inférieur ou égal",
4221
+ icontains: "Contient (ignorer la casse)",
4222
+ not_contains: "Ne contient pas",
4223
+ is_empty: "Est vide",
4224
+ is_not_empty: "N'est pas vide",
4225
+ greater_than: "Supérieur à",
4226
+ less_than: "Inférieur à",
4227
+ greater_than_or_equal: "Supérieur ou égal",
4228
+ less_than_or_equal: "Inférieur ou égal",
3290
4229
  before: "Avant",
3291
4230
  after: "Après",
3292
4231
  between: "Entre",
3293
4232
  in: "Dans",
3294
- notIn: "Pas dans",
3295
- startsWith: "Commence par",
3296
- endsWith: "Se termine par",
3297
- isNull: "Est null",
3298
- isNotNull: "N'est pas null",
4233
+ not_in: "Pas dans",
4234
+ starts_with: "Commence par",
4235
+ ends_with: "Se termine par",
4236
+ is_null: "Est null",
4237
+ is_not_null: "N'est pas null",
3299
4238
  exists: "Est défini",
3300
4239
  notExists: "N'est pas défini",
3301
4240
  },
4241
+ emptyCheckHint: {
4242
+ text: '« {{isEmpty}} » correspond aussi à un texte vide ; « {{isNull}} » uniquement à une valeur absente.',
4243
+ list: '« {{isEmpty}} » correspond aussi à une liste vide ; « {{isNull}} » uniquement à une valeur absente.',
4244
+ },
3302
4245
  },
3303
4246
  sortBuilder: {
3304
4247
  sortBy: "Trier par",
@@ -3311,7 +4254,9 @@ const fr = {
3311
4254
  },
3312
4255
  collaboration: {
3313
4256
  commentCount: "{{count}} commentaires",
3314
- commentCountOne: "{{count}} commentaire",
4257
+ commentCount_one: "{{count}} commentaire",
4258
+ commentCount_many: "{{count}} de commentaires",
4259
+ commentCount_other: "{{count}} commentaires",
3315
4260
  resolvedSuffix: " · Résolu",
3316
4261
  sortComments: "Trier les commentaires",
3317
4262
  sortOldest: "Plus anciens",
@@ -3320,11 +4265,22 @@ const fr = {
3320
4265
  reopen: "Rouvrir",
3321
4266
  justNow: "à l'instant",
3322
4267
  minutesAgo: "il y a {{count}} min",
4268
+ minutesAgo_one: "il y a {{count}} min",
4269
+ minutesAgo_many: "il y a {{count}} min",
4270
+ minutesAgo_other: "il y a {{count}} min",
3323
4271
  hoursAgo: "il y a {{count}} h",
4272
+ hoursAgo_one: "il y a {{count}} h",
4273
+ hoursAgo_many: "il y a {{count}} h",
4274
+ hoursAgo_other: "il y a {{count}} h",
3324
4275
  daysAgo: "il y a {{count}} j",
4276
+ daysAgo_one: "il y a {{count}} j",
4277
+ daysAgo_many: "il y a {{count}} j",
4278
+ daysAgo_other: "il y a {{count}} j",
3325
4279
  edited: "(modifié)",
3326
4280
  reactionCount: "{{count}} réactions",
3327
- reactionCountOne: "{{count}} réaction",
4281
+ reactionCount_one: "{{count}} réaction",
4282
+ reactionCount_many: "{{count}} de réactions",
4283
+ reactionCount_other: "{{count}} réactions",
3328
4284
  addThumbsUp: "Ajouter un pouce levé",
3329
4285
  reply: "Répondre",
3330
4286
  reactThumbsUp: "Réagir avec un pouce levé",
@@ -3335,9 +4291,13 @@ const fr = {
3335
4291
  commentPlaceholder: "Ajouter un commentaire… (utilisez @ pour mentionner)",
3336
4292
  send: "Envoyer",
3337
4293
  presentUserCount: "{{count}} utilisateurs présents",
3338
- presentUserCountOne: "{{count}} utilisateur présent",
4294
+ presentUserCount_one: "{{count}} utilisateur présent",
4295
+ presentUserCount_many: "{{count}} d'utilisateurs présents",
4296
+ presentUserCount_other: "{{count}} utilisateurs présents",
3339
4297
  moreUserCount: "{{count}} autres utilisateurs",
3340
- moreUserCountOne: "{{count}} autre utilisateur",
4298
+ moreUserCount_one: "{{count}} autre utilisateur",
4299
+ moreUserCount_many: "{{count}} d'autres utilisateurs",
4300
+ moreUserCount_other: "{{count}} autres utilisateurs",
3341
4301
  userStatusTitle: "{{name}} ({{status}})",
3342
4302
  statusActive: "actif",
3343
4303
  statusIdle: "inactif",
@@ -3345,6 +4305,11 @@ const fr = {
3345
4305
  },
3346
4306
  wizard: {
3347
4307
  missingRequired: "Veuillez renseigner les champs obligatoires : {{fields}}",
4308
+ back: "Retour",
4309
+ submitting: "Envoi…",
4310
+ stepFallback: "Étape {{n}}",
4311
+ progressLabel: "Progression",
4312
+ emptyStep: "Aucun champ configuré pour cette étape",
3348
4313
  },
3349
4314
  flowRunner: {
3350
4315
  title: 'Saisie',
@@ -3394,6 +4359,8 @@ const fr = {
3394
4359
  setDefaultFailed: "Échec de la définition de l'application par défaut : {{reason}}",
3395
4360
  appDeleted: "{{name}} supprimée",
3396
4361
  deleteFailed: "Échec de la suppression de l'application : {{reason}}",
4362
+ nothingToDelete: "Rien à supprimer pour {{name}} : {{reason}}",
4363
+ alreadyAtDefault: "elle est déjà à la valeur par défaut de son package",
3397
4364
  bulkEnabled: "{{n}} applications activées",
3398
4365
  bulkDisabled: "{{n}} applications désactivées",
3399
4366
  bulkFailed: "Échec pour {{n}} : {{details}}",
@@ -3402,5 +4369,131 @@ const fr = {
3402
4369
  bulkOperationFailed: "Échec de l'opération groupée : {{reason}}",
3403
4370
  },
3404
4371
  },
4372
+ // objectui#6301 — Configuration › Automatisation des packages (ADR-0126
4373
+ // §7.4). Terminologie du pack : `common.package` = Package,
4374
+ // `flowRunner.completed` = Flux, guillemets « … ». ⛔ Aucune formulation
4375
+ // d'ascendance ou de dérive dans ce groupe (§9).
4376
+ packagedAutomation: {
4377
+ title: "Automatisation des packages",
4378
+ subtitle: "Flux et actions fournis par les packages installés. Désactivez-en un pour ce déploiement, ou clonez un flux sous un nouveau nom pour le personnaliser. La modification se fait dans Studio.",
4379
+ refresh: "Actualiser",
4380
+ flowsHeading: "Flux des packages",
4381
+ actionsHeading: "Actions des packages",
4382
+ colFlow: "Flux",
4383
+ colActivation: "Activation",
4384
+ colActions: "Actions",
4385
+ toggleLabel: "Activation de {{label}}",
4386
+ on: "Activé",
4387
+ off: "Désactivé",
4388
+ notRunning: "Ne s'exécute pas ici",
4389
+ clone: "Cloner",
4390
+ cloneTitle: "Cloner le flux du package",
4391
+ cloneBody: "La copie reprend toute la définition et exige un nouveau nom machine et un nouveau libellé. Modifiez la copie dans Studio.",
4392
+ cloneName: "Nouveau nom machine",
4393
+ cloneLabel: "Nouveau libellé",
4394
+ cancel: "Annuler",
4395
+ cloneConfirm: "Créer le clone",
4396
+ cloneCreated: "Flux « {{name}} » créé.",
4397
+ cloneSwitchSourceOff: "Désactiver « {{label}} »",
4398
+ cloneSourceOff: "Le flux empaqueté « {{label}} » est désactivé.",
4399
+ cloneOpen: "Ouvrir la copie dans Studio",
4400
+ emptyTitle: "Aucun flux de package",
4401
+ emptyBody: "Aucun package installé ne fournit de flux d'automatisation sur ce déploiement. Les flux que vous créez vous-même se trouvent dans Studio.",
4402
+ loadFailed: "Impossible de charger l'automatisation des packages.",
4403
+ toggleFailedHttp: "Impossible de modifier l'activation (HTTP {{status}}).",
4404
+ toggleFailed: "Impossible de modifier l'activation.",
4405
+ cloneFailedHttp: "Impossible de cloner ce flux (HTTP {{status}}).",
4406
+ cloneFailed: "Impossible de cloner ce flux.",
4407
+ reasonDetails: "Détails",
4408
+ actionsSubtitle: "Actions fournies par les packages installés. Désactivez-en une pour ce déploiement et elle cesse de s'exécuter partout où elle est proposée. Vous pouvez toujours créer votre propre action à côté, dans Studio.",
4409
+ colAction: "Action",
4410
+ colObject: "Objet",
4411
+ actionToggleLabel: "Activation de {{label}} sur {{object}}",
4412
+ actionsEmptyTitle: "Aucune action de package",
4413
+ actionsEmptyBody: "Aucun package installé ne déclare d'action sur ce déploiement. Les actions que vous créez vous-même se trouvent dans Studio.",
4414
+ actionsLoadFailed: "Impossible de charger les actions des packages.",
4415
+ },
4416
+ element: {
4417
+ number: {
4418
+ noObject: "Aucun objet indiqué : définissez dataSource.object.",
4419
+ sourceUnresolved: "La source de données de cet indicateur n’a pas pu être résolue",
4420
+ },
4421
+ image: {
4422
+ noSource: "Aucune source d’image",
4423
+ },
4424
+ recordPicker: {
4425
+ sourceUnresolved: "La source de données de ce sélecteur d’enregistrement n’a pas pu être résolue",
4426
+ },
4427
+ calendar: {
4428
+ sourceUnresolved: "La source de données de ce calendrier n’a pas pu être résolue",
4429
+ },
4430
+ chart: {
4431
+ sourceUnresolved: "La source de données de ce graphique n’a pas pu être résolue",
4432
+ },
4433
+ pivotTable: {
4434
+ sourceUnresolved: "La source de données de ce tableau croisé dynamique n’a pas pu être résolue",
4435
+ },
4436
+ detailView: {
4437
+ sourceUnresolved: "La source de données de cette vue détaillée n’a pas pu être résolue",
4438
+ },
4439
+ relatedList: {
4440
+ sourceUnresolved: "La source de données de cette liste associée n’a pas pu être résolue",
4441
+ parentUnreadable: "L’enregistrement parent de cette liste associée n’a pas pu être lu",
4442
+ },
4443
+ form: {
4444
+ sourceUnresolved: "La source de données de ce formulaire n’a pas pu être résolue",
4445
+ },
4446
+ lineItems: {
4447
+ sourceUnresolved: "La source de données de ce panneau de lignes n’a pas pu être résolue",
4448
+ },
4449
+ gantt: {
4450
+ sourceUnresolved: "La source de données de ce diagramme de Gantt n’a pas pu être résolue",
4451
+ },
4452
+ grid: {
4453
+ sourceUnresolved: "La source de données de cette grille n’a pas pu être résolue",
4454
+ },
4455
+ board: {
4456
+ sourceUnresolved: "La source de données de ce tableau n’a pas pu être résolue",
4457
+ },
4458
+ listView: {
4459
+ sourceUnresolved: "La source de données de cette vue en liste n’a pas pu être résolue",
4460
+ },
4461
+ map: {
4462
+ sourceUnresolved: "La source de données de cette carte n’a pas pu être résolue",
4463
+ },
4464
+ timeline: {
4465
+ sourceUnresolved: "La source de données de cette chronologie n’a pas pu être résolue",
4466
+ },
4467
+ component: {
4468
+ sourceUnresolved: "La source de données de ce composant n’a pas pu être résolue",
4469
+ noDataSource: "Aucune source de données résolue",
4470
+ apiRefused: "La source de données API de ce composant est refusée",
4471
+ apiUnreadable: "La source de données API de ce composant n’a pas pu être lue",
4472
+ },
4473
+ metadataViewer: {
4474
+ missingKey: "{{key}} manquant pour cette vue.",
4475
+ loading: "Chargement de {{name}}…",
4476
+ loadFailed: "Impossible de charger {{name}} : {{message}}",
4477
+ notFound: "{{name}} introuvable.",
4478
+ stateMachine: "Machine à états",
4479
+ flow: "Flux",
4480
+ permission: "Autorisation",
4481
+ noStateMachine: "Aucune machine à états sur {{object}}.",
4482
+ noStateMachineNamed: "Aucune machine à états nommée « {{name}} » sur {{object}}.",
4483
+ lifecycle: "Cycle de vie de {{object}}",
4484
+ field: "champ {{field}}",
4485
+ initial: "début",
4486
+ final: "fin",
4487
+ steps: "Étapes : {{count}}",
4488
+ noSteps: "Aucune étape à afficher.",
4489
+ untitledStep: "(étape)",
4490
+ hiddenSteps: "Étapes techniques masquées : {{count}} · définissez {{setting}} pour tout afficher",
4491
+ objectAccess: "Accès aux objets : {{count}}",
4492
+ noPermissions: "Aucune autorisation d’objet déclarée.",
4493
+ object: "Objet",
4494
+ unknownType: "Type de vue de métadonnées inconnu. Attendu : {{a}}, {{b}} ou {{c}}.",
4495
+ unknownTypeNamed: "Type de vue de métadonnées inconnu « {{type}} ». Attendu : {{a}}, {{b}} ou {{c}}.",
4496
+ },
4497
+ },
3405
4498
  };
3406
4499
  export default fr;