dsh-life-pack 0.3.53 → 0.3.55

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/client.js CHANGED
@@ -471,14 +471,14 @@ window.__ModuleLoader__.load({
471
471
  path: "/api/ilife-manager"
472
472
  };
473
473
  //#endregion
474
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.12.0/node_modules/dsh-plugin-update/dist/config.js
474
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.17.0/node_modules/dsh-plugin-update/dist/config.js
475
475
  function assertPrefix(value, role) {
476
476
  if (typeof value !== "string" || value.length === 0) throw new Error("[dsh-plugin-update] " + role + " 非法:须为非空字符串(收到 " + JSON.stringify(value) + ")");
477
477
  if (value.includes(".") || value.includes("/") || value.includes("\\") || /\s/.test(value)) throw new Error("[dsh-plugin-update] " + role + " 非法:不得含有点、路径分隔符或空白(收到 " + JSON.stringify(value) + ")");
478
478
  return value;
479
479
  }
480
480
  //#endregion
481
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.12.0/node_modules/dsh-plugin-update/dist/redaction.js
481
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.17.0/node_modules/dsh-plugin-update/dist/redaction.js
482
482
  const COPY_BUDGET_CHARS = 1500;
483
483
  const REDACTED_PATH = "<路径>";
484
484
  const REDACTED_SECRET = "<脱敏>";
@@ -542,7 +542,7 @@ window.__ModuleLoader__.load({
542
542
  return truncateForCopy(scrubWithoutBudget(flat));
543
543
  }
544
544
  //#endregion
545
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.12.0/node_modules/dsh-plugin-update/dist/service.js
545
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.17.0/node_modules/dsh-plugin-update/dist/service.js
546
546
  function updateError(code) {
547
547
  return Object.assign(new Error(code), { code });
548
548
  }
@@ -629,7 +629,7 @@ window.__ModuleLoader__.load({
629
629
  return 0;
630
630
  }
631
631
  //#endregion
632
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.12.0/node_modules/dsh-plugin-update/dist/lang.js
632
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.17.0/node_modules/dsh-plugin-update/dist/lang.js
633
633
  function normalizeLangTag(tag) {
634
634
  if (typeof tag !== "string") return "zh";
635
635
  const s = tag.trim().toLowerCase().replace(/_/g, "-");
@@ -660,20 +660,41 @@ window.__ModuleLoader__.load({
660
660
  return [];
661
661
  }
662
662
  }
663
+ function overrideTagOf(override) {
664
+ if (override !== null && typeof override === "object") {
665
+ try {
666
+ const fn = override.getActive;
667
+ if (typeof fn === "function") {
668
+ const v = fn.call(override);
669
+ if (typeof v === "string" && v.trim()) return v;
670
+ }
671
+ } catch {}
672
+ return null;
673
+ }
674
+ if (typeof override === "string" && override.trim()) return override;
675
+ return null;
676
+ }
677
+ function langSignalSource(override) {
678
+ if (overrideTagOf(override) !== null) return "override";
679
+ if (readDocumentLang() !== null) return "dom";
680
+ if (readNavigatorLangs().length > 0) return "navigator";
681
+ return "default";
682
+ }
663
683
  function resolveLang(override) {
664
- if (override !== null && typeof override === "object") try {
665
- const fn = override.getActive;
666
- if (typeof fn === "function") {
667
- const v = fn.call(override);
668
- if (typeof v === "string" && v.trim()) return normalizeLangTag(v);
684
+ switch (langSignalSource(override)) {
685
+ case "override": {
686
+ const tag = overrideTagOf(override);
687
+ return tag === null ? "zh" : normalizeLangTag(tag);
669
688
  }
670
- } catch {}
671
- else if (typeof override === "string" && override.trim()) return normalizeLangTag(override);
672
- const docLang = readDocumentLang();
673
- if (docLang !== null) return normalizeLangTag(docLang);
674
- const navs = readNavigatorLangs();
675
- for (const c of navs) return normalizeLangTag(c);
676
- return "zh";
689
+ case "dom": {
690
+ const docLang = readDocumentLang();
691
+ return docLang === null ? "zh" : normalizeLangTag(docLang);
692
+ }
693
+ case "navigator":
694
+ for (const c of readNavigatorLangs()) return normalizeLangTag(c);
695
+ return "zh";
696
+ default: return "zh";
697
+ }
677
698
  }
678
699
  const entries = /* @__PURE__ */ new Set();
679
700
  let mo = null;
@@ -750,7 +771,7 @@ window.__ModuleLoader__.load({
750
771
  };
751
772
  }
752
773
  //#endregion
753
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.12.0/node_modules/dsh-plugin-update/dist/bilingual.js
774
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.17.0/node_modules/dsh-plugin-update/dist/bilingual.js
754
775
  const BILINGUAL_STRINGS = {
755
776
  "entry.label.idle": {
756
777
  en: "Check for updates",
@@ -759,7 +780,7 @@ window.__ModuleLoader__.load({
759
780
  },
760
781
  "entry.label.failed": {
761
782
  en: "Update failed — View details",
762
- zh: "更新失败,点此查看",
783
+ zh: "更新失败,请查看详情",
763
784
  draft: true
764
785
  },
765
786
  "entry.label.busy": {
@@ -774,12 +795,12 @@ window.__ModuleLoader__.load({
774
795
  },
775
796
  "entry.label.has-update": {
776
797
  en: "Update available {version}",
777
- zh: "有新版 {version}",
798
+ zh: "有新版本 {version}",
778
799
  draft: true
779
800
  },
780
801
  "entry.action.checking": {
781
802
  en: "Checking for updates…",
782
- zh: "正在查新版…",
803
+ zh: "正在查询版本信息…",
783
804
  draft: true
784
805
  },
785
806
  "entry.note.up-to-date": {
@@ -794,7 +815,7 @@ window.__ModuleLoader__.load({
794
815
  },
795
816
  "batch-entry.label.update": {
796
817
  en: "{count} updates available",
797
- zh: "{count} 家可更新",
818
+ zh: "{count} 个可更新",
798
819
  draft: true
799
820
  },
800
821
  "batch-entry.label.busy": {
@@ -804,17 +825,17 @@ window.__ModuleLoader__.load({
804
825
  },
805
826
  "batch-entry.label.restart": {
806
827
  en: "{count} restarts required",
807
- zh: "{count} 家待重启",
828
+ zh: "{count} 个待重启",
808
829
  draft: true
809
830
  },
810
831
  "batch-entry.label.failed": {
811
832
  en: "{count} failed — View details",
812
- zh: "{count} 家失败,点此查看",
833
+ zh: "{count} 个失败,请查看详情",
813
834
  draft: true
814
835
  },
815
836
  "batch-entry.action.checking": {
816
837
  en: "Checking for updates…",
817
- zh: "正在查新版…",
838
+ zh: "正在查询版本信息…",
818
839
  draft: true
819
840
  },
820
841
  "panel.blocked.unknown-profile.title": {
@@ -999,7 +1020,7 @@ window.__ModuleLoader__.load({
999
1020
  },
1000
1021
  "panel.seal.update.text": {
1001
1022
  en: "Update available",
1002
- zh: "可装",
1023
+ zh: "可更新",
1003
1024
  draft: true
1004
1025
  },
1005
1026
  "panel.seal.update.mini": {
@@ -1039,7 +1060,7 @@ window.__ModuleLoader__.load({
1039
1060
  },
1040
1061
  "panel.seal.failed.text": {
1041
1062
  en: "Failed — Retry available",
1042
- zh: "受阻",
1063
+ zh: "失败",
1043
1064
  draft: true
1044
1065
  },
1045
1066
  "panel.seal.failed.mini": {
@@ -1049,7 +1070,7 @@ window.__ModuleLoader__.load({
1049
1070
  },
1050
1071
  "panel.seal.done.text": {
1051
1072
  en: "Up to date",
1052
- zh: "已最新",
1073
+ zh: "已是最新",
1053
1074
  draft: true
1054
1075
  },
1055
1076
  "panel.seal.done.mini": {
@@ -1064,7 +1085,7 @@ window.__ModuleLoader__.load({
1064
1085
  },
1065
1086
  "panel.banner.error.action-fallback": {
1066
1087
  en: "Copy the diagnostics for the plugin author; see the log channel for details.",
1067
- zh: "复制诊断发给插件作者;深挖看日志通道。",
1088
+ zh: "请复制诊断信息提交至插件作者;详情请查看日志通道。",
1068
1089
  draft: true
1069
1090
  },
1070
1091
  "panel.action.retry-install": {
@@ -1084,32 +1105,32 @@ window.__ModuleLoader__.load({
1084
1105
  },
1085
1106
  "panel.queue.busy-self": {
1086
1107
  en: "Installing (this plugin is installing).",
1087
- zh: "正在安装(本插件在装)。",
1108
+ zh: "本插件正在安装。",
1088
1109
  draft: true
1089
1110
  },
1090
1111
  "panel.queue.busy-queued": {
1091
1112
  en: "An install is running ahead; this plugin is #{n} in queue. Install when it reaches the front.",
1092
- zh: "前方有安装在进行,本插件排第 {n} 位,到队首再点安装。",
1113
+ zh: "前方有安装正在进行,本插件排第 {n} 位;到队首后请选择安装。",
1093
1114
  draft: true
1094
1115
  },
1095
1116
  "panel.queue.busy-other": {
1096
1117
  en: "Another plugin is installing; retry later.",
1097
- zh: "前方有其他插件在安装,稍后重试。",
1118
+ zh: "前方有其他插件正在安装,请稍后重试。",
1098
1119
  draft: true
1099
1120
  },
1100
1121
  "panel.skip.skipped-title": {
1101
1122
  en: "Skipped {latest}",
1102
- zh: "已跳过 {latest}",
1123
+ zh: "已跳过版本 {latest}",
1103
1124
  draft: true
1104
1125
  },
1105
1126
  "panel.skip.skipped-action": {
1106
1127
  en: "Select “Restore” to be reminded of this version again; newer versions will still notify.",
1107
- zh: "点“恢复”可重新提醒该版本;有更新的新版本会照常提醒。",
1128
+ zh: "选择「恢复提醒」可重新提醒该版本;更新的版本仍会正常提醒。",
1108
1129
  draft: true
1109
1130
  },
1110
1131
  "panel.banner.restart-title": {
1111
1132
  en: "Version {latest} is installed; restart the host to take effect.",
1112
- zh: "新版 {latest} 已安装,重启宿主后生效。",
1133
+ zh: "新版本 {latest} 已安装,重启宿主后生效。",
1113
1134
  draft: true
1114
1135
  },
1115
1136
  "panel.banner.installing-title": {
@@ -1119,27 +1140,27 @@ window.__ModuleLoader__.load({
1119
1140
  },
1120
1141
  "panel.banner.installing-action": {
1121
1142
  en: "Progress refreshes automatically; reopening the panel restores the view within a second.",
1122
- zh: "进度按轮询自动刷新;重开面板 1 秒内恢复显示。",
1143
+ zh: "进度将自动轮询刷新;重新打开面板将在 1 秒内恢复显示。",
1123
1144
  draft: true
1124
1145
  },
1125
1146
  "panel.action.installing": {
1126
1147
  en: "Installing…",
1127
- zh: "安装中…",
1148
+ zh: "正在安装…",
1128
1149
  draft: true
1129
1150
  },
1130
1151
  "panel.banner.update-title": {
1131
1152
  en: "Update available: {latest} (current: {running}).",
1132
- zh: "有新版 {latest} 可装(当前 {running})。",
1153
+ zh: "有新版本 {latest} 可安装(当前版本 {running})。",
1133
1154
  draft: true
1134
1155
  },
1135
1156
  "panel.banner.update-action": {
1136
1157
  en: "Install runs the exact version; only one install runs per scope at a time.",
1137
- zh: "点安装即走精确版本安装;同一使用范围同时只装一个。",
1158
+ zh: "选择安装将按精确版本安装;同一使用范围同时仅安装一项。",
1138
1159
  draft: true
1139
1160
  },
1140
1161
  "panel.action.install-version": {
1141
1162
  en: "Install {latest}",
1142
- zh: "安装 {latest}",
1163
+ zh: "安装版本 {latest}",
1143
1164
  draft: true
1144
1165
  },
1145
1166
  "panel.banner.done": {
@@ -1147,9 +1168,14 @@ window.__ModuleLoader__.load({
1147
1168
  zh: "已是最新,无需更新。",
1148
1169
  draft: true
1149
1170
  },
1171
+ "panel.banner.not-installed": {
1172
+ en: "Not installed",
1173
+ zh: "未安装",
1174
+ draft: true
1175
+ },
1150
1176
  "panel.toast.checking": {
1151
1177
  en: "Checking for updates…",
1152
- zh: "正在查新版…",
1178
+ zh: "正在查询版本信息…",
1153
1179
  draft: true
1154
1180
  },
1155
1181
  "panel.toast.installing": {
@@ -1159,62 +1185,62 @@ window.__ModuleLoader__.load({
1159
1185
  },
1160
1186
  "panel.toast.copy-manual-ok": {
1161
1187
  en: "Manual command copied; paste the full line into the terminal to run it.",
1162
- zh: "手工命令已复制,粘到终端整行执行即可。",
1188
+ zh: "手工命令已复制,请粘贴至终端整行执行。",
1163
1189
  draft: true
1164
1190
  },
1165
1191
  "panel.toast.copy-manual-fail": {
1166
1192
  en: "Copy failed; please select the command above manually.",
1167
- zh: "复制失败,请手动选中上面的命令。",
1193
+ zh: "复制失败,请手动选择上方命令。",
1168
1194
  draft: true
1169
1195
  },
1170
1196
  "panel.toast.copy-diag-ok": {
1171
1197
  en: "Diagnostics copied; paste it to the plugin author (already redacted).",
1172
- zh: "诊断已复制,直接粘给插件作者即可(已脱敏)。",
1198
+ zh: "诊断信息已复制,请提交至插件作者(已脱敏)。",
1173
1199
  draft: true
1174
1200
  },
1175
1201
  "panel.toast.copy-diag-fail": {
1176
1202
  en: "Copy failed; please select the info above manually.",
1177
- zh: "复制失败,请手动选中上面的信息。",
1203
+ zh: "复制失败,请手动选择上方信息。",
1178
1204
  draft: true
1179
1205
  },
1180
1206
  "panel.toast.restart-delegated": {
1181
1207
  en: "Handled by the caller’s restart flow; the new version takes effect after restart.",
1182
- zh: "已按调用方的重启流程处理;重启后新版生效。",
1208
+ zh: "已按调用方重启流程处理;重启后新版本生效。",
1183
1209
  draft: true
1184
1210
  },
1185
1211
  "panel.toast.restart-manual": {
1186
1212
  en: "This host provides no restart entry; please restart the host manually. The new version takes effect after restart.",
1187
- zh: "本宿主未提供重启入口:请手动重启宿主,重启后新版生效。",
1213
+ zh: "本宿主未提供重启入口,请手动重启宿主;重启后新版本生效。",
1188
1214
  draft: true
1189
1215
  },
1190
1216
  "panel.toast.restart-failed": {
1191
1217
  en: "Restart entry failed; please restart the host manually. The new version takes effect after restart.",
1192
- zh: "重启入口调用失败:请手动重启宿主,重启后新版生效。",
1218
+ zh: "重启入口调用失败,请手动重启宿主;重启后新版本生效。",
1193
1219
  draft: true
1194
1220
  },
1195
1221
  "panel.toast.copy-state-ok": {
1196
1222
  en: "Current state copied (no failure); paste it to the plugin author (already redacted).",
1197
- zh: "已复制当前状态(无失败),直接粘给插件作者即可(已脱敏)。",
1223
+ zh: "当前状态已复制(无失败),请提交至插件作者(已脱敏)。",
1198
1224
  draft: true
1199
1225
  },
1200
1226
  "panel.toast.failure-dismissed": {
1201
1227
  en: "Failure acknowledged; it will be re-evaluated on the next check or install.",
1202
- zh: "已确认该失败提示;下次查新版或安装将重新评估。",
1228
+ zh: "已确认该失败提示;下次查询版本信息或安装将重新评估。",
1203
1229
  draft: true
1204
1230
  },
1205
1231
  "panel.strip.running": {
1206
1232
  en: "Running",
1207
- zh: "运行",
1233
+ zh: "运行版",
1208
1234
  draft: true
1209
1235
  },
1210
1236
  "panel.strip.installed": {
1211
1237
  en: "Installed",
1212
- zh: "磁盘",
1238
+ zh: "已安装",
1213
1239
  draft: true
1214
1240
  },
1215
1241
  "panel.strip.latest": {
1216
1242
  en: "Latest",
1217
- zh: "远端",
1243
+ zh: "最新版",
1218
1244
  draft: true
1219
1245
  },
1220
1246
  "panel.meta.label": {
@@ -1269,7 +1295,7 @@ window.__ModuleLoader__.load({
1269
1295
  },
1270
1296
  "panel.progress.installing": {
1271
1297
  en: "Installing new version…",
1272
- zh: "正在安装新版…",
1298
+ zh: "正在安装新版本…",
1273
1299
  draft: true
1274
1300
  },
1275
1301
  "panel.progress.verifying": {
@@ -1279,22 +1305,22 @@ window.__ModuleLoader__.load({
1279
1305
  },
1280
1306
  "panel.action.check": {
1281
1307
  en: "Check for updates",
1282
- zh: "查新版",
1308
+ zh: "检查更新",
1283
1309
  draft: true
1284
1310
  },
1285
1311
  "panel.action.check-title": {
1286
1312
  en: "Check the official source once more (read-only, never installs)",
1287
- zh: "重新向官方源查一次新版(只读,不安装)",
1313
+ zh: "重新向官方源查询版本信息(只读,不安装)",
1288
1314
  draft: true
1289
1315
  },
1290
1316
  "panel.action.checking-busy": {
1291
1317
  en: "Checking for updates…",
1292
- zh: "正在查新版…",
1318
+ zh: "正在查询版本信息…",
1293
1319
  draft: true
1294
1320
  },
1295
1321
  "panel.action.checking-busy-title": {
1296
1322
  en: "Checking the official source; please wait",
1297
- zh: "正在向官方源查询,请稍候",
1323
+ zh: "正在向官方源查询版本信息,请稍候",
1298
1324
  draft: true
1299
1325
  },
1300
1326
  "panel.action.installing-busy": {
@@ -1309,7 +1335,7 @@ window.__ModuleLoader__.load({
1309
1335
  },
1310
1336
  "panel.action.install-title": {
1311
1337
  en: "Install the exact version; one install per scope at a time",
1312
- zh: "用精确版本安装;同一使用范围同时只装一个",
1338
+ zh: "按精确版本安装;同一使用范围同时仅安装一项",
1313
1339
  draft: true
1314
1340
  },
1315
1341
  "panel.action.skip": {
@@ -1319,17 +1345,17 @@ window.__ModuleLoader__.load({
1319
1345
  },
1320
1346
  "panel.action.skip-title": {
1321
1347
  en: "This version will no longer notify; newer versions still will",
1322
- zh: "该版本不再提醒;有更新的新版本照常提醒",
1348
+ zh: "该版本将不再提醒;更新的版本仍会正常提醒",
1323
1349
  draft: true
1324
1350
  },
1325
1351
  "panel.action.unskip": {
1326
1352
  en: "Restore ({version})",
1327
- zh: "恢复({version})",
1353
+ zh: "恢复提醒({version})",
1328
1354
  draft: true
1329
1355
  },
1330
1356
  "panel.action.unskip-title": {
1331
1357
  en: "Undo skip; this version will remind again",
1332
- zh: "撤销跳过,该版本重新提醒",
1358
+ zh: "撤销跳过,该版本将重新提醒",
1333
1359
  draft: true
1334
1360
  },
1335
1361
  "panel.action.copy-manual": {
@@ -1339,7 +1365,7 @@ window.__ModuleLoader__.load({
1339
1365
  },
1340
1366
  "panel.action.copy-manual-title": {
1341
1367
  en: "Copy the manual command; paste the full line into the terminal",
1342
- zh: "复制手工命令,粘到终端整行执行",
1368
+ zh: "复制手工命令,请粘贴至终端整行执行",
1343
1369
  draft: true
1344
1370
  },
1345
1371
  "panel.action.restart-host": {
@@ -1349,17 +1375,17 @@ window.__ModuleLoader__.load({
1349
1375
  },
1350
1376
  "panel.action.restart-host-title": {
1351
1377
  en: "Run the caller restart flow if available, otherwise restart DSH manually",
1352
- zh: "点一下走调用方流程,没有就手动重启 DSH",
1378
+ zh: "优先走调用方重启流程;若无,请手动重启 DSH",
1353
1379
  draft: true
1354
1380
  },
1355
1381
  "panel.action.dismiss": {
1356
1382
  en: "Got it",
1357
- zh: "知道了",
1383
+ zh: "已知晓",
1358
1384
  draft: true
1359
1385
  },
1360
1386
  "panel.action.dismiss-title": {
1361
1387
  en: "Acknowledge the failure and return; next check or install will re-evaluate",
1362
- zh: "确认已知晓该失败:回到可装页,下次查/装将重新评估",
1388
+ zh: "确认已知晓该失败:返回可安装页,下次查询或安装将重新评估",
1363
1389
  draft: true
1364
1390
  },
1365
1391
  "panel.action.copy-diag": {
@@ -1369,17 +1395,17 @@ window.__ModuleLoader__.load({
1369
1395
  },
1370
1396
  "panel.action.copy-diag-title": {
1371
1397
  en: "Copy redacted diagnostics for the plugin author",
1372
- zh: "复制已脱敏诊断,直接粘给插件作者",
1398
+ zh: "复制已脱敏诊断,请提交至插件作者",
1373
1399
  draft: true
1374
1400
  },
1375
1401
  "panel.skip.line-tag": {
1376
1402
  en: "Skipped {version}",
1377
- zh: "已跳过 {version}",
1403
+ zh: "已跳过版本 {version}",
1378
1404
  draft: true
1379
1405
  },
1380
1406
  "panel.skip.line-note": {
1381
1407
  en: "Select “Restore” to undo; this version will remind again.",
1382
- zh: "点「恢复」可撤销,之后这一版还会再提醒。",
1408
+ zh: "选择「恢复提醒」可撤销,该版本此后仍会提醒。",
1383
1409
  draft: true
1384
1410
  },
1385
1411
  "panel.changelog.heading": {
@@ -1394,12 +1420,12 @@ window.__ModuleLoader__.load({
1394
1420
  },
1395
1421
  "panel.changelog.unavailable": {
1396
1422
  en: "Could not read logs; install is unaffected.",
1397
- zh: "日志读不出来,安装不受影响。",
1423
+ zh: "更新日志无法读取,安装不受影响。",
1398
1424
  draft: true
1399
1425
  },
1400
1426
  "panel.changelog.unavailable-empty": {
1401
1427
  en: "No release found yet; logs will show after a check.",
1402
- zh: "还没查到新版;查到后再显示日志。",
1428
+ zh: "尚未查询到新版本;查询到后将显示更新日志。",
1403
1429
  draft: true
1404
1430
  },
1405
1431
  "panel.changelog.toggle-title": {
@@ -1439,17 +1465,17 @@ window.__ModuleLoader__.load({
1439
1465
  },
1440
1466
  "panel.queue.pos-n": {
1441
1467
  en: "Position {n}",
1442
- zh: "第 {n} 位",
1468
+ zh: "排队第 {n} 位",
1443
1469
  draft: true
1444
1470
  },
1445
1471
  "panel.queue.pos-next": {
1446
1472
  en: "You are next",
1447
- zh: "下一个就是你",
1473
+ zh: "下一位就是你",
1448
1474
  draft: true
1449
1475
  },
1450
1476
  "panel.queue.pos-ahead": {
1451
1477
  en: "{n} ahead",
1452
- zh: "前方 {n} 个",
1478
+ zh: "前方还有 {n} 项",
1453
1479
  draft: true
1454
1480
  },
1455
1481
  "panel.queue.row-installing": {
@@ -1459,17 +1485,17 @@ window.__ModuleLoader__.load({
1459
1485
  },
1460
1486
  "panel.queue.row-installing-note": {
1461
1487
  en: "You are next when it finishes",
1462
- zh: "装完自动轮到你",
1488
+ zh: "安装完成后自动轮到你",
1463
1489
  draft: true
1464
1490
  },
1465
1491
  "panel.queue.row-idle-note": {
1466
1492
  en: "One install per scope at a time",
1467
- zh: "同一使用范围一次只装一个",
1493
+ zh: "同一使用范围同时仅安装一项",
1468
1494
  draft: true
1469
1495
  },
1470
1496
  "panel.queue.row-position": {
1471
1497
  en: "Your position",
1472
- zh: "你的顺位",
1498
+ zh: "你的排队顺位",
1473
1499
  draft: true
1474
1500
  },
1475
1501
  "panel.queue.row-order": {
@@ -1479,7 +1505,7 @@ window.__ModuleLoader__.load({
1479
1505
  },
1480
1506
  "panel.queue.toggle-hide": {
1481
1507
  en: "Hide others",
1482
- zh: "隐藏他人明细",
1508
+ zh: "隐藏其他插件明细",
1483
1509
  draft: true
1484
1510
  },
1485
1511
  "panel.queue.toggle-show": {
@@ -1489,7 +1515,7 @@ window.__ModuleLoader__.load({
1489
1515
  },
1490
1516
  "panel.queue.empty": {
1491
1517
  en: "No queued tasks; one install per scope at a time.",
1492
- zh: "当前没有排队任务,同一使用范围一次只装一个。",
1518
+ zh: "当前无排队任务;同一使用范围同时仅安装一项。",
1493
1519
  draft: true
1494
1520
  },
1495
1521
  "panel.error.code-label": {
@@ -1499,7 +1525,7 @@ window.__ModuleLoader__.load({
1499
1525
  },
1500
1526
  "panel.error.code-note": {
1501
1527
  en: "The line above tells you what to do; to report upstream, paste “Copy diagnostics” as a whole (already redacted).",
1502
- zh: "上一条中文说明就是要用户做的事;要往上游报,用「复制诊断」整段粘(已脱敏)。",
1528
+ zh: "上方中文说明即需执行的操作;如需向上游反馈,请使用「复制诊断」整段粘贴(已脱敏)。",
1503
1529
  draft: true
1504
1530
  },
1505
1531
  "panel.error.query-request": {
@@ -1514,47 +1540,47 @@ window.__ModuleLoader__.load({
1514
1540
  },
1515
1541
  "panel.error.failed-at": {
1516
1542
  en: "Failed at {time}",
1517
- zh: "失败于 {time}",
1543
+ zh: "失败时间 {time}",
1518
1544
  draft: true
1519
1545
  },
1520
1546
  "panel.error.query-keys": {
1521
1547
  en: "Query keys: {keys} (use them to match in logs).",
1522
- zh: "本次查询键:{keys}(拿着它们去日志里对)。",
1548
+ zh: "本次查询键:{keys}(可凭此在日志中检索匹配)。",
1523
1549
  draft: true
1524
1550
  },
1525
1551
  "panel.error.target-version": {
1526
1552
  en: "Failed target {version}",
1527
- zh: "失败目标 {version}",
1553
+ zh: "失败目标版本 {version}",
1528
1554
  draft: true
1529
1555
  },
1530
1556
  "panel.error.evidence-frozen": {
1531
1557
  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.",
1532
- zh: "证据已冻结:复制诊断里的码、版本、编号都取自失败时刻,不随轮询刷新;下一次查新版或安装会更新它。",
1558
+ zh: "证据已冻结:复制诊断中的稳定码、版本与编号均取自失败时刻,不随轮询刷新;下次查询版本信息或安装将更新。",
1533
1559
  draft: true
1534
1560
  },
1535
1561
  "panel.error.evidence-transient": {
1536
1562
  en: "Transient read failure: it clears on the next successful read; if it persists, troubleshoot by stable code.",
1537
- zh: "读数瞬态失败:下一次成功读数会自动解除;一直出现再按稳定码排查。",
1563
+ zh: "瞬态读取失败:下次成功读取将自动解除;若持续出现,请按稳定码排查。",
1538
1564
  draft: true
1539
1565
  },
1540
1566
  "panel.error.no-failure": {
1541
1567
  en: "No failure: copying diagnostics gives the current state snapshot.",
1542
- zh: "暂无失败:此时复制诊断给出的是当前状态快照。",
1568
+ zh: "暂无失败:此时复制诊断提供的是当前状态快照。",
1543
1569
  draft: true
1544
1570
  },
1545
1571
  "panel.error.log-hint": {
1546
- en: "Check logs: filter by plugin ID {pluginId} for events {e1}, {e2}, {e3}.",
1547
- zh: "深挖看日志:按插件标识 {pluginId} 过滤 {e1}、{e2}、{e3} 三个事件。",
1572
+ en: "Check logs: {dir} (one directory per plugin, no overlap). Read them with {cmd}; filter by plugin ID {pluginId} for events {e1}, {e2}, {e3}.",
1573
+ zh: "请查看日志:{dir}(一个插件一棵目录,互不覆盖)。一条命令看:{cmd};按插件标识 {pluginId} 筛选 {e1}、{e2}、{e3} 事件。",
1548
1574
  draft: true
1549
1575
  },
1550
1576
  "panel.error.log-follow": {
1551
1577
  en: "Match the request/check IDs above in {eFail}; baseline timing in {eCall}, execution result in {eExec}.",
1552
- zh: "凭上面的请求/检查编号在 {eFail} 里对上;基线耗时看 {eCall},执行结果看 {eExec}。",
1578
+ zh: "凭上方请求/检查编号在 {eFail} 中匹配;基线耗时请查看 {eCall},执行结果请查看 {eExec}。",
1553
1579
  draft: true
1554
1580
  },
1555
1581
  "panel.manual.heading": {
1556
1582
  en: "Manual fallback command (copy the full line to run):",
1557
- zh: "手工兜底命令(复制整行执行):",
1583
+ zh: "手工备用命令(请复制整行执行):",
1558
1584
  draft: true
1559
1585
  },
1560
1586
  "panel.manual.absent": {
@@ -1564,7 +1590,7 @@ window.__ModuleLoader__.load({
1564
1590
  },
1565
1591
  "panel.footer.note": {
1566
1592
  en: "Closing never interrupts updates; come back anytime",
1567
- zh: "关闭不影响更新,可随时回来查看",
1593
+ zh: "关闭窗口,更新不受影响,可随时返回查看。",
1568
1594
  draft: true
1569
1595
  },
1570
1596
  "panel.footer.close": {
@@ -1594,12 +1620,12 @@ window.__ModuleLoader__.load({
1594
1620
  },
1595
1621
  "panel.diag.label.installed": {
1596
1622
  en: "Installed: {version}",
1597
- zh: "已装:{version}",
1623
+ zh: "已安装:{version}",
1598
1624
  draft: true
1599
1625
  },
1600
1626
  "panel.diag.label.latest": {
1601
1627
  en: "Latest: {version}",
1602
- zh: "远端:{version}",
1628
+ zh: "最新版:{version}",
1603
1629
  draft: true
1604
1630
  },
1605
1631
  "panel.diag.queue.installing": {
@@ -1614,7 +1640,7 @@ window.__ModuleLoader__.load({
1614
1640
  },
1615
1641
  "panel.diag.queue.absent": {
1616
1642
  en: "Not queued",
1617
- zh: "不在队列里",
1643
+ zh: "未排队",
1618
1644
  draft: true
1619
1645
  },
1620
1646
  "panel.diag.label.host": {
@@ -1644,12 +1670,12 @@ window.__ModuleLoader__.load({
1644
1670
  },
1645
1671
  "panel.diag.copy.no-detail": {
1646
1672
  en: "(This response carries no diagnostic summary; it will be completed when phone-side diag lands)",
1647
- zh: "(本回包没有带诊断摘要,等电话侧 diag 落定后补齐)",
1673
+ zh: "(本响应未携带诊断摘要,待诊断信息就绪后补全)",
1648
1674
  draft: true
1649
1675
  },
1650
1676
  "panel.diag.copy.unknown-package": {
1651
1677
  en: "(Unknown package)",
1652
- zh: "(未知包)",
1678
+ zh: "(未知插件包)",
1653
1679
  draft: true
1654
1680
  },
1655
1681
  "panel.diag.copy.unknown": {
@@ -1759,17 +1785,17 @@ window.__ModuleLoader__.load({
1759
1785
  },
1760
1786
  "batch.action.resume": {
1761
1787
  en: "Continue the unfinished batch ({count} left)",
1762
- zh: "继续上次未完成的更新(还剩 {count} 家)",
1788
+ zh: "继续上次未完成的更新(剩余 {count} 个)。",
1763
1789
  draft: true
1764
1790
  },
1765
1791
  "batch.action.resume-title": {
1766
1792
  en: "Continue from where it stopped; installed ones stay",
1767
- zh: "从上次没做完的地方接着安装,已完成的不重装",
1793
+ zh: "从上次中断处继续安装,已完成的不会重复安装。",
1768
1794
  draft: true
1769
1795
  },
1770
1796
  "batch.action.discard": {
1771
1797
  en: "Discard this unfinished batch (installed ones stay)",
1772
- zh: "丢弃这批未完成的更新(已完成的保留)",
1798
+ zh: "丢弃本批未完成的更新(已完成的将保留)。",
1773
1799
  draft: true
1774
1800
  },
1775
1801
  "batch.action.confirm-discard": {
@@ -1779,7 +1805,7 @@ window.__ModuleLoader__.load({
1779
1805
  },
1780
1806
  "batch.fact.close-safe": {
1781
1807
  en: "Closing this panel won't stop it — progress is saved on disk.",
1782
- zh: "关掉面板不会中断:进度已写盘,回来可继续。",
1808
+ zh: "关闭面板不会中断更新:进度已保存,可随时返回继续。",
1783
1809
  draft: true
1784
1810
  },
1785
1811
  "batch.setting.check-on-open": {
@@ -1789,97 +1815,102 @@ window.__ModuleLoader__.load({
1789
1815
  },
1790
1816
  "batch.row.update": {
1791
1817
  en: "Update available {version}",
1792
- zh: "有新版 {version}",
1818
+ zh: "有新版本 {version}",
1793
1819
  draft: true
1794
1820
  },
1795
1821
  "batch.row.current": {
1796
1822
  en: "Up to date",
1797
- zh: "已是最新,不用动",
1823
+ zh: "已是最新,无需操作。",
1798
1824
  draft: true
1799
1825
  },
1800
1826
  "batch.row.never": {
1801
1827
  en: "Not checked yet",
1802
- zh: "还没查过",
1828
+ zh: "尚未查询",
1803
1829
  draft: true
1804
1830
  },
1805
1831
  "batch.row.failed": {
1806
1832
  en: "Last check failed",
1807
- zh: "这次没查到",
1833
+ zh: "本次未能查询",
1834
+ draft: true
1835
+ },
1836
+ "batch.row.not-installed": {
1837
+ en: "Not installed",
1838
+ zh: "未安装",
1808
1839
  draft: true
1809
1840
  },
1810
1841
  "batch.notice.auto-resumed": {
1811
1842
  en: "Auto-continued the unfinished batch ({count} left).",
1812
- zh: "已自动继续上次未完成的更新(还剩 {count} 家)。",
1843
+ zh: "已自动继续上次未完成的更新(剩余 {count} 个)。",
1813
1844
  draft: true
1814
1845
  },
1815
1846
  "batch.notice.resumed": {
1816
1847
  en: "Continued the unfinished batch ({count} left).",
1817
- zh: "已继续上次未完成的更新(还剩 {count} 家)。",
1848
+ zh: "已继续上次未完成的更新(剩余 {count} 个)。",
1818
1849
  draft: true
1819
1850
  },
1820
1851
  "batch.notice.no-resume": {
1821
1852
  en: "Nothing to continue.",
1822
- zh: "没有可继续的内容。",
1853
+ zh: "暂无可继续的内容。",
1823
1854
  draft: true
1824
1855
  },
1825
1856
  "batch.notice.discarded": {
1826
1857
  en: "Discarded this unfinished batch (installed ones stay).",
1827
- zh: "已丢弃这批未完成的更新(已完成的保留)。",
1858
+ zh: "已丢弃本批未完成的更新(已完成的将保留)。",
1828
1859
  draft: true
1829
1860
  },
1830
1861
  "batch.notice.cancel-confirm": {
1831
1862
  en: "Click again to confirm discard.",
1832
- zh: "再点一次确认丢弃。",
1863
+ zh: "请再次选择以确认丢弃。",
1833
1864
  draft: true
1834
1865
  },
1835
1866
  "batch.notice.busy-cancel": {
1836
1867
  en: "An install is running and cannot be stopped.",
1837
- zh: "正在装的那一家停不了。",
1868
+ zh: "正在安装的项无法停止。",
1838
1869
  draft: true
1839
1870
  },
1840
1871
  "batch.row.unfinished-tag": {
1841
1872
  en: "unfinished last time",
1842
- zh: "上一批没做完",
1873
+ zh: "上次未完成",
1843
1874
  draft: true
1844
1875
  },
1845
1876
  "batch.summary.updatable": {
1846
1877
  en: "{n} updates available",
1847
- zh: "{n} 家可更新",
1878
+ zh: "{n} 个可更新",
1848
1879
  draft: true
1849
1880
  },
1850
1881
  "batch.summary.installing": {
1851
1882
  en: "{n} installing",
1852
- zh: "{n} 家安装中",
1883
+ zh: "{n} 个安装中",
1853
1884
  draft: true
1854
1885
  },
1855
1886
  "batch.summary.pending": {
1856
1887
  en: "{n} not checked",
1857
- zh: "{n} 家待查",
1888
+ zh: "{n} 个待查询",
1858
1889
  draft: true
1859
1890
  },
1860
1891
  "batch.summary.restart": {
1861
1892
  en: "{n} restart required",
1862
- zh: "{n} 家待重启",
1893
+ zh: "{n} 个待重启",
1863
1894
  draft: true
1864
1895
  },
1865
1896
  "batch.summary.failed": {
1866
1897
  en: "{n} failed",
1867
- zh: "{n} 家失败",
1898
+ zh: "{n} 个失败",
1868
1899
  draft: true
1869
1900
  },
1870
1901
  "batch.summary.skipped": {
1871
1902
  en: "{n} skipped",
1872
- zh: "{n} 家已跳过",
1903
+ zh: "{n} 个已跳过",
1873
1904
  draft: true
1874
1905
  },
1875
1906
  "batch.summary.settled": {
1876
1907
  en: "{n} up to date",
1877
- zh: "{n} 家已最新",
1908
+ zh: "{n} 个已是最新",
1878
1909
  draft: true
1879
1910
  },
1880
1911
  "batch.summary.empty": {
1881
1912
  en: "No targets yet",
1882
- zh: "还没有目标",
1913
+ zh: "暂无目标",
1883
1914
  draft: true
1884
1915
  },
1885
1916
  "batch.header.title": {
@@ -1904,7 +1935,7 @@ window.__ModuleLoader__.load({
1904
1935
  },
1905
1936
  "batch.action.install-all-title": {
1906
1937
  en: "Submit all updatable plugins at once; one idempotency key per session",
1907
- zh: "把有新版的几家一次提交;同一会话同一幂等编号",
1938
+ zh: "将有更新的插件一次提交;同一会话使用同一幂等编号。",
1908
1939
  draft: true
1909
1940
  },
1910
1941
  "batch.action.close": {
@@ -1924,47 +1955,47 @@ window.__ModuleLoader__.load({
1924
1955
  },
1925
1956
  "batch.hint.error": {
1926
1957
  en: "Last run failed: follow the red banner below.",
1927
- zh: "刚才那次没成功:看下面的红条,照它说的做一次。",
1958
+ zh: "上次执行失败:请按下方红色横幅提示操作。",
1928
1959
  draft: true
1929
1960
  },
1930
1961
  "batch.hint.empty": {
1931
1962
  en: "No targets yet: select “Check for updates” to see which plugins have updates.",
1932
- zh: "还没有目标:点「检查更新」看看哪几家有新版。",
1963
+ zh: "暂无目标:请选择「检查更新」查看哪些插件有更新。",
1933
1964
  draft: true
1934
1965
  },
1935
1966
  "batch.hint.installing-queueable": {
1936
1967
  en: "Installing {a}; {b} more can join the queue.",
1937
- zh: "正在安装 {a} 家;还有 {b} 家可以点「加入队列」排队等。",
1968
+ zh: "正在安装 {a} 个;另有 {b} 个可选择「加入队列」等待。",
1938
1969
  draft: true
1939
1970
  },
1940
1971
  "batch.hint.installing-auto": {
1941
1972
  en: "Installing {a}; the next starts automatically.",
1942
- zh: "正在安装 {a} 家,安装完自动下一家。",
1973
+ zh: "正在安装 {a} 个,完成后自动安装下一项。",
1943
1974
  draft: true
1944
1975
  },
1945
1976
  "batch.hint.failed": {
1946
1977
  en: "{n} failed to install; retry each one from the failure notes below.",
1947
- zh: "{n} 家安装失败;照下面的失败提示逐家重试。",
1978
+ zh: "{n} 个插件安装失败;请按下方失败提示逐项重试。",
1948
1979
  draft: true
1949
1980
  },
1950
1981
  "batch.hint.updatable": {
1951
1982
  en: "{n} updates available; select “Update all” to install at once, or install each one inline.",
1952
- zh: "{n} 家可更新;点「全部更新」一次安装完,也可以逐家点「安装这家」。",
1983
+ zh: "{n} 个可更新;请选择「全部更新」一次安装完成,也可逐项选择「安装此插件」。",
1953
1984
  draft: true
1954
1985
  },
1955
1986
  "batch.hint.restart": {
1956
1987
  en: "{n} installed; restart the host to take effect.",
1957
- zh: "{n} 家已安装好,重启宿主后生效。",
1988
+ zh: "{n} 个已安装完成,重启宿主后生效。",
1958
1989
  draft: true
1959
1990
  },
1960
1991
  "batch.hint.pending": {
1961
1992
  en: "{n} not checked yet; select “Check for updates” for a round.",
1962
- zh: "{n} 家还没查过;点「检查更新」查一轮。",
1993
+ zh: "{n} 个尚未查询;请选择「检查更新」查询一轮。",
1963
1994
  draft: true
1964
1995
  },
1965
1996
  "batch.hint.done": {
1966
1997
  en: "All up to date; nothing to do.",
1967
- zh: "全部已最新,没有要做的。",
1998
+ zh: "已全部为最新,无需操作。",
1968
1999
  draft: true
1969
2000
  },
1970
2001
  "batch.seal.ledger": {
@@ -1974,7 +2005,7 @@ window.__ModuleLoader__.load({
1974
2005
  },
1975
2006
  "batch.banner.error-title": {
1976
2007
  en: "Failed this time ({code}): {detail}.",
1977
- zh: "这次没成功({code}):{detail}。",
2008
+ zh: "本次执行失败({code}):{detail}。",
1978
2009
  draft: true
1979
2010
  },
1980
2011
  "batch.banner.error-action-fallback": {
@@ -1984,7 +2015,7 @@ window.__ModuleLoader__.load({
1984
2015
  },
1985
2016
  "batch.banner.failed-title": {
1986
2017
  en: "{n} failed to install.",
1987
- zh: "{n} 家安装失败。",
2018
+ zh: "{n} 个插件安装失败。",
1988
2019
  draft: true
1989
2020
  },
1990
2021
  "batch.banner.failed-action": {
@@ -1994,7 +2025,7 @@ window.__ModuleLoader__.load({
1994
2025
  },
1995
2026
  "batch.banner.restart-title": {
1996
2027
  en: "{n} installed; restart the host to take effect.",
1997
- zh: "{n} 家已安装好,重启宿主后生效。",
2028
+ zh: "{n} 个已安装完成,重启宿主后生效。",
1998
2029
  draft: true
1999
2030
  },
2000
2031
  "batch.banner.restart-action": {
@@ -2009,72 +2040,72 @@ window.__ModuleLoader__.load({
2009
2040
  },
2010
2041
  "batch.row.queued-generic": {
2011
2042
  en: "Queued · waiting for the running install to finish",
2012
- zh: "已排队 · 等前面安装完",
2043
+ zh: "已排队 · 等待前方安装完成",
2013
2044
  draft: true
2014
2045
  },
2015
2046
  "batch.row.queued-n": {
2016
2047
  en: "Queued · {n} ahead",
2017
- zh: "已排队 · 前方 {n} 个",
2048
+ zh: "已排队 · 前方还有 {n} 项",
2018
2049
  draft: true
2019
2050
  },
2020
2051
  "batch.row.skipped": {
2021
2052
  en: "Skipped {version}",
2022
- zh: "已跳过 {version}",
2053
+ zh: "已跳过版本 {version}",
2023
2054
  draft: true
2024
2055
  },
2025
2056
  "batch.row.wait-turn": {
2026
2057
  en: "Waiting for its turn; it will check automatically",
2027
- zh: "等它,轮到就自动查新版",
2058
+ zh: "请等待,轮到将自动查询版本信息。",
2028
2059
  draft: true
2029
2060
  },
2030
2061
  "batch.row.checking": {
2031
2062
  en: "Checking for updates; please wait",
2032
- zh: "正在查新版,稍等",
2063
+ zh: "正在查询版本信息,请稍候。",
2033
2064
  draft: true
2034
2065
  },
2035
2066
  "batch.row.cta-version": {
2036
2067
  en: "Select “Install this plugin” to install {version}",
2037
- zh: "点「安装这家」安装 {version}",
2068
+ zh: "选择「安装此插件」安装 {version}",
2038
2069
  draft: true
2039
2070
  },
2040
2071
  "batch.row.cta-generic": {
2041
2072
  en: "Select “Install this plugin” to install the new version",
2042
- zh: "点「安装这家」安装新版",
2073
+ zh: "选择「安装此插件」安装新版本",
2043
2074
  draft: true
2044
2075
  },
2045
2076
  "batch.row.installing": {
2046
2077
  en: "Installing; please wait",
2047
- zh: "正在安装,别动",
2078
+ zh: "正在安装,请勿操作。",
2048
2079
  draft: true
2049
2080
  },
2050
2081
  "batch.row.done-restart": {
2051
2082
  en: "Installed; restart the host to take effect",
2052
- zh: "安装好了,重启宿主才生效",
2083
+ zh: "已安装完成,重启宿主后生效。",
2053
2084
  draft: true
2054
2085
  },
2055
2086
  "batch.row.done": {
2056
2087
  en: "Installed; nothing to do",
2057
- zh: "安装好了,不用动",
2088
+ zh: "已安装完成,无需操作。",
2058
2089
  draft: true
2059
2090
  },
2060
2091
  "batch.row.failed-retry": {
2061
2092
  en: "Install failed; select “Retry” to try again",
2062
- zh: "安装没成功,点「重试」再来一次",
2093
+ zh: "安装失败,请选择「重试」。",
2063
2094
  draft: true
2064
2095
  },
2065
2096
  "batch.row.skipped-idle": {
2066
2097
  en: "This version is skipped; nothing to do",
2067
- zh: "这一版已跳过,不用动",
2098
+ zh: "该版本已跳过,无需操作。",
2068
2099
  draft: true
2069
2100
  },
2070
2101
  "batch.row.unknown": {
2071
2102
  en: "Unknown state; select “Check for updates” to check again",
2072
- zh: "状态认不出,点「检查更新」重查一次",
2103
+ zh: "状态无法识别,请选择「检查更新」重新查询。",
2073
2104
  draft: true
2074
2105
  },
2075
2106
  "batch.row-action.installing": {
2076
2107
  en: "Installing…",
2077
- zh: "安装中…",
2108
+ zh: "正在安装…",
2078
2109
  draft: true
2079
2110
  },
2080
2111
  "batch.row-action.cancel-queue": {
@@ -2089,7 +2120,7 @@ window.__ModuleLoader__.load({
2089
2120
  },
2090
2121
  "batch.row-action.install-row": {
2091
2122
  en: "Install this plugin",
2092
- zh: "安装这家",
2123
+ zh: "安装此插件",
2093
2124
  draft: true
2094
2125
  },
2095
2126
  "batch.row-action.retry": {
@@ -2099,17 +2130,17 @@ window.__ModuleLoader__.load({
2099
2130
  },
2100
2131
  "batch.row-action.install-version": {
2101
2132
  en: "Install {version}",
2102
- zh: "安装 {version}",
2133
+ zh: "安装版本 {version}",
2103
2134
  draft: true
2104
2135
  },
2105
2136
  "batch.row-action.install-generic": {
2106
2137
  en: "Install the new version",
2107
- zh: "安装 新版",
2138
+ zh: "安装新版本",
2108
2139
  draft: true
2109
2140
  },
2110
2141
  "batch.row-action.unskip": {
2111
2142
  en: "Restore ({version})",
2112
- zh: "恢复({version})",
2143
+ zh: "恢复提醒({version})",
2113
2144
  draft: true
2114
2145
  },
2115
2146
  "batch.row-action.restart": {
@@ -2129,7 +2160,7 @@ window.__ModuleLoader__.load({
2129
2160
  },
2130
2161
  "batch.row-action.skip": {
2131
2162
  en: "Skip this version",
2132
- zh: "跳过这一版",
2163
+ zh: "跳过该版本",
2133
2164
  draft: true
2134
2165
  },
2135
2166
  "batch.row-action.copy-manual": {
@@ -2149,27 +2180,27 @@ window.__ModuleLoader__.load({
2149
2180
  },
2150
2181
  "batch.diag.source-job": {
2151
2182
  en: "(Source: background job record)",
2152
- zh: "(来源:后台任务收尾记录)",
2183
+ zh: "(来源:后台任务执行记录)",
2153
2184
  draft: true
2154
2185
  },
2155
2186
  "batch.toast.copy-fail": {
2156
2187
  en: "Copy failed; please select the info above manually.",
2157
- zh: "复制失败,请手动选中上面的信息。",
2188
+ zh: "复制失败,请手动选择上方信息。",
2158
2189
  draft: true
2159
2190
  },
2160
2191
  "batch.toast.queue-missed": {
2161
2192
  en: "Another install is running: this plugin is not queued yet; try again after it finishes.",
2162
- zh: "前面还在装:这一家还没排上,等那家装完再点一次。",
2193
+ zh: "前方仍在安装:此插件尚未排队,请待前方安装完成后再次选择。",
2163
2194
  draft: true
2164
2195
  },
2165
2196
  "batch.toast.skipped": {
2166
2197
  en: "Skipped {version}: no further reminders for this version; select “Restore” to undo.",
2167
- zh: "已跳过 {version}:这一版不再提醒;点「恢复」可撤销。",
2198
+ zh: "已跳过版本 {version}:该版本不再提醒;选择「恢复提醒」可撤销。",
2168
2199
  draft: true
2169
2200
  },
2170
2201
  "batch.toast.unskipped-version": {
2171
2202
  en: "Restored {version}: reminders for this version are back on.",
2172
- zh: "已恢复 {version}:这一版会照常提醒。",
2203
+ zh: "已恢复 {version}:该版本将正常提醒。",
2173
2204
  draft: true
2174
2205
  },
2175
2206
  "batch.toast.unskipped-all": {
@@ -2179,42 +2210,42 @@ window.__ModuleLoader__.load({
2179
2210
  },
2180
2211
  "batch.toast.cancel-unavailable": {
2181
2212
  en: "This row carries no phone or ID to cancel the queue; try again after the next refresh.",
2182
- zh: "这一行没带取消排队要用的电话名或编号,暂不能取消:等下一次刷新再看。",
2213
+ zh: "此行缺少取消排队所需的信息,暂无法取消;请待下次刷新后重试。",
2183
2214
  draft: true
2184
2215
  },
2185
2216
  "batch.toast.cancel-ok": {
2186
2217
  en: "Queue cancelled: this plugin will not wait.",
2187
- zh: "已取消排队:这一家不等了。",
2218
+ zh: "已取消排队:此插件将不再等待。",
2188
2219
  draft: true
2189
2220
  },
2190
2221
  "batch.toast.cancel-fail": {
2191
2222
  en: "Could not cancel the queue (it may have started installing); see the latest state below.",
2192
- zh: "取消排队没成功(可能已经开始装了):看下面最新状态。",
2223
+ zh: "取消排队失败(可能已开始安装):请查看下方最新状态。",
2193
2224
  draft: true
2194
2225
  },
2195
2226
  "batch.toast.copy-manual-ok": {
2196
2227
  en: "Manual command copied; paste the full line into the terminal to run it.",
2197
- zh: "手工命令已复制,粘到终端整行执行即可。",
2228
+ zh: "手工命令已复制,请粘贴至终端整行执行。",
2198
2229
  draft: true
2199
2230
  },
2200
2231
  "batch.toast.copy-diag-ok": {
2201
2232
  en: "Diagnostics copied; paste it to the plugin author (already redacted).",
2202
- zh: "诊断已复制,直接粘给插件作者即可(已脱敏)。",
2233
+ zh: "诊断信息已复制,请提交至插件作者(已脱敏)。",
2203
2234
  draft: true
2204
2235
  },
2205
2236
  "batch.toast.restart-delegated": {
2206
2237
  en: "Handled by the caller’s restart flow; the new version takes effect after restart.",
2207
- zh: "已按调用方的重启流程处理;重启后新版生效。",
2238
+ zh: "已按调用方重启流程处理;重启后新版本生效。",
2208
2239
  draft: true
2209
2240
  },
2210
2241
  "batch.toast.restart-manual": {
2211
2242
  en: "This host provides no restart entry; please restart the host manually. The new version takes effect after restart.",
2212
- zh: "本宿主未提供重启入口:请手动重启宿主,重启后新版生效。",
2243
+ zh: "本宿主未提供重启入口,请手动重启宿主;重启后新版本生效。",
2213
2244
  draft: true
2214
2245
  },
2215
2246
  "batch.toast.restart-failed": {
2216
2247
  en: "Restart entry failed; please restart the host manually. The new version takes effect after restart.",
2217
- zh: "重启入口调用失败:请手动重启宿主,重启后新版生效。",
2248
+ zh: "重启入口调用失败,请手动重启宿主;重启后新版本生效。",
2218
2249
  draft: true
2219
2250
  },
2220
2251
  "changelog.neutral.hint": {
@@ -2242,6 +2273,16 @@ window.__ModuleLoader__.load({
2242
2273
  zh: "共 {m} 条,仅显示前 {n} 条",
2243
2274
  draft: true
2244
2275
  },
2276
+ "changelog.truncated.file": {
2277
+ en: "This log is larger than 64 KiB; only the first part is rendered.",
2278
+ zh: "日志过长,超出上限的部分没有渲染。",
2279
+ draft: true
2280
+ },
2281
+ "changelog.truncated.versions": {
2282
+ en: "{n} more versions are hidden.",
2283
+ zh: "其后还有 {n} 个版本未显示。",
2284
+ draft: true
2285
+ },
2245
2286
  "changelog.yanked.banner": {
2246
2287
  en: "Version {version} was yanked by the author. Install is not affected. Please confirm before proceeding.",
2247
2288
  zh: "目标版本 {version} 已被作者撤回(yanked),安装不受影响,继续前请确认。",
@@ -2259,7 +2300,7 @@ window.__ModuleLoader__.load({
2259
2300
  },
2260
2301
  "changelog.security.note": {
2261
2302
  en: "Remaining entries are collapsed to keep the panel fast. See the original text.",
2262
- zh: "为保持面板性能,其余条目已折叠,可查看原文。",
2303
+ zh: "为保持面板性能,其余条目已折叠,请查看原文。",
2263
2304
  draft: true
2264
2305
  },
2265
2306
  "diag.fallback.generic": {
@@ -2279,12 +2320,12 @@ window.__ModuleLoader__.load({
2279
2320
  },
2280
2321
  "diag.fallback.rate-limited": {
2281
2322
  en: "Source returned 429. Too many requests this minute.",
2282
- zh: "源返回 429,这一分钟请求太多",
2323
+ zh: "数据源返回 429,本分钟请求过于频繁。",
2283
2324
  draft: true
2284
2325
  },
2285
2326
  "diag.fallback.http-status": {
2286
2327
  en: "Source returned {status}. Retry still failed.",
2287
- zh: "源返回 {status},重试仍失败",
2328
+ zh: "数据源返回 {status},重试后仍失败。",
2288
2329
  draft: true
2289
2330
  },
2290
2331
  "diag.fallback.invalid-release": {
@@ -2372,7 +2413,7 @@ window.__ModuleLoader__.load({
2372
2413
  }
2373
2414
  const BILINGUAL_CSS = [".dsh-upd-bi{display:inline;overflow-wrap:anywhere}", ".dsh-upd-bi [lang]{overflow-wrap:anywhere}"].join("\n");
2374
2415
  //#endregion
2375
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.12.0/node_modules/dsh-plugin-update/dist/changelog.js
2416
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.17.0/node_modules/dsh-plugin-update/dist/changelog.js
2376
2417
  const CHANGELOG_MAX_CHARS = 65536;
2377
2418
  const CHANGELOG_ALL_CATEGORIES = [
2378
2419
  "Added",
@@ -2397,6 +2438,27 @@ window.__ModuleLoader__.load({
2397
2438
  Removed: "移除",
2398
2439
  Security: "安全"
2399
2440
  };
2441
+ const CHANGELOG_CATEGORY_ALIASES = {
2442
+ "bug fixes": "Fixed",
2443
+ fixes: "Fixed",
2444
+ fix: "Fixed",
2445
+ "bug fix": "Fixed",
2446
+ features: "Added",
2447
+ feature: "Added",
2448
+ feat: "Added",
2449
+ "security fixes": "Security",
2450
+ "security fix": "Security",
2451
+ deprecations: "Deprecated",
2452
+ removals: "Removed",
2453
+ 修复: "Fixed",
2454
+ 新增: "Added",
2455
+ 特性: "Added",
2456
+ 变更: "Changed",
2457
+ 改动: "Changed",
2458
+ 移除: "Removed",
2459
+ 弃用: "Deprecated",
2460
+ 安全: "Security"
2461
+ };
2400
2462
  function emptySections() {
2401
2463
  return {
2402
2464
  Added: [],
@@ -2428,9 +2490,25 @@ window.__ModuleLoader__.load({
2428
2490
  if (t === "deprecated") return "Deprecated";
2429
2491
  if (t === "removed") return "Removed";
2430
2492
  if (t === "security") return "Security";
2493
+ const alias = CHANGELOG_CATEGORY_ALIASES[t];
2494
+ if (alias) return alias;
2431
2495
  for (const k of CHANGELOG_ALL_CATEGORIES) if (t === CHANGELOG_CATEGORY_ZH[k]) return k;
2432
2496
  return null;
2433
2497
  }
2498
+ function normalizeCategoryMulti(raw) {
2499
+ const t = String(raw || "").trim();
2500
+ if (!t) return null;
2501
+ const parts = t.split(/[/|·、,,;;+]/).map((s) => s.trim()).filter((s) => !!s);
2502
+ if (parts.length <= 1) return normalizeCategory(t);
2503
+ let acc = null;
2504
+ for (const part of parts) {
2505
+ const cat = normalizeCategory(part);
2506
+ if (!cat) return null;
2507
+ if (acc === null) acc = cat;
2508
+ else if (acc !== cat) return null;
2509
+ }
2510
+ return acc;
2511
+ }
2434
2512
  function isUnreleasedVersion(v) {
2435
2513
  return typeof v === "string" && v.trim().toLowerCase() === "unreleased";
2436
2514
  }
@@ -2447,7 +2525,7 @@ window.__ModuleLoader__.load({
2447
2525
  date: null,
2448
2526
  yanked
2449
2527
  };
2450
- const vm = t.match(/(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)/);
2528
+ const vm = t.match(RE_VERSION_TOKEN);
2451
2529
  if (!vm) return {
2452
2530
  version: null,
2453
2531
  date: null,
@@ -2466,28 +2544,110 @@ window.__ModuleLoader__.load({
2466
2544
  if (t.length <= 500) return t;
2467
2545
  return `${t.slice(0, 499)}\u2026`;
2468
2546
  }
2469
- const RE_VERSION_HEADING = /^##(?!#)\s*(.+?)\s*$/;
2470
- const RE_CATEGORY_HEADING = /^###\s*(.+?)\s*$/;
2547
+ function indentLevel(line) {
2548
+ const raw = (String(line || "").match(/^[ \t]*/) || [""])[0];
2549
+ let n = 0;
2550
+ for (const ch of raw) n += ch === " " ? 2 : 1;
2551
+ return Math.min(3, Math.floor(n / 2));
2552
+ }
2553
+ function matchOrderedBody(line) {
2554
+ const m = String(line || "").match(/^\s*\d{1,9}[.)]\s+(.+?)\s*$/);
2555
+ return m ? String(m[1] !== void 0 && m[1] !== null ? m[1] : "") : null;
2556
+ }
2557
+ function truncateEntryLines(lines, ledger) {
2558
+ const out = [];
2559
+ let truncated = false;
2560
+ for (const raw of lines) {
2561
+ const line = String(raw === null || raw === void 0 ? "" : raw).replace(/[ \t]+$/, "");
2562
+ if (!line) continue;
2563
+ if ((out.length > 0 ? out.join("\n") + "\n" + line : line).length <= 500) {
2564
+ out.push(line);
2565
+ continue;
2566
+ }
2567
+ truncated = true;
2568
+ break;
2569
+ }
2570
+ const text = out.join("\n");
2571
+ if (!truncated) return text;
2572
+ if (ledger) ledger.items += 1;
2573
+ if (text.length < 500) return text + "…";
2574
+ return text.slice(0, 499) + "…";
2575
+ }
2576
+ function bufEndsWithItem(lines) {
2577
+ const last = Array.isArray(lines) && lines.length > 0 ? String(lines[lines.length - 1] || "") : "";
2578
+ if (!last) return false;
2579
+ if (RE_FENCE_TOGGLE.test(last)) return true;
2580
+ return /^[ \t]*(?:[-*+]|\d{1,9}[.)])\s+/.test(last);
2581
+ }
2582
+ function canonicalNestedItem(line, level, body) {
2583
+ const m = String(line || "").match(/^[ \t]*(?:([-*+])|(\d{1,9}[.)]))\s+/);
2584
+ const marker = m && m[2] ? m[2] : m && m[1] ? m[1] : "-";
2585
+ return " ".repeat(Math.max(1, level)) + marker + " " + String(body || "").replace(/\s+/g, " ").trim();
2586
+ }
2471
2587
  const RE_BULLET = /^\s*[-*+]\s+(.+?)\s*$/;
2472
2588
  const RE_FENCE_TOGGLE = new RegExp("^\\s*(" + String.fromCharCode(96).repeat(3) + "|~~~)");
2473
- function matchVersionHeading(line) {
2474
- try {
2475
- const m = String(line !== null && line !== void 0 ? line : "").match(RE_VERSION_HEADING);
2476
- if (!m) return null;
2477
- return String(m[1] !== void 0 && m[1] !== null ? m[1] : "").trim();
2478
- } catch {
2479
- return null;
2589
+ const RE_VERSION_NUM = /(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)/;
2590
+ const RE_UNRELEASED = /unreleased/i;
2591
+ const RE_VERSION_TOKEN = /(\d+\.\d+(?:\.\d+)*(?:-[0-9A-Za-z.-]+)?)/;
2592
+ function isPlainVersionTitle(text) {
2593
+ const t = String(text || "").trim();
2594
+ if (!t) return false;
2595
+ if (!/(?:^|[^\d.])v?\d+\.\d+(?![\d.])/.test(t)) return false;
2596
+ const core = t.replace(/\[YANKED\]/gi, " ").replace(/\[([^\]]*)\]\([^)]*\)/g, " ").replace(/\([^)]*\)/g, " ").replace(/([^)]*)/g, " ").replace(/\d{4}-\d{2}-\d{2}/g, " ").replace(/[\[\]()()【】]/g, " ").replace(/^[\s#>*_\-\u2014\u2013::|]+/, "").replace(/[\s#>*_\-\u2014\u2013::|]+$/, "").trim();
2597
+ return /^v?\d+\.\d+$/.test(core);
2598
+ }
2599
+ function isVersionIshWithoutNumber(text) {
2600
+ const t = String(text !== null && text !== void 0 ? text : "").trim();
2601
+ if (!t) return false;
2602
+ if (extractVersionDateAndYanked(t).version) return false;
2603
+ return /^\s*v?\d+\s*(?:$|[\u2014\u2013\-((])/.test(t);
2604
+ }
2605
+ function isSetextTextCandidate(line) {
2606
+ const t = String(line === null || line === void 0 ? "" : line);
2607
+ if (!t.trim()) return false;
2608
+ if (/^[ \t]/.test(t)) return false;
2609
+ if (/^\s{0,3}#{1,6}\s/.test(t)) return false;
2610
+ if (/^\s*(?:[-*+]|\d{1,9}[.)])\s+/.test(t)) return false;
2611
+ if (/^\s*>/.test(t)) return false;
2612
+ if (/^\s*\|/.test(t)) return false;
2613
+ if (isFenceToggle(t)) return false;
2614
+ return true;
2615
+ }
2616
+ function normalizeSetextHeadings(lines) {
2617
+ const out = lines.map((l) => String(l === null || l === void 0 ? "" : l));
2618
+ for (let i = 0; i + 1 < out.length; i++) {
2619
+ const m = out[i + 1].match(/^ {0,3}(={3,}|-{3,})\s*$/);
2620
+ if (!m || !isSetextTextCandidate(out[i])) continue;
2621
+ out[i] = (m[1].charAt(0) === "=" ? "# " : "## ") + out[i].trim();
2622
+ out[i + 1] = "";
2480
2623
  }
2624
+ return out;
2625
+ }
2626
+ const RE_ANY_HEADING = /^\s{0,3}(#{1,6})\s*(.+?)\s*$/;
2627
+ function looksLikeVersionHeading(text) {
2628
+ const t = String(text !== null && text !== void 0 ? text : "").trim();
2629
+ if (!t) return false;
2630
+ if (RE_UNRELEASED.test(t)) return true;
2631
+ if (RE_VERSION_NUM.test(t)) return true;
2632
+ return isPlainVersionTitle(t);
2481
2633
  }
2482
- function matchCategoryHeading(line) {
2634
+ function matchAnyHeading(line) {
2483
2635
  try {
2484
- const m = String(line !== null && line !== void 0 ? line : "").match(RE_CATEGORY_HEADING);
2636
+ const m = String(line !== null && line !== void 0 ? line : "").match(RE_ANY_HEADING);
2485
2637
  if (!m) return null;
2486
- return String(m[1] !== void 0 && m[1] !== null ? m[1] : "").trim();
2638
+ return {
2639
+ level: (m[1] || "").length,
2640
+ text: String(m[2] !== void 0 && m[2] !== null ? m[2] : "").trim()
2641
+ };
2487
2642
  } catch {
2488
2643
  return null;
2489
2644
  }
2490
2645
  }
2646
+ function matchVersionHeadingAny(line) {
2647
+ const h = matchAnyHeading(line);
2648
+ if (!h || h.level > 4) return null;
2649
+ return looksLikeVersionHeading(h.text) ? h.text : null;
2650
+ }
2491
2651
  function matchBulletBody(line) {
2492
2652
  try {
2493
2653
  const m = String(line !== null && line !== void 0 ? line : "").match(RE_BULLET);
@@ -2545,85 +2705,247 @@ window.__ModuleLoader__.load({
2545
2705
  return true;
2546
2706
  }
2547
2707
  }
2548
- function parseChangelog(markdown) {
2708
+ function ensureOther(cur, title) {
2709
+ const list = cur.otherSections ?? (cur.otherSections = []);
2710
+ const last = list[list.length - 1];
2711
+ if (title && last && last.title === "" && last.items.length === 0) {
2712
+ last.title = title.slice(0, 120);
2713
+ return last;
2714
+ }
2715
+ const sec = {
2716
+ title: title.slice(0, 120),
2717
+ items: [],
2718
+ count: 0
2719
+ };
2720
+ list.push(sec);
2721
+ return sec;
2722
+ }
2723
+ function countVersionHeadings(tail) {
2724
+ let n = 0;
2725
+ for (const line of String(tail || "").split("\n")) if (matchVersionHeadingAny(line) !== null) n += 1;
2726
+ return n;
2727
+ }
2728
+ function parseChangelogReport(markdown) {
2729
+ const ledger = {
2730
+ chars: false,
2731
+ tailVersions: 0,
2732
+ entries: 0,
2733
+ sections: 0,
2734
+ sectionItems: 0,
2735
+ items: 0
2736
+ };
2549
2737
  try {
2550
- if (typeof markdown !== "string" || !markdown.trim()) return [];
2738
+ if (typeof markdown !== "string" || !markdown.trim()) return {
2739
+ entries: [],
2740
+ truncation: ledger
2741
+ };
2551
2742
  let text = markdown.replace(/\r\n/g, "\n");
2552
- if (text.length > 65536) text = text.slice(0, CHANGELOG_MAX_CHARS);
2553
- const lines = text.split("\n");
2743
+ if (text.length > 65536) {
2744
+ ledger.chars = true;
2745
+ ledger.tailVersions = countVersionHeadings(text.slice(CHANGELOG_MAX_CHARS));
2746
+ text = text.slice(0, CHANGELOG_MAX_CHARS);
2747
+ }
2748
+ const lines = normalizeSetextHeadings(text.split("\n"));
2554
2749
  const entries = [];
2555
2750
  let cur = null;
2556
- let curCat = null;
2751
+ let bucket = null;
2557
2752
  let inFence = false;
2753
+ let buf = null;
2754
+ const bufNow = () => buf;
2755
+ let fenceTo = null;
2756
+ let fenceIndent = 0;
2757
+ let pendingBlank = false;
2758
+ const destOf = () => {
2759
+ if (!bucket) return null;
2760
+ return "cat" in bucket ? { cat: bucket.cat } : { other: bucket.other };
2761
+ };
2762
+ const ensureDest = () => {
2763
+ const d = destOf();
2764
+ if (d) return d;
2765
+ if (!cur) return null;
2766
+ const other = ensureOther(cur, "");
2767
+ bucket = { other };
2768
+ return { other };
2769
+ };
2770
+ const flushBuf = () => {
2771
+ const pending = buf;
2772
+ buf = null;
2773
+ pendingBlank = false;
2774
+ if (!pending || !cur) return;
2775
+ const text2 = truncateEntryLines(pending.lines, ledger);
2776
+ if (!text2) return;
2777
+ const c = cur;
2778
+ if ("cat" in pending.dest) {
2779
+ c.sections[pending.dest.cat].push(text2);
2780
+ try {
2781
+ if (c.counts) c.counts[pending.dest.cat] += 1;
2782
+ } catch {}
2783
+ } else {
2784
+ pending.dest.other.items.push(text2);
2785
+ pending.dest.other.count = (pending.dest.other.count ?? 0) + 1;
2786
+ }
2787
+ };
2788
+ const openBuf = (first, dest) => {
2789
+ buf = {
2790
+ lines: [first],
2791
+ dest
2792
+ };
2793
+ };
2558
2794
  const pushCurrent = () => {
2795
+ flushBuf();
2559
2796
  if (!cur) return;
2560
- if (!CHANGELOG_ALL_CATEGORIES.some((c) => cur.sections[c].length > 0)) return;
2797
+ const e = cur;
2798
+ if (!(CHANGELOG_ALL_CATEGORIES.some((c) => e.sections[c].length > 0) || (e.otherSections ?? []).some((s) => s.items.length > 0))) return;
2561
2799
  for (const c of CHANGELOG_ALL_CATEGORIES) {
2562
- const list = cur.sections[c];
2563
- if (list.length > 200) cur.sections[c] = list.slice(0, 200);
2800
+ const list = e.sections[c];
2801
+ if (list.length > 200) {
2802
+ ledger.sections += 1;
2803
+ ledger.sectionItems += list.length - 200;
2804
+ e.sections[c] = list.slice(0, 200);
2805
+ }
2564
2806
  }
2565
- entries.push(cur);
2807
+ for (const s of e.otherSections ?? []) if (s.items.length > 200) {
2808
+ ledger.sections += 1;
2809
+ ledger.sectionItems += s.items.length - 200;
2810
+ s.items = s.items.slice(0, 200);
2811
+ }
2812
+ entries.push(e);
2566
2813
  };
2567
2814
  for (const rawLine of lines) {
2568
2815
  const line = String(rawLine ?? "");
2569
2816
  if (isFenceToggle(line)) {
2570
- inFence = !inFence;
2817
+ if (inFence) {
2818
+ inFence = false;
2819
+ if (fenceTo) {
2820
+ fenceTo.push("```");
2821
+ fenceTo = null;
2822
+ }
2823
+ continue;
2824
+ }
2825
+ inFence = true;
2826
+ const lead = ((line.match(/^[ \t]*/) || [""])[0] || "").length;
2827
+ fenceIndent = lead;
2828
+ const b0 = bufNow();
2829
+ if (lead > 0 && b0) {
2830
+ fenceTo = b0.lines;
2831
+ fenceTo.push("```" + line.replace(/^[ \t]*(?:`{3,}|~{3,})\s*/, "").trim());
2832
+ continue;
2833
+ }
2834
+ const dest = ensureDest();
2835
+ flushBuf();
2836
+ if (dest) {
2837
+ openBuf("```" + line.replace(/^[ \t]*(?:`{3,}|~{3,})\s*/, "").trim(), dest);
2838
+ const b1 = bufNow();
2839
+ fenceTo = b1 ? b1.lines : null;
2840
+ } else fenceTo = null;
2571
2841
  continue;
2572
2842
  }
2573
- if (inFence) continue;
2574
- const versionTitle = matchVersionHeading(line);
2575
- if (versionTitle !== null) {
2576
- pushCurrent();
2577
- cur = null;
2578
- curCat = null;
2579
- const { version, date, yanked } = extractVersionDateAndYanked(versionTitle);
2580
- if (!version) continue;
2581
- cur = {
2582
- version,
2583
- date,
2584
- yanked,
2585
- sections: emptySections(),
2586
- counts: emptyCounts()
2587
- };
2843
+ if (inFence) {
2844
+ if (fenceTo) {
2845
+ const lead = ((line.match(/^[ \t]*/) || [""])[0] || "").length;
2846
+ fenceTo.push(line.slice(Math.min(fenceIndent, lead)).replace(/[ \t]+$/, ""));
2847
+ }
2588
2848
  continue;
2589
2849
  }
2590
- const catTitle = matchCategoryHeading(line);
2591
- if (catTitle !== null) {
2592
- const cat = normalizeCategory(catTitle);
2593
- curCat = cur && cat && isCategoryName(cat) ? cat : null;
2850
+ const head = matchAnyHeading(line);
2851
+ if (head) {
2852
+ const vTitle = head.level <= 4 && looksLikeVersionHeading(head.text) ? head.text : null;
2853
+ if (vTitle !== null) {
2854
+ pushCurrent();
2855
+ cur = null;
2856
+ bucket = null;
2857
+ const { version, date, yanked } = extractVersionDateAndYanked(vTitle);
2858
+ if (!version) continue;
2859
+ cur = {
2860
+ version,
2861
+ date,
2862
+ yanked,
2863
+ sections: emptySections(),
2864
+ counts: emptyCounts()
2865
+ };
2866
+ continue;
2867
+ }
2868
+ if (isVersionIshWithoutNumber(head.text)) {
2869
+ if (cur) {
2870
+ pushCurrent();
2871
+ cur = null;
2872
+ bucket = null;
2873
+ }
2874
+ continue;
2875
+ }
2876
+ if (cur) {
2877
+ flushBuf();
2878
+ const cat = normalizeCategoryMulti(head.text);
2879
+ if (cat && isCategoryName(cat)) bucket = { cat };
2880
+ else bucket = { other: ensureOther(cur, head.text) };
2881
+ continue;
2882
+ }
2594
2883
  continue;
2595
2884
  }
2596
2885
  const bulletBody = matchBulletBody(line);
2597
- if (bulletBody !== null && cur && curCat) {
2598
- const item = truncateBullet(bulletBody);
2599
- if (item) {
2600
- cur.sections[curCat].push(item);
2601
- try {
2602
- if (cur.counts) cur.counts[curCat] += 1;
2603
- } catch {}
2886
+ const orderedBody = bulletBody === null ? matchOrderedBody(line) : null;
2887
+ const body = bulletBody !== null ? bulletBody : orderedBody;
2888
+ if (body !== null) {
2889
+ const level = indentLevel(line);
2890
+ const b = bufNow();
2891
+ if (level > 0 && b && !(pendingBlank && !bufEndsWithItem(b.lines))) {
2892
+ b.lines.push(canonicalNestedItem(line, level, body));
2893
+ pendingBlank = false;
2894
+ continue;
2895
+ }
2896
+ if (bulletBody !== null) {
2897
+ const b2 = bufNow();
2898
+ if (pendingBlank && b2 && !bufEndsWithItem(b2.lines)) flushBuf();
2899
+ flushBuf();
2900
+ const dest = ensureDest();
2901
+ if (body.replace(/\s+/g, " ").trim().length > 500) ledger.items += 1;
2902
+ const item = truncateBullet(body);
2903
+ if (dest && item) openBuf(item, dest);
2904
+ continue;
2604
2905
  }
2605
- continue;
2606
2906
  }
2607
2907
  const trimmed = line.trim();
2608
- if (trimmed && !trimmed.startsWith("#") && /^\s/.test(line) && cur && curCat) {
2609
- const list = cur.sections[curCat];
2610
- if (list.length > 0) {
2611
- const merged = truncateBullet(`${list[list.length - 1]} ${trimmed}`);
2612
- if (merged) list[list.length - 1] = merged;
2613
- }
2908
+ if (!trimmed) {
2909
+ pendingBlank = true;
2614
2910
  continue;
2615
2911
  }
2912
+ if (trimmed.startsWith("#")) continue;
2913
+ if (cur) {
2914
+ const dest = ensureDest();
2915
+ if (!dest) continue;
2916
+ if (bufNow() && pendingBlank && !/^[ \t]/.test(line)) flushBuf();
2917
+ const text2 = trimmed === ">" || trimmed.startsWith("> ") ? "> " + trimmed.replace(/^>\s?/, "") : /^[ \t]/.test(line) ? " ".repeat(Math.max(1, indentLevel(line))) + trimmed : trimmed.replace(/[ \t]+$/, "");
2918
+ const bp2 = bufNow();
2919
+ if (bp2) bp2.lines.push(text2);
2920
+ else openBuf(text2, dest);
2921
+ pendingBlank = false;
2922
+ }
2616
2923
  }
2617
2924
  pushCurrent();
2618
- return entries.slice(0, 100);
2925
+ if (entries.length > 100) {
2926
+ ledger.entries = entries.length - 100;
2927
+ return {
2928
+ entries: entries.slice(0, 100),
2929
+ truncation: ledger
2930
+ };
2931
+ }
2932
+ return {
2933
+ entries,
2934
+ truncation: ledger
2935
+ };
2619
2936
  } catch {
2620
- return [];
2937
+ return {
2938
+ entries: [],
2939
+ truncation: ledger
2940
+ };
2621
2941
  }
2622
2942
  }
2623
2943
  function hasVisibleSections(entry) {
2624
2944
  if (!entry || typeof entry !== "object") return false;
2625
2945
  try {
2626
- return CHANGELOG_ALL_CATEGORIES.some((c) => Array.isArray(entry.sections?.[c]) && entry.sections[c].length > 0);
2946
+ if (CHANGELOG_ALL_CATEGORIES.some((c) => Array.isArray(entry.sections?.[c]) && entry.sections[c].length > 0)) return true;
2947
+ const other = entry.otherSections;
2948
+ return Array.isArray(other) && other.some((s) => Array.isArray(s?.items) && s.items.length > 0);
2627
2949
  } catch {
2628
2950
  return false;
2629
2951
  }
@@ -2679,6 +3001,170 @@ window.__ModuleLoader__.load({
2679
3001
  function escapeChangelogHtml(text) {
2680
3002
  return String(text ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
2681
3003
  }
3004
+ const MD_URL_MAX = 2048;
3005
+ const MD_MAX_DEPTH = 2;
3006
+ function isHttpUrl(u) {
3007
+ return /^https?:\/\//i.test(String(u || ""));
3008
+ }
3009
+ function renderInlineTailAware(s) {
3010
+ let src = s;
3011
+ let out = renderInlineMarkdown(src, 0);
3012
+ if (!s.endsWith("…")) return out;
3013
+ for (let round = 0; round < 3; round++) {
3014
+ let visible = "";
3015
+ try {
3016
+ visible = out.replace(/<code[^>]*>[\s\S]*?<\/code>/g, "").replace(/<[^>]*>/g, "");
3017
+ } catch {
3018
+ break;
3019
+ }
3020
+ const m = visible.match(/\*\*|__|~~|`/);
3021
+ if (!m) break;
3022
+ const marker = m[0];
3023
+ const at = src.lastIndexOf(marker);
3024
+ if (at < 0) break;
3025
+ src = src.slice(0, at) + src.slice(at + marker.length);
3026
+ out = renderInlineMarkdown(src, 0);
3027
+ }
3028
+ return out;
3029
+ }
3030
+ function matchBracketLink(s, openIdx) {
3031
+ try {
3032
+ if (s[openIdx] !== "[") return null;
3033
+ const close = s.indexOf("]", openIdx + 1);
3034
+ if (close < 0 || s[close + 1] !== "(") return null;
3035
+ const urlEnd = s.indexOf(")", close + 2);
3036
+ if (urlEnd < 0) return null;
3037
+ const raw = s.slice(close + 2, urlEnd).trim();
3038
+ if (!raw || raw.length > MD_URL_MAX) return null;
3039
+ const url = raw.split(/\s+/)[0] || "";
3040
+ if (!url) return null;
3041
+ return {
3042
+ text: s.slice(openIdx + 1, close),
3043
+ url,
3044
+ end: urlEnd + 1
3045
+ };
3046
+ } catch {
3047
+ return null;
3048
+ }
3049
+ }
3050
+ function trimBareUrl(raw) {
3051
+ let u = String(raw || "");
3052
+ while (u.length > 0 && /[.,;:!?'"”’、。,;:!?]/.test(u[u.length - 1])) u = u.slice(0, -1);
3053
+ while (u.endsWith(")")) {
3054
+ const open = (u.match(/\(/g) || []).length;
3055
+ if ((u.match(/\)/g) || []).length <= open) break;
3056
+ u = u.slice(0, -1);
3057
+ }
3058
+ return u;
3059
+ }
3060
+ function mdAnchor(url, inner) {
3061
+ return "<a class=\"dsh-upd-md-link\" data-openlink=\"1\" href=\"" + escapeChangelogHtml(url) + "\" target=\"_blank\" rel=\"noopener noreferrer\">" + inner + "</a>";
3062
+ }
3063
+ function renderInlineMarkdown(text, depth) {
3064
+ const s = String(text ?? "");
3065
+ if (!s) return "";
3066
+ if (depth > MD_MAX_DEPTH) return escapeChangelogHtml(s);
3067
+ let out = "";
3068
+ let i = 0;
3069
+ const n = s.length;
3070
+ while (i < n) {
3071
+ const c = s[i];
3072
+ if (c === "\\" && i + 1 < n && /[\\`*_~[\]()!<>#|]/.test(s[i + 1])) {
3073
+ out += escapeChangelogHtml(s[i + 1]);
3074
+ i += 2;
3075
+ continue;
3076
+ }
3077
+ if (c === "`") {
3078
+ let ticks = 1;
3079
+ while (i + ticks < n && s[i + ticks] === "`" && ticks < 3) ticks++;
3080
+ const fence = "`".repeat(ticks);
3081
+ const end = s.indexOf(fence, i + ticks);
3082
+ if (end > i + ticks) {
3083
+ out += "<code class=\"dsh-upd-md-code\">" + escapeChangelogHtml(s.slice(i + ticks, end)) + "</code>";
3084
+ i = end + ticks;
3085
+ continue;
3086
+ }
3087
+ }
3088
+ if (c === "!" && s[i + 1] === "[") {
3089
+ const img = matchBracketLink(s, i + 1);
3090
+ if (img && isHttpUrl(img.url)) {
3091
+ const alt = img.text.trim() || img.url;
3092
+ out += "<span class=\"dsh-upd-md-img\" data-src=\"" + escapeChangelogHtml(img.url) + "\" title=\"" + escapeChangelogHtml(img.url) + "\">" + renderInlineMarkdown(alt, depth + 1) + "</span>";
3093
+ i = img.end;
3094
+ continue;
3095
+ }
3096
+ }
3097
+ if (c === "[") {
3098
+ const lk = matchBracketLink(s, i);
3099
+ if (lk && isHttpUrl(lk.url)) {
3100
+ out += mdAnchor(lk.url, renderInlineMarkdown(lk.text, depth + 1));
3101
+ i = lk.end;
3102
+ continue;
3103
+ }
3104
+ }
3105
+ if (c === "<") {
3106
+ const m = s.slice(i).match(/^<(https?:\/\/[^<>\s]+)>/i);
3107
+ if (m) {
3108
+ out += mdAnchor(m[1], escapeChangelogHtml(m[1]));
3109
+ i += m[0].length;
3110
+ continue;
3111
+ }
3112
+ }
3113
+ if ((c === "h" || c === "H") && /^https?:\/\//i.test(s.slice(i, i + 8))) {
3114
+ const m = s.slice(i).match(/^https?:\/\/[A-Za-z0-9\-._~:/?#@!$&*+,;=%()[\]]+/i);
3115
+ if (m) {
3116
+ const url = trimBareUrl(m[0]);
3117
+ if (url.length > 8) {
3118
+ out += mdAnchor(url, escapeChangelogHtml(url));
3119
+ i += url.length;
3120
+ continue;
3121
+ }
3122
+ }
3123
+ }
3124
+ if (c === "*" || c === "_") {
3125
+ let run = 1;
3126
+ while (i + run < n && s[i + run] === c && run < 2) run++;
3127
+ const marker = c.repeat(run);
3128
+ const prev = i > 0 ? s[i - 1] : "";
3129
+ if (!(c === "_" && /[0-9A-Za-z\u4e00-\u9fff]/.test(prev))) {
3130
+ const end = s.indexOf(marker, i + run);
3131
+ if (end > i + run) {
3132
+ const inner = s.slice(i + run, end);
3133
+ if (inner.trim() === inner && !inner.includes("\n")) {
3134
+ const tag = run === 2 ? "strong" : "em";
3135
+ out += "<" + tag + ">" + renderInlineMarkdown(inner, depth + 1) + "</" + tag + ">";
3136
+ i = end + run;
3137
+ continue;
3138
+ }
3139
+ }
3140
+ }
3141
+ }
3142
+ if (c === "~" && s[i + 1] === "~") {
3143
+ const end = s.indexOf("~~", i + 2);
3144
+ if (end > i + 2) {
3145
+ out += "<del class=\"dsh-upd-md-del\">" + renderInlineMarkdown(s.slice(i + 2, end), depth + 1) + "</del>";
3146
+ i = end + 2;
3147
+ continue;
3148
+ }
3149
+ }
3150
+ out += escapeChangelogHtml(c);
3151
+ i++;
3152
+ }
3153
+ return out;
3154
+ }
3155
+ function renderChangelogInline(text) {
3156
+ try {
3157
+ const s = String(text !== null && text !== void 0 ? text : "");
3158
+ if (!s) return "";
3159
+ return renderInlineTailAware(s);
3160
+ } catch {
3161
+ try {
3162
+ return escapeChangelogHtml(String(text !== null && text !== void 0 ? text : ""));
3163
+ } catch {
3164
+ return "";
3165
+ }
3166
+ }
3167
+ }
2682
3168
  function countsOf(entry) {
2683
3169
  try {
2684
3170
  const out = {
@@ -2733,19 +3219,159 @@ window.__ModuleLoader__.load({
2733
3219
  return "";
2734
3220
  }
2735
3221
  }
2736
- function renderChangelogItem(item, lang) {
3222
+ function matchListItem(line) {
3223
+ const m = String(line || "").match(/^([ \t]*)(?:([-*+])|(\d{1,9}[.)]))[ \t]+(.*)$/);
3224
+ if (!m) return null;
3225
+ return {
3226
+ depth: indentLevel(m[1] || ""),
3227
+ ordered: m[3] !== void 0 && m[3] !== null,
3228
+ text: m[4] || ""
3229
+ };
3230
+ }
3231
+ function renderListItems(items, start, base) {
3232
+ const first = items[start];
3233
+ const tag = first && first.ordered ? "ol" : "ul";
3234
+ const cls = tag === "ol" ? "dsh-upd-md-list-ol" : "dsh-upd-md-list";
3235
+ let html = "<" + tag + " class=\"" + cls + "\">";
3236
+ let i = start;
3237
+ while (i < items.length && items[i].depth >= base) {
3238
+ const it = items[i];
3239
+ if (it.depth > base) {
3240
+ const sub = renderListItems(items, i, it.depth);
3241
+ html += sub.html;
3242
+ i = sub.next;
3243
+ continue;
3244
+ }
3245
+ html += "<li>" + renderChangelogInline(it.text);
3246
+ i += 1;
3247
+ const nextItem = items[i];
3248
+ if (nextItem && nextItem.depth > base) {
3249
+ const sub = renderListItems(items, i, nextItem.depth);
3250
+ html += sub.html;
3251
+ i = sub.next;
3252
+ }
3253
+ html += "</li>";
3254
+ }
3255
+ html += "</" + tag + ">";
3256
+ return {
3257
+ html,
3258
+ next: i
3259
+ };
3260
+ }
3261
+ function isThematicBreak(line) {
3262
+ const t = String(line === null || line === void 0 ? "" : line);
3263
+ return /^ {0,3}([-*_])(?:\s*\1){2,}\s*$/.test(t);
3264
+ }
3265
+ function renderChangelogBlocks(lines) {
3266
+ try {
3267
+ const src = Array.isArray(lines) ? lines.map((x) => String(x === null || x === void 0 ? "" : x)) : [];
3268
+ const out = [];
3269
+ let para = [];
3270
+ const flushPara = () => {
3271
+ if (!para.length) return;
3272
+ out.push("<div class=\"dsh-upd-md-para\">" + renderChangelogInline(para.join(" ")) + "</div>");
3273
+ para = [];
3274
+ };
3275
+ let i = 0;
3276
+ while (i < src.length) {
3277
+ const line = src[i];
3278
+ if (isFenceToggle(line)) {
3279
+ flushPara();
3280
+ const code = [];
3281
+ i += 1;
3282
+ while (i < src.length && !isFenceToggle(src[i])) {
3283
+ code.push(src[i]);
3284
+ i += 1;
3285
+ }
3286
+ if (i < src.length) i += 1;
3287
+ out.push("<pre class=\"dsh-upd-md-pre\"><code class=\"dsh-upd-md-precode\">" + escapeChangelogHtml(code.join(String.fromCharCode(10))) + "</code></pre>");
3288
+ continue;
3289
+ }
3290
+ if (/^[ \t]*>/.test(line)) {
3291
+ flushPara();
3292
+ const quote = [];
3293
+ while (i < src.length && /^[ \t]*>/.test(src[i])) {
3294
+ quote.push(src[i].replace(/^[ \t]*>[ \t]?/, ""));
3295
+ i += 1;
3296
+ }
3297
+ out.push("<blockquote class=\"dsh-upd-md-quote\">" + renderChangelogInline(quote.join(" ")) + "</blockquote>");
3298
+ continue;
3299
+ }
3300
+ if (isThematicBreak(line)) {
3301
+ flushPara();
3302
+ out.push("<hr class=\"dsh-upd-md-hr\">");
3303
+ i += 1;
3304
+ continue;
3305
+ }
3306
+ if (matchListItem(line)) {
3307
+ flushPara();
3308
+ const items = [];
3309
+ while (i < src.length) {
3310
+ const head = matchListItem(src[i]);
3311
+ if (!head) break;
3312
+ let text2 = head.text;
3313
+ i += 1;
3314
+ while (i < src.length && !matchListItem(src[i]) && !isFenceToggle(src[i]) && !/^[ \t]*>/.test(src[i]) && !isThematicBreak(src[i])) {
3315
+ const extra = src[i].trim();
3316
+ if (extra) text2 += " " + extra;
3317
+ i += 1;
3318
+ }
3319
+ items.push({
3320
+ depth: head.depth,
3321
+ ordered: head.ordered,
3322
+ text: text2
3323
+ });
3324
+ }
3325
+ out.push(renderListItems(items, 0, items.length > 0 ? items[0].depth : 0).html);
3326
+ continue;
3327
+ }
3328
+ const text = line.trim();
3329
+ if (text) para.push(text);
3330
+ i += 1;
3331
+ }
3332
+ flushPara();
3333
+ return out.join("");
3334
+ } catch {
3335
+ return "";
3336
+ }
3337
+ }
3338
+ function leadsWithCategoryName(item, cat) {
3339
+ const first = String(item !== null && item !== void 0 ? item : "").split(String.fromCharCode(10))[0].trim();
3340
+ if (!first) return false;
3341
+ const bare = first.replace(/^[*_`~\s]+/, "");
3342
+ for (const name of [String(cat), CHANGELOG_CATEGORY_ZH[cat]]) {
3343
+ if (!name) continue;
3344
+ if (bare.slice(0, name.length).toLowerCase() !== name.toLowerCase()) continue;
3345
+ const next = bare.slice(name.length, name.length + 1);
3346
+ if (!next) return true;
3347
+ if (/[\s·::,,))\]】\-—–、。.;;/||*_`~]/.test(next)) return true;
3348
+ }
3349
+ return false;
3350
+ }
3351
+ function renderChangelogItem(item, lang, cat) {
2737
3352
  try {
2738
3353
  const l = normalizeLangTag(lang ?? "zh");
2739
3354
  const s = String(item !== null && item !== void 0 ? item : "");
2740
3355
  if (!s) return "";
2741
- const split = splitBreakingPrefix(s);
2742
- if (!split) return "<li>" + escapeChangelogHtml(s) + "</li>";
2743
- const head = escapeChangelogHtml(split.head);
2744
- const prefix = escapeChangelogHtml(split.prefix);
2745
- const rest = escapeChangelogHtml(split.rest);
3356
+ const nlIdx = s.indexOf(String.fromCharCode(10));
3357
+ const firstLine = nlIdx === -1 ? s : s.slice(0, nlIdx);
3358
+ if (/^[ \t]*(?:```|~~~|>|[-*+][ \t]|\d{1,9}[.)][ \t]|[-*_]{3,}\s*$)/.test(firstLine)) {
3359
+ const blockLead = cat && isCategoryName(String(cat)) ? " data-cat-block=\"1\"" : "";
3360
+ const blockHtml = renderChangelogBlocks(s.split(String.fromCharCode(10)));
3361
+ return blockHtml ? "<li" + blockLead + ">" + blockHtml + "</li>" : "";
3362
+ }
3363
+ const head = firstLine;
3364
+ const tailHtml = renderChangelogBlocks(nlIdx === -1 ? [] : s.slice(nlIdx + 1).split(String.fromCharCode(10)));
3365
+ const lead = cat && isCategoryName(String(cat)) && leadsWithCategoryName(head, String(cat)) ? " data-cat-lead=\"1\"" : "";
3366
+ if (!head) return tailHtml ? "<li" + lead + ">" + tailHtml + "</li>" : "";
3367
+ const split = splitBreakingPrefix(head);
3368
+ if (!split) return "<li" + lead + ">" + renderChangelogInline(head) + tailHtml + "</li>";
3369
+ const headHtml = renderChangelogInline(split.head);
3370
+ const prefix = renderChangelogInline(split.prefix);
3371
+ const rest = renderChangelogInline(split.rest);
2746
3372
  const badgeText = copyText("changelog.breaking.badge", l);
2747
3373
  const badge = "<span class=\"dsh-upd-breaking-badge\" role=\"img\" aria-label=\"" + escapeChangelogHtml(copyText("changelog.breaking.aria", l)) + "\">" + escapeChangelogHtml(badgeText) + "</span> ";
2748
- return "<li>" + head + badge + "<strong>" + prefix + "</strong>" + rest + "</li>";
3374
+ return "<li" + lead + ">" + headHtml + badge + "<strong>" + prefix + "</strong>" + rest + tailHtml + "</li>";
2749
3375
  } catch {
2750
3376
  return "";
2751
3377
  }
@@ -2777,7 +3403,7 @@ window.__ModuleLoader__.load({
2777
3403
  parts.push("<ul>");
2778
3404
  for (const item of items) {
2779
3405
  if (!item) continue;
2780
- const li = renderChangelogItem(item, l);
3406
+ const li = renderChangelogItem(item, l, cat);
2781
3407
  if (li) parts.push(li);
2782
3408
  }
2783
3409
  parts.push("</ul>");
@@ -2801,11 +3427,12 @@ window.__ModuleLoader__.load({
2801
3427
  parts.push("<ul>");
2802
3428
  for (const item of items) {
2803
3429
  if (!item) continue;
2804
- const li = renderChangelogItem(item, l);
3430
+ const li = renderChangelogItem(item, l, cat);
2805
3431
  if (li) parts.push(li);
2806
3432
  }
2807
3433
  parts.push("</ul></details>");
2808
3434
  }
3435
+ for (const block of renderOtherSections(entry, l)) parts.push(block);
2809
3436
  parts.push("</div>");
2810
3437
  return parts.join(String.fromCharCode(10));
2811
3438
  } catch {
@@ -2819,9 +3446,53 @@ window.__ModuleLoader__.load({
2819
3446
  return "";
2820
3447
  }
2821
3448
  }
3449
+ function renderOtherSections(entry, l) {
3450
+ const out = [];
3451
+ const list = Array.isArray(entry.otherSections) ? entry.otherSections : [];
3452
+ for (const s of list) {
3453
+ const items = Array.isArray(s?.items) ? s.items : [];
3454
+ if (items.length === 0) continue;
3455
+ const title = String(s.title || "").trim();
3456
+ out.push("<div class=\"dsh-upd-changelog-cat\" data-cat=\"other\">");
3457
+ if (title) out.push("<div class=\"dsh-upd-changelog-catname\">" + renderChangelogInline(title) + "</div>");
3458
+ const total = typeof s.count === "number" && s.count > items.length ? s.count : items.length;
3459
+ if (total > items.length) out.push(truncatedNoteHTML(total, items.length, l));
3460
+ out.push("<ul>");
3461
+ for (const item of items) {
3462
+ if (!item) continue;
3463
+ const li = renderChangelogItem(item, l, null);
3464
+ if (li) out.push(li);
3465
+ }
3466
+ out.push("</ul>");
3467
+ out.push("</div>");
3468
+ }
3469
+ return out;
3470
+ }
3471
+ function truncationNoteHTML(tr, lang) {
3472
+ try {
3473
+ const l = normalizeLangTag(lang ?? "zh");
3474
+ if (!tr || typeof tr !== "object") return "";
3475
+ const parts = [];
3476
+ if (tr.chars === true) {
3477
+ parts.push(copyText("changelog.truncated.file", l));
3478
+ const n = Number(tr.tailVersions) || 0;
3479
+ if (n > 0) parts.push(copyText("changelog.truncated.versions", l, { n: String(n) }));
3480
+ }
3481
+ const droppedEntries = Number(tr.entries) || 0;
3482
+ if (droppedEntries > 0) parts.push(copyText("changelog.truncated.count", l, {
3483
+ n: String(100),
3484
+ m: String(100 + droppedEntries)
3485
+ }));
3486
+ if (parts.length === 0) return "";
3487
+ return "<div class=\"dsh-upd-changelog-truncnote\">" + escapeChangelogHtml(parts.join(" ")) + "</div>";
3488
+ } catch {
3489
+ return "";
3490
+ }
3491
+ }
2822
3492
  function renderChangelogHTML(entries, opts) {
2823
3493
  try {
2824
3494
  const l = normalizeLangTag(opts?.lang ?? "zh");
3495
+ const note = truncationNoteHTML(opts?.truncated, l);
2825
3496
  if (!Array.isArray(entries) || entries.length === 0) return renderChangelogNeutral(l);
2826
3497
  const from = opts && typeof opts.from === "string" ? opts.from : null;
2827
3498
  const to = opts && typeof opts.to === "string" ? opts.to : null;
@@ -2835,11 +3506,11 @@ window.__ModuleLoader__.load({
2835
3506
  return false;
2836
3507
  }
2837
3508
  });
2838
- if (ranged.length === 0) return renderChangelogNeutral(l);
3509
+ if (ranged.length === 0) return note + renderChangelogNeutral(l);
2839
3510
  const blocks = ranged.map((e) => renderChangelogSection(e, l)).filter((s) => !!s);
2840
- if (blocks.length === 0) return renderChangelogNeutral(l);
3511
+ if (blocks.length === 0) return note + renderChangelogNeutral(l);
2841
3512
  return `<div class="dsh-upd-changelog">
2842
- ${blocks.join("\n")}
3513
+ ${note}${blocks.join("\n")}
2843
3514
  </div>`;
2844
3515
  } catch {
2845
3516
  try {
@@ -2850,12 +3521,46 @@ ${blocks.join("\n")}
2850
3521
  }
2851
3522
  }
2852
3523
  //#endregion
2853
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.12.0/node_modules/dsh-plugin-update/dist/log-events.js
3524
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.17.0/node_modules/dsh-plugin-update/dist/log-events.js
2854
3525
  const LOG_EVENT_CALL = "host.call";
2855
3526
  const LOG_EVENT_CALL_FAIL = "host.call.fail";
2856
3527
  const LOG_EVENT_INSTALL_EXEC = "update.install.exec";
2857
3528
  //#endregion
2858
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.12.0/node_modules/dsh-plugin-update/dist/panel.js
3529
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.17.0/node_modules/dsh-plugin-update/dist/codes.js
3530
+ const BLOCKED_REASONS = [
3531
+ "unknown-profile",
3532
+ "channel-mismatch",
3533
+ "source-install",
3534
+ "invalid-installation",
3535
+ "installation-changed",
3536
+ "pending-restart",
3537
+ "registry-conflict",
3538
+ "incompatible-node",
3539
+ "recovery-required"
3540
+ ];
3541
+ const PHONE_FAILURE_CODES = [
3542
+ "check-failed",
3543
+ "invalid-release",
3544
+ "check-expired",
3545
+ "update-busy",
3546
+ "install-failed"
3547
+ ];
3548
+ const CHECK_SIDE_FAILURE_CODES = [
3549
+ "check-failed",
3550
+ "invalid-release",
3551
+ "check-expired"
3552
+ ];
3553
+ const INTERNAL_CODE = "internal";
3554
+ [...BLOCKED_REASONS, ...PHONE_FAILURE_CODES];
3555
+ [...[...PHONE_FAILURE_CODES, ...BLOCKED_REASONS]];
3556
+ function isOneOf(codes, code) {
3557
+ return typeof code === "string" && codes.includes(code);
3558
+ }
3559
+ function isCheckSideFailureCode(code) {
3560
+ return typeof code === "string" && isOneOf(CHECK_SIDE_FAILURE_CODES, code.trim());
3561
+ }
3562
+ //#endregion
3563
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.17.0/node_modules/dsh-plugin-update/dist/panel.js
2859
3564
  function normalizePanelTheme(value) {
2860
3565
  return value === "archive" ? "archive" : "default";
2861
3566
  }
@@ -2894,7 +3599,12 @@ ${blocks.join("\n")}
2894
3599
  entryFontSize: "--dsh-update-entry-font-size",
2895
3600
  entryPadding: "--dsh-update-entry-padding",
2896
3601
  entryBorderRadius: "--dsh-update-entry-border-radius",
2897
- entryScale: "--dsh-update-entry-scale"
3602
+ entryScale: "--dsh-update-entry-scale",
3603
+ panelFontSize: "--dsh-update-panel-font-size",
3604
+ panelChapterFontSize: "--dsh-update-panel-chapter-font-size",
3605
+ panelBannerTitleFontSize: "--dsh-update-panel-banner-title-font-size",
3606
+ panelLogFontSize: "--dsh-update-panel-log-font-size",
3607
+ panelSmallFontSize: "--dsh-update-panel-small-font-size"
2898
3608
  };
2899
3609
  const THEME_TOKEN_COLOR_KEYS = /* @__PURE__ */ new Set([
2900
3610
  "text",
@@ -3030,7 +3740,7 @@ ${blocks.join("\n")}
3030
3740
  title: "panel.failure.install-failed.title",
3031
3741
  action: "panel.failure.install-failed.action"
3032
3742
  },
3033
- internal: {
3743
+ [INTERNAL_CODE]: {
3034
3744
  title: "panel.failure.internal.title",
3035
3745
  action: "panel.failure.internal.action"
3036
3746
  }
@@ -3071,7 +3781,7 @@ ${blocks.join("\n")}
3071
3781
  const err = reply && typeof reply.error === "string" ? reply.error.trim() : "";
3072
3782
  if (err) return err;
3073
3783
  if (typeof fallback === "string" && fallback.trim()) return fallback.trim();
3074
- return "internal";
3784
+ return INTERNAL_CODE;
3075
3785
  }
3076
3786
  function redactForCopy(text) {
3077
3787
  return sanitizeForCopy(text);
@@ -3414,12 +4124,13 @@ ${blocks.join("\n")}
3414
4124
  if (!staleFailure && (failedCode || jobState === "failed" || jobState === "interrupted")) {
3415
4125
  const code = failedCode || "install-failed";
3416
4126
  const copy = failureCopy(code, l);
4127
+ const checkDetail = copy?.zh ?? code;
3417
4128
  return {
3418
4129
  banner: {
3419
4130
  kind: "failed",
3420
4131
  title: copyText("panel.banner.error.title", l, {
3421
4132
  code,
3422
- detail: copy?.zh ?? code
4133
+ detail: snapshot?.installed === false && isCheckSideFailureCode(code) ? copyText("panel.banner.not-installed", l) + ":" + checkDetail : checkDetail
3423
4134
  }),
3424
4135
  action: copy?.act || copyText("panel.banner.error.action-fallback", l)
3425
4136
  },
@@ -3461,19 +4172,35 @@ ${blocks.join("\n")}
3461
4172
  queueNote
3462
4173
  };
3463
4174
  }
3464
- if (snapshot.canInstall && snapshot.latestVersion) return {
4175
+ if (snapshot.canInstall && snapshot.latestVersion) {
4176
+ const running = snapshot.installed === false ? copyText("panel.banner.not-installed", l) : snapshot.runningVersion;
4177
+ return {
4178
+ banner: {
4179
+ kind: "update",
4180
+ title: copyText("panel.banner.update-title", l, {
4181
+ latest: snapshot.latestVersion,
4182
+ running
4183
+ }),
4184
+ action: copyText("panel.banner.update-action", l)
4185
+ },
4186
+ installEnabled: true,
4187
+ installLabel: copyText("panel.action.install-version", l, { latest: snapshot.latestVersion }),
4188
+ skippedLatest: false,
4189
+ showManual: manual ? true : false,
4190
+ showReset: false,
4191
+ queueNote
4192
+ };
4193
+ }
4194
+ if (snapshot?.installed === false) return {
3465
4195
  banner: {
3466
- kind: "update",
3467
- title: copyText("panel.banner.update-title", l, {
3468
- latest: snapshot.latestVersion,
3469
- running: snapshot.runningVersion
3470
- }),
3471
- action: copyText("panel.banner.update-action", l)
4196
+ kind: "idle",
4197
+ title: copyText("panel.banner.not-installed", l),
4198
+ action: copyText("panel.action.check", l)
3472
4199
  },
3473
- installEnabled: true,
3474
- installLabel: copyText("panel.action.install-version", l, { latest: snapshot.latestVersion }),
4200
+ installEnabled: false,
4201
+ installLabel: copyText("panel.action.install", l),
3475
4202
  skippedLatest: false,
3476
- showManual: manual ? true : false,
4203
+ showManual: false,
3477
4204
  showReset: false,
3478
4205
  queueNote
3479
4206
  };
@@ -3492,7 +4219,7 @@ ${blocks.join("\n")}
3492
4219
  };
3493
4220
  }
3494
4221
  const UPDATE_PANEL_CSS = [
3495
- ".dsh-upd{font:14px/1.75 system-ui,\"Microsoft YaHei\",sans-serif;color:var(--dsh-update-text,#1f2937);",
4222
+ ".dsh-upd{font:var(--dsh-update-panel-font-size,14px)/1.75 system-ui,\"Microsoft YaHei\",sans-serif;color:var(--dsh-update-text,#1f2937);",
3496
4223
  "background:var(--dsh-update-bg,#ffffff);border:1px solid var(--dsh-update-border,#e5e7eb);border-radius:8px;padding:12px 14px;max-width:560px;",
3497
4224
  "--dsh-update-ok-bg:#ecfdf5;--dsh-update-ok-border:#059669;--dsh-update-warn-bg:#fffbeb;--dsh-update-warn-border:#d97706;",
3498
4225
  "--dsh-update-bad-bg:#fef2f2;--dsh-update-bad-border:#dc2626;--dsh-update-busy-bg:#eff6ff;--dsh-update-busy-border:#2563eb}",
@@ -3507,9 +4234,9 @@ ${blocks.join("\n")}
3507
4234
  ".dsh-upd-banner[data-kind=\"failed\"],.dsh-upd-banner[data-kind=\"blocked\"]{border-color:var(--dsh-update-bad-border);background:var(--dsh-update-bad-bg)}",
3508
4235
  ".dsh-upd-banner[data-kind=\"update\"]{border-color:var(--dsh-update-ok-border);background:var(--dsh-update-ok-bg)}",
3509
4236
  ".dsh-upd-banner[data-kind=\"busy\"]{border-color:var(--dsh-update-busy-border);background:var(--dsh-update-busy-bg)}",
3510
- ".dsh-upd code{font-family:Consolas,Menlo,monospace;font-size:12px;word-break:break-all}",
3511
- ".dsh-upd-manual,.dsh-upd-queue,.dsh-upd-log{margin:4px 0;font-size:13px}",
3512
- ".dsh-upd-changelog-wrap{margin:4px 0 0;font-size:13px}",
4237
+ ".dsh-upd code{font-family:Consolas,Menlo,monospace;font-size:var(--dsh-update-panel-log-font-size,12px);word-break:break-all}",
4238
+ ".dsh-upd-manual,.dsh-upd-queue,.dsh-upd-log{margin:4px 0;font-size:var(--dsh-update-panel-log-font-size,13px)}",
4239
+ ".dsh-upd-changelog-wrap{margin:4px 0 0;font-size:var(--dsh-update-panel-log-font-size,13px)}",
3513
4240
  ".dsh-upd-changelog-title{font-weight:700;margin:0 0 4px}",
3514
4241
  ".dsh-upd-changelog-version{margin:6px 0}",
3515
4242
  ".dsh-upd-changelog-catname{font-weight:600;margin:6px 0 2px}",
@@ -3517,13 +4244,26 @@ ${blocks.join("\n")}
3517
4244
  ".dsh-upd-changelog li{margin:2px 0}",
3518
4245
  ".dsh-upd-changelog-fold{margin:4px 0}",
3519
4246
  ".dsh-upd-changelog-fold>summary{cursor:pointer}",
3520
- ".dsh-upd-changelog-count{font-size:12px;opacity:.7;margin:2px 0 4px}",
3521
- ".dsh-upd-changelog-yanked{border-left:4px solid var(--dsh-update-warn-border,#d97706);background:var(--dsh-update-warn-bg,#fffbeb);padding:6px 10px;margin:6px 0;font-size:13px}",
3522
- ".dsh-upd-breaking-badge{display:inline-block;font-size:11px;font-weight:700;border:1px solid currentColor;border-radius:3px;padding:0 5px;margin-right:6px;vertical-align:baseline}",
4247
+ ".dsh-upd-changelog-count{font-size:var(--dsh-update-panel-small-font-size,12px);opacity:.7;margin:2px 0 4px}",
4248
+ ".dsh-upd-changelog-yanked{border-left:4px solid var(--dsh-update-warn-border,#d97706);background:var(--dsh-update-warn-bg,#fffbeb);padding:6px 10px;margin:6px 0;font-size:var(--dsh-update-panel-log-font-size,13px)}",
4249
+ ".dsh-upd-breaking-badge{display:inline-block;font-size:var(--dsh-update-panel-small-font-size,11px);font-weight:700;border:1px solid currentColor;border-radius:3px;padding:0 5px;margin-right:6px;vertical-align:baseline}",
3523
4250
  ".dsh-upd-changelog-security-more{margin:4px 0 6px}",
3524
- ".dsh-upd-changelog-security-more>summary{cursor:pointer;font-size:12px;opacity:.8}",
3525
- ".dsh-upd-changelog-more-note{font-size:12px;opacity:.7;margin:2px 0 4px}",
4251
+ ".dsh-upd-changelog-security-more>summary{cursor:pointer;font-size:var(--dsh-update-panel-small-font-size,12px);opacity:.8}",
4252
+ ".dsh-upd-changelog-more-note{font-size:var(--dsh-update-panel-small-font-size,12px);opacity:.7;margin:2px 0 4px}",
4253
+ ".dsh-upd-changelog-truncnote{font-size:var(--dsh-update-panel-small-font-size,12px);opacity:.8;border-left:3px solid var(--dsh-update-border,#d1d5db);padding:2px 0 2px 8px;margin:4px 0 6px}",
3526
4254
  ".dsh-upd-changelog-neutral{color:inherit;opacity:.8}",
4255
+ ".dsh-upd-md-code{font-family:var(--dsh-update-font-mono,Consolas,Menlo,monospace);font-size:.92em;background:var(--dsh-update-bg-soft,#f3f4f6);border:1px solid var(--dsh-update-border,#e5e7eb);border-radius:3px;padding:0 3px;word-break:break-word}",
4256
+ ".dsh-upd-md-link{color:var(--dsh-update-primary,#2563eb);text-decoration:underline;text-underline-offset:2px;cursor:pointer;word-break:break-all}",
4257
+ ".dsh-upd-md-del{opacity:.7}",
4258
+ ".dsh-upd-md-img{display:inline-block;max-width:100%;border:1px dashed var(--dsh-update-border,#d1d5db);border-radius:3px;padding:0 4px;font-size:var(--dsh-update-panel-small-font-size,12px);opacity:.85;word-break:break-all}",
4259
+ ".dsh-upd-md-pre{margin:6px 0;padding:7px 9px;max-width:100%;overflow-x:auto;background:var(--dsh-update-bg-soft,#f3f4f6);border:1px solid var(--dsh-update-border,#e5e7eb);border-radius:4px}",
4260
+ ".dsh-upd-md-precode{display:block;font-family:var(--dsh-update-font-mono,Consolas,Menlo,monospace);font-size:.9em;white-space:pre;background:none;border:0;padding:0}",
4261
+ ".dsh-upd-md-quote{margin:6px 0;padding:1px 0 1px 9px;border-left:3px solid var(--dsh-update-border,#d1d5db);color:var(--dsh-update-text-muted,#4b5563)}",
4262
+ ".dsh-upd-md-list{margin:4px 0;padding-left:18px;list-style:disc}",
4263
+ ".dsh-upd-md-list-ol{margin:4px 0;padding-left:20px;list-style:decimal}",
4264
+ ".dsh-upd-md-list li,.dsh-upd-md-list-ol li{margin:2px 0}",
4265
+ ".dsh-upd-md-para{margin:4px 0}",
4266
+ ".dsh-upd-md-hr{margin:8px 0;border:0;border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
3527
4267
  ".dsh-upd-overlay{position:fixed;inset:0;background:rgba(0,0,0,.35);display:flex;align-items:center;justify-content:center;z-index:9999}",
3528
4268
  ".dsh-upd-overlay .dsh-upd{background:var(--dsh-update-bg,#ffffff);max-height:85vh;display:flex;flex-direction:column;overflow:hidden}",
3529
4269
  ".dsh-upd-overlay .dsh-upd:has(>.dsh-upd-body)>:not(.dsh-upd-body){flex:none}",
@@ -3539,43 +4279,43 @@ ${blocks.join("\n")}
3539
4279
  ".dsh-upd-head{display:flex;gap:12px;align-items:baseline;flex-wrap:wrap}",
3540
4280
  ".dsh-upd-masthead{display:none}",
3541
4281
  ".dsh-upd-name{font-weight:700}",
3542
- ".dsh-upd-meta{font-size:12.5px;opacity:.75}",
3543
- ".dsh-upd-proftag{font-family:Consolas,Menlo,monospace;font-size:11px;border:1px solid var(--dsh-update-border,#d1d5db);border-radius:3px;padding:0 5px;margin-left:6px;letter-spacing:.06em}",
3544
- ".dsh-upd-strip{display:flex;flex-wrap:wrap;margin:8px 0 0;border:1px solid var(--dsh-update-border,#e5e7eb);border-radius:4px;overflow:hidden;font-size:12.5px}",
4282
+ ".dsh-upd-meta{font-size:var(--dsh-update-panel-small-font-size,12.5px);opacity:.75}",
4283
+ ".dsh-upd-proftag{font-family:Consolas,Menlo,monospace;font-size:var(--dsh-update-panel-small-font-size,11px);border:1px solid var(--dsh-update-border,#d1d5db);border-radius:3px;padding:0 5px;margin-left:6px;letter-spacing:.06em}",
4284
+ ".dsh-upd-strip{display:flex;flex-wrap:wrap;margin:8px 0 0;border:1px solid var(--dsh-update-border,#e5e7eb);border-radius:4px;overflow:hidden;font-size:var(--dsh-update-panel-small-font-size,12.5px)}",
3545
4285
  ".dsh-upd-strip>div{flex:1 1 110px;min-width:0;padding:6px 10px;border-left:1px solid var(--dsh-update-border,#e5e7eb)}",
3546
4286
  ".dsh-upd-strip>div:first-child{border-left:0}",
3547
- ".dsh-upd-strip-k{display:block;font-size:11px;letter-spacing:.14em;opacity:.7}",
3548
- ".dsh-upd-strip-v{font-family:Consolas,Menlo,monospace;font-size:12.5px;word-break:break-all}",
4287
+ ".dsh-upd-strip-k{display:block;font-size:var(--dsh-update-panel-small-font-size,11px);letter-spacing:.14em;opacity:.7}",
4288
+ ".dsh-upd-strip-v{font-family:Consolas,Menlo,monospace;font-size:var(--dsh-update-panel-small-font-size,12.5px);word-break:break-all}",
3549
4289
  ".dsh-upd-chapter{margin-top:18px;padding-top:14px;border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
3550
4290
  ".dsh-upd-footer{display:flex;align-items:center;justify-content:flex-end;gap:10px;margin-top:14px;padding-top:10px;border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
3551
- ".dsh-upd-foot-note{margin-right:auto;font-size:12px;opacity:.7}",
4291
+ ".dsh-upd-foot-note{margin-right:auto;font-size:var(--dsh-update-panel-small-font-size,12px);opacity:.7}",
3552
4292
  ".dsh-upd-footer button{margin:0}",
3553
4293
  ".dsh-upd-chap-head{display:flex;align-items:baseline;gap:10px;margin-bottom:6px}",
3554
- ".dsh-upd-chap-no{font-size:13px;font-style:italic;opacity:.6}",
3555
- ".dsh-upd-chap-title{font-size:14px;margin:0}",
4294
+ ".dsh-upd-chap-no{font-size:var(--dsh-update-panel-chapter-font-size,13px);font-style:italic;opacity:.6}",
4295
+ ".dsh-upd-chap-title{font-size:var(--dsh-update-panel-chapter-font-size,14px);margin:0}",
3556
4296
  ".dsh-upd .dsh-upd-chap-title{color:var(--dsh-update-text,#1f2937);background:none;-webkit-background-clip:border-box;-webkit-text-fill-color:currentColor}",
3557
4297
  ".dsh-upd-chap-rule{flex:1;border-top:1px solid var(--dsh-update-border,#e5e7eb);transform:translateY(-3px)}",
3558
- ".dsh-upd-chap-note{flex:none;font-size:12px;opacity:.75}",
4298
+ ".dsh-upd-chap-note{flex:none;font-size:var(--dsh-update-panel-small-font-size,12px);opacity:.75}",
3559
4299
  ".dsh-upd-chap-note button{margin:0}",
3560
4300
  ".dsh-upd-qrow{display:flex;align-items:baseline;flex-wrap:wrap;gap:10px;padding:6px 0;min-width:0}",
3561
4301
  ".dsh-upd-qrow+.dsh-upd-qrow{border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
3562
4302
  ".dsh-upd-qdot{width:8px;height:8px;border-radius:50%;flex:none;align-self:center;background:currentColor;opacity:.5}",
3563
4303
  ".dsh-upd-qdot[data-tone=\"busy\"]{background:var(--dsh-update-warn-border,#d97706);opacity:1}",
3564
4304
  ".dsh-upd-qdot[data-tone=\"you\"]{background:var(--dsh-update-primary,#2563eb);opacity:1}",
3565
- ".dsh-upd-qk{flex:none;width:5.5em;font-size:12px;opacity:.7}",
4305
+ ".dsh-upd-qk{flex:none;width:5.5em;font-size:var(--dsh-update-panel-small-font-size,12px);opacity:.7}",
3566
4306
  ".dsh-upd-qv{font-weight:600}",
3567
- ".dsh-upd-qn{margin-left:auto;font-size:12px;opacity:.7}",
3568
- ".dsh-upd-qseq{font-family:Consolas,Menlo,monospace;font-size:12px;word-break:break-all}",
4307
+ ".dsh-upd-qn{margin-left:auto;font-size:var(--dsh-update-panel-small-font-size,12px);opacity:.7}",
4308
+ ".dsh-upd-qseq{font-family:Consolas,Menlo,monospace;font-size:var(--dsh-update-panel-small-font-size,12px);word-break:break-all}",
3569
4309
  ".dsh-upd-prog{height:8px;background:var(--dsh-update-border,#e5e7eb);border-radius:4px;overflow:hidden;margin:10px 0 4px}",
3570
4310
  ".dsh-upd-prog-bar{display:block;height:100%;background:var(--dsh-update-primary,#2563eb);transition:width .3s}",
3571
- ".dsh-upd-progtxt{font-size:12.5px;opacity:.75}",
3572
- ".dsh-upd-skipline{font-size:13px;margin-top:8px}",
4311
+ ".dsh-upd-progtxt{font-size:var(--dsh-update-panel-small-font-size,12.5px);opacity:.75}",
4312
+ ".dsh-upd-skipline{font-size:var(--dsh-update-panel-log-font-size,13px);margin-top:8px}",
3573
4313
  ".dsh-upd-skv{display:inline-block;min-width:64px;border-radius:3px;color:transparent !important;user-select:none;",
3574
4314
  "background:linear-gradient(90deg,var(--dsh-update-border,#e5e7eb) 25%,var(--dsh-update-bg-soft,#f3f4f6) 50%,var(--dsh-update-border,#e5e7eb) 75%);",
3575
4315
  "background-size:200% 100%;animation:dsh-upd-shimmer 1.2s linear infinite}",
3576
4316
  "@keyframes dsh-upd-shimmer{to{background-position:-200% 0}}",
3577
- ".dsh-upd-tag{display:inline-block;border:1px dashed currentColor;border-radius:3px;padding:1px 8px;margin-right:8px;font-family:Consolas,Menlo,monospace;font-size:12px}",
3578
- ".dsh-upd-err{font-size:13px;margin:0 0 6px}",
4317
+ ".dsh-upd-tag{display:inline-block;border:1px dashed currentColor;border-radius:3px;padding:1px 8px;margin-right:8px;font-family:Consolas,Menlo,monospace;font-size:var(--dsh-update-panel-small-font-size,12px)}",
4318
+ ".dsh-upd-err{font-size:var(--dsh-update-panel-log-font-size,13px);margin:0 0 6px}",
3579
4319
  ".dsh-upd button{transition:background-color .15s ease,border-color .15s ease,color .15s ease,transform .06s ease}",
3580
4320
  ".dsh-upd button:hover:not(:disabled){border-color:var(--dsh-update-focus,#2563eb)}",
3581
4321
  ".dsh-upd button[data-primary=\"1\"]:hover:not(:disabled){filter:brightness(.93)}",
@@ -3606,7 +4346,8 @@ ${blocks.join("\n")}
3606
4346
  ".dsh-upd-actions button[data-primary=\"1\"]{min-width:9em}",
3607
4347
  ".dsh-upd-banner{min-height:3.4em;display:flex;flex-direction:column;justify-content:center}",
3608
4348
  ".dsh-upd-banner{animation:none}",
3609
- ".dsh-upd-banner-sub{font-size:12.5px;opacity:.75;margin:2px 0 8px;text-align:left}",
4349
+ ".dsh-upd-banner-sub{font-size:var(--dsh-update-panel-small-font-size,12.5px);opacity:.75;margin:2px 0 8px;text-align:left}",
4350
+ ".dsh-upd-banner>div:first-child strong{font-size:var(--dsh-update-panel-banner-title-font-size,inherit)}",
3610
4351
  ".dsh-upd-banner>div:first-child>.dsh-upd-sealmini{display:none}",
3611
4352
  ".dsh-upd-copy{min-height:1.75em}",
3612
4353
  ".dsh-upd-copy--empty{visibility:hidden}",
@@ -3655,13 +4396,13 @@ ${blocks.join("\n")}
3655
4396
  ".dsh-upd[data-theme=\"archive\"][data-seal-tone=\"yellow\"]::before{color:var(--dsh-update-warn-text)}",
3656
4397
  ".dsh-upd[data-theme=\"archive\"][data-seal-tone=\"red\"]::before{color:var(--dsh-update-bad-text)}",
3657
4398
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-masthead{display:block;padding:0 0 8px;margin:0 0 8px;border-bottom:1px solid var(--dsh-update-border)}",
3658
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-masthead-kicker{display:block;font-size:11px;letter-spacing:.35em;color:var(--dsh-update-text-muted);margin-bottom:3px}",
4399
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-masthead-kicker{display:block;font-size:var(--dsh-update-panel-small-font-size,11px);letter-spacing:.35em;color:var(--dsh-update-text-muted);margin-bottom:3px}",
3659
4400
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-masthead-title{font-family:var(--dsh-update-font-serif);font-size:26px;font-weight:700;line-height:1.2}",
3660
4401
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-masthead-title i{color:var(--dsh-update-primary);font-style:normal}",
3661
4402
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-qrow{padding:6px 0}",
3662
4403
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-qk{width:66px;letter-spacing:.18em}",
3663
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-qv{font-family:var(--dsh-update-font-serif);font-size:16px}",
3664
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-qn{font-family:var(--dsh-update-font-mono);font-size:11.5px;color:var(--dsh-update-text-muted)}",
4404
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-qv{font-family:var(--dsh-update-font-serif);font-size:var(--dsh-update-panel-small-font-size,16px)}",
4405
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-qn{font-family:var(--dsh-update-font-mono);font-size:var(--dsh-update-panel-small-font-size,11.5px);color:var(--dsh-update-text-muted)}",
3665
4406
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-qseq{color:var(--dsh-update-text-muted)}",
3666
4407
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-chap-note{color:var(--dsh-update-text-muted)}",
3667
4408
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-body .dsh-upd-chap-head{background:var(--dsh-update-bg)}",
@@ -3677,40 +4418,43 @@ ${blocks.join("\n")}
3677
4418
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner[data-kind=\"busy\"] .dsh-upd-sealmini{color:var(--dsh-update-warn-text)}",
3678
4419
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner[data-kind=\"blocked\"] .dsh-upd-sealmini,.dsh-upd[data-theme=\"archive\"] .dsh-upd-banner[data-kind=\"failed\"] .dsh-upd-sealmini{color:var(--dsh-update-bad-text)}",
3679
4420
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner[data-kind=\"done\"] .dsh-upd-sealmini{color:var(--dsh-update-ok-text)}",
3680
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-log code{font-family:var(--dsh-update-font-mono);font-size:11px;color:var(--dsh-update-text-muted);border:1px solid var(--dsh-update-border-strong);border-radius:3px;padding:0 6px;letter-spacing:.06em}",
3681
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-manual code{display:block;background:var(--dsh-update-text);color:var(--dsh-update-bg-soft);font-family:var(--dsh-update-font-mono);font-size:12.5px;padding:12px 14px;border-radius:4px;white-space:pre-wrap;word-break:break-all}",
4421
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-log code{font-family:var(--dsh-update-font-mono);font-size:var(--dsh-update-panel-log-font-size,11px);color:var(--dsh-update-text-muted);border:1px solid var(--dsh-update-border-strong);border-radius:3px;padding:0 6px;letter-spacing:.06em}",
4422
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-manual code{display:block;background:var(--dsh-update-text);color:var(--dsh-update-bg-soft);font-family:var(--dsh-update-font-mono);font-size:var(--dsh-update-panel-log-font-size,12.5px);padding:12px 14px;border-radius:4px;white-space:pre-wrap;word-break:break-all}",
4423
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner[data-kind=\"restart\"]>div:first-child strong{margin-left:-30px;text-indent:30px}",
3682
4424
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner[data-kind=\"restart\"]>div:first-child{display:flex;gap:10px;align-items:flex-start}",
3683
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner[data-kind=\"restart\"]>div:first-child::before{content:\"\";flex:none;width:20px;height:20px;margin-top:3px;",
4425
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner[data-kind=\"restart\"]>div:first-child::before{content:\"\";flex:none;width:20px;height:20px;margin-top:7px;",
3684
4426
  "background:url(\"data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2720%27 height=%2720%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27%238a5a00%27 stroke-width=%272%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3E%3Cpath d=%27M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z%27/%3E%3Cline x1=%2712%27 y1=%279%27 x2=%2712%27 y2=%2713%27/%3E%3Cline x1=%2712%27 y1=%2717%27 x2=%2712.01%27 y2=%2717%27/%3E%3C/svg%3E\") no-repeat center/20px 20px}",
3685
4427
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner>div:first-child{overflow:hidden;text-overflow:ellipsis}",
3686
4428
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-actions{flex-wrap:wrap}",
3687
4429
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-footer{margin-top:14px;padding-top:10px;border-top:1px solid var(--dsh-update-border)}",
3688
4430
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-foot-note{color:var(--dsh-update-text-muted)}",
4431
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-footer button{background:transparent}",
3689
4432
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-head{display:flex;gap:16px;align-items:baseline;flex-wrap:wrap;padding-right:120px}",
3690
4433
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-name{font-family:var(--dsh-update-font-serif);font-size:22px;font-weight:700}",
3691
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-meta{width:100%;font-size:12.5px;color:var(--dsh-update-text-muted)}",
4434
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-meta{width:100%;font-size:var(--dsh-update-panel-small-font-size,12.5px);color:var(--dsh-update-text-muted)}",
3692
4435
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-meta b{color:var(--dsh-update-text);font-weight:600}",
3693
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-proftag{font-family:var(--dsh-update-font-mono);font-size:11px;color:var(--dsh-update-text-muted);border:1px solid var(--dsh-update-border-strong);border-radius:3px;padding:0 6px;margin-left:8px;letter-spacing:.06em}",
3694
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-strip{display:flex;flex-wrap:wrap;margin:8px 0 0;border:1px solid var(--dsh-update-border);border-radius:4px;overflow:hidden;font-size:12.5px}",
4436
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-proftag{font-family:var(--dsh-update-font-mono);font-size:var(--dsh-update-panel-small-font-size,11px);color:var(--dsh-update-text-muted);border:1px solid var(--dsh-update-border-strong);border-radius:3px;padding:0 6px;margin-left:8px;letter-spacing:.06em}",
4437
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-strip{display:flex;flex-wrap:wrap;margin:8px 0 0;border:1px solid var(--dsh-update-border);border-radius:4px;overflow:hidden;font-size:var(--dsh-update-panel-small-font-size,12.5px)}",
3695
4438
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-strip>div{flex:1 1 120px;padding:6px 10px;border-left:1px solid var(--dsh-update-border)}",
3696
4439
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-strip>div:first-child{border-left:0}",
3697
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-strip-k{display:block;font-size:11px;letter-spacing:.2em;color:var(--dsh-update-text-muted)}",
3698
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-strip-v{font-family:var(--dsh-update-font-mono);font-size:13px}",
4440
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-strip-k{display:block;font-size:var(--dsh-update-panel-small-font-size,11px);letter-spacing:.2em;color:var(--dsh-update-text-muted)}",
4441
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-strip-v{font-family:var(--dsh-update-font-mono);font-size:var(--dsh-update-panel-small-font-size,13px)}",
3699
4442
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-chapter{margin-top:16px;padding-top:10px;border-top:1px solid var(--dsh-update-border)}",
3700
4443
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-chap-head{display:flex;align-items:baseline;gap:12px;margin-bottom:6px}",
3701
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-chap-no{font-family:var(--dsh-update-font-serif);font-style:italic;font-size:15px;color:var(--dsh-update-text-muted)}",
3702
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-chap-title{font-family:var(--dsh-update-font-serif);font-size:17px;margin:0;letter-spacing:.1em}",
4444
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-chap-no{font-family:var(--dsh-update-font-serif);font-style:italic;font-size:var(--dsh-update-panel-chapter-font-size,15px);color:var(--dsh-update-text-muted)}",
4445
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-chap-title{font-family:var(--dsh-update-font-serif);font-size:var(--dsh-update-panel-chapter-font-size,17px);margin:0;letter-spacing:.1em}",
3703
4446
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-chap-rule{flex:1;border-top:1px solid var(--dsh-update-border);transform:translateY(-4px)}",
3704
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner{border:2px solid var(--dsh-update-border-strong);border-radius:4px;padding:10px 12px;font-size:14.5px;font-family:var(--dsh-update-font-serif);gap:10px;align-items:center}",
4447
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner{border:2px solid var(--dsh-update-border-strong);border-radius:4px;padding:10px 12px;font-size:var(--dsh-update-panel-font-size,14.5px);font-family:var(--dsh-update-font-serif);gap:10px;align-items:center}",
3705
4448
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner>div:first-child{flex:1 1 auto;min-width:0;align-self:stretch}",
3706
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner>div:first-child strong{font-family:var(--dsh-update-font-serif);font-size:27px;font-weight:700;line-height:1.25}",
4449
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner>div:first-child strong{font-family:var(--dsh-update-font-serif);font-size:var(--dsh-update-panel-banner-title-font-size,27px);font-weight:700;line-height:1.25}",
4450
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner[data-kind=\"done\"]>div:first-child strong{font-size:var(--dsh-update-panel-banner-title-font-size,24px)}",
3707
4451
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-prog{height:8px;background:var(--dsh-update-border);border-radius:4px;overflow:hidden;margin:10px 0 4px}",
3708
4452
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-prog-bar{display:block;height:100%;background:var(--dsh-update-primary);transition:width .3s}",
3709
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-progtxt{font-size:12.5px;color:var(--dsh-update-text-muted)}",
3710
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-skipline{font-size:13px;margin-top:8px}",
3711
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-tag{display:inline-block;border:1px dashed var(--dsh-update-border-strong);border-radius:3px;padding:1px 8px;margin-right:8px;font-family:var(--dsh-update-font-mono);font-size:12px}",
3712
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-err{font-size:13px;margin:0 0 6px;color:var(--dsh-update-text-muted)}",
3713
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner-sub{color:var(--dsh-update-text-muted);font-size:12.5px;text-align:left;margin:2px 0 8px}",
4453
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-progtxt{font-size:var(--dsh-update-panel-small-font-size,12.5px);color:var(--dsh-update-text-muted)}",
4454
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-skipline{font-size:var(--dsh-update-panel-log-font-size,13px);margin-top:8px}",
4455
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-tag{display:inline-block;border:1px dashed var(--dsh-update-border-strong);border-radius:3px;padding:1px 8px;margin-right:8px;font-family:var(--dsh-update-font-mono);font-size:var(--dsh-update-panel-small-font-size,12px)}",
4456
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-err{font-size:var(--dsh-update-panel-log-font-size,13px);margin:0 0 6px;color:var(--dsh-update-text-muted)}",
4457
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner-sub{color:var(--dsh-update-text-muted);font-size:var(--dsh-update-panel-small-font-size,12.5px);text-align:left;margin:2px 0 8px}",
3714
4458
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-actions{gap:8px;min-height:0}",
3715
4459
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-actions button{font-size:13px;line-height:1.45;padding:6px 12px;margin:0;min-width:0}",
3716
4460
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-actions button:first-child{min-width:0}",
@@ -3718,18 +4462,28 @@ ${blocks.join("\n")}
3718
4462
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-actions button:first-child:not([aria-busy=\"true\"])::after{display:none}",
3719
4463
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-actions button:not([data-primary=\"1\"]){background:transparent}",
3720
4464
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-actions button[data-action=\"copy-manual\"],.dsh-upd[data-theme=\"archive\"] .dsh-upd-actions button[data-action=\"copy-diag\"]{font-size:12px;padding:4px 10px}",
4465
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-chap-note button{font-size:12px;line-height:1.45;padding:4px 10px;margin:0;min-width:0;background:transparent}",
3721
4466
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-version{margin:12px 0}",
3722
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-title{font-family:var(--dsh-update-font-mono);font-size:14px;font-weight:700}",
3723
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-date{font-weight:400;font-size:12px;color:var(--dsh-update-text-muted)}",
3724
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog ul{margin:6px 0 0 2px;padding-left:18px;font-size:13.5px}",
4467
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-title{font-family:var(--dsh-update-font-mono);font-size:var(--dsh-update-panel-log-font-size,14px);font-weight:700}",
4468
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-date{font-weight:400;font-size:var(--dsh-update-panel-small-font-size,12px);color:var(--dsh-update-text-muted)}",
4469
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog ul{margin:6px 0 0 2px;padding-left:18px;font-size:var(--dsh-update-panel-log-font-size,13.5px)}",
3725
4470
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog li{margin:3px 0}",
3726
4471
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-catname{display:none}",
3727
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-cat[data-cat=\"Added\"] ul li::before{content:\"Added · \";color:var(--dsh-update-primary);font-weight:700}",
3728
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-cat[data-cat=\"Fixed\"] ul li::before{content:\"Fixed · \";color:var(--dsh-update-primary);font-weight:700}",
3729
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-cat[data-cat=\"Changed\"] ul li::before{content:\"Changed · \";color:var(--dsh-update-primary);font-weight:700}",
3730
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-cat[data-cat=\"Security\"] ul li::before{content:\"Security · \";color:var(--dsh-update-primary);font-weight:700}",
3731
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-fold[data-cat=\"Deprecated\"] ul li::before{content:\"Deprecated · \";color:var(--dsh-update-text-muted);font-weight:700}",
3732
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-fold[data-cat=\"Removed\"] ul li::before{content:\"Removed · \";color:var(--dsh-update-text-muted);font-weight:700}",
4472
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-cat[data-cat=\"other\"] .dsh-upd-changelog-catname{display:block;font-size:var(--dsh-update-panel-small-font-size,12.5px);color:var(--dsh-update-primary);font-weight:700}",
4473
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-truncnote{border-left-color:var(--dsh-update-border-strong);opacity:1;color:var(--dsh-update-text-muted)}",
4474
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-cat[data-cat=\"Added\"]>ul>li:not([data-cat-lead]):not([data-cat-block])::before{content:\"Added · \";color:var(--dsh-update-primary);font-weight:700}",
4475
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-cat[data-cat=\"Fixed\"]>ul>li:not([data-cat-lead]):not([data-cat-block])::before{content:\"Fixed · \";color:var(--dsh-update-primary);font-weight:700}",
4476
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-cat[data-cat=\"Changed\"]>ul>li:not([data-cat-lead]):not([data-cat-block])::before{content:\"Changed · \";color:var(--dsh-update-primary);font-weight:700}",
4477
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-cat[data-cat=\"Security\"]>ul>li:not([data-cat-lead]):not([data-cat-block])::before{content:\"Security · \";color:var(--dsh-update-primary);font-weight:700}",
4478
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-fold[data-cat=\"Deprecated\"]>ul>li:not([data-cat-lead]):not([data-cat-block])::before{content:\"Deprecated · \";color:var(--dsh-update-text-muted);font-weight:700}",
4479
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-changelog-fold[data-cat=\"Removed\"]>ul>li:not([data-cat-lead]):not([data-cat-block])::before{content:\"Removed · \";color:var(--dsh-update-text-muted);font-weight:700}",
4480
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-md-code{background:var(--dsh-update-bg-soft);border-color:var(--dsh-update-border);color:var(--dsh-update-primary-deep);border-radius:2px;padding:0 3px}",
4481
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-md-link{color:var(--dsh-update-primary);text-decoration:none;border-bottom:1px solid currentColor}",
4482
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-md-img{border-color:var(--dsh-update-border-strong);color:var(--dsh-update-text-muted)}",
4483
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-md-pre{background:var(--dsh-update-bg-soft);border-color:var(--dsh-update-border);border-radius:2px}",
4484
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-md-quote{border-left-color:var(--dsh-update-border-strong);color:var(--dsh-update-text-muted)}",
4485
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-md-list,.dsh-upd[data-theme=\"archive\"] .dsh-upd-md-list-ol{padding-left:16px}",
4486
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-md-hr{border-top-color:var(--dsh-update-border-strong)}",
3733
4487
  "@media (max-width:640px){.dsh-upd[data-theme=\"archive\"]{padding:10px 12px}.dsh-upd[data-theme=\"archive\"]::before{top:12px;right:12px;width:56px;height:56px;font-size:15px;box-shadow:inset 0 0 0 4px var(--dsh-update-bg),inset 0 0 0 5px currentColor}.dsh-upd[data-theme=\"archive\"] .dsh-upd-masthead-title{font-size:19px}.dsh-upd[data-theme=\"archive\"] .dsh-upd-banner{padding-right:16px}.dsh-upd[data-theme=\"archive\"] .dsh-upd-banner .dsh-upd-sealmini{min-width:28px;height:28px;font-size:14px;line-height:20px}.dsh-upd[data-theme=\"archive\"] .dsh-upd-banner>div:first-child{white-space:normal}}",
3734
4488
  "@media (prefers-color-scheme: dark){.dsh-upd[data-theme=\"archive\"]{--dsh-update-bg-soft:#141210;--dsh-update-bg:#1e1a15;--dsh-update-text:#ece5d3;--dsh-update-text-muted:#a89c83;",
3735
4489
  "--dsh-update-border:#3a3226;--dsh-update-border-strong:#5c4e3b;--dsh-update-primary:#e0684e;--dsh-update-primary-deep:#f0866b;",
@@ -3737,6 +4491,7 @@ ${blocks.join("\n")}
3737
4491
  "--dsh-update-bad-text:#ef8a7d;--dsh-update-bad-bg:rgba(239,138,125,.12);--dsh-update-shadow:0 1px 2px rgba(0,0,0,.4),0 12px 32px rgba(0,0,0,.45)}}",
3738
4492
  "@media (prefers-color-scheme: dark){.dsh-upd[data-theme=\"archive\"] button[data-primary=\"1\"]{color:#141210}.dsh-upd[data-theme=\"archive\"] button:focus-visible{outline-color:var(--dsh-update-primary-deep)}}",
3739
4493
  "@media (prefers-color-scheme: dark){.dsh-upd[data-theme=\"archive\"] .dsh-upd-banner[data-kind=\"restart\"]>div:first-child::before{background-image:url(\"data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2720%27 height=%2720%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27%23e8c15a%27 stroke-width=%272%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3E%3Cpath d=%27M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z%27/%3E%3Cline x1=%2712%27 y1=%279%27 x2=%2712%27 y2=%2713%27/%3E%3Cline x1=%2712%27 y1=%2717%27 x2=%2712.01%27 y2=%2717%27/%3E%3C/svg%3E\")}}",
4494
+ "@media (prefers-color-scheme: dark){.dsh-upd[data-theme=\"archive\"] .dsh-upd-manual code{background:#26211a;color:#ece5d3;border:1px solid var(--dsh-update-border-strong)}}",
3740
4495
  "@media (forced-colors: active){.dsh-upd[data-theme=\"archive\"]{box-shadow:none}.dsh-upd[data-theme=\"archive\"]::before{background:none;box-shadow:none;border-color:CanvasText;color:CanvasText}.dsh-upd[data-theme=\"archive\"] .dsh-upd-banner{border:1px solid CanvasText}.dsh-upd[data-theme=\"archive\"] .dsh-upd-banner::before{border-color:CanvasText;color:CanvasText;background:Canvas}.dsh-upd[data-theme=\"archive\"] button{border:1px solid ButtonText}.dsh-upd[data-theme=\"archive\"] button[data-primary=\"1\"]{background:ButtonFace;color:ButtonText;border-color:ButtonText}.dsh-upd[data-theme=\"archive\"] .dsh-upd-banner[data-kind=\"restart\"]>div:first-child::before{background-image:none;content:\"⚠\"}}",
3741
4496
  "@media (prefers-reduced-motion: reduce){.dsh-upd[data-theme=\"archive\"] *{transition:none !important;animation:none !important}}"
3742
4497
  ].join("\n");
@@ -3784,7 +4539,7 @@ ${blocks.join("\n")}
3784
4539
  const unknown = copyText("panel.meta.unknown", l);
3785
4540
  const cell = (k, v) => `<div><span class="dsh-upd-strip-k">${escapeHtml$2(k)}</span><span class="dsh-upd-strip-v">${escapeHtml$2(v ?? unknown)}</span></div>`;
3786
4541
  if (!snapshot) return "";
3787
- return `<div class="dsh-upd-strip">` + cell(copyText("panel.strip.running", l), snapshot.runningVersion) + cell(copyText("panel.strip.installed", l), snapshot.installedVersion) + cell(copyText("panel.strip.latest", l), snapshot.latestVersion) + `</div>`;
4542
+ return `<div class="dsh-upd-strip">` + cell(copyText("panel.strip.running", l), snapshot.runningVersion) + cell(copyText("panel.strip.installed", l), snapshot.installed === false ? copyText("panel.banner.not-installed", l) : snapshot.installedVersion) + cell(copyText("panel.strip.latest", l), snapshot.latestVersion) + `</div>`;
3788
4543
  }
3789
4544
  function progressBar(snapshot, lang) {
3790
4545
  const job = snapshot?.job;
@@ -3837,14 +4592,18 @@ ${blocks.join("\n")}
3837
4592
  let hasLog = false;
3838
4593
  if (snapshot && snapshot.latestVersion) try {
3839
4594
  const mdText = typeof changelogMarkdown === "string" ? changelogMarkdown : "";
3840
- const entries = parseChangelog(mdText);
4595
+ const report = parseChangelogReport(mdText);
4596
+ const entries = report.entries;
3841
4597
  const ranged = changelogForUpdate(entries, snapshot.runningVersion, snapshot.latestVersion, snapshot.installedVersion);
3842
4598
  if (ranged.length === 0 && mdText.trim() && entries.length === 0) {
3843
- inner = `<div class="dsh-upd-changelog-wrap"><div class="dsh-upd-changelog-neutral">${escapeHtml$2(copyText("panel.changelog.unavailable", l))}</div></div>`;
4599
+ inner = `<div class="dsh-upd-changelog-wrap"><div class="dsh-upd-changelog-neutral">${escapeHtml$2(copyText("panel.changelog.unavailable", l))}</div>${truncationNoteHTML(report.truncation, l)}</div>`;
3844
4600
  hasLog = false;
3845
4601
  } else {
3846
- const changelogHTML = renderChangelogHTML(ranged, { lang: l });
3847
- const fromText = String(snapshot.runningVersion ?? "");
4602
+ const changelogHTML = renderChangelogHTML(ranged, {
4603
+ lang: l,
4604
+ truncated: report.truncation
4605
+ });
4606
+ const fromText = snapshot.installed === false ? copyText("panel.banner.not-installed", l) : String(snapshot.runningVersion ?? "");
3848
4607
  const toText = String(snapshot.latestVersion ?? "");
3849
4608
  const rangeTitle = fromText && toText ? copyText("panel.changelog.heading-range", l, {
3850
4609
  from: fromText,
@@ -3917,7 +4676,13 @@ ${changelogHTML}
3917
4676
  }
3918
4677
  } else errLines.push(`<div class="dsh-upd-changelog-neutral">${escapeHtml$2(copyText("panel.error.no-failure", l))}</div>`);
3919
4678
  if (input.showLogHint !== false) {
4679
+ const logDirInput = input.logDir;
4680
+ const logDirKnown = typeof logDirInput === "string" && logDirInput.trim() ? logDirInput.trim() : null;
4681
+ const logDirShown = logDirKnown ?? "<DSH_HOME>/logs/<derived>";
4682
+ const logCmdShown = logDirKnown ? `npx dsh-log ${logDirKnown}` : "npx dsh-log <log-dir>";
3920
4683
  errLines.push(`<div class="dsh-upd-log">${copyText("panel.error.log-hint", l, {
4684
+ dir: `<code>${escapeHtml$2(logDirShown)}</code>`,
4685
+ cmd: `<code>${escapeHtml$2(logCmdShown)}</code>`,
3921
4686
  pluginId: `<code>${escapeHtml$2(pluginId)}</code>`,
3922
4687
  e1: `<code>${LOG_EVENT_CALL}</code>`,
3923
4688
  e2: `<code>${LOG_EVENT_CALL_FAIL}</code>`,
@@ -3957,7 +4722,7 @@ ${UPDATE_PANEL_ARCHIVE_CSS}` : UPDATE_PANEL_CSS}</style>
3957
4722
  ${body}`;
3958
4723
  }
3959
4724
  //#endregion
3960
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.12.0/node_modules/dsh-plugin-update/dist/entry.js
4725
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.17.0/node_modules/dsh-plugin-update/dist/entry.js
3961
4726
  const UPDATE_ENTRY_CSS = [
3962
4727
  ".dsh-upd-entry{display:inline-flex;align-items:center;gap:8px;font:13px/1.6 var(--dsh-update-font-sans,system-ui,\"Microsoft YaHei\",sans-serif);font-size:var(--dsh-update-entry-font-size,13px);color:var(--dsh-update-text,#1f2937)}",
3963
4728
  ".dsh-upd-entry-btn{font:inherit;border:1px solid var(--dsh-update-border,#d1d5db);border-radius:var(--dsh-update-entry-border-radius,6px);",
@@ -4071,7 +4836,7 @@ ${body}`;
4071
4836
  }
4072
4837
  }
4073
4838
  //#endregion
4074
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.12.0/node_modules/dsh-plugin-update/dist/panel-batch.js
4839
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.17.0/node_modules/dsh-plugin-update/dist/panel-batch.js
4075
4840
  const BATCH_PANEL_POLL = {
4076
4841
  defaultMs: 1500,
4077
4842
  minMs: 250
@@ -4143,8 +4908,10 @@ ${body}`;
4143
4908
  if (!isObject$1(item)) return null;
4144
4909
  const e = item;
4145
4910
  const canInstallRaw = e["canInstall"];
4911
+ const installedRaw = e["installed"];
4146
4912
  return {
4147
4913
  lastCheckedAt: typeof e["lastCheckedAt"] === "number" ? e["lastCheckedAt"] : 0,
4914
+ installed: typeof installedRaw === "boolean" ? installedRaw : null,
4148
4915
  installedVersion: typeof e["installedVersion"] === "string" ? e["installedVersion"] : null,
4149
4916
  latestVersion: typeof e["latestVersion"] === "string" ? e["latestVersion"] : null,
4150
4917
  canInstall: typeof canInstallRaw === "boolean" ? canInstallRaw : null,
@@ -4230,7 +4997,7 @@ ${body}`;
4230
4997
  case "installing": return batchText("batch.row.installing", l);
4231
4998
  case "current": return batchText("batch.row.current", l);
4232
4999
  case "done": return row.restartRequired === true ? batchText("batch.row.done-restart", l) : batchText("batch.row.done", l);
4233
- case "failed": return batchText("batch.row.failed-retry", l);
5000
+ case "failed": return isCheckSideFailureCode(jobFailureOf(row)?.code ?? (typeof row.error === "string" && row.error ? row.error : null)) ? batchText("batch.row.failed", l) : batchText("batch.row.failed-retry", l);
4234
5001
  case "skipped": return batchText("batch.row.skipped-idle", l);
4235
5002
  default: return batchText("batch.row.unknown", l);
4236
5003
  }
@@ -4263,7 +5030,9 @@ ${body}`;
4263
5030
  hasUpdate: true
4264
5031
  };
4265
5032
  }
4266
- const current = currentVersionOf(row) ?? (knowledge && typeof knowledge.installedVersion === "string" && knowledge.installedVersion ? knowledge.installedVersion : null);
5033
+ const snapshotCurrent = currentVersionOf(row);
5034
+ const knowledgeCurrent = knowledge && knowledge.installed !== false && typeof knowledge.installedVersion === "string" && knowledge.installedVersion ? knowledge.installedVersion : null;
5035
+ const current = snapshotCurrent ?? knowledgeCurrent;
4267
5036
  const latest = knowledge && typeof knowledge.latestVersion === "string" && knowledge.latestVersion ? knowledge.latestVersion : null;
4268
5037
  if (current && latest && latest !== current) return {
4269
5038
  current,
@@ -4286,10 +5055,11 @@ ${body}`;
4286
5055
  hasUpdate: false
4287
5056
  };
4288
5057
  }
4289
- function batchRowVersionHTML(row, knowledge) {
5058
+ function batchRowVersionHTML(row, knowledge, lang) {
4290
5059
  const parts = batchRowVersionParts(row, knowledge);
4291
5060
  if (parts.hasUpdate && parts.latest) {
4292
- const cur = parts.current ?? "?";
5061
+ const snapshot = isObject$1(row.snapshot) ? row.snapshot : null;
5062
+ const cur = parts.current ?? (snapshot !== null && snapshot["installed"] === false ? batchText("batch.row.not-installed", lang) : "?");
4293
5063
  const newCls = asBatchPhase(row.phase) === "done" ? "dsh-upd-bver-new-ok" : "dsh-upd-bver-new";
4294
5064
  return "<span class=\"dsh-upd-bver\"><span class=\"dsh-upd-bver-cur\">" + escapeHtml$1(cur) + "</span><span class=\"dsh-upd-bver-arrow\" aria-hidden=\"true\"> → </span><span class=\"" + newCls + "\">" + escapeHtml$1(parts.latest) + "</span></span>";
4295
5065
  }
@@ -4395,12 +5165,27 @@ ${body}`;
4395
5165
  const seal = batchSealOf(counts, lang);
4396
5166
  const root = "<div class=\"dsh-upd dsh-upd-batch\" data-mode=\"" + mode + "\" data-seal=\"" + escapeHtml$1(seal.text) + "\" data-seal-tone=\"" + seal.tone + "\"" + attr + tokensAttr + ">\n" + kernel + "\n</div>";
4397
5167
  const body = mode === "dialog" ? "<div class=\"dsh-upd-overlay\" data-mode=\"dialog\">" + root + "</div>" : root;
5168
+ let detailDialog = "";
5169
+ if (expandedKey !== null) {
5170
+ const target = rows.find((row) => row.key === expandedKey) ?? null;
5171
+ if (target !== null) {
5172
+ const rawSkipped = skippedVersions[target.key];
5173
+ const skippedForDialog = typeof rawSkipped === "string" && rawSkipped ? rawSkipped : null;
5174
+ detailDialog = detailDialogHTML(target, {
5175
+ ...ctx,
5176
+ expanded: true,
5177
+ skipped: skippedForDialog,
5178
+ notice: target.key === detailNoticeKey ? notice : null,
5179
+ changelogMarkdown: typeof changelogs[target.key] === "string" ? changelogs[target.key] : null
5180
+ });
5181
+ }
5182
+ }
4398
5183
  return "<style>" + (archive ? [
4399
5184
  UPDATE_PANEL_CSS,
4400
5185
  UPDATE_BATCH_PANEL_CSS,
4401
5186
  UPDATE_PANEL_ARCHIVE_CSS,
4402
5187
  UPDATE_BATCH_PANEL_ARCHIVE_CSS
4403
- ].join(String.fromCharCode(10)) : [UPDATE_PANEL_CSS, UPDATE_BATCH_PANEL_CSS].join(String.fromCharCode(10))) + "</style>\n" + body;
5188
+ ].join(String.fromCharCode(10)) : [UPDATE_PANEL_CSS, UPDATE_BATCH_PANEL_CSS].join(String.fromCharCode(10))) + "</style>\n" + body + (detailDialog ? "\n" + detailDialog : "");
4404
5189
  }
4405
5190
  function batchSummaryText(counts, rows, total, installing, hasError, lang) {
4406
5191
  const l = langOf(lang);
@@ -4448,7 +5233,8 @@ ${body}`;
4448
5233
  parts.push("<div class=\"dsh-upd-banner\" data-kind=\"failed\" data-mini=\"阻\" role=\"status\"><div><span class=\"dsh-upd-sealmini\" aria-hidden=\"true\">阻</span><strong>" + escapeHtml$1(batchText("batch.banner.error-title", l, {
4449
5234
  code: lastError,
4450
5235
  detail
4451
- })) + "</strong></div><div>" + escapeHtml$1(act) + "</div></div>");
5236
+ })) + "</strong></div></div>");
5237
+ if (act) parts.push("<div class=\"dsh-upd-banner-sub\">" + escapeHtml$1(act) + "</div>");
4452
5238
  }
4453
5239
  const failed = rows.filter((row) => asBatchPhase(row.phase) === "failed" && !isQueueBusyRow(row));
4454
5240
  if (failed.length > 0) {
@@ -4457,10 +5243,16 @@ ${body}`;
4457
5243
  const copy = failureCopy(code, l);
4458
5244
  return "<div>" + escapeHtml$1(titleOf(row, titles)) + ":<code>" + escapeHtml$1(code) + "</code> " + escapeHtml$1(copy?.zh ?? failureCopy("unknown", l)?.zh ?? "") + "</div>";
4459
5245
  }).join("");
4460
- parts.push("<div class=\"dsh-upd-banner\" data-kind=\"failed\" data-mini=\"阻\" role=\"status\"><div><span class=\"dsh-upd-sealmini\" aria-hidden=\"true\">阻</span><strong>" + escapeHtml$1(batchText("batch.banner.failed-title", l, { n: String(failed.length) })) + "</strong></div><div>" + escapeHtml$1(batchText("batch.banner.failed-action", l)) + "</div><div class=\"dsh-upd-blist\">" + lines + "</div></div>");
5246
+ const failedAct = batchText("batch.banner.failed-action", l);
5247
+ parts.push("<div class=\"dsh-upd-banner\" data-kind=\"failed\" data-mini=\"阻\" role=\"status\"><div><span class=\"dsh-upd-sealmini\" aria-hidden=\"true\">阻</span><strong>" + escapeHtml$1(batchText("batch.banner.failed-title", l, { n: String(failed.length) })) + "</strong></div><div class=\"dsh-upd-blist\">" + lines + "</div></div>");
5248
+ if (failedAct) parts.push("<div class=\"dsh-upd-banner-sub\">" + escapeHtml$1(failedAct) + "</div>");
4461
5249
  }
4462
5250
  const restart = rows.filter((row) => row.restartRequired === true);
4463
- if (restart.length > 0) parts.push("<div class=\"dsh-upd-banner\" data-kind=\"restart\" role=\"status\"><div><strong>" + escapeHtml$1(batchText("batch.banner.restart-title", l, { n: String(restart.length) })) + "</strong></div><div>" + escapeHtml$1(batchText("batch.banner.restart-action", l)) + "</div><div class=\"dsh-upd-blist\">" + restart.map((row) => escapeHtml$1(titleOf(row, titles))).join("、") + "</div><div><button type=\"button\" data-act=\"restart\">" + escapeHtml$1(batchText("batch.banner.restart-button", l)) + "</button></div></div>");
5251
+ if (restart.length > 0) {
5252
+ const restartAct = batchText("batch.banner.restart-action", l);
5253
+ parts.push("<div class=\"dsh-upd-banner\" data-kind=\"restart\" role=\"status\"><div><strong>" + escapeHtml$1(batchText("batch.banner.restart-title", l, { n: String(restart.length) })) + "</strong></div><div class=\"dsh-upd-browline\"><span class=\"dsh-upd-blist\">" + restart.map((row) => escapeHtml$1(titleOf(row, titles))).join("、") + "</span><button type=\"button\" data-act=\"restart\">" + escapeHtml$1(batchText("batch.banner.restart-button", l)) + "</button></div></div>");
5254
+ if (restartAct) parts.push("<div class=\"dsh-upd-banner-sub\">" + escapeHtml$1(restartAct) + "</div>");
5255
+ }
4464
5256
  return parts.join("");
4465
5257
  }
4466
5258
  function rowSetHTML(row, ctx) {
@@ -4469,7 +5261,7 @@ ${body}`;
4469
5261
  const skipped = ctx.skipped;
4470
5262
  const queued = isQueuedRow(row);
4471
5263
  const position = queued ? queuePositionOf(row) : null;
4472
- const versionHTML = batchRowVersionHTML(row, ctx.knowledge);
5264
+ const versionHTML = batchRowVersionHTML(row, ctx.knowledge, ctx.lang);
4473
5265
  const rowStatusText = queued ? batchQueuedStatus(position, ctx.lang) : ctx.worldLatest !== null ? batchText("batch.row.update", ctx.lang, { version: ctx.worldLatest }) : ctx.inRound ? batchRowKnowledgeText(row, ctx.knowledge, ctx.lang) ?? batchRowStatus(row, skipped, ctx.lang) : batchRowPendingStatus(row, ctx.knowledge, ctx.lang) ?? batchRowStatus(row, skipped, ctx.lang);
4474
5266
  const actions = [];
4475
5267
  const off = ctx.inFlight ? " disabled" : "";
@@ -4483,7 +5275,7 @@ ${body}`;
4483
5275
  actions.push("<button type=\"button\" data-act=\"toggle-details\" data-key=\"" + keyAttr + "\">" + escapeHtml$1(ctx.expanded ? batchText("batch.row-action.hide-detail", ctx.lang) : batchText("batch.row-action.show-detail", ctx.lang)) + "</button>");
4484
5276
  const failLine = phase === "failed" && !queued ? (() => {
4485
5277
  const failCode = row.error || "install-failed";
4486
- const failDetail = failureCopy(failCode, ctx.lang)?.zh ?? failureCopy("unknown", ctx.lang)?.zh ?? "";
5278
+ const failDetail = isCheckSideFailureCode(jobFailureOf(row)?.code ?? (typeof row.error === "string" && row.error ? row.error : null)) ? batchText("batch.row.failed", ctx.lang) : failureCopy(failCode, ctx.lang)?.zh ?? failureCopy("unknown", ctx.lang)?.zh ?? "";
4487
5279
  const escaped = escapeHtml$1(batchText("batch.row.error-label", ctx.lang, {
4488
5280
  code: failCode,
4489
5281
  detail: failDetail
@@ -4492,28 +5284,7 @@ ${body}`;
4492
5284
  return "<span class=\"dsh-upd-bfail\">" + (escaped.includes(codeEsc) ? escaped.replace(codeEsc, "<code>" + codeEsc + "</code>") : escaped) + "</span>";
4493
5285
  })() : "";
4494
5286
  const main = "<button type=\"button\" class=\"dsh-upd-brow-main\" data-act=\"toggle-details\" data-key=\"" + keyAttr + "\" aria-expanded=\"" + (ctx.expanded ? "true" : "false") + "\"><span class=\"dsh-upd-updot\" data-tone=\"" + dotToneOf(row, phase, skipped, queued, ctx.worldLatest) + "\"></span><span class=\"dsh-upd-bname\">" + escapeHtml$1(titleOf(row, ctx.titles)) + "</span>" + versionHTML + "<span class=\"dsh-upd-bstat\">" + escapeHtml$1(rowStatusText) + (ctx.inRound && !queued ? "(" + escapeHtml$1(batchText("batch.row.unfinished-tag", ctx.lang)) + ")" : "") + "</span>" + failLine + "</button>";
4495
- const detail = ctx.expanded ? "<div class=\"dsh-upd-bdetail\" data-key=\"" + keyAttr + "\">" + detailActionsHTML(row, ctx) + (ctx.notice !== null ? "<div class=\"dsh-upd-bdetail-notice\" role=\"status\">" + escapeHtml$1(ctx.notice) + "</div>" : "") + detailHTML(row, ctx) + "</div>" : "";
4496
- return "<div class=\"dsh-upd-brow-set\" data-key=\"" + keyAttr + "\"><div class=\"dsh-upd-brow\" data-phase=\"" + escapeHtml$1(phase) + "\" data-key=\"" + keyAttr + "\"" + (queued ? " data-queued=\"1\"" : "") + ">" + main + "<span class=\"dsh-upd-brow-actions\">" + actions.join("") + "</span></div>" + detail + "</div>";
4497
- }
4498
- function detailHTML(row, ctx) {
4499
- return stripActionButtons(renderUpdatePanelHTML({
4500
- snapshot: asSnapshotLike(row.snapshot),
4501
- manual: typeof row.manual === "string" ? row.manual : null,
4502
- changelogMarkdown: typeof ctx.changelogMarkdown === "string" ? ctx.changelogMarkdown : null,
4503
- queue: asQueueLike(row.queue),
4504
- skippedLatest: ctx.skipped !== null,
4505
- lastError: row.error,
4506
- errorKind: row.error,
4507
- mode: "embedded",
4508
- showOthers: false,
4509
- pluginId: pluginIdOf(row),
4510
- copyNotice: null,
4511
- theme: ctx.theme,
4512
- themeTokens: ctx.themeTokens,
4513
- profileName: typeof row.profileName === "string" && row.profileName ? row.profileName : null,
4514
- hostKind: typeof row.hostKind === "string" && row.hostKind ? row.hostKind : null,
4515
- actions: "none"
4516
- }, ctx.lang));
5287
+ return "<div class=\"dsh-upd-brow-set\" data-key=\"" + keyAttr + "\"><div class=\"dsh-upd-brow\" data-phase=\"" + escapeHtml$1(phase) + "\" data-key=\"" + keyAttr + "\"" + (queued ? " data-queued=\"1\"" : "") + ">" + main + "<span class=\"dsh-upd-brow-actions\">" + actions.join("") + "</span></div></div>";
4517
5288
  }
4518
5289
  function detailActionsHTML(row, ctx) {
4519
5290
  const phase = asBatchPhase(row.phase);
@@ -4537,6 +5308,37 @@ ${body}`;
4537
5308
  function stripActionButtons(html) {
4538
5309
  return html.replace(/<button\b[^>]*data-action=[^>]*>[\s\S]*?<\/button>/g, "");
4539
5310
  }
5311
+ function detailFooterHTML(row, ctx) {
5312
+ const keyAttr = escapeHtml$1(row.key);
5313
+ return "<div class=\"dsh-upd-footer\"><span class=\"dsh-upd-foot-note\">" + escapeHtml$1(batchText("panel.footer.note", ctx.lang)) + "</span><button type=\"button\" data-act=\"detail-close\" data-key=\"" + keyAttr + "\" title=\"" + escapeHtml$1(batchText("panel.footer.close-title", ctx.lang)) + "\">" + escapeHtml$1(batchText("panel.footer.close", ctx.lang)) + "</button></div>";
5314
+ }
5315
+ function detailDialogHTML(row, ctx) {
5316
+ const keyAttr = escapeHtml$1(row.key);
5317
+ const withoutStyle = stripActionButtons(renderUpdatePanelHTML({
5318
+ snapshot: asSnapshotLike(row.snapshot),
5319
+ manual: typeof row.manual === "string" ? row.manual : null,
5320
+ changelogMarkdown: typeof ctx.changelogMarkdown === "string" ? ctx.changelogMarkdown : null,
5321
+ queue: asQueueLike(row.queue),
5322
+ skippedLatest: ctx.skipped !== null,
5323
+ lastError: row.error,
5324
+ errorKind: row.error,
5325
+ mode: "dialog",
5326
+ showOthers: false,
5327
+ pluginId: pluginIdOf(row),
5328
+ copyNotice: null,
5329
+ theme: ctx.theme,
5330
+ themeTokens: ctx.themeTokens,
5331
+ profileName: typeof row.profileName === "string" && row.profileName ? row.profileName : null,
5332
+ hostKind: typeof row.hostKind === "string" && row.hostKind ? row.hostKind : null,
5333
+ actions: "none"
5334
+ }, ctx.lang)).replace(/^<style>[\s\S]*?<\/style>\s*/, "");
5335
+ const bar = "<div class=\"dsh-upd-bdetail-dialog-bar\" data-detail-bar=\"" + keyAttr + "\">" + detailActionsHTML(row, ctx) + "</div>" + (ctx.notice !== null ? "<div class=\"dsh-upd-bdetail-notice\" role=\"status\">" + escapeHtml$1(ctx.notice) + "</div>" : "");
5336
+ const withBar = withoutStyle.replace("<div class=\"dsh-upd-overlay\"", "<div class=\"dsh-upd-overlay dsh-upd-bdetail-dialog\" data-detail-key=\"" + keyAttr + "\"").replace("<div class=\"dsh-upd-body\">", bar + "<div class=\"dsh-upd-body\">");
5337
+ const footer = detailFooterHTML(row, ctx);
5338
+ const at = withBar.lastIndexOf("</div></div>");
5339
+ if (at < 0) return withBar + footer;
5340
+ return withBar.slice(0, at) + footer + withBar.slice(at);
5341
+ }
4540
5342
  function dotToneOf(row, phase, skipped, queued, worldLatest = null) {
4541
5343
  if (phase === "failed" && !queued) return "bad";
4542
5344
  if (phase === "installing" || phase === "checking") return "busy";
@@ -4550,10 +5352,10 @@ ${body}`;
4550
5352
  const UPDATE_BATCH_PANEL_CSS = [
4551
5353
  "/* 批量面板(#25):类名沿用 dsh-upd-* 前缀;默认(最小)主题,Archive 皮肤见 UPDATE_BATCH_PANEL_ARCHIVE_CSS。 */",
4552
5354
  ".dsh-upd-batch-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;flex-wrap:wrap}",
4553
- ".dsh-upd-batch-title{font-weight:700;font-size:15px;letter-spacing:.06em}",
5355
+ ".dsh-upd-batch-title{font-weight:700;font-size:var(--dsh-update-panel-chapter-font-size,15px);letter-spacing:.06em}",
4554
5356
  ".dsh-upd-batch-title i{font-style:normal;color:var(--dsh-update-primary,#2563eb)}",
4555
5357
  ".dsh-upd-batch-macros{flex:none}",
4556
- ".dsh-upd-batch-sum{margin:4px 0 8px;font-size:13.5px}",
5358
+ ".dsh-upd-batch-sum{margin:4px 0 8px;font-size:var(--dsh-update-panel-log-font-size,13.5px)}",
4557
5359
  ".dsh-upd-btable{margin-top:2px}",
4558
5360
  ".dsh-upd-brow-set{border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
4559
5361
  ".dsh-upd-brow-set:first-child{border-top:0}",
@@ -4570,34 +5372,35 @@ ${body}`;
4570
5372
  ".dsh-upd-updot[data-tone=\"warn\"]{background:var(--dsh-update-warn-border,#d97706);opacity:1}",
4571
5373
  ".dsh-upd-updot[data-tone=\"bad\"]{background:var(--dsh-update-bad-border,#dc2626);opacity:1}",
4572
5374
  ".dsh-upd-bname{font-weight:700;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}",
4573
- ".dsh-upd-bver{font-family:Consolas,Menlo,monospace;font-size:12px;white-space:nowrap;font-variant-numeric:tabular-nums;min-width:0}",
5375
+ ".dsh-upd-bver{font-family:Consolas,Menlo,monospace;font-size:var(--dsh-update-panel-small-font-size,12px);white-space:nowrap;font-variant-numeric:tabular-nums;min-width:0}",
4574
5376
  ".dsh-upd-bver-cur{opacity:.65}",
4575
5377
  ".dsh-upd-bver-arrow{opacity:.6}",
4576
5378
  ".dsh-upd-bver-new{color:var(--dsh-update-new-text,#dc2626);font-weight:700}",
4577
5379
  ".dsh-upd-bver-new-ok{color:var(--dsh-update-new-ok-text,#047857);font-weight:700}",
4578
- ".dsh-upd-bstat{font-size:12.5px;opacity:.9;min-width:0;overflow-wrap:anywhere}",
4579
- ".dsh-upd-bfail{grid-column:1/-1;display:block;font-size:12.5px;color:var(--dsh-update-bad-border,#dc2626)}",
5380
+ ".dsh-upd-bstat{font-size:var(--dsh-update-panel-small-font-size,12.5px);opacity:.9;min-width:0;overflow-wrap:anywhere}",
5381
+ ".dsh-upd-bfail{grid-column:1/-1;display:block;font-size:var(--dsh-update-panel-small-font-size,12.5px);color:var(--dsh-update-bad-border,#dc2626)}",
4580
5382
  ".dsh-upd-batch{--dsh-update-new-text:#dc2626}",
4581
5383
  ".dsh-upd-batch{--dsh-update-new-ok-text:#047857}",
4582
5384
  "@media (prefers-color-scheme: dark){.dsh-upd-batch{--dsh-update-new-text:#f87171}}",
4583
5385
  "@media (prefers-color-scheme: dark){.dsh-upd-batch{--dsh-update-new-ok-text:#34d399}}",
4584
5386
  "@media (forced-colors: active){.dsh-upd-bver-new{color:CanvasText}}",
4585
5387
  "@media (forced-colors: active){.dsh-upd-bver-new-ok{color:CanvasText}}",
4586
- ".dsh-upd-blist{font-size:12.5px;margin-top:2px}",
4587
- ".dsh-upd-batch-ledger{margin:8px 0 0;font-size:13px;opacity:.85}",
5388
+ ".dsh-upd-blist{font-size:var(--dsh-update-panel-small-font-size,12.5px);margin-top:2px}",
5389
+ ".dsh-upd-browline{display:flex;align-items:center;gap:10px;flex-wrap:wrap}",
5390
+ ".dsh-upd-browline>.dsh-upd-blist{flex:1 1 auto;min-width:0;text-align:left;margin:0}",
5391
+ ".dsh-upd-browline>button{flex:none;margin:0;margin-left:auto}",
5392
+ ".dsh-upd-batch-ledger{margin:8px 0 0;font-size:var(--dsh-update-panel-log-font-size,13px);opacity:.85}",
4588
5393
  ".dsh-upd-batch-more{margin-top:6px}",
4589
5394
  ".dsh-upd-batch-more button{font-size:12px}",
4590
5395
  ".dsh-upd-batch-more button[data-confirm=\"1\"]{border-color:var(--dsh-update-bad-border,#dc2626);color:var(--dsh-update-bad-border,#dc2626)}",
4591
- ".dsh-upd-batch-notice{margin-top:6px;font-size:12.5px;opacity:.85}",
5396
+ ".dsh-upd-batch-notice{margin-top:6px;font-size:var(--dsh-update-panel-small-font-size,12.5px);opacity:.85}",
4592
5397
  ".dsh-upd-bdetail-actions{margin:0 0 6px}",
4593
5398
  ".dsh-upd .dsh-upd-bdetail-actions button{font-size:12.5px}",
4594
- ".dsh-upd-bdetail-notice{margin:0 0 6px;font-size:12.5px;opacity:.85}",
4595
- "/* 详情复用单插件内核:不许嵌套滚动——中性化 overlay 的 max-height/overflow,自身也不给 overflow。 */",
4596
- ".dsh-upd-bdetail{margin:2px 0 10px;overflow:visible}",
4597
- ".dsh-upd .dsh-upd-bdetail .dsh-upd{max-width:none}",
4598
- ".dsh-upd-overlay .dsh-upd-bdetail .dsh-upd{max-height:none;overflow:visible}",
4599
- ".dsh-upd-overlay .dsh-upd-bdetail .dsh-upd-body{overflow:visible}",
4600
- ".dsh-upd-overlay .dsh-upd-bdetail .dsh-upd-body .dsh-upd-chap-head{position:static}",
5399
+ ".dsh-upd-bdetail-notice{margin:0 0 6px;font-size:var(--dsh-update-panel-small-font-size,12.5px);opacity:.85}",
5400
+ "/* Detail dialog (#108): reuse kernel dialog scroll (body scroll + sticky heads); batch actions as fixed bar; legacy inline overflow:visible retired with inline removal. */",
5401
+ ".dsh-upd-overlay.dsh-upd-bdetail-dialog{z-index:10000}",
5402
+ ".dsh-upd-bdetail-dialog-bar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:8px 0;margin-bottom:8px;border-bottom:1px dashed var(--dsh-update-border,#e5e7eb)}",
5403
+ ".dsh-upd-bdetail-dialog-bar .dsh-upd-bdetail-actions{margin:0}",
4601
5404
  "@media (prefers-color-scheme: dark){.dsh-upd-batch-title i{color:var(--dsh-update-focus,#93c5fd)}}",
4602
5405
  "@media (prefers-reduced-motion: reduce){.dsh-upd-batch *{transition:none !important;animation:none !important}}",
4603
5406
  ".dsh-upd-batch{overflow-anchor:none}",
@@ -4610,7 +5413,7 @@ ${body}`;
4610
5413
  const UPDATE_BATCH_PANEL_ARCHIVE_CSS = [
4611
5414
  "/* 批量面板的 Archive 皮肤:只换颜色/字体/间距;根上的大印章由 UPDATE_PANEL_ARCHIVE_CSS 负责。 */",
4612
5415
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-head{padding-right:120px}",
4613
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-title{font-family:var(--dsh-update-font-serif);font-size:21px;letter-spacing:.04em}",
5416
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-title{font-family:var(--dsh-update-font-serif);font-size:var(--dsh-update-panel-chapter-font-size,21px);letter-spacing:.04em}",
4614
5417
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-title i{color:var(--dsh-update-primary)}",
4615
5418
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-brow-main{background:transparent;border:0;color:var(--dsh-update-text)}",
4616
5419
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-brow-main:hover{color:var(--dsh-update-primary)}",
@@ -4625,7 +5428,18 @@ ${body}`;
4625
5428
  "@media (prefers-color-scheme: dark){.dsh-upd[data-theme=\"archive\"] .dsh-upd-batch{--dsh-update-new-text:#ef8a7d}}",
4626
5429
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-ledger{color:var(--dsh-update-text-muted)}",
4627
5430
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-sum{color:var(--dsh-update-text)}",
4628
- ".dsh-upd[data-theme=\"archive\"] .dsh-upd-brow-set{border-top-color:var(--dsh-update-border)}"
5431
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-brow-set{border-top-color:var(--dsh-update-border)}",
5432
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-macros{gap:8px}",
5433
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-macros button{font-size:13px;line-height:1.45;padding:6px 12px;margin:0;min-width:0}",
5434
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-macros button:first-child,.dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-macros button[data-primary=\"1\"]{min-width:0}",
5435
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-macros button:not([data-primary=\"1\"]){background:transparent}",
5436
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-brow-actions button{font-size:12px;line-height:1.45;padding:4px 10px;margin:0;min-width:0;background:transparent}",
5437
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-bdetail-actions button{font-size:12px;line-height:1.45;padding:4px 10px;margin:0;min-width:0;background:transparent}",
5438
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-more button{font-size:12px;line-height:1.45;padding:4px 10px;margin:0;min-width:0;background:transparent}",
5439
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-prefs button{font-size:13px;line-height:1.45;padding:6px 12px;margin:0;min-width:0;background:transparent}",
5440
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner>.dsh-upd-browline{align-self:stretch;display:flex;align-items:center;gap:10px;flex-wrap:wrap}",
5441
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner>.dsh-upd-browline .dsh-upd-blist{flex:1 1 auto;min-width:220px;text-align:left;margin:0;color:var(--dsh-update-text-muted)}",
5442
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-banner>.dsh-upd-browline button{flex:none;margin:0;margin-left:auto;font-size:13px;line-height:1.45;padding:6px 12px;min-width:0;background:transparent}"
4629
5443
  ].join(String.fromCharCode(10));
4630
5444
  function escapeHtml$1(text) {
4631
5445
  return String(text).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
@@ -4718,6 +5532,7 @@ ${body}`;
4718
5532
  function currentVersionOf(row) {
4719
5533
  const snapshot = row.snapshot;
4720
5534
  if (!isObject$1(snapshot)) return null;
5535
+ if (snapshot["installed"] === false) return null;
4721
5536
  const running = snapshot["runningVersion"];
4722
5537
  if (typeof running === "string" && running) return running;
4723
5538
  const installed = snapshot["installedVersion"];
@@ -5367,6 +6182,11 @@ ${body}`;
5367
6182
  render();
5368
6183
  maybeAutoRowChangelog(expandedKey);
5369
6184
  return;
6185
+ case "detail-close":
6186
+ if (expandedKey === null) return;
6187
+ expandedKey = null;
6188
+ render();
6189
+ return;
5370
6190
  case "restart":
5371
6191
  try {
5372
6192
  if (typeof onRestartRequested === "function") {
@@ -5394,7 +6214,13 @@ ${body}`;
5394
6214
  function onKeyDown(ev) {
5395
6215
  try {
5396
6216
  const e = ev;
5397
- if (!mounted || mode !== "dialog" || !e || e.key !== "Escape") return;
6217
+ if (!mounted || !e || e.key !== "Escape") return;
6218
+ if (expandedKey !== null) {
6219
+ expandedKey = null;
6220
+ render();
6221
+ return;
6222
+ }
6223
+ if (mode !== "dialog") return;
5398
6224
  requestDialogClose();
5399
6225
  } catch {}
5400
6226
  }
@@ -5529,7 +6355,7 @@ ${body}`;
5529
6355
  };
5530
6356
  }
5531
6357
  //#endregion
5532
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.12.0/node_modules/dsh-plugin-update/dist/entry-batch.js
6358
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.17.0/node_modules/dsh-plugin-update/dist/entry-batch.js
5533
6359
  function isObject(value) {
5534
6360
  return !!value && typeof value === "object" && !Array.isArray(value);
5535
6361
  }
@@ -8428,7 +9254,7 @@ ${body}`;
8428
9254
  }, react.createElement("span", { style: S.morePkg }, row.pkg), react.createElement("span", { style: S.moreDesc }, row.desc), react.createElement("span", { style: S.moreIcon }, react.createElement(ExternalIcon, null)))));
8429
9255
  }
8430
9256
  /** 版本胶囊那一行字:只在这里拼一次,屏上与用例读的是同一串。 */
8431
- const MANAGER_VERSION_TEXT = "dsh-life-pack · 0.3.53";
9257
+ const MANAGER_VERSION_TEXT = "dsh-life-pack · 0.3.55";
8432
9258
  /** 右下角那本书离面板两沿的距离:用户口径「一直处于面板右下角、不随列表滑动消失」
8433
9259
  * ⇒ sticky 吸附(面板相对,视口多大都落在面板角上);INSET=右沿,BOTTOM=底沿。 */
8434
9260
  const MANUAL_ENTRY_INSET = 16;