diff --git a/src/lang/ar-ye.json b/src/lang/ar-ye.json
index dddeeface..079faa8e5 100644
--- a/src/lang/ar-ye.json
+++ b/src/lang/ar-ye.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/be-by.json b/src/lang/be-by.json
index fcd9de980..798a5f1f3 100644
--- a/src/lang/be-by.json
+++ b/src/lang/be-by.json
@@ -455,5 +455,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/bn-bd.json b/src/lang/bn-bd.json
index ff1e6a85d..7e99886ac 100644
--- a/src/lang/bn-bd.json
+++ b/src/lang/bn-bd.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/cs-cz.json b/src/lang/cs-cz.json
index 721c3329a..e94ff38b0 100644
--- a/src/lang/cs-cz.json
+++ b/src/lang/cs-cz.json
@@ -454,5 +454,38 @@
"keywords": "Klíčová slova",
"author": "Autor",
"filtered by": "Filtrováno podle",
- "clean install state": "Čistý stav instalace"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/de-de.json b/src/lang/de-de.json
index 44c35b38e..81e5c0fb6 100644
--- a/src/lang/de-de.json
+++ b/src/lang/de-de.json
@@ -454,5 +454,38 @@
"keywords": "Schlüsselwörter",
"author": "Autor",
"filtered by": "Gefiltert nach",
- "clean install state": "Sauberer Installationsstatus"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/en-us.json b/src/lang/en-us.json
index b2fcbae24..6dbb8e75c 100644
--- a/src/lang/en-us.json
+++ b/src/lang/en-us.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/es-sv.json b/src/lang/es-sv.json
index b05eb6b57..43483cc4c 100644
--- a/src/lang/es-sv.json
+++ b/src/lang/es-sv.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/fr-fr.json b/src/lang/fr-fr.json
index ea5fe18c7..d05d5007b 100644
--- a/src/lang/fr-fr.json
+++ b/src/lang/fr-fr.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/he-il.json b/src/lang/he-il.json
index 28cbf14e0..62bacbda6 100644
--- a/src/lang/he-il.json
+++ b/src/lang/he-il.json
@@ -455,5 +455,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/hi-in.json b/src/lang/hi-in.json
index dd19f0f85..95fbee698 100644
--- a/src/lang/hi-in.json
+++ b/src/lang/hi-in.json
@@ -455,5 +455,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/hu-hu.json b/src/lang/hu-hu.json
index dbfede25e..5d23ca502 100644
--- a/src/lang/hu-hu.json
+++ b/src/lang/hu-hu.json
@@ -454,5 +454,38 @@
"keywords": "Kulcsszavak",
"author": "Szerző",
"filtered by": "Szűrési szempont",
- "clean install state": "Tiszta telepítési állapot"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/id-id.json b/src/lang/id-id.json
index 63d478b06..bbcbc5785 100644
--- a/src/lang/id-id.json
+++ b/src/lang/id-id.json
@@ -455,5 +455,38 @@
"keywords": "Kata kunci",
"author": "Pembuat",
"filtered by": "Disaring oleh",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/ir-fa.json b/src/lang/ir-fa.json
index 95ca111c1..99274c11a 100644
--- a/src/lang/ir-fa.json
+++ b/src/lang/ir-fa.json
@@ -455,5 +455,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/it-it.json b/src/lang/it-it.json
index 9fbb2c7e5..f1960a29c 100644
--- a/src/lang/it-it.json
+++ b/src/lang/it-it.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/ja-jp.json b/src/lang/ja-jp.json
index 348172cfe..348fbc91c 100644
--- a/src/lang/ja-jp.json
+++ b/src/lang/ja-jp.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/ko-kr.json b/src/lang/ko-kr.json
index ae226c614..185b7aea6 100644
--- a/src/lang/ko-kr.json
+++ b/src/lang/ko-kr.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/ml-in.json b/src/lang/ml-in.json
index 56f551a6c..5d0c233b5 100644
--- a/src/lang/ml-in.json
+++ b/src/lang/ml-in.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/mm-unicode.json b/src/lang/mm-unicode.json
index b8b211fd8..175260b7b 100644
--- a/src/lang/mm-unicode.json
+++ b/src/lang/mm-unicode.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/mm-zawgyi.json b/src/lang/mm-zawgyi.json
index 5a57884a8..c310c6a1f 100644
--- a/src/lang/mm-zawgyi.json
+++ b/src/lang/mm-zawgyi.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/pl-pl.json b/src/lang/pl-pl.json
index f52669a16..9059bc685 100644
--- a/src/lang/pl-pl.json
+++ b/src/lang/pl-pl.json
@@ -454,5 +454,38 @@
"keywords": "Słowa kluczowe",
"author": "Autor",
"filtered by": "Filtrowane wg",
- "clean install state": "Stan czystej instalacji"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/pt-br.json b/src/lang/pt-br.json
index 87fef2e18..a0a33ccb3 100644
--- a/src/lang/pt-br.json
+++ b/src/lang/pt-br.json
@@ -454,5 +454,38 @@
"keywords": "Palavras-chave",
"author": "Autor",
"filtered by": "Filtrado por",
- "clean install state": "Estado de Instalação Limpa"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/pu-in.json b/src/lang/pu-in.json
index ff03fcb75..dbf06e1eb 100644
--- a/src/lang/pu-in.json
+++ b/src/lang/pu-in.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/ru-ru.json b/src/lang/ru-ru.json
index d7dcf31e7..5c2354729 100644
--- a/src/lang/ru-ru.json
+++ b/src/lang/ru-ru.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/tl-ph.json b/src/lang/tl-ph.json
index 1a7f24865..d87e885c9 100644
--- a/src/lang/tl-ph.json
+++ b/src/lang/tl-ph.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/tr-tr.json b/src/lang/tr-tr.json
index c1e7dd0b1..99e985945 100644
--- a/src/lang/tr-tr.json
+++ b/src/lang/tr-tr.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/uk-ua.json b/src/lang/uk-ua.json
index 4c69bd63e..446fad06a 100644
--- a/src/lang/uk-ua.json
+++ b/src/lang/uk-ua.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/uz-uz.json b/src/lang/uz-uz.json
index d39af9fb3..656f6ea11 100644
--- a/src/lang/uz-uz.json
+++ b/src/lang/uz-uz.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/vi-vn.json b/src/lang/vi-vn.json
index 3054398ea..a9144adc5 100644
--- a/src/lang/vi-vn.json
+++ b/src/lang/vi-vn.json
@@ -455,5 +455,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/zh-cn.json b/src/lang/zh-cn.json
index 92a1aa225..59592447f 100644
--- a/src/lang/zh-cn.json
+++ b/src/lang/zh-cn.json
@@ -454,5 +454,38 @@
"keywords": "关键字",
"author": "作者",
"filtered by": "过滤条件",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/zh-hant.json b/src/lang/zh-hant.json
index 990257b60..51ab570ae 100644
--- a/src/lang/zh-hant.json
+++ b/src/lang/zh-hant.json
@@ -454,5 +454,38 @@
"keywords": "關鍵字",
"author": "作者",
"filtered by": "篩選條件",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/lang/zh-tw.json b/src/lang/zh-tw.json
index 5f068530a..21f42f67a 100644
--- a/src/lang/zh-tw.json
+++ b/src/lang/zh-tw.json
@@ -454,5 +454,38 @@
"keywords": "Keywords",
"author": "Author",
"filtered by": "Filtered by",
- "clean install state": "Clean Install State"
+ "clean install state": "Clean Install State",
+ "backup created": "Backup created",
+ "restore completed": "Restore completed",
+ "restore will include": "This will restore",
+ "restore warning": "This action cannot be undone. Continue?",
+ "reload to apply": "Reload to apply changes?",
+ "reload app": "Reload app",
+ "preparing backup": "Preparing backup",
+ "collecting settings": "Collecting settings",
+ "collecting key bindings": "Collecting key bindings",
+ "collecting plugins": "Collecting plugin information",
+ "creating backup": "Creating backup file",
+ "validating backup": "Validating backup",
+ "restoring key bindings": "Restoring key bindings",
+ "restoring plugins": "Restoring plugins",
+ "restoring settings": "Restoring settings",
+ "legacy backup warning": "This is an older backup format. Some features may be limited.",
+ "checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted.",
+ "plugin not found": "Plugin not found in registry",
+ "paid plugin skipped": "Paid plugin - purchase not found",
+ "source not found": "Source file no longer exists",
+ "restored": "Restored",
+ "skipped": "Skipped",
+ "backup not valid object": "Backup file is not a valid object",
+ "backup no data": "Backup file contains no data to restore",
+ "backup legacy warning": "This is an older backup format (v1). Some features may be limited.",
+ "backup missing metadata": "Missing backup metadata - some info may be unavailable",
+ "backup checksum mismatch": "Checksum mismatch - backup file may have been modified or corrupted. Proceed with caution.",
+ "backup checksum verify failed": "Could not verify checksum",
+ "backup invalid settings": "Invalid settings format",
+ "backup invalid keybindings": "Invalid keyBindings format",
+ "backup invalid plugins": "Invalid installedPlugins format",
+ "issues found": "Issues found",
+ "error details": "Error details"
}
diff --git a/src/settings/backupRestore.js b/src/settings/backupRestore.js
index 522d572c8..a181c2d47 100644
--- a/src/settings/backupRestore.js
+++ b/src/settings/backupRestore.js
@@ -2,6 +2,8 @@ import fsOperation from "fileSystem";
import settingsPage from "components/settingsPage";
import toast from "components/toast";
import alert from "dialogs/alert";
+import confirm from "dialogs/confirm";
+import loader from "dialogs/loader";
import constants from "lib/constants";
import appSettings from "lib/settings";
import FileBrowser from "pages/fileBrowser";
@@ -9,6 +11,129 @@ import helpers from "utils/helpers";
import Uri from "utils/Uri";
import Url from "utils/Url";
+// Backup format version for future compatibility
+const BACKUP_VERSION = 2;
+
+/**
+ * CRC32 lookup table for checksum calculation
+ */
+const CRC32_TABLE = (() => {
+ const table = new Uint32Array(256);
+ for (let i = 0; i < 256; i++) {
+ let crc = i;
+ for (let j = 0; j < 8; j++) {
+ crc = crc & 1 ? 0xedb88320 ^ (crc >>> 1) : crc >>> 1;
+ }
+ table[i] = crc >>> 0;
+ }
+ return table;
+})();
+
+/**
+ * Generates a CRC32 checksum for data integrity verification
+ * More robust than simple hash for detecting corrupted data
+ * @param {string} data
+ * @returns {string}
+ */
+function generateChecksum(data) {
+ let crc = 0xffffffff;
+ for (let i = 0; i < data.length; i++) {
+ const byte = data.charCodeAt(i) & 0xff;
+ crc = CRC32_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);
+ }
+ return ((crc ^ 0xffffffff) >>> 0).toString(16).padStart(8, "0");
+}
+
+/**
+ * Validates the structure of a backup object
+ * Supports both v1 (legacy) and v2 (new) backup formats
+ * @param {object} backup
+ * @returns {{valid: boolean, errors: string[], warnings: string[], isLegacy: boolean}}
+ */
+function validateBackupStructure(backup) {
+ const errors = [];
+ const warnings = [];
+
+ if (!backup || typeof backup !== "object") {
+ errors.push(strings["backup not valid object"]);
+ return { valid: false, errors, warnings, isLegacy: false };
+ }
+
+ // Determine if this is a legacy (v1) backup
+ const isLegacy = !backup.version;
+
+ if (isLegacy) {
+ // Legacy backup (v1) - just needs settings or installedPlugins to be valid
+ const hasData =
+ backup.settings || backup.keyBindings || backup.installedPlugins;
+ if (!hasData) {
+ errors.push(strings["backup no data"]);
+ }
+ warnings.push(strings["backup legacy warning"]);
+ } else {
+ // Version 2+ backup
+ if (backup.version >= 2) {
+ if (!backup.metadata) {
+ warnings.push(strings["backup missing metadata"]);
+ }
+
+ // Verify checksum if present
+ if (backup.checksum) {
+ try {
+ const dataToCheck = JSON.stringify({
+ settings: backup.settings,
+ keyBindings: backup.keyBindings,
+ installedPlugins: backup.installedPlugins,
+ });
+ const expectedChecksum = generateChecksum(dataToCheck);
+ if (backup.checksum !== expectedChecksum) {
+ warnings.push(strings["backup checksum mismatch"]);
+ }
+ } catch (e) {
+ warnings.push(strings["backup checksum verify failed"]);
+ }
+ }
+ }
+ }
+
+ // Validate settings (both versions)
+ if (backup.settings !== undefined && typeof backup.settings !== "object") {
+ errors.push(strings["backup invalid settings"]);
+ }
+
+ // Validate keyBindings (both versions)
+ if (
+ backup.keyBindings !== undefined &&
+ typeof backup.keyBindings !== "object"
+ ) {
+ errors.push(strings["backup invalid keybindings"]);
+ }
+
+ // Validate installedPlugins (both versions)
+ if (
+ backup.installedPlugins !== undefined &&
+ !Array.isArray(backup.installedPlugins)
+ ) {
+ errors.push(strings["backup invalid plugins"]);
+ }
+
+ return { valid: errors.length === 0, errors, warnings, isLegacy };
+}
+
+/**
+ * Formats a date for backup filename
+ * @param {Date} date
+ * @returns {string}
+ */
+function formatDateForFilename(date) {
+ const year = date.getFullYear();
+ const month = String(date.getMonth() + 1).padStart(2, "0");
+ const day = String(date.getDate()).padStart(2, "0");
+ const hours = String(date.getHours()).padStart(2, "0");
+ const minutes = String(date.getMinutes()).padStart(2, "0");
+ return `${year}${month}${day}_${hours}${minutes}`;
+}
+
function backupRestore() {
const title =
strings.backup.capitalize() + "/" + strings.restore.capitalize();
@@ -46,35 +171,91 @@ function backupRestore() {
}
async function backup() {
+ const loaderDialog = loader.create(
+ strings.backup.capitalize(),
+ strings["preparing backup"],
+ );
+
try {
+ loaderDialog.show();
+ loaderDialog.setMessage(strings["collecting settings"]);
+
const settings = appSettings.value;
- const keyBindings = await fsOperation(KEYBINDING_FILE).readFile("json");
- const plugins = await fsOperation(window.PLUGIN_DIR).lsDir();
+
+ // Read keybindings with fallback
+ loaderDialog.setMessage(strings["collecting key bindings"]);
+ let keyBindings = null;
+ try {
+ const keybindingsFS = fsOperation(KEYBINDING_FILE);
+ if (await keybindingsFS.exists()) {
+ keyBindings = await keybindingsFS.readFile("json");
+ }
+ } catch (error) {
+ console.warn("Could not read keybindings:", error);
+ }
+
+ // Collect plugin information
+ loaderDialog.setMessage(strings["collecting plugins"]);
const installedPlugins = [];
- const installedPluginsWithSource = [];
+ const pluginDetails = [];
- for (const plugin of plugins) {
- try {
- const pluginJsonPath = Url.join(
- window.PLUGIN_DIR,
- plugin.name,
- "plugin.json",
- );
- const pluginJson = await fsOperation(pluginJsonPath).readFile("json");
+ try {
+ const pluginsDir = fsOperation(window.PLUGIN_DIR);
+ if (await pluginsDir.exists()) {
+ const plugins = await pluginsDir.lsDir();
- if (pluginJson.source) {
- installedPluginsWithSource.push(pluginJson.source);
- } else {
- installedPlugins.push(plugin.name);
+ for (const plugin of plugins) {
+ try {
+ const pluginJsonPath = Url.join(
+ window.PLUGIN_DIR,
+ plugin.name,
+ "plugin.json",
+ );
+ const pluginJson =
+ await fsOperation(pluginJsonPath).readFile("json");
+
+ // Store detailed plugin info for better restore
+ const pluginInfo = {
+ id: pluginJson.id || plugin.name,
+ name: pluginJson.name || plugin.name,
+ version: pluginJson.version || "unknown",
+ source: pluginJson.source || null,
+ };
+ pluginDetails.push(pluginInfo);
+
+ if (pluginJson.source) {
+ installedPlugins.push(pluginJson.source);
+ } else {
+ installedPlugins.push(pluginJson.id || plugin.name);
+ }
+ } catch (error) {
+ // Fallback to just plugin name
+ installedPlugins.push(plugin.name);
+ pluginDetails.push({
+ id: plugin.name,
+ name: plugin.name,
+ version: "unknown",
+ source: null,
+ });
+ }
}
- } catch (error) {
- installedPlugins.push(plugin.name);
}
+ } catch (error) {
+ console.warn("Could not read plugins directory:", error);
}
+ loaderDialog.hide();
+
+ // Get destination folder
const { url } = await FileBrowser("folder", strings["select folder"]);
- const backupFilename = "Acode.backup";
+ loaderDialog.show();
+ loaderDialog.setMessage(
+ strings["creating backup"] || "Creating backup file...",
+ );
+
+ const timestamp = formatDateForFilename(new Date());
+ const backupFilename = `Acode_backup_${timestamp}.backup`;
const backupDirname = "Backup";
const backupDir = Url.join(url, backupDirname);
const backupFile = Url.join(backupDir, backupFilename);
@@ -82,31 +263,62 @@ function backupRestore() {
const backupDirFS = fsOperation(backupDir);
const backupFileFS = fsOperation(backupFile);
+ // Create backup directory if needed
if (!(await backupDirFS.exists())) {
await backupStorageFS.createDirectory(backupDirname);
}
+ // Create backup file
if (!(await backupFileFS.exists())) {
await backupDirFS.createFile(backupFilename);
}
- const backupString = JSON.stringify({
+ // Prepare backup data with checksum
+ const backupData = {
+ settings,
+ keyBindings,
+ installedPlugins,
+ };
+
+ const checksum = generateChecksum(JSON.stringify(backupData));
+
+ const backupObject = {
+ version: BACKUP_VERSION,
+ metadata: {
+ createdAt: new Date().toISOString(),
+ appVersion: BuildInfo?.version || "unknown",
+ pluginCount: installedPlugins.length,
+ hasSettings: !!settings,
+ hasKeyBindings: !!keyBindings,
+ },
+ checksum,
settings,
keyBindings,
- installedPlugins: [...installedPlugins, ...installedPluginsWithSource],
- });
+ installedPlugins,
+ pluginDetails, // Extra detail for better restoration info
+ };
+ const backupString = JSON.stringify(backupObject, null, 2);
await backupFileFS.writeFile(backupString);
+ loaderDialog.destroy();
+
+ const message = [
+ strings["backup successful"],
+ `
${Uri.getVirtualAddress(backupFile)}
`,
+ `${strings.settings || "Settings"}: ✓`,
+ `${strings["key bindings"] || "Key Bindings"}: ${keyBindings ? "✓" : "-"}`,
+ `${strings.plugins || "Plugins"}: ${installedPlugins.length}`,
+ ].join("
");
+
+ alert(strings.success.toUpperCase(), message);
+ } catch (error) {
+ loaderDialog.destroy();
+ console.error("Backup error:", error);
alert(
- strings.success.toUpperCase(),
- `${strings["backup successful"]}\n${Uri.getVirtualAddress(
- backupFile,
- )}.`,
+ strings.error.toUpperCase(),
+ `${strings["error details"] || "Error"}: ${error.message || error}`,
);
- } catch (error) {
- console.error(error);
- toast(error);
}
}
@@ -115,93 +327,365 @@ function backupRestore() {
(data) => {
backupRestore.restore(data.uri);
},
- toast,
+ (error) => {
+ console.error("File picker error:", error);
+ toast(strings.error || "Error selecting file");
+ },
"application/octet-stream",
);
}
}
backupRestore.restore = async function (url) {
+ const loaderDialog = loader.create(
+ strings.restore.capitalize(),
+ strings["please wait..."],
+ );
+
+ const restoreResults = {
+ settings: { attempted: false, success: false, error: null },
+ keyBindings: { attempted: false, success: false, error: null },
+ plugins: { attempted: false, success: [], failed: [], skipped: [] },
+ };
+
try {
- let fs = fsOperation(url);
- let backup = await fs.readFile("utf8");
+ loaderDialog.show();
+
+ // Read and parse backup file
+ const fs = fsOperation(url);
+ let backupContent;
try {
- backup = JSON.parse(backup);
+ backupContent = await fs.readFile("utf8");
} catch (error) {
- alert(strings.error.toUpperCase(), strings["invalid backup file"]);
- return;
+ throw new Error(`Could not read backup file: ${error.message}`);
}
+ let backup;
try {
- const text = JSON.stringify(backup.keyBindings, undefined, 2);
- await fsOperation(window.KEYBINDING_FILE).writeFile(text);
+ backup = JSON.parse(backupContent);
} catch (error) {
- console.error("Error restoring key bindings:", error);
+ loaderDialog.destroy();
+ alert(strings.error.toUpperCase(), strings["invalid backup file"]);
+ return;
+ }
+
+ // Validate backup structure
+ loaderDialog.setMessage(strings["validating backup"]);
+ const validation = validateBackupStructure(backup);
+
+ if (!validation.valid) {
+ loaderDialog.destroy();
+ const errorMessage = [
+ strings["invalid backup file"],
+ "",
+ `${strings["issues found"]}:`,
+ ...validation.errors.map((e) => `• ${e}`),
+ ].join("\n");
+ alert(strings.error.toUpperCase(), errorMessage);
+ return;
+ }
+
+ loaderDialog.hide();
+
+ // Show backup info and ask for confirmation
+ const backupInfo = backup.metadata || {};
+ const confirmParts = [
+ `${strings["restore will include"]}
`,
+ `${strings.settings}: ${backup.settings ? strings.yes : strings.no}
`,
+ `${strings["key bindings"]}: ${backup.keyBindings ? strings.yes : strings.no}
`,
+ `${strings.plugins}: ${backup.installedPlugins?.length || 0}
`,
+ ];
+
+ if (backupInfo.createdAt) {
+ confirmParts.push(
+ `
${strings["last modified"]}: ${new Date(backupInfo.createdAt).toLocaleString()}
`,
+ );
+ }
+
+ // Show warnings if any (legacy backup, checksum issues, etc.)
+ if (validation.warnings && validation.warnings.length > 0) {
+ confirmParts.push(`
${strings.warning}:
`);
+ for (const warning of validation.warnings) {
+ confirmParts.push(`- ${warning}
`);
+ }
+ }
+
+ confirmParts.push(`
${strings["restore warning"]}`);
+
+ const shouldContinue = await confirm(
+ strings.restore.capitalize(),
+ confirmParts.join(""),
+ true,
+ );
+
+ if (!shouldContinue) {
+ return;
}
- const { settings, installedPlugins } = backup;
+ // What to restore - restore everything available
+ const selectedOptions = [];
+ if (backup.settings) selectedOptions.push("settings");
+ if (backup.keyBindings) selectedOptions.push("keyBindings");
+ if (backup.installedPlugins?.length) selectedOptions.push("plugins");
+
+ loaderDialog.show();
- const { default: installPlugin } = await import("lib/installPlugin");
+ // Restore key bindings first (before settings, in case of reload)
+ if (selectedOptions.includes("keyBindings") && backup.keyBindings) {
+ restoreResults.keyBindings.attempted = true;
+ loaderDialog.setMessage(strings["restoring key bindings"]);
+
+ try {
+ const keybindingsFS = fsOperation(window.KEYBINDING_FILE);
+
+ // Ensure file exists
+ if (!(await keybindingsFS.exists())) {
+ const parentDir = fsOperation(DATA_STORAGE);
+ await parentDir.createFile(".key-bindings.json");
+ }
+
+ const text = JSON.stringify(backup.keyBindings, undefined, 2);
+ await keybindingsFS.writeFile(text);
+ restoreResults.keyBindings.success = true;
+ } catch (error) {
+ console.error("Error restoring key bindings:", error);
+ restoreResults.keyBindings.error = error.message;
+ }
+ }
// Restore plugins
- if (Array.isArray(installedPlugins)) {
- for (const id of installedPlugins) {
+ if (
+ selectedOptions.includes("plugins") &&
+ Array.isArray(backup.installedPlugins) &&
+ backup.installedPlugins.length > 0
+ ) {
+ restoreResults.plugins.attempted = true;
+ const { default: installPlugin } = await import("lib/installPlugin");
+
+ const totalPlugins = backup.installedPlugins.length;
+ let currentPlugin = 0;
+
+ for (const id of backup.installedPlugins) {
+ currentPlugin++;
+
+ if (!id) {
+ restoreResults.plugins.skipped.push({
+ id: "(empty)",
+ reason: "Empty plugin ID",
+ });
+ continue;
+ }
+
+ const pluginName =
+ backup.pluginDetails?.find((p) => p.id === id || p.source === id)
+ ?.name || id;
+
+ loaderDialog.setMessage(
+ `${strings["restoring plugins"]} (${currentPlugin}/${totalPlugins}): ${pluginName}`,
+ );
+
try {
- if (!id) continue;
if (
id.startsWith("content://") ||
id.startsWith("file://") ||
id.includes("/")
) {
- // Local plugin case - pass URI directly
- toast("Restoring plugins");
- await installPlugin(id);
+ // Local plugin case
+ try {
+ // Check if the source file still exists
+ const sourceFS = fsOperation(id);
+ if (!(await sourceFS.exists())) {
+ restoreResults.plugins.skipped.push({
+ id: pluginName,
+ reason: strings["source not found"],
+ });
+ continue;
+ }
+ await installPlugin(id);
+ restoreResults.plugins.success.push(pluginName);
+ } catch (error) {
+ restoreResults.plugins.failed.push({
+ id: pluginName,
+ reason: error.message,
+ });
+ }
} else {
// Remote plugin case - fetch from API
const pluginUrl = Url.join(constants.API_BASE, `plugin/${id}`);
- const remotePlugin = await fsOperation(pluginUrl)
- .readFile("json")
- .catch(() => null);
+ let remotePlugin = null;
+
+ try {
+ remotePlugin = await fsOperation(pluginUrl).readFile("json");
+ } catch (error) {
+ restoreResults.plugins.failed.push({
+ id: pluginName,
+ reason: strings["plugin not found"],
+ });
+ continue;
+ }
if (remotePlugin) {
let purchaseToken = null;
- if (Number.parseFloat(remotePlugin.price) > 0) {
+ const isPaid = Number.parseFloat(remotePlugin.price) > 0;
+
+ if (isPaid) {
try {
const [product] = await helpers.promisify(iap.getProducts, [
remotePlugin.sku,
]);
if (product) {
- async function getPurchase(sku) {
- const purchases = await helpers.promisify(
- iap.getPurchases,
- );
- const purchase = purchases.find((p) =>
- p.productIds.includes(sku),
- );
- return purchase;
- }
- const purchase = await getPurchase(product.productId);
+ const purchases = await helpers.promisify(iap.getPurchases);
+ const purchase = purchases.find((p) =>
+ p.productIds.includes(product.productId),
+ );
purchaseToken = purchase?.purchaseToken;
}
+
+ if (!purchaseToken) {
+ restoreResults.plugins.skipped.push({
+ id: pluginName,
+ reason: strings["paid plugin skipped"],
+ });
+ continue;
+ }
} catch (error) {
- helpers.error(error);
+ restoreResults.plugins.skipped.push({
+ id: pluginName,
+ reason: `Paid plugin - ${error.message}`,
+ });
+ continue;
}
}
- toast("Restoring plugins", 3000);
- await installPlugin(id, remotePlugin.name, purchaseToken);
+
+ try {
+ await installPlugin(id, remotePlugin.name, purchaseToken);
+ restoreResults.plugins.success.push(pluginName);
+ } catch (error) {
+ restoreResults.plugins.failed.push({
+ id: pluginName,
+ reason: error.message,
+ });
+ }
}
}
} catch (error) {
console.error(`Error restoring plugin ${id}:`, error);
+ restoreResults.plugins.failed.push({
+ id: pluginName,
+ reason: error.message,
+ });
+ }
+ }
+ }
+
+ // Restore settings last (may trigger reload)
+ if (selectedOptions.includes("settings") && backup.settings) {
+ restoreResults.settings.attempted = true;
+ loaderDialog.setMessage(strings["restoring settings"]);
+
+ try {
+ // Validate and merge settings carefully
+ const currentSettings = appSettings.value;
+ const restoredSettings = backup.settings;
+
+ // Only restore known settings keys to prevent issues with outdated backups
+ const validSettings = {};
+ for (const key of Object.keys(currentSettings)) {
+ if (key in restoredSettings) {
+ // Type check before applying
+ if (typeof restoredSettings[key] === typeof currentSettings[key]) {
+ validSettings[key] = restoredSettings[key];
+ }
+ }
}
+
+ await appSettings.update(validSettings, false);
+ restoreResults.settings.success = true;
+ } catch (error) {
+ console.error("Error restoring settings:", error);
+ restoreResults.settings.error = error.message;
}
}
- await appSettings.update(settings);
- location.reload();
+ loaderDialog.destroy();
+
+ // Build restore summary
+ const summaryParts = [
+ `${strings["restore completed"]}
`,
+ ];
+
+ if (restoreResults.settings.attempted) {
+ const status = restoreResults.settings.success
+ ? `✓ ${strings.restored}`
+ : `✗ ${strings.failed}`;
+ summaryParts.push(`${strings.settings}: ${status}
`);
+ }
+
+ if (restoreResults.keyBindings.attempted) {
+ const status = restoreResults.keyBindings.success
+ ? `✓ ${strings.restored}`
+ : `✗ ${strings.failed}`;
+ summaryParts.push(`${strings["key bindings"]}: ${status}
`);
+ }
+
+ if (restoreResults.plugins.attempted) {
+ summaryParts.push(`
${strings.plugins}
`);
+
+ if (restoreResults.plugins.success.length > 0) {
+ summaryParts.push(
+ `✓ ${strings.restored}: ${restoreResults.plugins.success.length}
`,
+ );
+ }
+
+ if (restoreResults.plugins.failed.length > 0) {
+ summaryParts.push(
+ `✗ ${strings.failed}: ${restoreResults.plugins.failed.length}
`,
+ );
+ for (const f of restoreResults.plugins.failed.slice(0, 3)) {
+ summaryParts.push(`- ${f.id}: ${f.reason}
`);
+ }
+ if (restoreResults.plugins.failed.length > 3) {
+ summaryParts.push(
+ `...${strings.more || "and"} ${restoreResults.plugins.failed.length - 3} ${strings.more || "more"}
`,
+ );
+ }
+ }
+
+ if (restoreResults.plugins.skipped.length > 0) {
+ summaryParts.push(
+ `${strings.skipped}: ${restoreResults.plugins.skipped.length}
`,
+ );
+ for (const s of restoreResults.plugins.skipped.slice(0, 3)) {
+ summaryParts.push(`- ${s.id}: ${s.reason}
`);
+ }
+ if (restoreResults.plugins.skipped.length > 3) {
+ summaryParts.push(
+ `...${strings.more} ${restoreResults.plugins.skipped.length - 3} ${strings.more}
`,
+ );
+ }
+ }
+ }
+
+ summaryParts.push(`
${strings["reload to apply"]}`);
+
+ const shouldReload = await confirm(
+ strings["restore completed"],
+ summaryParts.join(""),
+ true,
+ );
+
+ // Reload only if user confirms
+ if (shouldReload) {
+ location.reload();
+ }
} catch (err) {
- toast(err);
+ loaderDialog.destroy();
+ console.error("Restore error:", err);
+ alert(
+ strings.error.toUpperCase(),
+ `${strings["error details"]}: ${err.message || err}`,
+ );
}
};
diff --git a/utils/lang.js b/utils/lang.js
index a3f76f7fc..d3390e426 100755
--- a/utils/lang.js
+++ b/utils/lang.js
@@ -4,7 +4,9 @@ const yargs = require("yargs");
const { hideBin } = require("yargs/helpers");
const readline = require("node:readline");
-const args = yargs(hideBin(process.argv)).alias("a", "all").argv;
+const args = yargs(hideBin(process.argv))
+ .alias("a", "all")
+ .alias("b", "bulk").argv;
const dir = path.resolve(__dirname, "../src/lang");
const read = readline.createInterface({
input: process.stdin,
@@ -35,9 +37,17 @@ switch (command) {
case "check":
update();
break;
+ case "add-all":
+ addToAllFiles();
+ break;
+ case "bulk-add":
+ bulkAddStrings();
+ break;
default:
console.error(`Missing/Invalid arguments.
use 'add' to add a new string
+use 'add-all ' to add the same string to ALL language files at once
+use 'bulk-add ' to add multiple strings from a JSON file to all language files
use 'remove' to remove a string
use 'search' to search a string
use 'update' to update a string
@@ -46,6 +56,122 @@ use 'check' to check a string`);
process.exit();
}
+/**
+ * Adds a key-value pair to ALL language files at once
+ * Usage: pnpm lang add-all "key" "value"
+ */
+function addToAllFiles() {
+ if (!arg || !val) {
+ console.error('Usage: pnpm lang add-all "" ""');
+ console.error('Example: pnpm lang add-all "hello world" "Hello World"');
+ process.exit(1);
+ }
+
+ const key = arg.toLowerCase();
+ let addedCount = 0;
+ let skippedCount = 0;
+
+ for (const lang of list) {
+ const file = path.resolve(dir, lang);
+ const text = fs.readFileSync(file, "utf8");
+ const strings = JSON.parse(text);
+
+ if (key in strings) {
+ console.log(`${lang}: Skipped (already exists)`);
+ skippedCount++;
+ continue;
+ }
+
+ strings[key] = val;
+ const newText = JSON.stringify(strings, undefined, 2);
+ fs.writeFileSync(file, newText, "utf8");
+ console.log(`${lang}: Added ✓`);
+ addedCount++;
+ }
+
+ console.log(
+ `\nDone! Added to ${addedCount} files, skipped ${skippedCount} files.`,
+ );
+ process.exit(0);
+}
+
+/**
+ * Bulk add multiple strings from a JSON file to ALL language files
+ * Usage: pnpm lang bulk-add strings.json
+ *
+ * JSON file format:
+ * {
+ * "key1": "value1",
+ * "key2": "value2"
+ * }
+ */
+function bulkAddStrings() {
+ if (!arg) {
+ console.error("Usage: pnpm lang bulk-add ");
+ console.error("Example: pnpm lang bulk-add new-strings.json");
+ console.error("\nJSON file format:");
+ console.error("{");
+ console.error(' "key1": "value1",');
+ console.error(' "key2": "value2"');
+ console.error("}");
+ process.exit(1);
+ }
+
+ const jsonFilePath = path.resolve(process.cwd(), arg);
+
+ if (!fs.existsSync(jsonFilePath)) {
+ console.error(`File not found: ${jsonFilePath}`);
+ process.exit(1);
+ }
+
+ let newStrings;
+ try {
+ const jsonContent = fs.readFileSync(jsonFilePath, "utf8");
+ newStrings = JSON.parse(jsonContent);
+ } catch (err) {
+ console.error(`Error parsing JSON file: ${err.message}`);
+ process.exit(1);
+ }
+
+ const keys = Object.keys(newStrings);
+ if (keys.length === 0) {
+ console.error("No strings found in the JSON file.");
+ process.exit(1);
+ }
+
+ console.log(
+ `Adding ${keys.length} strings to ${list.length} language files...\n`,
+ );
+
+ for (const lang of list) {
+ const file = path.resolve(dir, lang);
+ const text = fs.readFileSync(file, "utf8");
+ const strings = JSON.parse(text);
+ let addedCount = 0;
+ let skippedCount = 0;
+
+ for (const key of keys) {
+ const lowerKey = key.toLowerCase();
+ if (lowerKey in strings) {
+ skippedCount++;
+ continue;
+ }
+ strings[lowerKey] = newStrings[key];
+ addedCount++;
+ }
+
+ if (addedCount > 0) {
+ const newText = JSON.stringify(strings, undefined, 2);
+ fs.writeFileSync(file, newText, "utf8");
+ }
+
+ console.log(`${lang}: Added ${addedCount}, Skipped ${skippedCount}`);
+ }
+
+ console.log(`\nDone! Added ${keys.length} strings to all language files.`);
+ process.exit(0);
+}
+
async function update() {
let key;