dsh-plugin-update 0.5.7 → 0.6.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/bilingual.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // AUTO-GENERATED by node build.mjs — DO NOT EDIT. Source: src/bilingual.ts
2
+ import { normalizeLangTag, resolveLang } from "./lang.js";
2
3
  const BILINGUAL_DICT_VERSION = "2026-10-06-pin53";
3
4
  const BILINGUAL_STRINGS = {
4
5
  "entry.label.idle": { en: "Check for updates", zh: "\u68C0\u67E5\u66F4\u65B0", draft: true },
@@ -7,7 +8,312 @@ const BILINGUAL_STRINGS = {
7
8
  "entry.label.restart": { en: "Restart required", zh: "\u5F85\u91CD\u542F", draft: true },
8
9
  "entry.label.has-update": { en: "Update available {version}", zh: "\u6709\u65B0\u7248 {version}", draft: true },
9
10
  "entry.action.checking": { en: "Checking for updates\u2026", zh: "\u6B63\u5728\u67E5\u65B0\u7248\u2026", draft: true },
10
- "entry.note.up-to-date": { en: "Up to date {version}", zh: "\u5DF2\u662F\u6700\u65B0 {version}", draft: true }
11
+ "entry.note.up-to-date": { en: "Up to date {version}", zh: "\u5DF2\u662F\u6700\u65B0 {version}", draft: true },
12
+ "batch-entry.label.idle": { en: "Check for updates", zh: "\u68C0\u67E5\u66F4\u65B0", draft: true },
13
+ "batch-entry.label.update": { en: "{count} updates available", zh: "{count} \u5BB6\u53EF\u66F4\u65B0", draft: true },
14
+ "batch-entry.label.busy": { en: "Installing\u2026", zh: "\u6B63\u5728\u5B89\u88C5\u2026", draft: true },
15
+ "batch-entry.label.restart": { en: "{count} restarts required", zh: "{count} \u5BB6\u5F85\u91CD\u542F", draft: true },
16
+ "batch-entry.label.failed": { en: "{count} failed \u2014 View details", zh: "{count} \u5BB6\u5931\u8D25\uFF0C\u70B9\u6B64\u67E5\u770B", draft: true },
17
+ "batch-entry.action.checking": { en: "Checking for updates\u2026", zh: "\u6B63\u5728\u67E5\u65B0\u7248\u2026", draft: true },
18
+ "panel.blocked.unknown-profile.title": { en: "Unrecognized scope or plugin location", zh: "\u4F7F\u7528\u8303\u56F4\u6216\u63D2\u4EF6\u4F4D\u7F6E\u8BA4\u4E0D\u51FA", draft: true },
19
+ "panel.blocked.unknown-profile.action": { en: "Reopen the host and check again; if it persists, send the version and logs to the plugin author; no manual command is provided for this case.", zh: "\u91CD\u5F00\u5BBF\u4E3B\u518D\u67E5\u4E00\u6B21\uFF1B\u4E00\u76F4\u8FD9\u6837\u5C31\u628A\u7248\u672C\u53F7\u4E0E\u65E5\u5FD7\u4EA4\u7ED9\u63D2\u4EF6\u4F5C\u8005\uFF1B\u8FD9\u79CD\u60C5\u5F62\u4E0D\u7ED9\u624B\u5DE5\u547D\u4EE4", draft: true },
20
+ "panel.blocked.source-install.title": { en: "Installed from source, not by version", zh: "\u5F53\u524D\u662F\u4ECE\u6E90\u7801\u88C5\u7684\uFF0C\u4E0D\u662F\u6309\u7248\u672C\u53F7\u88C5\u7684", draft: true },
21
+ "panel.blocked.source-install.action": { en: "No manual command is provided here; to update, reinstall by version first.", zh: "\u8FD9\u79CD\u60C5\u5F62\u4E0D\u7ED9\u624B\u5DE5\u547D\u4EE4\uFF1B\u60F3\u8D70\u66F4\u65B0\u5148\u6309\u7248\u672C\u53F7\u91CD\u88C5\u4E00\u6B21", draft: true },
22
+ "panel.blocked.invalid-installation.title": { en: "Installed package is incomplete (name mismatch, invalid version, or missing entry file)", zh: "\u5DF2\u88C5\u7684\u5305\u4E0D\u5B8C\u6574\uFF08\u540D\u5B57\u5BF9\u4E0D\u4E0A\u3001\u7248\u672C\u975E\u6CD5\u3001\u5165\u53E3\u6587\u4EF6\u7F3A\u5931\uFF09", draft: true },
23
+ "panel.blocked.invalid-installation.action": { en: "Reinstall the current version to repair the install directory, then check again.", zh: "\u91CD\u88C5\u5F53\u524D\u7248\u672C\uFF0C\u4FEE\u597D\u5DF2\u88C5\u76EE\u5F55\u518D\u67E5\u66F4\u65B0", draft: true },
24
+ "panel.blocked.installation-changed.title": { en: "Install location changed during use (directory or package changed)", zh: "\u5B89\u88C5\u4F4D\u7F6E\u5728\u4F7F\u7528\u4E2D\u9014\u53D8\u4E86\uFF08\u6362\u4E86\u76EE\u5F55\u6216\u6362\u4E86\u5305\uFF09", draft: true },
25
+ "panel.blocked.installation-changed.action": { en: "Reopen the host and check again; if it persists, reinstall.", zh: "\u91CD\u65B0\u6253\u5F00\u5BBF\u4E3B\u518D\u67E5\u4E00\u6B21\uFF1B\u8FD8\u51FA\u73B0\u5C31\u91CD\u88C5", draft: true },
26
+ "panel.blocked.pending-restart.title": { en: "New version is on disk; the running instance is still the old version", zh: "\u65B0\u7248\u5DF2\u88C5\u5230\u78C1\u76D8\uFF0C\u6B63\u5728\u8DD1\u7684\u8FD8\u662F\u65E7\u7248", draft: true },
27
+ "panel.blocked.pending-restart.action": { en: "Restart the host to run the new version; this is a normal end state, not a failure.", zh: "\u91CD\u542F\u5BBF\u4E3B\uFF0C\u8BA9\u65B0\u7248\u8DD1\u8D77\u6765\uFF1B\u8FD9\u662F\u6B63\u5E38\u7EC8\u6001\uFF0C\u4E0D\u662F\u5931\u8D25", draft: true },
28
+ "panel.blocked.registry-conflict.title": { en: "Declared version conflicts with the version on disk", zh: "\u672C\u5730\u58F0\u660E\u7684\u7248\u672C\u4E0E\u78C1\u76D8\u5B9E\u9645\u7248\u672C\u4E92\u76F8\u77DB\u76FE", draft: true },
29
+ "panel.blocked.registry-conflict.action": { en: "Open the scope manifest and set the target package line to the version number, then retry.", zh: "\u6253\u5F00\u4F7F\u7528\u8303\u56F4\u7684\u6E05\u5355\u6587\u4EF6\uFF0C\u628A\u76EE\u6807\u5305\u540D\u90A3\u4E00\u884C\u6539\u6210\u7248\u672C\u53F7\u518D\u8BD5", draft: true },
30
+ "panel.blocked.incompatible-node.title": { en: "Required Node version does not match the running Node", zh: "\u65B0\u7248\u8981\u6C42\u7684 Node \u4E0E\u5F53\u524D\u8FD0\u884C\u7684\u5BF9\u4E0D\u4E0A", draft: true },
31
+ "panel.blocked.incompatible-node.action": { en: "Upgrade Node to 22 or later, then check again.", zh: "\u5148\u5347\u7EA7 Node \u5230 22 \u6216\u66F4\u9AD8\uFF0C\u518D\u67E5\u66F4\u65B0", draft: true },
32
+ "panel.blocked.recovery-required.title": { en: "Last install was interrupted, leaving a partial task", zh: "\u4E0A\u6B21\u5B89\u88C5\u88AB\u6253\u65AD\uFF0C\u7559\u4E0B\u4E00\u4E2A\u534A\u622A\u4EFB\u52A1", draft: true },
33
+ "panel.blocked.recovery-required.action": { en: "Run install once more; if it persists, follow section 6 to troubleshoot.", zh: "\u91CD\u65B0\u70B9\u4E00\u6B21\u5B89\u88C5\uFF1B\u4E00\u76F4\u51FA\u73B0\u5C31\u6309\u7B2C 6 \u8282\u6392\u9519", draft: true },
34
+ "panel.failure.check-failed.title": { en: "Couldn\u2019t check for updates (network, source, or rate limit)", zh: "\u67E5\u65B0\u7248\u6CA1\u6210\u529F\uFF08\u8054\u7F51\u3001\u6E90\u3001\u9650\u6D41\u90FD\u53EF\u80FD\uFF09", draft: true },
35
+ "panel.failure.check-failed.action": { en: "Try checking again later; if it keeps failing, send the copied diagnostics to the plugin author.", zh: "\u8FC7\u4E00\u4F1A\u513F\u518D\u67E5\u4E00\u6B21\uFF1B\u4E00\u76F4\u5931\u8D25\u5C31\u628A\u590D\u5236\u8BCA\u65AD\u4EA4\u7ED9\u63D2\u4EF6\u4F5C\u8005", draft: true },
36
+ "panel.failure.invalid-release.title": { en: "Release info is invalid (bad version or mismatched content)", zh: "\u62FF\u5230\u7684\u53D1\u5E03\u4FE1\u606F\u4E0D\u5408\u6CD5\uFF08\u7248\u672C\u53F7\u975E\u6CD5\u6216\u5185\u5BB9\u5BF9\u4E0D\u4E0A\uFF09", draft: true },
37
+ "panel.failure.invalid-release.action": { en: "Check the package name and version in the manifest, then check again.", zh: "\u68C0\u67E5\u6E05\u5355\u6587\u4EF6\u91CC\u7684\u5305\u540D\u4E0E\u7248\u672C\u5199\u6CD5\uFF0C\u518D\u67E5\u4E00\u6B21", draft: true },
38
+ "panel.failure.check-expired.title": { en: "Credentials expired; the install request was rejected", zh: "\u51ED\u8BC1\u8FC7\u671F\u4E86\uFF0C\u5B89\u88C5\u8BF7\u6C42\u88AB\u62D2", draft: true },
39
+ "panel.failure.check-expired.action": { en: "Check for updates again before installing; do not retry with the old ID.", zh: "\u91CD\u65B0\u67E5\u4E00\u6B21\u65B0\u7248\u518D\u70B9\u5B89\u88C5\uFF0C\u4E0D\u8981\u91CD\u8BD5\u65E7\u7F16\u53F7", draft: true },
40
+ "panel.failure.update-busy.title": { en: "Another install is running in the same scope", zh: "\u540C\u4E00\u4F7F\u7528\u8303\u56F4\u6B63\u5728\u88C5\u53E6\u4E00\u4E2A", draft: true },
41
+ "panel.failure.update-busy.action": { en: "Wait until the current task leaves installing/verifying, then try; check status for your queue position.", zh: "\u7B49\u5F53\u524D\u4EFB\u52A1\u79BB\u5F00 installing/verifying \u518D\u70B9\uFF1B\u6392\u961F\u4E2D\u53BB\u67E5\u72B6\u6001\u770B\u4F4D\u7F6E", draft: true },
42
+ "panel.failure.install-failed.title": { en: "Couldn\u2019t install (see the diagnostic summary)", zh: "\u88C5\u4E0D\u4E0A\uFF08\u8BE6\u89C1\u8BCA\u65AD\u6458\u8981\uFF09", draft: true },
43
+ "panel.failure.install-failed.action": { en: "Read the copied diagnostics first; on official desktop builds, send it to the plugin author.", zh: "\u5148\u770B\u590D\u5236\u8BCA\u65AD\uFF1B\u5B98\u65B9\u684C\u9762\u7248\u628A\u8FD9\u6BB5\u4EA4\u7ED9\u63D2\u4EF6\u4F5C\u8005", draft: true },
44
+ "panel.failure.internal.title": { en: "Something went wrong; the cause is unknown", zh: "\u51FA\u4E86\u70B9\u95EE\u9898\uFF0C\u8BA4\u4E0D\u51FA\u5177\u4F53\u539F\u56E0", draft: true },
45
+ "panel.failure.internal.action": { en: "Retry once first; if it persists, send the copied diagnostics to the plugin author.", zh: "\u5148\u91CD\u8BD5\u4E00\u6B21\uFF1B\u4E00\u76F4\u8FD9\u6837\u5C31\u628A\u590D\u5236\u8BCA\u65AD\u4EA4\u7ED9\u63D2\u4EF6\u4F5C\u8005", draft: true },
46
+ "panel.failure.unknown.title": { en: "Something went wrong; the cause is unknown", zh: "\u51FA\u4E86\u70B9\u95EE\u9898\uFF0C\u8BA4\u4E0D\u51FA\u5177\u4F53\u539F\u56E0", draft: true },
47
+ "panel.failure.unknown.action": { en: "Retry once first; if it persists, send the copied diagnostics to the plugin author (include the code you saw).", zh: "\u5148\u91CD\u8BD5\u4E00\u6B21\uFF1B\u4E00\u76F4\u8FD9\u6837\u5C31\u628A\u590D\u5236\u8BCA\u65AD\u4EA4\u7ED9\u63D2\u4EF6\u4F5C\u8005\uFF08\u5E26\u4E0A\u4F60\u770B\u5230\u7684\u7801\uFF09", draft: true },
48
+ "panel.seal.loading.text": { en: "Not checked", zh: "\u5F85\u67E5", draft: true },
49
+ "panel.seal.loading.mini": { en: "Check", zh: "\u67E5", draft: true },
50
+ "panel.seal.idle.text": { en: "Not checked", zh: "\u5F85\u67E5", draft: true },
51
+ "panel.seal.idle.mini": { en: "Check", zh: "\u67E5", draft: true },
52
+ "panel.seal.update.text": { en: "Update available", zh: "\u53EF\u88C5", draft: true },
53
+ "panel.seal.update.mini": { en: "Install", zh: "\u88C5", draft: true },
54
+ "panel.seal.busy.text": { en: "Installing", zh: "\u5B89\u88C5\u4E2D", draft: true },
55
+ "panel.seal.busy.mini": { en: "Install", zh: "\u88C5", draft: true },
56
+ "panel.seal.restart.text": { en: "Restart required", zh: "\u5F85\u91CD\u542F", draft: true },
57
+ "panel.seal.restart.mini": { en: "Restart", zh: "\u542F", draft: true },
58
+ "panel.seal.blocked.text": { en: "Blocked \u2014 Action needed", zh: "\u53D7\u963B", draft: true },
59
+ "panel.seal.blocked.mini": { en: "Blocked", zh: "\u963B", draft: true },
60
+ "panel.seal.failed.text": { en: "Failed \u2014 Retry available", zh: "\u53D7\u963B", draft: true },
61
+ "panel.seal.failed.mini": { en: "Failed", zh: "\u963B", draft: true },
62
+ "panel.seal.done.text": { en: "Up to date", zh: "\u5DF2\u6700\u65B0", draft: true },
63
+ "panel.seal.done.mini": { en: "Done", zh: "\u5B9A", draft: true },
64
+ "panel.banner.error.title": { en: "Update failed ({code}): {detail}.", zh: "\u66F4\u65B0\u5931\u8D25\uFF08{code}\uFF09\uFF1A{detail}\u3002", draft: true },
65
+ "panel.banner.error.action-fallback": { en: "Copy the diagnostics for the plugin author; see the log channel for details.", zh: "\u590D\u5236\u8BCA\u65AD\u53D1\u7ED9\u63D2\u4EF6\u4F5C\u8005\uFF1B\u6DF1\u6316\u770B\u65E5\u5FD7\u901A\u9053\u3002", draft: true },
66
+ "panel.action.retry-install": { en: "Retry install", zh: "\u91CD\u8BD5\u5B89\u88C5", draft: true },
67
+ "panel.banner.loading": { en: "Loading update status\u2026", zh: "\u6B63\u5728\u8BFB\u53D6\u66F4\u65B0\u72B6\u6001\u2026", draft: true },
68
+ "panel.action.install": { en: "Install update", zh: "\u5B89\u88C5\u66F4\u65B0", draft: true },
69
+ "panel.queue.busy-self": { en: "Installing (this plugin is installing).", zh: "\u6B63\u5728\u5B89\u88C5\uFF08\u672C\u63D2\u4EF6\u5728\u88C5\uFF09\u3002", draft: true },
70
+ "panel.queue.busy-queued": { en: "An install is running ahead; this plugin is #{n} in queue. Install when it reaches the front.", zh: "\u524D\u65B9\u6709\u5B89\u88C5\u5728\u8FDB\u884C\uFF0C\u672C\u63D2\u4EF6\u6392\u7B2C {n} \u4F4D\uFF0C\u5230\u961F\u9996\u518D\u70B9\u5B89\u88C5\u3002", draft: true },
71
+ "panel.queue.busy-other": { en: "Another plugin is installing; retry later.", zh: "\u524D\u65B9\u6709\u5176\u4ED6\u63D2\u4EF6\u5728\u5B89\u88C5\uFF0C\u7A0D\u540E\u91CD\u8BD5\u3002", draft: true },
72
+ "panel.skip.skipped-title": { en: "Skipped {latest}", zh: "\u5DF2\u8DF3\u8FC7 {latest}", draft: true },
73
+ "panel.skip.skipped-action": { en: "Select \u201CRestore\u201D to be reminded of this version again; newer versions will still notify.", zh: "\u70B9\u201C\u6062\u590D\u201D\u53EF\u91CD\u65B0\u63D0\u9192\u8BE5\u7248\u672C\uFF1B\u6709\u66F4\u65B0\u7684\u65B0\u7248\u672C\u4F1A\u7167\u5E38\u63D0\u9192\u3002", draft: true },
74
+ "panel.banner.restart-title": { en: "Version {latest} is installed; restart the host to take effect.", zh: "\u65B0\u7248 {latest} \u5DF2\u5B89\u88C5\uFF0C\u91CD\u542F\u5BBF\u4E3B\u540E\u751F\u6548\u3002", draft: true },
75
+ "panel.banner.installing-title": { en: "Installing {version}\u2026 Closing the panel won\u2019t interrupt it.", zh: "\u6B63\u5728\u5B89\u88C5 {version}\u2026\u5173\u95ED\u9762\u677F\u4E0D\u4F1A\u4E2D\u65AD\u3002", draft: true },
76
+ "panel.banner.installing-action": { en: "Progress refreshes automatically; reopening the panel restores the view within a second.", zh: "\u8FDB\u5EA6\u6309\u8F6E\u8BE2\u81EA\u52A8\u5237\u65B0\uFF1B\u91CD\u5F00\u9762\u677F 1 \u79D2\u5185\u6062\u590D\u663E\u793A\u3002", draft: true },
77
+ "panel.action.installing": { en: "Installing\u2026", zh: "\u5B89\u88C5\u4E2D\u2026", draft: true },
78
+ "panel.banner.update-title": { en: "Update available: {latest} (current: {running}).", zh: "\u6709\u65B0\u7248 {latest} \u53EF\u88C5\uFF08\u5F53\u524D {running}\uFF09\u3002", draft: true },
79
+ "panel.banner.update-action": { en: "Install runs the exact version; only one install runs per scope at a time.", zh: "\u70B9\u5B89\u88C5\u5373\u8D70\u7CBE\u786E\u7248\u672C\u5B89\u88C5\uFF1B\u540C\u4E00\u4F7F\u7528\u8303\u56F4\u540C\u65F6\u53EA\u88C5\u4E00\u4E2A\u3002", draft: true },
80
+ "panel.action.install-version": { en: "Install {latest}", zh: "\u5B89\u88C5 {latest}", draft: true },
81
+ "panel.banner.done": { en: "Up to date. No update needed.", zh: "\u5DF2\u662F\u6700\u65B0\uFF0C\u65E0\u9700\u66F4\u65B0\u3002", draft: true },
82
+ "panel.toast.checking": { en: "Checking for updates\u2026", zh: "\u6B63\u5728\u67E5\u65B0\u7248\u2026", draft: true },
83
+ "panel.toast.installing": { en: "Installing\u2026", zh: "\u6B63\u5728\u5B89\u88C5\u2026", draft: true },
84
+ "panel.toast.copy-manual-ok": { en: "Manual command copied; paste the full line into the terminal to run it.", zh: "\u624B\u5DE5\u547D\u4EE4\u5DF2\u590D\u5236\uFF0C\u7C98\u5230\u7EC8\u7AEF\u6574\u884C\u6267\u884C\u5373\u53EF\u3002", draft: true },
85
+ "panel.toast.copy-manual-fail": { en: "Copy failed; please select the command above manually.", zh: "\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u9009\u4E2D\u4E0A\u9762\u7684\u547D\u4EE4\u3002", draft: true },
86
+ "panel.toast.copy-diag-ok": { en: "Diagnostics copied; paste it to the plugin author (already redacted).", zh: "\u8BCA\u65AD\u5DF2\u590D\u5236\uFF0C\u76F4\u63A5\u7C98\u7ED9\u63D2\u4EF6\u4F5C\u8005\u5373\u53EF\uFF08\u5DF2\u8131\u654F\uFF09\u3002", draft: true },
87
+ "panel.toast.copy-diag-fail": { en: "Copy failed; please select the info above manually.", zh: "\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u9009\u4E2D\u4E0A\u9762\u7684\u4FE1\u606F\u3002", draft: true },
88
+ "panel.toast.restart-delegated": { en: "Handled by the caller\u2019s restart flow; the new version takes effect after restart.", zh: "\u5DF2\u6309\u8C03\u7528\u65B9\u7684\u91CD\u542F\u6D41\u7A0B\u5904\u7406\uFF1B\u91CD\u542F\u540E\u65B0\u7248\u751F\u6548\u3002", draft: true },
89
+ "panel.toast.restart-manual": { en: "This host provides no restart entry; please restart the host manually. The new version takes effect after restart.", zh: "\u672C\u5BBF\u4E3B\u672A\u63D0\u4F9B\u91CD\u542F\u5165\u53E3\uFF1A\u8BF7\u624B\u52A8\u91CD\u542F\u5BBF\u4E3B\uFF0C\u91CD\u542F\u540E\u65B0\u7248\u751F\u6548\u3002", draft: true },
90
+ "panel.toast.restart-failed": { en: "Restart entry failed; please restart the host manually. The new version takes effect after restart.", zh: "\u91CD\u542F\u5165\u53E3\u8C03\u7528\u5931\u8D25\uFF1A\u8BF7\u624B\u52A8\u91CD\u542F\u5BBF\u4E3B\uFF0C\u91CD\u542F\u540E\u65B0\u7248\u751F\u6548\u3002", draft: true },
91
+ "panel.toast.copy-state-ok": { en: "Current state copied (no failure); paste it to the plugin author (already redacted).", zh: "\u5DF2\u590D\u5236\u5F53\u524D\u72B6\u6001\uFF08\u65E0\u5931\u8D25\uFF09\uFF0C\u76F4\u63A5\u7C98\u7ED9\u63D2\u4EF6\u4F5C\u8005\u5373\u53EF\uFF08\u5DF2\u8131\u654F\uFF09\u3002", draft: true },
92
+ "panel.toast.failure-dismissed": { en: "Failure acknowledged; it will be re-evaluated on the next check or install.", zh: "\u5DF2\u786E\u8BA4\u8BE5\u5931\u8D25\u63D0\u793A\uFF1B\u4E0B\u6B21\u67E5\u65B0\u7248\u6216\u5B89\u88C5\u5C06\u91CD\u65B0\u8BC4\u4F30\u3002", draft: true },
93
+ "panel.strip.running": { en: "Running", zh: "\u8FD0\u884C", draft: true },
94
+ "panel.strip.installed": { en: "Installed", zh: "\u78C1\u76D8", draft: true },
95
+ "panel.strip.latest": { en: "Latest", zh: "\u8FDC\u7AEF", draft: true },
96
+ "panel.meta.label": { en: "Scope", zh: "\u4F7F\u7528\u8303\u56F4", draft: true },
97
+ "panel.meta.unknown": { en: "Unknown", zh: "\u672A\u77E5", draft: true },
98
+ "panel.masthead.kicker": { en: "Plugin update", zh: "\u63D2\u4EF6\u66F4\u65B0", draft: true },
99
+ "panel.masthead.title": { en: "Update archive", zh: "\u66F4\u65B0\u6863\u6848", draft: true },
100
+ "panel.masthead.volume": { en: "Vol.", zh: "\u5377", draft: true },
101
+ "panel.chapter.check": { en: "Check and install", zh: "\u68C0\u67E5\u4E0E\u5B89\u88C5", draft: true },
102
+ "panel.chapter.changelog": { en: "Changelog", zh: "\u66F4\u65B0\u65E5\u5FD7", draft: true },
103
+ "panel.chapter.queue": { en: "Update queue", zh: "\u66F4\u65B0\u961F\u5217", draft: true },
104
+ "panel.chapter.error": { en: "Error details", zh: "\u9519\u8BEF\u4FE1\u606F", draft: true },
105
+ "panel.chapter.manual": { en: "Manual command", zh: "\u624B\u5DE5\u547D\u4EE4", draft: true },
106
+ "panel.progress.installing": { en: "Installing new version\u2026", zh: "\u6B63\u5728\u5B89\u88C5\u65B0\u7248\u2026", draft: true },
107
+ "panel.progress.verifying": { en: "Verifying install result\u2026", zh: "\u6B63\u5728\u6821\u9A8C\u5B89\u88C5\u7ED3\u679C\u2026", draft: true },
108
+ "panel.action.check": { en: "Check for updates", zh: "\u67E5\u65B0\u7248", draft: true },
109
+ "panel.action.check-title": { en: "Check the official source once more (read-only, never installs)", zh: "\u91CD\u65B0\u5411\u5B98\u65B9\u6E90\u67E5\u4E00\u6B21\u65B0\u7248\uFF08\u53EA\u8BFB\uFF0C\u4E0D\u5B89\u88C5\uFF09", draft: true },
110
+ "panel.action.checking-busy": { en: "Checking for updates\u2026", zh: "\u6B63\u5728\u67E5\u65B0\u7248\u2026", draft: true },
111
+ "panel.action.checking-busy-title": { en: "Checking the official source; please wait", zh: "\u6B63\u5728\u5411\u5B98\u65B9\u6E90\u67E5\u8BE2\uFF0C\u8BF7\u7A0D\u5019", draft: true },
112
+ "panel.action.installing-busy": { en: "Installing\u2026", zh: "\u6B63\u5728\u5B89\u88C5\u2026", draft: true },
113
+ "panel.action.installing-busy-title": { en: "Installing; please wait", zh: "\u6B63\u5728\u5B89\u88C5\uFF0C\u8BF7\u7A0D\u5019", draft: true },
114
+ "panel.action.install-title": { en: "Install the exact version; one install per scope at a time", zh: "\u7528\u7CBE\u786E\u7248\u672C\u5B89\u88C5\uFF1B\u540C\u4E00\u4F7F\u7528\u8303\u56F4\u540C\u65F6\u53EA\u88C5\u4E00\u4E2A", draft: true },
115
+ "panel.action.skip": { en: "Skip this version", zh: "\u8DF3\u8FC7\u8BE5\u7248\u672C", draft: true },
116
+ "panel.action.skip-title": { en: "This version will no longer notify; newer versions still will", zh: "\u8BE5\u7248\u672C\u4E0D\u518D\u63D0\u9192\uFF1B\u6709\u66F4\u65B0\u7684\u65B0\u7248\u672C\u7167\u5E38\u63D0\u9192", draft: true },
117
+ "panel.action.unskip": { en: "Restore ({version})", zh: "\u6062\u590D\uFF08{version}\uFF09", draft: true },
118
+ "panel.action.unskip-title": { en: "Undo skip; this version will remind again", zh: "\u64A4\u9500\u8DF3\u8FC7\uFF0C\u8BE5\u7248\u672C\u91CD\u65B0\u63D0\u9192", draft: true },
119
+ "panel.action.copy-manual": { en: "Copy manual command", zh: "\u590D\u5236\u624B\u5DE5\u547D\u4EE4", draft: true },
120
+ "panel.action.copy-manual-title": { en: "Copy the manual command; paste the full line into the terminal", zh: "\u590D\u5236\u624B\u5DE5\u547D\u4EE4\uFF0C\u7C98\u5230\u7EC8\u7AEF\u6574\u884C\u6267\u884C", draft: true },
121
+ "panel.action.restart-host": { en: "Restart host", zh: "\u91CD\u542F\u5BBF\u4E3B", draft: true },
122
+ "panel.action.restart-host-title": { en: "This host provides no restart entry; restart the host manually", zh: "\u5BBF\u4E3B\u6CA1\u6709\u81EA\u91CD\u542F\u7535\u8BDD\uFF1A\u8BF7\u624B\u52A8\u91CD\u542F\u5BBF\u4E3B", draft: true },
123
+ "panel.action.dismiss": { en: "Got it", zh: "\u77E5\u9053\u4E86", draft: true },
124
+ "panel.action.dismiss-title": { en: "Acknowledge the failure and return; next check or install will re-evaluate", zh: "\u786E\u8BA4\u5DF2\u77E5\u6653\u8BE5\u5931\u8D25\uFF1A\u56DE\u5230\u53EF\u88C5\u9875\uFF0C\u4E0B\u6B21\u67E5/\u88C5\u5C06\u91CD\u65B0\u8BC4\u4F30", draft: true },
125
+ "panel.action.copy-diag": { en: "Copy diagnostics", zh: "\u590D\u5236\u8BCA\u65AD", draft: true },
126
+ "panel.action.copy-diag-title": { en: "Copy redacted diagnostics for the plugin author", zh: "\u590D\u5236\u5DF2\u8131\u654F\u8BCA\u65AD\uFF0C\u76F4\u63A5\u7C98\u7ED9\u63D2\u4EF6\u4F5C\u8005", draft: true },
127
+ "panel.skip.line-tag": { en: "Skipped {version}", zh: "\u5DF2\u8DF3\u8FC7 {version}", draft: true },
128
+ "panel.skip.line-note": { en: "Select \u201CRestore\u201D to undo; this version will remind again.", zh: "\u70B9\u300C\u6062\u590D\u300D\u53EF\u64A4\u9500\uFF0C\u4E4B\u540E\u8FD9\u4E00\u7248\u8FD8\u4F1A\u518D\u63D0\u9192\u3002", draft: true },
129
+ "panel.changelog.heading": { en: "Changelog:", zh: "\u66F4\u65B0\u8BF4\u660E\uFF1A", draft: true },
130
+ "panel.changelog.heading-range": { en: "Changelog ({from} \u2192 {to}):", zh: "\u66F4\u65B0\u8BF4\u660E\uFF08{from} \u2192 {to}\uFF09\uFF1A", draft: true },
131
+ "panel.changelog.unavailable": { en: "Could not read logs; install is unaffected.", zh: "\u65E5\u5FD7\u8BFB\u4E0D\u51FA\u6765\uFF0C\u5B89\u88C5\u4E0D\u53D7\u5F71\u54CD\u3002", draft: true },
132
+ "panel.changelog.unavailable-empty": { en: "No release found yet; logs will show after a check.", zh: "\u8FD8\u6CA1\u67E5\u5230\u65B0\u7248\uFF1B\u67E5\u5230\u540E\u518D\u663E\u793A\u65E5\u5FD7\u3002", draft: true },
133
+ "panel.changelog.toggle-title": { en: "Expand or collapse changelog", zh: "\u5C55\u5F00\u6216\u6536\u8D77\u66F4\u65B0\u65E5\u5FD7", draft: true },
134
+ "panel.changelog.expand": { en: "Expand changelog", zh: "\u5C55\u5F00\u66F4\u65B0\u65E5\u5FD7", draft: true },
135
+ "panel.changelog.collapse": { en: "Collapse changelog", zh: "\u6536\u8D77\u66F4\u65B0\u65E5\u5FD7", draft: true },
136
+ "panel.queue.state-idle": { en: "Idle", zh: "\u7A7A\u95F2", draft: true },
137
+ "panel.queue.other": { en: "Other plugin", zh: "\u5176\u4ED6\u63D2\u4EF6", draft: true },
138
+ "panel.queue.self": { en: "This plugin", zh: "\u672C\u63D2\u4EF6", draft: true },
139
+ "panel.queue.pos-absent": { en: "Not queued", zh: "\u672A\u6392\u961F", draft: true },
140
+ "panel.queue.pos-n": { en: "Position {n}", zh: "\u7B2C {n} \u4F4D", draft: true },
141
+ "panel.queue.pos-next": { en: "You are next", zh: "\u4E0B\u4E00\u4E2A\u5C31\u662F\u4F60", draft: true },
142
+ "panel.queue.pos-ahead": { en: "{n} ahead", zh: "\u524D\u65B9 {n} \u4E2A", draft: true },
143
+ "panel.queue.row-installing": { en: "Installing", zh: "\u6B63\u5728\u5B89\u88C5", draft: true },
144
+ "panel.queue.row-installing-note": { en: "You are next when it finishes", zh: "\u88C5\u5B8C\u81EA\u52A8\u8F6E\u5230\u4F60", draft: true },
145
+ "panel.queue.row-idle-note": { en: "One install per scope at a time", zh: "\u540C\u4E00\u4F7F\u7528\u8303\u56F4\u4E00\u6B21\u53EA\u88C5\u4E00\u4E2A", draft: true },
146
+ "panel.queue.row-position": { en: "Your position", zh: "\u4F60\u7684\u987A\u4F4D", draft: true },
147
+ "panel.queue.row-order": { en: "Queue order", zh: "\u6392\u961F\u987A\u5E8F", draft: true },
148
+ "panel.queue.toggle-hide": { en: "Hide others", zh: "\u9690\u85CF\u4ED6\u4EBA\u660E\u7EC6", draft: true },
149
+ "panel.queue.toggle-show": { en: "Show others", zh: "\u663E\u793A\u5176\u4ED6\u63D2\u4EF6", draft: true },
150
+ "panel.queue.empty": { en: "No queued tasks; one install per scope at a time.", zh: "\u5F53\u524D\u6CA1\u6709\u6392\u961F\u4EFB\u52A1\uFF0C\u540C\u4E00\u4F7F\u7528\u8303\u56F4\u4E00\u6B21\u53EA\u88C5\u4E00\u4E2A\u3002", draft: true },
151
+ "panel.error.code-label": { en: "Stable code", zh: "\u7A33\u5B9A\u7801", draft: true },
152
+ "panel.error.code-note": { en: "The line above tells you what to do; to report upstream, paste \u201CCopy diagnostics\u201D as a whole (already redacted).", zh: "\u4E0A\u4E00\u6761\u4E2D\u6587\u8BF4\u660E\u5C31\u662F\u8981\u7528\u6237\u505A\u7684\u4E8B\uFF1B\u8981\u5F80\u4E0A\u6E38\u62A5\uFF0C\u7528\u300C\u590D\u5236\u8BCA\u65AD\u300D\u6574\u6BB5\u7C98\uFF08\u5DF2\u8131\u654F\uFF09\u3002", draft: true },
153
+ "panel.error.query-request": { en: "Request", zh: "\u8BF7\u6C42", draft: true },
154
+ "panel.error.query-check": { en: "Check", zh: "\u68C0\u67E5", draft: true },
155
+ "panel.error.failed-at": { en: "Failed at {time}", zh: "\u5931\u8D25\u4E8E {time}", draft: true },
156
+ "panel.error.query-keys": { en: "Query keys: {keys} (use them to match in logs).", zh: "\u672C\u6B21\u67E5\u8BE2\u952E\uFF1A{keys}\uFF08\u62FF\u7740\u5B83\u4EEC\u53BB\u65E5\u5FD7\u91CC\u5BF9\uFF09\u3002", draft: true },
157
+ "panel.error.evidence-frozen": { en: "Evidence frozen: the code, versions, and IDs in copied diagnostics are from the failure moment and do not refresh with polling; the next check or install will update them.", zh: "\u8BC1\u636E\u5DF2\u51BB\u7ED3\uFF1A\u590D\u5236\u8BCA\u65AD\u91CC\u7684\u7801\u3001\u7248\u672C\u3001\u7F16\u53F7\u90FD\u53D6\u81EA\u5931\u8D25\u65F6\u523B\uFF0C\u4E0D\u968F\u8F6E\u8BE2\u5237\u65B0\uFF1B\u4E0B\u4E00\u6B21\u67E5\u65B0\u7248\u6216\u5B89\u88C5\u4F1A\u66F4\u65B0\u5B83\u3002", draft: true },
158
+ "panel.error.evidence-transient": { en: "Transient read failure: it clears on the next successful read; if it persists, troubleshoot by stable code.", zh: "\u8BFB\u6570\u77AC\u6001\u5931\u8D25\uFF1A\u4E0B\u4E00\u6B21\u6210\u529F\u8BFB\u6570\u4F1A\u81EA\u52A8\u89E3\u9664\uFF1B\u4E00\u76F4\u51FA\u73B0\u518D\u6309\u7A33\u5B9A\u7801\u6392\u67E5\u3002", draft: true },
159
+ "panel.error.no-failure": { en: "No failure: copying diagnostics gives the current state snapshot.", zh: "\u6682\u65E0\u5931\u8D25\uFF1A\u6B64\u65F6\u590D\u5236\u8BCA\u65AD\u7ED9\u51FA\u7684\u662F\u5F53\u524D\u72B6\u6001\u5FEB\u7167\u3002", draft: true },
160
+ "panel.error.log-hint": { en: "Check logs: filter by plugin ID {pluginId} for events {e1}, {e2}, {e3}.", zh: "\u6DF1\u6316\u770B\u65E5\u5FD7\uFF1A\u6309\u63D2\u4EF6\u6807\u8BC6 {pluginId} \u8FC7\u6EE4 {e1}\u3001{e2}\u3001{e3} \u4E09\u4E2A\u4E8B\u4EF6\u3002", draft: true },
161
+ "panel.error.log-follow": { en: "Match the request/check IDs above in {eFail}; baseline timing in {eCall}, execution result in {eExec}.", zh: "\u51ED\u4E0A\u9762\u7684\u8BF7\u6C42\uFF0F\u68C0\u67E5\u7F16\u53F7\u5728 {eFail} \u91CC\u5BF9\u4E0A\uFF1B\u57FA\u7EBF\u8017\u65F6\u770B {eCall}\uFF0C\u6267\u884C\u7ED3\u679C\u770B {eExec}\u3002", draft: true },
162
+ "panel.manual.heading": { en: "Manual fallback command (copy the full line to run):", zh: "\u624B\u5DE5\u515C\u5E95\u547D\u4EE4\uFF08\u590D\u5236\u6574\u884C\u6267\u884C\uFF09\uFF1A", draft: true },
163
+ "panel.manual.absent": { en: "No manual command available (unrecognized scope or source install).", zh: "\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u7684\u624B\u5DE5\u547D\u4EE4\uFF08\u8BA4\u4E0D\u51FA\u4F7F\u7528\u8303\u56F4\u6216\u5C5E\u6E90\u7801\u5B89\u88C5\u65F6\u4E0D\u7ED9\uFF09\u3002", draft: true },
164
+ "panel.footer.note": { en: "Closing never interrupts updates; come back anytime", zh: "\u5173\u95ED\u4E0D\u5F71\u54CD\u66F4\u65B0\uFF0C\u53EF\u968F\u65F6\u56DE\u6765\u67E5\u770B", draft: true },
165
+ "panel.footer.close": { en: "Close", zh: "\u5173\u95ED", draft: true },
166
+ "panel.footer.close-title": { en: "Close the window; updates keep running", zh: "\u5173\u95ED\u7A97\u53E3\uFF0C\u66F4\u65B0\u4E0D\u53D7\u5F71\u54CD", draft: true },
167
+ "panel.diag.header": { en: "[Update Diagnostics] {pluginId} Stable code: {code}", zh: "[\u66F4\u65B0\u8BCA\u65AD] {pluginId} \u7A33\u5B9A\u7801\uFF1A{code}", draft: true },
168
+ "panel.diag.label.human": { en: "Detail: {detail}", zh: "\u4EBA\u8BDD\uFF1A{detail}", draft: true },
169
+ "panel.diag.label.running": { en: "Running: {version}", zh: "\u8FD0\u884C\u7248\uFF1A{version}", draft: true },
170
+ "panel.diag.label.installed": { en: "Installed: {version}", zh: "\u5DF2\u88C5\uFF1A{version}", draft: true },
171
+ "panel.diag.label.latest": { en: "Latest: {version}", zh: "\u8FDC\u7AEF\uFF1A{version}", draft: true },
172
+ "panel.diag.queue.installing": { en: "Installing", zh: "\u6B63\u5728\u5B89\u88C5", draft: true },
173
+ "panel.diag.queue.position": { en: "Queued at position {n}", zh: "\u6392\u961F\u7B2C {n} \u4F4D", draft: true },
174
+ "panel.diag.queue.absent": { en: "Not queued", zh: "\u4E0D\u5728\u961F\u5217\u91CC", draft: true },
175
+ "panel.diag.label.host": { en: "Host: {host}", zh: "\u5BBF\u4E3B\uFF1A{host}", draft: true },
176
+ "panel.diag.label.profile": { en: "Scope: {profile}", zh: "\u4F7F\u7528\u8303\u56F4\uFF1A{profile}", draft: true },
177
+ "panel.diag.label.queue": { en: "Queue: {queue}", zh: "\u961F\u5217\uFF1A{queue}", draft: true },
178
+ "panel.diag.label.request": { en: "Request ID: {requestId}", zh: "\u8BF7\u6C42\u7F16\u53F7\uFF1A{requestId}", draft: true },
179
+ "panel.diag.label.manual": { en: "Manual command: {manual}", zh: "\u624B\u5DE5\u547D\u4EE4\uFF1A{manual}", draft: true },
180
+ "panel.diag.copy.no-detail": { en: "(This response carries no diagnostic summary; it will be completed when phone-side diag lands)", zh: "\uFF08\u672C\u56DE\u5305\u6CA1\u6709\u5E26\u8BCA\u65AD\u6458\u8981\uFF0C\u7B49\u7535\u8BDD\u4FA7 diag \u843D\u5B9A\u540E\u8865\u9F50\uFF09", draft: true },
181
+ "panel.diag.copy.unknown-package": { en: "(Unknown package)", zh: "(\u672A\u77E5\u5305)", draft: true },
182
+ "panel.diag.copy.unknown": { en: "Unknown", zh: "\u672A\u77E5", draft: true },
183
+ "panel.diag.copy.field.plugin": { en: "Plugin={plugin}", zh: "\u63D2\u4EF6={plugin}", draft: true },
184
+ "panel.diag.copy.field.version": { en: "Version={run}\u2192{inst}", zh: "\u7248\u672C={run}\u2192{inst}", draft: true },
185
+ "panel.diag.copy.field.host": { en: "Host={host}", zh: "\u5BBF\u4E3B={host}", draft: true },
186
+ "panel.diag.copy.field.profile": { en: "Scope={profile}", zh: "\u4F7F\u7528\u8303\u56F4={profile}", draft: true },
187
+ "panel.diag.copy.field.route": { en: "Route={route}", zh: "\u8DEF\u7531={route}", draft: true },
188
+ "panel.diag.copy.field.stage": { en: "Stage={stage}", zh: "\u9636\u6BB5={stage}", draft: true },
189
+ "panel.diag.copy.field.method": { en: "Method={method}", zh: "\u65B9\u6CD5={method}", draft: true },
190
+ "panel.diag.copy.field.latency": { en: "Latency={latency}", zh: "\u8017\u65F6={latency}", draft: true },
191
+ "panel.diag.copy.field.registry": { en: "Source={host}", zh: "\u6E90={host}", draft: true },
192
+ "panel.diag.copy.field.registry-unknown": { en: "Source=Unknown (Omitted for non-official sources, which is itself information)", zh: "\u6E90=\u672A\u77E5\uFF08\u975E\u5B98\u65B9\u6E90\u65F6\u7701\u7565\u672C\u8EAB\u5373\u4FE1\u606F\uFF09", draft: true },
193
+ "panel.diag.copy.field.action": { en: "Suggestion={action}", zh: "\u5EFA\u8BAE={action}", draft: true },
194
+ "panel.diag.copy.field.request": { en: "Request={request}", zh: "\u8BF7\u6C42={request}", draft: true },
195
+ "panel.diag.copy.field.check": { en: "Check={check}", zh: "\u68C0\u67E5={check}", draft: true },
196
+ "panel.diag.copy.field.queue": { en: "Queue={queue}", zh: "\u961F\u5217={queue}", draft: true },
197
+ "panel.diag.copy.line.summary": { en: "Summary={summary}", zh: "\u6458\u8981={summary}", draft: true },
198
+ "panel.diag.copy.line.remedy": { en: "Remedy={remedy}", zh: "\u600E\u4E48\u529E={remedy}", draft: true },
199
+ "panel.diag.copy.block.summary": { en: "Summary\uFF1A{summary}", zh: "\u6458\u8981\uFF1A{summary}", draft: true },
200
+ "panel.diag.copy.block.source": { en: "Source\uFF1A{source}", zh: "\u6765\u6E90\uFF1A{source}", draft: true },
201
+ "panel.diag.copy.block.remedy": { en: "Remedy\uFF1A{remedy}", zh: "\u600E\u4E48\u529E\uFF1A{remedy}", draft: true },
202
+ "batch.action.resume": { en: "Continue the unfinished batch ({count} left)", zh: "\u7EE7\u7EED\u4E0A\u6B21\u672A\u5B8C\u6210\u7684\u66F4\u65B0\uFF08\u8FD8\u5269 {count} \u5BB6\uFF09", draft: true },
203
+ "batch.action.discard": { en: "Discard this unfinished batch (installed ones stay)", zh: "\u4E22\u5F03\u8FD9\u6279\u672A\u5B8C\u6210\u7684\u66F4\u65B0\uFF08\u5DF2\u5B8C\u6210\u7684\u4FDD\u7559\uFF09", draft: true },
204
+ "batch.action.confirm-discard": { en: "Confirm discard", zh: "\u786E\u8BA4\u4E22\u5F03", draft: true },
205
+ "batch.fact.close-safe": { en: "Closing this panel won't stop it \u2014 progress is saved on disk.", zh: "\u5173\u6389\u9762\u677F\u4E0D\u4F1A\u4E2D\u65AD\uFF1A\u8FDB\u5EA6\u5DF2\u5199\u76D8\uFF0C\u56DE\u6765\u53EF\u7EE7\u7EED\u3002", draft: true },
206
+ "batch.setting.check-on-open": { en: "Check for updates when opening", zh: "\u6253\u5F00\u9762\u677F\u65F6\u81EA\u52A8\u68C0\u67E5\u66F4\u65B0", draft: true },
207
+ "batch.row.update": { en: "Update available {version}", zh: "\u6709\u65B0\u7248 {version}", draft: true },
208
+ "batch.row.current": { en: "Up to date", zh: "\u5DF2\u662F\u6700\u65B0\uFF0C\u4E0D\u7528\u52A8", draft: true },
209
+ "batch.row.never": { en: "Not checked yet", zh: "\u8FD8\u6CA1\u67E5\u8FC7", draft: true },
210
+ "batch.row.failed": { en: "Last check failed", zh: "\u8FD9\u6B21\u6CA1\u67E5\u5230", draft: true },
211
+ "batch.notice.auto-resumed": { en: "Auto-continued the unfinished batch ({count} left).", zh: "\u5DF2\u81EA\u52A8\u7EE7\u7EED\u4E0A\u6B21\u672A\u5B8C\u6210\u7684\u66F4\u65B0\uFF08\u8FD8\u5269 {count} \u5BB6\uFF09\u3002", draft: true },
212
+ "batch.notice.resumed": { en: "Continued the unfinished batch ({count} left).", zh: "\u5DF2\u7EE7\u7EED\u4E0A\u6B21\u672A\u5B8C\u6210\u7684\u66F4\u65B0\uFF08\u8FD8\u5269 {count} \u5BB6\uFF09\u3002", draft: true },
213
+ "batch.notice.no-resume": { en: "Nothing to continue.", zh: "\u6CA1\u6709\u53EF\u7EE7\u7EED\u7684\u5185\u5BB9\u3002", draft: true },
214
+ "batch.notice.discarded": { en: "Discarded this unfinished batch (installed ones stay).", zh: "\u5DF2\u4E22\u5F03\u8FD9\u6279\u672A\u5B8C\u6210\u7684\u66F4\u65B0\uFF08\u5DF2\u5B8C\u6210\u7684\u4FDD\u7559\uFF09\u3002", draft: true },
215
+ "batch.notice.cancel-confirm": { en: "Click again to confirm discard.", zh: "\u518D\u70B9\u4E00\u6B21\u786E\u8BA4\u4E22\u5F03\u3002", draft: true },
216
+ "batch.notice.busy-cancel": { en: "An install is running and cannot be stopped.", zh: "\u6B63\u5728\u88C5\u7684\u90A3\u4E00\u5BB6\u505C\u4E0D\u4E86\u3002", draft: true },
217
+ "batch.row.unfinished-tag": { en: "unfinished last time", zh: "\u4E0A\u4E00\u6279\u6CA1\u505A\u5B8C", draft: true },
218
+ "batch.summary.updatable": { en: "{n} updates available", zh: "{n} \u5BB6\u53EF\u66F4\u65B0", draft: true },
219
+ "batch.summary.installing": { en: "{n} installing", zh: "{n} \u5BB6\u5B89\u88C5\u4E2D", draft: true },
220
+ "batch.summary.pending": { en: "{n} not checked", zh: "{n} \u5BB6\u5F85\u67E5", draft: true },
221
+ "batch.summary.restart": { en: "{n} restart required", zh: "{n} \u5BB6\u5F85\u91CD\u542F", draft: true },
222
+ "batch.summary.failed": { en: "{n} failed", zh: "{n} \u5BB6\u5931\u8D25", draft: true },
223
+ "batch.summary.skipped": { en: "{n} skipped", zh: "{n} \u5BB6\u5DF2\u8DF3\u8FC7", draft: true },
224
+ "batch.summary.settled": { en: "{n} up to date", zh: "{n} \u5BB6\u5DF2\u6700\u65B0", draft: true },
225
+ "batch.summary.empty": { en: "No targets yet", zh: "\u8FD8\u6CA1\u6709\u76EE\u6807", draft: true },
226
+ "batch.header.title": { en: "Update archive", zh: "\u66F4\u65B0\u6863\u6848", draft: true },
227
+ "batch.action.check": { en: "Check for updates", zh: "\u68C0\u67E5\u66F4\u65B0", draft: true },
228
+ "batch.action.check-title": { en: "Re-read batch status (read-only)", zh: "\u91CD\u65B0\u8BFB\u53D6\u6279\u91CF\u72B6\u6001\uFF08\u53EA\u8BFB\uFF09", draft: true },
229
+ "batch.action.install-all": { en: "Update all", zh: "\u5168\u90E8\u66F4\u65B0", draft: true },
230
+ "batch.action.install-all-title": { en: "Submit all updatable plugins at once; one idempotency key per session", zh: "\u628A\u6709\u65B0\u7248\u7684\u51E0\u5BB6\u4E00\u6B21\u63D0\u4EA4\uFF1B\u540C\u4E00\u4F1A\u8BDD\u540C\u4E00\u5E42\u7B49\u7F16\u53F7", draft: true },
231
+ "batch.action.close": { en: "Close", zh: "\u5173\u95ED", draft: true },
232
+ "batch.action.close-title": { en: "Close the window; batch progress keeps running", zh: "\u5173\u95ED\u7A97\u53E3\uFF0C\u6279\u91CF\u66F4\u65B0\u4E0D\u53D7\u5F71\u54CD", draft: true },
233
+ "batch.banner.loading": { en: "Loading batch update status\u2026", zh: "\u6B63\u5728\u8BFB\u53D6\u6279\u91CF\u66F4\u65B0\u72B6\u6001\u2026", draft: true },
234
+ "batch.hint.error": { en: "Last run failed: follow the red banner below.", zh: "\u521A\u624D\u90A3\u6B21\u6CA1\u6210\u529F\uFF1A\u770B\u4E0B\u9762\u7684\u7EA2\u6761\uFF0C\u7167\u5B83\u8BF4\u7684\u505A\u4E00\u6B21\u3002", draft: true },
235
+ "batch.hint.empty": { en: "No targets yet: select \u201CCheck for updates\u201D to see which plugins have updates.", zh: "\u8FD8\u6CA1\u6709\u76EE\u6807\uFF1A\u70B9\u300C\u68C0\u67E5\u66F4\u65B0\u300D\u770B\u770B\u54EA\u51E0\u5BB6\u6709\u65B0\u7248\u3002", draft: true },
236
+ "batch.hint.installing-queueable": { en: "Installing {a}; {b} more can join the queue.", zh: "\u6B63\u5728\u5B89\u88C5 {a} \u5BB6\uFF1B\u8FD8\u6709 {b} \u5BB6\u53EF\u4EE5\u70B9\u300C\u52A0\u5165\u961F\u5217\u300D\u6392\u961F\u7B49\u3002", draft: true },
237
+ "batch.hint.installing-auto": { en: "Installing {a}; the next starts automatically.", zh: "\u6B63\u5728\u5B89\u88C5 {a} \u5BB6\uFF0C\u5B89\u88C5\u5B8C\u81EA\u52A8\u4E0B\u4E00\u5BB6\u3002", draft: true },
238
+ "batch.hint.failed": { en: "{n} failed to install; retry each one from the failure notes below.", zh: "{n} \u5BB6\u5B89\u88C5\u5931\u8D25\uFF1B\u7167\u4E0B\u9762\u7684\u5931\u8D25\u63D0\u793A\u9010\u5BB6\u91CD\u8BD5\u3002", draft: true },
239
+ "batch.hint.updatable": { en: "{n} updates available; select \u201CUpdate all\u201D to install at once, or install each one inline.", zh: "{n} \u5BB6\u53EF\u66F4\u65B0\uFF1B\u70B9\u300C\u5168\u90E8\u66F4\u65B0\u300D\u4E00\u6B21\u5B89\u88C5\u5B8C\uFF0C\u4E5F\u53EF\u4EE5\u9010\u5BB6\u70B9\u300C\u5B89\u88C5\u8FD9\u5BB6\u300D\u3002", draft: true },
240
+ "batch.hint.restart": { en: "{n} installed; restart the host to take effect.", zh: "{n} \u5BB6\u5DF2\u5B89\u88C5\u597D\uFF0C\u91CD\u542F\u5BBF\u4E3B\u540E\u751F\u6548\u3002", draft: true },
241
+ "batch.hint.pending": { en: "{n} not checked yet; select \u201CCheck for updates\u201D for a round.", zh: "{n} \u5BB6\u8FD8\u6CA1\u67E5\u8FC7\uFF1B\u70B9\u300C\u68C0\u67E5\u66F4\u65B0\u300D\u67E5\u4E00\u8F6E\u3002", draft: true },
242
+ "batch.hint.done": { en: "All up to date; nothing to do.", zh: "\u5168\u90E8\u5DF2\u6700\u65B0\uFF0C\u6CA1\u6709\u8981\u505A\u7684\u3002", draft: true },
243
+ "batch.seal.ledger": { en: "Ledger", zh: "\u603B\u8D26", draft: true },
244
+ "batch.banner.error-title": { en: "Failed this time ({code}): {detail}.", zh: "\u8FD9\u6B21\u6CA1\u6210\u529F\uFF08{code}\uFF09\uFF1A{detail}\u3002", draft: true },
245
+ "batch.banner.error-action-fallback": { en: "Retry once first; if it persists, send the copied diagnostics to the plugin author.", zh: "\u5148\u91CD\u8BD5\u4E00\u6B21\uFF1B\u4E00\u76F4\u8FD9\u6837\u5C31\u628A\u590D\u5236\u8BCA\u65AD\u4EA4\u7ED9\u63D2\u4EF6\u4F5C\u8005\u3002", draft: true },
246
+ "batch.banner.failed-title": { en: "{n} failed to install.", zh: "{n} \u5BB6\u5B89\u88C5\u5931\u8D25\u3002", draft: true },
247
+ "batch.banner.failed-action": { en: "Retry each one inline; if it keeps failing, send the copied diagnostics to the plugin author.", zh: "\u9010\u5BB6\u70B9\u884C\u5185\u300C\u91CD\u8BD5\u300D\u518D\u6765\u4E00\u6B21\uFF1B\u4E00\u76F4\u5931\u8D25\u5C31\u628A\u590D\u5236\u8BCA\u65AD\u4EA4\u7ED9\u63D2\u4EF6\u4F5C\u8005\u3002", draft: true },
248
+ "batch.banner.restart-title": { en: "{n} installed; restart the host to take effect.", zh: "{n} \u5BB6\u5DF2\u5B89\u88C5\u597D\uFF0C\u91CD\u542F\u5BBF\u4E3B\u540E\u751F\u6548\u3002", draft: true },
249
+ "batch.banner.restart-action": { en: "Restart the host to run the new version; this is a normal end state, not a failure.", zh: "\u91CD\u542F\u5BBF\u4E3B\uFF0C\u8BA9\u65B0\u7248\u8DD1\u8D77\u6765\uFF1B\u8FD9\u662F\u6B63\u5E38\u7EC8\u6001\uFF0C\u4E0D\u662F\u5931\u8D25\u3002", draft: true },
250
+ "batch.banner.restart-button": { en: "Restart host", zh: "\u91CD\u542F\u5BBF\u4E3B", draft: true },
251
+ "batch.row.queued-generic": { en: "Queued \xB7 waiting for the running install to finish", zh: "\u5DF2\u6392\u961F \xB7 \u7B49\u524D\u9762\u5B89\u88C5\u5B8C", draft: true },
252
+ "batch.row.queued-n": { en: "Queued \xB7 {n} ahead", zh: "\u5DF2\u6392\u961F \xB7 \u524D\u65B9 {n} \u4E2A", draft: true },
253
+ "batch.row.skipped": { en: "Skipped {version}", zh: "\u5DF2\u8DF3\u8FC7 {version}", draft: true },
254
+ "batch.row.wait-turn": { en: "Waiting for its turn; it will check automatically", zh: "\u7B49\u5B83\uFF0C\u8F6E\u5230\u5C31\u81EA\u52A8\u67E5\u65B0\u7248", draft: true },
255
+ "batch.row.checking": { en: "Checking for updates; please wait", zh: "\u6B63\u5728\u67E5\u65B0\u7248\uFF0C\u7A0D\u7B49", draft: true },
256
+ "batch.row.cta-version": { en: "Select \u201CInstall this plugin\u201D to install {version}", zh: "\u70B9\u300C\u5B89\u88C5\u8FD9\u5BB6\u300D\u5B89\u88C5 {version}", draft: true },
257
+ "batch.row.cta-generic": { en: "Select \u201CInstall this plugin\u201D to install the new version", zh: "\u70B9\u300C\u5B89\u88C5\u8FD9\u5BB6\u300D\u5B89\u88C5\u65B0\u7248", draft: true },
258
+ "batch.row.installing": { en: "Installing; please wait", zh: "\u6B63\u5728\u5B89\u88C5\uFF0C\u522B\u52A8", draft: true },
259
+ "batch.row.done-restart": { en: "Installed; restart the host to take effect", zh: "\u5B89\u88C5\u597D\u4E86\uFF0C\u91CD\u542F\u5BBF\u4E3B\u624D\u751F\u6548", draft: true },
260
+ "batch.row.done": { en: "Installed; nothing to do", zh: "\u5B89\u88C5\u597D\u4E86\uFF0C\u4E0D\u7528\u52A8", draft: true },
261
+ "batch.row.failed-retry": { en: "Install failed; select \u201CRetry\u201D to try again", zh: "\u5B89\u88C5\u6CA1\u6210\u529F\uFF0C\u70B9\u300C\u91CD\u8BD5\u300D\u518D\u6765\u4E00\u6B21", draft: true },
262
+ "batch.row.skipped-idle": { en: "This version is skipped; nothing to do", zh: "\u8FD9\u4E00\u7248\u5DF2\u8DF3\u8FC7\uFF0C\u4E0D\u7528\u52A8", draft: true },
263
+ "batch.row.unknown": { en: "Unknown state; select \u201CCheck for updates\u201D to check again", zh: "\u72B6\u6001\u8BA4\u4E0D\u51FA\uFF0C\u70B9\u300C\u68C0\u67E5\u66F4\u65B0\u300D\u91CD\u67E5\u4E00\u6B21", draft: true },
264
+ "batch.row-action.installing": { en: "Installing\u2026", zh: "\u5B89\u88C5\u4E2D\u2026", draft: true },
265
+ "batch.row-action.cancel-queue": { en: "Cancel queue", zh: "\u53D6\u6D88\u6392\u961F", draft: true },
266
+ "batch.row-action.queue": { en: "Join queue", zh: "\u52A0\u5165\u961F\u5217", draft: true },
267
+ "batch.row-action.install-row": { en: "Install this plugin", zh: "\u5B89\u88C5\u8FD9\u5BB6", draft: true },
268
+ "batch.row-action.retry": { en: "Retry", zh: "\u91CD\u8BD5", draft: true },
269
+ "batch.row-action.install-version": { en: "Install {version}", zh: "\u5B89\u88C5 {version}", draft: true },
270
+ "batch.row-action.install-generic": { en: "Install the new version", zh: "\u5B89\u88C5 \u65B0\u7248", draft: true },
271
+ "batch.row-action.unskip": { en: "Restore ({version})", zh: "\u6062\u590D\uFF08{version}\uFF09", draft: true },
272
+ "batch.row-action.restart": { en: "Restart host", zh: "\u91CD\u542F\u5BBF\u4E3B", draft: true },
273
+ "batch.row-action.show-detail": { en: "Details", zh: "\u8BE6\u60C5", draft: true },
274
+ "batch.row-action.hide-detail": { en: "Collapse", zh: "\u6536\u8D77", draft: true },
275
+ "batch.row-action.skip": { en: "Skip this version", zh: "\u8DF3\u8FC7\u8FD9\u4E00\u7248", draft: true },
276
+ "batch.row-action.copy-manual": { en: "Copy manual command", zh: "\u590D\u5236\u624B\u5DE5\u547D\u4EE4", draft: true },
277
+ "batch.row-action.copy-diag": { en: "Copy diagnostics", zh: "\u590D\u5236\u8BCA\u65AD", draft: true },
278
+ "batch.row.error-label": { en: "Failed {code}: {detail}", zh: "\u5931\u8D25 {code}\uFF1A{detail}", draft: true },
279
+ "batch.diag.source-job": { en: "(Source: background job record)", zh: "\uFF08\u6765\u6E90\uFF1A\u540E\u53F0\u4EFB\u52A1\u6536\u5C3E\u8BB0\u5F55\uFF09", draft: true },
280
+ "batch.toast.copy-fail": { en: "Copy failed; please select the info above manually.", zh: "\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u9009\u4E2D\u4E0A\u9762\u7684\u4FE1\u606F\u3002", draft: true },
281
+ "batch.toast.queue-missed": { en: "Another install is running: this plugin is not queued yet; try again after it finishes.", zh: "\u524D\u9762\u8FD8\u5728\u88C5\uFF1A\u8FD9\u4E00\u5BB6\u8FD8\u6CA1\u6392\u4E0A\uFF0C\u7B49\u90A3\u5BB6\u88C5\u5B8C\u518D\u70B9\u4E00\u6B21\u3002", draft: true },
282
+ "batch.toast.skipped": { en: "Skipped {version}: no further reminders for this version; select \u201CRestore\u201D to undo.", zh: "\u5DF2\u8DF3\u8FC7 {version}\uFF1A\u8FD9\u4E00\u7248\u4E0D\u518D\u63D0\u9192\uFF1B\u70B9\u300C\u6062\u590D\u300D\u53EF\u64A4\u9500\u3002", draft: true },
283
+ "batch.toast.unskipped-version": { en: "Restored {version}: reminders for this version are back on.", zh: "\u5DF2\u6062\u590D {version}\uFF1A\u8FD9\u4E00\u7248\u4F1A\u7167\u5E38\u63D0\u9192\u3002", draft: true },
284
+ "batch.toast.unskipped-all": { en: "Skip reminder restored.", zh: "\u5DF2\u6062\u590D\u8DF3\u8FC7\u63D0\u9192\u3002", draft: true },
285
+ "batch.toast.cancel-unavailable": { en: "This row carries no phone or ID to cancel the queue; try again after the next refresh.", zh: "\u8FD9\u4E00\u884C\u6CA1\u5E26\u53D6\u6D88\u6392\u961F\u8981\u7528\u7684\u7535\u8BDD\u540D\u6216\u7F16\u53F7\uFF0C\u6682\u4E0D\u80FD\u53D6\u6D88\uFF1A\u7B49\u4E0B\u4E00\u6B21\u5237\u65B0\u518D\u770B\u3002", draft: true },
286
+ "batch.toast.cancel-ok": { en: "Queue cancelled: this plugin will not wait.", zh: "\u5DF2\u53D6\u6D88\u6392\u961F\uFF1A\u8FD9\u4E00\u5BB6\u4E0D\u7B49\u4E86\u3002", draft: true },
287
+ "batch.toast.cancel-fail": { en: "Could not cancel the queue (it may have started installing); see the latest state below.", zh: "\u53D6\u6D88\u6392\u961F\u6CA1\u6210\u529F\uFF08\u53EF\u80FD\u5DF2\u7ECF\u5F00\u59CB\u88C5\u4E86\uFF09\uFF1A\u770B\u4E0B\u9762\u6700\u65B0\u72B6\u6001\u3002", draft: true },
288
+ "batch.toast.copy-manual-ok": { en: "Manual command copied; paste the full line into the terminal to run it.", zh: "\u624B\u5DE5\u547D\u4EE4\u5DF2\u590D\u5236\uFF0C\u7C98\u5230\u7EC8\u7AEF\u6574\u884C\u6267\u884C\u5373\u53EF\u3002", draft: true },
289
+ "batch.toast.copy-diag-ok": { en: "Diagnostics copied; paste it to the plugin author (already redacted).", zh: "\u8BCA\u65AD\u5DF2\u590D\u5236\uFF0C\u76F4\u63A5\u7C98\u7ED9\u63D2\u4EF6\u4F5C\u8005\u5373\u53EF\uFF08\u5DF2\u8131\u654F\uFF09\u3002", draft: true },
290
+ "batch.toast.restart-delegated": { en: "Handled by the caller\u2019s restart flow; the new version takes effect after restart.", zh: "\u5DF2\u6309\u8C03\u7528\u65B9\u7684\u91CD\u542F\u6D41\u7A0B\u5904\u7406\uFF1B\u91CD\u542F\u540E\u65B0\u7248\u751F\u6548\u3002", draft: true },
291
+ "batch.toast.restart-manual": { en: "This host provides no restart entry; please restart the host manually. The new version takes effect after restart.", zh: "\u672C\u5BBF\u4E3B\u672A\u63D0\u4F9B\u91CD\u542F\u5165\u53E3\uFF1A\u8BF7\u624B\u52A8\u91CD\u542F\u5BBF\u4E3B\uFF0C\u91CD\u542F\u540E\u65B0\u7248\u751F\u6548\u3002", draft: true },
292
+ "batch.toast.restart-failed": { en: "Restart entry failed; please restart the host manually. The new version takes effect after restart.", zh: "\u91CD\u542F\u5165\u53E3\u8C03\u7528\u5931\u8D25\uFF1A\u8BF7\u624B\u52A8\u91CD\u542F\u5BBF\u4E3B\uFF0C\u91CD\u542F\u540E\u65B0\u7248\u751F\u6548\u3002", draft: true },
293
+ "changelog.neutral.hint": { en: "No changelog provided", zh: "\u4F5C\u8005\u672A\u63D0\u4F9B\u66F4\u65B0\u8BF4\u660E", draft: true },
294
+ "changelog.neutral.line": { en: "No changelog provided. Install is not affected.", zh: "\u4F5C\u8005\u672A\u63D0\u4F9B\u66F4\u65B0\u8BF4\u660E\uFF0C\u5B89\u88C5\u4E0D\u53D7\u5F71\u54CD\u3002", draft: true },
295
+ "changelog.breaking.badge": { en: "Breaking", zh: "\u4E0D\u517C\u5BB9", draft: true },
296
+ "changelog.breaking.aria": { en: "Breaking change", zh: "\u7834\u574F\u6027\u53D8\u66F4", draft: true },
297
+ "changelog.truncated.count": { en: "Showing {n} of {m} items", zh: "\u5171 {m} \u6761\uFF0C\u4EC5\u663E\u793A\u524D {n} \u6761", draft: true },
298
+ "changelog.yanked.banner": { en: "Version {version} was yanked by the author. Install is not affected. Please confirm before proceeding.", zh: "\u76EE\u6807\u7248\u672C {version} \u5DF2\u88AB\u4F5C\u8005\u64A4\u56DE\uFF08yanked\uFF09\uFF0C\u5B89\u88C5\u4E0D\u53D7\u5F71\u54CD\uFF0C\u7EE7\u7EED\u524D\u8BF7\u786E\u8BA4\u3002", draft: true },
299
+ "changelog.yanked.suffix": { en: " \xB7 Yanked", zh: " \xB7 \u5DF2\u64A4\u56DE", draft: true },
300
+ "changelog.security.summary": { en: "{n} more items", zh: "\u5176\u4F59 {n} \u6761", draft: true },
301
+ "changelog.security.note": { en: "Remaining entries are collapsed to keep the panel fast. See the original text.", zh: "\u4E3A\u4FDD\u6301\u9762\u677F\u6027\u80FD\uFF0C\u5176\u4F59\u6761\u76EE\u5DF2\u6298\u53E0\uFF0C\u53EF\u67E5\u770B\u539F\u6587\u3002", draft: true },
302
+ "diag.fallback.generic": { en: "Operation failed", zh: "\u64CD\u4F5C\u5931\u8D25", draft: true },
303
+ "diag.fallback.read-installed": { en: "Failed to read local state", zh: "\u8BFB\u672C\u5730\u72B6\u6001\u6CA1\u6210\u529F", draft: true },
304
+ "diag.fallback.revalidate-fetch": { en: "Revalidation fetch failed before install", zh: "\u88C5\u524D\u91CD\u9A8C\u53D6\u6570\u6CA1\u6210\u529F", draft: true },
305
+ "diag.fallback.rate-limited": { en: "Source returned 429. Too many requests this minute.", zh: "\u6E90\u8FD4\u56DE 429\uFF0C\u8FD9\u4E00\u5206\u949F\u8BF7\u6C42\u592A\u591A", draft: true },
306
+ "diag.fallback.http-status": { en: "Source returned {status}. Retry still failed.", zh: "\u6E90\u8FD4\u56DE {status}\uFF0C\u91CD\u8BD5\u4ECD\u5931\u8D25", draft: true },
307
+ "diag.fallback.invalid-release": { en: "Version in the manifest is not valid", zh: "\u6E05\u5355\u91CC\u7684\u7248\u672C\u53F7\u4E0D\u662F\u5408\u6CD5\u7248\u672C", draft: true },
308
+ "diag.fallback.install-failed": { en: "Install failed", zh: "\u5B89\u88C5\u5931\u8D25", draft: true },
309
+ "diag.fallback.unknown-profile": { en: "Scope or plugin location not recognized", zh: "\u4F7F\u7528\u8303\u56F4\u6216\u63D2\u4EF6\u4F4D\u7F6E\u8BA4\u4E0D\u51FA", draft: true },
310
+ "diag.fallback.source-install": { en: "Installed from source, not by version", zh: "\u5F53\u524D\u662F\u4ECE\u6E90\u7801\u88C5\u7684\uFF0C\u4E0D\u662F\u6309\u7248\u672C\u53F7\u88C5\u7684", draft: true },
311
+ "diag.fallback.invalid-installation": { en: "Installed package is incomplete", zh: "\u5DF2\u88C5\u7684\u5305\u4E0D\u5B8C\u6574", draft: true },
312
+ "diag.fallback.installation-changed": { en: "Install location changed during use", zh: "\u5B89\u88C5\u4F4D\u7F6E\u5728\u4F7F\u7528\u4E2D\u9014\u53D8\u4E86", draft: true },
313
+ "diag.fallback.pending-restart": { en: "New version is on disk. The running version is still the old one.", zh: "\u65B0\u7248\u5DF2\u88C5\u5230\u78C1\u76D8\uFF0C\u6B63\u5728\u8DD1\u7684\u8FD8\u662F\u65E7\u7248", draft: true },
314
+ "diag.fallback.incompatible-node": { en: "New version needs a different Node version than the running one", zh: "\u65B0\u7248\u8981\u6C42\u7684 Node \u4E0E\u5F53\u524D\u8FD0\u884C\u7684\u5BF9\u4E0D\u4E0A", draft: true },
315
+ "diag.fallback.registry-conflict": { en: "Declared version conflicts with the on-disk version", zh: "\u672C\u5730\u58F0\u660E\u7684\u7248\u672C\u4E0E\u78C1\u76D8\u5B9E\u9645\u7248\u672C\u4E92\u76F8\u77DB\u76FE", draft: true },
316
+ "diag.fallback.recovery-required": { en: "Last install was interrupted, leaving a partial task", zh: "\u4E0A\u6B21\u5B89\u88C5\u88AB\u6253\u65AD\uFF0C\u7559\u4E0B\u4E00\u4E2A\u534A\u622A\u4EFB\u52A1", draft: true }
11
317
  };
12
318
  function escapeHtml(value) {
13
319
  return String(value ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
@@ -25,15 +331,22 @@ function bilingualEntry(key) {
25
331
  if (!hit) throw new Error("[dsh-plugin-update] \u672A\u77E5\u6587\u6848 key\uFF1A" + String(key));
26
332
  return hit;
27
333
  }
28
- function bilingualText(key, values) {
334
+ function copyText(key, lang, values) {
335
+ const l = normalizeLangTag(lang ?? "zh");
29
336
  const e = bilingualEntry(key);
30
- return formatTemplate(e.en, values) + " " + formatTemplate(e.zh, values);
337
+ return formatTemplate(l === "en" ? e.en : e.zh, values);
31
338
  }
32
- function bilingualHTML(key, values) {
339
+ function copyHTML(key, lang, values) {
340
+ const l = normalizeLangTag(lang ?? "zh");
33
341
  const e = bilingualEntry(key);
34
- const en = escapeHtml(formatTemplate(e.en, values));
35
- const zh = escapeHtml(formatTemplate(e.zh, values));
36
- return '<span class="dsh-upd-bi"><span lang="en">' + en + '</span> <span lang="zh">' + zh + "</span></span>";
342
+ const text = escapeHtml(formatTemplate(l === "en" ? e.en : e.zh, values));
343
+ return '<span class="dsh-upd-bi"><span lang="' + l + '">' + text + "</span></span>";
344
+ }
345
+ function bilingualText(key, values) {
346
+ return copyText(key, resolveLang(), values);
347
+ }
348
+ function bilingualHTML(key, values) {
349
+ return copyHTML(key, resolveLang(), values);
37
350
  }
38
351
  function isDraft(key) {
39
352
  return bilingualEntry(key).draft;
@@ -42,9 +355,8 @@ function draftKeys() {
42
355
  return Object.keys(BILINGUAL_STRINGS).filter((k) => BILINGUAL_STRINGS[k].draft);
43
356
  }
44
357
  const BILINGUAL_CSS = [
45
- ".dsh-upd-bi{display:inline-flex;align-items:baseline;gap:.5em;max-width:100%}",
46
- '.dsh-upd-bi [lang="en"],.dsh-upd-bi [lang="zh"]{overflow-wrap:anywhere}',
47
- "@media (max-width:360px){.dsh-upd-bi{flex-direction:column;gap:0}}"
358
+ ".dsh-upd-bi{display:inline;overflow-wrap:anywhere}",
359
+ ".dsh-upd-bi [lang]{overflow-wrap:anywhere}"
48
360
  ].join("\n");
49
361
  export {
50
362
  BILINGUAL_CSS,
@@ -53,6 +365,8 @@ export {
53
365
  bilingualEntry,
54
366
  bilingualHTML,
55
367
  bilingualText,
368
+ copyHTML,
369
+ copyText,
56
370
  draftKeys,
57
371
  isDraft
58
372
  };
@@ -20,11 +20,12 @@
20
20
  * - 截断数值不动(100 节/每类 200 条/单条 500 字/全文 64K),解析附计数元数据只记数字;
21
21
  * 超限类标计数小字,Security 超限进内折叠;BREAKING 前缀识别 + 行首徽标;yanked 横幅只看 to 版。
22
22
  */
23
+ import { type AppLang } from './lang.js';
23
24
  /** 包内日志文件名(包根,与 tarball 内同名文件同一名字)。 */
24
25
  export declare const CHANGELOG_FILENAME = "CHANGELOG.md";
25
- /** 缺日志时的中性提示(不挡安装,安装按钮状态不变)。 */
26
+ /** 缺日志时的中性提示(不挡安装,安装按钮状态不变;zh 原文,渲染走字典 changelog.neutral.hint,留常量只为兼容既有导入)。 */
26
27
  export declare const CHANGELOG_NEUTRAL_HINT = "\u4F5C\u8005\u672A\u63D0\u4F9B\u66F4\u65B0\u8BF4\u660E";
27
- /** 中性提示完整行(含“安装不受影响”,把“不挡安装”说成人话)。 */
28
+ /** 中性提示完整行(含“安装不受影响”,把“不挡安装”说成人话;渲染走字典 changelog.neutral.line)。 */
28
29
  export declare const CHANGELOG_NEUTRAL_LINE = "\u4F5C\u8005\u672A\u63D0\u4F9B\u66F4\u65B0\u8BF4\u660E\uFF0C\u5B89\u88C5\u4E0D\u53D7\u5F71\u54CD\u3002";
29
30
  /** 输入上限(字符):超限截断后解析,永不抛错、不OOM。 */
30
31
  export declare const CHANGELOG_MAX_CHARS: number;
@@ -79,8 +80,12 @@ export declare function matchVersionHeading(line: unknown): string | null;
79
80
  export declare function matchCategoryHeading(line: unknown): string | null;
80
81
  export declare function matchBulletBody(line: unknown): string | null;
81
82
  export declare function isFenceToggle(line: unknown): boolean;
82
- /** 破坏标记徽标文案(中文 UI 一致,原文前缀另行加粗保留)。 */
83
+ /** 破坏标记徽标文案(中文 UI 一致,原文前缀另行加粗保留;渲染走字典 changelog.breaking.badge/aria,留常量只为兼容既有导入)。 */
83
84
  export declare const BREAKING_BADGE_TEXT = "\u4E0D\u517C\u5BB9";
85
+ /** 六类标题按当前语言单语组装(#66,唯一源仍是 CATEGORY_ZH,不另起第二套映射):中文「新增(Added)」观感、英文「Added」。 */
86
+ export declare function changelogCategoryLabel(cat: ChangelogCategory, lang?: AppLang | string | null): string;
87
+ /** 折叠类标题(含条数):中文「弃用预告(Deprecated)(3)」/英文「Deprecated (3)」;条数是变量值,不译。 */
88
+ export declare function changelogFoldedLabel(cat: ChangelogCategory, count: number, lang?: AppLang | string | null): string;
84
89
  /** 剥行首 markdown 装饰(加粗/引用/前后空白),只为识别,渲染保留原文一字不动。 */
85
90
  export declare function stripBreakingDecorations(s: unknown): string;
86
91
  /** 条目是否为破坏标记(去饰后开头匹配,大小写不敏感,中英文冒号皆可)。 */
@@ -122,16 +127,16 @@ export declare function selectChangelogEntries(entries: unknown, fromExclusive:
122
127
  export declare function changelogForUpdate(entries: unknown, runningVersion: unknown, latestVersion: unknown, installedVersion?: unknown): ChangelogEntry[];
123
128
  /** 计数元数据取值(缺省视为与 sections 等长,只记数字)。 */
124
129
  export declare function countsOf(entry: ChangelogEntry | null | undefined): Record<ChangelogCategory, number>;
125
- /** 超限小字(诚实截断):共 M 条,仅显示前 N 条。 */
126
- export declare function truncatedNoteHTML(total: number, shown: number): string;
127
- /** 撤回横幅(只看 to 版,纯展示,不挡安装,文案冻结)。 */
128
- export declare function yankedBannerHTML(version: unknown): string;
129
- /** 单条目 HTML(含破坏标记徽标与前缀加粗,正文一字不动)。 */
130
- export declare function renderChangelogItem(item: string): string;
131
- /** 单节 HTML(调用方保证已过滤 Unreleased 与空节,本函数再兜底一次)。 */
132
- export declare function renderChangelogSection(entry: ChangelogEntry): string;
133
- /** 中性提示 HTML(缺日志、取不到、无区间内容时统一用它,不挡安装)。 */
134
- export declare function renderChangelogNeutral(): string;
130
+ /** 超限小字(诚实截断,#66 入字典单语,lang 缺省 zh 零回归):中文与旧文案一字不差,英文走字典。 */
131
+ export declare function truncatedNoteHTML(total: number, shown: number, lang?: AppLang | string | null): string;
132
+ /** 撤回横幅(只看 to 版,纯展示,不挡安装,#66 入字典单语,lang 缺省 zh 零回归;中文与旧文案一字不差)。 */
133
+ export declare function yankedBannerHTML(version: unknown, lang?: AppLang | string | null): string;
134
+ /** 单条目 HTML(含破坏标记徽标与前缀加粗,正文一字不动;#66 徽标与无障碍名入字典单语,lang 缺省 zh 零回归)。 */
135
+ export declare function renderChangelogItem(item: string, lang?: AppLang | string | null): string;
136
+ /** 单节 HTML(调用方保证已过滤 Unreleased 与空节,本函数再兜底一次;#66 按 lang 单语,缺省 zh 零回归)。 */
137
+ export declare function renderChangelogSection(entry: ChangelogEntry, lang?: AppLang | string | null): string;
138
+ /** 中性提示 HTML(缺日志、取不到、无区间内容时统一用它,不挡安装;#66 入字典单语,lang 缺省 zh 零回归)。 */
139
+ export declare function renderChangelogNeutral(lang?: AppLang | string | null): string;
135
140
  /**
136
141
  * 区间渲染 HTML(纯函数):
137
142
  * entries 非数组/空、无可见区间内容一律回中性提示;
@@ -140,6 +145,7 @@ export declare function renderChangelogNeutral(): string;
140
145
  export declare function renderChangelogHTML(entries: unknown, opts?: {
141
146
  from?: string | null;
142
147
  to?: string | null;
148
+ lang?: AppLang | string | null;
143
149
  }): string;
144
150
  /** 校验诊断(一行一码,行号为原文件 1-based,诊断按行号排序)。 */
145
151
  export interface ChangelogDiagnostic {