@keepkit/ui 0.10.0 → 0.12.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.
package/dist/index.js CHANGED
@@ -12,8 +12,82 @@ import { useRef, useState } from "react";
12
12
 
13
13
  // src/ui-context.tsx
14
14
  import { createContext, useContext, useMemo } from "react";
15
- import { jsx } from "react/jsx-runtime";
16
- var DEFAULT_LABELS = {
15
+
16
+ // src/locales/de.ts
17
+ var DE_LABELS = {
18
+ save: "Speichern",
19
+ saved: "Gespeichert",
20
+ remove: "Entfernen",
21
+ loading: "Wird geladen\u2026",
22
+ saving: "Wird gespeichert\u2026",
23
+ syncing: "Wird synchronisiert\u2026",
24
+ error: "Ein Fehler ist aufgetreten.",
25
+ allTags: "Alle",
26
+ tags: "Tags",
27
+ filterTags: "Gespeicherte Elemente nach Tag filtern",
28
+ note: "Notiz",
29
+ saveNote: "Notiz speichern",
30
+ noItems: "Keine gespeicherten Elemente.",
31
+ loadingItems: "Gespeicherte Elemente werden geladen\u2026",
32
+ errorItems: "Gespeicherte Elemente konnten nicht geladen werden.",
33
+ search: "Gespeicherte Elemente durchsuchen",
34
+ sort: "Gespeicherte Elemente sortieren",
35
+ newest: "Neueste zuerst",
36
+ oldest: "\xC4lteste zuerst",
37
+ savedNewest: "Zuletzt gespeichert zuerst",
38
+ savedOldest: "Am l\xE4ngsten gespeichert zuerst",
39
+ updatedNewest: "Zuletzt aktualisiert zuerst",
40
+ updatedOldest: "Am l\xE4ngsten nicht aktualisiert zuerst",
41
+ previousPage: "Vorherige Seite",
42
+ nextPage: "N\xE4chste Seite",
43
+ pagination: "Seitennavigation",
44
+ page: "Seite",
45
+ selectItems: "Gespeicherte Elemente ausw\xE4hlen",
46
+ selectedCount: "ausgew\xE4hlt",
47
+ deleteSelected: "Auswahl l\xF6schen",
48
+ tagsToApply: "Anzuwendende Tags",
49
+ applyTags: "Tags anwenden",
50
+ savedMessage: "Element gespeichert.",
51
+ removedMessage: "Element entfernt.",
52
+ undo: "R\xFCckg\xE4ngig",
53
+ undoAvailable: "Element entfernt. R\xFCckg\xE4ngig machen?",
54
+ selectionScope: "Auswahlbereich",
55
+ currentPage: "Aktuelle Seite",
56
+ searchResults: "Aktuelle Suchergebnisse",
57
+ allItems: "Alle gespeicherten Elemente",
58
+ statusAvailable: "Verf\xFCgbar",
59
+ noteSavedMessage: "Notiz gespeichert.",
60
+ exportData: "JSON exportieren",
61
+ importData: "JSON importieren",
62
+ importMode: "Importmodus",
63
+ merge: "Zusammenf\xFChren",
64
+ replace: "Ersetzen",
65
+ importedCount: "Elemente importiert",
66
+ failedCount: "Elemente fehlgeschlagen",
67
+ storageQuotaError: "Der Speicher ist voll. Schaffen Sie Speicherplatz und versuchen Sie es erneut.",
68
+ statusExpired: "Abgelaufen",
69
+ statusRemoved: "Entfernt",
70
+ statusDeleted: "Gel\xF6scht",
71
+ statusPrivate: "Privat",
72
+ statusUnknown: "Nicht verf\xFCgbar",
73
+ retry: "Erneut versuchen",
74
+ removeFromList: "Aus Liste entfernen",
75
+ pruneStale: "Nicht verf\xFCgbare Elemente entfernen",
76
+ retrySync: "Synchronisierung erneut versuchen",
77
+ resolveSync: "Konflikte l\xF6sen",
78
+ keepLocal: "Lokale Version behalten",
79
+ useServer: "Serverversion verwenden",
80
+ manualMerge: "Manuell zusammenf\xFChren",
81
+ close: "Schlie\xDFen",
82
+ backupRecovery: "Aus Backup wiederherstellen",
83
+ backupRecoveryDescription: "Wenn lokale Synchronisierungsdaten besch\xE4digt sind, stellen Sie ein g\xFCltiges JSON-Backup wieder her.",
84
+ syncPending: "\xC4nderungen warten auf die Synchronisierung.",
85
+ syncSynced: "Alle \xC4nderungen sind synchronisiert.",
86
+ syncConflict: "Einige \xC4nderungen ben\xF6tigen eine Konfliktl\xF6sung."
87
+ };
88
+
89
+ // src/locales/en.ts
90
+ var EN_LABELS = {
17
91
  save: "Save",
18
92
  saved: "Saved",
19
93
  remove: "Remove",
@@ -22,6 +96,7 @@ var DEFAULT_LABELS = {
22
96
  syncing: "Syncing\u2026",
23
97
  error: "Something went wrong.",
24
98
  allTags: "All",
99
+ tags: "Tags",
25
100
  filterTags: "Filter saved items by tag",
26
101
  note: "Note",
27
102
  saveNote: "Save note",
@@ -47,6 +122,13 @@ var DEFAULT_LABELS = {
47
122
  applyTags: "Apply tags",
48
123
  savedMessage: "Item saved.",
49
124
  removedMessage: "Item removed.",
125
+ undo: "Undo",
126
+ undoAvailable: "Item removed. Undo?",
127
+ selectionScope: "Selection scope",
128
+ currentPage: "Current page",
129
+ searchResults: "Current search results",
130
+ allItems: "All saved items",
131
+ statusAvailable: "Available",
50
132
  noteSavedMessage: "Note saved.",
51
133
  exportData: "Export JSON",
52
134
  importData: "Import JSON",
@@ -60,13 +142,1114 @@ var DEFAULT_LABELS = {
60
142
  statusRemoved: "Removed",
61
143
  statusDeleted: "Deleted",
62
144
  statusPrivate: "Private",
63
- statusUnknown: "Unavailable"
145
+ statusUnknown: "Unavailable",
146
+ retry: "Retry",
147
+ removeFromList: "Remove from list",
148
+ pruneStale: "Remove unavailable items",
149
+ retrySync: "Retry sync",
150
+ resolveSync: "Resolve conflicts",
151
+ keepLocal: "Keep local",
152
+ useServer: "Use server",
153
+ manualMerge: "Manual merge",
154
+ close: "Close",
155
+ backupRecovery: "Restore from backup",
156
+ backupRecoveryDescription: "If local sync data is damaged, restore a known-good JSON backup.",
157
+ syncPending: "Changes are waiting to sync.",
158
+ syncSynced: "All changes are synced.",
159
+ syncConflict: "Some changes need conflict resolution."
160
+ };
161
+
162
+ // src/locales/es.ts
163
+ var ES_LABELS = {
164
+ save: "Guardar",
165
+ saved: "Guardado",
166
+ remove: "Eliminar",
167
+ loading: "Cargando\u2026",
168
+ saving: "Guardando\u2026",
169
+ syncing: "Sincronizando\u2026",
170
+ error: "Se produjo un error.",
171
+ allTags: "Todos",
172
+ tags: "Etiquetas",
173
+ filterTags: "Filtrar elementos guardados por etiqueta",
174
+ note: "Nota",
175
+ saveNote: "Guardar nota",
176
+ noItems: "No hay elementos guardados.",
177
+ loadingItems: "Cargando elementos guardados\u2026",
178
+ errorItems: "No se pudieron cargar los elementos guardados.",
179
+ search: "Buscar elementos guardados",
180
+ sort: "Ordenar elementos guardados",
181
+ newest: "M\xE1s recientes primero",
182
+ oldest: "M\xE1s antiguos primero",
183
+ savedNewest: "Guardados m\xE1s recientemente primero",
184
+ savedOldest: "Guardados m\xE1s antiguos primero",
185
+ updatedNewest: "Actualizados m\xE1s recientemente primero",
186
+ updatedOldest: "Actualizados m\xE1s antiguos primero",
187
+ previousPage: "P\xE1gina anterior",
188
+ nextPage: "P\xE1gina siguiente",
189
+ pagination: "Paginaci\xF3n",
190
+ page: "P\xE1gina",
191
+ selectItems: "Seleccionar elementos guardados",
192
+ selectedCount: "seleccionados",
193
+ deleteSelected: "Eliminar seleccionados",
194
+ tagsToApply: "Etiquetas que aplicar",
195
+ applyTags: "Aplicar etiquetas",
196
+ savedMessage: "Elemento guardado.",
197
+ removedMessage: "Elemento eliminado.",
198
+ undo: "Deshacer",
199
+ undoAvailable: "Elemento eliminado. \xBFDeshacer?",
200
+ selectionScope: "\xC1mbito de selecci\xF3n",
201
+ currentPage: "P\xE1gina actual",
202
+ searchResults: "Resultados de b\xFAsqueda actuales",
203
+ allItems: "Todos los elementos guardados",
204
+ statusAvailable: "Disponible",
205
+ noteSavedMessage: "Nota guardada.",
206
+ exportData: "Exportar JSON",
207
+ importData: "Importar JSON",
208
+ importMode: "Modo de importaci\xF3n",
209
+ merge: "Combinar",
210
+ replace: "Reemplazar",
211
+ importedCount: "elementos importados",
212
+ failedCount: "elementos fallidos",
213
+ storageQuotaError: "El almacenamiento est\xE1 lleno. Libere espacio y vuelva a intentarlo.",
214
+ statusExpired: "Caducado",
215
+ statusRemoved: "Eliminado",
216
+ statusDeleted: "Borrado",
217
+ statusPrivate: "Privado",
218
+ statusUnknown: "No disponible",
219
+ retry: "Reintentar",
220
+ removeFromList: "Quitar de la lista",
221
+ pruneStale: "Quitar elementos no disponibles",
222
+ retrySync: "Reintentar sincronizaci\xF3n",
223
+ resolveSync: "Resolver conflictos",
224
+ keepLocal: "Conservar versi\xF3n local",
225
+ useServer: "Usar versi\xF3n del servidor",
226
+ manualMerge: "Combinar manualmente",
227
+ close: "Cerrar",
228
+ backupRecovery: "Restaurar desde copia de seguridad",
229
+ backupRecoveryDescription: "Si los datos locales est\xE1n da\xF1ados, restaura una copia JSON v\xE1lida.",
230
+ syncPending: "Hay cambios pendientes de sincronizaci\xF3n.",
231
+ syncSynced: "Todos los cambios est\xE1n sincronizados.",
232
+ syncConflict: "Algunos cambios necesitan resolver un conflicto."
233
+ };
234
+
235
+ // src/locales/fil.ts
236
+ var FIL_LABELS = {
237
+ save: "I-save",
238
+ saved: "Nai-save",
239
+ remove: "Alisin",
240
+ loading: "Naglo-load\u2026",
241
+ saving: "Sini-save\u2026",
242
+ syncing: "Sini-sync\u2026",
243
+ error: "May naganap na error.",
244
+ allTags: "Lahat",
245
+ tags: "Mga tag",
246
+ filterTags: "I-filter ang mga naka-save na item ayon sa tag",
247
+ note: "Tala",
248
+ saveNote: "I-save ang tala",
249
+ noItems: "Walang naka-save na item.",
250
+ loadingItems: "Nilo-load ang mga naka-save na item\u2026",
251
+ errorItems: "Hindi ma-load ang mga naka-save na item.",
252
+ search: "Maghanap ng naka-save na item",
253
+ sort: "Ayusin ang mga naka-save na item",
254
+ newest: "Pinakabago muna",
255
+ oldest: "Pinakaluma muna",
256
+ savedNewest: "Pinakabagong na-save muna",
257
+ savedOldest: "Pinakamatagal na naka-save muna",
258
+ updatedNewest: "Pinakabagong na-update muna",
259
+ updatedOldest: "Pinakamatagal na hindi na-update muna",
260
+ previousPage: "Nakaraang pahina",
261
+ nextPage: "Susunod na pahina",
262
+ pagination: "Pagpapa-pahina",
263
+ page: "Pahina",
264
+ selectItems: "Pumili ng naka-save na item",
265
+ selectedCount: "napili",
266
+ deleteSelected: "Tanggalin ang napili",
267
+ tagsToApply: "Mga tag na ilalapat",
268
+ applyTags: "Ilapat ang mga tag",
269
+ savedMessage: "Na-save ang item.",
270
+ removedMessage: "Inalis ang item.",
271
+ undo: "I-undo",
272
+ undoAvailable: "Inalis ang item. I-undo?",
273
+ selectionScope: "Saklaw ng pagpili",
274
+ currentPage: "Kasalukuyang pahina",
275
+ searchResults: "Kasalukuyang resulta ng paghahanap",
276
+ allItems: "Lahat ng naka-save na item",
277
+ statusAvailable: "Available",
278
+ noteSavedMessage: "Na-save ang tala.",
279
+ exportData: "I-export ang JSON",
280
+ importData: "I-import ang JSON",
281
+ importMode: "Mode ng pag-import",
282
+ merge: "Pagsamahin",
283
+ replace: "Palitan",
284
+ importedCount: "item ang na-import",
285
+ failedCount: "item ang nabigo",
286
+ storageQuotaError: "Puno na ang storage. Magbakante ng espasyo at subukan muli.",
287
+ statusExpired: "Nag-expire",
288
+ statusRemoved: "Inalis",
289
+ statusDeleted: "Tinanggal",
290
+ statusPrivate: "Pribado",
291
+ statusUnknown: "Hindi available",
292
+ retry: "Subukan muli",
293
+ removeFromList: "Alisin sa listahan",
294
+ pruneStale: "Alisin ang hindi available na item",
295
+ retrySync: "Subukan muli ang sync",
296
+ resolveSync: "Ayusin ang mga conflict",
297
+ keepLocal: "Panatilihin ang lokal",
298
+ useServer: "Gamitin ang server",
299
+ manualMerge: "Manwal na pagsamahin",
300
+ close: "Isara",
301
+ backupRecovery: "I-restore mula sa backup",
302
+ backupRecoveryDescription: "Kung sira ang lokal na sync data, mag-restore ng gumaganang JSON backup.",
303
+ syncPending: "May mga pagbabagong naghihintay ng sync.",
304
+ syncSynced: "Naka-sync na ang lahat ng pagbabago.",
305
+ syncConflict: "May mga pagbabagong kailangang ayusin ang conflict."
306
+ };
307
+
308
+ // src/locales/fr.ts
309
+ var FR_LABELS = {
310
+ save: "Enregistrer",
311
+ saved: "Enregistr\xE9",
312
+ remove: "Supprimer",
313
+ loading: "Chargement\u2026",
314
+ saving: "Enregistrement\u2026",
315
+ syncing: "Synchronisation\u2026",
316
+ error: "Une erreur s\u2019est produite.",
317
+ allTags: "Tous",
318
+ tags: "\xC9tiquettes",
319
+ filterTags: "Filtrer les \xE9l\xE9ments enregistr\xE9s par \xE9tiquette",
320
+ note: "Note",
321
+ saveNote: "Enregistrer la note",
322
+ noItems: "Aucun \xE9l\xE9ment enregistr\xE9.",
323
+ loadingItems: "Chargement des \xE9l\xE9ments enregistr\xE9s\u2026",
324
+ errorItems: "Impossible de charger les \xE9l\xE9ments enregistr\xE9s.",
325
+ search: "Rechercher des \xE9l\xE9ments enregistr\xE9s",
326
+ sort: "Trier les \xE9l\xE9ments enregistr\xE9s",
327
+ newest: "Plus r\xE9cent d\u2019abord",
328
+ oldest: "Plus ancien d\u2019abord",
329
+ savedNewest: "Enregistrement le plus r\xE9cent d\u2019abord",
330
+ savedOldest: "Enregistrement le plus ancien d\u2019abord",
331
+ updatedNewest: "Mise \xE0 jour la plus r\xE9cente d\u2019abord",
332
+ updatedOldest: "Mise \xE0 jour la plus ancienne d\u2019abord",
333
+ previousPage: "Page pr\xE9c\xE9dente",
334
+ nextPage: "Page suivante",
335
+ pagination: "Pagination",
336
+ page: "Page",
337
+ selectItems: "S\xE9lectionner les \xE9l\xE9ments enregistr\xE9s",
338
+ selectedCount: "s\xE9lectionn\xE9s",
339
+ deleteSelected: "Supprimer la s\xE9lection",
340
+ tagsToApply: "\xC9tiquettes \xE0 appliquer",
341
+ applyTags: "Appliquer les \xE9tiquettes",
342
+ savedMessage: "\xC9l\xE9ment enregistr\xE9.",
343
+ removedMessage: "\xC9l\xE9ment supprim\xE9.",
344
+ undo: "Annuler",
345
+ undoAvailable: "\xC9l\xE9ment supprim\xE9. Annuler ?",
346
+ selectionScope: "Port\xE9e de la s\xE9lection",
347
+ currentPage: "Page actuelle",
348
+ searchResults: "R\xE9sultats de recherche actuels",
349
+ allItems: "Tous les \xE9l\xE9ments enregistr\xE9s",
350
+ statusAvailable: "Disponible",
351
+ noteSavedMessage: "Note enregistr\xE9e.",
352
+ exportData: "Exporter JSON",
353
+ importData: "Importer JSON",
354
+ importMode: "Mode d\u2019importation",
355
+ merge: "Fusionner",
356
+ replace: "Remplacer",
357
+ importedCount: "\xE9l\xE9ments import\xE9s",
358
+ failedCount: "\xE9l\xE9ments en \xE9chec",
359
+ storageQuotaError: "Le stockage est plein. Lib\xE9rez de l\u2019espace et r\xE9essayez.",
360
+ statusExpired: "Expir\xE9",
361
+ statusRemoved: "Supprim\xE9",
362
+ statusDeleted: "Effac\xE9",
363
+ statusPrivate: "Priv\xE9",
364
+ statusUnknown: "Indisponible",
365
+ retry: "R\xE9essayer",
366
+ removeFromList: "Retirer de la liste",
367
+ pruneStale: "Retirer les \xE9l\xE9ments indisponibles",
368
+ retrySync: "R\xE9essayer la synchronisation",
369
+ resolveSync: "R\xE9soudre les conflits",
370
+ keepLocal: "Garder la version locale",
371
+ useServer: "Utiliser la version serveur",
372
+ manualMerge: "Fusion manuelle",
373
+ close: "Fermer",
374
+ backupRecovery: "Restaurer depuis une sauvegarde",
375
+ backupRecoveryDescription: "Si les donn\xE9es locales sont endommag\xE9es, restaurez une sauvegarde JSON valide.",
376
+ syncPending: "Des modifications attendent la synchronisation.",
377
+ syncSynced: "Toutes les modifications sont synchronis\xE9es.",
378
+ syncConflict: "Certaines modifications n\xE9cessitent une r\xE9solution de conflit."
379
+ };
380
+
381
+ // src/locales/id.ts
382
+ var ID_LABELS = {
383
+ save: "Simpan",
384
+ saved: "Tersimpan",
385
+ remove: "Hapus",
386
+ loading: "Memuat\u2026",
387
+ saving: "Menyimpan\u2026",
388
+ syncing: "Menyinkronkan\u2026",
389
+ error: "Terjadi kesalahan.",
390
+ allTags: "Semua",
391
+ tags: "Tag",
392
+ filterTags: "Filter item tersimpan berdasarkan tag",
393
+ note: "Catatan",
394
+ saveNote: "Simpan catatan",
395
+ noItems: "Belum ada item tersimpan.",
396
+ loadingItems: "Memuat item tersimpan\u2026",
397
+ errorItems: "Tidak dapat memuat item tersimpan.",
398
+ search: "Cari item tersimpan",
399
+ sort: "Urutkan item tersimpan",
400
+ newest: "Terbaru dahulu",
401
+ oldest: "Terlama dahulu",
402
+ savedNewest: "Paling baru disimpan dahulu",
403
+ savedOldest: "Paling lama disimpan dahulu",
404
+ updatedNewest: "Paling baru diperbarui dahulu",
405
+ updatedOldest: "Paling lama diperbarui dahulu",
406
+ previousPage: "Halaman sebelumnya",
407
+ nextPage: "Halaman berikutnya",
408
+ pagination: "Paginasi",
409
+ page: "Halaman",
410
+ selectItems: "Pilih item tersimpan",
411
+ selectedCount: "dipilih",
412
+ deleteSelected: "Hapus yang dipilih",
413
+ tagsToApply: "Tag yang akan diterapkan",
414
+ applyTags: "Terapkan tag",
415
+ savedMessage: "Item tersimpan.",
416
+ removedMessage: "Item dihapus.",
417
+ undo: "Urungkan",
418
+ undoAvailable: "Item dihapus. Urungkan?",
419
+ selectionScope: "Cakupan pilihan",
420
+ currentPage: "Halaman saat ini",
421
+ searchResults: "Hasil pencarian saat ini",
422
+ allItems: "Semua item tersimpan",
423
+ statusAvailable: "Tersedia",
424
+ noteSavedMessage: "Catatan tersimpan.",
425
+ exportData: "Ekspor JSON",
426
+ importData: "Impor JSON",
427
+ importMode: "Mode impor",
428
+ merge: "Gabungkan",
429
+ replace: "Ganti",
430
+ importedCount: "item diimpor",
431
+ failedCount: "item gagal",
432
+ storageQuotaError: "Penyimpanan penuh. Kosongkan ruang lalu coba lagi.",
433
+ statusExpired: "Kedaluwarsa",
434
+ statusRemoved: "Dihapus",
435
+ statusDeleted: "Terhapus",
436
+ statusPrivate: "Pribadi",
437
+ statusUnknown: "Tidak tersedia",
438
+ retry: "Coba lagi",
439
+ removeFromList: "Hapus dari daftar",
440
+ pruneStale: "Hapus item yang tidak tersedia",
441
+ retrySync: "Coba sinkronisasi lagi",
442
+ resolveSync: "Selesaikan konflik",
443
+ keepLocal: "Pertahankan versi lokal",
444
+ useServer: "Gunakan versi server",
445
+ manualMerge: "Gabungkan manual",
446
+ close: "Tutup",
447
+ backupRecovery: "Pulihkan dari cadangan",
448
+ backupRecoveryDescription: "Jika data sinkronisasi lokal rusak, pulihkan cadangan JSON yang valid.",
449
+ syncPending: "Ada perubahan yang menunggu sinkronisasi.",
450
+ syncSynced: "Semua perubahan telah disinkronkan.",
451
+ syncConflict: "Beberapa perubahan memerlukan penyelesaian konflik."
452
+ };
453
+
454
+ // src/locales/it.ts
455
+ var IT_LABELS = {
456
+ save: "Salva",
457
+ saved: "Salvato",
458
+ remove: "Rimuovi",
459
+ loading: "Caricamento\u2026",
460
+ saving: "Salvataggio\u2026",
461
+ syncing: "Sincronizzazione\u2026",
462
+ error: "Si \xE8 verificato un errore.",
463
+ allTags: "Tutti",
464
+ tags: "Tag",
465
+ filterTags: "Filtra gli elementi salvati per tag",
466
+ note: "Nota",
467
+ saveNote: "Salva nota",
468
+ noItems: "Nessun elemento salvato.",
469
+ loadingItems: "Caricamento degli elementi salvati\u2026",
470
+ errorItems: "Impossibile caricare gli elementi salvati.",
471
+ search: "Cerca elementi salvati",
472
+ sort: "Ordina elementi salvati",
473
+ newest: "Pi\xF9 recenti prima",
474
+ oldest: "Pi\xF9 vecchi prima",
475
+ savedNewest: "Salvati pi\xF9 di recente prima",
476
+ savedOldest: "Salvati meno di recente prima",
477
+ updatedNewest: "Aggiornati pi\xF9 di recente prima",
478
+ updatedOldest: "Aggiornati meno di recente prima",
479
+ previousPage: "Pagina precedente",
480
+ nextPage: "Pagina successiva",
481
+ pagination: "Paginazione",
482
+ page: "Pagina",
483
+ selectItems: "Seleziona elementi salvati",
484
+ selectedCount: "selezionati",
485
+ deleteSelected: "Elimina selezionati",
486
+ tagsToApply: "Tag da applicare",
487
+ applyTags: "Applica tag",
488
+ savedMessage: "Elemento salvato.",
489
+ removedMessage: "Elemento rimosso.",
490
+ undo: "Annulla",
491
+ undoAvailable: "Elemento rimosso. Annullare?",
492
+ selectionScope: "Ambito della selezione",
493
+ currentPage: "Pagina corrente",
494
+ searchResults: "Risultati di ricerca correnti",
495
+ allItems: "Tutti gli elementi salvati",
496
+ statusAvailable: "Disponibile",
497
+ noteSavedMessage: "Nota salvata.",
498
+ exportData: "Esporta JSON",
499
+ importData: "Importa JSON",
500
+ importMode: "Modalit\xE0 di importazione",
501
+ merge: "Unisci",
502
+ replace: "Sostituisci",
503
+ importedCount: "elementi importati",
504
+ failedCount: "elementi non riusciti",
505
+ storageQuotaError: "Lo spazio di archiviazione \xE8 pieno. Libera spazio e riprova.",
506
+ statusExpired: "Scaduto",
507
+ statusRemoved: "Rimosso",
508
+ statusDeleted: "Eliminato",
509
+ statusPrivate: "Privato",
510
+ statusUnknown: "Non disponibile",
511
+ retry: "Riprova",
512
+ removeFromList: "Rimuovi dall'elenco",
513
+ pruneStale: "Rimuovi elementi non disponibili",
514
+ retrySync: "Riprova sincronizzazione",
515
+ resolveSync: "Risolvi conflitti",
516
+ keepLocal: "Mantieni versione locale",
517
+ useServer: "Usa versione del server",
518
+ manualMerge: "Unione manuale",
519
+ close: "Chiudi",
520
+ backupRecovery: "Ripristina dal backup",
521
+ backupRecoveryDescription: "Se i dati locali sono danneggiati, ripristina un backup JSON valido.",
522
+ syncPending: "Ci sono modifiche in attesa di sincronizzazione.",
523
+ syncSynced: "Tutte le modifiche sono sincronizzate.",
524
+ syncConflict: "Alcune modifiche richiedono la risoluzione di un conflitto."
525
+ };
526
+
527
+ // src/locales/ja.ts
528
+ var JA_LABELS = {
529
+ save: "\u4FDD\u5B58",
530
+ saved: "\u4FDD\u5B58\u6E08\u307F",
531
+ remove: "\u524A\u9664",
532
+ loading: "\u8AAD\u307F\u8FBC\u307F\u4E2D\u2026",
533
+ saving: "\u4FDD\u5B58\u4E2D\u2026",
534
+ syncing: "\u540C\u671F\u4E2D\u2026",
535
+ error: "\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002",
536
+ allTags: "\u3059\u3079\u3066",
537
+ tags: "\u30BF\u30B0",
538
+ filterTags: "\u4FDD\u5B58\u30A2\u30A4\u30C6\u30E0\u3092\u30BF\u30B0\u3067\u7D5E\u308A\u8FBC\u3080",
539
+ note: "\u30E1\u30E2",
540
+ saveNote: "\u30E1\u30E2\u3092\u4FDD\u5B58",
541
+ noItems: "\u4FDD\u5B58\u3055\u308C\u305F\u30A2\u30A4\u30C6\u30E0\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
542
+ loadingItems: "\u4FDD\u5B58\u30A2\u30A4\u30C6\u30E0\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D\u2026",
543
+ errorItems: "\u4FDD\u5B58\u30A2\u30A4\u30C6\u30E0\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093\u3067\u3057\u305F\u3002",
544
+ search: "\u4FDD\u5B58\u30A2\u30A4\u30C6\u30E0\u3092\u691C\u7D22",
545
+ sort: "\u4FDD\u5B58\u30A2\u30A4\u30C6\u30E0\u3092\u4E26\u3079\u66FF\u3048",
546
+ newest: "\u65B0\u3057\u3044\u9806",
547
+ oldest: "\u53E4\u3044\u9806",
548
+ savedNewest: "\u4FDD\u5B58\u65E5\u6642\u306E\u65B0\u3057\u3044\u9806",
549
+ savedOldest: "\u4FDD\u5B58\u65E5\u6642\u306E\u53E4\u3044\u9806",
550
+ updatedNewest: "\u66F4\u65B0\u65E5\u6642\u306E\u65B0\u3057\u3044\u9806",
551
+ updatedOldest: "\u66F4\u65B0\u65E5\u6642\u306E\u53E4\u3044\u9806",
552
+ previousPage: "\u524D\u306E\u30DA\u30FC\u30B8",
553
+ nextPage: "\u6B21\u306E\u30DA\u30FC\u30B8",
554
+ pagination: "\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3",
555
+ page: "\u30DA\u30FC\u30B8",
556
+ selectItems: "\u4FDD\u5B58\u30A2\u30A4\u30C6\u30E0\u3092\u9078\u629E",
557
+ selectedCount: "\u4EF6\u3092\u9078\u629E\u4E2D",
558
+ deleteSelected: "\u9078\u629E\u9805\u76EE\u3092\u524A\u9664",
559
+ tagsToApply: "\u9069\u7528\u3059\u308B\u30BF\u30B0",
560
+ applyTags: "\u30BF\u30B0\u3092\u9069\u7528",
561
+ savedMessage: "\u30A2\u30A4\u30C6\u30E0\u3092\u4FDD\u5B58\u3057\u307E\u3057\u305F\u3002",
562
+ removedMessage: "\u30A2\u30A4\u30C6\u30E0\u3092\u524A\u9664\u3057\u307E\u3057\u305F\u3002",
563
+ undo: "\u5143\u306B\u623B\u3059",
564
+ undoAvailable: "\u30A2\u30A4\u30C6\u30E0\u3092\u524A\u9664\u3057\u307E\u3057\u305F\u3002\u5143\u306B\u623B\u3057\u307E\u3059\u304B\uFF1F",
565
+ selectionScope: "\u9078\u629E\u7BC4\u56F2",
566
+ currentPage: "\u8868\u793A\u4E2D\u306E\u30DA\u30FC\u30B8",
567
+ searchResults: "\u73FE\u5728\u306E\u691C\u7D22\u7D50\u679C\u5168\u4F53",
568
+ allItems: "\u3059\u3079\u3066\u306E\u4FDD\u5B58\u30A2\u30A4\u30C6\u30E0",
569
+ statusAvailable: "\u5229\u7528\u53EF\u80FD",
570
+ noteSavedMessage: "\u30E1\u30E2\u3092\u4FDD\u5B58\u3057\u307E\u3057\u305F\u3002",
571
+ exportData: "JSON\u3092\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8",
572
+ importData: "JSON\u3092\u30A4\u30F3\u30DD\u30FC\u30C8",
573
+ importMode: "\u30A4\u30F3\u30DD\u30FC\u30C8\u65B9\u6CD5",
574
+ merge: "\u7D71\u5408",
575
+ replace: "\u7F6E\u304D\u63DB\u3048",
576
+ importedCount: "\u4EF6\u3092\u30A4\u30F3\u30DD\u30FC\u30C8\u3057\u307E\u3057\u305F",
577
+ failedCount: "\u4EF6\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
578
+ storageQuotaError: "\u4FDD\u5B58\u5BB9\u91CF\u304C\u4E0D\u8DB3\u3057\u3066\u3044\u307E\u3059\u3002\u7A7A\u304D\u5BB9\u91CF\u3092\u78BA\u4FDD\u3057\u3066\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
579
+ statusExpired: "\u671F\u9650\u5207\u308C",
580
+ statusRemoved: "\u524A\u9664\u6E08\u307F",
581
+ statusDeleted: "\u524A\u9664\u6E08\u307F",
582
+ statusPrivate: "\u975E\u516C\u958B",
583
+ statusUnknown: "\u5229\u7528\u4E0D\u53EF",
584
+ retry: "\u518D\u53D6\u5F97",
585
+ removeFromList: "\u4E00\u89A7\u304B\u3089\u524A\u9664",
586
+ pruneStale: "\u5229\u7528\u3067\u304D\u306A\u3044\u9805\u76EE\u3092\u524A\u9664",
587
+ retrySync: "\u540C\u671F\u3092\u518D\u8A66\u884C",
588
+ resolveSync: "\u7AF6\u5408\u3092\u89E3\u6C7A",
589
+ keepLocal: "\u30ED\u30FC\u30AB\u30EB\u3092\u512A\u5148",
590
+ useServer: "\u30B5\u30FC\u30D0\u30FC\u3092\u512A\u5148",
591
+ manualMerge: "\u624B\u52D5\u3067\u7D71\u5408",
592
+ close: "\u9589\u3058\u308B",
593
+ backupRecovery: "\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u304B\u3089\u5FA9\u5143",
594
+ backupRecoveryDescription: "\u30ED\u30FC\u30AB\u30EB\u306E\u540C\u671F\u30C7\u30FC\u30BF\u304C\u7834\u640D\u3057\u305F\u5834\u5408\u306F\u3001\u6B63\u5E38\u306AJSON\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u304B\u3089\u5FA9\u5143\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
595
+ syncPending: "\u540C\u671F\u5F85\u3061\u306E\u5909\u66F4\u304C\u3042\u308A\u307E\u3059\u3002",
596
+ syncSynced: "\u3059\u3079\u3066\u306E\u5909\u66F4\u3092\u540C\u671F\u3057\u307E\u3057\u305F\u3002",
597
+ syncConflict: "\u7AF6\u5408\u3057\u3066\u3044\u308B\u5909\u66F4\u304C\u3042\u308A\u307E\u3059\u3002\u89E3\u6C7A\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
598
+ };
599
+
600
+ // src/locales/ko.ts
601
+ var KO_LABELS = {
602
+ save: "\uC800\uC7A5",
603
+ saved: "\uC800\uC7A5\uB428",
604
+ remove: "\uC0AD\uC81C",
605
+ loading: "\uB85C\uB4DC \uC911\u2026",
606
+ saving: "\uC800\uC7A5 \uC911\u2026",
607
+ syncing: "\uB3D9\uAE30\uD654 \uC911\u2026",
608
+ error: "\uBB38\uC81C\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.",
609
+ allTags: "\uBAA8\uB450",
610
+ tags: "\uD0DC\uADF8",
611
+ filterTags: "\uD0DC\uADF8\uB85C \uC800\uC7A5 \uD56D\uBAA9 \uD544\uD130\uB9C1",
612
+ note: "\uBA54\uBAA8",
613
+ saveNote: "\uBA54\uBAA8 \uC800\uC7A5",
614
+ noItems: "\uC800\uC7A5\uB41C \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.",
615
+ loadingItems: "\uC800\uC7A5 \uD56D\uBAA9\uC744 \uBD88\uB7EC\uC624\uB294 \uC911\u2026",
616
+ errorItems: "\uC800\uC7A5 \uD56D\uBAA9\uC744 \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
617
+ search: "\uC800\uC7A5 \uD56D\uBAA9 \uAC80\uC0C9",
618
+ sort: "\uC800\uC7A5 \uD56D\uBAA9 \uC815\uB82C",
619
+ newest: "\uCD5C\uC2E0\uC21C",
620
+ oldest: "\uC624\uB798\uB41C\uC21C",
621
+ savedNewest: "\uC800\uC7A5\uC77C \uCD5C\uC2E0\uC21C",
622
+ savedOldest: "\uC800\uC7A5\uC77C \uC624\uB798\uB41C\uC21C",
623
+ updatedNewest: "\uC218\uC815\uC77C \uCD5C\uC2E0\uC21C",
624
+ updatedOldest: "\uC218\uC815\uC77C \uC624\uB798\uB41C\uC21C",
625
+ previousPage: "\uC774\uC804 \uD398\uC774\uC9C0",
626
+ nextPage: "\uB2E4\uC74C \uD398\uC774\uC9C0",
627
+ pagination: "\uD398\uC774\uC9C0 \uB9E4\uAE40",
628
+ page: "\uD398\uC774\uC9C0",
629
+ selectItems: "\uC800\uC7A5 \uD56D\uBAA9 \uC120\uD0DD",
630
+ selectedCount: "\uAC1C \uC120\uD0DD\uB428",
631
+ deleteSelected: "\uC120\uD0DD \uD56D\uBAA9 \uC0AD\uC81C",
632
+ tagsToApply: "\uC801\uC6A9\uD560 \uD0DC\uADF8",
633
+ applyTags: "\uD0DC\uADF8 \uC801\uC6A9",
634
+ savedMessage: "\uD56D\uBAA9\uC744 \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4.",
635
+ removedMessage: "\uD56D\uBAA9\uC744 \uC0AD\uC81C\uD588\uC2B5\uB2C8\uB2E4.",
636
+ undo: "\uC2E4\uD589 \uCDE8\uC18C",
637
+ undoAvailable: "\uD56D\uBAA9\uC744 \uC0AD\uC81C\uD588\uC2B5\uB2C8\uB2E4. \uC2E4\uD589 \uCDE8\uC18C\uD560\uAE4C\uC694?",
638
+ selectionScope: "\uC120\uD0DD \uBC94\uC704",
639
+ currentPage: "\uD604\uC7AC \uD398\uC774\uC9C0",
640
+ searchResults: "\uD604\uC7AC \uAC80\uC0C9 \uACB0\uACFC \uC804\uCCB4",
641
+ allItems: "\uBAA8\uB4E0 \uC800\uC7A5 \uD56D\uBAA9",
642
+ statusAvailable: "\uC0AC\uC6A9 \uAC00\uB2A5",
643
+ noteSavedMessage: "\uBA54\uBAA8\uB97C \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4.",
644
+ exportData: "JSON \uB0B4\uBCF4\uB0B4\uAE30",
645
+ importData: "JSON \uAC00\uC838\uC624\uAE30",
646
+ importMode: "\uAC00\uC838\uC624\uAE30 \uBC29\uC2DD",
647
+ merge: "\uBCD1\uD569",
648
+ replace: "\uAD50\uCCB4",
649
+ importedCount: "\uAC1C \uAC00\uC838\uC634",
650
+ failedCount: "\uAC1C \uC2E4\uD328",
651
+ storageQuotaError: "\uC800\uC7A5 \uACF5\uAC04\uC774 \uBD80\uC871\uD569\uB2C8\uB2E4. \uACF5\uAC04\uC744 \uD655\uBCF4\uD55C \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.",
652
+ statusExpired: "\uB9CC\uB8CC\uB428",
653
+ statusRemoved: "\uC81C\uAC70\uB428",
654
+ statusDeleted: "\uC0AD\uC81C\uB428",
655
+ statusPrivate: "\uBE44\uACF5\uAC1C",
656
+ statusUnknown: "\uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC74C",
657
+ retry: "\uB2E4\uC2DC \uC2DC\uB3C4",
658
+ removeFromList: "\uBAA9\uB85D\uC5D0\uC11C \uC0AD\uC81C",
659
+ pruneStale: "\uC0AC\uC6A9\uD560 \uC218 \uC5C6\uB294 \uD56D\uBAA9 \uC0AD\uC81C",
660
+ retrySync: "\uB3D9\uAE30\uD654 \uB2E4\uC2DC \uC2DC\uB3C4",
661
+ resolveSync: "\uCDA9\uB3CC \uD574\uACB0",
662
+ keepLocal: "\uB85C\uCEEC \uBC84\uC804 \uC720\uC9C0",
663
+ useServer: "\uC11C\uBC84 \uBC84\uC804 \uC0AC\uC6A9",
664
+ manualMerge: "\uC218\uB3D9 \uBCD1\uD569",
665
+ close: "\uB2EB\uAE30",
666
+ backupRecovery: "\uBC31\uC5C5\uC5D0\uC11C \uBCF5\uC6D0",
667
+ backupRecoveryDescription: "\uB85C\uCEEC \uB3D9\uAE30\uD654 \uB370\uC774\uD130\uAC00 \uC190\uC0C1\uB41C \uACBD\uC6B0 \uC815\uC0C1\uC801\uC778 JSON \uBC31\uC5C5\uC744 \uBCF5\uC6D0\uD558\uC138\uC694.",
668
+ syncPending: "\uB3D9\uAE30\uD654 \uB300\uAE30 \uC911\uC778 \uBCC0\uACBD \uC0AC\uD56D\uC774 \uC788\uC2B5\uB2C8\uB2E4.",
669
+ syncSynced: "\uBAA8\uB4E0 \uBCC0\uACBD \uC0AC\uD56D\uC774 \uB3D9\uAE30\uD654\uB418\uC5C8\uC2B5\uB2C8\uB2E4.",
670
+ syncConflict: "\uCDA9\uB3CC\uC744 \uD574\uACB0\uD574\uC57C \uD558\uB294 \uBCC0\uACBD \uC0AC\uD56D\uC774 \uC788\uC2B5\uB2C8\uB2E4."
671
+ };
672
+
673
+ // src/locales/ms.ts
674
+ var MS_LABELS = {
675
+ save: "Simpan",
676
+ saved: "Disimpan",
677
+ remove: "Buang",
678
+ loading: "Memuatkan\u2026",
679
+ saving: "Menyimpan\u2026",
680
+ syncing: "Menyegerakkan\u2026",
681
+ error: "Ralat telah berlaku.",
682
+ allTags: "Semua",
683
+ tags: "Tag",
684
+ filterTags: "Tapis item yang disimpan mengikut tag",
685
+ note: "Nota",
686
+ saveNote: "Simpan nota",
687
+ noItems: "Tiada item disimpan.",
688
+ loadingItems: "Memuatkan item yang disimpan\u2026",
689
+ errorItems: "Tidak dapat memuatkan item yang disimpan.",
690
+ search: "Cari item yang disimpan",
691
+ sort: "Isih item yang disimpan",
692
+ newest: "Terbaharu dahulu",
693
+ oldest: "Terlama dahulu",
694
+ savedNewest: "Disimpan paling baharu dahulu",
695
+ savedOldest: "Disimpan paling lama dahulu",
696
+ updatedNewest: "Dikemas kini paling baharu dahulu",
697
+ updatedOldest: "Dikemas kini paling lama dahulu",
698
+ previousPage: "Halaman sebelumnya",
699
+ nextPage: "Halaman seterusnya",
700
+ pagination: "Penomboran halaman",
701
+ page: "Halaman",
702
+ selectItems: "Pilih item yang disimpan",
703
+ selectedCount: "dipilih",
704
+ deleteSelected: "Padam pilihan",
705
+ tagsToApply: "Tag untuk digunakan",
706
+ applyTags: "Gunakan tag",
707
+ savedMessage: "Item disimpan.",
708
+ removedMessage: "Item dibuang.",
709
+ undo: "Buat asal",
710
+ undoAvailable: "Item dibuang. Buat asal?",
711
+ selectionScope: "Skop pilihan",
712
+ currentPage: "Halaman semasa",
713
+ searchResults: "Hasil carian semasa",
714
+ allItems: "Semua item yang disimpan",
715
+ statusAvailable: "Tersedia",
716
+ noteSavedMessage: "Nota disimpan.",
717
+ exportData: "Eksport JSON",
718
+ importData: "Import JSON",
719
+ importMode: "Mod import",
720
+ merge: "Gabung",
721
+ replace: "Ganti",
722
+ importedCount: "item diimport",
723
+ failedCount: "item gagal",
724
+ storageQuotaError: "Storan penuh. Kosongkan ruang dan cuba lagi.",
725
+ statusExpired: "Tamat tempoh",
726
+ statusRemoved: "Dibuang",
727
+ statusDeleted: "Dipadam",
728
+ statusPrivate: "Peribadi",
729
+ statusUnknown: "Tidak tersedia",
730
+ retry: "Cuba lagi",
731
+ removeFromList: "Buang daripada senarai",
732
+ pruneStale: "Buang item yang tidak tersedia",
733
+ retrySync: "Cuba penyegerakan lagi",
734
+ resolveSync: "Selesaikan konflik",
735
+ keepLocal: "Kekalkan versi setempat",
736
+ useServer: "Gunakan versi pelayan",
737
+ manualMerge: "Gabung secara manual",
738
+ close: "Tutup",
739
+ backupRecovery: "Pulihkan daripada sandaran",
740
+ backupRecoveryDescription: "Jika data penyegerakan setempat rosak, pulihkan sandaran JSON yang sah.",
741
+ syncPending: "Terdapat perubahan yang menunggu penyegerakan.",
742
+ syncSynced: "Semua perubahan telah disegerakkan.",
743
+ syncConflict: "Sesetengah perubahan memerlukan penyelesaian konflik."
64
744
  };
745
+
746
+ // src/locales/pt-BR.ts
747
+ var PT_BR_LABELS = {
748
+ save: "Salvar",
749
+ saved: "Salvo",
750
+ remove: "Remover",
751
+ loading: "Carregando\u2026",
752
+ saving: "Salvando\u2026",
753
+ syncing: "Sincronizando\u2026",
754
+ error: "Ocorreu um erro.",
755
+ allTags: "Todos",
756
+ tags: "Tags",
757
+ filterTags: "Filtrar itens salvos por tag",
758
+ note: "Nota",
759
+ saveNote: "Salvar nota",
760
+ noItems: "Nenhum item salvo.",
761
+ loadingItems: "Carregando itens salvos\u2026",
762
+ errorItems: "N\xE3o foi poss\xEDvel carregar os itens salvos.",
763
+ search: "Pesquisar itens salvos",
764
+ sort: "Ordenar itens salvos",
765
+ newest: "Mais recentes primeiro",
766
+ oldest: "Mais antigos primeiro",
767
+ savedNewest: "Salvos mais recentemente primeiro",
768
+ savedOldest: "Salvos h\xE1 mais tempo primeiro",
769
+ updatedNewest: "Atualizados mais recentemente primeiro",
770
+ updatedOldest: "Atualizados h\xE1 mais tempo primeiro",
771
+ previousPage: "P\xE1gina anterior",
772
+ nextPage: "Pr\xF3xima p\xE1gina",
773
+ pagination: "Pagina\xE7\xE3o",
774
+ page: "P\xE1gina",
775
+ selectItems: "Selecionar itens salvos",
776
+ selectedCount: "selecionados",
777
+ deleteSelected: "Excluir selecionados",
778
+ tagsToApply: "Tags a aplicar",
779
+ applyTags: "Aplicar tags",
780
+ savedMessage: "Item salvo.",
781
+ removedMessage: "Item removido.",
782
+ undo: "Desfazer",
783
+ undoAvailable: "Item removido. Desfazer?",
784
+ selectionScope: "Escopo da sele\xE7\xE3o",
785
+ currentPage: "P\xE1gina atual",
786
+ searchResults: "Resultados da pesquisa atual",
787
+ allItems: "Todos os itens salvos",
788
+ statusAvailable: "Dispon\xEDvel",
789
+ noteSavedMessage: "Nota salva.",
790
+ exportData: "Exportar JSON",
791
+ importData: "Importar JSON",
792
+ importMode: "Modo de importa\xE7\xE3o",
793
+ merge: "Mesclar",
794
+ replace: "Substituir",
795
+ importedCount: "itens importados",
796
+ failedCount: "itens com falha",
797
+ storageQuotaError: "O armazenamento est\xE1 cheio. Libere espa\xE7o e tente novamente.",
798
+ statusExpired: "Expirado",
799
+ statusRemoved: "Removido",
800
+ statusDeleted: "Exclu\xEDdo",
801
+ statusPrivate: "Privado",
802
+ statusUnknown: "Indispon\xEDvel",
803
+ retry: "Tentar novamente",
804
+ removeFromList: "Remover da lista",
805
+ pruneStale: "Remover itens indispon\xEDveis",
806
+ retrySync: "Tentar sincronizar novamente",
807
+ resolveSync: "Resolver conflitos",
808
+ keepLocal: "Manter vers\xE3o local",
809
+ useServer: "Usar vers\xE3o do servidor",
810
+ manualMerge: "Mesclagem manual",
811
+ close: "Fechar",
812
+ backupRecovery: "Restaurar do backup",
813
+ backupRecoveryDescription: "Se os dados locais estiverem corrompidos, restaure um backup JSON v\xE1lido.",
814
+ syncPending: "H\xE1 altera\xE7\xF5es aguardando sincroniza\xE7\xE3o.",
815
+ syncSynced: "Todas as altera\xE7\xF5es foram sincronizadas.",
816
+ syncConflict: "Algumas altera\xE7\xF5es precisam de resolu\xE7\xE3o de conflito."
817
+ };
818
+
819
+ // src/locales/ru.ts
820
+ var RU_LABELS = {
821
+ save: "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C",
822
+ saved: "\u0421\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u043E",
823
+ remove: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C",
824
+ loading: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430\u2026",
825
+ saving: "\u0421\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u0435\u2026",
826
+ syncing: "\u0421\u0438\u043D\u0445\u0440\u043E\u043D\u0438\u0437\u0430\u0446\u0438\u044F\u2026",
827
+ error: "\u041F\u0440\u043E\u0438\u0437\u043E\u0448\u043B\u0430 \u043E\u0448\u0438\u0431\u043A\u0430.",
828
+ allTags: "\u0412\u0441\u0435",
829
+ tags: "\u0422\u0435\u0433\u0438",
830
+ filterTags: "\u0424\u0438\u043B\u044C\u0442\u0440\u043E\u0432\u0430\u0442\u044C \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B \u043F\u043E \u0442\u0435\u0433\u0443",
831
+ note: "\u0417\u0430\u043C\u0435\u0442\u043A\u0430",
832
+ saveNote: "\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C \u0437\u0430\u043C\u0435\u0442\u043A\u0443",
833
+ noItems: "\u041D\u0435\u0442 \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0445 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432.",
834
+ loadingItems: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0445 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432\u2026",
835
+ errorItems: "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B.",
836
+ search: "\u041F\u043E\u0438\u0441\u043A \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0445 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432",
837
+ sort: "\u0421\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430 \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0445 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432",
838
+ newest: "\u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u043D\u043E\u0432\u044B\u0435",
839
+ oldest: "\u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u0441\u0442\u0430\u0440\u044B\u0435",
840
+ savedNewest: "\u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u043D\u0435\u0434\u0430\u0432\u043D\u043E \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0435",
841
+ savedOldest: "\u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u0434\u0430\u0432\u043D\u043E \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0435",
842
+ updatedNewest: "\u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u043D\u0435\u0434\u0430\u0432\u043D\u043E \u043E\u0431\u043D\u043E\u0432\u043B\u0451\u043D\u043D\u044B\u0435",
843
+ updatedOldest: "\u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u0434\u0430\u0432\u043D\u043E \u043E\u0431\u043D\u043E\u0432\u043B\u0451\u043D\u043D\u044B\u0435",
844
+ previousPage: "\u041F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0430\u044F \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430",
845
+ nextPage: "\u0421\u043B\u0435\u0434\u0443\u044E\u0449\u0430\u044F \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430",
846
+ pagination: "\u041F\u0430\u0433\u0438\u043D\u0430\u0446\u0438\u044F",
847
+ page: "\u0421\u0442\u0440\u0430\u043D\u0438\u0446\u0430",
848
+ selectItems: "\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B",
849
+ selectedCount: "\u0432\u044B\u0431\u0440\u0430\u043D\u043E",
850
+ deleteSelected: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0435",
851
+ tagsToApply: "\u0422\u0435\u0433\u0438 \u0434\u043B\u044F \u043F\u0440\u0438\u043C\u0435\u043D\u0435\u043D\u0438\u044F",
852
+ applyTags: "\u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C \u0442\u0435\u0433\u0438",
853
+ savedMessage: "\u042D\u043B\u0435\u043C\u0435\u043D\u0442 \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D.",
854
+ removedMessage: "\u042D\u043B\u0435\u043C\u0435\u043D\u0442 \u0443\u0434\u0430\u043B\u0451\u043D.",
855
+ undo: "\u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C",
856
+ undoAvailable: "\u042D\u043B\u0435\u043C\u0435\u043D\u0442 \u0443\u0434\u0430\u043B\u0451\u043D. \u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C?",
857
+ selectionScope: "\u041E\u0431\u043B\u0430\u0441\u0442\u044C \u0432\u044B\u0431\u043E\u0440\u0430",
858
+ currentPage: "\u0422\u0435\u043A\u0443\u0449\u0430\u044F \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430",
859
+ searchResults: "\u0422\u0435\u043A\u0443\u0449\u0438\u0435 \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B \u043F\u043E\u0438\u0441\u043A\u0430",
860
+ allItems: "\u0412\u0441\u0435 \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B",
861
+ statusAvailable: "\u0414\u043E\u0441\u0442\u0443\u043F\u0435\u043D",
862
+ noteSavedMessage: "\u0417\u0430\u043C\u0435\u0442\u043A\u0430 \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0430.",
863
+ exportData: "\u042D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C JSON",
864
+ importData: "\u0418\u043C\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C JSON",
865
+ importMode: "\u0420\u0435\u0436\u0438\u043C \u0438\u043C\u043F\u043E\u0440\u0442\u0430",
866
+ merge: "\u041E\u0431\u044A\u0435\u0434\u0438\u043D\u0438\u0442\u044C",
867
+ replace: "\u0417\u0430\u043C\u0435\u043D\u0438\u0442\u044C",
868
+ importedCount: "\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432 \u0438\u043C\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u043E",
869
+ failedCount: "\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432 \u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0438\u043C\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
870
+ storageQuotaError: "\u0425\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435 \u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u043E. \u041E\u0441\u0432\u043E\u0431\u043E\u0434\u0438\u0442\u0435 \u043C\u0435\u0441\u0442\u043E \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 \u043F\u043E\u043F\u044B\u0442\u043A\u0443.",
871
+ statusExpired: "\u0418\u0441\u0442\u0451\u043A \u0441\u0440\u043E\u043A",
872
+ statusRemoved: "\u0423\u0434\u0430\u043B\u0451\u043D",
873
+ statusDeleted: "\u0423\u0434\u0430\u043B\u0451\u043D \u043D\u0430\u0432\u0441\u0435\u0433\u0434\u0430",
874
+ statusPrivate: "\u041F\u0440\u0438\u0432\u0430\u0442\u043D\u044B\u0439",
875
+ statusUnknown: "\u041D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D",
876
+ retry: "\u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u044C",
877
+ removeFromList: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0438\u0437 \u0441\u043F\u0438\u0441\u043A\u0430",
878
+ pruneStale: "\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B",
879
+ retrySync: "\u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u044C \u0441\u0438\u043D\u0445\u0440\u043E\u043D\u0438\u0437\u0430\u0446\u0438\u044E",
880
+ resolveSync: "\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044C \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u044B",
881
+ keepLocal: "\u041E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u0443\u044E \u0432\u0435\u0440\u0441\u0438\u044E",
882
+ useServer: "\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0432\u0435\u0440\u0441\u0438\u044E \u0441\u0435\u0440\u0432\u0435\u0440\u0430",
883
+ manualMerge: "\u041E\u0431\u044A\u0435\u0434\u0438\u043D\u0438\u0442\u044C \u0432\u0440\u0443\u0447\u043D\u0443\u044E",
884
+ close: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C",
885
+ backupRecovery: "\u0412\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u0438\u0437 \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u043E\u0439 \u043A\u043E\u043F\u0438\u0438",
886
+ backupRecoveryDescription: "\u0415\u0441\u043B\u0438 \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u044B\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 \u0441\u0438\u043D\u0445\u0440\u043E\u043D\u0438\u0437\u0430\u0446\u0438\u0438 \u043F\u043E\u0432\u0440\u0435\u0436\u0434\u0435\u043D\u044B, \u0432\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0435 \u0440\u0430\u0431\u043E\u0447\u0443\u044E JSON-\u043A\u043E\u043F\u0438\u044E.",
887
+ syncPending: "\u0415\u0441\u0442\u044C \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F, \u043E\u0436\u0438\u0434\u0430\u044E\u0449\u0438\u0435 \u0441\u0438\u043D\u0445\u0440\u043E\u043D\u0438\u0437\u0430\u0446\u0438\u0438.",
888
+ syncSynced: "\u0412\u0441\u0435 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0441\u0438\u043D\u0445\u0440\u043E\u043D\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u044B.",
889
+ syncConflict: "\u041D\u0435\u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0442\u0440\u0435\u0431\u0443\u044E\u0442 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u0438\u044F \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u0430."
890
+ };
891
+
892
+ // src/locales/th.ts
893
+ var TH_LABELS = {
894
+ save: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01",
895
+ saved: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E41\u0E25\u0E49\u0E27",
896
+ remove: "\u0E25\u0E1A",
897
+ loading: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E42\u0E2B\u0E25\u0E14\u2026",
898
+ saving: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u2026",
899
+ syncing: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E0B\u0E34\u0E07\u0E04\u0E4C\u2026",
900
+ error: "\u0E40\u0E01\u0E34\u0E14\u0E02\u0E49\u0E2D\u0E1C\u0E34\u0E14\u0E1E\u0E25\u0E32\u0E14",
901
+ allTags: "\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14",
902
+ tags: "\u0E41\u0E17\u0E47\u0E01",
903
+ filterTags: "\u0E01\u0E23\u0E2D\u0E07\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E14\u0E49\u0E27\u0E22\u0E41\u0E17\u0E47\u0E01",
904
+ note: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E22\u0E48\u0E2D",
905
+ saveNote: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E22\u0E48\u0E2D",
906
+ noItems: "\u0E44\u0E21\u0E48\u0E21\u0E35\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E44\u0E27\u0E49",
907
+ loadingItems: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E42\u0E2B\u0E25\u0E14\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u2026",
908
+ errorItems: "\u0E42\u0E2B\u0E25\u0E14\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49",
909
+ search: "\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01",
910
+ sort: "\u0E40\u0E23\u0E35\u0E22\u0E07\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01",
911
+ newest: "\u0E43\u0E2B\u0E21\u0E48\u0E2A\u0E38\u0E14\u0E01\u0E48\u0E2D\u0E19",
912
+ oldest: "\u0E40\u0E01\u0E48\u0E32\u0E2A\u0E38\u0E14\u0E01\u0E48\u0E2D\u0E19",
913
+ savedNewest: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E43\u0E2B\u0E21\u0E48\u0E2A\u0E38\u0E14\u0E01\u0E48\u0E2D\u0E19",
914
+ savedOldest: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E40\u0E01\u0E48\u0E32\u0E2A\u0E38\u0E14\u0E01\u0E48\u0E2D\u0E19",
915
+ updatedNewest: "\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15\u0E43\u0E2B\u0E21\u0E48\u0E2A\u0E38\u0E14\u0E01\u0E48\u0E2D\u0E19",
916
+ updatedOldest: "\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15\u0E40\u0E01\u0E48\u0E32\u0E2A\u0E38\u0E14\u0E01\u0E48\u0E2D\u0E19",
917
+ previousPage: "\u0E2B\u0E19\u0E49\u0E32\u0E01\u0E48\u0E2D\u0E19\u0E2B\u0E19\u0E49\u0E32",
918
+ nextPage: "\u0E2B\u0E19\u0E49\u0E32\u0E16\u0E31\u0E14\u0E44\u0E1B",
919
+ pagination: "\u0E01\u0E32\u0E23\u0E41\u0E1A\u0E48\u0E07\u0E2B\u0E19\u0E49\u0E32",
920
+ page: "\u0E2B\u0E19\u0E49\u0E32",
921
+ selectItems: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01",
922
+ selectedCount: "\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E40\u0E25\u0E37\u0E2D\u0E01",
923
+ deleteSelected: "\u0E25\u0E1A\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E40\u0E25\u0E37\u0E2D\u0E01",
924
+ tagsToApply: "\u0E41\u0E17\u0E47\u0E01\u0E17\u0E35\u0E48\u0E08\u0E30\u0E43\u0E0A\u0E49",
925
+ applyTags: "\u0E43\u0E0A\u0E49\u0E41\u0E17\u0E47\u0E01",
926
+ savedMessage: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E41\u0E25\u0E49\u0E27",
927
+ removedMessage: "\u0E25\u0E1A\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E41\u0E25\u0E49\u0E27",
928
+ undo: "\u0E40\u0E25\u0E34\u0E01\u0E17\u0E33",
929
+ undoAvailable: "\u0E25\u0E1A\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E41\u0E25\u0E49\u0E27 \u0E15\u0E49\u0E2D\u0E07\u0E01\u0E32\u0E23\u0E40\u0E25\u0E34\u0E01\u0E17\u0E33\u0E2B\u0E23\u0E37\u0E2D\u0E44\u0E21\u0E48",
930
+ selectionScope: "\u0E02\u0E2D\u0E1A\u0E40\u0E02\u0E15\u0E01\u0E32\u0E23\u0E40\u0E25\u0E37\u0E2D\u0E01",
931
+ currentPage: "\u0E2B\u0E19\u0E49\u0E32\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19",
932
+ searchResults: "\u0E1C\u0E25\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19",
933
+ allItems: "\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14",
934
+ statusAvailable: "\u0E1E\u0E23\u0E49\u0E2D\u0E21\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19",
935
+ noteSavedMessage: "\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E22\u0E48\u0E2D\u0E41\u0E25\u0E49\u0E27",
936
+ exportData: "\u0E2A\u0E48\u0E07\u0E2D\u0E2D\u0E01 JSON",
937
+ importData: "\u0E19\u0E33\u0E40\u0E02\u0E49\u0E32 JSON",
938
+ importMode: "\u0E42\u0E2B\u0E21\u0E14\u0E19\u0E33\u0E40\u0E02\u0E49\u0E32",
939
+ merge: "\u0E23\u0E27\u0E21",
940
+ replace: "\u0E41\u0E17\u0E19\u0E17\u0E35\u0E48",
941
+ importedCount: "\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E19\u0E33\u0E40\u0E02\u0E49\u0E32\u0E41\u0E25\u0E49\u0E27",
942
+ failedCount: "\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E25\u0E49\u0E21\u0E40\u0E2B\u0E25\u0E27",
943
+ storageQuotaError: "\u0E1E\u0E37\u0E49\u0E19\u0E17\u0E35\u0E48\u0E08\u0E31\u0E14\u0E40\u0E01\u0E47\u0E1A\u0E40\u0E15\u0E47\u0E21 \u0E42\u0E1B\u0E23\u0E14\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E1E\u0E37\u0E49\u0E19\u0E17\u0E35\u0E48\u0E41\u0E25\u0E49\u0E27\u0E25\u0E2D\u0E07\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07",
944
+ statusExpired: "\u0E2B\u0E21\u0E14\u0E2D\u0E32\u0E22\u0E38",
945
+ statusRemoved: "\u0E19\u0E33\u0E2D\u0E2D\u0E01\u0E41\u0E25\u0E49\u0E27",
946
+ statusDeleted: "\u0E25\u0E1A\u0E41\u0E25\u0E49\u0E27",
947
+ statusPrivate: "\u0E40\u0E1B\u0E47\u0E19\u0E2A\u0E48\u0E27\u0E19\u0E15\u0E31\u0E27",
948
+ statusUnknown: "\u0E44\u0E21\u0E48\u0E1E\u0E23\u0E49\u0E2D\u0E21\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19",
949
+ retry: "\u0E25\u0E2D\u0E07\u0E43\u0E2B\u0E21\u0E48",
950
+ removeFromList: "\u0E25\u0E1A\u0E2D\u0E2D\u0E01\u0E08\u0E32\u0E01\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23",
951
+ pruneStale: "\u0E25\u0E1A\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49",
952
+ retrySync: "\u0E25\u0E2D\u0E07\u0E0B\u0E34\u0E07\u0E04\u0E4C\u0E43\u0E2B\u0E21\u0E48",
953
+ resolveSync: "\u0E41\u0E01\u0E49\u0E44\u0E02\u0E02\u0E49\u0E2D\u0E02\u0E31\u0E14\u0E41\u0E22\u0E49\u0E07",
954
+ keepLocal: "\u0E43\u0E0A\u0E49\u0E40\u0E27\u0E2D\u0E23\u0E4C\u0E0A\u0E31\u0E19\u0E43\u0E19\u0E40\u0E04\u0E23\u0E37\u0E48\u0E2D\u0E07",
955
+ useServer: "\u0E43\u0E0A\u0E49\u0E40\u0E27\u0E2D\u0E23\u0E4C\u0E0A\u0E31\u0E19\u0E40\u0E0B\u0E34\u0E23\u0E4C\u0E1F\u0E40\u0E27\u0E2D\u0E23\u0E4C",
956
+ manualMerge: "\u0E23\u0E27\u0E21\u0E14\u0E49\u0E27\u0E22\u0E15\u0E19\u0E40\u0E2D\u0E07",
957
+ close: "\u0E1B\u0E34\u0E14",
958
+ backupRecovery: "\u0E01\u0E39\u0E49\u0E04\u0E37\u0E19\u0E08\u0E32\u0E01\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E2A\u0E33\u0E23\u0E2D\u0E07",
959
+ backupRecoveryDescription: "\u0E2B\u0E32\u0E01\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E0B\u0E34\u0E07\u0E04\u0E4C\u0E43\u0E19\u0E40\u0E04\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E40\u0E2A\u0E35\u0E22\u0E2B\u0E32\u0E22 \u0E43\u0E2B\u0E49\u0E01\u0E39\u0E49\u0E04\u0E37\u0E19\u0E08\u0E32\u0E01\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E2A\u0E33\u0E23\u0E2D\u0E07 JSON \u0E17\u0E35\u0E48\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19\u0E44\u0E14\u0E49",
960
+ syncPending: "\u0E21\u0E35\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E17\u0E35\u0E48\u0E23\u0E2D\u0E01\u0E32\u0E23\u0E0B\u0E34\u0E07\u0E04\u0E4C",
961
+ syncSynced: "\u0E0B\u0E34\u0E07\u0E04\u0E4C\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14\u0E41\u0E25\u0E49\u0E27",
962
+ syncConflict: "\u0E21\u0E35\u0E01\u0E32\u0E23\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E41\u0E1B\u0E25\u0E07\u0E17\u0E35\u0E48\u0E15\u0E49\u0E2D\u0E07\u0E41\u0E01\u0E49\u0E44\u0E02\u0E02\u0E49\u0E2D\u0E02\u0E31\u0E14\u0E41\u0E22\u0E49\u0E07"
963
+ };
964
+
965
+ // src/locales/vi.ts
966
+ var VI_LABELS = {
967
+ save: "L\u01B0u",
968
+ saved: "\u0110\xE3 l\u01B0u",
969
+ remove: "X\xF3a",
970
+ loading: "\u0110ang t\u1EA3i\u2026",
971
+ saving: "\u0110ang l\u01B0u\u2026",
972
+ syncing: "\u0110ang \u0111\u1ED3ng b\u1ED9\u2026",
973
+ error: "\u0110\xE3 x\u1EA3y ra l\u1ED7i.",
974
+ allTags: "T\u1EA5t c\u1EA3",
975
+ tags: "Th\u1EBB",
976
+ filterTags: "L\u1ECDc m\u1EE5c \u0111\xE3 l\u01B0u theo th\u1EBB",
977
+ note: "Ghi ch\xFA",
978
+ saveNote: "L\u01B0u ghi ch\xFA",
979
+ noItems: "Ch\u01B0a c\xF3 m\u1EE5c n\xE0o \u0111\u01B0\u1EE3c l\u01B0u.",
980
+ loadingItems: "\u0110ang t\u1EA3i c\xE1c m\u1EE5c \u0111\xE3 l\u01B0u\u2026",
981
+ errorItems: "Kh\xF4ng th\u1EC3 t\u1EA3i c\xE1c m\u1EE5c \u0111\xE3 l\u01B0u.",
982
+ search: "T\xECm ki\u1EBFm m\u1EE5c \u0111\xE3 l\u01B0u",
983
+ sort: "S\u1EAFp x\u1EBFp m\u1EE5c \u0111\xE3 l\u01B0u",
984
+ newest: "M\u1EDBi nh\u1EA5t tr\u01B0\u1EDBc",
985
+ oldest: "C\u0169 nh\u1EA5t tr\u01B0\u1EDBc",
986
+ savedNewest: "L\u01B0u g\u1EA7n \u0111\xE2y nh\u1EA5t tr\u01B0\u1EDBc",
987
+ savedOldest: "L\u01B0u l\xE2u nh\u1EA5t tr\u01B0\u1EDBc",
988
+ updatedNewest: "C\u1EADp nh\u1EADt g\u1EA7n \u0111\xE2y nh\u1EA5t tr\u01B0\u1EDBc",
989
+ updatedOldest: "C\u1EADp nh\u1EADt l\xE2u nh\u1EA5t tr\u01B0\u1EDBc",
990
+ previousPage: "Trang tr\u01B0\u1EDBc",
991
+ nextPage: "Trang sau",
992
+ pagination: "Ph\xE2n trang",
993
+ page: "Trang",
994
+ selectItems: "Ch\u1ECDn m\u1EE5c \u0111\xE3 l\u01B0u",
995
+ selectedCount: "\u0111\xE3 ch\u1ECDn",
996
+ deleteSelected: "X\xF3a m\u1EE5c \u0111\xE3 ch\u1ECDn",
997
+ tagsToApply: "Th\u1EBB c\u1EA7n \xE1p d\u1EE5ng",
998
+ applyTags: "\xC1p d\u1EE5ng th\u1EBB",
999
+ savedMessage: "\u0110\xE3 l\u01B0u m\u1EE5c.",
1000
+ removedMessage: "\u0110\xE3 x\xF3a m\u1EE5c.",
1001
+ undo: "Ho\xE0n t\xE1c",
1002
+ undoAvailable: "\u0110\xE3 x\xF3a m\u1EE5c. Ho\xE0n t\xE1c?",
1003
+ selectionScope: "Ph\u1EA1m vi l\u1EF1a ch\u1ECDn",
1004
+ currentPage: "Trang hi\u1EC7n t\u1EA1i",
1005
+ searchResults: "K\u1EBFt qu\u1EA3 t\xECm ki\u1EBFm hi\u1EC7n t\u1EA1i",
1006
+ allItems: "T\u1EA5t c\u1EA3 m\u1EE5c \u0111\xE3 l\u01B0u",
1007
+ statusAvailable: "Kh\u1EA3 d\u1EE5ng",
1008
+ noteSavedMessage: "\u0110\xE3 l\u01B0u ghi ch\xFA.",
1009
+ exportData: "Xu\u1EA5t JSON",
1010
+ importData: "Nh\u1EADp JSON",
1011
+ importMode: "Ch\u1EBF \u0111\u1ED9 nh\u1EADp",
1012
+ merge: "H\u1EE3p nh\u1EA5t",
1013
+ replace: "Thay th\u1EBF",
1014
+ importedCount: "m\u1EE5c \u0111\xE3 nh\u1EADp",
1015
+ failedCount: "m\u1EE5c b\u1ECB l\u1ED7i",
1016
+ storageQuotaError: "B\u1ED9 nh\u1EDB \u0111\xE3 \u0111\u1EA7y. H\xE3y gi\u1EA3i ph\xF3ng dung l\u01B0\u1EE3ng r\u1ED3i th\u1EED l\u1EA1i.",
1017
+ statusExpired: "\u0110\xE3 h\u1EBFt h\u1EA1n",
1018
+ statusRemoved: "\u0110\xE3 g\u1EE1",
1019
+ statusDeleted: "\u0110\xE3 x\xF3a",
1020
+ statusPrivate: "Ri\xEAng t\u01B0",
1021
+ statusUnknown: "Kh\xF4ng kh\u1EA3 d\u1EE5ng",
1022
+ retry: "Th\u1EED l\u1EA1i",
1023
+ removeFromList: "X\xF3a kh\u1ECFi danh s\xE1ch",
1024
+ pruneStale: "X\xF3a c\xE1c m\u1EE5c kh\xF4ng kh\u1EA3 d\u1EE5ng",
1025
+ retrySync: "Th\u1EED \u0111\u1ED3ng b\u1ED9 l\u1EA1i",
1026
+ resolveSync: "Gi\u1EA3i quy\u1EBFt xung \u0111\u1ED9t",
1027
+ keepLocal: "Gi\u1EEF b\u1EA3n c\u1EE5c b\u1ED9",
1028
+ useServer: "D\xF9ng b\u1EA3n m\xE1y ch\u1EE7",
1029
+ manualMerge: "G\u1ED9p th\u1EE7 c\xF4ng",
1030
+ close: "\u0110\xF3ng",
1031
+ backupRecovery: "Kh\xF4i ph\u1EE5c t\u1EEB b\u1EA3n sao l\u01B0u",
1032
+ backupRecoveryDescription: "N\u1EBFu d\u1EEF li\u1EC7u \u0111\u1ED3ng b\u1ED9 c\u1EE5c b\u1ED9 b\u1ECB h\u1ECFng, h\xE3y kh\xF4i ph\u1EE5c b\u1EA3n sao l\u01B0u JSON h\u1EE3p l\u1EC7.",
1033
+ syncPending: "C\xF3 thay \u0111\u1ED5i \u0111ang ch\u1EDD \u0111\u1ED3ng b\u1ED9.",
1034
+ syncSynced: "T\u1EA5t c\u1EA3 thay \u0111\u1ED5i \u0111\xE3 \u0111\u01B0\u1EE3c \u0111\u1ED3ng b\u1ED9.",
1035
+ syncConflict: "M\u1ED9t s\u1ED1 thay \u0111\u1ED5i c\u1EA7n gi\u1EA3i quy\u1EBFt xung \u0111\u1ED9t."
1036
+ };
1037
+
1038
+ // src/locales/zh-Hans.ts
1039
+ var ZH_HANS_LABELS = {
1040
+ save: "\u4FDD\u5B58",
1041
+ saved: "\u5DF2\u4FDD\u5B58",
1042
+ remove: "\u5220\u9664",
1043
+ loading: "\u52A0\u8F7D\u4E2D\u2026",
1044
+ saving: "\u4FDD\u5B58\u4E2D\u2026",
1045
+ syncing: "\u540C\u6B65\u4E2D\u2026",
1046
+ error: "\u53D1\u751F\u9519\u8BEF\u3002",
1047
+ allTags: "\u5168\u90E8",
1048
+ tags: "\u6807\u7B7E",
1049
+ filterTags: "\u6309\u6807\u7B7E\u7B5B\u9009\u5DF2\u4FDD\u5B58\u9879\u76EE",
1050
+ note: "\u5907\u6CE8",
1051
+ saveNote: "\u4FDD\u5B58\u5907\u6CE8",
1052
+ noItems: "\u6CA1\u6709\u5DF2\u4FDD\u5B58\u7684\u9879\u76EE\u3002",
1053
+ loadingItems: "\u6B63\u5728\u52A0\u8F7D\u5DF2\u4FDD\u5B58\u9879\u76EE\u2026",
1054
+ errorItems: "\u65E0\u6CD5\u52A0\u8F7D\u5DF2\u4FDD\u5B58\u9879\u76EE\u3002",
1055
+ search: "\u641C\u7D22\u5DF2\u4FDD\u5B58\u9879\u76EE",
1056
+ sort: "\u6392\u5E8F\u5DF2\u4FDD\u5B58\u9879\u76EE",
1057
+ newest: "\u6700\u65B0\u4F18\u5148",
1058
+ oldest: "\u6700\u65E9\u4F18\u5148",
1059
+ savedNewest: "\u4FDD\u5B58\u65F6\u95F4\u6700\u65B0\u4F18\u5148",
1060
+ savedOldest: "\u4FDD\u5B58\u65F6\u95F4\u6700\u65E9\u4F18\u5148",
1061
+ updatedNewest: "\u66F4\u65B0\u65F6\u95F4\u6700\u65B0\u4F18\u5148",
1062
+ updatedOldest: "\u66F4\u65B0\u65F6\u95F4\u6700\u65E9\u4F18\u5148",
1063
+ previousPage: "\u4E0A\u4E00\u9875",
1064
+ nextPage: "\u4E0B\u4E00\u9875",
1065
+ pagination: "\u5206\u9875",
1066
+ page: "\u9875",
1067
+ selectItems: "\u9009\u62E9\u5DF2\u4FDD\u5B58\u9879\u76EE",
1068
+ selectedCount: "\u9879\u5DF2\u9009\u62E9",
1069
+ deleteSelected: "\u5220\u9664\u6240\u9009\u9879\u76EE",
1070
+ tagsToApply: "\u8981\u5E94\u7528\u7684\u6807\u7B7E",
1071
+ applyTags: "\u5E94\u7528\u6807\u7B7E",
1072
+ savedMessage: "\u9879\u76EE\u5DF2\u4FDD\u5B58\u3002",
1073
+ removedMessage: "\u9879\u76EE\u5DF2\u5220\u9664\u3002",
1074
+ undo: "\u64A4\u9500",
1075
+ undoAvailable: "\u9879\u76EE\u5DF2\u5220\u9664\u3002\u8981\u64A4\u9500\u5417\uFF1F",
1076
+ selectionScope: "\u9009\u62E9\u8303\u56F4",
1077
+ currentPage: "\u5F53\u524D\u9875",
1078
+ searchResults: "\u5F53\u524D\u5168\u90E8\u641C\u7D22\u7ED3\u679C",
1079
+ allItems: "\u5168\u90E8\u5DF2\u4FDD\u5B58\u9879\u76EE",
1080
+ statusAvailable: "\u53EF\u7528",
1081
+ noteSavedMessage: "\u5907\u6CE8\u5DF2\u4FDD\u5B58\u3002",
1082
+ exportData: "\u5BFC\u51FAJSON",
1083
+ importData: "\u5BFC\u5165JSON",
1084
+ importMode: "\u5BFC\u5165\u65B9\u5F0F",
1085
+ merge: "\u5408\u5E76",
1086
+ replace: "\u66FF\u6362",
1087
+ importedCount: "\u9879\u5DF2\u5BFC\u5165",
1088
+ failedCount: "\u9879\u5931\u8D25",
1089
+ storageQuotaError: "\u5B58\u50A8\u7A7A\u95F4\u5DF2\u6EE1\u3002\u8BF7\u91CA\u653E\u7A7A\u95F4\u540E\u91CD\u8BD5\u3002",
1090
+ statusExpired: "\u5DF2\u8FC7\u671F",
1091
+ statusRemoved: "\u5DF2\u79FB\u9664",
1092
+ statusDeleted: "\u5DF2\u5220\u9664",
1093
+ statusPrivate: "\u4E0D\u516C\u5F00",
1094
+ statusUnknown: "\u4E0D\u53EF\u7528",
1095
+ retry: "\u91CD\u8BD5",
1096
+ removeFromList: "\u4ECE\u5217\u8868\u4E2D\u5220\u9664",
1097
+ pruneStale: "\u5220\u9664\u4E0D\u53EF\u7528\u9879\u76EE",
1098
+ retrySync: "\u91CD\u8BD5\u540C\u6B65",
1099
+ resolveSync: "\u89E3\u51B3\u51B2\u7A81",
1100
+ keepLocal: "\u4FDD\u7559\u672C\u5730\u7248\u672C",
1101
+ useServer: "\u4F7F\u7528\u670D\u52A1\u5668\u7248\u672C",
1102
+ manualMerge: "\u624B\u52A8\u5408\u5E76",
1103
+ close: "\u5173\u95ED",
1104
+ backupRecovery: "\u4ECE\u5907\u4EFD\u6062\u590D",
1105
+ backupRecoveryDescription: "\u5982\u679C\u672C\u5730\u540C\u6B65\u6570\u636E\u635F\u574F\uFF0C\u8BF7\u6062\u590D\u53EF\u7528\u7684 JSON \u5907\u4EFD\u3002",
1106
+ syncPending: "\u6709\u66F4\u6539\u7B49\u5F85\u540C\u6B65\u3002",
1107
+ syncSynced: "\u6240\u6709\u66F4\u6539\u5747\u5DF2\u540C\u6B65\u3002",
1108
+ syncConflict: "\u6709\u4E9B\u66F4\u6539\u9700\u8981\u89E3\u51B3\u51B2\u7A81\u3002"
1109
+ };
1110
+
1111
+ // src/locales/zh-Hant.ts
1112
+ var ZH_HANT_LABELS = {
1113
+ save: "\u5132\u5B58",
1114
+ saved: "\u5DF2\u5132\u5B58",
1115
+ remove: "\u522A\u9664",
1116
+ loading: "\u8F09\u5165\u4E2D\u2026",
1117
+ saving: "\u5132\u5B58\u4E2D\u2026",
1118
+ syncing: "\u540C\u6B65\u4E2D\u2026",
1119
+ error: "\u767C\u751F\u932F\u8AA4\u3002",
1120
+ allTags: "\u5168\u90E8",
1121
+ tags: "\u6A19\u7C64",
1122
+ filterTags: "\u4F9D\u6A19\u7C64\u7BE9\u9078\u5DF2\u5132\u5B58\u9805\u76EE",
1123
+ note: "\u5099\u8A3B",
1124
+ saveNote: "\u5132\u5B58\u5099\u8A3B",
1125
+ noItems: "\u6C92\u6709\u5DF2\u5132\u5B58\u7684\u9805\u76EE\u3002",
1126
+ loadingItems: "\u6B63\u5728\u8F09\u5165\u5DF2\u5132\u5B58\u9805\u76EE\u2026",
1127
+ errorItems: "\u7121\u6CD5\u8F09\u5165\u5DF2\u5132\u5B58\u9805\u76EE\u3002",
1128
+ search: "\u641C\u5C0B\u5DF2\u5132\u5B58\u9805\u76EE",
1129
+ sort: "\u6392\u5E8F\u5DF2\u5132\u5B58\u9805\u76EE",
1130
+ newest: "\u6700\u65B0\u512A\u5148",
1131
+ oldest: "\u6700\u65E9\u512A\u5148",
1132
+ savedNewest: "\u5132\u5B58\u6642\u9593\u6700\u65B0\u512A\u5148",
1133
+ savedOldest: "\u5132\u5B58\u6642\u9593\u6700\u65E9\u512A\u5148",
1134
+ updatedNewest: "\u66F4\u65B0\u6642\u9593\u6700\u65B0\u512A\u5148",
1135
+ updatedOldest: "\u66F4\u65B0\u6642\u9593\u6700\u65E9\u512A\u5148",
1136
+ previousPage: "\u4E0A\u4E00\u9801",
1137
+ nextPage: "\u4E0B\u4E00\u9801",
1138
+ pagination: "\u5206\u9801",
1139
+ page: "\u9801",
1140
+ selectItems: "\u9078\u53D6\u5DF2\u5132\u5B58\u9805\u76EE",
1141
+ selectedCount: "\u9805\u5DF2\u9078\u53D6",
1142
+ deleteSelected: "\u522A\u9664\u6240\u9078\u9805\u76EE",
1143
+ tagsToApply: "\u8981\u5957\u7528\u7684\u6A19\u7C64",
1144
+ applyTags: "\u5957\u7528\u6A19\u7C64",
1145
+ savedMessage: "\u9805\u76EE\u5DF2\u5132\u5B58\u3002",
1146
+ removedMessage: "\u9805\u76EE\u5DF2\u522A\u9664\u3002",
1147
+ undo: "\u5FA9\u539F",
1148
+ undoAvailable: "\u9805\u76EE\u5DF2\u522A\u9664\u3002\u8981\u5FA9\u539F\u55CE\uFF1F",
1149
+ selectionScope: "\u9078\u53D6\u7BC4\u570D",
1150
+ currentPage: "\u76EE\u524D\u9801\u9762",
1151
+ searchResults: "\u76EE\u524D\u5168\u90E8\u641C\u5C0B\u7D50\u679C",
1152
+ allItems: "\u6240\u6709\u5DF2\u5132\u5B58\u9805\u76EE",
1153
+ statusAvailable: "\u53EF\u7528",
1154
+ noteSavedMessage: "\u5099\u8A3B\u5DF2\u5132\u5B58\u3002",
1155
+ exportData: "\u532F\u51FAJSON",
1156
+ importData: "\u532F\u5165JSON",
1157
+ importMode: "\u532F\u5165\u65B9\u5F0F",
1158
+ merge: "\u5408\u4F75",
1159
+ replace: "\u53D6\u4EE3",
1160
+ importedCount: "\u9805\u5DF2\u532F\u5165",
1161
+ failedCount: "\u9805\u5931\u6557",
1162
+ storageQuotaError: "\u5132\u5B58\u7A7A\u9593\u5DF2\u6EFF\u3002\u8ACB\u91CB\u653E\u7A7A\u9593\u5F8C\u91CD\u8A66\u3002",
1163
+ statusExpired: "\u5DF2\u904E\u671F",
1164
+ statusRemoved: "\u5DF2\u79FB\u9664",
1165
+ statusDeleted: "\u5DF2\u522A\u9664",
1166
+ statusPrivate: "\u4E0D\u516C\u958B",
1167
+ statusUnknown: "\u7121\u6CD5\u4F7F\u7528",
1168
+ retry: "\u91CD\u8A66",
1169
+ removeFromList: "\u5F9E\u6E05\u55AE\u4E2D\u522A\u9664",
1170
+ pruneStale: "\u522A\u9664\u7121\u6CD5\u4F7F\u7528\u7684\u9805\u76EE",
1171
+ retrySync: "\u91CD\u8A66\u540C\u6B65",
1172
+ resolveSync: "\u89E3\u6C7A\u885D\u7A81",
1173
+ keepLocal: "\u4FDD\u7559\u672C\u6A5F\u7248\u672C",
1174
+ useServer: "\u4F7F\u7528\u4F3A\u670D\u5668\u7248\u672C",
1175
+ manualMerge: "\u624B\u52D5\u5408\u4F75",
1176
+ close: "\u95DC\u9589",
1177
+ backupRecovery: "\u5F9E\u5099\u4EFD\u9084\u539F",
1178
+ backupRecoveryDescription: "\u5982\u679C\u672C\u6A5F\u540C\u6B65\u8CC7\u6599\u640D\u6BC0\uFF0C\u8ACB\u9084\u539F\u53EF\u7528\u7684 JSON \u5099\u4EFD\u3002",
1179
+ syncPending: "\u6709\u8B8A\u66F4\u7B49\u5F85\u540C\u6B65\u3002",
1180
+ syncSynced: "\u6240\u6709\u8B8A\u66F4\u90FD\u5DF2\u540C\u6B65\u3002",
1181
+ syncConflict: "\u6709\u4E9B\u8B8A\u66F4\u9700\u8981\u89E3\u6C7A\u885D\u7A81\u3002"
1182
+ };
1183
+
1184
+ // src/locales/index.ts
1185
+ var KEEP_BUILT_IN_LOCALES = [
1186
+ "en",
1187
+ "ja",
1188
+ "ko",
1189
+ "zh-Hans",
1190
+ "zh-Hant",
1191
+ "th",
1192
+ "fr",
1193
+ "es",
1194
+ "pt-BR",
1195
+ "it",
1196
+ "de",
1197
+ "ru",
1198
+ "fil",
1199
+ "vi",
1200
+ "id",
1201
+ "ms"
1202
+ ];
1203
+ var KEEP_LOCALE_LABELS = {
1204
+ en: EN_LABELS,
1205
+ ja: JA_LABELS,
1206
+ ko: KO_LABELS,
1207
+ "zh-Hans": ZH_HANS_LABELS,
1208
+ "zh-Hant": ZH_HANT_LABELS,
1209
+ th: TH_LABELS,
1210
+ fr: FR_LABELS,
1211
+ es: ES_LABELS,
1212
+ "pt-BR": PT_BR_LABELS,
1213
+ it: IT_LABELS,
1214
+ de: DE_LABELS,
1215
+ ru: RU_LABELS,
1216
+ fil: FIL_LABELS,
1217
+ vi: VI_LABELS,
1218
+ id: ID_LABELS,
1219
+ ms: MS_LABELS
1220
+ };
1221
+ var LOCALE_ALIASES = {
1222
+ "zh-cn": "zh-Hans",
1223
+ "zh-sg": "zh-Hans",
1224
+ zh: "zh-Hans",
1225
+ "zh-tw": "zh-Hant",
1226
+ "zh-hk": "zh-Hant",
1227
+ "zh-mo": "zh-Hant",
1228
+ "pt-pt": "pt-BR"
1229
+ };
1230
+ function normalizeKeepLocale(locale) {
1231
+ const normalized = locale?.trim().replace(/_/g, "-").toLowerCase() ?? "en";
1232
+ const exact = KEEP_BUILT_IN_LOCALES.find((candidate) => candidate.toLowerCase() === normalized);
1233
+ if (exact) return exact;
1234
+ if (LOCALE_ALIASES[normalized]) return LOCALE_ALIASES[normalized];
1235
+ const language = normalized.split("-")[0];
1236
+ const languageMatch = KEEP_BUILT_IN_LOCALES.find((candidate) => candidate.toLowerCase() === language);
1237
+ return languageMatch ?? "en";
1238
+ }
1239
+ function getKeepLocaleLabels(locale) {
1240
+ return { ...KEEP_LOCALE_LABELS[normalizeKeepLocale(locale)] };
1241
+ }
1242
+
1243
+ // src/ui-context.tsx
1244
+ import { jsx } from "react/jsx-runtime";
1245
+ var DEFAULT_LABELS = KEEP_LOCALE_LABELS.en;
65
1246
  var KeepUiLabelsContext = createContext({ labels: DEFAULT_LABELS });
66
1247
  function KeepUiProvider({ labels, locale, labelResolver, children }) {
67
1248
  const value = useMemo(() => {
68
- const resolved = { ...DEFAULT_LABELS, ...labels };
69
- return { locale, labels: resolved, labelResolver };
1249
+ const resolvedLocale = normalizeKeepLocale(locale);
1250
+ const dictionary = getKeepLocaleLabels(resolvedLocale);
1251
+ const resolved = { ...DEFAULT_LABELS, ...dictionary, ...labels };
1252
+ return { locale: locale ?? resolvedLocale, labels: resolved, customLabels: labels, labelResolver };
70
1253
  }, [labelResolver, labels, locale]);
71
1254
  return /* @__PURE__ */ jsx(KeepUiLabelsContext.Provider, { value, children });
72
1255
  }
@@ -75,7 +1258,7 @@ function useKeepUiLabels() {
75
1258
  }
76
1259
  function useUiLabel(key, override) {
77
1260
  const context = useKeepUiLabels();
78
- return override ?? context.labelResolver?.(key, { locale: context.locale }) ?? context.labels[key];
1261
+ return override ?? context.customLabels?.[key] ?? context.labelResolver?.(key, { locale: context.locale }) ?? context.labels[key];
79
1262
  }
80
1263
 
81
1264
  // src/KeepBackup.tsx
@@ -265,6 +1448,8 @@ function KeepBulkActions({
265
1448
  onSelectedIdsChange,
266
1449
  renderItem,
267
1450
  onCompleted,
1451
+ selectionScope: controlledScope,
1452
+ onSelectionScopeChange,
268
1453
  render,
269
1454
  children,
270
1455
  ...props
@@ -274,7 +1459,20 @@ function KeepBulkActions({
274
1459
  const deleteSelectedLabel = useUiLabel("deleteSelected");
275
1460
  const tagsLabel = useUiLabel("tagsToApply");
276
1461
  const applyTagsLabel = useUiLabel("applyTags");
1462
+ const selectionScopeLabel = useUiLabel("selectionScope");
1463
+ const currentPageLabel = useUiLabel("currentPage");
1464
+ const searchResultsLabel = useUiLabel("searchResults");
1465
+ const allItemsLabel = useUiLabel("allItems");
277
1466
  const list = useKeepList(query);
1467
+ const queryList = useKeepList(query ? { ...query, pagination: void 0 } : { pagination: void 0 });
1468
+ const allList = useKeepList({ pagination: void 0 });
1469
+ const [uncontrolledScope, setUncontrolledScope] = useState2(controlledScope ?? "page");
1470
+ const selectionScope = controlledScope ?? uncontrolledScope;
1471
+ const setSelectionScope = (scope) => {
1472
+ if (controlledScope === void 0) setUncontrolledScope(scope);
1473
+ onSelectionScopeChange?.(scope);
1474
+ };
1475
+ const targetItems = selectionScope === "page" ? list.items : selectionScope === "query" ? queryList.items : allList.items;
278
1476
  const [uncontrolledSelectedIds, setUncontrolledSelectedIds] = useState2(defaultSelectedIds);
279
1477
  const selectedIds = controlledSelectedIds ?? uncontrolledSelectedIds;
280
1478
  const selected = new Set(selectedIds);
@@ -284,11 +1482,11 @@ function KeepBulkActions({
284
1482
  onSelectedIdsChange?.(ids);
285
1483
  };
286
1484
  const toggle = (id) => setSelectedIds(selected.has(id) ? selectedIds.filter((current) => current !== id) : [...selectedIds, id]);
287
- const allSelected = isAllSelected(list.items, selectedIds);
288
- const toggleAll = () => setSelectedIds(toggleSelectAll(list.items, selectedIds));
1485
+ const allSelected = isAllSelected(targetItems, selectedIds);
1486
+ const toggleAll = () => setSelectedIds(toggleSelectAll(targetItems, selectedIds));
289
1487
  const remove = async () => {
290
1488
  const ids = [...selectedIds];
291
- await list.removeBatch(ids);
1489
+ await list.removeBatchWithUndo(ids);
292
1490
  onCompleted?.("remove", ids);
293
1491
  setSelectedIds([]);
294
1492
  };
@@ -299,7 +1497,7 @@ function KeepBulkActions({
299
1497
  setSelectedIds([]);
300
1498
  };
301
1499
  const state = {
302
- items: list.items,
1500
+ items: targetItems,
303
1501
  selectedIds,
304
1502
  selectedCount: selectedIds.length,
305
1503
  isAllSelected: allSelected,
@@ -311,18 +1509,35 @@ function KeepBulkActions({
311
1509
  toggleAll,
312
1510
  remove,
313
1511
  updateTags,
314
- isMutating: list.isMutating
1512
+ isMutating: list.isMutating,
1513
+ selectionScope,
1514
+ setSelectionScope
315
1515
  };
316
1516
  const body = render ? render(state) : typeof children === "function" ? children(state) : children ?? /* @__PURE__ */ jsxs2(Fragment, { children: [
317
1517
  /* @__PURE__ */ jsxs2("fieldset", { children: [
318
1518
  /* @__PURE__ */ jsx5("legend", { children: selectItemsLabel }),
1519
+ /* @__PURE__ */ jsxs2("label", { children: [
1520
+ selectionScopeLabel,
1521
+ /* @__PURE__ */ jsxs2(
1522
+ "select",
1523
+ {
1524
+ value: selectionScope,
1525
+ onChange: (event) => setSelectionScope(event.currentTarget.value),
1526
+ children: [
1527
+ /* @__PURE__ */ jsx5("option", { value: "page", children: currentPageLabel }),
1528
+ /* @__PURE__ */ jsx5("option", { value: "query", children: searchResultsLabel }),
1529
+ /* @__PURE__ */ jsx5("option", { value: "all", children: allItemsLabel })
1530
+ ]
1531
+ }
1532
+ )
1533
+ ] }),
319
1534
  /* @__PURE__ */ jsxs2("label", { children: [
320
1535
  /* @__PURE__ */ jsx5("input", { type: "checkbox", checked: allSelected, onChange: toggleAll, "aria-label": selectItemsLabel }),
321
1536
  selectedIds.length,
322
1537
  " ",
323
1538
  selectedCountLabel
324
1539
  ] }),
325
- list.items.map((item) => /* @__PURE__ */ jsxs2("span", { children: [
1540
+ targetItems.map((item) => /* @__PURE__ */ jsxs2("span", { children: [
326
1541
  /* @__PURE__ */ jsx5(
327
1542
  KeepItemCheckbox,
328
1543
  {
@@ -395,7 +1610,7 @@ function KeepButton({ labels, ...props }) {
395
1610
 
396
1611
  // src/KeepCollection.tsx
397
1612
  import { KeepErrorBoundary as KeepErrorBoundary2, useKeepList as useKeepList4 } from "@keepkit/core/react";
398
- import { useMemo as useMemo3, useState as useState5 } from "react";
1613
+ import { useMemo as useMemo3, useState as useState6 } from "react";
399
1614
 
400
1615
  // src/KeepList.tsx
401
1616
  import {
@@ -409,7 +1624,116 @@ import { useKeepItem as useKeepItem2 } from "@keepkit/core/react";
409
1624
  import {
410
1625
  isValidElement as isValidElement2
411
1626
  } from "react";
412
- import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
1627
+
1628
+ // src/KeepStaleNotice.tsx
1629
+ import { useKeepContext as useKeepContext2 } from "@keepkit/core/react";
1630
+ import { useState as useState3 } from "react";
1631
+
1632
+ // src/KeepItemStatusBadge.tsx
1633
+ import { jsx as jsx7 } from "react/jsx-runtime";
1634
+ function KeepItemStatusBadge({ status = "available", label, className, ...props }) {
1635
+ const resolvedStatus = status === "available" ? "available" : status;
1636
+ const statusLabel = useUiLabel(getStatusLabelKey(resolvedStatus));
1637
+ return /* @__PURE__ */ jsx7("span", { ...props, className, "data-keepkit": "status-badge", "data-status": resolvedStatus, children: label ?? statusLabel });
1638
+ }
1639
+ function getStatusLabelKey(status) {
1640
+ switch (status) {
1641
+ case "available":
1642
+ return "statusAvailable";
1643
+ case "expired":
1644
+ return "statusExpired";
1645
+ case "removed":
1646
+ return "statusRemoved";
1647
+ case "deleted":
1648
+ return "statusDeleted";
1649
+ case "private":
1650
+ case "unknown":
1651
+ return status === "private" ? "statusPrivate" : "statusUnknown";
1652
+ }
1653
+ }
1654
+
1655
+ // src/KeepStaleNotice.tsx
1656
+ import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
1657
+ function KeepStaleNotice({
1658
+ item,
1659
+ onRetry,
1660
+ onRemoved,
1661
+ retryLabel,
1662
+ removeLabel,
1663
+ children,
1664
+ className,
1665
+ ...props
1666
+ }) {
1667
+ const context = useKeepContext2();
1668
+ const retryText = useUiLabel("retry");
1669
+ const removeText = useUiLabel("removeFromList");
1670
+ const errorText = useUiLabel("error");
1671
+ const [isRetrying, setIsRetrying] = useState3(false);
1672
+ const [error, setError] = useState3(null);
1673
+ const status = item.status && item.status !== "available" ? item.status : "unknown";
1674
+ async function handleRetry() {
1675
+ setError(null);
1676
+ setIsRetrying(true);
1677
+ try {
1678
+ if (onRetry) await onRetry(item);
1679
+ else await context.revalidateItems();
1680
+ } catch (cause) {
1681
+ setError(cause);
1682
+ } finally {
1683
+ setIsRetrying(false);
1684
+ }
1685
+ }
1686
+ async function handleRemove() {
1687
+ try {
1688
+ await context.removeItemWithUndo(item.id);
1689
+ onRemoved?.(item);
1690
+ } catch (cause) {
1691
+ setError(cause);
1692
+ }
1693
+ }
1694
+ return /* @__PURE__ */ jsxs3("aside", { ...props, className, "data-keepkit": "stale-notice", "data-state": error ? "error" : "stale", children: [
1695
+ /* @__PURE__ */ jsx8(KeepItemStatusBadge, { status }),
1696
+ children ?? (item.statusReason ? /* @__PURE__ */ jsx8("p", { children: item.statusReason }) : null),
1697
+ /* @__PURE__ */ jsxs3("div", { children: [
1698
+ /* @__PURE__ */ jsx8("button", { type: "button", onClick: () => void handleRetry(), disabled: isRetrying || context.isMutating, children: retryLabel ?? retryText }),
1699
+ /* @__PURE__ */ jsx8("button", { type: "button", onClick: () => void handleRemove(), disabled: context.isMutating, children: removeLabel ?? removeText })
1700
+ ] }),
1701
+ error ? /* @__PURE__ */ jsx8("p", { role: "alert", children: error instanceof Error ? error.message : errorText }) : null
1702
+ ] });
1703
+ }
1704
+ function KeepPruneStaleButton({
1705
+ statuses = ["expired", "removed", "deleted", "private", "unknown"],
1706
+ label,
1707
+ onPruned,
1708
+ children,
1709
+ disabled,
1710
+ ...props
1711
+ }) {
1712
+ const context = useKeepContext2();
1713
+ const defaultLabel = useUiLabel("pruneStale");
1714
+ const staleIds = context.items.filter((item) => item.status && statuses.includes(item.status)).map((item) => item.id);
1715
+ async function handlePrune() {
1716
+ const ids = [...staleIds];
1717
+ await context.removeItemsWithUndo(ids);
1718
+ onPruned?.(ids);
1719
+ }
1720
+ return /* @__PURE__ */ jsx8(
1721
+ "button",
1722
+ {
1723
+ ...props,
1724
+ type: "button",
1725
+ className: props.className,
1726
+ "data-keepkit": "prune-stale",
1727
+ "data-state": staleIds.length > 0 ? "available" : "empty",
1728
+ disabled: staleIds.length === 0 || context.isMutating || disabled,
1729
+ onClick: () => void handlePrune(),
1730
+ children: children ?? label ?? `${defaultLabel} (${staleIds.length})`
1731
+ }
1732
+ );
1733
+ }
1734
+
1735
+ // src/KeepItemCard.tsx
1736
+ import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
413
1737
  function KeepItemCard({
414
1738
  item,
415
1739
  title,
@@ -417,12 +1741,15 @@ function KeepItemCard({
417
1741
  getImageProps,
418
1742
  imageComponent: ImageComponent,
419
1743
  renderImage,
1744
+ renderTags,
1745
+ showTags = true,
420
1746
  imageAlt,
421
1747
  render,
422
1748
  children,
423
1749
  removeLabel,
424
1750
  onRemoveError,
425
1751
  onRemoved,
1752
+ onRetry,
426
1753
  showSaveButton = true,
427
1754
  saveButtonLabels,
428
1755
  asChild = false,
@@ -451,8 +1778,9 @@ function KeepItemCard({
451
1778
  const imageProps = getImageProps?.(item, resolvedTitle);
452
1779
  const href = typeof hrefOption === "function" ? hrefOption(item) : hrefOption;
453
1780
  const isAvailable = item.status === void 0 || item.status === "available";
454
- const statusLabelKey = item.status && item.status !== "available" ? getStatusLabelKey(item.status) : "statusUnknown";
1781
+ const statusLabelKey = item.status && item.status !== "available" ? getStatusLabelKey2(item.status) : "statusUnknown";
455
1782
  const unavailableLabel = useUiLabel(statusLabelKey);
1783
+ const tagsLabel = useUiLabel("tags");
456
1784
  const statusLabel = item.status && item.status !== "available" ? unavailableLabel : void 0;
457
1785
  function renderLink(content) {
458
1786
  if (!href || !isAvailable) return content;
@@ -463,7 +1791,7 @@ function KeepItemCard({
463
1791
  onClick: (event) => onOpen?.(item, event),
464
1792
  children: content
465
1793
  };
466
- return LinkComponent ? /* @__PURE__ */ jsx7(LinkComponent, { ...linkProps }) : /* @__PURE__ */ jsx7("a", { ...linkProps });
1794
+ return LinkComponent ? /* @__PURE__ */ jsx9(LinkComponent, { ...linkProps }) : /* @__PURE__ */ jsx9("a", { ...linkProps });
467
1795
  }
468
1796
  async function handleRemove() {
469
1797
  try {
@@ -473,11 +1801,12 @@ function KeepItemCard({
473
1801
  onRemoveError?.(error);
474
1802
  }
475
1803
  }
476
- const body = render ? render(state) : typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? /* @__PURE__ */ jsxs3(Fragment3, { children: [
477
- imageProps ? renderImage?.({ ...imageProps, alt: imageAlt ?? imageProps.alt }, item) ?? (ImageComponent ? /* @__PURE__ */ jsx7(ImageComponent, { ...imageProps, alt: imageAlt ?? imageProps.alt }) : /* @__PURE__ */ jsx7("img", { ...imageProps, alt: imageAlt ?? imageProps.alt })) : null,
478
- /* @__PURE__ */ jsx7("h3", { children: linkTarget === "title" ? renderLink(resolvedTitle) : resolvedTitle }),
479
- statusLabel ? /* @__PURE__ */ jsx7("p", { "data-status": item.status, children: statusLabel }) : null,
480
- showSaveButton ? /* @__PURE__ */ jsx7(
1804
+ const body = render ? render(state) : typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? /* @__PURE__ */ jsxs4(Fragment3, { children: [
1805
+ imageProps ? renderImage?.({ ...imageProps, alt: imageAlt ?? imageProps.alt }, item) ?? (ImageComponent ? /* @__PURE__ */ jsx9(ImageComponent, { ...imageProps, alt: imageAlt ?? imageProps.alt }) : /* @__PURE__ */ jsx9("img", { ...imageProps, alt: imageAlt ?? imageProps.alt })) : null,
1806
+ /* @__PURE__ */ jsx9("h3", { children: linkTarget === "title" ? renderLink(resolvedTitle) : resolvedTitle }),
1807
+ showTags && (item.tags?.length ?? 0) > 0 ? renderTags ? renderTags(item.tags ?? [], item) : /* @__PURE__ */ jsx9("ul", { "aria-label": tagsLabel, children: item.tags?.map((tag) => /* @__PURE__ */ jsx9("li", { children: tag }, tag)) }) : null,
1808
+ statusLabel ? /* @__PURE__ */ jsx9(KeepStaleNotice, { item, onRetry, onRemoved }) : null,
1809
+ showSaveButton && !statusLabel ? /* @__PURE__ */ jsx9(
481
1810
  KeepButton,
482
1811
  {
483
1812
  item: toKeepButtonItem(item),
@@ -485,7 +1814,7 @@ function KeepItemCard({
485
1814
  getAriaLabel: (buttonState) => `${buttonState.isSaved ? removeActionLabel : saveActionLabel} ${String(resolvedTitle)}`
486
1815
  }
487
1816
  ) : null,
488
- /* @__PURE__ */ jsx7("button", { type: "button", onClick: () => void handleRemove(), disabled: itemState.isMutating, children: removeLabel ?? removeActionLabel })
1817
+ !statusLabel ? /* @__PURE__ */ jsx9("button", { type: "button", onClick: () => void handleRemove(), disabled: itemState.isMutating, children: removeLabel ?? removeActionLabel }) : null
489
1818
  ] });
490
1819
  const linkedBody = linkTarget === "card" ? renderLink(body) : body;
491
1820
  return renderRoot(
@@ -503,7 +1832,7 @@ function KeepItemCard({
503
1832
  "KeepItemCard"
504
1833
  );
505
1834
  }
506
- function getStatusLabelKey(status) {
1835
+ function getStatusLabelKey2(status) {
507
1836
  switch (status) {
508
1837
  case "expired":
509
1838
  return "statusExpired";
@@ -519,12 +1848,12 @@ function getStatusLabelKey(status) {
519
1848
  }
520
1849
 
521
1850
  // src/KeepList.tsx
522
- import { jsx as jsx8 } from "react/jsx-runtime";
1851
+ import { jsx as jsx10 } from "react/jsx-runtime";
523
1852
  function KeepList(props) {
524
1853
  const { fallback, onBoundaryError, boundaryResetKey, ...listProps } = props;
525
- const content = /* @__PURE__ */ jsx8(KeepListContent, { ...listProps });
1854
+ const content = /* @__PURE__ */ jsx10(KeepListContent, { ...listProps });
526
1855
  if (fallback === void 0 && onBoundaryError === void 0) return content;
527
- return /* @__PURE__ */ jsx8(KeepErrorBoundary, { fallback, onError: onBoundaryError, resetKey: boundaryResetKey, children: content });
1856
+ return /* @__PURE__ */ jsx10(KeepErrorBoundary, { fallback, onError: onBoundaryError, resetKey: boundaryResetKey, children: content });
528
1857
  }
529
1858
  function KeepListContent({
530
1859
  query,
@@ -534,6 +1863,7 @@ function KeepListContent({
534
1863
  empty,
535
1864
  error: errorContent,
536
1865
  itemCardProps,
1866
+ layout = "list",
537
1867
  asChild = false,
538
1868
  className,
539
1869
  ...rootProps
@@ -548,7 +1878,8 @@ function KeepListContent({
548
1878
  loading: loading ?? defaultLoading,
549
1879
  empty: empty ?? defaultEmpty,
550
1880
  error: errorContent ?? defaultError,
551
- itemCardProps
1881
+ itemCardProps,
1882
+ layout
552
1883
  });
553
1884
  return renderRoot(
554
1885
  asChild,
@@ -576,15 +1907,22 @@ function getListBody(state, options) {
576
1907
  if (state.isHydrated && state.items.length === 0) return resolveContent(options.empty, state);
577
1908
  if (typeof options.children === "function") return options.children(state);
578
1909
  if (options.children !== void 0 && !isValidElement3(options.children)) return options.children;
579
- return /* @__PURE__ */ jsx8("ul", { children: state.items.map(
580
- (item) => options.renderItem ? options.renderItem(item, state) : /* @__PURE__ */ jsx8("li", { children: /* @__PURE__ */ jsx8(KeepItemCard, { item, ...options.itemCardProps }) }, item.id)
581
- ) });
1910
+ return /* @__PURE__ */ jsx10(
1911
+ "ul",
1912
+ {
1913
+ "data-layout": options.layout,
1914
+ style: options.layout === "grid" ? { display: "grid", gap: "1rem", gridTemplateColumns: "repeat(auto-fit, minmax(16rem, 1fr))" } : options.layout === "compact" ? { display: "grid", gap: "0.5rem", gridTemplateColumns: "repeat(auto-fit, minmax(12rem, 1fr))" } : { display: "flex", flexDirection: "column", gap: "1rem" },
1915
+ children: state.items.map(
1916
+ (item) => options.renderItem ? options.renderItem(item, state) : /* @__PURE__ */ jsx10("li", { children: /* @__PURE__ */ jsx10(KeepItemCard, { item, ...options.itemCardProps }) }, item.id)
1917
+ )
1918
+ }
1919
+ );
582
1920
  }
583
1921
 
584
1922
  // src/KeepTagFilter.tsx
585
1923
  import { useKeepList as useKeepList3 } from "@keepkit/core/react";
586
- import { isValidElement as isValidElement4, useCallback, useMemo as useMemo2, useState as useState3 } from "react";
587
- import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
1924
+ import { isValidElement as isValidElement4, useCallback, useMemo as useMemo2, useState as useState4 } from "react";
1925
+ import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
588
1926
  function KeepTagFilter({
589
1927
  query,
590
1928
  value: controlledValue,
@@ -602,7 +1940,7 @@ function KeepTagFilter({
602
1940
  }) {
603
1941
  const uiAllLabel = useUiLabel("allTags");
604
1942
  const uiAriaLabel = useUiLabel("filterTags");
605
- const [uncontrolledValue, setUncontrolledValue] = useState3(defaultValue);
1943
+ const [uncontrolledValue, setUncontrolledValue] = useState4(defaultValue);
606
1944
  const resolvedValue = controlledValue ?? uncontrolledValue;
607
1945
  const list = useKeepList3({
608
1946
  ...query,
@@ -621,12 +1959,12 @@ function KeepTagFilter({
621
1959
  [list.tagCounts, list.tags, resolvedValue, select]
622
1960
  );
623
1961
  const contentChildren = asChild && isValidElement4(children) ? void 0 : children;
624
- const body = render ? render(state) : typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? /* @__PURE__ */ jsxs4("fieldset", { children: [
625
- /* @__PURE__ */ jsx9("legend", { children: ariaLabel ?? uiAriaLabel }),
626
- /* @__PURE__ */ jsx9("button", { type: "button", "aria-pressed": resolvedValue === void 0, onClick: () => select(), children: allLabel ?? uiAllLabel }),
627
- list.tags.map((tag) => /* @__PURE__ */ jsxs4("button", { type: "button", "aria-pressed": resolvedValue === tag, onClick: () => select(tag), children: [
1962
+ const body = render ? render(state) : typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? /* @__PURE__ */ jsxs5("fieldset", { children: [
1963
+ /* @__PURE__ */ jsx11("legend", { children: ariaLabel ?? uiAriaLabel }),
1964
+ /* @__PURE__ */ jsx11("button", { type: "button", "aria-pressed": resolvedValue === void 0, onClick: () => select(), children: allLabel ?? uiAllLabel }),
1965
+ list.tags.map((tag) => /* @__PURE__ */ jsxs5("button", { type: "button", "aria-pressed": resolvedValue === tag, onClick: () => select(tag), children: [
628
1966
  renderTag ? renderTag(tag, list.tagCounts[tag] ?? 0, resolvedValue === tag) : tag,
629
- /* @__PURE__ */ jsxs4("span", { children: [
1967
+ /* @__PURE__ */ jsxs5("span", { children: [
630
1968
  " (",
631
1969
  list.tagCounts[tag] ?? 0,
632
1970
  ")"
@@ -648,8 +1986,8 @@ function KeepTagFilter({
648
1986
  }
649
1987
 
650
1988
  // src/query-controls.tsx
651
- import { useEffect, useState as useState4 } from "react";
652
- import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
1989
+ import { useEffect, useState as useState5 } from "react";
1990
+ import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
653
1991
  function KeepSearchInput({
654
1992
  value: controlledValue,
655
1993
  defaultValue = "",
@@ -660,7 +1998,7 @@ function KeepSearchInput({
660
1998
  ...props
661
1999
  }) {
662
2000
  const label = useUiLabel("search");
663
- const [uncontrolledValue, setUncontrolledValue] = useState4(defaultValue);
2001
+ const [uncontrolledValue, setUncontrolledValue] = useState5(defaultValue);
664
2002
  const value = controlledValue ?? uncontrolledValue;
665
2003
  useEffect(() => {
666
2004
  if (!onValueChange) return;
@@ -671,7 +2009,7 @@ function KeepSearchInput({
671
2009
  const timer = window.setTimeout(() => onValueChange(value), debounceMs);
672
2010
  return () => window.clearTimeout(timer);
673
2011
  }, [debounceMs, onValueChange, value]);
674
- return /* @__PURE__ */ jsx10(
2012
+ return /* @__PURE__ */ jsx12(
675
2013
  "input",
676
2014
  {
677
2015
  ...props,
@@ -701,15 +2039,15 @@ function KeepSortSelect({
701
2039
  const updatedOldestLabel = useUiLabel("updatedOldest");
702
2040
  const savedNewestLabel = useUiLabel("savedNewest");
703
2041
  const savedOldestLabel = useUiLabel("savedOldest");
704
- const [uncontrolledValue, setUncontrolledValue] = useState4(defaultValue);
2042
+ const [uncontrolledValue, setUncontrolledValue] = useState5(defaultValue);
705
2043
  const value = controlledValue ?? uncontrolledValue;
706
- const options = children ?? /* @__PURE__ */ jsxs5(Fragment4, { children: [
707
- /* @__PURE__ */ jsx10("option", { value: "updatedAt:desc", children: updatedNewestLabel }),
708
- /* @__PURE__ */ jsx10("option", { value: "updatedAt:asc", children: updatedOldestLabel }),
709
- /* @__PURE__ */ jsx10("option", { value: "savedAt:desc", children: savedNewestLabel }),
710
- /* @__PURE__ */ jsx10("option", { value: "savedAt:asc", children: savedOldestLabel })
2044
+ const options = children ?? /* @__PURE__ */ jsxs6(Fragment4, { children: [
2045
+ /* @__PURE__ */ jsx12("option", { value: "updatedAt:desc", children: updatedNewestLabel }),
2046
+ /* @__PURE__ */ jsx12("option", { value: "updatedAt:asc", children: updatedOldestLabel }),
2047
+ /* @__PURE__ */ jsx12("option", { value: "savedAt:desc", children: savedNewestLabel }),
2048
+ /* @__PURE__ */ jsx12("option", { value: "savedAt:asc", children: savedOldestLabel })
711
2049
  ] });
712
- return /* @__PURE__ */ jsx10(
2050
+ return /* @__PURE__ */ jsx12(
713
2051
  "select",
714
2052
  {
715
2053
  ...props,
@@ -751,11 +2089,11 @@ function KeepPagination({
751
2089
  "aria-label": props["aria-label"] ?? paginationLabel,
752
2090
  "data-state": pageCount > 1 ? "active" : "idle"
753
2091
  };
754
- if (render) return /* @__PURE__ */ jsx10("nav", { ...navProps, children: render({ page: currentPage, pageCount, goToPage }) });
2092
+ if (render) return /* @__PURE__ */ jsx12("nav", { ...navProps, children: render({ page: currentPage, pageCount, goToPage }) });
755
2093
  const visiblePages = getVisiblePages(currentPage, pageCount, Math.max(1, maxPageButtons));
756
- return /* @__PURE__ */ jsxs5("nav", { ...navProps, children: [
757
- /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => goToPage(currentPage - 1), disabled: currentPage <= 1, children: previousPageLabel }),
758
- visiblePages.map((nextPage) => /* @__PURE__ */ jsx10(
2094
+ return /* @__PURE__ */ jsxs6("nav", { ...navProps, children: [
2095
+ /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => goToPage(currentPage - 1), disabled: currentPage <= 1, children: previousPageLabel }),
2096
+ visiblePages.map((nextPage) => /* @__PURE__ */ jsx12(
759
2097
  "button",
760
2098
  {
761
2099
  type: "button",
@@ -766,7 +2104,7 @@ function KeepPagination({
766
2104
  },
767
2105
  nextPage
768
2106
  )),
769
- /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => goToPage(currentPage + 1), disabled: currentPage >= pageCount, children: nextPageLabel })
2107
+ /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => goToPage(currentPage + 1), disabled: currentPage >= pageCount, children: nextPageLabel })
770
2108
  ] });
771
2109
  }
772
2110
  function getVisiblePages(currentPage, pageCount, maxPageButtons) {
@@ -776,17 +2114,102 @@ function getVisiblePages(currentPage, pageCount, maxPageButtons) {
776
2114
  return Array.from({ length: maxPageButtons }, (_, index) => start + index);
777
2115
  }
778
2116
 
2117
+ // src/url-sync.tsx
2118
+ import {
2119
+ DEFAULT_KEEP_URL_PARAMS,
2120
+ decodeKeepListQuery,
2121
+ encodeKeepListQuery
2122
+ } from "@keepkit/core/core";
2123
+ import { useEffect as useEffect2, useRef as useRef2 } from "react";
2124
+ function createNextPagesRouterAdapter(router) {
2125
+ const getUrl = () => router.asPath ?? (typeof window === "undefined" ? "/" : window.location.href);
2126
+ return {
2127
+ getUrl,
2128
+ subscribe: router.events ? (listener) => {
2129
+ router.events?.on("routeChangeComplete", listener);
2130
+ return () => router.events?.off("routeChangeComplete", listener);
2131
+ } : void 0,
2132
+ navigate: (url, mode) => {
2133
+ void router[mode](url, void 0, { shallow: true });
2134
+ }
2135
+ };
2136
+ }
2137
+ function useKeepUrlSync({
2138
+ enabled = true,
2139
+ query,
2140
+ onQueryChange,
2141
+ options = {},
2142
+ adapter: providedAdapter
2143
+ }) {
2144
+ const browserAdapterRef = useRef2(getBrowserAdapter());
2145
+ const adapter = providedAdapter ?? browserAdapterRef.current;
2146
+ const onQueryChangeRef = useRef2(onQueryChange);
2147
+ onQueryChangeRef.current = onQueryChange;
2148
+ const skipWriteRef = useRef2(true);
2149
+ const params = options.params;
2150
+ useEffect2(() => {
2151
+ if (!enabled) return;
2152
+ const read = () => {
2153
+ const url = adapter.getUrl();
2154
+ const decoded = decodeKeepListQuery(url, { params });
2155
+ skipWriteRef.current = true;
2156
+ onQueryChangeRef.current((previousQuery) => ({
2157
+ ...previousQuery,
2158
+ ...decoded.search ? { search: decoded.search } : { search: void 0 },
2159
+ ...decoded.tags ? { tags: decoded.tags } : { tags: void 0 },
2160
+ ...decoded.sort ? { sort: decoded.sort } : {},
2161
+ ...decoded.pagination ? { pagination: { ...previousQuery.pagination, ...decoded.pagination } } : {}
2162
+ }));
2163
+ };
2164
+ read();
2165
+ return adapter.subscribe?.(read);
2166
+ }, [adapter, enabled, params]);
2167
+ useEffect2(() => {
2168
+ if (!enabled) return;
2169
+ if (skipWriteRef.current) {
2170
+ skipWriteRef.current = false;
2171
+ return;
2172
+ }
2173
+ const currentUrl = new URL(adapter.getUrl(), "http://keepkit.invalid");
2174
+ const urlParams = { ...DEFAULT_KEEP_URL_PARAMS, ...params };
2175
+ for (const key of Object.values(urlParams)) currentUrl.searchParams.delete(key);
2176
+ const nextParams = encodeKeepListQuery(query, { params });
2177
+ nextParams.forEach((value, key) => {
2178
+ currentUrl.searchParams.append(key, value);
2179
+ });
2180
+ const nextUrl = `${currentUrl.pathname}${currentUrl.search}${currentUrl.hash}`;
2181
+ adapter.navigate(nextUrl, options.history ?? "push");
2182
+ }, [adapter, enabled, options.history, params, query]);
2183
+ }
2184
+ function getBrowserAdapter() {
2185
+ return {
2186
+ getUrl: () => typeof window === "undefined" ? "/" : window.location.href,
2187
+ subscribe: (listener) => {
2188
+ if (typeof window === "undefined") return () => void 0;
2189
+ window.addEventListener("popstate", listener);
2190
+ return () => window.removeEventListener("popstate", listener);
2191
+ },
2192
+ navigate: (url, mode) => {
2193
+ if (typeof window === "undefined") return;
2194
+ window.history[mode === "push" ? "pushState" : "replaceState"]({}, "", url);
2195
+ }
2196
+ };
2197
+ }
2198
+
779
2199
  // src/KeepCollection.tsx
780
- import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
2200
+ import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
781
2201
  function KeepCollection(props) {
782
2202
  const { fallback, onBoundaryError, boundaryResetKey, ...collectionProps } = props;
783
- const content = /* @__PURE__ */ jsx11(KeepCollectionContent, { ...collectionProps });
2203
+ const content = /* @__PURE__ */ jsx13(KeepCollectionContent, { ...collectionProps });
784
2204
  if (fallback === void 0 && onBoundaryError === void 0) return content;
785
- return /* @__PURE__ */ jsx11(KeepErrorBoundary2, { fallback, onError: onBoundaryError, resetKey: boundaryResetKey, children: content });
2205
+ return /* @__PURE__ */ jsx13(KeepErrorBoundary2, { fallback, onError: onBoundaryError, resetKey: boundaryResetKey, children: content });
786
2206
  }
787
2207
  function KeepCollectionContent({
788
2208
  query = {},
789
2209
  pageSize = 20,
2210
+ layout = "list",
2211
+ urlSync = false,
2212
+ urlAdapter,
790
2213
  features,
791
2214
  renderItem,
792
2215
  itemCardProps,
@@ -804,10 +2227,10 @@ function KeepCollectionContent({
804
2227
  bulkActions: false,
805
2228
  ...features
806
2229
  };
807
- const [searchValue, setSearchValue] = useState5(query.search?.query ?? "");
808
- const [sort, setSort] = useState5(query.sort ?? { by: "updatedAt", direction: "desc" });
809
- const [tag, setTag] = useState5(query.tags?.[0]);
810
- const [page, setPage] = useState5(query.pagination?.page ?? 1);
2230
+ const [searchValue, setSearchValue] = useState6(query.search?.query ?? "");
2231
+ const [sort, setSort] = useState6(query.sort ?? { by: "updatedAt", direction: "desc" });
2232
+ const [tag, setTag] = useState6(query.tags?.[0]);
2233
+ const [page, setPage] = useState6(query.pagination?.page ?? 1);
811
2234
  const resolvedPageSize = query.pagination?.pageSize ?? pageSize;
812
2235
  const resolvedQuery = useMemo3(
813
2236
  () => ({
@@ -819,8 +2242,21 @@ function KeepCollectionContent({
819
2242
  }),
820
2243
  [enabled.pagination, enabled.search, enabled.sort, page, query, resolvedPageSize, searchValue, sort, tag]
821
2244
  );
2245
+ useKeepUrlSync({
2246
+ enabled: Boolean(urlSync),
2247
+ query: resolvedQuery,
2248
+ onQueryChange: (nextOrUpdater) => {
2249
+ const next = typeof nextOrUpdater === "function" ? nextOrUpdater(resolvedQuery) : nextOrUpdater;
2250
+ setSearchValue(next.search?.query ?? "");
2251
+ setSort(next.sort ?? { by: "updatedAt", direction: "desc" });
2252
+ setTag(next.tags?.[0]);
2253
+ setPage(next.pagination?.page ?? 1);
2254
+ },
2255
+ options: typeof urlSync === "object" ? urlSync : {},
2256
+ adapter: urlAdapter
2257
+ });
822
2258
  const list = useKeepList4(resolvedQuery);
823
- return /* @__PURE__ */ jsxs6(
2259
+ return /* @__PURE__ */ jsxs7(
824
2260
  "section",
825
2261
  {
826
2262
  ...rootProps,
@@ -829,8 +2265,8 @@ function KeepCollectionContent({
829
2265
  "data-state": getCollectionState(list),
830
2266
  "data-loading": list.isLoading || list.isMutating ? "true" : void 0,
831
2267
  children: [
832
- /* @__PURE__ */ jsxs6("div", { children: [
833
- enabled.search ? /* @__PURE__ */ jsx11(
2268
+ /* @__PURE__ */ jsxs7("div", { children: [
2269
+ enabled.search ? /* @__PURE__ */ jsx13(
834
2270
  KeepSearchInput,
835
2271
  {
836
2272
  value: searchValue,
@@ -840,7 +2276,7 @@ function KeepCollectionContent({
840
2276
  }
841
2277
  }
842
2278
  ) : null,
843
- enabled.sort ? /* @__PURE__ */ jsx11(
2279
+ enabled.sort ? /* @__PURE__ */ jsx13(
844
2280
  KeepSortSelect,
845
2281
  {
846
2282
  value: sortToValue(sort),
@@ -850,7 +2286,7 @@ function KeepCollectionContent({
850
2286
  }
851
2287
  }
852
2288
  ) : null,
853
- enabled.tagFilter ? /* @__PURE__ */ jsx11(
2289
+ enabled.tagFilter ? /* @__PURE__ */ jsx13(
854
2290
  KeepTagFilter,
855
2291
  {
856
2292
  query,
@@ -862,18 +2298,19 @@ function KeepCollectionContent({
862
2298
  }
863
2299
  ) : null
864
2300
  ] }),
865
- /* @__PURE__ */ jsx11(
2301
+ /* @__PURE__ */ jsx13(
866
2302
  KeepList,
867
2303
  {
868
2304
  query: resolvedQuery,
869
2305
  renderItem,
870
2306
  itemCardProps,
2307
+ layout,
871
2308
  loading,
872
2309
  empty,
873
2310
  error
874
2311
  }
875
2312
  ),
876
- enabled.pagination ? /* @__PURE__ */ jsx11(
2313
+ enabled.pagination ? /* @__PURE__ */ jsx13(
877
2314
  KeepPagination,
878
2315
  {
879
2316
  totalCount: list.totalCount,
@@ -882,7 +2319,7 @@ function KeepCollectionContent({
882
2319
  onPageChange: (nextPage) => setPage(nextPage)
883
2320
  }
884
2321
  ) : null,
885
- enabled.bulkActions ? /* @__PURE__ */ jsx11(KeepBulkActions, { query: resolvedQuery }) : null
2322
+ enabled.bulkActions ? /* @__PURE__ */ jsx13(KeepBulkActions, { query: resolvedQuery }) : null
886
2323
  ]
887
2324
  }
888
2325
  );
@@ -894,16 +2331,23 @@ function getCollectionState(list) {
894
2331
  return "ready";
895
2332
  }
896
2333
 
2334
+ // src/KeepLayout.tsx
2335
+ import { jsx as jsx14 } from "react/jsx-runtime";
2336
+ function KeepLayout({ layout = "list", children, style, ...props }) {
2337
+ const layoutStyle = layout === "grid" ? { display: "grid", gap: "1rem", gridTemplateColumns: "repeat(auto-fit, minmax(16rem, 1fr))" } : layout === "compact" ? { display: "grid", gap: "0.5rem", gridTemplateColumns: "repeat(auto-fit, minmax(12rem, 1fr))" } : { display: "flex", flexDirection: "column", gap: "1rem" };
2338
+ return /* @__PURE__ */ jsx14("div", { ...props, style: { ...layoutStyle, ...style }, "data-layout": layout, children });
2339
+ }
2340
+
897
2341
  // src/KeepNoteEditor.tsx
898
2342
  import { useKeepItem as useKeepItem3 } from "@keepkit/core/react";
899
2343
  import {
900
2344
  isValidElement as isValidElement5,
901
2345
  useCallback as useCallback2,
902
- useEffect as useEffect2,
903
- useRef as useRef2,
904
- useState as useState6
2346
+ useEffect as useEffect3,
2347
+ useRef as useRef3,
2348
+ useState as useState7
905
2349
  } from "react";
906
- import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
2350
+ import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
907
2351
  function KeepNoteEditor({
908
2352
  item,
909
2353
  label,
@@ -923,11 +2367,11 @@ function KeepNoteEditor({
923
2367
  const itemState = useKeepItem3(item);
924
2368
  const { error, isMutating, item: savedItem, updateNote } = itemState;
925
2369
  const contentChildren = asChild && isValidElement5(children) ? void 0 : children;
926
- const [note, setNote] = useState6(item.note ?? "");
2370
+ const [note, setNote] = useState7(item.note ?? "");
927
2371
  const baselineNote = savedItem?.note ?? item.note ?? "";
928
2372
  const isDirty = note !== baselineNote;
929
- const lastSavedNoteRef = useRef2(void 0);
930
- useEffect2(() => setNote(baselineNote), [baselineNote]);
2373
+ const lastSavedNoteRef = useRef3(void 0);
2374
+ useEffect3(() => setNote(baselineNote), [baselineNote]);
931
2375
  const save = useCallback2(async () => {
932
2376
  const nextNote = note.trim() || void 0;
933
2377
  try {
@@ -939,7 +2383,7 @@ function KeepNoteEditor({
939
2383
  throw error2;
940
2384
  }
941
2385
  }, [note, onSaveError, onSaved, updateNote]);
942
- useEffect2(() => {
2386
+ useEffect3(() => {
943
2387
  if (!isDirty || debounceMs <= 0 || lastSavedNoteRef.current === note) return;
944
2388
  const timer = window.setTimeout(() => void save().catch(() => void 0), debounceMs);
945
2389
  return () => window.clearTimeout(timer);
@@ -953,10 +2397,10 @@ function KeepNoteEditor({
953
2397
  error,
954
2398
  save
955
2399
  };
956
- const body = render ? render(state) : typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? /* @__PURE__ */ jsxs7(Fragment5, { children: [
957
- /* @__PURE__ */ jsxs7("label", { children: [
2400
+ const body = render ? render(state) : typeof contentChildren === "function" ? contentChildren(state) : contentChildren ?? /* @__PURE__ */ jsxs8(Fragment5, { children: [
2401
+ /* @__PURE__ */ jsxs8("label", { children: [
958
2402
  label ?? defaultLabel,
959
- /* @__PURE__ */ jsx12(
2403
+ /* @__PURE__ */ jsx15(
960
2404
  "textarea",
961
2405
  {
962
2406
  value: note,
@@ -972,14 +2416,14 @@ function KeepNoteEditor({
972
2416
  }
973
2417
  )
974
2418
  ] }),
975
- /* @__PURE__ */ jsx12("button", { type: "submit", disabled: isMutating, "aria-busy": isMutating, children: saveLabel ?? defaultSaveLabel })
2419
+ /* @__PURE__ */ jsx15("button", { type: "submit", disabled: isMutating, "aria-busy": isMutating, children: saveLabel ?? defaultSaveLabel })
976
2420
  ] });
977
2421
  const handleSubmit = (event) => {
978
2422
  event.preventDefault();
979
2423
  void save().catch(() => void 0);
980
2424
  };
981
2425
  if (!asChild) {
982
- return /* @__PURE__ */ jsx12(
2426
+ return /* @__PURE__ */ jsx15(
983
2427
  "form",
984
2428
  {
985
2429
  ...formProps,
@@ -1010,10 +2454,159 @@ function KeepNoteEditor({
1010
2454
  );
1011
2455
  }
1012
2456
 
2457
+ // src/KeepSyncRecoveryDialog.tsx
2458
+ import { useKeepContext as useKeepContext3 } from "@keepkit/core/react";
2459
+ import { useEffect as useEffect4, useState as useState8 } from "react";
2460
+ import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
2461
+ function KeepSyncRecoveryDialog({
2462
+ open,
2463
+ onOpenChange,
2464
+ conflicts,
2465
+ onManualMerge,
2466
+ backup,
2467
+ showBackupControls = true,
2468
+ title,
2469
+ children,
2470
+ className,
2471
+ ...props
2472
+ }) {
2473
+ const context = useKeepContext3();
2474
+ const closeLabel = useUiLabel("close");
2475
+ const defaultDialogTitle = useUiLabel("resolveSync");
2476
+ const dialogTitle = title ?? defaultDialogTitle;
2477
+ const conflictLabel = useUiLabel("syncConflict");
2478
+ const keepLocalLabel = useUiLabel("keepLocal");
2479
+ const useServerLabel = useUiLabel("useServer");
2480
+ const manualMergeLabel = useUiLabel("manualMerge");
2481
+ const backupRecoveryLabel = useUiLabel("backupRecovery");
2482
+ const backupRecoveryDescription = useUiLabel("backupRecoveryDescription");
2483
+ const errorLabel = useUiLabel("error");
2484
+ const conflictList = conflicts ?? context.syncState.conflicts ?? [];
2485
+ const hasRecovery = conflictList.length > 0 || context.syncState.status === "error" || Boolean(context.error);
2486
+ const [dismissed, setDismissed] = useState8(false);
2487
+ const [busyId, setBusyId] = useState8();
2488
+ const [error, setError] = useState8();
2489
+ useEffect4(() => {
2490
+ if (hasRecovery) setDismissed(false);
2491
+ }, [hasRecovery]);
2492
+ const isOpen = open ?? (hasRecovery && !dismissed);
2493
+ if (!isOpen) return null;
2494
+ const close = () => {
2495
+ setDismissed(true);
2496
+ onOpenChange?.(false);
2497
+ };
2498
+ async function resolve(conflict, resolution) {
2499
+ setError(void 0);
2500
+ setBusyId(conflict.id);
2501
+ try {
2502
+ const merged = resolution === "manual" ? await onManualMerge?.(conflict) : void 0;
2503
+ if (resolution === "manual" && !merged) throw new Error("A manual merge result is required.");
2504
+ await context.resolveSyncConflict(conflict.id, resolution, merged);
2505
+ } catch (cause) {
2506
+ setError(cause);
2507
+ } finally {
2508
+ setBusyId(void 0);
2509
+ }
2510
+ }
2511
+ return /* @__PURE__ */ jsxs9(
2512
+ "section",
2513
+ {
2514
+ ...props,
2515
+ className,
2516
+ role: "dialog",
2517
+ "aria-modal": "true",
2518
+ "aria-labelledby": "keepkit-sync-recovery-title",
2519
+ "data-keepkit": "sync-recovery",
2520
+ "data-state": conflictList.length > 0 ? "conflict" : "error",
2521
+ children: [
2522
+ /* @__PURE__ */ jsxs9("header", { children: [
2523
+ /* @__PURE__ */ jsx16("h2", { id: "keepkit-sync-recovery-title", children: dialogTitle }),
2524
+ /* @__PURE__ */ jsx16("button", { type: "button", onClick: close, "aria-label": closeLabel, children: closeLabel })
2525
+ ] }),
2526
+ children,
2527
+ conflictList.length > 0 ? /* @__PURE__ */ jsxs9("div", { children: [
2528
+ /* @__PURE__ */ jsx16("p", { children: conflictLabel }),
2529
+ conflictList.map((conflict) => /* @__PURE__ */ jsxs9("article", { "data-conflict-id": conflict.id, children: [
2530
+ /* @__PURE__ */ jsx16("h3", { children: getMetaTitle(conflict.operation.item?.meta) ?? conflict.id }),
2531
+ /* @__PURE__ */ jsxs9("div", { children: [
2532
+ /* @__PURE__ */ jsx16("button", { type: "button", onClick: () => void resolve(conflict, "local"), disabled: busyId !== void 0, children: keepLocalLabel }),
2533
+ /* @__PURE__ */ jsx16("button", { type: "button", onClick: () => void resolve(conflict, "remote"), disabled: busyId !== void 0, children: useServerLabel }),
2534
+ /* @__PURE__ */ jsx16(
2535
+ "button",
2536
+ {
2537
+ type: "button",
2538
+ onClick: () => void resolve(conflict, "manual"),
2539
+ disabled: busyId !== void 0 || !onManualMerge,
2540
+ children: manualMergeLabel
2541
+ }
2542
+ )
2543
+ ] })
2544
+ ] }, conflict.id))
2545
+ ] }) : null,
2546
+ context.syncState.status === "error" || context.error ? /* @__PURE__ */ jsxs9("section", { "data-recovery": "backup", children: [
2547
+ /* @__PURE__ */ jsx16("h3", { children: backupRecoveryLabel }),
2548
+ /* @__PURE__ */ jsx16("p", { children: backupRecoveryDescription }),
2549
+ backup ?? (showBackupControls ? /* @__PURE__ */ jsx16(KeepBackup, {}) : null)
2550
+ ] }) : null,
2551
+ error ? /* @__PURE__ */ jsx16("p", { role: "alert", children: error instanceof Error ? error.message : errorLabel }) : null
2552
+ ]
2553
+ }
2554
+ );
2555
+ }
2556
+
2557
+ // src/KeepSyncStatusBanner.tsx
2558
+ import { useKeepContext as useKeepContext4 } from "@keepkit/core/react";
2559
+ import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
2560
+ function KeepSyncStatusBanner({
2561
+ onRetry,
2562
+ onResolveConflicts,
2563
+ children,
2564
+ className,
2565
+ ...props
2566
+ }) {
2567
+ const context = useKeepContext4();
2568
+ const retryLabel = useUiLabel("retrySync");
2569
+ const resolveLabel = useUiLabel("resolveSync");
2570
+ const conflictLabel = useUiLabel("syncConflict");
2571
+ const pendingLabel = useUiLabel("syncPending");
2572
+ const syncedLabel = useUiLabel("syncSynced");
2573
+ const status = context.syncState.status;
2574
+ const hasConflicts = (context.syncState.conflicts?.length ?? 0) > 0 || context.syncState.conflictIds.length > 0;
2575
+ if (status === "idle" && !hasConflicts) return null;
2576
+ const message = children ?? (status === "error" ? getErrorMessage2(context.syncState.error) : status === "conflict" || hasConflicts ? conflictLabel : status === "pending" || status === "syncing" ? pendingLabel : syncedLabel);
2577
+ const role = status === "error" || status === "conflict" || hasConflicts ? "alert" : "status";
2578
+ const retry = async () => {
2579
+ if (onRetry) {
2580
+ await onRetry();
2581
+ return;
2582
+ }
2583
+ await context.flushSync();
2584
+ };
2585
+ return /* @__PURE__ */ jsxs10(
2586
+ "aside",
2587
+ {
2588
+ ...props,
2589
+ className,
2590
+ role: props.role ?? role,
2591
+ "aria-live": props["aria-live"] ?? "polite",
2592
+ "data-keepkit": "sync-status",
2593
+ "data-state": status,
2594
+ children: [
2595
+ /* @__PURE__ */ jsx17("p", { children: message }),
2596
+ status === "error" || status === "pending" || status === "syncing" ? /* @__PURE__ */ jsx17("button", { type: "button", onClick: () => void retry(), disabled: context.isMutating, children: retryLabel }) : null,
2597
+ hasConflicts ? /* @__PURE__ */ jsx17("button", { type: "button", onClick: onResolveConflicts, disabled: !onResolveConflicts, children: resolveLabel }) : null
2598
+ ]
2599
+ }
2600
+ );
2601
+ }
2602
+ function getErrorMessage2(error) {
2603
+ return error instanceof Error ? error.message : "Sync failed.";
2604
+ }
2605
+
1013
2606
  // src/KeepTagEditor.tsx
1014
2607
  import { useKeepItem as useKeepItem4 } from "@keepkit/core/react";
1015
- import { useCallback as useCallback3, useEffect as useEffect3, useState as useState7 } from "react";
1016
- import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
2608
+ import { useCallback as useCallback3, useEffect as useEffect5, useState as useState9 } from "react";
2609
+ import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
1017
2610
  function KeepTagEditor({
1018
2611
  item,
1019
2612
  availableTags = [],
@@ -1026,9 +2619,9 @@ function KeepTagEditor({
1026
2619
  const removeLabel = useUiLabel("remove");
1027
2620
  const applyTagsLabel = useUiLabel("applyTags");
1028
2621
  const itemState = useKeepItem4(item);
1029
- const [tags, setTags] = useState7(item.tags ?? []);
1030
- const [input, setInput] = useState7("");
1031
- useEffect3(() => setTags(itemState.item?.tags ?? item.tags ?? []), [item.tags, itemState.item?.tags]);
2622
+ const [tags, setTags] = useState9(item.tags ?? []);
2623
+ const [input, setInput] = useState9("");
2624
+ useEffect5(() => setTags(itemState.item?.tags ?? item.tags ?? []), [item.tags, itemState.item?.tags]);
1032
2625
  const save = useCallback3(async () => {
1033
2626
  const nextTags = normalizeUiTags(tags);
1034
2627
  try {
@@ -1044,10 +2637,10 @@ function KeepTagEditor({
1044
2637
  setTags(normalizeUiTags([...tags, tag]));
1045
2638
  setInput("");
1046
2639
  };
1047
- const body = render ? render({ tags, setTags, save, isSaving: itemState.isMutating }) : /* @__PURE__ */ jsxs8(Fragment6, { children: [
1048
- /* @__PURE__ */ jsxs8("label", { children: [
2640
+ const body = render ? render({ tags, setTags, save, isSaving: itemState.isMutating }) : /* @__PURE__ */ jsxs11(Fragment6, { children: [
2641
+ /* @__PURE__ */ jsxs11("label", { children: [
1049
2642
  tagsLabel,
1050
- /* @__PURE__ */ jsx13(
2643
+ /* @__PURE__ */ jsx18(
1051
2644
  "input",
1052
2645
  {
1053
2646
  value: input,
@@ -1066,14 +2659,14 @@ function KeepTagEditor({
1066
2659
  }
1067
2660
  )
1068
2661
  ] }),
1069
- availableTags.length > 0 ? /* @__PURE__ */ jsx13("datalist", { id: `keep-tags-${item.id}`, children: availableTags.map((tag) => /* @__PURE__ */ jsx13("option", { value: tag }, tag)) }) : null,
1070
- /* @__PURE__ */ jsx13("ul", { "aria-label": tagsLabel, children: tags.map((tag) => /* @__PURE__ */ jsxs8("li", { children: [
2662
+ availableTags.length > 0 ? /* @__PURE__ */ jsx18("datalist", { id: `keep-tags-${item.id}`, children: availableTags.map((tag) => /* @__PURE__ */ jsx18("option", { value: tag }, tag)) }) : null,
2663
+ /* @__PURE__ */ jsx18("ul", { "aria-label": tagsLabel, children: tags.map((tag) => /* @__PURE__ */ jsxs11("li", { children: [
1071
2664
  tag,
1072
- /* @__PURE__ */ jsx13("button", { type: "button", onClick: () => setTags(tags.filter((current) => current !== tag)), children: removeLabel })
2665
+ /* @__PURE__ */ jsx18("button", { type: "button", onClick: () => setTags(tags.filter((current) => current !== tag)), children: removeLabel })
1073
2666
  ] }, tag)) }),
1074
- /* @__PURE__ */ jsx13("button", { type: "submit", disabled: itemState.isMutating, "aria-busy": itemState.isMutating, children: applyTagsLabel })
2667
+ /* @__PURE__ */ jsx18("button", { type: "submit", disabled: itemState.isMutating, "aria-busy": itemState.isMutating, children: applyTagsLabel })
1075
2668
  ] });
1076
- return /* @__PURE__ */ jsx13(
2669
+ return /* @__PURE__ */ jsx18(
1077
2670
  "form",
1078
2671
  {
1079
2672
  ...props,
@@ -1090,10 +2683,24 @@ function KeepTagEditor({
1090
2683
  );
1091
2684
  }
1092
2685
 
2686
+ // src/KeepUndo.tsx
2687
+ import { useKeepContext as useKeepContext5 } from "@keepkit/core/react";
2688
+ import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
2689
+ function KeepUndo({ children, label, ...props }) {
2690
+ const context = useKeepContext5();
2691
+ const message = useUiLabel("undoAvailable");
2692
+ const undoLabel = useUiLabel("undo");
2693
+ if (!context.undo.canUndo) return null;
2694
+ return /* @__PURE__ */ jsxs12("div", { ...props, role: "status", "aria-live": "polite", "data-state": "available", children: [
2695
+ children ?? message,
2696
+ /* @__PURE__ */ jsx19("button", { type: "button", onClick: () => void context.undoLastRemoval(), children: label ?? undoLabel })
2697
+ ] });
2698
+ }
2699
+
1093
2700
  // src/status.tsx
1094
- import { useKeepContext as useKeepContext2 } from "@keepkit/core/react";
1095
- import { isValidElement as isValidElement6, useEffect as useEffect4, useRef as useRef3, useState as useState8 } from "react";
1096
- import { Fragment as Fragment7, jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
2701
+ import { useKeepContext as useKeepContext6 } from "@keepkit/core/react";
2702
+ import { isValidElement as isValidElement6, useEffect as useEffect6, useRef as useRef4, useState as useState10 } from "react";
2703
+ import { Fragment as Fragment7, jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
1097
2704
  function KeepEmptyState({
1098
2705
  title,
1099
2706
  description,
@@ -1105,9 +2712,9 @@ function KeepEmptyState({
1105
2712
  }) {
1106
2713
  const defaultTitle = useUiLabel("noItems").replace(/\.$/, "");
1107
2714
  const contentChildren = asChild && isValidElement6(children) ? void 0 : children;
1108
- const body = contentChildren ?? /* @__PURE__ */ jsxs9(Fragment7, { children: [
1109
- /* @__PURE__ */ jsx14("h2", { children: title ?? defaultTitle }),
1110
- description ? /* @__PURE__ */ jsx14("p", { children: description }) : null,
2715
+ const body = contentChildren ?? /* @__PURE__ */ jsxs13(Fragment7, { children: [
2716
+ /* @__PURE__ */ jsx20("h2", { children: title ?? defaultTitle }),
2717
+ description ? /* @__PURE__ */ jsx20("p", { children: description }) : null,
1111
2718
  action
1112
2719
  ] });
1113
2720
  return renderRoot(asChild, children, { ...rootProps, className, "data-state": "empty" }, body, "KeepEmptyState");
@@ -1121,10 +2728,10 @@ function KeepStatus({
1121
2728
  className,
1122
2729
  ...rootProps
1123
2730
  }) {
1124
- const context = useKeepContext2();
2731
+ const context = useKeepContext6();
1125
2732
  const contentChildren = asChild && isValidElement6(children) ? void 0 : children;
1126
2733
  const resolvedStatus = status ?? getDerivedStatus(context);
1127
- const defaultLabel = useUiLabel(getStatusLabelKey2(resolvedStatus));
2734
+ const defaultLabel = useUiLabel(getStatusLabelKey3(resolvedStatus));
1128
2735
  const state = {
1129
2736
  status: resolvedStatus,
1130
2737
  error: context.error,
@@ -1149,13 +2756,13 @@ function KeepStatus({
1149
2756
  );
1150
2757
  }
1151
2758
  function KeepAnnouncements({ messages, ...props }) {
1152
- const context = useKeepContext2();
2759
+ const context = useKeepContext6();
1153
2760
  const savedMessage = useUiLabel("savedMessage", messages?.save);
1154
2761
  const removedMessage = useUiLabel("removedMessage", messages?.remove);
1155
2762
  const noteSavedMessage = useUiLabel("noteSavedMessage", messages?.note);
1156
- const [message, setMessage] = useState8("");
1157
- const lastChangeRef = useRef3(void 0);
1158
- useEffect4(() => {
2763
+ const [message, setMessage] = useState10("");
2764
+ const lastChangeRef = useRef4(void 0);
2765
+ useEffect6(() => {
1159
2766
  const change = context.lastChange;
1160
2767
  if (!change || change === lastChangeRef.current) return;
1161
2768
  lastChangeRef.current = change;
@@ -1163,7 +2770,7 @@ function KeepAnnouncements({ messages, ...props }) {
1163
2770
  else if (change.action === "remove" || change.action === "removeBatch") setMessage(removedMessage);
1164
2771
  else if (change.action === "updateNote") setMessage(noteSavedMessage);
1165
2772
  }, [context.lastChange, noteSavedMessage, removedMessage, savedMessage]);
1166
- return /* @__PURE__ */ jsx14(
2773
+ return /* @__PURE__ */ jsx20(
1167
2774
  "div",
1168
2775
  {
1169
2776
  ...props,
@@ -1184,7 +2791,7 @@ function getDerivedStatus(context) {
1184
2791
  if (context.isHydrated && context.items.length === 0) return "empty";
1185
2792
  return "idle";
1186
2793
  }
1187
- function getStatusLabelKey2(status) {
2794
+ function getStatusLabelKey3(status) {
1188
2795
  if (status === "empty") return "noItems";
1189
2796
  if (status === "loading") return "loadingItems";
1190
2797
  if (status === "error") return "error";
@@ -1194,10 +2801,11 @@ function getStatusLabelKey2(status) {
1194
2801
  }
1195
2802
 
1196
2803
  // src/index.tsx
2804
+ import { createAuthenticatedSyncKit } from "@keepkit/core/core";
1197
2805
  import {
1198
2806
  KeepErrorBoundary as KeepErrorBoundary3,
1199
2807
  KeepProvider,
1200
- useKeepContext as useKeepContext3,
2808
+ useKeepContext as useKeepContext7,
1201
2809
  useKeepItem as useKeepItem5,
1202
2810
  useKeepList as useKeepList5,
1203
2811
  useKeepShortcut
@@ -1212,7 +2820,7 @@ import {
1212
2820
  LocalStorageSyncQueueAdapter,
1213
2821
  SyncStorageAdapter
1214
2822
  } from "@keepkit/core/storage";
1215
- import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
2823
+ import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
1216
2824
  function KeepKitProvider({
1217
2825
  labels,
1218
2826
  locale,
@@ -1220,16 +2828,16 @@ function KeepKitProvider({
1220
2828
  children,
1221
2829
  ...providerProps
1222
2830
  }) {
1223
- return /* @__PURE__ */ jsx15(KeepUiProvider, { labels, locale, labelResolver, children: /* @__PURE__ */ jsxs10(CoreKeepProvider, { ...providerProps, children: [
2831
+ return /* @__PURE__ */ jsx21(KeepUiProvider, { labels, locale, labelResolver, children: /* @__PURE__ */ jsxs14(CoreKeepProvider, { ...providerProps, children: [
1224
2832
  children,
1225
- /* @__PURE__ */ jsx15(KeepAnnouncements, {})
2833
+ /* @__PURE__ */ jsx21(KeepAnnouncements, {})
1226
2834
  ] }) });
1227
2835
  }
1228
2836
  function createKeepKit(options = {}) {
1229
2837
  const { labels, locale, labelResolver, getTitle, getImageProps, ...coreOptions } = options;
1230
2838
  const coreKit = createCoreKeepKit(coreOptions);
1231
2839
  return {
1232
- Provider: (props) => /* @__PURE__ */ jsx15(
2840
+ Provider: (props) => /* @__PURE__ */ jsx21(
1233
2841
  KeepKitProvider,
1234
2842
  {
1235
2843
  ...coreOptions,
@@ -1239,9 +2847,9 @@ function createKeepKit(options = {}) {
1239
2847
  ...props
1240
2848
  }
1241
2849
  ),
1242
- Button: (props) => /* @__PURE__ */ jsx15(KeepButton, { ...props }),
1243
- Backup: (props) => /* @__PURE__ */ jsx15(KeepBackup, { ...props }),
1244
- Collection: (props) => /* @__PURE__ */ jsx15(
2850
+ Button: (props) => /* @__PURE__ */ jsx21(KeepButton, { ...props }),
2851
+ Backup: (props) => /* @__PURE__ */ jsx21(KeepBackup, { ...props }),
2852
+ Collection: (props) => /* @__PURE__ */ jsx21(
1245
2853
  KeepCollection,
1246
2854
  {
1247
2855
  ...props,
@@ -1272,29 +2880,40 @@ export {
1272
2880
  KeepErrorBoundary3 as KeepErrorBoundary,
1273
2881
  KeepItemCard,
1274
2882
  KeepItemCheckbox,
2883
+ KeepItemStatusBadge,
1275
2884
  KeepKitProvider,
2885
+ KeepLayout,
1276
2886
  KeepList,
1277
2887
  KeepNoteEditor,
1278
2888
  KeepPagination,
1279
2889
  KeepProvider,
2890
+ KeepPruneStaleButton,
1280
2891
  KeepSearchInput,
1281
2892
  KeepSortSelect,
2893
+ KeepStaleNotice,
1282
2894
  KeepStatus,
2895
+ KeepSyncRecoveryDialog,
2896
+ KeepSyncStatusBanner,
1283
2897
  KeepTagEditor,
1284
2898
  KeepTagFilter,
1285
2899
  KeepUiProvider,
2900
+ KeepUndo,
1286
2901
  LocalStorageAdapter,
1287
2902
  LocalStorageSyncQueueAdapter,
1288
2903
  SyncStorageAdapter,
2904
+ createAuthenticatedSyncKit,
1289
2905
  createBrowserStorageAdapter,
1290
2906
  createKeepKit,
2907
+ createNextPagesRouterAdapter,
1291
2908
  createStorageAdapter,
2909
+ getKeepLocaleLabels,
1292
2910
  isAllSelected,
1293
2911
  toggleSelectAll,
1294
- useKeepContext3 as useKeepContext,
2912
+ useKeepContext7 as useKeepContext,
1295
2913
  useKeepItem5 as useKeepItem,
1296
2914
  useKeepList5 as useKeepList,
1297
2915
  useKeepShortcut,
1298
- useKeepUiLabels
2916
+ useKeepUiLabels,
2917
+ useKeepUrlSync
1299
2918
  };
1300
2919
  //# sourceMappingURL=index.js.map