From da5fd8d4f4caa16ec194f388dcd5c5b1df173025 Mon Sep 17 00:00:00 2001 From: ShiinaKuroko <208154746+ShiinaKuroko@users.noreply.github.com> Date: Mon, 3 Aug 2026 05:18:47 +0800 Subject: [PATCH 01/21] =?UTF-8?q?feat(gui):=20=E5=AE=8C=E6=88=90=20GUI=202?= =?UTF-8?q?.0=20=E5=8F=AF=E8=A7=86=E5=8C=96=E8=AE=A1=E5=88=92=E4=B8=8E?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构作战、计划与设置页面,完善舰队规划、出征规划、计划管理和运行状态展示。 新增本地舰船资料库及增量更新工具,统一 YAML 生命周期、环境管理、主题、窗口持久化和保存反馈,并补充迁移与设置隔离测试。 --- .gitignore | 7 +- .tmp_issue360.json | 2 - .tmp_issue360_comments.json | 2 - .tmp_issue372.json | 2 - .tmp_issue372_comments.json | 2 - .tmp_runs.json | 2 - .tmp_weekly_fix.ps1 | 93 - README.md | 322 +- docs/architecture/00-overview.md | 6 +- docs/architecture/04-battle-plan.md | 14 +- docs/architecture/08-dev-setup.md | 3 +- docs/features/gui-2.0.md | 1203 ++ docs/plan-guide.md | 2 +- .../2026-08-03-workspace-review-pending.md | 152 + electron/backend.ts | 28 +- electron/main.ts | 2384 ++- electron/preload.ts | 171 + electron/pythonEnv/context.ts | 2 + electron/pythonEnv/envCheck.ts | 109 +- electron/pythonEnv/finder.ts | 4 +- electron/pythonEnv/index.ts | 11 +- electron/pythonEnv/installer.ts | 13 +- package-lock.json | 4 +- package.json | 35 +- .../\345\206\263\346\210\230.yaml" | 19 - ...1\250\345\270\27010\347\253\240-10-1.yaml" | 46 - ...221\250\345\270\2701\347\253\240-1-5.yaml" | 24 - ...221\250\345\270\2702\347\253\240-2-1.yaml" | 44 - ...221\250\345\270\2703\347\253\240-3-1.yaml" | 37 - ...221\250\345\270\2703\347\253\240-3-3.yaml" | 34 - ...221\250\345\270\2704\347\253\240-4-1.yaml" | 35 - ...221\250\345\270\2705\347\253\240-5-5.yaml" | 32 - ...221\250\345\270\2706\347\253\240-6-3.yaml" | 31 - ...221\250\345\270\2706\347\253\240-6-4.yaml" | 41 - ...221\250\345\270\2707\347\253\240-7-4.yaml" | 32 - ...221\250\345\270\2708\347\253\240-8-2.yaml" | 39 - ...221\250\345\270\2709\347\253\240-9-2.yaml" | 103 - .../\346\210\230\345\275\271.yaml" | 6 - ...6\215\236\350\203\226\346\254\2412-1.yaml" | 15 - ...6\215\236\350\203\226\346\254\2417-4.yaml" | 28 - ...6\215\236\350\203\226\346\254\2418-5.yaml" | 22 - ...6\215\236\350\203\226\346\254\2419-2.yaml" | 129 - ...020260730-E1\347\202\270\351\261\274.yaml" | 8 - ...020260730-E5\345\244\234\346\210\230.yaml" | 16 - ...020260730-H1\347\202\270\351\261\274.yaml" | 8 - ...020260730-H5\345\244\234\346\210\230.yaml" | 16 - ...\345\212\250\346\274\224\344\271\240.yaml" | 5 - resource/builtin_templates.json | 48 +- .../assets/backgrounds/rarity-1.webp | Bin 0 -> 13186 bytes .../assets/backgrounds/rarity-2.webp | Bin 0 -> 28136 bytes .../assets/backgrounds/rarity-3.webp | Bin 0 -> 28126 bytes .../assets/backgrounds/rarity-4.webp | Bin 0 -> 28236 bytes .../assets/backgrounds/rarity-5.webp | Bin 0 -> 31944 bytes .../assets/backgrounds/rarity-6.webp | Bin 0 -> 31358 bytes .../ship-library/assets/frames/rarity-1.webp | Bin 0 -> 5852 bytes .../ship-library/assets/frames/rarity-2.webp | Bin 0 -> 13590 bytes .../ship-library/assets/frames/rarity-3.webp | Bin 0 -> 14034 bytes .../ship-library/assets/frames/rarity-4.webp | Bin 0 -> 13652 bytes .../ship-library/assets/frames/rarity-5.webp | Bin 0 -> 15068 bytes .../ship-library/assets/frames/rarity-6.webp | Bin 0 -> 13474 bytes resource/ship-library/assets/portraits/1.webp | Bin 0 -> 30208 bytes .../ship-library/assets/portraits/10.webp | Bin 0 -> 20616 bytes .../ship-library/assets/portraits/100.webp | Bin 0 -> 25528 bytes .../ship-library/assets/portraits/1001.webp | Bin 0 -> 41054 bytes .../ship-library/assets/portraits/1002.webp | Bin 0 -> 30008 bytes .../ship-library/assets/portraits/1003.webp | Bin 0 -> 33626 bytes .../ship-library/assets/portraits/1004.webp | Bin 0 -> 27768 bytes .../ship-library/assets/portraits/1005.webp | Bin 0 -> 24502 bytes .../ship-library/assets/portraits/1006.webp | Bin 0 -> 38586 bytes .../ship-library/assets/portraits/1007.webp | Bin 0 -> 32936 bytes .../ship-library/assets/portraits/1008.webp | Bin 0 -> 33780 bytes .../ship-library/assets/portraits/1009.webp | Bin 0 -> 32110 bytes .../ship-library/assets/portraits/101.webp | Bin 0 -> 24162 bytes .../ship-library/assets/portraits/1010.webp | Bin 0 -> 24710 bytes .../ship-library/assets/portraits/1011.webp | Bin 0 -> 35786 bytes .../ship-library/assets/portraits/1012.webp | Bin 0 -> 34668 bytes .../ship-library/assets/portraits/1013.webp | Bin 0 -> 34082 bytes .../ship-library/assets/portraits/1014.webp | Bin 0 -> 24818 bytes .../ship-library/assets/portraits/1018.webp | Bin 0 -> 26016 bytes .../ship-library/assets/portraits/1019.webp | Bin 0 -> 20094 bytes .../ship-library/assets/portraits/102.webp | Bin 0 -> 25156 bytes .../ship-library/assets/portraits/1020.webp | Bin 0 -> 33184 bytes .../ship-library/assets/portraits/1021.webp | Bin 0 -> 35264 bytes .../ship-library/assets/portraits/1022.webp | Bin 0 -> 31228 bytes .../ship-library/assets/portraits/1023.webp | Bin 0 -> 30350 bytes .../ship-library/assets/portraits/1024.webp | Bin 0 -> 22992 bytes .../ship-library/assets/portraits/1025.webp | Bin 0 -> 25160 bytes .../ship-library/assets/portraits/1026.webp | Bin 0 -> 21028 bytes .../ship-library/assets/portraits/1027.webp | Bin 0 -> 31060 bytes .../ship-library/assets/portraits/1028.webp | Bin 0 -> 35960 bytes .../ship-library/assets/portraits/1029.webp | Bin 0 -> 20202 bytes .../ship-library/assets/portraits/103.webp | Bin 0 -> 30872 bytes .../ship-library/assets/portraits/1030.webp | Bin 0 -> 22694 bytes .../ship-library/assets/portraits/1031.webp | Bin 0 -> 30554 bytes .../ship-library/assets/portraits/1032.webp | Bin 0 -> 31634 bytes .../ship-library/assets/portraits/1033.webp | Bin 0 -> 29076 bytes .../ship-library/assets/portraits/1034.webp | Bin 0 -> 25408 bytes .../ship-library/assets/portraits/1035.webp | Bin 0 -> 24294 bytes .../ship-library/assets/portraits/1036.webp | Bin 0 -> 35808 bytes .../ship-library/assets/portraits/1037.webp | Bin 0 -> 33058 bytes .../ship-library/assets/portraits/1038.webp | Bin 0 -> 33310 bytes .../ship-library/assets/portraits/1039.webp | Bin 0 -> 25936 bytes .../ship-library/assets/portraits/104.webp | Bin 0 -> 24882 bytes .../ship-library/assets/portraits/1040.webp | Bin 0 -> 30464 bytes .../ship-library/assets/portraits/1041.webp | Bin 0 -> 27362 bytes .../ship-library/assets/portraits/1042.webp | Bin 0 -> 24184 bytes .../ship-library/assets/portraits/1043.webp | Bin 0 -> 31512 bytes .../ship-library/assets/portraits/1044.webp | Bin 0 -> 29472 bytes .../ship-library/assets/portraits/1045.webp | Bin 0 -> 21952 bytes .../ship-library/assets/portraits/1046.webp | Bin 0 -> 30054 bytes .../ship-library/assets/portraits/1047.webp | Bin 0 -> 26358 bytes .../ship-library/assets/portraits/1048.webp | Bin 0 -> 29064 bytes .../ship-library/assets/portraits/1049.webp | Bin 0 -> 31160 bytes .../ship-library/assets/portraits/105.webp | Bin 0 -> 32284 bytes .../ship-library/assets/portraits/1050.webp | Bin 0 -> 41794 bytes .../ship-library/assets/portraits/1054.webp | Bin 0 -> 46128 bytes .../ship-library/assets/portraits/1055.webp | Bin 0 -> 37704 bytes .../ship-library/assets/portraits/1056.webp | Bin 0 -> 38272 bytes .../ship-library/assets/portraits/1057.webp | Bin 0 -> 37668 bytes .../ship-library/assets/portraits/1058.webp | Bin 0 -> 32488 bytes .../ship-library/assets/portraits/1059.webp | Bin 0 -> 30884 bytes .../ship-library/assets/portraits/106.webp | Bin 0 -> 19910 bytes .../ship-library/assets/portraits/1060.webp | Bin 0 -> 33188 bytes .../ship-library/assets/portraits/1061.webp | Bin 0 -> 28348 bytes .../ship-library/assets/portraits/1062.webp | Bin 0 -> 28910 bytes .../ship-library/assets/portraits/1063.webp | Bin 0 -> 24522 bytes .../ship-library/assets/portraits/1064.webp | Bin 0 -> 26914 bytes .../ship-library/assets/portraits/1065.webp | Bin 0 -> 24672 bytes .../ship-library/assets/portraits/1066.webp | Bin 0 -> 21208 bytes .../ship-library/assets/portraits/1067.webp | Bin 0 -> 30274 bytes .../ship-library/assets/portraits/1068.webp | Bin 0 -> 24162 bytes .../ship-library/assets/portraits/1069.webp | Bin 0 -> 23582 bytes .../ship-library/assets/portraits/107.webp | Bin 0 -> 33430 bytes .../ship-library/assets/portraits/1070.webp | Bin 0 -> 26922 bytes .../ship-library/assets/portraits/1071.webp | Bin 0 -> 24228 bytes .../ship-library/assets/portraits/1072.webp | Bin 0 -> 23690 bytes .../ship-library/assets/portraits/1073.webp | Bin 0 -> 25878 bytes .../ship-library/assets/portraits/1074.webp | Bin 0 -> 34940 bytes .../ship-library/assets/portraits/1075.webp | Bin 0 -> 31070 bytes .../ship-library/assets/portraits/1076.webp | Bin 0 -> 28952 bytes .../ship-library/assets/portraits/1077.webp | Bin 0 -> 28578 bytes .../ship-library/assets/portraits/1079.webp | Bin 0 -> 24264 bytes .../ship-library/assets/portraits/108.webp | Bin 0 -> 28360 bytes .../ship-library/assets/portraits/1080.webp | Bin 0 -> 36064 bytes .../ship-library/assets/portraits/1081.webp | Bin 0 -> 27946 bytes .../ship-library/assets/portraits/1082.webp | Bin 0 -> 33558 bytes .../ship-library/assets/portraits/1083.webp | Bin 0 -> 32404 bytes .../ship-library/assets/portraits/1084.webp | Bin 0 -> 43242 bytes .../ship-library/assets/portraits/1085.webp | Bin 0 -> 35508 bytes .../ship-library/assets/portraits/1086.webp | Bin 0 -> 26842 bytes .../ship-library/assets/portraits/1087.webp | Bin 0 -> 24008 bytes .../ship-library/assets/portraits/1088.webp | Bin 0 -> 27006 bytes .../ship-library/assets/portraits/1089.webp | Bin 0 -> 26968 bytes .../ship-library/assets/portraits/109.webp | Bin 0 -> 28162 bytes .../ship-library/assets/portraits/1092.webp | Bin 0 -> 27104 bytes .../ship-library/assets/portraits/1093.webp | Bin 0 -> 33218 bytes .../ship-library/assets/portraits/1094.webp | Bin 0 -> 25014 bytes .../ship-library/assets/portraits/1097.webp | Bin 0 -> 28874 bytes .../ship-library/assets/portraits/1098.webp | Bin 0 -> 29776 bytes .../ship-library/assets/portraits/1099.webp | Bin 0 -> 29774 bytes .../ship-library/assets/portraits/11.webp | Bin 0 -> 34272 bytes .../ship-library/assets/portraits/110.webp | Bin 0 -> 30530 bytes .../ship-library/assets/portraits/1100.webp | Bin 0 -> 28032 bytes .../ship-library/assets/portraits/1101.webp | Bin 0 -> 28072 bytes .../ship-library/assets/portraits/1102.webp | Bin 0 -> 28510 bytes .../ship-library/assets/portraits/1105.webp | Bin 0 -> 32838 bytes .../ship-library/assets/portraits/1106.webp | Bin 0 -> 31562 bytes .../ship-library/assets/portraits/1107.webp | Bin 0 -> 33222 bytes .../ship-library/assets/portraits/1108.webp | Bin 0 -> 32634 bytes .../ship-library/assets/portraits/1109.webp | Bin 0 -> 36838 bytes .../ship-library/assets/portraits/111.webp | Bin 0 -> 28396 bytes .../ship-library/assets/portraits/1110.webp | Bin 0 -> 32010 bytes .../ship-library/assets/portraits/1111.webp | Bin 0 -> 36414 bytes .../ship-library/assets/portraits/1112.webp | Bin 0 -> 24310 bytes .../ship-library/assets/portraits/1113.webp | Bin 0 -> 41544 bytes .../ship-library/assets/portraits/1117.webp | Bin 0 -> 36682 bytes .../ship-library/assets/portraits/1118.webp | Bin 0 -> 33566 bytes .../ship-library/assets/portraits/112.webp | Bin 0 -> 31514 bytes .../ship-library/assets/portraits/1120.webp | Bin 0 -> 28996 bytes .../ship-library/assets/portraits/1121.webp | Bin 0 -> 31928 bytes .../ship-library/assets/portraits/1123.webp | Bin 0 -> 31476 bytes .../ship-library/assets/portraits/1124.webp | Bin 0 -> 26692 bytes .../ship-library/assets/portraits/1125.webp | Bin 0 -> 29882 bytes .../ship-library/assets/portraits/1126.webp | Bin 0 -> 26150 bytes .../ship-library/assets/portraits/113.webp | Bin 0 -> 46724 bytes .../ship-library/assets/portraits/1130.webp | Bin 0 -> 25876 bytes .../ship-library/assets/portraits/1131.webp | Bin 0 -> 27638 bytes .../ship-library/assets/portraits/1132.webp | Bin 0 -> 28670 bytes .../ship-library/assets/portraits/1133.webp | Bin 0 -> 26164 bytes .../ship-library/assets/portraits/1135.webp | Bin 0 -> 22660 bytes .../ship-library/assets/portraits/1136.webp | Bin 0 -> 22984 bytes .../ship-library/assets/portraits/1137.webp | Bin 0 -> 24820 bytes .../ship-library/assets/portraits/1139.webp | Bin 0 -> 23210 bytes .../ship-library/assets/portraits/114.webp | Bin 0 -> 32260 bytes .../ship-library/assets/portraits/1141.webp | Bin 0 -> 27196 bytes .../ship-library/assets/portraits/1142.webp | Bin 0 -> 25324 bytes .../ship-library/assets/portraits/1143.webp | Bin 0 -> 27820 bytes .../ship-library/assets/portraits/1145.webp | Bin 0 -> 29846 bytes .../ship-library/assets/portraits/1149.webp | Bin 0 -> 26296 bytes .../ship-library/assets/portraits/115.webp | Bin 0 -> 27100 bytes .../ship-library/assets/portraits/1150.webp | Bin 0 -> 30424 bytes .../ship-library/assets/portraits/1151.webp | Bin 0 -> 31774 bytes .../ship-library/assets/portraits/1158.webp | Bin 0 -> 38448 bytes .../ship-library/assets/portraits/1160.webp | Bin 0 -> 29064 bytes .../ship-library/assets/portraits/1162.webp | Bin 0 -> 24008 bytes .../ship-library/assets/portraits/1164.webp | Bin 0 -> 23296 bytes .../ship-library/assets/portraits/1165.webp | Bin 0 -> 22782 bytes .../ship-library/assets/portraits/1166.webp | Bin 0 -> 29536 bytes .../ship-library/assets/portraits/1167.webp | Bin 0 -> 33454 bytes .../ship-library/assets/portraits/1168.webp | Bin 0 -> 28188 bytes .../ship-library/assets/portraits/1169.webp | Bin 0 -> 25326 bytes .../ship-library/assets/portraits/117.webp | Bin 0 -> 34894 bytes .../ship-library/assets/portraits/1171.webp | Bin 0 -> 27564 bytes .../ship-library/assets/portraits/1175.webp | Bin 0 -> 36304 bytes .../ship-library/assets/portraits/1178.webp | Bin 0 -> 26838 bytes .../ship-library/assets/portraits/118.webp | Bin 0 -> 28902 bytes .../ship-library/assets/portraits/1181.webp | Bin 0 -> 31558 bytes .../ship-library/assets/portraits/1182.webp | Bin 0 -> 27414 bytes .../ship-library/assets/portraits/1183.webp | Bin 0 -> 22308 bytes .../ship-library/assets/portraits/1185.webp | Bin 0 -> 25756 bytes .../ship-library/assets/portraits/1187.webp | Bin 0 -> 32188 bytes .../ship-library/assets/portraits/1188.webp | Bin 0 -> 30856 bytes .../ship-library/assets/portraits/119.webp | Bin 0 -> 32408 bytes .../ship-library/assets/portraits/1192.webp | Bin 0 -> 26960 bytes .../ship-library/assets/portraits/1194.webp | Bin 0 -> 31256 bytes .../ship-library/assets/portraits/1195.webp | Bin 0 -> 29754 bytes .../ship-library/assets/portraits/1197.webp | Bin 0 -> 24928 bytes .../ship-library/assets/portraits/1198.webp | Bin 0 -> 24208 bytes .../ship-library/assets/portraits/1199.webp | Bin 0 -> 20344 bytes .../ship-library/assets/portraits/12.webp | Bin 0 -> 34658 bytes .../ship-library/assets/portraits/120.webp | Bin 0 -> 30704 bytes .../ship-library/assets/portraits/1205.webp | Bin 0 -> 26634 bytes .../ship-library/assets/portraits/1206.webp | Bin 0 -> 37438 bytes .../ship-library/assets/portraits/1207.webp | Bin 0 -> 26830 bytes .../ship-library/assets/portraits/1209.webp | Bin 0 -> 25176 bytes .../ship-library/assets/portraits/121.webp | Bin 0 -> 28992 bytes .../ship-library/assets/portraits/1211.webp | Bin 0 -> 35202 bytes .../ship-library/assets/portraits/1215.webp | Bin 0 -> 35168 bytes .../ship-library/assets/portraits/1219.webp | Bin 0 -> 30604 bytes .../ship-library/assets/portraits/122.webp | Bin 0 -> 29476 bytes .../ship-library/assets/portraits/1220.webp | Bin 0 -> 26766 bytes .../ship-library/assets/portraits/1221.webp | Bin 0 -> 30842 bytes .../ship-library/assets/portraits/1222.webp | Bin 0 -> 23038 bytes .../ship-library/assets/portraits/1223.webp | Bin 0 -> 30394 bytes .../ship-library/assets/portraits/1224.webp | Bin 0 -> 24046 bytes .../ship-library/assets/portraits/1225.webp | Bin 0 -> 28780 bytes .../ship-library/assets/portraits/1227.webp | Bin 0 -> 28808 bytes .../ship-library/assets/portraits/1228.webp | Bin 0 -> 31496 bytes .../ship-library/assets/portraits/123.webp | Bin 0 -> 22582 bytes .../ship-library/assets/portraits/1232.webp | Bin 0 -> 23152 bytes .../ship-library/assets/portraits/1233.webp | Bin 0 -> 27814 bytes .../ship-library/assets/portraits/1238.webp | Bin 0 -> 26166 bytes .../ship-library/assets/portraits/1239.webp | Bin 0 -> 28168 bytes .../ship-library/assets/portraits/124.webp | Bin 0 -> 25342 bytes .../ship-library/assets/portraits/1240.webp | Bin 0 -> 32494 bytes .../ship-library/assets/portraits/1241.webp | Bin 0 -> 34318 bytes .../ship-library/assets/portraits/1244.webp | Bin 0 -> 33450 bytes .../ship-library/assets/portraits/1247.webp | Bin 0 -> 30696 bytes .../ship-library/assets/portraits/1248.webp | Bin 0 -> 31468 bytes .../ship-library/assets/portraits/1249.webp | Bin 0 -> 26698 bytes .../ship-library/assets/portraits/125.webp | Bin 0 -> 28490 bytes .../ship-library/assets/portraits/1258.webp | Bin 0 -> 16656 bytes .../ship-library/assets/portraits/126.webp | Bin 0 -> 26022 bytes .../ship-library/assets/portraits/1265.webp | Bin 0 -> 29170 bytes .../ship-library/assets/portraits/1266.webp | Bin 0 -> 38296 bytes .../ship-library/assets/portraits/1267.webp | Bin 0 -> 35082 bytes .../ship-library/assets/portraits/1269.webp | Bin 0 -> 27256 bytes .../ship-library/assets/portraits/127.webp | Bin 0 -> 61178 bytes .../ship-library/assets/portraits/1270.webp | Bin 0 -> 26360 bytes .../ship-library/assets/portraits/1273.webp | Bin 0 -> 36416 bytes .../ship-library/assets/portraits/1275.webp | Bin 0 -> 25824 bytes .../ship-library/assets/portraits/1277.webp | Bin 0 -> 25872 bytes .../ship-library/assets/portraits/1278.webp | Bin 0 -> 32886 bytes .../ship-library/assets/portraits/1279.webp | Bin 0 -> 24278 bytes .../ship-library/assets/portraits/128.webp | Bin 0 -> 25288 bytes .../ship-library/assets/portraits/1280.webp | Bin 0 -> 29844 bytes .../ship-library/assets/portraits/1289.webp | Bin 0 -> 31412 bytes .../ship-library/assets/portraits/129.webp | Bin 0 -> 26448 bytes .../ship-library/assets/portraits/1290.webp | Bin 0 -> 32944 bytes .../ship-library/assets/portraits/1291.webp | Bin 0 -> 23606 bytes .../ship-library/assets/portraits/1293.webp | Bin 0 -> 27040 bytes .../ship-library/assets/portraits/1299.webp | Bin 0 -> 25088 bytes .../ship-library/assets/portraits/13.webp | Bin 0 -> 30448 bytes .../ship-library/assets/portraits/130.webp | Bin 0 -> 26966 bytes .../ship-library/assets/portraits/1301.webp | Bin 0 -> 30034 bytes .../ship-library/assets/portraits/1306.webp | Bin 0 -> 28374 bytes .../ship-library/assets/portraits/131.webp | Bin 0 -> 23212 bytes .../ship-library/assets/portraits/1311.webp | Bin 0 -> 31874 bytes .../ship-library/assets/portraits/1316.webp | Bin 0 -> 24794 bytes .../ship-library/assets/portraits/132.webp | Bin 0 -> 23228 bytes .../ship-library/assets/portraits/1323.webp | Bin 0 -> 32294 bytes .../ship-library/assets/portraits/1325.webp | Bin 0 -> 28528 bytes .../ship-library/assets/portraits/133.webp | Bin 0 -> 22446 bytes .../ship-library/assets/portraits/1332.webp | Bin 0 -> 23124 bytes .../ship-library/assets/portraits/1335.webp | Bin 0 -> 37438 bytes .../ship-library/assets/portraits/1339.webp | Bin 0 -> 30710 bytes .../ship-library/assets/portraits/134.webp | Bin 0 -> 25160 bytes .../ship-library/assets/portraits/1340.webp | Bin 0 -> 37824 bytes .../ship-library/assets/portraits/1342.webp | Bin 0 -> 25718 bytes .../ship-library/assets/portraits/1343.webp | Bin 0 -> 28280 bytes .../ship-library/assets/portraits/1344.webp | Bin 0 -> 24804 bytes .../ship-library/assets/portraits/135.webp | Bin 0 -> 20276 bytes .../ship-library/assets/portraits/1351.webp | Bin 0 -> 25034 bytes .../ship-library/assets/portraits/136.webp | Bin 0 -> 22682 bytes .../ship-library/assets/portraits/1362.webp | Bin 0 -> 36610 bytes .../ship-library/assets/portraits/1363.webp | Bin 0 -> 30176 bytes .../ship-library/assets/portraits/1366.webp | Bin 0 -> 28036 bytes .../ship-library/assets/portraits/137.webp | Bin 0 -> 23528 bytes .../ship-library/assets/portraits/1372.webp | Bin 0 -> 24082 bytes .../ship-library/assets/portraits/138.webp | Bin 0 -> 24318 bytes .../ship-library/assets/portraits/1380.webp | Bin 0 -> 29144 bytes .../ship-library/assets/portraits/139.webp | Bin 0 -> 25534 bytes .../ship-library/assets/portraits/14.webp | Bin 0 -> 25160 bytes .../ship-library/assets/portraits/140.webp | Bin 0 -> 25788 bytes .../ship-library/assets/portraits/1400.webp | Bin 0 -> 34502 bytes .../ship-library/assets/portraits/1408.webp | Bin 0 -> 34336 bytes .../ship-library/assets/portraits/141.webp | Bin 0 -> 25676 bytes .../ship-library/assets/portraits/1413.webp | Bin 0 -> 29660 bytes .../ship-library/assets/portraits/1414.webp | Bin 0 -> 33298 bytes .../ship-library/assets/portraits/1416.webp | Bin 0 -> 22106 bytes .../ship-library/assets/portraits/142.webp | Bin 0 -> 24832 bytes .../ship-library/assets/portraits/1425.webp | Bin 0 -> 25146 bytes .../ship-library/assets/portraits/1426.webp | Bin 0 -> 26452 bytes .../ship-library/assets/portraits/1429.webp | Bin 0 -> 47076 bytes .../ship-library/assets/portraits/143.webp | Bin 0 -> 24328 bytes .../ship-library/assets/portraits/1430.webp | Bin 0 -> 28578 bytes .../ship-library/assets/portraits/1431.webp | Bin 0 -> 30022 bytes .../ship-library/assets/portraits/144.webp | Bin 0 -> 32326 bytes .../ship-library/assets/portraits/145.webp | Bin 0 -> 22322 bytes .../ship-library/assets/portraits/1456.webp | Bin 0 -> 25460 bytes .../ship-library/assets/portraits/146.webp | Bin 0 -> 22308 bytes .../ship-library/assets/portraits/1467.webp | Bin 0 -> 23778 bytes .../ship-library/assets/portraits/147.webp | Bin 0 -> 24618 bytes .../ship-library/assets/portraits/148.webp | Bin 0 -> 22712 bytes .../ship-library/assets/portraits/1483.webp | Bin 0 -> 26266 bytes .../ship-library/assets/portraits/149.webp | Bin 0 -> 28102 bytes .../ship-library/assets/portraits/1490.webp | Bin 0 -> 25028 bytes .../ship-library/assets/portraits/1496.webp | Bin 0 -> 21638 bytes .../ship-library/assets/portraits/15.webp | Bin 0 -> 22540 bytes .../ship-library/assets/portraits/150.webp | Bin 0 -> 24686 bytes .../ship-library/assets/portraits/1503.webp | Bin 0 -> 25498 bytes .../ship-library/assets/portraits/1509.webp | Bin 0 -> 30930 bytes .../ship-library/assets/portraits/151.webp | Bin 0 -> 23620 bytes .../ship-library/assets/portraits/1516.webp | Bin 0 -> 39356 bytes .../ship-library/assets/portraits/1517.webp | Bin 0 -> 19560 bytes .../ship-library/assets/portraits/1519.webp | Bin 0 -> 28506 bytes .../ship-library/assets/portraits/152.webp | Bin 0 -> 29482 bytes .../ship-library/assets/portraits/1527.webp | Bin 0 -> 30416 bytes .../ship-library/assets/portraits/1528.webp | Bin 0 -> 30000 bytes .../ship-library/assets/portraits/153.webp | Bin 0 -> 34826 bytes .../ship-library/assets/portraits/1530.webp | Bin 0 -> 21030 bytes .../ship-library/assets/portraits/1532.webp | Bin 0 -> 42718 bytes .../ship-library/assets/portraits/1538.webp | Bin 0 -> 25218 bytes .../ship-library/assets/portraits/154.webp | Bin 0 -> 32200 bytes .../ship-library/assets/portraits/1545.webp | Bin 0 -> 20288 bytes .../ship-library/assets/portraits/155.webp | Bin 0 -> 36554 bytes .../ship-library/assets/portraits/156.webp | Bin 0 -> 31868 bytes .../ship-library/assets/portraits/1560.webp | Bin 0 -> 24616 bytes .../ship-library/assets/portraits/157.webp | Bin 0 -> 34990 bytes .../ship-library/assets/portraits/1575.webp | Bin 0 -> 35670 bytes .../ship-library/assets/portraits/158.webp | Bin 0 -> 36320 bytes .../ship-library/assets/portraits/1583.webp | Bin 0 -> 38250 bytes .../ship-library/assets/portraits/1589.webp | Bin 0 -> 29764 bytes .../ship-library/assets/portraits/159.webp | Bin 0 -> 31428 bytes .../ship-library/assets/portraits/1590.webp | Bin 0 -> 43408 bytes .../ship-library/assets/portraits/16.webp | Bin 0 -> 24616 bytes .../ship-library/assets/portraits/160.webp | Bin 0 -> 23116 bytes .../ship-library/assets/portraits/1606.webp | Bin 0 -> 25636 bytes .../ship-library/assets/portraits/161.webp | Bin 0 -> 21816 bytes .../ship-library/assets/portraits/1618.webp | Bin 0 -> 31544 bytes .../ship-library/assets/portraits/162.webp | Bin 0 -> 20100 bytes .../ship-library/assets/portraits/163.webp | Bin 0 -> 28618 bytes .../ship-library/assets/portraits/164.webp | Bin 0 -> 25700 bytes .../ship-library/assets/portraits/165.webp | Bin 0 -> 22600 bytes .../ship-library/assets/portraits/166.webp | Bin 0 -> 23484 bytes .../ship-library/assets/portraits/167.webp | Bin 0 -> 22106 bytes .../ship-library/assets/portraits/168.webp | Bin 0 -> 21904 bytes .../ship-library/assets/portraits/169.webp | Bin 0 -> 21182 bytes .../ship-library/assets/portraits/17.webp | Bin 0 -> 22674 bytes .../ship-library/assets/portraits/170.webp | Bin 0 -> 30146 bytes .../ship-library/assets/portraits/171.webp | Bin 0 -> 23076 bytes .../ship-library/assets/portraits/172.webp | Bin 0 -> 27840 bytes .../ship-library/assets/portraits/173.webp | Bin 0 -> 28798 bytes .../ship-library/assets/portraits/174.webp | Bin 0 -> 27120 bytes .../ship-library/assets/portraits/175.webp | Bin 0 -> 30088 bytes .../ship-library/assets/portraits/176.webp | Bin 0 -> 31104 bytes .../ship-library/assets/portraits/177.webp | Bin 0 -> 30750 bytes .../ship-library/assets/portraits/178.webp | Bin 0 -> 28314 bytes .../ship-library/assets/portraits/179.webp | Bin 0 -> 22772 bytes .../ship-library/assets/portraits/18.webp | Bin 0 -> 23884 bytes .../ship-library/assets/portraits/180.webp | Bin 0 -> 29206 bytes .../ship-library/assets/portraits/181.webp | Bin 0 -> 26394 bytes .../ship-library/assets/portraits/182.webp | Bin 0 -> 25256 bytes .../ship-library/assets/portraits/183.webp | Bin 0 -> 27652 bytes .../ship-library/assets/portraits/184.webp | Bin 0 -> 24572 bytes .../ship-library/assets/portraits/185.webp | Bin 0 -> 24252 bytes .../ship-library/assets/portraits/186.webp | Bin 0 -> 31960 bytes .../ship-library/assets/portraits/187.webp | Bin 0 -> 26042 bytes .../ship-library/assets/portraits/188.webp | Bin 0 -> 25290 bytes .../ship-library/assets/portraits/189.webp | Bin 0 -> 27468 bytes .../ship-library/assets/portraits/19.webp | Bin 0 -> 22000 bytes .../ship-library/assets/portraits/190.webp | Bin 0 -> 34090 bytes .../ship-library/assets/portraits/191.webp | Bin 0 -> 34996 bytes .../ship-library/assets/portraits/192.webp | Bin 0 -> 25026 bytes .../ship-library/assets/portraits/193.webp | Bin 0 -> 34028 bytes .../ship-library/assets/portraits/194.webp | Bin 0 -> 21148 bytes .../ship-library/assets/portraits/195.webp | Bin 0 -> 23788 bytes .../ship-library/assets/portraits/196.webp | Bin 0 -> 25322 bytes .../ship-library/assets/portraits/197.webp | Bin 0 -> 18314 bytes .../ship-library/assets/portraits/198.webp | Bin 0 -> 21760 bytes .../ship-library/assets/portraits/199.webp | Bin 0 -> 19268 bytes resource/ship-library/assets/portraits/2.webp | Bin 0 -> 23282 bytes .../ship-library/assets/portraits/20.webp | Bin 0 -> 37880 bytes .../ship-library/assets/portraits/200.webp | Bin 0 -> 26934 bytes .../ship-library/assets/portraits/201.webp | Bin 0 -> 34036 bytes .../ship-library/assets/portraits/202.webp | Bin 0 -> 20510 bytes .../ship-library/assets/portraits/203.webp | Bin 0 -> 21168 bytes .../ship-library/assets/portraits/205.webp | Bin 0 -> 21140 bytes .../ship-library/assets/portraits/206.webp | Bin 0 -> 28856 bytes .../ship-library/assets/portraits/207.webp | Bin 0 -> 35774 bytes .../ship-library/assets/portraits/208.webp | Bin 0 -> 33672 bytes .../ship-library/assets/portraits/209.webp | Bin 0 -> 26488 bytes .../ship-library/assets/portraits/21.webp | Bin 0 -> 32570 bytes .../ship-library/assets/portraits/210.webp | Bin 0 -> 21936 bytes .../ship-library/assets/portraits/211.webp | Bin 0 -> 30330 bytes .../ship-library/assets/portraits/212.webp | Bin 0 -> 25222 bytes .../ship-library/assets/portraits/213.webp | Bin 0 -> 25558 bytes .../ship-library/assets/portraits/214.webp | Bin 0 -> 29678 bytes .../ship-library/assets/portraits/215.webp | Bin 0 -> 32790 bytes .../ship-library/assets/portraits/216.webp | Bin 0 -> 33126 bytes .../ship-library/assets/portraits/217.webp | Bin 0 -> 30116 bytes .../ship-library/assets/portraits/218.webp | Bin 0 -> 24898 bytes .../ship-library/assets/portraits/219.webp | Bin 0 -> 30010 bytes .../ship-library/assets/portraits/22.webp | Bin 0 -> 26700 bytes .../ship-library/assets/portraits/220.webp | Bin 0 -> 29974 bytes .../ship-library/assets/portraits/221.webp | Bin 0 -> 24678 bytes .../ship-library/assets/portraits/222.webp | Bin 0 -> 21390 bytes .../ship-library/assets/portraits/223.webp | Bin 0 -> 26644 bytes .../ship-library/assets/portraits/224.webp | Bin 0 -> 27114 bytes .../ship-library/assets/portraits/225.webp | Bin 0 -> 31056 bytes .../ship-library/assets/portraits/226.webp | Bin 0 -> 35372 bytes .../ship-library/assets/portraits/227.webp | Bin 0 -> 25466 bytes .../ship-library/assets/portraits/228.webp | Bin 0 -> 30510 bytes .../ship-library/assets/portraits/229.webp | Bin 0 -> 24642 bytes .../ship-library/assets/portraits/23.webp | Bin 0 -> 26432 bytes .../ship-library/assets/portraits/230.webp | Bin 0 -> 23346 bytes .../ship-library/assets/portraits/231.webp | Bin 0 -> 18044 bytes .../ship-library/assets/portraits/232.webp | Bin 0 -> 30072 bytes .../ship-library/assets/portraits/233.webp | Bin 0 -> 26016 bytes .../ship-library/assets/portraits/234.webp | Bin 0 -> 22390 bytes .../ship-library/assets/portraits/235.webp | Bin 0 -> 25522 bytes .../ship-library/assets/portraits/236.webp | Bin 0 -> 21698 bytes .../ship-library/assets/portraits/237.webp | Bin 0 -> 25240 bytes .../ship-library/assets/portraits/238.webp | Bin 0 -> 29008 bytes .../ship-library/assets/portraits/239.webp | Bin 0 -> 27464 bytes .../ship-library/assets/portraits/24.webp | Bin 0 -> 27790 bytes .../ship-library/assets/portraits/240.webp | Bin 0 -> 29122 bytes .../ship-library/assets/portraits/241.webp | Bin 0 -> 30164 bytes .../ship-library/assets/portraits/242.webp | Bin 0 -> 18376 bytes .../ship-library/assets/portraits/243.webp | Bin 0 -> 26148 bytes .../ship-library/assets/portraits/244.webp | Bin 0 -> 35594 bytes .../ship-library/assets/portraits/245.webp | Bin 0 -> 29414 bytes .../ship-library/assets/portraits/246.webp | Bin 0 -> 26192 bytes .../ship-library/assets/portraits/247.webp | Bin 0 -> 26064 bytes .../ship-library/assets/portraits/248.webp | Bin 0 -> 32382 bytes .../ship-library/assets/portraits/249.webp | Bin 0 -> 25652 bytes .../ship-library/assets/portraits/25.webp | Bin 0 -> 30744 bytes .../ship-library/assets/portraits/250.webp | Bin 0 -> 28188 bytes .../ship-library/assets/portraits/251.webp | Bin 0 -> 30772 bytes .../ship-library/assets/portraits/252.webp | Bin 0 -> 25184 bytes .../ship-library/assets/portraits/253.webp | Bin 0 -> 29164 bytes .../ship-library/assets/portraits/254.webp | Bin 0 -> 28280 bytes .../ship-library/assets/portraits/255.webp | Bin 0 -> 32734 bytes .../ship-library/assets/portraits/256.webp | Bin 0 -> 29692 bytes .../ship-library/assets/portraits/257.webp | Bin 0 -> 34380 bytes .../ship-library/assets/portraits/258.webp | Bin 0 -> 20208 bytes .../ship-library/assets/portraits/259.webp | Bin 0 -> 31536 bytes .../ship-library/assets/portraits/26.webp | Bin 0 -> 24500 bytes .../ship-library/assets/portraits/260.webp | Bin 0 -> 30830 bytes .../ship-library/assets/portraits/261.webp | Bin 0 -> 25900 bytes .../ship-library/assets/portraits/262.webp | Bin 0 -> 25664 bytes .../ship-library/assets/portraits/263.webp | Bin 0 -> 27084 bytes .../ship-library/assets/portraits/264.webp | Bin 0 -> 30832 bytes .../ship-library/assets/portraits/265.webp | Bin 0 -> 28240 bytes .../ship-library/assets/portraits/266.webp | Bin 0 -> 28376 bytes .../ship-library/assets/portraits/267.webp | Bin 0 -> 28616 bytes .../ship-library/assets/portraits/268.webp | Bin 0 -> 17980 bytes .../ship-library/assets/portraits/269.webp | Bin 0 -> 21612 bytes .../ship-library/assets/portraits/27.webp | Bin 0 -> 23764 bytes .../ship-library/assets/portraits/270.webp | Bin 0 -> 23670 bytes .../ship-library/assets/portraits/271.webp | Bin 0 -> 28700 bytes .../ship-library/assets/portraits/272.webp | Bin 0 -> 26720 bytes .../ship-library/assets/portraits/273.webp | Bin 0 -> 29504 bytes .../ship-library/assets/portraits/274.webp | Bin 0 -> 35520 bytes .../ship-library/assets/portraits/275.webp | Bin 0 -> 29870 bytes .../ship-library/assets/portraits/276.webp | Bin 0 -> 30420 bytes .../ship-library/assets/portraits/277.webp | Bin 0 -> 31798 bytes .../ship-library/assets/portraits/278.webp | Bin 0 -> 28128 bytes .../ship-library/assets/portraits/279.webp | Bin 0 -> 22102 bytes .../ship-library/assets/portraits/28.webp | Bin 0 -> 37056 bytes .../ship-library/assets/portraits/280.webp | Bin 0 -> 28022 bytes .../ship-library/assets/portraits/281.webp | Bin 0 -> 24818 bytes .../ship-library/assets/portraits/282.webp | Bin 0 -> 24538 bytes .../ship-library/assets/portraits/283.webp | Bin 0 -> 25454 bytes .../ship-library/assets/portraits/284.webp | Bin 0 -> 26818 bytes .../ship-library/assets/portraits/285.webp | Bin 0 -> 32096 bytes .../ship-library/assets/portraits/286.webp | Bin 0 -> 36774 bytes .../ship-library/assets/portraits/287.webp | Bin 0 -> 35064 bytes .../ship-library/assets/portraits/288.webp | Bin 0 -> 30304 bytes .../ship-library/assets/portraits/289.webp | Bin 0 -> 20652 bytes .../ship-library/assets/portraits/29.webp | Bin 0 -> 22794 bytes .../ship-library/assets/portraits/290.webp | Bin 0 -> 28388 bytes .../ship-library/assets/portraits/291.webp | Bin 0 -> 27288 bytes .../ship-library/assets/portraits/292.webp | Bin 0 -> 25336 bytes .../ship-library/assets/portraits/293.webp | Bin 0 -> 16798 bytes .../ship-library/assets/portraits/294.webp | Bin 0 -> 24932 bytes .../ship-library/assets/portraits/295.webp | Bin 0 -> 26046 bytes .../ship-library/assets/portraits/296.webp | Bin 0 -> 20966 bytes .../ship-library/assets/portraits/297.webp | Bin 0 -> 35692 bytes .../ship-library/assets/portraits/298.webp | Bin 0 -> 30110 bytes .../ship-library/assets/portraits/299.webp | Bin 0 -> 24818 bytes resource/ship-library/assets/portraits/3.webp | Bin 0 -> 22694 bytes .../ship-library/assets/portraits/30.webp | Bin 0 -> 22546 bytes .../ship-library/assets/portraits/300.webp | Bin 0 -> 32252 bytes .../ship-library/assets/portraits/301.webp | Bin 0 -> 29390 bytes .../ship-library/assets/portraits/302.webp | Bin 0 -> 32802 bytes .../ship-library/assets/portraits/303.webp | Bin 0 -> 20022 bytes .../ship-library/assets/portraits/304.webp | Bin 0 -> 31212 bytes .../ship-library/assets/portraits/305.webp | Bin 0 -> 19560 bytes .../ship-library/assets/portraits/306.webp | Bin 0 -> 27464 bytes .../ship-library/assets/portraits/307.webp | Bin 0 -> 24932 bytes .../ship-library/assets/portraits/308.webp | Bin 0 -> 30164 bytes .../ship-library/assets/portraits/309.webp | Bin 0 -> 26800 bytes .../ship-library/assets/portraits/31.webp | Bin 0 -> 27862 bytes .../ship-library/assets/portraits/310.webp | Bin 0 -> 37930 bytes .../ship-library/assets/portraits/311.webp | Bin 0 -> 26074 bytes .../ship-library/assets/portraits/312.webp | Bin 0 -> 24340 bytes .../ship-library/assets/portraits/313.webp | Bin 0 -> 25816 bytes .../ship-library/assets/portraits/314.webp | Bin 0 -> 28268 bytes .../ship-library/assets/portraits/315.webp | Bin 0 -> 24726 bytes .../ship-library/assets/portraits/316.webp | Bin 0 -> 28636 bytes .../ship-library/assets/portraits/317.webp | Bin 0 -> 24538 bytes .../ship-library/assets/portraits/318.webp | Bin 0 -> 26082 bytes .../ship-library/assets/portraits/319.webp | Bin 0 -> 28908 bytes .../ship-library/assets/portraits/32.webp | Bin 0 -> 31790 bytes .../ship-library/assets/portraits/320.webp | Bin 0 -> 30090 bytes .../ship-library/assets/portraits/321.webp | Bin 0 -> 26432 bytes .../ship-library/assets/portraits/322.webp | Bin 0 -> 27198 bytes .../ship-library/assets/portraits/323.webp | Bin 0 -> 28630 bytes .../ship-library/assets/portraits/324.webp | Bin 0 -> 30048 bytes .../ship-library/assets/portraits/325.webp | Bin 0 -> 21786 bytes .../ship-library/assets/portraits/326.webp | Bin 0 -> 23168 bytes .../ship-library/assets/portraits/327.webp | Bin 0 -> 31076 bytes .../ship-library/assets/portraits/328.webp | Bin 0 -> 22162 bytes .../ship-library/assets/portraits/329.webp | Bin 0 -> 24912 bytes .../ship-library/assets/portraits/33.webp | Bin 0 -> 27896 bytes .../ship-library/assets/portraits/330.webp | Bin 0 -> 32966 bytes .../ship-library/assets/portraits/331.webp | Bin 0 -> 25308 bytes .../ship-library/assets/portraits/332.webp | Bin 0 -> 30428 bytes .../ship-library/assets/portraits/333.webp | Bin 0 -> 31378 bytes .../ship-library/assets/portraits/334.webp | Bin 0 -> 32860 bytes .../ship-library/assets/portraits/335.webp | Bin 0 -> 32870 bytes .../ship-library/assets/portraits/336.webp | Bin 0 -> 25262 bytes .../ship-library/assets/portraits/337.webp | Bin 0 -> 23844 bytes .../ship-library/assets/portraits/338.webp | Bin 0 -> 32346 bytes .../ship-library/assets/portraits/339.webp | Bin 0 -> 24902 bytes .../ship-library/assets/portraits/34.webp | Bin 0 -> 26068 bytes .../ship-library/assets/portraits/340.webp | Bin 0 -> 27870 bytes .../ship-library/assets/portraits/341.webp | Bin 0 -> 34736 bytes .../ship-library/assets/portraits/342.webp | Bin 0 -> 27126 bytes .../ship-library/assets/portraits/343.webp | Bin 0 -> 32386 bytes .../ship-library/assets/portraits/344.webp | Bin 0 -> 27560 bytes .../ship-library/assets/portraits/345.webp | Bin 0 -> 22148 bytes .../ship-library/assets/portraits/346.webp | Bin 0 -> 30886 bytes .../ship-library/assets/portraits/347.webp | Bin 0 -> 25042 bytes .../ship-library/assets/portraits/348.webp | Bin 0 -> 30608 bytes .../ship-library/assets/portraits/349.webp | Bin 0 -> 26136 bytes .../ship-library/assets/portraits/35.webp | Bin 0 -> 24498 bytes .../ship-library/assets/portraits/350.webp | Bin 0 -> 25216 bytes .../ship-library/assets/portraits/351.webp | Bin 0 -> 26874 bytes .../ship-library/assets/portraits/352.webp | Bin 0 -> 25798 bytes .../ship-library/assets/portraits/353.webp | Bin 0 -> 26884 bytes .../ship-library/assets/portraits/354.webp | Bin 0 -> 27292 bytes .../ship-library/assets/portraits/355.webp | Bin 0 -> 30216 bytes .../ship-library/assets/portraits/356.webp | Bin 0 -> 37276 bytes .../ship-library/assets/portraits/357.webp | Bin 0 -> 24652 bytes .../ship-library/assets/portraits/358.webp | Bin 0 -> 29576 bytes .../ship-library/assets/portraits/359.webp | Bin 0 -> 25474 bytes .../ship-library/assets/portraits/36.webp | Bin 0 -> 24378 bytes .../ship-library/assets/portraits/360.webp | Bin 0 -> 24286 bytes .../ship-library/assets/portraits/361.webp | Bin 0 -> 24062 bytes .../ship-library/assets/portraits/362.webp | Bin 0 -> 29342 bytes .../ship-library/assets/portraits/363.webp | Bin 0 -> 23172 bytes .../ship-library/assets/portraits/364.webp | Bin 0 -> 25330 bytes .../ship-library/assets/portraits/365.webp | Bin 0 -> 28558 bytes .../ship-library/assets/portraits/366.webp | Bin 0 -> 26502 bytes .../ship-library/assets/portraits/367.webp | Bin 0 -> 21154 bytes .../ship-library/assets/portraits/368.webp | Bin 0 -> 35742 bytes .../ship-library/assets/portraits/369.webp | Bin 0 -> 28188 bytes .../ship-library/assets/portraits/37.webp | Bin 0 -> 28122 bytes .../ship-library/assets/portraits/370.webp | Bin 0 -> 24588 bytes .../ship-library/assets/portraits/371.webp | Bin 0 -> 24412 bytes .../ship-library/assets/portraits/372.webp | Bin 0 -> 29384 bytes .../ship-library/assets/portraits/373.webp | Bin 0 -> 27952 bytes .../ship-library/assets/portraits/374.webp | Bin 0 -> 21736 bytes .../ship-library/assets/portraits/375.webp | Bin 0 -> 24496 bytes .../ship-library/assets/portraits/376.webp | Bin 0 -> 27986 bytes .../ship-library/assets/portraits/377.webp | Bin 0 -> 30650 bytes .../ship-library/assets/portraits/378.webp | Bin 0 -> 30706 bytes .../ship-library/assets/portraits/379.webp | Bin 0 -> 28314 bytes .../ship-library/assets/portraits/38.webp | Bin 0 -> 26138 bytes .../ship-library/assets/portraits/380.webp | Bin 0 -> 27962 bytes .../ship-library/assets/portraits/381.webp | Bin 0 -> 29078 bytes .../ship-library/assets/portraits/382.webp | Bin 0 -> 29698 bytes .../ship-library/assets/portraits/383.webp | Bin 0 -> 28012 bytes .../ship-library/assets/portraits/384.webp | Bin 0 -> 25374 bytes .../ship-library/assets/portraits/385.webp | Bin 0 -> 29528 bytes .../ship-library/assets/portraits/386.webp | Bin 0 -> 28996 bytes .../ship-library/assets/portraits/387.webp | Bin 0 -> 31964 bytes .../ship-library/assets/portraits/388.webp | Bin 0 -> 28302 bytes .../ship-library/assets/portraits/389.webp | Bin 0 -> 30570 bytes .../ship-library/assets/portraits/39.webp | Bin 0 -> 26136 bytes .../ship-library/assets/portraits/390.webp | Bin 0 -> 27122 bytes .../ship-library/assets/portraits/391.webp | Bin 0 -> 23376 bytes .../ship-library/assets/portraits/392.webp | Bin 0 -> 32852 bytes .../ship-library/assets/portraits/393.webp | Bin 0 -> 24876 bytes .../ship-library/assets/portraits/394.webp | Bin 0 -> 35284 bytes .../ship-library/assets/portraits/395.webp | Bin 0 -> 28764 bytes .../ship-library/assets/portraits/396.webp | Bin 0 -> 24406 bytes .../ship-library/assets/portraits/397.webp | Bin 0 -> 23722 bytes .../ship-library/assets/portraits/398.webp | Bin 0 -> 32656 bytes .../ship-library/assets/portraits/399.webp | Bin 0 -> 25018 bytes resource/ship-library/assets/portraits/4.webp | Bin 0 -> 26932 bytes .../ship-library/assets/portraits/40.webp | Bin 0 -> 33582 bytes .../ship-library/assets/portraits/400.webp | Bin 0 -> 25846 bytes .../ship-library/assets/portraits/401.webp | Bin 0 -> 23986 bytes .../ship-library/assets/portraits/402.webp | Bin 0 -> 23166 bytes .../ship-library/assets/portraits/403.webp | Bin 0 -> 36522 bytes .../ship-library/assets/portraits/404.webp | Bin 0 -> 26866 bytes .../ship-library/assets/portraits/405.webp | Bin 0 -> 28032 bytes .../ship-library/assets/portraits/406.webp | Bin 0 -> 27378 bytes .../ship-library/assets/portraits/407.webp | Bin 0 -> 20218 bytes .../ship-library/assets/portraits/408.webp | Bin 0 -> 32128 bytes .../ship-library/assets/portraits/409.webp | Bin 0 -> 23390 bytes .../ship-library/assets/portraits/41.webp | Bin 0 -> 25008 bytes .../ship-library/assets/portraits/410.webp | Bin 0 -> 32090 bytes .../ship-library/assets/portraits/411.webp | Bin 0 -> 23320 bytes .../ship-library/assets/portraits/412.webp | Bin 0 -> 25160 bytes .../ship-library/assets/portraits/413.webp | Bin 0 -> 31812 bytes .../ship-library/assets/portraits/414.webp | Bin 0 -> 30080 bytes .../ship-library/assets/portraits/415.webp | Bin 0 -> 29210 bytes .../ship-library/assets/portraits/416.webp | Bin 0 -> 26704 bytes .../ship-library/assets/portraits/417.webp | Bin 0 -> 34176 bytes .../ship-library/assets/portraits/418.webp | Bin 0 -> 31398 bytes .../ship-library/assets/portraits/419.webp | Bin 0 -> 21242 bytes .../ship-library/assets/portraits/42.webp | Bin 0 -> 23498 bytes .../ship-library/assets/portraits/420.webp | Bin 0 -> 20842 bytes .../ship-library/assets/portraits/421.webp | Bin 0 -> 23866 bytes .../ship-library/assets/portraits/422.webp | Bin 0 -> 44568 bytes .../ship-library/assets/portraits/423.webp | Bin 0 -> 25284 bytes .../ship-library/assets/portraits/424.webp | Bin 0 -> 28918 bytes .../ship-library/assets/portraits/425.webp | Bin 0 -> 24960 bytes .../ship-library/assets/portraits/426.webp | Bin 0 -> 27946 bytes .../ship-library/assets/portraits/427.webp | Bin 0 -> 26800 bytes .../ship-library/assets/portraits/428.webp | Bin 0 -> 23434 bytes .../ship-library/assets/portraits/429.webp | Bin 0 -> 26978 bytes .../ship-library/assets/portraits/43.webp | Bin 0 -> 32106 bytes .../ship-library/assets/portraits/430.webp | Bin 0 -> 23952 bytes .../ship-library/assets/portraits/431.webp | Bin 0 -> 31730 bytes .../ship-library/assets/portraits/432.webp | Bin 0 -> 25982 bytes .../ship-library/assets/portraits/433.webp | Bin 0 -> 23500 bytes .../ship-library/assets/portraits/434.webp | Bin 0 -> 34382 bytes .../ship-library/assets/portraits/435.webp | Bin 0 -> 36034 bytes .../ship-library/assets/portraits/436.webp | Bin 0 -> 24180 bytes .../ship-library/assets/portraits/437.webp | Bin 0 -> 28078 bytes .../ship-library/assets/portraits/438.webp | Bin 0 -> 23810 bytes .../ship-library/assets/portraits/439.webp | Bin 0 -> 21790 bytes .../ship-library/assets/portraits/44.webp | Bin 0 -> 29618 bytes .../ship-library/assets/portraits/440.webp | Bin 0 -> 30026 bytes .../ship-library/assets/portraits/441.webp | Bin 0 -> 37398 bytes .../ship-library/assets/portraits/442.webp | Bin 0 -> 25080 bytes .../ship-library/assets/portraits/443.webp | Bin 0 -> 21638 bytes .../ship-library/assets/portraits/444.webp | Bin 0 -> 25090 bytes .../ship-library/assets/portraits/445.webp | Bin 0 -> 28474 bytes .../ship-library/assets/portraits/446.webp | Bin 0 -> 37192 bytes .../ship-library/assets/portraits/447.webp | Bin 0 -> 27344 bytes .../ship-library/assets/portraits/448.webp | Bin 0 -> 31044 bytes .../ship-library/assets/portraits/449.webp | Bin 0 -> 30430 bytes .../ship-library/assets/portraits/45.webp | Bin 0 -> 21870 bytes .../ship-library/assets/portraits/450.webp | Bin 0 -> 28762 bytes .../ship-library/assets/portraits/451.webp | Bin 0 -> 26612 bytes .../ship-library/assets/portraits/452.webp | Bin 0 -> 27798 bytes .../ship-library/assets/portraits/453.webp | Bin 0 -> 22840 bytes .../ship-library/assets/portraits/454.webp | Bin 0 -> 33464 bytes .../ship-library/assets/portraits/455.webp | Bin 0 -> 32192 bytes .../ship-library/assets/portraits/456.webp | Bin 0 -> 28576 bytes .../ship-library/assets/portraits/457.webp | Bin 0 -> 28188 bytes .../ship-library/assets/portraits/458.webp | Bin 0 -> 26368 bytes .../ship-library/assets/portraits/459.webp | Bin 0 -> 27138 bytes .../ship-library/assets/portraits/46.webp | Bin 0 -> 28326 bytes .../ship-library/assets/portraits/460.webp | Bin 0 -> 22520 bytes .../ship-library/assets/portraits/461.webp | Bin 0 -> 21376 bytes .../ship-library/assets/portraits/462.webp | Bin 0 -> 29496 bytes .../ship-library/assets/portraits/463.webp | Bin 0 -> 27844 bytes .../ship-library/assets/portraits/464.webp | Bin 0 -> 28918 bytes .../ship-library/assets/portraits/465.webp | Bin 0 -> 22356 bytes .../ship-library/assets/portraits/466.webp | Bin 0 -> 42452 bytes .../ship-library/assets/portraits/467.webp | Bin 0 -> 31368 bytes .../ship-library/assets/portraits/468.webp | Bin 0 -> 26764 bytes .../ship-library/assets/portraits/469.webp | Bin 0 -> 21820 bytes .../ship-library/assets/portraits/47.webp | Bin 0 -> 23986 bytes .../ship-library/assets/portraits/470.webp | Bin 0 -> 29878 bytes .../ship-library/assets/portraits/471.webp | Bin 0 -> 27320 bytes .../ship-library/assets/portraits/472.webp | Bin 0 -> 20214 bytes .../ship-library/assets/portraits/473.webp | Bin 0 -> 28632 bytes .../ship-library/assets/portraits/474.webp | Bin 0 -> 25960 bytes .../ship-library/assets/portraits/475.webp | Bin 0 -> 25622 bytes .../ship-library/assets/portraits/476.webp | Bin 0 -> 31550 bytes .../ship-library/assets/portraits/477.webp | Bin 0 -> 26088 bytes .../ship-library/assets/portraits/478.webp | Bin 0 -> 25226 bytes .../ship-library/assets/portraits/479.webp | Bin 0 -> 25288 bytes .../ship-library/assets/portraits/48.webp | Bin 0 -> 23930 bytes .../ship-library/assets/portraits/480.webp | Bin 0 -> 30432 bytes .../ship-library/assets/portraits/481.webp | Bin 0 -> 36094 bytes .../ship-library/assets/portraits/482.webp | Bin 0 -> 31274 bytes .../ship-library/assets/portraits/483.webp | Bin 0 -> 20248 bytes .../ship-library/assets/portraits/484.webp | Bin 0 -> 34368 bytes .../ship-library/assets/portraits/485.webp | Bin 0 -> 27672 bytes .../ship-library/assets/portraits/486.webp | Bin 0 -> 34964 bytes .../ship-library/assets/portraits/487.webp | Bin 0 -> 24584 bytes .../ship-library/assets/portraits/488.webp | Bin 0 -> 27482 bytes .../ship-library/assets/portraits/489.webp | Bin 0 -> 22930 bytes .../ship-library/assets/portraits/49.webp | Bin 0 -> 27852 bytes .../ship-library/assets/portraits/490.webp | Bin 0 -> 21884 bytes .../ship-library/assets/portraits/491.webp | Bin 0 -> 29002 bytes .../ship-library/assets/portraits/492.webp | Bin 0 -> 30466 bytes .../ship-library/assets/portraits/493.webp | Bin 0 -> 22612 bytes .../ship-library/assets/portraits/494.webp | Bin 0 -> 39468 bytes .../ship-library/assets/portraits/495.webp | Bin 0 -> 28182 bytes .../ship-library/assets/portraits/496.webp | Bin 0 -> 22744 bytes .../ship-library/assets/portraits/497.webp | Bin 0 -> 25392 bytes .../ship-library/assets/portraits/498.webp | Bin 0 -> 22922 bytes .../ship-library/assets/portraits/499.webp | Bin 0 -> 30946 bytes resource/ship-library/assets/portraits/5.webp | Bin 0 -> 25872 bytes .../ship-library/assets/portraits/50.webp | Bin 0 -> 34618 bytes .../ship-library/assets/portraits/500.webp | Bin 0 -> 23246 bytes .../ship-library/assets/portraits/501.webp | Bin 0 -> 31396 bytes .../ship-library/assets/portraits/502.webp | Bin 0 -> 29866 bytes .../ship-library/assets/portraits/503.webp | Bin 0 -> 26034 bytes .../ship-library/assets/portraits/504.webp | Bin 0 -> 23254 bytes .../ship-library/assets/portraits/505.webp | Bin 0 -> 24948 bytes .../ship-library/assets/portraits/506.webp | Bin 0 -> 26762 bytes .../ship-library/assets/portraits/507.webp | Bin 0 -> 31442 bytes .../ship-library/assets/portraits/508.webp | Bin 0 -> 21622 bytes .../ship-library/assets/portraits/509.webp | Bin 0 -> 31002 bytes .../ship-library/assets/portraits/51.webp | Bin 0 -> 24680 bytes .../ship-library/assets/portraits/510.webp | Bin 0 -> 27458 bytes .../ship-library/assets/portraits/511.webp | Bin 0 -> 43710 bytes .../ship-library/assets/portraits/512.webp | Bin 0 -> 26964 bytes .../ship-library/assets/portraits/513.webp | Bin 0 -> 21436 bytes .../ship-library/assets/portraits/514.webp | Bin 0 -> 27456 bytes .../ship-library/assets/portraits/515.webp | Bin 0 -> 26392 bytes .../ship-library/assets/portraits/516.webp | Bin 0 -> 24254 bytes .../ship-library/assets/portraits/517.webp | Bin 0 -> 22312 bytes .../ship-library/assets/portraits/518.webp | Bin 0 -> 20750 bytes .../ship-library/assets/portraits/519.webp | Bin 0 -> 23264 bytes .../ship-library/assets/portraits/52.webp | Bin 0 -> 22140 bytes .../ship-library/assets/portraits/520.webp | Bin 0 -> 24468 bytes .../ship-library/assets/portraits/521.webp | Bin 0 -> 28268 bytes .../ship-library/assets/portraits/522.webp | Bin 0 -> 27630 bytes .../ship-library/assets/portraits/523.webp | Bin 0 -> 28032 bytes .../ship-library/assets/portraits/524.webp | Bin 0 -> 27420 bytes .../ship-library/assets/portraits/525.webp | Bin 0 -> 26868 bytes .../ship-library/assets/portraits/526.webp | Bin 0 -> 25622 bytes .../ship-library/assets/portraits/527.webp | Bin 0 -> 23680 bytes .../ship-library/assets/portraits/528.webp | Bin 0 -> 24810 bytes .../ship-library/assets/portraits/529.webp | Bin 0 -> 44324 bytes .../ship-library/assets/portraits/53.webp | Bin 0 -> 23978 bytes .../ship-library/assets/portraits/530.webp | Bin 0 -> 24034 bytes .../ship-library/assets/portraits/531.webp | Bin 0 -> 28776 bytes .../ship-library/assets/portraits/532.webp | Bin 0 -> 42432 bytes .../ship-library/assets/portraits/533.webp | Bin 0 -> 22546 bytes .../ship-library/assets/portraits/534.webp | Bin 0 -> 20226 bytes .../ship-library/assets/portraits/535.webp | Bin 0 -> 26296 bytes .../ship-library/assets/portraits/536.webp | Bin 0 -> 28310 bytes .../ship-library/assets/portraits/537.webp | Bin 0 -> 27700 bytes .../ship-library/assets/portraits/538.webp | Bin 0 -> 24104 bytes .../ship-library/assets/portraits/539.webp | Bin 0 -> 23318 bytes .../ship-library/assets/portraits/54.webp | Bin 0 -> 28038 bytes .../ship-library/assets/portraits/540.webp | Bin 0 -> 21152 bytes .../ship-library/assets/portraits/541.webp | Bin 0 -> 27772 bytes .../ship-library/assets/portraits/542.webp | Bin 0 -> 22584 bytes .../ship-library/assets/portraits/543.webp | Bin 0 -> 25596 bytes .../ship-library/assets/portraits/544.webp | Bin 0 -> 37336 bytes .../ship-library/assets/portraits/545.webp | Bin 0 -> 22276 bytes .../ship-library/assets/portraits/546.webp | Bin 0 -> 19084 bytes .../ship-library/assets/portraits/547.webp | Bin 0 -> 22712 bytes .../ship-library/assets/portraits/548.webp | Bin 0 -> 25520 bytes .../ship-library/assets/portraits/549.webp | Bin 0 -> 36898 bytes .../ship-library/assets/portraits/55.webp | Bin 0 -> 27390 bytes .../ship-library/assets/portraits/550.webp | Bin 0 -> 32320 bytes .../ship-library/assets/portraits/551.webp | Bin 0 -> 21832 bytes .../ship-library/assets/portraits/552.webp | Bin 0 -> 31106 bytes .../ship-library/assets/portraits/553.webp | Bin 0 -> 26000 bytes .../ship-library/assets/portraits/554.webp | Bin 0 -> 27126 bytes .../ship-library/assets/portraits/555.webp | Bin 0 -> 26008 bytes .../ship-library/assets/portraits/556.webp | Bin 0 -> 27860 bytes .../ship-library/assets/portraits/557.webp | Bin 0 -> 22808 bytes .../ship-library/assets/portraits/558.webp | Bin 0 -> 30576 bytes .../ship-library/assets/portraits/559.webp | Bin 0 -> 28696 bytes .../ship-library/assets/portraits/56.webp | Bin 0 -> 50450 bytes .../ship-library/assets/portraits/560.webp | Bin 0 -> 23172 bytes .../ship-library/assets/portraits/561.webp | Bin 0 -> 17094 bytes .../ship-library/assets/portraits/562.webp | Bin 0 -> 26750 bytes .../ship-library/assets/portraits/563.webp | Bin 0 -> 17706 bytes .../ship-library/assets/portraits/564.webp | Bin 0 -> 33336 bytes .../ship-library/assets/portraits/565.webp | Bin 0 -> 25912 bytes .../ship-library/assets/portraits/566.webp | Bin 0 -> 33850 bytes .../ship-library/assets/portraits/567.webp | Bin 0 -> 23296 bytes .../ship-library/assets/portraits/568.webp | Bin 0 -> 26086 bytes .../ship-library/assets/portraits/569.webp | Bin 0 -> 36840 bytes .../ship-library/assets/portraits/57.webp | Bin 0 -> 30828 bytes .../ship-library/assets/portraits/570.webp | Bin 0 -> 28182 bytes .../ship-library/assets/portraits/571.webp | Bin 0 -> 27998 bytes .../ship-library/assets/portraits/572.webp | Bin 0 -> 31886 bytes .../ship-library/assets/portraits/573.webp | Bin 0 -> 33154 bytes .../ship-library/assets/portraits/574.webp | Bin 0 -> 23038 bytes .../ship-library/assets/portraits/575.webp | Bin 0 -> 30414 bytes .../ship-library/assets/portraits/576.webp | Bin 0 -> 28682 bytes .../ship-library/assets/portraits/577.webp | Bin 0 -> 39244 bytes .../ship-library/assets/portraits/578.webp | Bin 0 -> 24314 bytes .../ship-library/assets/portraits/579.webp | Bin 0 -> 35716 bytes .../ship-library/assets/portraits/58.webp | Bin 0 -> 27534 bytes .../ship-library/assets/portraits/580.webp | Bin 0 -> 26690 bytes .../ship-library/assets/portraits/581.webp | Bin 0 -> 30094 bytes .../ship-library/assets/portraits/582.webp | Bin 0 -> 38840 bytes .../ship-library/assets/portraits/583.webp | Bin 0 -> 46704 bytes .../ship-library/assets/portraits/584.webp | Bin 0 -> 34422 bytes .../ship-library/assets/portraits/585.webp | Bin 0 -> 34798 bytes .../ship-library/assets/portraits/586.webp | Bin 0 -> 25130 bytes .../ship-library/assets/portraits/587.webp | Bin 0 -> 31274 bytes .../ship-library/assets/portraits/588.webp | Bin 0 -> 28470 bytes .../ship-library/assets/portraits/589.webp | Bin 0 -> 27626 bytes .../ship-library/assets/portraits/59.webp | Bin 0 -> 22924 bytes .../ship-library/assets/portraits/590.webp | Bin 0 -> 30690 bytes .../ship-library/assets/portraits/591.webp | Bin 0 -> 24992 bytes .../ship-library/assets/portraits/592.webp | Bin 0 -> 25540 bytes .../ship-library/assets/portraits/593.webp | Bin 0 -> 22276 bytes .../ship-library/assets/portraits/594.webp | Bin 0 -> 29772 bytes .../ship-library/assets/portraits/595.webp | Bin 0 -> 27062 bytes .../ship-library/assets/portraits/596.webp | Bin 0 -> 39148 bytes .../ship-library/assets/portraits/597.webp | Bin 0 -> 30294 bytes .../ship-library/assets/portraits/598.webp | Bin 0 -> 24104 bytes .../ship-library/assets/portraits/599.webp | Bin 0 -> 33272 bytes resource/ship-library/assets/portraits/6.webp | Bin 0 -> 27070 bytes .../ship-library/assets/portraits/60.webp | Bin 0 -> 26838 bytes .../ship-library/assets/portraits/600.webp | Bin 0 -> 27898 bytes .../ship-library/assets/portraits/601.webp | Bin 0 -> 35742 bytes .../ship-library/assets/portraits/602.webp | Bin 0 -> 32948 bytes .../ship-library/assets/portraits/603.webp | Bin 0 -> 32888 bytes .../ship-library/assets/portraits/604.webp | Bin 0 -> 30902 bytes .../ship-library/assets/portraits/605.webp | Bin 0 -> 29760 bytes .../ship-library/assets/portraits/606.webp | Bin 0 -> 26654 bytes .../ship-library/assets/portraits/607.webp | Bin 0 -> 33024 bytes .../ship-library/assets/portraits/608.webp | Bin 0 -> 28424 bytes .../ship-library/assets/portraits/609.webp | Bin 0 -> 34610 bytes .../ship-library/assets/portraits/61.webp | Bin 0 -> 28176 bytes .../ship-library/assets/portraits/610.webp | Bin 0 -> 30726 bytes .../ship-library/assets/portraits/611.webp | Bin 0 -> 31462 bytes .../ship-library/assets/portraits/612.webp | Bin 0 -> 25868 bytes .../ship-library/assets/portraits/613.webp | Bin 0 -> 39128 bytes .../ship-library/assets/portraits/614.webp | Bin 0 -> 31616 bytes .../ship-library/assets/portraits/615.webp | Bin 0 -> 38612 bytes .../ship-library/assets/portraits/616.webp | Bin 0 -> 27424 bytes .../ship-library/assets/portraits/617.webp | Bin 0 -> 30592 bytes .../ship-library/assets/portraits/618.webp | Bin 0 -> 42478 bytes .../ship-library/assets/portraits/619.webp | Bin 0 -> 35188 bytes .../ship-library/assets/portraits/62.webp | Bin 0 -> 25720 bytes .../ship-library/assets/portraits/620.webp | Bin 0 -> 36220 bytes .../ship-library/assets/portraits/621.webp | Bin 0 -> 32154 bytes .../ship-library/assets/portraits/622.webp | Bin 0 -> 33556 bytes .../ship-library/assets/portraits/623.webp | Bin 0 -> 30674 bytes .../ship-library/assets/portraits/624.webp | Bin 0 -> 28862 bytes .../ship-library/assets/portraits/625.webp | Bin 0 -> 27718 bytes .../ship-library/assets/portraits/626.webp | Bin 0 -> 27678 bytes .../ship-library/assets/portraits/627.webp | Bin 0 -> 33330 bytes .../ship-library/assets/portraits/628.webp | Bin 0 -> 29658 bytes .../ship-library/assets/portraits/629.webp | Bin 0 -> 21292 bytes .../ship-library/assets/portraits/63.webp | Bin 0 -> 23992 bytes .../ship-library/assets/portraits/630.webp | Bin 0 -> 39530 bytes .../ship-library/assets/portraits/631.webp | Bin 0 -> 25594 bytes .../ship-library/assets/portraits/632.webp | Bin 0 -> 29774 bytes .../ship-library/assets/portraits/633.webp | Bin 0 -> 29048 bytes .../ship-library/assets/portraits/634.webp | Bin 0 -> 28464 bytes .../ship-library/assets/portraits/635.webp | Bin 0 -> 32166 bytes .../ship-library/assets/portraits/636.webp | Bin 0 -> 30730 bytes .../ship-library/assets/portraits/637.webp | Bin 0 -> 18560 bytes .../ship-library/assets/portraits/638.webp | Bin 0 -> 33298 bytes .../ship-library/assets/portraits/639.webp | Bin 0 -> 26848 bytes .../ship-library/assets/portraits/64.webp | Bin 0 -> 26282 bytes .../ship-library/assets/portraits/640.webp | Bin 0 -> 29062 bytes .../ship-library/assets/portraits/641.webp | Bin 0 -> 28608 bytes .../ship-library/assets/portraits/642.webp | Bin 0 -> 25538 bytes .../ship-library/assets/portraits/643.webp | Bin 0 -> 28040 bytes .../ship-library/assets/portraits/644.webp | Bin 0 -> 34284 bytes .../ship-library/assets/portraits/645.webp | Bin 0 -> 27512 bytes .../ship-library/assets/portraits/646.webp | Bin 0 -> 25890 bytes .../ship-library/assets/portraits/647.webp | Bin 0 -> 22096 bytes .../ship-library/assets/portraits/648.webp | Bin 0 -> 31344 bytes .../ship-library/assets/portraits/649.webp | Bin 0 -> 23704 bytes .../ship-library/assets/portraits/65.webp | Bin 0 -> 30746 bytes .../ship-library/assets/portraits/650.webp | Bin 0 -> 26066 bytes .../ship-library/assets/portraits/651.webp | Bin 0 -> 36054 bytes .../ship-library/assets/portraits/66.webp | Bin 0 -> 24536 bytes .../ship-library/assets/portraits/67.webp | Bin 0 -> 23294 bytes .../ship-library/assets/portraits/68.webp | Bin 0 -> 23474 bytes .../ship-library/assets/portraits/69.webp | Bin 0 -> 20722 bytes resource/ship-library/assets/portraits/7.webp | Bin 0 -> 29254 bytes .../ship-library/assets/portraits/70.webp | Bin 0 -> 21932 bytes .../ship-library/assets/portraits/71.webp | Bin 0 -> 25486 bytes .../ship-library/assets/portraits/72.webp | Bin 0 -> 22164 bytes .../ship-library/assets/portraits/73.webp | Bin 0 -> 23500 bytes .../ship-library/assets/portraits/74.webp | Bin 0 -> 22914 bytes .../ship-library/assets/portraits/75.webp | Bin 0 -> 21944 bytes .../ship-library/assets/portraits/76.webp | Bin 0 -> 23662 bytes .../ship-library/assets/portraits/77.webp | Bin 0 -> 26624 bytes .../ship-library/assets/portraits/78.webp | Bin 0 -> 33520 bytes .../ship-library/assets/portraits/79.webp | Bin 0 -> 33246 bytes resource/ship-library/assets/portraits/8.webp | Bin 0 -> 27466 bytes .../ship-library/assets/portraits/80.webp | Bin 0 -> 35144 bytes .../ship-library/assets/portraits/8007.webp | Bin 0 -> 44416 bytes .../ship-library/assets/portraits/8009.webp | Bin 0 -> 28342 bytes .../ship-library/assets/portraits/81.webp | Bin 0 -> 23444 bytes .../ship-library/assets/portraits/8111.webp | Bin 0 -> 30744 bytes .../ship-library/assets/portraits/8116.webp | Bin 0 -> 41452 bytes .../ship-library/assets/portraits/82.webp | Bin 0 -> 25420 bytes .../ship-library/assets/portraits/83.webp | Bin 0 -> 27496 bytes .../ship-library/assets/portraits/84.webp | Bin 0 -> 29412 bytes .../ship-library/assets/portraits/85.webp | Bin 0 -> 23988 bytes .../ship-library/assets/portraits/86.webp | Bin 0 -> 24408 bytes .../ship-library/assets/portraits/87.webp | Bin 0 -> 22862 bytes .../ship-library/assets/portraits/88.webp | Bin 0 -> 34682 bytes .../ship-library/assets/portraits/89.webp | Bin 0 -> 22034 bytes resource/ship-library/assets/portraits/9.webp | Bin 0 -> 23730 bytes .../ship-library/assets/portraits/90.webp | Bin 0 -> 25486 bytes .../ship-library/assets/portraits/91.webp | Bin 0 -> 33724 bytes .../ship-library/assets/portraits/92.webp | Bin 0 -> 22198 bytes .../ship-library/assets/portraits/93.webp | Bin 0 -> 27778 bytes .../ship-library/assets/portraits/94.webp | Bin 0 -> 26118 bytes .../ship-library/assets/portraits/95.webp | Bin 0 -> 23580 bytes .../ship-library/assets/portraits/96.webp | Bin 0 -> 25520 bytes .../ship-library/assets/portraits/97.webp | Bin 0 -> 20046 bytes .../ship-library/assets/portraits/98.webp | Bin 0 -> 26150 bytes .../ship-library/assets/portraits/99.webp | Bin 0 -> 29844 bytes .../ship-library/assets/type-icons/ap.webp | Bin 0 -> 1484 bytes .../ship-library/assets/type-icons/av.webp | Bin 0 -> 1614 bytes .../ship-library/assets/type-icons/bb.webp | Bin 0 -> 1586 bytes .../ship-library/assets/type-icons/bbg.webp | Bin 0 -> 1782 bytes .../ship-library/assets/type-icons/bbv.webp | Bin 0 -> 1560 bytes .../ship-library/assets/type-icons/bc.webp | Bin 0 -> 1586 bytes .../ship-library/assets/type-icons/bm.webp | Bin 0 -> 1496 bytes .../ship-library/assets/type-icons/ca.webp | Bin 0 -> 1538 bytes .../ship-library/assets/type-icons/cav.webp | Bin 0 -> 1664 bytes .../ship-library/assets/type-icons/cbg.webp | Bin 0 -> 2232 bytes .../ship-library/assets/type-icons/cf.webp | Bin 0 -> 1878 bytes .../ship-library/assets/type-icons/cg.webp | Bin 0 -> 1772 bytes .../ship-library/assets/type-icons/cgaa.webp | Bin 0 -> 1510 bytes .../ship-library/assets/type-icons/cl.webp | Bin 0 -> 1618 bytes .../ship-library/assets/type-icons/clt.webp | Bin 0 -> 1662 bytes .../ship-library/assets/type-icons/cv.webp | Bin 0 -> 1512 bytes .../ship-library/assets/type-icons/cvl.webp | Bin 0 -> 1552 bytes .../ship-library/assets/type-icons/dd.webp | Bin 0 -> 1528 bytes .../ship-library/assets/type-icons/ddg.webp | Bin 0 -> 2612 bytes .../ship-library/assets/type-icons/ddgaa.webp | Bin 0 -> 2580 bytes .../ship-library/assets/type-icons/sc.webp | Bin 0 -> 1580 bytes .../ship-library/assets/type-icons/ss.webp | Bin 0 -> 1536 bytes .../ship-library/assets/type-icons/ssg.webp | Bin 0 -> 1480 bytes resource/ship-library/database/ships.sqlite3 | Bin 0 -> 950272 bytes resource/ship-library/labels.zh-CN.json | 53 + resource/ship-library/manifest.json | 14436 ++++++++++++++++ .../bettle-\345\221\250\345\270\270-1-1.yaml" | 90 + ...bettle-\345\221\250\345\270\270-10-1.yaml" | 78 + .../bettle-\345\221\250\345\270\270-2-1.yaml" | 91 + .../bettle-\345\221\250\345\270\270-3-1.yaml" | 83 + .../bettle-\345\221\250\345\270\270-4-1.yaml" | 49 + .../bettle-\345\221\250\345\270\270-5-5.yaml" | 89 + .../bettle-\345\221\250\345\270\270-6-4.yaml" | 62 + .../bettle-\345\221\250\345\270\270-7-4.yaml" | 89 + .../bettle-\345\221\250\345\270\270-8-2.yaml" | 41 + .../bettle-\345\221\250\345\270\270-9-2.yaml" | 72 + resource/system_team_plans/.gitkeep | 1 + ...\345\267\245\347\250\213\351\230\237.yaml" | 47 + ...\345\221\250\345\270\270\351\230\237.yaml" | 38 + ...\345\221\250\345\270\270\351\230\237.yaml" | 38 + ...\346\227\245\351\251\261\351\230\237.yaml" | 68 + ...\346\275\234\350\211\207\351\230\237.yaml" | 74 + ...\351\230\262\351\251\261\351\230\237.yaml" | 52 + ...\345\276\267\351\251\261\351\230\237.yaml" | 34 + ...44\247\346\267\20085AIII\351\230\237.yaml" | 26 + ...\345\221\250\345\270\270\351\230\237.yaml" | 59 + resource/user_team_plans/.gitkeep | 1 + scripts/prepare-python.js | 43 +- scripts/test-legacy-plan-conversion.js | 381 + scripts/test-settings-persistence.js | 525 + src/controller/app/AppController.ts | 367 +- src/controller/app/ConfigController.ts | 188 +- src/controller/app/SchedulerBinder.ts | 130 +- src/controller/app/rendering.ts | 63 +- src/controller/app/theme.ts | 48 +- src/controller/plan/PlanController.ts | 1159 +- src/controller/plan/importExport.ts | 48 - src/controller/plan/nodeEditor.ts | 27 +- src/controller/plan/presetFlow.ts | 2 +- src/controller/plan/rendering.ts | 13 +- src/controller/shared/DialogHelper.ts | 41 +- src/controller/shared/index.ts | 7 +- src/controller/startup/connection.ts | 7 +- .../taskGroup/TaskGroupController.ts | 113 +- .../taskGroup/TaskListLoaderController.ts | 335 + src/controller/taskGroup/addItems.ts | 22 + src/controller/taskGroup/contextMenu.ts | 10 + src/controller/taskGroup/importExport.ts | 24 +- src/controller/taskGroup/managedPlanReader.ts | 50 + src/controller/taskGroup/metaLoader.ts | 19 +- src/controller/taskGroup/queueLoader.ts | 138 +- src/controller/template/TemplateController.ts | 9 +- src/controller/template/selectors.ts | 80 +- src/controller/template/useTemplate.ts | 2 - src/controller/template/wizard.ts | 28 +- src/data/shipData.ts | 70 +- src/model/ApiClient.ts | 44 +- src/model/ConfigModel.ts | 415 +- src/model/PlanModel.ts | 402 +- src/model/TaskGroupModel.ts | 16 +- src/model/TemplateModel.ts | 14 +- src/model/scheduler/CronScheduler.ts | 19 +- src/model/scheduler/Scheduler.ts | 205 +- src/model/scheduler/TaskQueue.ts | 16 +- src/types/api.ts | 17 +- src/types/electronBridge.ts | 291 +- src/types/model.ts | 112 +- src/types/scheduler.ts | 11 +- src/types/view.ts | 41 +- src/utils/Logger.ts | 3 +- src/view/config/ConfigView.ts | 533 +- src/view/index.html | 1991 ++- src/view/main/FleetPreviewView.ts | 122 + src/view/main/LogView.ts | 4 +- src/view/main/MainView.ts | 4 + src/view/main/StatusBar.ts | 34 + src/view/main/TaskQueueView.ts | 104 +- src/view/plan/DecisivePlanView.ts | 1222 ++ src/view/plan/FleetEditDialog.ts | 69 +- src/view/plan/FleetPlannerView.ts | 3320 ++++ src/view/plan/FleetPresetView.ts | 809 +- src/view/plan/MapView.ts | 62 +- src/view/plan/NodeEditorView.ts | 156 +- src/view/plan/PlanPreviewView.ts | 307 +- src/view/plan/ShipArtwork.ts | 72 + src/view/plan/TeamPlanListUi.ts | 134 + src/view/shared/scrollPosition.ts | 26 + src/view/styles/base/_base.scss | 44 +- src/view/styles/base/_variables.scss | 86 +- src/view/styles/components/_autocomplete.scss | 6 +- src/view/styles/components/_buttons.scss | 6 +- src/view/styles/components/_forms.scss | 9 +- src/view/styles/components/_modal.scss | 5 +- src/view/styles/components/_nav.scss | 184 +- src/view/styles/components/_save-notice.scss | 50 + src/view/styles/components/_task-group.scss | 394 +- src/view/styles/components/_template.scss | 4 +- src/view/styles/main.scss | 2 + src/view/styles/pages/_config.scss | 737 +- src/view/styles/pages/main-page/_layout.scss | 137 +- src/view/styles/pages/main-page/_log.scss | 13 +- .../styles/pages/main-page/_task-queue.scss | 65 +- .../styles/pages/plan/_decisive-plan.scss | 168 + .../styles/pages/plan/_fleet-planner.scss | 1990 +++ src/view/styles/pages/plan/_fleet-preset.scss | 570 +- src/view/styles/pages/plan/_header.scss | 131 +- src/view/styles/pages/plan/_index.scss | 2 + src/view/styles/pages/plan/_layout.scss | 107 +- src/view/styles/pages/plan/_node-editor.scss | 211 +- src/view/styles/pages/plan/_node-map.scss | 27 +- src/view/styles/pages/plan/_task-config.scss | 344 +- src/view/styles/styles.css | 6468 +++++-- src/view/styles/themes/_light.scss | 187 + src/view/taskGroup/TaskGroupView.ts | 173 +- src/view/template/TemplateLibraryView.ts | 7 +- src/view/template/TemplateWizardView.ts | 3 +- ...\346\210\230\351\205\215\347\275\256.json" | 11 - ...\350\247\204\345\207\272\345\207\273.json" | 17 - ...\345\270\270\346\210\230\345\275\271.json" | 32 - ...\345\212\250\346\274\224\344\271\240.json" | 8 - tools/ship_library/update_ship_library.py | 1014 ++ 1095 files changed, 44553 insertions(+), 4245 deletions(-) delete mode 100644 .tmp_issue360.json delete mode 100644 .tmp_issue360_comments.json delete mode 100644 .tmp_issue372.json delete mode 100644 .tmp_issue372_comments.json delete mode 100644 .tmp_runs.json delete mode 100644 .tmp_weekly_fix.ps1 create mode 100644 docs/features/gui-2.0.md create mode 100644 docs/reviews/2026-08-03-workspace-review-pending.md delete mode 100644 "resource/builtin_plans/\345\206\263\346\210\230.yaml" delete mode 100644 "resource/builtin_plans/\345\221\250\345\270\27010\347\253\240-10-1.yaml" delete mode 100644 "resource/builtin_plans/\345\221\250\345\270\2701\347\253\240-1-5.yaml" delete mode 100644 "resource/builtin_plans/\345\221\250\345\270\2702\347\253\240-2-1.yaml" delete mode 100644 "resource/builtin_plans/\345\221\250\345\270\2703\347\253\240-3-1.yaml" delete mode 100644 "resource/builtin_plans/\345\221\250\345\270\2703\347\253\240-3-3.yaml" delete mode 100644 "resource/builtin_plans/\345\221\250\345\270\2704\347\253\240-4-1.yaml" delete mode 100644 "resource/builtin_plans/\345\221\250\345\270\2705\347\253\240-5-5.yaml" delete mode 100644 "resource/builtin_plans/\345\221\250\345\270\2706\347\253\240-6-3.yaml" delete mode 100644 "resource/builtin_plans/\345\221\250\345\270\2706\347\253\240-6-4.yaml" delete mode 100644 "resource/builtin_plans/\345\221\250\345\270\2707\347\253\240-7-4.yaml" delete mode 100644 "resource/builtin_plans/\345\221\250\345\270\2708\347\253\240-8-2.yaml" delete mode 100644 "resource/builtin_plans/\345\221\250\345\270\2709\347\253\240-9-2.yaml" delete mode 100644 "resource/builtin_plans/\346\210\230\345\275\271.yaml" delete mode 100644 "resource/builtin_plans/\346\215\236\350\203\226\346\254\2412-1.yaml" delete mode 100644 "resource/builtin_plans/\346\215\236\350\203\226\346\254\2417-4.yaml" delete mode 100644 "resource/builtin_plans/\346\215\236\350\203\226\346\254\2418-5.yaml" delete mode 100644 "resource/builtin_plans/\346\215\236\350\203\226\346\254\2419-2.yaml" delete mode 100644 "resource/builtin_plans/\346\264\273\345\212\25020260730-E1\347\202\270\351\261\274.yaml" delete mode 100644 "resource/builtin_plans/\346\264\273\345\212\25020260730-E5\345\244\234\346\210\230.yaml" delete mode 100644 "resource/builtin_plans/\346\264\273\345\212\25020260730-H1\347\202\270\351\261\274.yaml" delete mode 100644 "resource/builtin_plans/\346\264\273\345\212\25020260730-H5\345\244\234\346\210\230.yaml" delete mode 100644 "resource/builtin_plans/\350\207\252\345\212\250\346\274\224\344\271\240.yaml" create mode 100644 resource/ship-library/assets/backgrounds/rarity-1.webp create mode 100644 resource/ship-library/assets/backgrounds/rarity-2.webp create mode 100644 resource/ship-library/assets/backgrounds/rarity-3.webp create mode 100644 resource/ship-library/assets/backgrounds/rarity-4.webp create mode 100644 resource/ship-library/assets/backgrounds/rarity-5.webp create mode 100644 resource/ship-library/assets/backgrounds/rarity-6.webp create mode 100644 resource/ship-library/assets/frames/rarity-1.webp create mode 100644 resource/ship-library/assets/frames/rarity-2.webp create mode 100644 resource/ship-library/assets/frames/rarity-3.webp create mode 100644 resource/ship-library/assets/frames/rarity-4.webp create mode 100644 resource/ship-library/assets/frames/rarity-5.webp create mode 100644 resource/ship-library/assets/frames/rarity-6.webp create mode 100644 resource/ship-library/assets/portraits/1.webp create mode 100644 resource/ship-library/assets/portraits/10.webp create mode 100644 resource/ship-library/assets/portraits/100.webp create mode 100644 resource/ship-library/assets/portraits/1001.webp create mode 100644 resource/ship-library/assets/portraits/1002.webp create mode 100644 resource/ship-library/assets/portraits/1003.webp create mode 100644 resource/ship-library/assets/portraits/1004.webp create mode 100644 resource/ship-library/assets/portraits/1005.webp create mode 100644 resource/ship-library/assets/portraits/1006.webp create mode 100644 resource/ship-library/assets/portraits/1007.webp create mode 100644 resource/ship-library/assets/portraits/1008.webp create mode 100644 resource/ship-library/assets/portraits/1009.webp create mode 100644 resource/ship-library/assets/portraits/101.webp create mode 100644 resource/ship-library/assets/portraits/1010.webp create mode 100644 resource/ship-library/assets/portraits/1011.webp create mode 100644 resource/ship-library/assets/portraits/1012.webp create mode 100644 resource/ship-library/assets/portraits/1013.webp create mode 100644 resource/ship-library/assets/portraits/1014.webp create mode 100644 resource/ship-library/assets/portraits/1018.webp create mode 100644 resource/ship-library/assets/portraits/1019.webp create mode 100644 resource/ship-library/assets/portraits/102.webp create mode 100644 resource/ship-library/assets/portraits/1020.webp create mode 100644 resource/ship-library/assets/portraits/1021.webp create mode 100644 resource/ship-library/assets/portraits/1022.webp create mode 100644 resource/ship-library/assets/portraits/1023.webp create mode 100644 resource/ship-library/assets/portraits/1024.webp create mode 100644 resource/ship-library/assets/portraits/1025.webp create mode 100644 resource/ship-library/assets/portraits/1026.webp create mode 100644 resource/ship-library/assets/portraits/1027.webp create mode 100644 resource/ship-library/assets/portraits/1028.webp create mode 100644 resource/ship-library/assets/portraits/1029.webp create mode 100644 resource/ship-library/assets/portraits/103.webp create mode 100644 resource/ship-library/assets/portraits/1030.webp create mode 100644 resource/ship-library/assets/portraits/1031.webp create mode 100644 resource/ship-library/assets/portraits/1032.webp create mode 100644 resource/ship-library/assets/portraits/1033.webp create mode 100644 resource/ship-library/assets/portraits/1034.webp create mode 100644 resource/ship-library/assets/portraits/1035.webp create mode 100644 resource/ship-library/assets/portraits/1036.webp create mode 100644 resource/ship-library/assets/portraits/1037.webp create mode 100644 resource/ship-library/assets/portraits/1038.webp create mode 100644 resource/ship-library/assets/portraits/1039.webp create mode 100644 resource/ship-library/assets/portraits/104.webp create mode 100644 resource/ship-library/assets/portraits/1040.webp create mode 100644 resource/ship-library/assets/portraits/1041.webp create mode 100644 resource/ship-library/assets/portraits/1042.webp create mode 100644 resource/ship-library/assets/portraits/1043.webp create mode 100644 resource/ship-library/assets/portraits/1044.webp create mode 100644 resource/ship-library/assets/portraits/1045.webp create mode 100644 resource/ship-library/assets/portraits/1046.webp create mode 100644 resource/ship-library/assets/portraits/1047.webp create mode 100644 resource/ship-library/assets/portraits/1048.webp create mode 100644 resource/ship-library/assets/portraits/1049.webp create mode 100644 resource/ship-library/assets/portraits/105.webp create mode 100644 resource/ship-library/assets/portraits/1050.webp create mode 100644 resource/ship-library/assets/portraits/1054.webp create mode 100644 resource/ship-library/assets/portraits/1055.webp create mode 100644 resource/ship-library/assets/portraits/1056.webp create mode 100644 resource/ship-library/assets/portraits/1057.webp create mode 100644 resource/ship-library/assets/portraits/1058.webp create mode 100644 resource/ship-library/assets/portraits/1059.webp create mode 100644 resource/ship-library/assets/portraits/106.webp create mode 100644 resource/ship-library/assets/portraits/1060.webp create mode 100644 resource/ship-library/assets/portraits/1061.webp create mode 100644 resource/ship-library/assets/portraits/1062.webp create mode 100644 resource/ship-library/assets/portraits/1063.webp create mode 100644 resource/ship-library/assets/portraits/1064.webp create mode 100644 resource/ship-library/assets/portraits/1065.webp create mode 100644 resource/ship-library/assets/portraits/1066.webp create mode 100644 resource/ship-library/assets/portraits/1067.webp create mode 100644 resource/ship-library/assets/portraits/1068.webp create mode 100644 resource/ship-library/assets/portraits/1069.webp create mode 100644 resource/ship-library/assets/portraits/107.webp create mode 100644 resource/ship-library/assets/portraits/1070.webp create mode 100644 resource/ship-library/assets/portraits/1071.webp create mode 100644 resource/ship-library/assets/portraits/1072.webp create mode 100644 resource/ship-library/assets/portraits/1073.webp create mode 100644 resource/ship-library/assets/portraits/1074.webp create mode 100644 resource/ship-library/assets/portraits/1075.webp create mode 100644 resource/ship-library/assets/portraits/1076.webp create mode 100644 resource/ship-library/assets/portraits/1077.webp create mode 100644 resource/ship-library/assets/portraits/1079.webp create mode 100644 resource/ship-library/assets/portraits/108.webp create mode 100644 resource/ship-library/assets/portraits/1080.webp create mode 100644 resource/ship-library/assets/portraits/1081.webp create mode 100644 resource/ship-library/assets/portraits/1082.webp create mode 100644 resource/ship-library/assets/portraits/1083.webp create mode 100644 resource/ship-library/assets/portraits/1084.webp create mode 100644 resource/ship-library/assets/portraits/1085.webp create mode 100644 resource/ship-library/assets/portraits/1086.webp create mode 100644 resource/ship-library/assets/portraits/1087.webp create mode 100644 resource/ship-library/assets/portraits/1088.webp create mode 100644 resource/ship-library/assets/portraits/1089.webp create mode 100644 resource/ship-library/assets/portraits/109.webp create mode 100644 resource/ship-library/assets/portraits/1092.webp create mode 100644 resource/ship-library/assets/portraits/1093.webp create mode 100644 resource/ship-library/assets/portraits/1094.webp create mode 100644 resource/ship-library/assets/portraits/1097.webp create mode 100644 resource/ship-library/assets/portraits/1098.webp create mode 100644 resource/ship-library/assets/portraits/1099.webp create mode 100644 resource/ship-library/assets/portraits/11.webp create mode 100644 resource/ship-library/assets/portraits/110.webp create mode 100644 resource/ship-library/assets/portraits/1100.webp create mode 100644 resource/ship-library/assets/portraits/1101.webp create mode 100644 resource/ship-library/assets/portraits/1102.webp create mode 100644 resource/ship-library/assets/portraits/1105.webp create mode 100644 resource/ship-library/assets/portraits/1106.webp create mode 100644 resource/ship-library/assets/portraits/1107.webp create mode 100644 resource/ship-library/assets/portraits/1108.webp create mode 100644 resource/ship-library/assets/portraits/1109.webp create mode 100644 resource/ship-library/assets/portraits/111.webp create mode 100644 resource/ship-library/assets/portraits/1110.webp create mode 100644 resource/ship-library/assets/portraits/1111.webp create mode 100644 resource/ship-library/assets/portraits/1112.webp create mode 100644 resource/ship-library/assets/portraits/1113.webp create mode 100644 resource/ship-library/assets/portraits/1117.webp create mode 100644 resource/ship-library/assets/portraits/1118.webp create mode 100644 resource/ship-library/assets/portraits/112.webp create mode 100644 resource/ship-library/assets/portraits/1120.webp create mode 100644 resource/ship-library/assets/portraits/1121.webp create mode 100644 resource/ship-library/assets/portraits/1123.webp create mode 100644 resource/ship-library/assets/portraits/1124.webp create mode 100644 resource/ship-library/assets/portraits/1125.webp create mode 100644 resource/ship-library/assets/portraits/1126.webp create mode 100644 resource/ship-library/assets/portraits/113.webp create mode 100644 resource/ship-library/assets/portraits/1130.webp create mode 100644 resource/ship-library/assets/portraits/1131.webp create mode 100644 resource/ship-library/assets/portraits/1132.webp create mode 100644 resource/ship-library/assets/portraits/1133.webp create mode 100644 resource/ship-library/assets/portraits/1135.webp create mode 100644 resource/ship-library/assets/portraits/1136.webp create mode 100644 resource/ship-library/assets/portraits/1137.webp create mode 100644 resource/ship-library/assets/portraits/1139.webp create mode 100644 resource/ship-library/assets/portraits/114.webp create mode 100644 resource/ship-library/assets/portraits/1141.webp create mode 100644 resource/ship-library/assets/portraits/1142.webp create mode 100644 resource/ship-library/assets/portraits/1143.webp create mode 100644 resource/ship-library/assets/portraits/1145.webp create mode 100644 resource/ship-library/assets/portraits/1149.webp create mode 100644 resource/ship-library/assets/portraits/115.webp create mode 100644 resource/ship-library/assets/portraits/1150.webp create mode 100644 resource/ship-library/assets/portraits/1151.webp create mode 100644 resource/ship-library/assets/portraits/1158.webp create mode 100644 resource/ship-library/assets/portraits/1160.webp create mode 100644 resource/ship-library/assets/portraits/1162.webp create mode 100644 resource/ship-library/assets/portraits/1164.webp create mode 100644 resource/ship-library/assets/portraits/1165.webp create mode 100644 resource/ship-library/assets/portraits/1166.webp create mode 100644 resource/ship-library/assets/portraits/1167.webp create mode 100644 resource/ship-library/assets/portraits/1168.webp create mode 100644 resource/ship-library/assets/portraits/1169.webp create mode 100644 resource/ship-library/assets/portraits/117.webp create mode 100644 resource/ship-library/assets/portraits/1171.webp create mode 100644 resource/ship-library/assets/portraits/1175.webp create mode 100644 resource/ship-library/assets/portraits/1178.webp create mode 100644 resource/ship-library/assets/portraits/118.webp create mode 100644 resource/ship-library/assets/portraits/1181.webp create mode 100644 resource/ship-library/assets/portraits/1182.webp create mode 100644 resource/ship-library/assets/portraits/1183.webp create mode 100644 resource/ship-library/assets/portraits/1185.webp create mode 100644 resource/ship-library/assets/portraits/1187.webp create mode 100644 resource/ship-library/assets/portraits/1188.webp create mode 100644 resource/ship-library/assets/portraits/119.webp create mode 100644 resource/ship-library/assets/portraits/1192.webp create mode 100644 resource/ship-library/assets/portraits/1194.webp create mode 100644 resource/ship-library/assets/portraits/1195.webp create mode 100644 resource/ship-library/assets/portraits/1197.webp create mode 100644 resource/ship-library/assets/portraits/1198.webp create mode 100644 resource/ship-library/assets/portraits/1199.webp create mode 100644 resource/ship-library/assets/portraits/12.webp create mode 100644 resource/ship-library/assets/portraits/120.webp create mode 100644 resource/ship-library/assets/portraits/1205.webp create mode 100644 resource/ship-library/assets/portraits/1206.webp create mode 100644 resource/ship-library/assets/portraits/1207.webp create mode 100644 resource/ship-library/assets/portraits/1209.webp create mode 100644 resource/ship-library/assets/portraits/121.webp create mode 100644 resource/ship-library/assets/portraits/1211.webp create mode 100644 resource/ship-library/assets/portraits/1215.webp create mode 100644 resource/ship-library/assets/portraits/1219.webp create mode 100644 resource/ship-library/assets/portraits/122.webp create mode 100644 resource/ship-library/assets/portraits/1220.webp create mode 100644 resource/ship-library/assets/portraits/1221.webp create mode 100644 resource/ship-library/assets/portraits/1222.webp create mode 100644 resource/ship-library/assets/portraits/1223.webp create mode 100644 resource/ship-library/assets/portraits/1224.webp create mode 100644 resource/ship-library/assets/portraits/1225.webp create mode 100644 resource/ship-library/assets/portraits/1227.webp create mode 100644 resource/ship-library/assets/portraits/1228.webp create mode 100644 resource/ship-library/assets/portraits/123.webp create mode 100644 resource/ship-library/assets/portraits/1232.webp create mode 100644 resource/ship-library/assets/portraits/1233.webp create mode 100644 resource/ship-library/assets/portraits/1238.webp create mode 100644 resource/ship-library/assets/portraits/1239.webp create mode 100644 resource/ship-library/assets/portraits/124.webp create mode 100644 resource/ship-library/assets/portraits/1240.webp create mode 100644 resource/ship-library/assets/portraits/1241.webp create mode 100644 resource/ship-library/assets/portraits/1244.webp create mode 100644 resource/ship-library/assets/portraits/1247.webp create mode 100644 resource/ship-library/assets/portraits/1248.webp create mode 100644 resource/ship-library/assets/portraits/1249.webp create mode 100644 resource/ship-library/assets/portraits/125.webp create mode 100644 resource/ship-library/assets/portraits/1258.webp create mode 100644 resource/ship-library/assets/portraits/126.webp create mode 100644 resource/ship-library/assets/portraits/1265.webp create mode 100644 resource/ship-library/assets/portraits/1266.webp create mode 100644 resource/ship-library/assets/portraits/1267.webp create mode 100644 resource/ship-library/assets/portraits/1269.webp create mode 100644 resource/ship-library/assets/portraits/127.webp create mode 100644 resource/ship-library/assets/portraits/1270.webp create mode 100644 resource/ship-library/assets/portraits/1273.webp create mode 100644 resource/ship-library/assets/portraits/1275.webp create mode 100644 resource/ship-library/assets/portraits/1277.webp create mode 100644 resource/ship-library/assets/portraits/1278.webp create mode 100644 resource/ship-library/assets/portraits/1279.webp create mode 100644 resource/ship-library/assets/portraits/128.webp create mode 100644 resource/ship-library/assets/portraits/1280.webp create mode 100644 resource/ship-library/assets/portraits/1289.webp create mode 100644 resource/ship-library/assets/portraits/129.webp create mode 100644 resource/ship-library/assets/portraits/1290.webp create mode 100644 resource/ship-library/assets/portraits/1291.webp create mode 100644 resource/ship-library/assets/portraits/1293.webp create mode 100644 resource/ship-library/assets/portraits/1299.webp create mode 100644 resource/ship-library/assets/portraits/13.webp create mode 100644 resource/ship-library/assets/portraits/130.webp create mode 100644 resource/ship-library/assets/portraits/1301.webp create mode 100644 resource/ship-library/assets/portraits/1306.webp create mode 100644 resource/ship-library/assets/portraits/131.webp create mode 100644 resource/ship-library/assets/portraits/1311.webp create mode 100644 resource/ship-library/assets/portraits/1316.webp create mode 100644 resource/ship-library/assets/portraits/132.webp create mode 100644 resource/ship-library/assets/portraits/1323.webp create mode 100644 resource/ship-library/assets/portraits/1325.webp create mode 100644 resource/ship-library/assets/portraits/133.webp create mode 100644 resource/ship-library/assets/portraits/1332.webp create mode 100644 resource/ship-library/assets/portraits/1335.webp create mode 100644 resource/ship-library/assets/portraits/1339.webp create mode 100644 resource/ship-library/assets/portraits/134.webp create mode 100644 resource/ship-library/assets/portraits/1340.webp create mode 100644 resource/ship-library/assets/portraits/1342.webp create mode 100644 resource/ship-library/assets/portraits/1343.webp create mode 100644 resource/ship-library/assets/portraits/1344.webp create mode 100644 resource/ship-library/assets/portraits/135.webp create mode 100644 resource/ship-library/assets/portraits/1351.webp create mode 100644 resource/ship-library/assets/portraits/136.webp create mode 100644 resource/ship-library/assets/portraits/1362.webp create mode 100644 resource/ship-library/assets/portraits/1363.webp create mode 100644 resource/ship-library/assets/portraits/1366.webp create mode 100644 resource/ship-library/assets/portraits/137.webp create mode 100644 resource/ship-library/assets/portraits/1372.webp create mode 100644 resource/ship-library/assets/portraits/138.webp create mode 100644 resource/ship-library/assets/portraits/1380.webp create mode 100644 resource/ship-library/assets/portraits/139.webp create mode 100644 resource/ship-library/assets/portraits/14.webp create mode 100644 resource/ship-library/assets/portraits/140.webp create mode 100644 resource/ship-library/assets/portraits/1400.webp create mode 100644 resource/ship-library/assets/portraits/1408.webp create mode 100644 resource/ship-library/assets/portraits/141.webp create mode 100644 resource/ship-library/assets/portraits/1413.webp create mode 100644 resource/ship-library/assets/portraits/1414.webp create mode 100644 resource/ship-library/assets/portraits/1416.webp create mode 100644 resource/ship-library/assets/portraits/142.webp create mode 100644 resource/ship-library/assets/portraits/1425.webp create mode 100644 resource/ship-library/assets/portraits/1426.webp create mode 100644 resource/ship-library/assets/portraits/1429.webp create mode 100644 resource/ship-library/assets/portraits/143.webp create mode 100644 resource/ship-library/assets/portraits/1430.webp create mode 100644 resource/ship-library/assets/portraits/1431.webp create mode 100644 resource/ship-library/assets/portraits/144.webp create mode 100644 resource/ship-library/assets/portraits/145.webp create mode 100644 resource/ship-library/assets/portraits/1456.webp create mode 100644 resource/ship-library/assets/portraits/146.webp create mode 100644 resource/ship-library/assets/portraits/1467.webp create mode 100644 resource/ship-library/assets/portraits/147.webp create mode 100644 resource/ship-library/assets/portraits/148.webp create mode 100644 resource/ship-library/assets/portraits/1483.webp create mode 100644 resource/ship-library/assets/portraits/149.webp create mode 100644 resource/ship-library/assets/portraits/1490.webp create mode 100644 resource/ship-library/assets/portraits/1496.webp create mode 100644 resource/ship-library/assets/portraits/15.webp create mode 100644 resource/ship-library/assets/portraits/150.webp create mode 100644 resource/ship-library/assets/portraits/1503.webp create mode 100644 resource/ship-library/assets/portraits/1509.webp create mode 100644 resource/ship-library/assets/portraits/151.webp create mode 100644 resource/ship-library/assets/portraits/1516.webp create mode 100644 resource/ship-library/assets/portraits/1517.webp create mode 100644 resource/ship-library/assets/portraits/1519.webp create mode 100644 resource/ship-library/assets/portraits/152.webp create mode 100644 resource/ship-library/assets/portraits/1527.webp create mode 100644 resource/ship-library/assets/portraits/1528.webp create mode 100644 resource/ship-library/assets/portraits/153.webp create mode 100644 resource/ship-library/assets/portraits/1530.webp create mode 100644 resource/ship-library/assets/portraits/1532.webp create mode 100644 resource/ship-library/assets/portraits/1538.webp create mode 100644 resource/ship-library/assets/portraits/154.webp create mode 100644 resource/ship-library/assets/portraits/1545.webp create mode 100644 resource/ship-library/assets/portraits/155.webp create mode 100644 resource/ship-library/assets/portraits/156.webp create mode 100644 resource/ship-library/assets/portraits/1560.webp create mode 100644 resource/ship-library/assets/portraits/157.webp create mode 100644 resource/ship-library/assets/portraits/1575.webp create mode 100644 resource/ship-library/assets/portraits/158.webp create mode 100644 resource/ship-library/assets/portraits/1583.webp create mode 100644 resource/ship-library/assets/portraits/1589.webp create mode 100644 resource/ship-library/assets/portraits/159.webp create mode 100644 resource/ship-library/assets/portraits/1590.webp create mode 100644 resource/ship-library/assets/portraits/16.webp create mode 100644 resource/ship-library/assets/portraits/160.webp create mode 100644 resource/ship-library/assets/portraits/1606.webp create mode 100644 resource/ship-library/assets/portraits/161.webp create mode 100644 resource/ship-library/assets/portraits/1618.webp create mode 100644 resource/ship-library/assets/portraits/162.webp create mode 100644 resource/ship-library/assets/portraits/163.webp create mode 100644 resource/ship-library/assets/portraits/164.webp create mode 100644 resource/ship-library/assets/portraits/165.webp create mode 100644 resource/ship-library/assets/portraits/166.webp create mode 100644 resource/ship-library/assets/portraits/167.webp create mode 100644 resource/ship-library/assets/portraits/168.webp create mode 100644 resource/ship-library/assets/portraits/169.webp create mode 100644 resource/ship-library/assets/portraits/17.webp create mode 100644 resource/ship-library/assets/portraits/170.webp create mode 100644 resource/ship-library/assets/portraits/171.webp create mode 100644 resource/ship-library/assets/portraits/172.webp create mode 100644 resource/ship-library/assets/portraits/173.webp create mode 100644 resource/ship-library/assets/portraits/174.webp create mode 100644 resource/ship-library/assets/portraits/175.webp create mode 100644 resource/ship-library/assets/portraits/176.webp create mode 100644 resource/ship-library/assets/portraits/177.webp create mode 100644 resource/ship-library/assets/portraits/178.webp create mode 100644 resource/ship-library/assets/portraits/179.webp create mode 100644 resource/ship-library/assets/portraits/18.webp create mode 100644 resource/ship-library/assets/portraits/180.webp create mode 100644 resource/ship-library/assets/portraits/181.webp create mode 100644 resource/ship-library/assets/portraits/182.webp create mode 100644 resource/ship-library/assets/portraits/183.webp create mode 100644 resource/ship-library/assets/portraits/184.webp create mode 100644 resource/ship-library/assets/portraits/185.webp create mode 100644 resource/ship-library/assets/portraits/186.webp create mode 100644 resource/ship-library/assets/portraits/187.webp create mode 100644 resource/ship-library/assets/portraits/188.webp create mode 100644 resource/ship-library/assets/portraits/189.webp create mode 100644 resource/ship-library/assets/portraits/19.webp create mode 100644 resource/ship-library/assets/portraits/190.webp create mode 100644 resource/ship-library/assets/portraits/191.webp create mode 100644 resource/ship-library/assets/portraits/192.webp create mode 100644 resource/ship-library/assets/portraits/193.webp create mode 100644 resource/ship-library/assets/portraits/194.webp create mode 100644 resource/ship-library/assets/portraits/195.webp create mode 100644 resource/ship-library/assets/portraits/196.webp create mode 100644 resource/ship-library/assets/portraits/197.webp create mode 100644 resource/ship-library/assets/portraits/198.webp create mode 100644 resource/ship-library/assets/portraits/199.webp create mode 100644 resource/ship-library/assets/portraits/2.webp create mode 100644 resource/ship-library/assets/portraits/20.webp create mode 100644 resource/ship-library/assets/portraits/200.webp create mode 100644 resource/ship-library/assets/portraits/201.webp create mode 100644 resource/ship-library/assets/portraits/202.webp create mode 100644 resource/ship-library/assets/portraits/203.webp create mode 100644 resource/ship-library/assets/portraits/205.webp create mode 100644 resource/ship-library/assets/portraits/206.webp create mode 100644 resource/ship-library/assets/portraits/207.webp create mode 100644 resource/ship-library/assets/portraits/208.webp create mode 100644 resource/ship-library/assets/portraits/209.webp create mode 100644 resource/ship-library/assets/portraits/21.webp create mode 100644 resource/ship-library/assets/portraits/210.webp create mode 100644 resource/ship-library/assets/portraits/211.webp create mode 100644 resource/ship-library/assets/portraits/212.webp create mode 100644 resource/ship-library/assets/portraits/213.webp create mode 100644 resource/ship-library/assets/portraits/214.webp create mode 100644 resource/ship-library/assets/portraits/215.webp create mode 100644 resource/ship-library/assets/portraits/216.webp create mode 100644 resource/ship-library/assets/portraits/217.webp create mode 100644 resource/ship-library/assets/portraits/218.webp create mode 100644 resource/ship-library/assets/portraits/219.webp create mode 100644 resource/ship-library/assets/portraits/22.webp create mode 100644 resource/ship-library/assets/portraits/220.webp create mode 100644 resource/ship-library/assets/portraits/221.webp create mode 100644 resource/ship-library/assets/portraits/222.webp create mode 100644 resource/ship-library/assets/portraits/223.webp create mode 100644 resource/ship-library/assets/portraits/224.webp create mode 100644 resource/ship-library/assets/portraits/225.webp create mode 100644 resource/ship-library/assets/portraits/226.webp create mode 100644 resource/ship-library/assets/portraits/227.webp create mode 100644 resource/ship-library/assets/portraits/228.webp create mode 100644 resource/ship-library/assets/portraits/229.webp create mode 100644 resource/ship-library/assets/portraits/23.webp create mode 100644 resource/ship-library/assets/portraits/230.webp create mode 100644 resource/ship-library/assets/portraits/231.webp create mode 100644 resource/ship-library/assets/portraits/232.webp create mode 100644 resource/ship-library/assets/portraits/233.webp create mode 100644 resource/ship-library/assets/portraits/234.webp create mode 100644 resource/ship-library/assets/portraits/235.webp create mode 100644 resource/ship-library/assets/portraits/236.webp create mode 100644 resource/ship-library/assets/portraits/237.webp create mode 100644 resource/ship-library/assets/portraits/238.webp create mode 100644 resource/ship-library/assets/portraits/239.webp create mode 100644 resource/ship-library/assets/portraits/24.webp create mode 100644 resource/ship-library/assets/portraits/240.webp create mode 100644 resource/ship-library/assets/portraits/241.webp create mode 100644 resource/ship-library/assets/portraits/242.webp create mode 100644 resource/ship-library/assets/portraits/243.webp create mode 100644 resource/ship-library/assets/portraits/244.webp create mode 100644 resource/ship-library/assets/portraits/245.webp create mode 100644 resource/ship-library/assets/portraits/246.webp create mode 100644 resource/ship-library/assets/portraits/247.webp create mode 100644 resource/ship-library/assets/portraits/248.webp create mode 100644 resource/ship-library/assets/portraits/249.webp create mode 100644 resource/ship-library/assets/portraits/25.webp create mode 100644 resource/ship-library/assets/portraits/250.webp create mode 100644 resource/ship-library/assets/portraits/251.webp create mode 100644 resource/ship-library/assets/portraits/252.webp create mode 100644 resource/ship-library/assets/portraits/253.webp create mode 100644 resource/ship-library/assets/portraits/254.webp create mode 100644 resource/ship-library/assets/portraits/255.webp create mode 100644 resource/ship-library/assets/portraits/256.webp create mode 100644 resource/ship-library/assets/portraits/257.webp create mode 100644 resource/ship-library/assets/portraits/258.webp create mode 100644 resource/ship-library/assets/portraits/259.webp create mode 100644 resource/ship-library/assets/portraits/26.webp create mode 100644 resource/ship-library/assets/portraits/260.webp create mode 100644 resource/ship-library/assets/portraits/261.webp create mode 100644 resource/ship-library/assets/portraits/262.webp create mode 100644 resource/ship-library/assets/portraits/263.webp create mode 100644 resource/ship-library/assets/portraits/264.webp create mode 100644 resource/ship-library/assets/portraits/265.webp create mode 100644 resource/ship-library/assets/portraits/266.webp create mode 100644 resource/ship-library/assets/portraits/267.webp create mode 100644 resource/ship-library/assets/portraits/268.webp create mode 100644 resource/ship-library/assets/portraits/269.webp create mode 100644 resource/ship-library/assets/portraits/27.webp create mode 100644 resource/ship-library/assets/portraits/270.webp create mode 100644 resource/ship-library/assets/portraits/271.webp create mode 100644 resource/ship-library/assets/portraits/272.webp create mode 100644 resource/ship-library/assets/portraits/273.webp create mode 100644 resource/ship-library/assets/portraits/274.webp create mode 100644 resource/ship-library/assets/portraits/275.webp create mode 100644 resource/ship-library/assets/portraits/276.webp create mode 100644 resource/ship-library/assets/portraits/277.webp create mode 100644 resource/ship-library/assets/portraits/278.webp create mode 100644 resource/ship-library/assets/portraits/279.webp create mode 100644 resource/ship-library/assets/portraits/28.webp create mode 100644 resource/ship-library/assets/portraits/280.webp create mode 100644 resource/ship-library/assets/portraits/281.webp create mode 100644 resource/ship-library/assets/portraits/282.webp create mode 100644 resource/ship-library/assets/portraits/283.webp create mode 100644 resource/ship-library/assets/portraits/284.webp create mode 100644 resource/ship-library/assets/portraits/285.webp create mode 100644 resource/ship-library/assets/portraits/286.webp create mode 100644 resource/ship-library/assets/portraits/287.webp create mode 100644 resource/ship-library/assets/portraits/288.webp create mode 100644 resource/ship-library/assets/portraits/289.webp create mode 100644 resource/ship-library/assets/portraits/29.webp create mode 100644 resource/ship-library/assets/portraits/290.webp create mode 100644 resource/ship-library/assets/portraits/291.webp create mode 100644 resource/ship-library/assets/portraits/292.webp create mode 100644 resource/ship-library/assets/portraits/293.webp create mode 100644 resource/ship-library/assets/portraits/294.webp create mode 100644 resource/ship-library/assets/portraits/295.webp create mode 100644 resource/ship-library/assets/portraits/296.webp create mode 100644 resource/ship-library/assets/portraits/297.webp create mode 100644 resource/ship-library/assets/portraits/298.webp create mode 100644 resource/ship-library/assets/portraits/299.webp create mode 100644 resource/ship-library/assets/portraits/3.webp create mode 100644 resource/ship-library/assets/portraits/30.webp create mode 100644 resource/ship-library/assets/portraits/300.webp create mode 100644 resource/ship-library/assets/portraits/301.webp create mode 100644 resource/ship-library/assets/portraits/302.webp create mode 100644 resource/ship-library/assets/portraits/303.webp create mode 100644 resource/ship-library/assets/portraits/304.webp create mode 100644 resource/ship-library/assets/portraits/305.webp create mode 100644 resource/ship-library/assets/portraits/306.webp create mode 100644 resource/ship-library/assets/portraits/307.webp create mode 100644 resource/ship-library/assets/portraits/308.webp create mode 100644 resource/ship-library/assets/portraits/309.webp create mode 100644 resource/ship-library/assets/portraits/31.webp create mode 100644 resource/ship-library/assets/portraits/310.webp create mode 100644 resource/ship-library/assets/portraits/311.webp create mode 100644 resource/ship-library/assets/portraits/312.webp create mode 100644 resource/ship-library/assets/portraits/313.webp create mode 100644 resource/ship-library/assets/portraits/314.webp create mode 100644 resource/ship-library/assets/portraits/315.webp create mode 100644 resource/ship-library/assets/portraits/316.webp create mode 100644 resource/ship-library/assets/portraits/317.webp create mode 100644 resource/ship-library/assets/portraits/318.webp create mode 100644 resource/ship-library/assets/portraits/319.webp create mode 100644 resource/ship-library/assets/portraits/32.webp create mode 100644 resource/ship-library/assets/portraits/320.webp create mode 100644 resource/ship-library/assets/portraits/321.webp create mode 100644 resource/ship-library/assets/portraits/322.webp create mode 100644 resource/ship-library/assets/portraits/323.webp create mode 100644 resource/ship-library/assets/portraits/324.webp create mode 100644 resource/ship-library/assets/portraits/325.webp create mode 100644 resource/ship-library/assets/portraits/326.webp create mode 100644 resource/ship-library/assets/portraits/327.webp create mode 100644 resource/ship-library/assets/portraits/328.webp create mode 100644 resource/ship-library/assets/portraits/329.webp create mode 100644 resource/ship-library/assets/portraits/33.webp create mode 100644 resource/ship-library/assets/portraits/330.webp create mode 100644 resource/ship-library/assets/portraits/331.webp create mode 100644 resource/ship-library/assets/portraits/332.webp create mode 100644 resource/ship-library/assets/portraits/333.webp create mode 100644 resource/ship-library/assets/portraits/334.webp create mode 100644 resource/ship-library/assets/portraits/335.webp create mode 100644 resource/ship-library/assets/portraits/336.webp create mode 100644 resource/ship-library/assets/portraits/337.webp create mode 100644 resource/ship-library/assets/portraits/338.webp create mode 100644 resource/ship-library/assets/portraits/339.webp create mode 100644 resource/ship-library/assets/portraits/34.webp create mode 100644 resource/ship-library/assets/portraits/340.webp create mode 100644 resource/ship-library/assets/portraits/341.webp create mode 100644 resource/ship-library/assets/portraits/342.webp create mode 100644 resource/ship-library/assets/portraits/343.webp create mode 100644 resource/ship-library/assets/portraits/344.webp create mode 100644 resource/ship-library/assets/portraits/345.webp create mode 100644 resource/ship-library/assets/portraits/346.webp create mode 100644 resource/ship-library/assets/portraits/347.webp create mode 100644 resource/ship-library/assets/portraits/348.webp create mode 100644 resource/ship-library/assets/portraits/349.webp create mode 100644 resource/ship-library/assets/portraits/35.webp create mode 100644 resource/ship-library/assets/portraits/350.webp create mode 100644 resource/ship-library/assets/portraits/351.webp create mode 100644 resource/ship-library/assets/portraits/352.webp create mode 100644 resource/ship-library/assets/portraits/353.webp create mode 100644 resource/ship-library/assets/portraits/354.webp create mode 100644 resource/ship-library/assets/portraits/355.webp create mode 100644 resource/ship-library/assets/portraits/356.webp create mode 100644 resource/ship-library/assets/portraits/357.webp create mode 100644 resource/ship-library/assets/portraits/358.webp create mode 100644 resource/ship-library/assets/portraits/359.webp create mode 100644 resource/ship-library/assets/portraits/36.webp create mode 100644 resource/ship-library/assets/portraits/360.webp create mode 100644 resource/ship-library/assets/portraits/361.webp create mode 100644 resource/ship-library/assets/portraits/362.webp create mode 100644 resource/ship-library/assets/portraits/363.webp create mode 100644 resource/ship-library/assets/portraits/364.webp create mode 100644 resource/ship-library/assets/portraits/365.webp create mode 100644 resource/ship-library/assets/portraits/366.webp create mode 100644 resource/ship-library/assets/portraits/367.webp create mode 100644 resource/ship-library/assets/portraits/368.webp create mode 100644 resource/ship-library/assets/portraits/369.webp create mode 100644 resource/ship-library/assets/portraits/37.webp create mode 100644 resource/ship-library/assets/portraits/370.webp create mode 100644 resource/ship-library/assets/portraits/371.webp create mode 100644 resource/ship-library/assets/portraits/372.webp create mode 100644 resource/ship-library/assets/portraits/373.webp create mode 100644 resource/ship-library/assets/portraits/374.webp create mode 100644 resource/ship-library/assets/portraits/375.webp create mode 100644 resource/ship-library/assets/portraits/376.webp create mode 100644 resource/ship-library/assets/portraits/377.webp create mode 100644 resource/ship-library/assets/portraits/378.webp create mode 100644 resource/ship-library/assets/portraits/379.webp create mode 100644 resource/ship-library/assets/portraits/38.webp create mode 100644 resource/ship-library/assets/portraits/380.webp create mode 100644 resource/ship-library/assets/portraits/381.webp create mode 100644 resource/ship-library/assets/portraits/382.webp create mode 100644 resource/ship-library/assets/portraits/383.webp create mode 100644 resource/ship-library/assets/portraits/384.webp create mode 100644 resource/ship-library/assets/portraits/385.webp create mode 100644 resource/ship-library/assets/portraits/386.webp create mode 100644 resource/ship-library/assets/portraits/387.webp create mode 100644 resource/ship-library/assets/portraits/388.webp create mode 100644 resource/ship-library/assets/portraits/389.webp create mode 100644 resource/ship-library/assets/portraits/39.webp create mode 100644 resource/ship-library/assets/portraits/390.webp create mode 100644 resource/ship-library/assets/portraits/391.webp create mode 100644 resource/ship-library/assets/portraits/392.webp create mode 100644 resource/ship-library/assets/portraits/393.webp create mode 100644 resource/ship-library/assets/portraits/394.webp create mode 100644 resource/ship-library/assets/portraits/395.webp create mode 100644 resource/ship-library/assets/portraits/396.webp create mode 100644 resource/ship-library/assets/portraits/397.webp create mode 100644 resource/ship-library/assets/portraits/398.webp create mode 100644 resource/ship-library/assets/portraits/399.webp create mode 100644 resource/ship-library/assets/portraits/4.webp create mode 100644 resource/ship-library/assets/portraits/40.webp create mode 100644 resource/ship-library/assets/portraits/400.webp create mode 100644 resource/ship-library/assets/portraits/401.webp create mode 100644 resource/ship-library/assets/portraits/402.webp create mode 100644 resource/ship-library/assets/portraits/403.webp create mode 100644 resource/ship-library/assets/portraits/404.webp create mode 100644 resource/ship-library/assets/portraits/405.webp create mode 100644 resource/ship-library/assets/portraits/406.webp create mode 100644 resource/ship-library/assets/portraits/407.webp create mode 100644 resource/ship-library/assets/portraits/408.webp create mode 100644 resource/ship-library/assets/portraits/409.webp create mode 100644 resource/ship-library/assets/portraits/41.webp create mode 100644 resource/ship-library/assets/portraits/410.webp create mode 100644 resource/ship-library/assets/portraits/411.webp create mode 100644 resource/ship-library/assets/portraits/412.webp create mode 100644 resource/ship-library/assets/portraits/413.webp create mode 100644 resource/ship-library/assets/portraits/414.webp create mode 100644 resource/ship-library/assets/portraits/415.webp create mode 100644 resource/ship-library/assets/portraits/416.webp create mode 100644 resource/ship-library/assets/portraits/417.webp create mode 100644 resource/ship-library/assets/portraits/418.webp create mode 100644 resource/ship-library/assets/portraits/419.webp create mode 100644 resource/ship-library/assets/portraits/42.webp create mode 100644 resource/ship-library/assets/portraits/420.webp create mode 100644 resource/ship-library/assets/portraits/421.webp create mode 100644 resource/ship-library/assets/portraits/422.webp create mode 100644 resource/ship-library/assets/portraits/423.webp create mode 100644 resource/ship-library/assets/portraits/424.webp create mode 100644 resource/ship-library/assets/portraits/425.webp create mode 100644 resource/ship-library/assets/portraits/426.webp create mode 100644 resource/ship-library/assets/portraits/427.webp create mode 100644 resource/ship-library/assets/portraits/428.webp create mode 100644 resource/ship-library/assets/portraits/429.webp create mode 100644 resource/ship-library/assets/portraits/43.webp create mode 100644 resource/ship-library/assets/portraits/430.webp create mode 100644 resource/ship-library/assets/portraits/431.webp create mode 100644 resource/ship-library/assets/portraits/432.webp create mode 100644 resource/ship-library/assets/portraits/433.webp create mode 100644 resource/ship-library/assets/portraits/434.webp create mode 100644 resource/ship-library/assets/portraits/435.webp create mode 100644 resource/ship-library/assets/portraits/436.webp create mode 100644 resource/ship-library/assets/portraits/437.webp create mode 100644 resource/ship-library/assets/portraits/438.webp create mode 100644 resource/ship-library/assets/portraits/439.webp create mode 100644 resource/ship-library/assets/portraits/44.webp create mode 100644 resource/ship-library/assets/portraits/440.webp create mode 100644 resource/ship-library/assets/portraits/441.webp create mode 100644 resource/ship-library/assets/portraits/442.webp create mode 100644 resource/ship-library/assets/portraits/443.webp create mode 100644 resource/ship-library/assets/portraits/444.webp create mode 100644 resource/ship-library/assets/portraits/445.webp create mode 100644 resource/ship-library/assets/portraits/446.webp create mode 100644 resource/ship-library/assets/portraits/447.webp create mode 100644 resource/ship-library/assets/portraits/448.webp create mode 100644 resource/ship-library/assets/portraits/449.webp create mode 100644 resource/ship-library/assets/portraits/45.webp create mode 100644 resource/ship-library/assets/portraits/450.webp create mode 100644 resource/ship-library/assets/portraits/451.webp create mode 100644 resource/ship-library/assets/portraits/452.webp create mode 100644 resource/ship-library/assets/portraits/453.webp create mode 100644 resource/ship-library/assets/portraits/454.webp create mode 100644 resource/ship-library/assets/portraits/455.webp create mode 100644 resource/ship-library/assets/portraits/456.webp create mode 100644 resource/ship-library/assets/portraits/457.webp create mode 100644 resource/ship-library/assets/portraits/458.webp create mode 100644 resource/ship-library/assets/portraits/459.webp create mode 100644 resource/ship-library/assets/portraits/46.webp create mode 100644 resource/ship-library/assets/portraits/460.webp create mode 100644 resource/ship-library/assets/portraits/461.webp create mode 100644 resource/ship-library/assets/portraits/462.webp create mode 100644 resource/ship-library/assets/portraits/463.webp create mode 100644 resource/ship-library/assets/portraits/464.webp create mode 100644 resource/ship-library/assets/portraits/465.webp create mode 100644 resource/ship-library/assets/portraits/466.webp create mode 100644 resource/ship-library/assets/portraits/467.webp create mode 100644 resource/ship-library/assets/portraits/468.webp create mode 100644 resource/ship-library/assets/portraits/469.webp create mode 100644 resource/ship-library/assets/portraits/47.webp create mode 100644 resource/ship-library/assets/portraits/470.webp create mode 100644 resource/ship-library/assets/portraits/471.webp create mode 100644 resource/ship-library/assets/portraits/472.webp create mode 100644 resource/ship-library/assets/portraits/473.webp create mode 100644 resource/ship-library/assets/portraits/474.webp create mode 100644 resource/ship-library/assets/portraits/475.webp create mode 100644 resource/ship-library/assets/portraits/476.webp create mode 100644 resource/ship-library/assets/portraits/477.webp create mode 100644 resource/ship-library/assets/portraits/478.webp create mode 100644 resource/ship-library/assets/portraits/479.webp create mode 100644 resource/ship-library/assets/portraits/48.webp create mode 100644 resource/ship-library/assets/portraits/480.webp create mode 100644 resource/ship-library/assets/portraits/481.webp create mode 100644 resource/ship-library/assets/portraits/482.webp create mode 100644 resource/ship-library/assets/portraits/483.webp create mode 100644 resource/ship-library/assets/portraits/484.webp create mode 100644 resource/ship-library/assets/portraits/485.webp create mode 100644 resource/ship-library/assets/portraits/486.webp create mode 100644 resource/ship-library/assets/portraits/487.webp create mode 100644 resource/ship-library/assets/portraits/488.webp create mode 100644 resource/ship-library/assets/portraits/489.webp create mode 100644 resource/ship-library/assets/portraits/49.webp create mode 100644 resource/ship-library/assets/portraits/490.webp create mode 100644 resource/ship-library/assets/portraits/491.webp create mode 100644 resource/ship-library/assets/portraits/492.webp create mode 100644 resource/ship-library/assets/portraits/493.webp create mode 100644 resource/ship-library/assets/portraits/494.webp create mode 100644 resource/ship-library/assets/portraits/495.webp create mode 100644 resource/ship-library/assets/portraits/496.webp create mode 100644 resource/ship-library/assets/portraits/497.webp create mode 100644 resource/ship-library/assets/portraits/498.webp create mode 100644 resource/ship-library/assets/portraits/499.webp create mode 100644 resource/ship-library/assets/portraits/5.webp create mode 100644 resource/ship-library/assets/portraits/50.webp create mode 100644 resource/ship-library/assets/portraits/500.webp create mode 100644 resource/ship-library/assets/portraits/501.webp create mode 100644 resource/ship-library/assets/portraits/502.webp create mode 100644 resource/ship-library/assets/portraits/503.webp create mode 100644 resource/ship-library/assets/portraits/504.webp create mode 100644 resource/ship-library/assets/portraits/505.webp create mode 100644 resource/ship-library/assets/portraits/506.webp create mode 100644 resource/ship-library/assets/portraits/507.webp create mode 100644 resource/ship-library/assets/portraits/508.webp create mode 100644 resource/ship-library/assets/portraits/509.webp create mode 100644 resource/ship-library/assets/portraits/51.webp create mode 100644 resource/ship-library/assets/portraits/510.webp create mode 100644 resource/ship-library/assets/portraits/511.webp create mode 100644 resource/ship-library/assets/portraits/512.webp create mode 100644 resource/ship-library/assets/portraits/513.webp create mode 100644 resource/ship-library/assets/portraits/514.webp create mode 100644 resource/ship-library/assets/portraits/515.webp create mode 100644 resource/ship-library/assets/portraits/516.webp create mode 100644 resource/ship-library/assets/portraits/517.webp create mode 100644 resource/ship-library/assets/portraits/518.webp create mode 100644 resource/ship-library/assets/portraits/519.webp create mode 100644 resource/ship-library/assets/portraits/52.webp create mode 100644 resource/ship-library/assets/portraits/520.webp create mode 100644 resource/ship-library/assets/portraits/521.webp create mode 100644 resource/ship-library/assets/portraits/522.webp create mode 100644 resource/ship-library/assets/portraits/523.webp create mode 100644 resource/ship-library/assets/portraits/524.webp create mode 100644 resource/ship-library/assets/portraits/525.webp create mode 100644 resource/ship-library/assets/portraits/526.webp create mode 100644 resource/ship-library/assets/portraits/527.webp create mode 100644 resource/ship-library/assets/portraits/528.webp create mode 100644 resource/ship-library/assets/portraits/529.webp create mode 100644 resource/ship-library/assets/portraits/53.webp create mode 100644 resource/ship-library/assets/portraits/530.webp create mode 100644 resource/ship-library/assets/portraits/531.webp create mode 100644 resource/ship-library/assets/portraits/532.webp create mode 100644 resource/ship-library/assets/portraits/533.webp create mode 100644 resource/ship-library/assets/portraits/534.webp create mode 100644 resource/ship-library/assets/portraits/535.webp create mode 100644 resource/ship-library/assets/portraits/536.webp create mode 100644 resource/ship-library/assets/portraits/537.webp create mode 100644 resource/ship-library/assets/portraits/538.webp create mode 100644 resource/ship-library/assets/portraits/539.webp create mode 100644 resource/ship-library/assets/portraits/54.webp create mode 100644 resource/ship-library/assets/portraits/540.webp create mode 100644 resource/ship-library/assets/portraits/541.webp create mode 100644 resource/ship-library/assets/portraits/542.webp create mode 100644 resource/ship-library/assets/portraits/543.webp create mode 100644 resource/ship-library/assets/portraits/544.webp create mode 100644 resource/ship-library/assets/portraits/545.webp create mode 100644 resource/ship-library/assets/portraits/546.webp create mode 100644 resource/ship-library/assets/portraits/547.webp create mode 100644 resource/ship-library/assets/portraits/548.webp create mode 100644 resource/ship-library/assets/portraits/549.webp create mode 100644 resource/ship-library/assets/portraits/55.webp create mode 100644 resource/ship-library/assets/portraits/550.webp create mode 100644 resource/ship-library/assets/portraits/551.webp create mode 100644 resource/ship-library/assets/portraits/552.webp create mode 100644 resource/ship-library/assets/portraits/553.webp create mode 100644 resource/ship-library/assets/portraits/554.webp create mode 100644 resource/ship-library/assets/portraits/555.webp create mode 100644 resource/ship-library/assets/portraits/556.webp create mode 100644 resource/ship-library/assets/portraits/557.webp create mode 100644 resource/ship-library/assets/portraits/558.webp create mode 100644 resource/ship-library/assets/portraits/559.webp create mode 100644 resource/ship-library/assets/portraits/56.webp create mode 100644 resource/ship-library/assets/portraits/560.webp create mode 100644 resource/ship-library/assets/portraits/561.webp create mode 100644 resource/ship-library/assets/portraits/562.webp create mode 100644 resource/ship-library/assets/portraits/563.webp create mode 100644 resource/ship-library/assets/portraits/564.webp create mode 100644 resource/ship-library/assets/portraits/565.webp create mode 100644 resource/ship-library/assets/portraits/566.webp create mode 100644 resource/ship-library/assets/portraits/567.webp create mode 100644 resource/ship-library/assets/portraits/568.webp create mode 100644 resource/ship-library/assets/portraits/569.webp create mode 100644 resource/ship-library/assets/portraits/57.webp create mode 100644 resource/ship-library/assets/portraits/570.webp create mode 100644 resource/ship-library/assets/portraits/571.webp create mode 100644 resource/ship-library/assets/portraits/572.webp create mode 100644 resource/ship-library/assets/portraits/573.webp create mode 100644 resource/ship-library/assets/portraits/574.webp create mode 100644 resource/ship-library/assets/portraits/575.webp create mode 100644 resource/ship-library/assets/portraits/576.webp create mode 100644 resource/ship-library/assets/portraits/577.webp create mode 100644 resource/ship-library/assets/portraits/578.webp create mode 100644 resource/ship-library/assets/portraits/579.webp create mode 100644 resource/ship-library/assets/portraits/58.webp create mode 100644 resource/ship-library/assets/portraits/580.webp create mode 100644 resource/ship-library/assets/portraits/581.webp create mode 100644 resource/ship-library/assets/portraits/582.webp create mode 100644 resource/ship-library/assets/portraits/583.webp create mode 100644 resource/ship-library/assets/portraits/584.webp create mode 100644 resource/ship-library/assets/portraits/585.webp create mode 100644 resource/ship-library/assets/portraits/586.webp create mode 100644 resource/ship-library/assets/portraits/587.webp create mode 100644 resource/ship-library/assets/portraits/588.webp create mode 100644 resource/ship-library/assets/portraits/589.webp create mode 100644 resource/ship-library/assets/portraits/59.webp create mode 100644 resource/ship-library/assets/portraits/590.webp create mode 100644 resource/ship-library/assets/portraits/591.webp create mode 100644 resource/ship-library/assets/portraits/592.webp create mode 100644 resource/ship-library/assets/portraits/593.webp create mode 100644 resource/ship-library/assets/portraits/594.webp create mode 100644 resource/ship-library/assets/portraits/595.webp create mode 100644 resource/ship-library/assets/portraits/596.webp create mode 100644 resource/ship-library/assets/portraits/597.webp create mode 100644 resource/ship-library/assets/portraits/598.webp create mode 100644 resource/ship-library/assets/portraits/599.webp create mode 100644 resource/ship-library/assets/portraits/6.webp create mode 100644 resource/ship-library/assets/portraits/60.webp create mode 100644 resource/ship-library/assets/portraits/600.webp create mode 100644 resource/ship-library/assets/portraits/601.webp create mode 100644 resource/ship-library/assets/portraits/602.webp create mode 100644 resource/ship-library/assets/portraits/603.webp create mode 100644 resource/ship-library/assets/portraits/604.webp create mode 100644 resource/ship-library/assets/portraits/605.webp create mode 100644 resource/ship-library/assets/portraits/606.webp create mode 100644 resource/ship-library/assets/portraits/607.webp create mode 100644 resource/ship-library/assets/portraits/608.webp create mode 100644 resource/ship-library/assets/portraits/609.webp create mode 100644 resource/ship-library/assets/portraits/61.webp create mode 100644 resource/ship-library/assets/portraits/610.webp create mode 100644 resource/ship-library/assets/portraits/611.webp create mode 100644 resource/ship-library/assets/portraits/612.webp create mode 100644 resource/ship-library/assets/portraits/613.webp create mode 100644 resource/ship-library/assets/portraits/614.webp create mode 100644 resource/ship-library/assets/portraits/615.webp create mode 100644 resource/ship-library/assets/portraits/616.webp create mode 100644 resource/ship-library/assets/portraits/617.webp create mode 100644 resource/ship-library/assets/portraits/618.webp create mode 100644 resource/ship-library/assets/portraits/619.webp create mode 100644 resource/ship-library/assets/portraits/62.webp create mode 100644 resource/ship-library/assets/portraits/620.webp create mode 100644 resource/ship-library/assets/portraits/621.webp create mode 100644 resource/ship-library/assets/portraits/622.webp create mode 100644 resource/ship-library/assets/portraits/623.webp create mode 100644 resource/ship-library/assets/portraits/624.webp create mode 100644 resource/ship-library/assets/portraits/625.webp create mode 100644 resource/ship-library/assets/portraits/626.webp create mode 100644 resource/ship-library/assets/portraits/627.webp create mode 100644 resource/ship-library/assets/portraits/628.webp create mode 100644 resource/ship-library/assets/portraits/629.webp create mode 100644 resource/ship-library/assets/portraits/63.webp create mode 100644 resource/ship-library/assets/portraits/630.webp create mode 100644 resource/ship-library/assets/portraits/631.webp create mode 100644 resource/ship-library/assets/portraits/632.webp create mode 100644 resource/ship-library/assets/portraits/633.webp create mode 100644 resource/ship-library/assets/portraits/634.webp create mode 100644 resource/ship-library/assets/portraits/635.webp create mode 100644 resource/ship-library/assets/portraits/636.webp create mode 100644 resource/ship-library/assets/portraits/637.webp create mode 100644 resource/ship-library/assets/portraits/638.webp create mode 100644 resource/ship-library/assets/portraits/639.webp create mode 100644 resource/ship-library/assets/portraits/64.webp create mode 100644 resource/ship-library/assets/portraits/640.webp create mode 100644 resource/ship-library/assets/portraits/641.webp create mode 100644 resource/ship-library/assets/portraits/642.webp create mode 100644 resource/ship-library/assets/portraits/643.webp create mode 100644 resource/ship-library/assets/portraits/644.webp create mode 100644 resource/ship-library/assets/portraits/645.webp create mode 100644 resource/ship-library/assets/portraits/646.webp create mode 100644 resource/ship-library/assets/portraits/647.webp create mode 100644 resource/ship-library/assets/portraits/648.webp create mode 100644 resource/ship-library/assets/portraits/649.webp create mode 100644 resource/ship-library/assets/portraits/65.webp create mode 100644 resource/ship-library/assets/portraits/650.webp create mode 100644 resource/ship-library/assets/portraits/651.webp create mode 100644 resource/ship-library/assets/portraits/66.webp create mode 100644 resource/ship-library/assets/portraits/67.webp create mode 100644 resource/ship-library/assets/portraits/68.webp create mode 100644 resource/ship-library/assets/portraits/69.webp create mode 100644 resource/ship-library/assets/portraits/7.webp create mode 100644 resource/ship-library/assets/portraits/70.webp create mode 100644 resource/ship-library/assets/portraits/71.webp create mode 100644 resource/ship-library/assets/portraits/72.webp create mode 100644 resource/ship-library/assets/portraits/73.webp create mode 100644 resource/ship-library/assets/portraits/74.webp create mode 100644 resource/ship-library/assets/portraits/75.webp create mode 100644 resource/ship-library/assets/portraits/76.webp create mode 100644 resource/ship-library/assets/portraits/77.webp create mode 100644 resource/ship-library/assets/portraits/78.webp create mode 100644 resource/ship-library/assets/portraits/79.webp create mode 100644 resource/ship-library/assets/portraits/8.webp create mode 100644 resource/ship-library/assets/portraits/80.webp create mode 100644 resource/ship-library/assets/portraits/8007.webp create mode 100644 resource/ship-library/assets/portraits/8009.webp create mode 100644 resource/ship-library/assets/portraits/81.webp create mode 100644 resource/ship-library/assets/portraits/8111.webp create mode 100644 resource/ship-library/assets/portraits/8116.webp create mode 100644 resource/ship-library/assets/portraits/82.webp create mode 100644 resource/ship-library/assets/portraits/83.webp create mode 100644 resource/ship-library/assets/portraits/84.webp create mode 100644 resource/ship-library/assets/portraits/85.webp create mode 100644 resource/ship-library/assets/portraits/86.webp create mode 100644 resource/ship-library/assets/portraits/87.webp create mode 100644 resource/ship-library/assets/portraits/88.webp create mode 100644 resource/ship-library/assets/portraits/89.webp create mode 100644 resource/ship-library/assets/portraits/9.webp create mode 100644 resource/ship-library/assets/portraits/90.webp create mode 100644 resource/ship-library/assets/portraits/91.webp create mode 100644 resource/ship-library/assets/portraits/92.webp create mode 100644 resource/ship-library/assets/portraits/93.webp create mode 100644 resource/ship-library/assets/portraits/94.webp create mode 100644 resource/ship-library/assets/portraits/95.webp create mode 100644 resource/ship-library/assets/portraits/96.webp create mode 100644 resource/ship-library/assets/portraits/97.webp create mode 100644 resource/ship-library/assets/portraits/98.webp create mode 100644 resource/ship-library/assets/portraits/99.webp create mode 100644 resource/ship-library/assets/type-icons/ap.webp create mode 100644 resource/ship-library/assets/type-icons/av.webp create mode 100644 resource/ship-library/assets/type-icons/bb.webp create mode 100644 resource/ship-library/assets/type-icons/bbg.webp create mode 100644 resource/ship-library/assets/type-icons/bbv.webp create mode 100644 resource/ship-library/assets/type-icons/bc.webp create mode 100644 resource/ship-library/assets/type-icons/bm.webp create mode 100644 resource/ship-library/assets/type-icons/ca.webp create mode 100644 resource/ship-library/assets/type-icons/cav.webp create mode 100644 resource/ship-library/assets/type-icons/cbg.webp create mode 100644 resource/ship-library/assets/type-icons/cf.webp create mode 100644 resource/ship-library/assets/type-icons/cg.webp create mode 100644 resource/ship-library/assets/type-icons/cgaa.webp create mode 100644 resource/ship-library/assets/type-icons/cl.webp create mode 100644 resource/ship-library/assets/type-icons/clt.webp create mode 100644 resource/ship-library/assets/type-icons/cv.webp create mode 100644 resource/ship-library/assets/type-icons/cvl.webp create mode 100644 resource/ship-library/assets/type-icons/dd.webp create mode 100644 resource/ship-library/assets/type-icons/ddg.webp create mode 100644 resource/ship-library/assets/type-icons/ddgaa.webp create mode 100644 resource/ship-library/assets/type-icons/sc.webp create mode 100644 resource/ship-library/assets/type-icons/ss.webp create mode 100644 resource/ship-library/assets/type-icons/ssg.webp create mode 100644 resource/ship-library/database/ships.sqlite3 create mode 100644 resource/ship-library/labels.zh-CN.json create mode 100644 resource/ship-library/manifest.json create mode 100644 "resource/system_battle_plans/bettle-\345\221\250\345\270\270-1-1.yaml" create mode 100644 "resource/system_battle_plans/bettle-\345\221\250\345\270\270-10-1.yaml" create mode 100644 "resource/system_battle_plans/bettle-\345\221\250\345\270\270-2-1.yaml" create mode 100644 "resource/system_battle_plans/bettle-\345\221\250\345\270\270-3-1.yaml" create mode 100644 "resource/system_battle_plans/bettle-\345\221\250\345\270\270-4-1.yaml" create mode 100644 "resource/system_battle_plans/bettle-\345\221\250\345\270\270-5-5.yaml" create mode 100644 "resource/system_battle_plans/bettle-\345\221\250\345\270\270-6-4.yaml" create mode 100644 "resource/system_battle_plans/bettle-\345\221\250\345\270\270-7-4.yaml" create mode 100644 "resource/system_battle_plans/bettle-\345\221\250\345\270\270-8-2.yaml" create mode 100644 "resource/system_battle_plans/bettle-\345\221\250\345\270\270-9-2.yaml" create mode 100644 resource/system_team_plans/.gitkeep create mode 100644 "resource/system_team_plans/team-3\351\251\261\345\205\213\345\212\26385\345\267\245\347\250\213\351\230\237.yaml" create mode 100644 "resource/system_team_plans/team-4\345\276\267\351\251\261\345\221\250\345\270\270\351\230\237.yaml" create mode 100644 "resource/system_team_plans/team-4\346\227\245\351\251\261\345\221\250\345\270\270\351\230\237.yaml" create mode 100644 "resource/system_team_plans/team-6\346\227\245\351\251\261\351\230\237.yaml" create mode 100644 "resource/system_team_plans/team-6\346\275\234\350\211\207\351\230\237.yaml" create mode 100644 "resource/system_team_plans/team-85AIII4\351\230\262\351\251\261\351\230\237.yaml" create mode 100644 "resource/system_team_plans/team-85\345\267\245\347\250\213+3\345\276\267\351\251\261\351\230\237.yaml" create mode 100644 "resource/system_team_plans/team-\345\244\247\346\267\20085AIII\351\230\237.yaml" create mode 100644 "resource/system_team_plans/team-\351\207\215\345\267\241\345\221\250\345\270\270\351\230\237.yaml" create mode 100644 resource/user_team_plans/.gitkeep create mode 100644 scripts/test-legacy-plan-conversion.js create mode 100644 scripts/test-settings-persistence.js create mode 100644 src/controller/taskGroup/TaskListLoaderController.ts create mode 100644 src/controller/taskGroup/managedPlanReader.ts create mode 100644 src/view/main/FleetPreviewView.ts create mode 100644 src/view/plan/DecisivePlanView.ts create mode 100644 src/view/plan/FleetPlannerView.ts create mode 100644 src/view/plan/ShipArtwork.ts create mode 100644 src/view/plan/TeamPlanListUi.ts create mode 100644 src/view/shared/scrollPosition.ts create mode 100644 src/view/styles/components/_save-notice.scss create mode 100644 src/view/styles/pages/plan/_decisive-plan.scss create mode 100644 src/view/styles/pages/plan/_fleet-planner.scss create mode 100644 src/view/styles/themes/_light.scss delete mode 100644 "templates/\345\206\263\346\210\230\351\205\215\347\275\256.json" delete mode 100644 "templates/\345\270\270\350\247\204\345\207\272\345\207\273.json" delete mode 100644 "templates/\346\227\245\345\270\270\346\210\230\345\275\271.json" delete mode 100644 "templates/\350\207\252\345\212\250\346\274\224\344\271\240.json" create mode 100644 tools/ship_library/update_ship_library.py diff --git a/.gitignore b/.gitignore index 8485763..0e7dbcb 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ release/ # 安装临时文件 _setup_tmp/ .tmp/ +.tmp_* node/ python/ redist/ @@ -45,10 +46,14 @@ adb/ # 缓存 .cache/ +.dbg/ +__pycache__/ +*.py[cod] +/debug-backend-pipe-epipe.md # Kilo 工作区 .kilo/ # 测试用地图 resource/maps/99-1.json -plans/99-1.yaml. \ No newline at end of file +plans/99-1.yaml. diff --git a/.tmp_issue360.json b/.tmp_issue360.json deleted file mode 100644 index 9df7d21..0000000 --- a/.tmp_issue360.json +++ /dev/null @@ -1,2 +0,0 @@ -{"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/360","repository_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/360/labels{/name}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/360/comments","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/360/events","html_url":"https://github.com/OpenWSGR/AutoWSGR/issues/360","id":4052520746,"node_id":"I_kwDOHhoLA87xjI8q","number":360,"title":"[Feature] GUI API ǿֹͣÿֽݡ","user":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"labels":[],"state":"open","locked":false,"assignees":[],"milestone":null,"comments":2,"created_at":"2026-03-10T15:21:29Z","updated_at":"2026-04-05T06:37:38Z","closed_at":null,"assignee":null,"author_association":"CONTRIBUTOR","type":null,"active_lock_reason":null,"sub_issues_summary":{"total":0,"completed":0,"percent_completed":0},"issue_dependencies_summary":{"blocked_by":0,"total_blocked_by":0,"blocking":0,"total_blocking":0},"body":"## \n\nAutoWSGR-GUI ʵеȡֹͣ顢ÿսչʾȹܿܣֹ API ݲû޷ issue GUI ĺ API ǿ\n\n---\n\n## 1. ֹͣɿÿֵȼߣ\n\n**ǰ״**\n- ʵ `stopCondition` ƣ`loot_count_ge` / `ship_count_ge`ûáˢ N սƷ/ʱԶֹͣ\n- `/api/game/context` ص `dropped_ship_count` / `dropped_loot_count` ɿ**ֹͣ߼עͽ**\n\n**Ҫģ**\n- ÿս׼ȷۼƱγĵ佢սƷ\n- ͨ `/api/game/context`սشṩ׼ȷۼֵ\n- #355 ĵ佢ʶ𻥲#355 ʶʲôۼƵ˶١\n\n**ǰеĵô루ǰעͣ**\n```typescript\n// Scheduler.ts\nconst resp = await this.api.gameContext();\nif (data.dropped_loot_count >= cond.loot_count_ge) { /* ֹͣ */ }\nif (data.dropped_ship_count >= cond.ship_count_ge) { /* ֹͣ */ }\n```\n\n---\n\n## 2. ÿսشȼͣ\n\n**ǰ״**\n- `RoundResult` ݽṹѶ `mvp``grade``ship_damage` ֶ\n- WebSocket `task_completed` Ϣе `result.details` ĿǰЩֶΪ\n\n**Ҫģ**\n- սʱ `RoundResult` 䣺\n - `ship_damage`: λ̶ȣѡǰչʾ״̬\n- MVP ƺ͵佢 #355 \n\n** gradeѽ**\n> սۣSS/S/A/B/C/Dͨǰ˽ stderr ־ `[Combat] ս: MVP=0 =SS ڵ: A` ʵɫʾ** API ⷵ**δ `grade` ֶΣǰ˿ֱʹãⲻ\n\n---\n\n## 3. ˵㣨ȼͣ\n\n**ǰ״**\n- WebSocket Զ\n- ޷˽̿ OCR סģӦȳ\n\n**Ҫģ**\n- ṩ `GET /api/health` ˵㣬غ˴״̬\n- ѡصǰǷij賬쳣ʱ\n\n---\n\n## \n\n- #355 MVPƻش & 佢ʶشϵ\n- GUI ֿ⣺[yltx/AutoWSGR-GUI](https://github.com/yltx/AutoWSGR-GUI)","closed_by":null,"reactions":{"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/360/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"timeline_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/360/timeline","performed_via_github_app":null,"state_reason":null,"pinned_comment":null} - diff --git a/.tmp_issue360_comments.json b/.tmp_issue360_comments.json deleted file mode 100644 index fe5ae76..0000000 --- a/.tmp_issue360_comments.json +++ /dev/null @@ -1,2 +0,0 @@ -[{"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments/4188401106","html_url":"https://github.com/OpenWSGR/AutoWSGR/issues/360#issuecomment-4188401106","issue_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/360","id":4188401106,"node_id":"IC_kwDOHhoLA875pe3S","user":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"created_at":"2026-04-05T06:37:17Z","updated_at":"2026-04-05T06:37:17Z","body":"ǰ˷һ£issueǷѾ@github-actions","author_association":"CONTRIBUTOR","pin":null,"reactions":{"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments/4188401106/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"performed_via_github_app":null},{"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments/4188401263","html_url":"https://github.com/OpenWSGR/AutoWSGR/issues/360#issuecomment-4188401263","issue_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/360","id":4188401263,"node_id":"IC_kwDOHhoLA875pe5v","user":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"created_at":"2026-04-05T06:37:29Z","updated_at":"2026-04-05T06:37:38Z","body":"ִԡ\n\n---\n\n
˴չ\nError: Model \"gpt-5.4\" from --model flag is not available.\n
\n\n?? [GitHub Action м¼](https://github.com/OpenWSGR/AutoWSGR/actions/runs/23996089391)\n","author_association":"CONTRIBUTOR","pin":null,"reactions":{"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments/4188401263/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"performed_via_github_app":{"id":15368,"client_id":"Iv1.05c79e9ad1f6bdfa","slug":"github-actions","node_id":"MDM6QXBwMTUzNjg=","owner":{"login":"github","id":9919,"node_id":"MDEyOk9yZ2FuaXphdGlvbjk5MTk=","avatar_url":"https://avatars.githubusercontent.com/u/9919?v=4","gravatar_id":"","url":"https://api.github.com/users/github","html_url":"https://github.com/github","followers_url":"https://api.github.com/users/github/followers","following_url":"https://api.github.com/users/github/following{/other_user}","gists_url":"https://api.github.com/users/github/gists{/gist_id}","starred_url":"https://api.github.com/users/github/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github/subscriptions","organizations_url":"https://api.github.com/users/github/orgs","repos_url":"https://api.github.com/users/github/repos","events_url":"https://api.github.com/users/github/events{/privacy}","received_events_url":"https://api.github.com/users/github/received_events","type":"Organization","user_view_type":"public","site_admin":false},"name":"GitHub Actions","description":"Automate your workflow from idea to production","external_url":"https://help.github.com/en/actions","html_url":"https://github.com/apps/github-actions","created_at":"2018-07-30T09:30:17Z","updated_at":"2025-12-02T18:13:15Z","permissions":{"actions":"write","administration":"read","artifact_metadata":"write","attestations":"write","checks":"write","contents":"write","copilot_requests":"write","deployments":"write","discussions":"write","issues":"write","merge_queues":"write","metadata":"read","models":"read","packages":"write","pages":"write","pull_requests":"write","repository_hooks":"write","repository_projects":"write","security_events":"write","statuses":"write","vulnerability_alerts":"read"},"events":["branch_protection_rule","check_run","check_suite","create","delete","deployment","deployment_status","discussion","discussion_comment","fork","gollum","issues","issue_comment","label","merge_group","milestone","page_build","public","pull_request","pull_request_review","pull_request_review_comment","push","registry_package","release","repository","repository_dispatch","status","watch","workflow_dispatch","workflow_run"]}}] - diff --git a/.tmp_issue372.json b/.tmp_issue372.json deleted file mode 100644 index 32cc256..0000000 --- a/.tmp_issue372.json +++ /dev/null @@ -1,2 +0,0 @@ -{"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/372","repository_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/372/labels{/name}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/372/comments","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/372/events","html_url":"https://github.com/OpenWSGR/AutoWSGR/issues/372","id":4080457974,"node_id":"I_kwDOHhoLA87zNtj2","number":372,"title":"[Feature Request] ҳ OCR ʶ ֧/ճ״̬ѯ","user":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"labels":[],"state":"open","locked":false,"assignees":[],"milestone":null,"comments":2,"created_at":"2026-03-16T06:12:51Z","updated_at":"2026-04-05T06:10:41Z","closed_at":null,"assignee":null,"author_association":"CONTRIBUTOR","type":null,"active_lock_reason":null,"sub_issues_summary":{"total":0,"completed":0,"percent_completed":0},"issue_dependencies_summary":{"blocked_by":0,"total_blocked_by":0,"blocking":0,"total_blocking":0},"body":"## \n\nϣͨ OCR ʶҳ棨ճ/ܳ/ս۵ȣȡ״̬Ӷ GUI Զűһ\n\n## ʹó\n\n- GUI ǰչʾǰճ/ܳɽ\n- Զűδ̬ѡһִ\n- ÿԶУԽʡʱ\n\n## Ԥʵ\n\n1. ҳ\n2. OCR ʶƺ״̬/δ/У\n3. ؽṹб\n\n## ѵ\n\n- Ҫ OCR ģƥҳ\n- ݿ⣨ Ӧӳ䣩\n- ֱͬµ\n\n## ȼ\n\nе Ŀǰ̶ͨƹ˴˹ܿԴԶܶȡ","closed_by":null,"reactions":{"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/372/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"timeline_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/372/timeline","performed_via_github_app":null,"state_reason":null,"pinned_comment":null} - diff --git a/.tmp_issue372_comments.json b/.tmp_issue372_comments.json deleted file mode 100644 index ba104aa..0000000 --- a/.tmp_issue372_comments.json +++ /dev/null @@ -1,2 +0,0 @@ -[{"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments/4188369930","html_url":"https://github.com/OpenWSGR/AutoWSGR/issues/372#issuecomment-4188369930","issue_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/372","id":4188369930,"node_id":"IC_kwDOHhoLA875pXQK","user":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"created_at":"2026-04-05T06:10:22Z","updated_at":"2026-04-05T06:10:22Z","body":"@github-actions һ","author_association":"CONTRIBUTOR","pin":null,"reactions":{"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments/4188369930/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"performed_via_github_app":null},{"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments/4188370118","html_url":"https://github.com/OpenWSGR/AutoWSGR/issues/372#issuecomment-4188370118","issue_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/372","id":4188370118,"node_id":"IC_kwDOHhoLA875pXTG","user":{"login":"github-actions[bot]","id":41898282,"node_id":"MDM6Qm90NDE4OTgyODI=","avatar_url":"https://avatars.githubusercontent.com/in/15368?v=4","gravatar_id":"","url":"https://api.github.com/users/github-actions%5Bbot%5D","html_url":"https://github.com/apps/github-actions","followers_url":"https://api.github.com/users/github-actions%5Bbot%5D/followers","following_url":"https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github-actions%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/github-actions%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/github-actions%5Bbot%5D/repos","events_url":"https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/github-actions%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"created_at":"2026-04-05T06:10:33Z","updated_at":"2026-04-05T06:10:41Z","body":"ִԡ\n\n---\n\n
˴չ\nError: Authentication failed (Request ID: 9401:14A9D1:93F818:D06440:69D1FCDF)\n\nYour GitHub token may be invalid, expired, or lacking the required permissions.\n\nTo resolve this, try the following:\n ? Start 'copilot' and run the '/login' command to re-authenticate\n ? If using a Fine-Grained PAT, ensure it has the 'Copilot Requests' permission enabled\n ? If using COPILOT_GITHUB_TOKEN, GH_TOKEN or GITHUB_TOKEN environment variable, verify the token is valid and not expired\n ? Run 'gh auth status' to check your current authentication status\n
\n\n?? [GitHub Action м¼](https://github.com/OpenWSGR/AutoWSGR/actions/runs/23995683447)\n","author_association":"CONTRIBUTOR","pin":null,"reactions":{"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments/4188370118/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"performed_via_github_app":{"id":15368,"client_id":"Iv1.05c79e9ad1f6bdfa","slug":"github-actions","node_id":"MDM6QXBwMTUzNjg=","owner":{"login":"github","id":9919,"node_id":"MDEyOk9yZ2FuaXphdGlvbjk5MTk=","avatar_url":"https://avatars.githubusercontent.com/u/9919?v=4","gravatar_id":"","url":"https://api.github.com/users/github","html_url":"https://github.com/github","followers_url":"https://api.github.com/users/github/followers","following_url":"https://api.github.com/users/github/following{/other_user}","gists_url":"https://api.github.com/users/github/gists{/gist_id}","starred_url":"https://api.github.com/users/github/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github/subscriptions","organizations_url":"https://api.github.com/users/github/orgs","repos_url":"https://api.github.com/users/github/repos","events_url":"https://api.github.com/users/github/events{/privacy}","received_events_url":"https://api.github.com/users/github/received_events","type":"Organization","user_view_type":"public","site_admin":false},"name":"GitHub Actions","description":"Automate your workflow from idea to production","external_url":"https://help.github.com/en/actions","html_url":"https://github.com/apps/github-actions","created_at":"2018-07-30T09:30:17Z","updated_at":"2025-12-02T18:13:15Z","permissions":{"actions":"write","administration":"read","artifact_metadata":"write","attestations":"write","checks":"write","contents":"write","copilot_requests":"write","deployments":"write","discussions":"write","issues":"write","merge_queues":"write","metadata":"read","models":"read","packages":"write","pages":"write","pull_requests":"write","repository_hooks":"write","repository_projects":"write","security_events":"write","statuses":"write","vulnerability_alerts":"read"},"events":["branch_protection_rule","check_run","check_suite","create","delete","deployment","deployment_status","discussion","discussion_comment","fork","gollum","issues","issue_comment","label","merge_group","milestone","page_build","public","pull_request","pull_request_review","pull_request_review_comment","push","registry_package","release","repository","repository_dispatch","status","watch","workflow_dispatch","workflow_run"]}}] - diff --git a/.tmp_runs.json b/.tmp_runs.json deleted file mode 100644 index 5efad4f..0000000 --- a/.tmp_runs.json +++ /dev/null @@ -1,2 +0,0 @@ -{"total_count":236,"workflow_runs":[{"id":23995683447,"name":"AI Issue Analysis","node_id":"WFR_kwLOHhoLA88AAAAFlkESdw","head_branch":"main","head_sha":"8e568107bd3ccce8bbf4896d30a50c16b793e633","path":".github/workflows/ai-issue-analysis.yml","display_title":"[Feature Request] ҳ OCR ʶ ֧/ճ״̬ѯ","run_number":2,"event":"issue_comment","status":"completed","conclusion":"failure","workflow_id":256224518,"check_suite_id":63358713624,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOwHk_GA","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23995683447","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23995683447","pull_requests":[],"created_at":"2026-04-05T06:10:25Z","updated_at":"2026-04-05T06:10:43Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-05T06:10:25Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23995683447/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23995683447/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63358713624","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23995683447/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23995683447/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23995683447/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/256224518","head_commit":{"id":"8e568107bd3ccce8bbf4896d30a50c16b793e633","tree_id":"9771f8ad31c04a907fed94274b10c059af83a062","message":"ci: add AI issue analysis bot workflow and skill (#398)","timestamp":"2026-04-04T16:23:59Z","author":{"name":"yltx","email":"37734213+yltx@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23992934314,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFlhcfqg","head_branch":"main","head_sha":"8e568107bd3ccce8bbf4896d30a50c16b793e633","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":104,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":63351563072,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOwAwjQA","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23992934314","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23992934314","pull_requests":[],"created_at":"2026-04-05T02:56:47Z","updated_at":"2026-04-05T02:56:48Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-05T02:56:47Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23992934314/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23992934314/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63351563072","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23992934314/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23992934314/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23992934314/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"8e568107bd3ccce8bbf4896d30a50c16b793e633","tree_id":"9771f8ad31c04a907fed94274b10c059af83a062","message":"ci: add AI issue analysis bot workflow and skill (#398)","timestamp":"2026-04-04T16:23:59Z","author":{"name":"yltx","email":"37734213+yltx@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23989486085,"name":"AI Issue Analysis","node_id":"WFR_kwLOHhoLA88AAAAFleKCBQ","head_branch":"main","head_sha":"8e568107bd3ccce8bbf4896d30a50c16b793e633","path":".github/workflows/ai-issue-analysis.yml","display_title":"űȱȷϻ","run_number":1,"event":"issues","status":"completed","conclusion":"failure","workflow_id":256224518,"check_suite_id":63342341233,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOv39scQ","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23989486085","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23989486085","pull_requests":[],"created_at":"2026-04-04T23:04:58Z","updated_at":"2026-04-04T23:05:14Z","actor":{"login":"syokounya","id":93929783,"node_id":"U_kgDOBZlBNw","avatar_url":"https://avatars.githubusercontent.com/u/93929783?v=4","gravatar_id":"","url":"https://api.github.com/users/syokounya","html_url":"https://github.com/syokounya","followers_url":"https://api.github.com/users/syokounya/followers","following_url":"https://api.github.com/users/syokounya/following{/other_user}","gists_url":"https://api.github.com/users/syokounya/gists{/gist_id}","starred_url":"https://api.github.com/users/syokounya/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/syokounya/subscriptions","organizations_url":"https://api.github.com/users/syokounya/orgs","repos_url":"https://api.github.com/users/syokounya/repos","events_url":"https://api.github.com/users/syokounya/events{/privacy}","received_events_url":"https://api.github.com/users/syokounya/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-04T23:04:58Z","triggering_actor":{"login":"syokounya","id":93929783,"node_id":"U_kgDOBZlBNw","avatar_url":"https://avatars.githubusercontent.com/u/93929783?v=4","gravatar_id":"","url":"https://api.github.com/users/syokounya","html_url":"https://github.com/syokounya","followers_url":"https://api.github.com/users/syokounya/followers","following_url":"https://api.github.com/users/syokounya/following{/other_user}","gists_url":"https://api.github.com/users/syokounya/gists{/gist_id}","starred_url":"https://api.github.com/users/syokounya/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/syokounya/subscriptions","organizations_url":"https://api.github.com/users/syokounya/orgs","repos_url":"https://api.github.com/users/syokounya/repos","events_url":"https://api.github.com/users/syokounya/events{/privacy}","received_events_url":"https://api.github.com/users/syokounya/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23989486085/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23989486085/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63342341233","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23989486085/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23989486085/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23989486085/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/256224518","head_commit":{"id":"8e568107bd3ccce8bbf4896d30a50c16b793e633","tree_id":"9771f8ad31c04a907fed94274b10c059af83a062","message":"ci: add AI issue analysis bot workflow and skill (#398)","timestamp":"2026-04-04T16:23:59Z","author":{"name":"yltx","email":"37734213+yltx@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23985336227,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFlaMvow","head_branch":"main","head_sha":"8e568107bd3ccce8bbf4896d30a50c16b793e633","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":103,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":63331452211,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOvtlFMw","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23985336227","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23985336227","pull_requests":[],"created_at":"2026-04-04T18:51:32Z","updated_at":"2026-04-04T18:51:33Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-04T18:51:32Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23985336227/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23985336227/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63331452211","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23985336227/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23985336227/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23985336227/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"8e568107bd3ccce8bbf4896d30a50c16b793e633","tree_id":"9771f8ad31c04a907fed94274b10c059af83a062","message":"ci: add AI issue analysis bot workflow and skill (#398)","timestamp":"2026-04-04T16:23:59Z","author":{"name":"yltx","email":"37734213+yltx@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23982824993,"name":"Lint","node_id":"WFR_kwLOHhoLA88AAAAFlXzeIQ","head_branch":"main","head_sha":"8e568107bd3ccce8bbf4896d30a50c16b793e633","path":".github/workflows/lint.yml","display_title":"ci: add AI issue analysis bot workflow and skill (#398)","run_number":16,"event":"push","status":"completed","conclusion":"success","workflow_id":253260226,"check_suite_id":63324589462,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOvnCNlg","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982824993","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23982824993","pull_requests":[],"created_at":"2026-04-04T16:24:02Z","updated_at":"2026-04-04T16:24:26Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-04T16:24:02Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982824993/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982824993/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63324589462","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982824993/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982824993/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982824993/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/253260226","head_commit":{"id":"8e568107bd3ccce8bbf4896d30a50c16b793e633","tree_id":"9771f8ad31c04a907fed94274b10c059af83a062","message":"ci: add AI issue analysis bot workflow and skill (#398)","timestamp":"2026-04-04T16:23:59Z","author":{"name":"yltx","email":"37734213+yltx@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23982820830,"name":"Copilot code review","node_id":"WFR_kwLOHhoLA88AAAAFlXzN3g","head_branch":"refs/pull/398/head","head_sha":"e994212b43653113829747305dfa8a0018c352d7","path":"dynamic/copilot-pull-request-reviewer/copilot-pull-request-reviewer","display_title":"Copilot code review","run_number":17,"event":"dynamic","status":"completed","conclusion":"success","workflow_id":220767798,"check_suite_id":63324579249,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOvnBlsQ","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982820830","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23982820830","pull_requests":[],"created_at":"2026-04-04T16:23:50Z","updated_at":"2026-04-04T16:26:35Z","actor":{"login":"Copilot","id":175728472,"node_id":"BOT_kgDOCnlnWA","avatar_url":"https://avatars.githubusercontent.com/in/946600?v=4","gravatar_id":"","url":"https://api.github.com/users/Copilot","html_url":"https://github.com/apps/copilot-pull-request-reviewer","followers_url":"https://api.github.com/users/Copilot/followers","following_url":"https://api.github.com/users/Copilot/following{/other_user}","gists_url":"https://api.github.com/users/Copilot/gists{/gist_id}","starred_url":"https://api.github.com/users/Copilot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Copilot/subscriptions","organizations_url":"https://api.github.com/users/Copilot/orgs","repos_url":"https://api.github.com/users/Copilot/repos","events_url":"https://api.github.com/users/Copilot/events{/privacy}","received_events_url":"https://api.github.com/users/Copilot/received_events","type":"Bot","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-04T16:23:50Z","triggering_actor":{"login":"Copilot","id":175728472,"node_id":"BOT_kgDOCnlnWA","avatar_url":"https://avatars.githubusercontent.com/in/946600?v=4","gravatar_id":"","url":"https://api.github.com/users/Copilot","html_url":"https://github.com/apps/copilot-pull-request-reviewer","followers_url":"https://api.github.com/users/Copilot/followers","following_url":"https://api.github.com/users/Copilot/following{/other_user}","gists_url":"https://api.github.com/users/Copilot/gists{/gist_id}","starred_url":"https://api.github.com/users/Copilot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Copilot/subscriptions","organizations_url":"https://api.github.com/users/Copilot/orgs","repos_url":"https://api.github.com/users/Copilot/repos","events_url":"https://api.github.com/users/Copilot/events{/privacy}","received_events_url":"https://api.github.com/users/Copilot/received_events","type":"Bot","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982820830/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982820830/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63324579249","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982820830/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982820830/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982820830/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/220767798","head_commit":{"id":"e994212b43653113829747305dfa8a0018c352d7","tree_id":"9771f8ad31c04a907fed94274b10c059af83a062","message":"ci: add AI issue analysis bot workflow and skill","timestamp":"2026-04-04T16:20:48Z","author":{"name":"yltx","email":"2326439151@qq.com"},"committer":{"name":"yltx","email":"2326439151@qq.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23982820779,"name":"Lint","node_id":"WFR_kwLOHhoLA88AAAAFlXzNqw","head_branch":"yltx/ai-issue-analysis-bot","head_sha":"e994212b43653113829747305dfa8a0018c352d7","path":".github/workflows/lint.yml","display_title":"ci: add AI issue analysis bot workflow and skill","run_number":15,"event":"pull_request","status":"completed","conclusion":"success","workflow_id":253260226,"check_suite_id":63324579166,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOvnBlXg","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982820779","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23982820779","pull_requests":[],"created_at":"2026-04-04T16:23:49Z","updated_at":"2026-04-04T16:24:16Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-04T16:23:49Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982820779/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982820779/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63324579166","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982820779/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982820779/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982820779/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/253260226","head_commit":{"id":"e994212b43653113829747305dfa8a0018c352d7","tree_id":"9771f8ad31c04a907fed94274b10c059af83a062","message":"ci: add AI issue analysis bot workflow and skill","timestamp":"2026-04-04T16:20:48Z","author":{"name":"yltx","email":"2326439151@qq.com"},"committer":{"name":"yltx","email":"2326439151@qq.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23982415777,"name":"Copilot code review","node_id":"WFR_kwLOHhoLA88AAAAFlXafoQ","head_branch":"refs/pull/397/head","head_sha":"3b5d45ec8f6155ad7059e18996bd9f9388a6d83c","path":"dynamic/copilot-pull-request-reviewer/copilot-pull-request-reviewer","display_title":"Copilot code review","run_number":16,"event":"dynamic","status":"completed","conclusion":"success","workflow_id":220767798,"check_suite_id":63323476980,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOvl-T9A","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982415777","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23982415777","pull_requests":[],"created_at":"2026-04-04T16:00:31Z","updated_at":"2026-04-04T16:03:43Z","actor":{"login":"Copilot","id":175728472,"node_id":"BOT_kgDOCnlnWA","avatar_url":"https://avatars.githubusercontent.com/in/946600?v=4","gravatar_id":"","url":"https://api.github.com/users/Copilot","html_url":"https://github.com/apps/copilot-pull-request-reviewer","followers_url":"https://api.github.com/users/Copilot/followers","following_url":"https://api.github.com/users/Copilot/following{/other_user}","gists_url":"https://api.github.com/users/Copilot/gists{/gist_id}","starred_url":"https://api.github.com/users/Copilot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Copilot/subscriptions","organizations_url":"https://api.github.com/users/Copilot/orgs","repos_url":"https://api.github.com/users/Copilot/repos","events_url":"https://api.github.com/users/Copilot/events{/privacy}","received_events_url":"https://api.github.com/users/Copilot/received_events","type":"Bot","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-04T16:00:31Z","triggering_actor":{"login":"Copilot","id":175728472,"node_id":"BOT_kgDOCnlnWA","avatar_url":"https://avatars.githubusercontent.com/in/946600?v=4","gravatar_id":"","url":"https://api.github.com/users/Copilot","html_url":"https://github.com/apps/copilot-pull-request-reviewer","followers_url":"https://api.github.com/users/Copilot/followers","following_url":"https://api.github.com/users/Copilot/following{/other_user}","gists_url":"https://api.github.com/users/Copilot/gists{/gist_id}","starred_url":"https://api.github.com/users/Copilot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Copilot/subscriptions","organizations_url":"https://api.github.com/users/Copilot/orgs","repos_url":"https://api.github.com/users/Copilot/repos","events_url":"https://api.github.com/users/Copilot/events{/privacy}","received_events_url":"https://api.github.com/users/Copilot/received_events","type":"Bot","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982415777/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982415777/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63323476980","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982415777/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982415777/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982415777/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/220767798","head_commit":{"id":"3b5d45ec8f6155ad7059e18996bd9f9388a6d83c","tree_id":"fffe0658788dd1a57ad15482ec87ce0de6c0564d","message":"fix(server): forward plan fleet overrides for task routes","timestamp":"2026-04-04T15:58:59Z","author":{"name":"yltx","email":"2326439151@qq.com"},"committer":{"name":"yltx","email":"2326439151@qq.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23982415664,"name":"Lint","node_id":"WFR_kwLOHhoLA88AAAAFlXafMA","head_branch":"yltx/web-fleet-override","head_sha":"3b5d45ec8f6155ad7059e18996bd9f9388a6d83c","path":".github/workflows/lint.yml","display_title":"fix(server): forward plan fleet overrides for task routes","run_number":14,"event":"pull_request","status":"completed","conclusion":"success","workflow_id":253260226,"check_suite_id":63323476662,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOvl-Stg","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982415664","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23982415664","pull_requests":[{"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls/397","id":3489133143,"number":397,"head":{"ref":"yltx/web-fleet-override","sha":"3b5d45ec8f6155ad7059e18996bd9f9388a6d83c","repo":{"id":505023235,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","name":"AutoWSGR"}},"base":{"ref":"main","sha":"77e0a80d72158d1a56c70237a2c12b32b237b383","repo":{"id":505023235,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","name":"AutoWSGR"}}}],"created_at":"2026-04-04T16:00:31Z","updated_at":"2026-04-04T16:00:59Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-04T16:00:31Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982415664/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982415664/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63323476662","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982415664/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982415664/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23982415664/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/253260226","head_commit":{"id":"3b5d45ec8f6155ad7059e18996bd9f9388a6d83c","tree_id":"fffe0658788dd1a57ad15482ec87ce0de6c0564d","message":"fix(server): forward plan fleet overrides for task routes","timestamp":"2026-04-04T15:58:59Z","author":{"name":"yltx","email":"2326439151@qq.com"},"committer":{"name":"yltx","email":"2326439151@qq.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23979515051,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFlUpcqw","head_branch":"main","head_sha":"77e0a80d72158d1a56c70237a2c12b32b237b383","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":102,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":63315604070,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOvedyZg","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23979515051","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23979515051","pull_requests":[],"created_at":"2026-04-04T13:07:10Z","updated_at":"2026-04-04T13:07:12Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-04T13:07:10Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23979515051/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23979515051/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63315604070","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23979515051/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23979515051/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23979515051/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"77e0a80d72158d1a56c70237a2c12b32b237b383","tree_id":"2998c9e90d00effc80e88e6562fbea42d20f1c7a","message":"fix: harden page recovery and chapter navigation (#395)","timestamp":"2026-04-02T08:58:55Z","author":{"name":"syokounya","email":"93929783+syokounya@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23973883346,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFlPRt0g","head_branch":"main","head_sha":"77e0a80d72158d1a56c70237a2c12b32b237b383","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":101,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":63300865246,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOvQaM3g","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23973883346","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23973883346","pull_requests":[],"created_at":"2026-04-04T07:07:54Z","updated_at":"2026-04-04T07:07:55Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-04T07:07:54Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23973883346/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23973883346/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63300865246","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23973883346/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23973883346/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23973883346/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"77e0a80d72158d1a56c70237a2c12b32b237b383","tree_id":"2998c9e90d00effc80e88e6562fbea42d20f1c7a","message":"fix: harden page recovery and chapter navigation (#395)","timestamp":"2026-04-02T08:58:55Z","author":{"name":"syokounya","email":"93929783+syokounya@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23969581474,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFlLLJog","head_branch":"main","head_sha":"77e0a80d72158d1a56c70237a2c12b32b237b383","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":100,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":63289590630,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOvFqDZg","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23969581474","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23969581474","pull_requests":[],"created_at":"2026-04-04T02:39:07Z","updated_at":"2026-04-04T02:39:08Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-04T02:39:07Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23969581474/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23969581474/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63289590630","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23969581474/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23969581474/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23969581474/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"77e0a80d72158d1a56c70237a2c12b32b237b383","tree_id":"2998c9e90d00effc80e88e6562fbea42d20f1c7a","message":"fix: harden page recovery and chapter navigation (#395)","timestamp":"2026-04-02T08:58:55Z","author":{"name":"syokounya","email":"93929783+syokounya@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23958205726,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFlAU1Hg","head_branch":"main","head_sha":"77e0a80d72158d1a56c70237a2c12b32b237b383","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":99,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":63256920847,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOumgDDw","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23958205726","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23958205726","pull_requests":[],"created_at":"2026-04-03T18:55:21Z","updated_at":"2026-04-03T18:55:22Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-03T18:55:21Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23958205726/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23958205726/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63256920847","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23958205726/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23958205726/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23958205726/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"77e0a80d72158d1a56c70237a2c12b32b237b383","tree_id":"2998c9e90d00effc80e88e6562fbea42d20f1c7a","message":"fix: harden page recovery and chapter navigation (#395)","timestamp":"2026-04-02T08:58:55Z","author":{"name":"syokounya","email":"93929783+syokounya@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23947464491,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFk2FPKw","head_branch":"main","head_sha":"77e0a80d72158d1a56c70237a2c12b32b237b383","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":98,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":63223243938,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOuGYkog","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23947464491","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23947464491","pull_requests":[],"created_at":"2026-04-03T13:15:08Z","updated_at":"2026-04-03T13:15:09Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-03T13:15:08Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23947464491/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23947464491/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63223243938","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23947464491/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23947464491/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23947464491/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"77e0a80d72158d1a56c70237a2c12b32b237b383","tree_id":"2998c9e90d00effc80e88e6562fbea42d20f1c7a","message":"fix: harden page recovery and chapter navigation (#395)","timestamp":"2026-04-02T08:58:55Z","author":{"name":"syokounya","email":"93929783+syokounya@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23937894897,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFks9J8Q","head_branch":"main","head_sha":"77e0a80d72158d1a56c70237a2c12b32b237b383","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":97,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":63194817144,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOtrRieA","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23937894897","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23937894897","pull_requests":[],"created_at":"2026-04-03T07:17:28Z","updated_at":"2026-04-03T07:17:29Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-03T07:17:28Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23937894897/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23937894897/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63194817144","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23937894897/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23937894897/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23937894897/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"77e0a80d72158d1a56c70237a2c12b32b237b383","tree_id":"2998c9e90d00effc80e88e6562fbea42d20f1c7a","message":"fix: harden page recovery and chapter navigation (#395)","timestamp":"2026-04-02T08:58:55Z","author":{"name":"syokounya","email":"93929783+syokounya@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23931542572,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFkm5cLA","head_branch":"main","head_sha":"77e0a80d72158d1a56c70237a2c12b32b237b383","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":96,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":63177894139,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOtbIo-w","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23931542572","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23931542572","pull_requests":[],"created_at":"2026-04-03T02:48:52Z","updated_at":"2026-04-03T02:48:53Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-03T02:48:52Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23931542572/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23931542572/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63177894139","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23931542572/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23931542572/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23931542572/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"77e0a80d72158d1a56c70237a2c12b32b237b383","tree_id":"2998c9e90d00effc80e88e6562fbea42d20f1c7a","message":"fix: harden page recovery and chapter navigation (#395)","timestamp":"2026-04-02T08:58:55Z","author":{"name":"syokounya","email":"93929783+syokounya@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23917157522,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFkZLckg","head_branch":"main","head_sha":"77e0a80d72158d1a56c70237a2c12b32b237b383","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":95,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":63135940764,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOszIAnA","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23917157522","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23917157522","pull_requests":[],"created_at":"2026-04-02T19:03:25Z","updated_at":"2026-04-02T19:03:26Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-02T19:03:25Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23917157522/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23917157522/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63135940764","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23917157522/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23917157522/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23917157522/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"77e0a80d72158d1a56c70237a2c12b32b237b383","tree_id":"2998c9e90d00effc80e88e6562fbea42d20f1c7a","message":"fix: harden page recovery and chapter navigation (#395)","timestamp":"2026-04-02T08:58:55Z","author":{"name":"syokounya","email":"93929783+syokounya@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23902717157,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFkLaE5Q","head_branch":"main","head_sha":"77e0a80d72158d1a56c70237a2c12b32b237b383","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":94,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":63089076243,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOsGboEw","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23902717157","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23902717157","pull_requests":[],"created_at":"2026-04-02T13:26:34Z","updated_at":"2026-04-02T13:26:35Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-02T13:26:34Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23902717157/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23902717157/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63089076243","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23902717157/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23902717157/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23902717157/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"77e0a80d72158d1a56c70237a2c12b32b237b383","tree_id":"2998c9e90d00effc80e88e6562fbea42d20f1c7a","message":"fix: harden page recovery and chapter navigation (#395)","timestamp":"2026-04-02T08:58:55Z","author":{"name":"syokounya","email":"93929783+syokounya@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23892656683,"name":"Lint","node_id":"WFR_kwLOHhoLA88AAAAFkB0CKw","head_branch":"main","head_sha":"77e0a80d72158d1a56c70237a2c12b32b237b383","path":".github/workflows/lint.yml","display_title":"fix: harden page recovery and chapter navigation (#395)","run_number":13,"event":"push","status":"completed","conclusion":"success","workflow_id":253260226,"check_suite_id":63057918939,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOrot72w","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23892656683","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23892656683","pull_requests":[],"created_at":"2026-04-02T08:58:58Z","updated_at":"2026-04-02T08:59:25Z","actor":{"login":"huan-yp","id":85162020,"node_id":"MDQ6VXNlcjg1MTYyMDIw","avatar_url":"https://avatars.githubusercontent.com/u/85162020?v=4","gravatar_id":"","url":"https://api.github.com/users/huan-yp","html_url":"https://github.com/huan-yp","followers_url":"https://api.github.com/users/huan-yp/followers","following_url":"https://api.github.com/users/huan-yp/following{/other_user}","gists_url":"https://api.github.com/users/huan-yp/gists{/gist_id}","starred_url":"https://api.github.com/users/huan-yp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/huan-yp/subscriptions","organizations_url":"https://api.github.com/users/huan-yp/orgs","repos_url":"https://api.github.com/users/huan-yp/repos","events_url":"https://api.github.com/users/huan-yp/events{/privacy}","received_events_url":"https://api.github.com/users/huan-yp/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-02T08:58:58Z","triggering_actor":{"login":"huan-yp","id":85162020,"node_id":"MDQ6VXNlcjg1MTYyMDIw","avatar_url":"https://avatars.githubusercontent.com/u/85162020?v=4","gravatar_id":"","url":"https://api.github.com/users/huan-yp","html_url":"https://github.com/huan-yp","followers_url":"https://api.github.com/users/huan-yp/followers","following_url":"https://api.github.com/users/huan-yp/following{/other_user}","gists_url":"https://api.github.com/users/huan-yp/gists{/gist_id}","starred_url":"https://api.github.com/users/huan-yp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/huan-yp/subscriptions","organizations_url":"https://api.github.com/users/huan-yp/orgs","repos_url":"https://api.github.com/users/huan-yp/repos","events_url":"https://api.github.com/users/huan-yp/events{/privacy}","received_events_url":"https://api.github.com/users/huan-yp/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23892656683/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23892656683/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63057918939","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23892656683/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23892656683/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23892656683/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/253260226","head_commit":{"id":"77e0a80d72158d1a56c70237a2c12b32b237b383","tree_id":"2998c9e90d00effc80e88e6562fbea42d20f1c7a","message":"fix: harden page recovery and chapter navigation (#395)","timestamp":"2026-04-02T08:58:55Z","author":{"name":"syokounya","email":"93929783+syokounya@users.noreply.github.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23891911883,"name":"Lint","node_id":"WFR_kwLOHhoLA88AAAAFkBGkyw","head_branch":"main","head_sha":"5c276f1f1d9239a577e9dfffb54a5042b844307f","path":".github/workflows/lint.yml","display_title":"fix: ǿҳָ½ڵȶ ","run_number":12,"event":"pull_request","status":"completed","conclusion":"success","workflow_id":253260226,"check_suite_id":63055673298,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOrmk30g","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23891911883","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23891911883","pull_requests":[],"created_at":"2026-04-02T08:39:25Z","updated_at":"2026-04-02T08:39:54Z","actor":{"login":"syokounya","id":93929783,"node_id":"U_kgDOBZlBNw","avatar_url":"https://avatars.githubusercontent.com/u/93929783?v=4","gravatar_id":"","url":"https://api.github.com/users/syokounya","html_url":"https://github.com/syokounya","followers_url":"https://api.github.com/users/syokounya/followers","following_url":"https://api.github.com/users/syokounya/following{/other_user}","gists_url":"https://api.github.com/users/syokounya/gists{/gist_id}","starred_url":"https://api.github.com/users/syokounya/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/syokounya/subscriptions","organizations_url":"https://api.github.com/users/syokounya/orgs","repos_url":"https://api.github.com/users/syokounya/repos","events_url":"https://api.github.com/users/syokounya/events{/privacy}","received_events_url":"https://api.github.com/users/syokounya/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-02T08:39:25Z","triggering_actor":{"login":"syokounya","id":93929783,"node_id":"U_kgDOBZlBNw","avatar_url":"https://avatars.githubusercontent.com/u/93929783?v=4","gravatar_id":"","url":"https://api.github.com/users/syokounya","html_url":"https://github.com/syokounya","followers_url":"https://api.github.com/users/syokounya/followers","following_url":"https://api.github.com/users/syokounya/following{/other_user}","gists_url":"https://api.github.com/users/syokounya/gists{/gist_id}","starred_url":"https://api.github.com/users/syokounya/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/syokounya/subscriptions","organizations_url":"https://api.github.com/users/syokounya/orgs","repos_url":"https://api.github.com/users/syokounya/repos","events_url":"https://api.github.com/users/syokounya/events{/privacy}","received_events_url":"https://api.github.com/users/syokounya/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23891911883/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23891911883/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63055673298","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23891911883/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23891911883/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23891911883/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/253260226","head_commit":{"id":"5c276f1f1d9239a577e9dfffb54a5042b844307f","tree_id":"2998c9e90d00effc80e88e6562fbea42d20f1c7a","message":"fix: harden page recovery and chapter navigation","timestamp":"2026-04-02T03:36:20Z","author":{"name":"syokounya","email":"syokounya0828@gmail.com"},"committer":{"name":"syokounya","email":"syokounya0828@gmail.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":1179848710,"node_id":"R_kgDORlMQBg","name":"AutoWSGR","full_name":"syokounya/AutoWSGR","private":false,"owner":{"login":"syokounya","id":93929783,"node_id":"U_kgDOBZlBNw","avatar_url":"https://avatars.githubusercontent.com/u/93929783?v=4","gravatar_id":"","url":"https://api.github.com/users/syokounya","html_url":"https://github.com/syokounya","followers_url":"https://api.github.com/users/syokounya/followers","following_url":"https://api.github.com/users/syokounya/following{/other_user}","gists_url":"https://api.github.com/users/syokounya/gists{/gist_id}","starred_url":"https://api.github.com/users/syokounya/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/syokounya/subscriptions","organizations_url":"https://api.github.com/users/syokounya/orgs","repos_url":"https://api.github.com/users/syokounya/repos","events_url":"https://api.github.com/users/syokounya/events{/privacy}","received_events_url":"https://api.github.com/users/syokounya/received_events","type":"User","user_view_type":"public","site_admin":false},"html_url":"https://github.com/syokounya/AutoWSGR","description":"սŮRȫͰ","fork":true,"url":"https://api.github.com/repos/syokounya/AutoWSGR","forks_url":"https://api.github.com/repos/syokounya/AutoWSGR/forks","keys_url":"https://api.github.com/repos/syokounya/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/syokounya/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/syokounya/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/syokounya/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/syokounya/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/syokounya/AutoWSGR/events","assignees_url":"https://api.github.com/repos/syokounya/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/syokounya/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/syokounya/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/syokounya/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/syokounya/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/syokounya/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/syokounya/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/syokounya/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/syokounya/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/syokounya/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/syokounya/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/syokounya/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/syokounya/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/syokounya/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/syokounya/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/syokounya/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/syokounya/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/syokounya/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/syokounya/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/syokounya/AutoWSGR/merges","archive_url":"https://api.github.com/repos/syokounya/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/syokounya/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/syokounya/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/syokounya/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/syokounya/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/syokounya/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/syokounya/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/syokounya/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/syokounya/AutoWSGR/deployments"}},{"id":23889006308,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFj-VO5A","head_branch":"main","head_sha":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":93,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":63047307737,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOremR2Q","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23889006308","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23889006308","pull_requests":[],"created_at":"2026-04-02T07:21:00Z","updated_at":"2026-04-02T07:21:01Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-02T07:21:00Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23889006308/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23889006308/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63047307737","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23889006308/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23889006308/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23889006308/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","tree_id":"57d2c142267649a540cdb46fd868e39b57bfb5a2","message":"feat: quick repair retry (#394)\n\n* quick repair retry\n\n* [pre-commit.ci] auto fixes from pre-commit.com hooks\n\nfor more information, see https://pre-commit.ci\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>","timestamp":"2026-03-31T09:45:37Z","author":{"name":"KUAI","email":"ekuai@foxmail.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23881218529,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFj2554Q","head_branch":"main","head_sha":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":92,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":63026316384,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOrKlEYA","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23881218529","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23881218529","pull_requests":[],"created_at":"2026-04-02T02:46:08Z","updated_at":"2026-04-02T02:46:09Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-02T02:46:08Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23881218529/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23881218529/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/63026316384","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23881218529/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23881218529/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23881218529/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","tree_id":"57d2c142267649a540cdb46fd868e39b57bfb5a2","message":"feat: quick repair retry (#394)\n\n* quick repair retry\n\n* [pre-commit.ci] auto fixes from pre-commit.com hooks\n\nfor more information, see https://pre-commit.ci\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>","timestamp":"2026-03-31T09:45:37Z","author":{"name":"KUAI","email":"ekuai@foxmail.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23866101683,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFjofPsw","head_branch":"main","head_sha":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":91,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":62981311854,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOqfqNbg","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23866101683","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23866101683","pull_requests":[],"created_at":"2026-04-01T19:10:33Z","updated_at":"2026-04-01T19:10:34Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-01T19:10:33Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23866101683/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23866101683/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/62981311854","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23866101683/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23866101683/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23866101683/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","tree_id":"57d2c142267649a540cdb46fd868e39b57bfb5a2","message":"feat: quick repair retry (#394)\n\n* quick repair retry\n\n* [pre-commit.ci] auto fixes from pre-commit.com hooks\n\nfor more information, see https://pre-commit.ci\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>","timestamp":"2026-03-31T09:45:37Z","author":{"name":"KUAI","email":"ekuai@foxmail.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23851946501,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFja_SBQ","head_branch":"main","head_sha":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":90,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":62934235612,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOpyw53A","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23851946501","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23851946501","pull_requests":[],"created_at":"2026-04-01T13:47:53Z","updated_at":"2026-04-01T13:47:54Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-01T13:47:53Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23851946501/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23851946501/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/62934235612","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23851946501/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23851946501/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23851946501/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","tree_id":"57d2c142267649a540cdb46fd868e39b57bfb5a2","message":"feat: quick repair retry (#394)\n\n* quick repair retry\n\n* [pre-commit.ci] auto fixes from pre-commit.com hooks\n\nfor more information, see https://pre-commit.ci\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>","timestamp":"2026-03-31T09:45:37Z","author":{"name":"KUAI","email":"ekuai@foxmail.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23837688033,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFjNZA4Q","head_branch":"main","head_sha":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":89,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":62889571829,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOpIK19Q","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23837688033","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23837688033","pull_requests":[],"created_at":"2026-04-01T07:42:07Z","updated_at":"2026-04-01T07:42:08Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-01T07:42:07Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23837688033/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23837688033/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/62889571829","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23837688033/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23837688033/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23837688033/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","tree_id":"57d2c142267649a540cdb46fd868e39b57bfb5a2","message":"feat: quick repair retry (#394)\n\n* quick repair retry\n\n* [pre-commit.ci] auto fixes from pre-commit.com hooks\n\nfor more information, see https://pre-commit.ci\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>","timestamp":"2026-03-31T09:45:37Z","author":{"name":"KUAI","email":"ekuai@foxmail.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23830299495,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFjGWDZw","head_branch":"main","head_sha":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":88,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":62868399833,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOoz-m2Q","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23830299495","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23830299495","pull_requests":[],"created_at":"2026-04-01T03:20:04Z","updated_at":"2026-04-01T03:20:04Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-04-01T03:20:04Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23830299495/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23830299495/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/62868399833","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23830299495/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23830299495/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23830299495/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","tree_id":"57d2c142267649a540cdb46fd868e39b57bfb5a2","message":"feat: quick repair retry (#394)\n\n* quick repair retry\n\n* [pre-commit.ci] auto fixes from pre-commit.com hooks\n\nfor more information, see https://pre-commit.ci\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>","timestamp":"2026-03-31T09:45:37Z","author":{"name":"KUAI","email":"ekuai@foxmail.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23814811476,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFi3kvVA","head_branch":"main","head_sha":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":87,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":62821967453,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOoHsmXQ","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23814811476","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23814811476","pull_requests":[],"created_at":"2026-03-31T19:09:17Z","updated_at":"2026-03-31T19:09:19Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-03-31T19:09:17Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23814811476/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23814811476/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/62821967453","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23814811476/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23814811476/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23814811476/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","tree_id":"57d2c142267649a540cdb46fd868e39b57bfb5a2","message":"feat: quick repair retry (#394)\n\n* quick repair retry\n\n* [pre-commit.ci] auto fixes from pre-commit.com hooks\n\nfor more information, see https://pre-commit.ci\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>","timestamp":"2026-03-31T09:45:37Z","author":{"name":"KUAI","email":"ekuai@foxmail.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23800635818,"name":"Sync upstream","node_id":"WFR_kwLOHhoLA88AAAAFiqDhqg","head_branch":"main","head_sha":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","path":".github/workflows/sync-upstream.yml","display_title":"Sync upstream","run_number":86,"event":"schedule","status":"completed","conclusion":"skipped","workflow_id":244437590,"check_suite_id":62775432391,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOnbUUxw","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23800635818","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23800635818","pull_requests":[],"created_at":"2026-03-31T13:45:28Z","updated_at":"2026-03-31T13:45:29Z","actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-03-31T13:45:28Z","triggering_actor":{"login":"yltx","id":37734213,"node_id":"MDQ6VXNlcjM3NzM0MjEz","avatar_url":"https://avatars.githubusercontent.com/u/37734213?v=4","gravatar_id":"","url":"https://api.github.com/users/yltx","html_url":"https://github.com/yltx","followers_url":"https://api.github.com/users/yltx/followers","following_url":"https://api.github.com/users/yltx/following{/other_user}","gists_url":"https://api.github.com/users/yltx/gists{/gist_id}","starred_url":"https://api.github.com/users/yltx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yltx/subscriptions","organizations_url":"https://api.github.com/users/yltx/orgs","repos_url":"https://api.github.com/users/yltx/repos","events_url":"https://api.github.com/users/yltx/events{/privacy}","received_events_url":"https://api.github.com/users/yltx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23800635818/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23800635818/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/62775432391","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23800635818/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23800635818/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23800635818/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/244437590","head_commit":{"id":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","tree_id":"57d2c142267649a540cdb46fd868e39b57bfb5a2","message":"feat: quick repair retry (#394)\n\n* quick repair retry\n\n* [pre-commit.ci] auto fixes from pre-commit.com hooks\n\nfor more information, see https://pre-commit.ci\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>","timestamp":"2026-03-31T09:45:37Z","author":{"name":"KUAI","email":"ekuai@foxmail.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23791041751,"name":"Lint","node_id":"WFR_kwLOHhoLA88AAAAFig581w","head_branch":"main","head_sha":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","path":".github/workflows/lint.yml","display_title":"feat: quick repair retry (#394)","run_number":11,"event":"push","status":"completed","conclusion":"success","workflow_id":253260226,"check_suite_id":62744802505,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOm-G0yQ","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23791041751","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23791041751","pull_requests":[],"created_at":"2026-03-31T09:45:40Z","updated_at":"2026-03-31T09:46:06Z","actor":{"login":"kuainx","id":22209650,"node_id":"MDQ6VXNlcjIyMjA5NjUw","avatar_url":"https://avatars.githubusercontent.com/u/22209650?v=4","gravatar_id":"","url":"https://api.github.com/users/kuainx","html_url":"https://github.com/kuainx","followers_url":"https://api.github.com/users/kuainx/followers","following_url":"https://api.github.com/users/kuainx/following{/other_user}","gists_url":"https://api.github.com/users/kuainx/gists{/gist_id}","starred_url":"https://api.github.com/users/kuainx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kuainx/subscriptions","organizations_url":"https://api.github.com/users/kuainx/orgs","repos_url":"https://api.github.com/users/kuainx/repos","events_url":"https://api.github.com/users/kuainx/events{/privacy}","received_events_url":"https://api.github.com/users/kuainx/received_events","type":"User","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-03-31T09:45:40Z","triggering_actor":{"login":"kuainx","id":22209650,"node_id":"MDQ6VXNlcjIyMjA5NjUw","avatar_url":"https://avatars.githubusercontent.com/u/22209650?v=4","gravatar_id":"","url":"https://api.github.com/users/kuainx","html_url":"https://github.com/kuainx","followers_url":"https://api.github.com/users/kuainx/followers","following_url":"https://api.github.com/users/kuainx/following{/other_user}","gists_url":"https://api.github.com/users/kuainx/gists{/gist_id}","starred_url":"https://api.github.com/users/kuainx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kuainx/subscriptions","organizations_url":"https://api.github.com/users/kuainx/orgs","repos_url":"https://api.github.com/users/kuainx/repos","events_url":"https://api.github.com/users/kuainx/events{/privacy}","received_events_url":"https://api.github.com/users/kuainx/received_events","type":"User","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23791041751/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23791041751/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/62744802505","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23791041751/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23791041751/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23791041751/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/253260226","head_commit":{"id":"1b9fb1ec4ed2236b1f50ca235cb760c761a8bdb4","tree_id":"57d2c142267649a540cdb46fd868e39b57bfb5a2","message":"feat: quick repair retry (#394)\n\n* quick repair retry\n\n* [pre-commit.ci] auto fixes from pre-commit.com hooks\n\nfor more information, see https://pre-commit.ci\n\n---------\n\nCo-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>","timestamp":"2026-03-31T09:45:37Z","author":{"name":"KUAI","email":"ekuai@foxmail.com"},"committer":{"name":"GitHub","email":"noreply@github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"}},{"id":23790790019,"name":"Lint","node_id":"WFR_kwLOHhoLA88AAAAFigqlgw","head_branch":"quick-repair","head_sha":"daf3afb0c5dafe933e5512d26e80535219a21509","path":".github/workflows/lint.yml","display_title":"feat: quick repair retry","run_number":10,"event":"pull_request","status":"completed","conclusion":"success","workflow_id":253260226,"check_suite_id":62744035802,"check_suite_node_id":"CS_kwDOHhoLA88AAAAOm9YB2g","url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23790790019","html_url":"https://github.com/OpenWSGR/AutoWSGR/actions/runs/23790790019","pull_requests":[],"created_at":"2026-03-31T09:39:30Z","updated_at":"2026-03-31T09:39:58Z","actor":{"login":"pre-commit-ci[bot]","id":66853113,"node_id":"MDM6Qm90NjY4NTMxMTM=","avatar_url":"https://avatars.githubusercontent.com/in/68672?v=4","gravatar_id":"","url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D","html_url":"https://github.com/apps/pre-commit-ci","followers_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/followers","following_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/repos","events_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"run_attempt":1,"referenced_workflows":[],"run_started_at":"2026-03-31T09:39:30Z","triggering_actor":{"login":"pre-commit-ci[bot]","id":66853113,"node_id":"MDM6Qm90NjY4NTMxMTM=","avatar_url":"https://avatars.githubusercontent.com/in/68672?v=4","gravatar_id":"","url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D","html_url":"https://github.com/apps/pre-commit-ci","followers_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/followers","following_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/following{/other_user}","gists_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/gists{/gist_id}","starred_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/subscriptions","organizations_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/orgs","repos_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/repos","events_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/events{/privacy}","received_events_url":"https://api.github.com/users/pre-commit-ci%5Bbot%5D/received_events","type":"Bot","user_view_type":"public","site_admin":false},"jobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23790790019/jobs","logs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23790790019/logs","check_suite_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/check-suites/62744035802","artifacts_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23790790019/artifacts","cancel_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23790790019/cancel","rerun_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/runs/23790790019/rerun","previous_attempt_url":null,"workflow_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/actions/workflows/253260226","head_commit":{"id":"daf3afb0c5dafe933e5512d26e80535219a21509","tree_id":"57d2c142267649a540cdb46fd868e39b57bfb5a2","message":"[pre-commit.ci] auto fixes from pre-commit.com hooks\n\nfor more information, see https://pre-commit.ci","timestamp":"2026-03-31T09:39:17Z","author":{"name":"pre-commit-ci[bot]","email":"66853113+pre-commit-ci[bot]@users.noreply.github.com"},"committer":{"name":"pre-commit-ci[bot]","email":"66853113+pre-commit-ci[bot]@users.noreply.github.com"}},"repository":{"id":505023235,"node_id":"R_kgDOHhoLAw","name":"AutoWSGR","full_name":"OpenWSGR/AutoWSGR","private":false,"owner":{"login":"OpenWSGR","id":186071259,"node_id":"O_kgDOCxc42w","avatar_url":"https://avatars.githubusercontent.com/u/186071259?v=4","gravatar_id":"","url":"https://api.github.com/users/OpenWSGR","html_url":"https://github.com/OpenWSGR","followers_url":"https://api.github.com/users/OpenWSGR/followers","following_url":"https://api.github.com/users/OpenWSGR/following{/other_user}","gists_url":"https://api.github.com/users/OpenWSGR/gists{/gist_id}","starred_url":"https://api.github.com/users/OpenWSGR/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OpenWSGR/subscriptions","organizations_url":"https://api.github.com/users/OpenWSGR/orgs","repos_url":"https://api.github.com/users/OpenWSGR/repos","events_url":"https://api.github.com/users/OpenWSGR/events{/privacy}","received_events_url":"https://api.github.com/users/OpenWSGR/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/OpenWSGR/AutoWSGR","description":"սŮRȫͰ","fork":false,"url":"https://api.github.com/repos/OpenWSGR/AutoWSGR","forks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/forks","keys_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/events","assignees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/merges","archive_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/OpenWSGR/AutoWSGR/deployments"},"head_repository":{"id":917691832,"node_id":"R_kgDONrLduA","name":"AutoWSGR","full_name":"kuainx/AutoWSGR","private":false,"owner":{"login":"kuainx","id":22209650,"node_id":"MDQ6VXNlcjIyMjA5NjUw","avatar_url":"https://avatars.githubusercontent.com/u/22209650?v=4","gravatar_id":"","url":"https://api.github.com/users/kuainx","html_url":"https://github.com/kuainx","followers_url":"https://api.github.com/users/kuainx/followers","following_url":"https://api.github.com/users/kuainx/following{/other_user}","gists_url":"https://api.github.com/users/kuainx/gists{/gist_id}","starred_url":"https://api.github.com/users/kuainx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kuainx/subscriptions","organizations_url":"https://api.github.com/users/kuainx/orgs","repos_url":"https://api.github.com/users/kuainx/repos","events_url":"https://api.github.com/users/kuainx/events{/privacy}","received_events_url":"https://api.github.com/users/kuainx/received_events","type":"User","user_view_type":"public","site_admin":false},"html_url":"https://github.com/kuainx/AutoWSGR","description":"սŮRȫͰ","fork":true,"url":"https://api.github.com/repos/kuainx/AutoWSGR","forks_url":"https://api.github.com/repos/kuainx/AutoWSGR/forks","keys_url":"https://api.github.com/repos/kuainx/AutoWSGR/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kuainx/AutoWSGR/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kuainx/AutoWSGR/teams","hooks_url":"https://api.github.com/repos/kuainx/AutoWSGR/hooks","issue_events_url":"https://api.github.com/repos/kuainx/AutoWSGR/issues/events{/number}","events_url":"https://api.github.com/repos/kuainx/AutoWSGR/events","assignees_url":"https://api.github.com/repos/kuainx/AutoWSGR/assignees{/user}","branches_url":"https://api.github.com/repos/kuainx/AutoWSGR/branches{/branch}","tags_url":"https://api.github.com/repos/kuainx/AutoWSGR/tags","blobs_url":"https://api.github.com/repos/kuainx/AutoWSGR/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kuainx/AutoWSGR/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kuainx/AutoWSGR/git/refs{/sha}","trees_url":"https://api.github.com/repos/kuainx/AutoWSGR/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kuainx/AutoWSGR/statuses/{sha}","languages_url":"https://api.github.com/repos/kuainx/AutoWSGR/languages","stargazers_url":"https://api.github.com/repos/kuainx/AutoWSGR/stargazers","contributors_url":"https://api.github.com/repos/kuainx/AutoWSGR/contributors","subscribers_url":"https://api.github.com/repos/kuainx/AutoWSGR/subscribers","subscription_url":"https://api.github.com/repos/kuainx/AutoWSGR/subscription","commits_url":"https://api.github.com/repos/kuainx/AutoWSGR/commits{/sha}","git_commits_url":"https://api.github.com/repos/kuainx/AutoWSGR/git/commits{/sha}","comments_url":"https://api.github.com/repos/kuainx/AutoWSGR/comments{/number}","issue_comment_url":"https://api.github.com/repos/kuainx/AutoWSGR/issues/comments{/number}","contents_url":"https://api.github.com/repos/kuainx/AutoWSGR/contents/{+path}","compare_url":"https://api.github.com/repos/kuainx/AutoWSGR/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kuainx/AutoWSGR/merges","archive_url":"https://api.github.com/repos/kuainx/AutoWSGR/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kuainx/AutoWSGR/downloads","issues_url":"https://api.github.com/repos/kuainx/AutoWSGR/issues{/number}","pulls_url":"https://api.github.com/repos/kuainx/AutoWSGR/pulls{/number}","milestones_url":"https://api.github.com/repos/kuainx/AutoWSGR/milestones{/number}","notifications_url":"https://api.github.com/repos/kuainx/AutoWSGR/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kuainx/AutoWSGR/labels{/name}","releases_url":"https://api.github.com/repos/kuainx/AutoWSGR/releases{/id}","deployments_url":"https://api.github.com/repos/kuainx/AutoWSGR/deployments"}}]} - diff --git a/.tmp_weekly_fix.ps1 b/.tmp_weekly_fix.ps1 deleted file mode 100644 index 433231a..0000000 --- a/.tmp_weekly_fix.ps1 +++ /dev/null @@ -1,93 +0,0 @@ -$utf8 = New-Object System.Text.UTF8Encoding($false) -function Get-Indent([string]$s){ $s.Length - $s.TrimStart(' ').Length } -function Is-PureString([string[]]$b){ - if($b.Count -ne 1){return $false} - if($b[0] -notmatch '^(\s*)-\s*(.*)$'){return $false} - $r=$matches[2].Trim(); if(!$r -or $r.StartsWith('#')){return $false} - if($r -match '^\{.*\}$' -or $r -match '^\[.*\]$' -or $r -match '^[^#]+:\s*'){return $false} - return $true -} -function Split-ItemBlocks([string[]]$lines,[int]$start,[int]$shipsIndent){ - $line=$lines[$start] - $line -match '^(\s*)-\s*(.*)$' | Out-Null - $itemIndent=$matches[1].Length - $block=New-Object System.Collections.Generic.List[string]; $block.Add($line) - $j=$start+1 - while($j -lt $lines.Length){ - $nl=$lines[$j]; $nt=$nl.Trim() - if($nt -ne '' -and -not $nl.TrimStart().StartsWith('#')){ - $nind=Get-Indent $nl - if($nind -le $shipsIndent){break} - if($nind -eq $itemIndent -and $nl -match '^\s*-\s*'){break} - } - $block.Add($nl); $j++ - } - return @($block,$j,$itemIndent) -} -$files=Get-ChildItem resource/builtin_plans -Filter '周常*.yaml' -File | Sort-Object Name -$rows=@() -foreach($f in $files){ - $lines=[IO.File]::ReadAllLines($f.FullName,[Text.Encoding]::UTF8) - $out=New-Object System.Collections.Generic.List[string] - $inFleet=$false;$fleetIndent=-1;$inShips=$false;$shipsIndent=-1 - $nameConverted=0;$shipTypeMinAdded=0;$unchanged=0 - for($i=0;$i -lt $lines.Length;){ - $line=$lines[$i];$t=$line.Trim() - if($inShips -and $t -ne '' -and -not $line.TrimStart().StartsWith('#') -and (Get-Indent $line) -le $shipsIndent){$inShips=$false} - if($inFleet -and $t -ne '' -and -not $line.TrimStart().StartsWith('#') -and (Get-Indent $line) -le $fleetIndent -and $line -notmatch '^\s*fleet_presets:\s*$'){$inFleet=$false;$inShips=$false} - if($line -match '^(\s*)fleet_presets:\s*$'){ $inFleet=$true;$fleetIndent=$matches[1].Length; $out.Add($line);$i++; continue } - if($inFleet -and $line -match '^(\s*)ships:\s*$'){ $inShips=$true;$shipsIndent=$matches[1].Length; $out.Add($line);$i++; continue } - if($inShips -and $line -match '^(\s*)-\s*(.*)$' -and $matches[1].Length -gt $shipsIndent){ - $res=Split-ItemBlocks $lines $i $shipsIndent; $block=[string[]]$res[0]; $j=[int]$res[1]; $itemIndent=[int]$res[2] - $changed=$false - if(Is-PureString $block){ - $block[0] -match '^(\s*)-\s*(.*)$' | Out-Null; $ws=$matches[1]; $rest=$matches[2].Trim(); $comment='' - if($rest -match '^(.*?)(\s+#.*)$'){ $rest=$matches[1].TrimEnd(); $comment=$matches[2] } - $out.Add("$ws- { name: $rest, min_level: 100 }$comment"); $nameConverted++; $changed=$true - } else { - $hasType=($block|Where-Object{$_ -match '\bship_type\s*:'}).Count -gt 0 - $hasMin=($block|Where-Object{$_ -match '\bmin_level\s*:'}).Count -gt 0 - if($hasType -and -not $hasMin){ - $first=$block[0] - if($block.Count -eq 1 -and $first -match '^(\s*)-\s*(.*)$'){ - $ws=$matches[1]; $body=$matches[2].Trim(); $comment='' - if($body -match '^(.*?)(\s+#.*)$'){ $body=$matches[1].TrimEnd(); $comment=$matches[2] } - if($body -match '^\{(.*)\}$'){ $inner=$matches[1].Trim(); $newBody = if($inner){"{ $inner, min_level: 100 }"}else{'{ min_level: 100 }'}; $out.Add("$ws- $newBody$comment") } - else { $out.Add($first); $out.Add((' ' * ($itemIndent+2)) + 'min_level: 100') } - } else { foreach($b in $block){$out.Add($b)}; $out.Add((' ' * ($itemIndent+2)) + 'min_level: 100') } - $shipTypeMinAdded++; $changed=$true - } - } - if(-not $changed){ foreach($b in $block){$out.Add($b)}; $unchanged++ } - $i=$j; continue - } - $out.Add($line); $i++ - } - [IO.File]::WriteAllLines($f.FullName,$out,$utf8) - $rows += [pscustomobject]@{File=$f.Name;nameConverted=$nameConverted;shipTypeMinAdded=$shipTypeMinAdded;unchanged=$unchanged} -} -$rows | Format-Table -AutoSize - -$pure=0;$missing=0 -foreach($f in $files){ - $lines=[IO.File]::ReadAllLines($f.FullName,[Text.Encoding]::UTF8) - $inFleet=$false;$fleetIndent=-1;$inShips=$false;$shipsIndent=-1 - for($i=0;$i -lt $lines.Length;){ - $line=$lines[$i];$t=$line.Trim() - if($inShips -and $t -ne '' -and -not $line.TrimStart().StartsWith('#') -and (Get-Indent $line) -le $shipsIndent){$inShips=$false} - if($inFleet -and $t -ne '' -and -not $line.TrimStart().StartsWith('#') -and (Get-Indent $line) -le $fleetIndent -and $line -notmatch '^\s*fleet_presets:\s*$'){$inFleet=$false;$inShips=$false} - if($line -match '^(\s*)fleet_presets:\s*$'){ $inFleet=$true;$fleetIndent=$matches[1].Length; $i++; continue } - if($inFleet -and $line -match '^(\s*)ships:\s*$'){ $inShips=$true;$shipsIndent=$matches[1].Length; $i++; continue } - if($inShips -and $line -match '^(\s*)-\s*(.*)$' -and $matches[1].Length -gt $shipsIndent){ - $res=Split-ItemBlocks $lines $i $shipsIndent; $block=[string[]]$res[0]; $j=[int]$res[1] - if(Is-PureString $block){$pure++} - $hasType=($block|Where-Object{$_ -match '\bship_type\s*:'}).Count -gt 0 - $hasMin=($block|Where-Object{$_ -match '\bmin_level\s*:'}).Count -gt 0 - if($hasType -and -not $hasMin){$missing++} - $i=$j; continue - } - $i++ - } -} -"pureStringRemain=$pure shipTypeNoMinRemain=$missing" -if($pure -eq 0 -and $missing -eq 0){ 'WEEKLY_SHIPS_LEVEL_RULES_OK' } diff --git a/README.md b/README.md index 9229808..27885a5 100644 --- a/README.md +++ b/README.md @@ -1,140 +1,238 @@ -# AutoWSGR GUI - -[AutoWSGR](https://github.com/OpenWSGR/AutoWSGR) 的桌面图形界面,基于 Electron + TypeScript 构建。 - -## 当前 GUI 已实现功能 - -- **主页** - - 连接状态与远征倒计时展示 - - 手动运维操作(收远征 / 收奖励 / 收建造 / 食堂烹饪 / 浴室修理) - - 任务队列开始、停止、清空 - - 任务组管理(新建、重命名、删除、导入导出、整组入队) - - 后端日志实时查看与等级过滤 -- **方案预览** - - 导入 YAML 或从地图新建方案 - - 节点路线可视化与节点级参数编辑 - - 方案级参数配置(修理策略、战况、编队、次数、间隔、终止条件) - - 编队预设与泡澡修理阈值配置 - - 一键加入队列 / 加入任务组 / 保存 YAML / 另存为 -- **模板库** - - 支持普通出击、演习、战役、决战四类模板 - - 模板导入、创建、详情配置、加入任务列表 -- **配置页** - - 模拟器类型、路径、ADB 串号检测 - - Python 解释器路径检测与后端端口设置 - - 自动更新模式与手动检查更新 - - 每日自动任务(远征、战役、演习、常规出击、决战、战利品) - - 主题模式、主色调、调试模式 -- **调度与运行** - - 任务优先级调度 - - 条件停止与失败重试 - - 启动流程检查与运行期日志可观测 - -## 安装 +# AutoWSGR-GUI + +[AutoWSGR](https://github.com/OpenWSGR/AutoWSGR) 的 Windows 桌面图形界面,使用 Electron、TypeScript 和 SCSS 构建。 + +GUI 负责配置、编辑和管理 YAML,并通过 HTTP 与 WebSocket 连接 AutoWSGR 后端。后端模型和 YAML 契约是功能的事实来源,GUI 不额外定义后端不支持的字段或规则。 + +## 功能总览 + +当前主导航分为 **作战**、**计划** 和 **设置**。 + +### 作战 + +- 展示当前任务、剩余次数、任务进度、运行状态和远征倒计时。 +- 导入出征 YAML,或从计划管理中选择已有计划。 +- 管理任务列表:新建、保存、加载及整组加入队列。 +- 管理任务队列:开始、停止和清空。 +- 提供收取远征、收取奖励、收取建造、食堂烹饪和浴室修理等快捷操作。 +- 实时显示后端日志,并支持按日志等级筛选。 +- 当前任务携带明确编队时,在舰队预览中展示最多六艘舰船立绘; + 没有任务执行时显示空状态。 + +### 计划 + +计划页用于生成、保存和管理 YAML,不直接执行出征任务。完成编辑后,需要回到作战页将计划加入任务列表和任务队列。 + +#### 舰队规划 + +- 使用本地舰船资料库展示舰船立绘和资料。 +- 支持舰名或编号搜索、舰种和国籍多选、改造过滤及多种排序方式。 +- 编辑六个主选位置,以及每个位置独立的备选队列。 +- 支持主选、备选和舰船图鉴之间拖拽,空位自动整理到右侧。 +- 支持纯备选位置、位置级等级限制及复制备选队列。 +- 支持新建、保存和加载;未保存修改与同名覆盖均会二次确认。 +- 用户舰队保存为 `resource/user_team_plans/team-{预设名称}.yaml`。 + +舰队 YAML 支持主选舰船和位置级 `candidates`。一个位置也可以没有主选 `name`,只保留非空的结构化 `candidates`。 + +#### 出征规划 + +- 编辑地图章节、关卡、执行次数、轮次间隔和舰队编号。 +- 配置战况、维修策略、维修方式、战利品停止条件和掉落停止条件。 +- 选择并预览一个或多个舰队方案。 +- 通过地图编辑节点启用状态、终点、迂回、阵型、战斗动作、最低战果和索敌规则。 +- 支持新建、保存和加载;保存时校验文件名、地图信息及 YAML 内容。 +- 用户计划保存为 `resource/user_battle_plans/bettle-{预设名称}.yaml`。 + +出征规划当前没有直接执行入口。保存后的计划应在作战页加载并加入队列。 + +#### 决战计划(旧) + +保留旧版决战计划配置入口,用于现有决战流程。该页面属于兼容功能,不代表新的统一 YAML 任务设计。 + +#### 计划管理 + +- 汇总系统和用户的出征计划、舰队方案及关联状态。 +- 支持按来源、类型、名称和“仅看需要处理”筛选。 +- 标记舰队缺失、未被引用或 YAML 无法读取等状态。 +- 支持从管理列表跳转到舰队规划或出征规划并加载对应文件。 +- 用户 YAML 可以删除;系统 YAML 在界面中按只读资源处理。 +- 对不需要关联舰队的 YAML,可以忽略未关联提示并随时恢复。 + +### 设置 + +设置页分为 **系统设置** 和 **脚本行为**。 + +系统设置包括: + +- 模拟器类型、路径、账号和 ADB 地址。 +- ADB 主动连接、断开、自动检测及在线状态。 +- 自动远征、战役、演习、出征和胖次任务。 +- 日志等级、日志目录和调试模式。 +- Python 路径、后端地址、后端启动模式及本地 AutoWSGR 仓库路径。 +- 默认窗口大小、记录退出时窗口位置和大小。 +- GUI 更新模式、舰船数据库更新。 +- 亮色、暗色、跟随系统主题及主色调。 + +脚本行为包括: + +- 全局操作延迟。 +- OCR 下载源、加速模式、CUDA 路径和硬件识别。 +- 舰名匹配置信度、系统舰名规则、自定义舰名映射和识别纠错规则。 +- 舰队、船坞、维修、解装及自定义作战方案目录等后端配置。 + +## 推荐使用流程 + +1. 在设置页配置模拟器、ADB、Python 和后端启动模式。 +2. 按需更新舰船数据库。 +3. 在舰队规划中创建并保存舰队方案。 +4. 在出征规划中创建计划、关联舰队并保存 YAML。 +5. 在计划管理中检查计划与舰队的关联状态。 +6. 回到作战页加载计划,加入任务列表和任务队列后执行。 + +## 安装与运行 ### 普通用户 -1. 安装 Android 模拟器(MuMu 12 / 雷电 / 蓝叠) -2. 从 [Releases](https://github.com/yltx/AutoWSGR-GUI/releases) 下载最新安装包 -3. 安装运行,程序自动配置环境(下载便携 Python 3.12、安装 autowsgr 依赖到程序目录,**不影响系统环境**) -4. 确保模拟器已运行,程序自动检测并连接 +1. 安装并启动 MuMu 12、雷电或 BlueStacks。 +2. 从 [Releases](https://github.com/yltx/AutoWSGR-GUI/releases) 下载 Windows x64 安装包。 +3. 安装并启动 AutoWSGR-GUI。 +4. 在设置页确认模拟器、ADB 地址和后端环境。 + +默认的 `managed` 模式由 GUI 管理 Python 和 AutoWSGR 依赖。依赖安装到程序自己的 `python/site-packages/`,不会写入系统 Python 的全局包目录。 + +遇到环境问题时,可以运行 `debug_deps.bat` 生成诊断信息。 + +### 源码运行 -> 如果你已有 Python ≥ 3.12,程序也可以使用它(依赖仍安装到 `python/site-packages/`,不修改全局包)。 -> -> 遇到问题时可运行 `debug_deps.bat` 生成诊断报告。 +前置要求: -### 开发者 +- Windows 10/11 +- Node.js 18 或更高版本 +- npm +- AutoWSGR 后端需要 Python 3.12 或 3.13 -```bash +```powershell git clone https://github.com/yltx/AutoWSGR-GUI.git cd AutoWSGR-GUI npm install -setup.bat # 安装便携 Python + autowsgr 依赖 -npm run dev # 编译 + 启动 Electron +npm run dev ``` -## 用户文档 +项目没有热重载。修改代码后需要退出当前 Electron 实例,再次运行 `npm run dev`。 -- GUI 操作指南(含“从方案预览页开始的新建任务配置流程”):[docs/user-guide.md](docs/user-guide.md) -- YAML 关键字说明(战斗方案编写):[docs/plan-guide.md](docs/plan-guide.md) +## 后端启动模式 -## 编写战斗方案 +### managed -参见 [docs/plan-guide.md](docs/plan-guide.md),详细说明 YAML 方案的所有关键字和用法。 +适合普通用户: -`plans/` 目录提供了多个示例方案可供参考。 +- GUI 查找或准备可用的 Python。 +- AutoWSGR 及依赖由 GUI 安装到本地 `python/site-packages/`。 +- GUI 启动并管理 uvicorn 后端进程。 +- 自动更新策略由设置页的更新模式控制。 -## 项目结构 +### external -```text -├── electron/ # Electron 主进程 -│ ├── main.ts # 窗口管理、IPC 注册、应用生命周期 -│ ├── preload.ts # contextBridge 安全桥接 -│ ├── backend.ts # Python 后端进程管理 -│ ├── emulatorDetect.ts # 模拟器注册表检测 -│ └── pythonEnv/ # Python 环境检查、安装、更新(7 个模块) -├── src/ -│ ├── controller/ # 控制器层 — 业务逻辑与调度 -│ │ ├── app/ # AppController、ConfigController、SchedulerBinder -│ │ ├── plan/ # PlanController(方案编辑) -│ │ ├── startup/ # StartupController(启动流程) -│ │ ├── taskGroup/ # TaskGroupController -│ │ ├── template/ # TemplateController -│ │ └── shared/ # ControllerHost 接口 -│ ├── model/ # 模型层 — 数据、API、调度 -│ │ ├── ApiClient.ts # HTTP + WebSocket 通信 -│ │ ├── ConfigModel.ts # 用户配置读写 -│ │ ├── PlanModel.ts # 方案数据 & YAML 序列化 -│ │ ├── scheduler/ # Scheduler、CronScheduler、TaskQueue -│ │ ├── TaskGroupModel.ts -│ │ └── TemplateModel.ts -│ ├── view/ # 视图层 — 纯 DOM 渲染 -│ │ ├── main/ # 主页面(状态、队列、日志) -│ │ ├── plan/ # 方案预览 & 地图可视化 -│ │ ├── config/ # 配置页 -│ │ ├── template/ # 模板库 -│ │ ├── taskGroup/ # 任务组管理 -│ │ ├── setup/ # 安装向导 -│ │ └── styles/ # SCSS 样式 -│ ├── types/ # TypeScript 类型定义 -│ ├── data/ # 静态数据(舰船信息) -│ └── utils/ # 工具(Logger 等) -├── resource/ # 运行时资源(地图 JSON、内置方案、图片) -├── scripts/ # 构建脚本(esbuild、prepare-python、prepare-adb) -├── plans/ # 示例 YAML 战斗方案 -├── templates/ # 用户模板持久化 -├── docs/ # 文档 & 架构说明 -├── build/ # electron-builder 配置(NSIS 脚本) -├── setup.bat # 环境一键配置 -├── debug_deps.bat # 依赖诊断脚本 -├── package.json -└── tsconfig.json +适合同时开发 GUI 和 AutoWSGR 后端: + +- 使用本地 AutoWSGR 仓库源码及其虚拟环境。 +- 本地仓库根目录必须包含 `autowsgr/server/main.py`。 +- GUI 将仓库根目录加入后端 Python 的模块搜索路径。 +- external 模式不会自动安装或更新远端 `autowsgr`;缺少依赖时,本地仓库本身作为安装 requirement。 + +可以在设置页填写,也可以在开发模式的 `gui_settings.json` 中配置: + +```json +{ + "backend_startup_mode": "external", + "backend_repo_path": "C:\\path\\to\\AutoWSGR", + "python_path": "C:\\path\\to\\AutoWSGR\\.venv\\Scripts\\python.exe", + "update_mode": "manual" +} ``` -## 开发命令 +默认后端地址为 `http://127.0.0.1:8438`。MuMu 12 常用 ADB 地址为 `127.0.0.1:16384`,实际值应以模拟器实例为准。 -| 命令 | 说明 | -| ------ | ------ | -| `npm run dev` | 编译 TypeScript + 打包 + 启动 Electron | -| `npm run build` | 仅编译 + 打包(不启动) | -| `npm run build:css` | 编译 SCSS → CSS | -| `npm run dist` | 下载 Python/ADB + 编译 + 打包为 NSIS 安装程序 | -| `npm run pack` | 编译 + 打包为目录(不生成安装程序) | +## YAML 与数据目录 + +开发模式下的主要目录如下: -## 架构说明 +| 路径 | 内容 | +| --- | --- | +| `resource/system_battle_plans/` | 系统出征计划,界面中只读 | +| `resource/user_battle_plans/` | 用户出征计划,标准文件名为 `bettle-{名称}.yaml` | +| `resource/system_team_plans/` | 系统舰队方案,界面中只读 | +| `resource/user_team_plans/` | 用户舰队方案,标准文件名为 `team-{名称}.yaml` | +| `resource/ship-library/` | 舰船资料库 manifest、中文标签和本地资源 | +| `resource/maps/` | 出征规划使用的地图数据 | +| `usersettings.yaml` | 传递给 AutoWSGR 后端的用户配置 | +| `gui_settings.json` | GUI 环境、窗口、调度及界面状态 | +| `task_groups.json` | 作战页任务列表数据 | -采用 **MVC + ViewObject** 模式,详细文档见 [docs/architecture/](docs/architecture/)。 +打包运行时,系统资源从安装包资源目录读取,用户数据由主进程写入应用可写目录。不要直接修改系统方案;需要调整时应另存到用户目录。 -- **Controller** — 从 Model 提取数据,拼装为只读 ViewObject,单向传递给 View -- **View** — 纯 DOM 渲染,不包含业务逻辑 -- **Model** — API 通信、配置解析、任务调度、数据持久化 +GUI 保存的 YAML 必须通过当前前端校验,并最终符合 AutoWSGR 后端模型。战斗方案字段说明见 [docs/plan-guide.md](docs/plan-guide.md)。 + +## 开发命令 -Python 后端通过 `pip install autowsgr` 安装(`--target` 安装到程序目录),由 Electron 主进程管理 uvicorn 子进程,前端通过 HTTP + WebSocket 与后端通信。 +| 命令 | 说明 | +| --- | --- | +| `npm run dev` | 清理、编译、打包并启动 Electron | +| `npm start` | 执行构建后启动 Electron | +| `npm run build` | 编译 TypeScript、SCSS 并打包渲染进程,不启动应用 | +| `npm run build:css` | 单独编译 SCSS | +| `npm run prepare-python` | 准备便携版 Python | +| `npm run prepare-adb` | 准备 ADB 工具 | +| `npm run pack` | 生成未安装的应用目录 | +| `npm run dist` | 准备 Python 和 ADB,并生成 NSIS 安装包 | + +## 项目结构 + +```text +├── electron/ # Electron 主进程、IPC、后端和环境管理 +│ ├── main.ts # 窗口生命周期、文件管理及 IPC +│ ├── preload.ts # 安全桥接 +│ ├── backend.ts # AutoWSGR 后端进程管理 +│ ├── emulatorDetect.ts # 模拟器检测 +│ └── pythonEnv/ # Python 与依赖环境管理 +├── src/ +│ ├── controller/ # 页面业务协调与调度 +│ ├── model/ # 配置、计划、API、任务和调度模型 +│ ├── view/ # 作战、计划、设置页面及 SCSS +│ ├── types/ # TypeScript 类型与 bridge 契约 +│ └── utils/ # 日志及通用工具 +├── resource/ +│ ├── maps/ # 地图数据 +│ ├── ship-library/ # 舰船资料库 +│ ├── system_battle_plans/ # 系统出征计划 +│ ├── system_team_plans/ # 系统舰队方案 +│ ├── user_battle_plans/ # 用户出征计划 +│ └── user_team_plans/ # 用户舰队方案 +├── tools/ship_library/ # 舰船资料库更新工具 +├── scripts/ # 构建、Python 和 ADB 准备脚本 +├── docs/ # 使用与架构文档 +├── build/ # electron-builder / NSIS 配置 +├── setup.bat # Windows 环境配置脚本 +├── debug_deps.bat # 环境诊断脚本 +├── package.json +└── tsconfig.json +``` -## 贡献 +## 文档 -欢迎参与开发!请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。 +- [战斗方案 YAML 说明](docs/plan-guide.md) +- [架构文档索引](docs/architecture/README.md) +- [开发环境搭建](docs/architecture/08-dev-setup.md) +- [环境管理](docs/architecture/07-environment-management.md) +- [贡献指南](CONTRIBUTING.md) -## 许可证 +## 技术栈 -MIT +- Electron 33 +- TypeScript 5.6 +- esbuild +- Sass / SCSS +- electron-builder / NSIS +- js-yaml +- AutoWSGR FastAPI / uvicorn 后端 diff --git a/docs/architecture/00-overview.md b/docs/architecture/00-overview.md index ea9ff62..e6e903d 100644 --- a/docs/architecture/00-overview.md +++ b/docs/architecture/00-overview.md @@ -106,12 +106,14 @@ AutoWSGR-GUI/ │ ├── data/ # 静态数据(舰船数据库) │ └── utils/ # 工具类(Logger) ├── resource/ # 只读资源 -│ ├── builtin_plans/ # 内置战斗方案 (.yaml) +│ ├── system_battle_plans/ # 系统作战计划 (.yaml) +│ ├── system_team_plans/ # 系统编队计划 (.yaml) +│ ├── user_battle_plans/ # 用户作战计划 (.yaml) +│ ├── user_team_plans/ # 用户编队计划 (.yaml) │ ├── builtin_templates.json # 内置模板 │ ├── maps/ # 地图 JSON(节点坐标、连线) │ └── images/ # 图片资源 ├── templates/ # 用户自定义模板 -├── plans/ # 用户战斗方案目录 ├── scripts/ # 构建脚本 ├── build/ # electron-builder 配置 ├── usersettings.yaml # 用户配置文件 diff --git a/docs/architecture/04-battle-plan.md b/docs/architecture/04-battle-plan.md index ddbf6b4..3fe2b58 100644 --- a/docs/architecture/04-battle-plan.md +++ b/docs/architecture/04-battle-plan.md @@ -1,6 +1,6 @@ # 出击计划系统 -> 涉及文件:`src/model/PlanModel.ts` · `src/controller/plan/`(PlanController · importExport · presetFlow · nodeEditor · rendering)· `src/view/plan/`(PlanPreviewView(Facade) · MapView · NodeEditorView · FleetPresetView · FleetEditDialog)· `src/model/MapDataLoader.ts` · `src/types/model.ts` · `resource/builtin_plans/` · `resource/maps/` +> 涉及文件:`src/model/PlanModel.ts` · `src/controller/plan/`(PlanController · importExport · presetFlow · nodeEditor · rendering)· `src/view/plan/`(PlanPreviewView(Facade) · MapView · NodeEditorView · FleetPresetView · FleetEditDialog)· `src/model/MapDataLoader.ts` · `src/types/model.ts` · `resource/system_battle_plans/` · `resource/maps/` ## 概述 @@ -175,7 +175,7 @@ interface MapNode { flowchart TB subgraph Input["输入"] YAML["方案 YAML 文件"] - Builtin["内置方案
resource/builtin_plans/"] + Builtin["系统方案
resource/system_battle_plans/"] end subgraph Parse["解析"] @@ -209,17 +209,13 @@ flowchart TB --- -## 内置方案 +## 系统方案 -`resource/builtin_plans/` 包含 18 个预制方案: +`resource/system_battle_plans/` 当前包含 10 个周常预制方案: | 分类 | 数量 | 示例 | |------|------|------| -| 周常 | 11 | `周常1章-1-2.yaml` ~ `周常9章-9-2.yaml` | -| 捞胖次 | 4 | `捞胖次9-2.yaml`, `捞胖次7-4.yaml` | -| 战役 | 1 | `战役.yaml` | -| 演习 | 1 | `自动演习.yaml` | -| 决战 | 1 | `决战.yaml` | +| 周常 | 10 | `bettle-周常-1-1.yaml` ~ `bettle-周常-10-1.yaml` | --- diff --git a/docs/architecture/08-dev-setup.md b/docs/architecture/08-dev-setup.md index 7eaea6b..2f7fe94 100644 --- a/docs/architecture/08-dev-setup.md +++ b/docs/architecture/08-dev-setup.md @@ -114,7 +114,8 @@ flowchart LR |------|--------------|--------------| | `appRoot()` | 项目根目录 | `%LOCALAPPDATA%/autowsgr-gui/` 或安装目录 | | `resourceRoot()` | 同 appRoot | `resources/` (extraResources) | -| `plans/` | 项目根 `plans/` | extraResources `plans/` | +| `resource/system_battle_plans/` | 项目根 `resource/system_battle_plans/` | extraResources `resource/system_battle_plans/` | +| `resource/user_battle_plans/` | 项目根 `resource/user_battle_plans/` | appRoot `resource/user_battle_plans/` | | `python/` | 项目根 `python/` | extraResources `python/` | | `adb/` | 项目根 `adb/` | extraResources `adb/` | | `usersettings.yaml` | 项目根 | appRoot | diff --git a/docs/features/gui-2.0.md b/docs/features/gui-2.0.md new file mode 100644 index 0000000..f485cac --- /dev/null +++ b/docs/features/gui-2.0.md @@ -0,0 +1,1203 @@ +# GUI 2.0 功能说明 + +> 文档状态:GUI 2.0 开发版 +> 对应版本:`2.0.1-dev` +> 基线分支:`upstream/main` +> 目标平台:Windows 10/11 x64 +> 前端技术:Electron 33、TypeScript 5.6、SCSS +> 后端接口:AutoWSGR FastAPI、WebSocket 和 YAML 模型 +> 文档用途:功能说明、数据契约、代码审查和发布验收 + +## 1. 改造背景 + +GUI 2.0 不是对旧页面做局部换皮,而是重新明确 AutoWSGR-GUI 的职责: + +1. GUI 是用户配置、舰队方案和出征计划的可视化管理器。 +2. AutoWSGR 后端模型和 YAML 契约是业务规则的唯一事实来源。 +3. GUI 可以在数据进入后端前提供明确校验,但不能发明后端不存在的字段。 +4. 用户编辑的是可持久化 YAML;执行时再将引用的舰队展开为后端可消费的完整计划。 +5. 页面按“作战、计划、设置”组织,减少旧版页面之间重复、割裂的操作。 +6. 系统资源与用户文件分开维护,系统资源用于提供默认能力,用户文件用于保存修改。 +7. 开发模式必须能够直接连接本地 AutoWSGR 源码,避免 GUI 调试被远端包版本阻塞。 + +旧版 GUI 已经能够启动后端、管理任务队列和编辑基础出征方案,但存在以下问题: + +- 配置项平铺且缺少清晰分类,部分设置只有界面没有完整持久化链。 +- 舰队规则只能通过文本或旧弹窗维护,无法直观看到舰船、位置和备选关系。 +- 出征计划与舰队数据耦合在同一份 YAML 中,不便复用和独立维护。 +- 系统方案、用户方案、任务分组和模板入口分散,缺少统一的状态总览。 +- 保存、新建和加载的行为不一致,容易误覆盖或误报未保存。 +- 开发环境可能错误使用远端 `autowsgr`,无法稳定联调本地后端源码。 +- 页面在 720P 或更窄窗口下存在控件挤压、换行失控和内容不可见问题。 +- 成功提示没有统一语义,点击保存并不等于数据已经成功落盘。 + +GUI 2.0 围绕这些问题建立新的页面结构、数据边界和持久化流程。 + +## 2. 核心设计原则 + +### 2.1 后端契约优先 + +- YAML 字段、允许值和业务含义以 AutoWSGR 后端模型为准。 +- GUI 只负责收集、展示、预校验和序列化。 +- 舰种参数使用后端允许的代码值,例如 `dd`、`cl`、`ddg`、`ddgaa`、 + `cgaa` 和 `cbg`。 +- `fleet_presets` 保持列表结构。 +- 一份舰队 YAML 只描述一支舰队。 +- 一个舰队位置可以有主选,也可以只有结构化 `candidates`。 +- `candidates` 中的每一项必须是含 `name` 的对象,不接受仅有字符串的旧写法。 + +### 2.2 系统资源与用户数据分离 + +| 数据类型 | 系统目录 | 用户目录 | +| --- | --- | --- | +| 出征计划 | `resource/system_battle_plans/` | `resource/user_battle_plans/` | +| 舰队方案 | `resource/system_team_plans/` | `resource/user_team_plans/` | +| 舰船资料 | `resource/ship-library/` | 打包版更新到用户可写资料目录 | + +系统资源在界面中按只读内容展示。用户修改系统方案时,需要保存为用户方案。 +打包时不把用户目录中的本地内容写入安装包。 + +### 2.3 编辑态与运行态分离 + +- 编辑态出征计划只保存舰队名称引用,避免重复保存大量舰船规则。 +- 运行任务前,主进程读取对应舰队文件并展开 `ships`。 +- 展开后的完整 YAML 写入进程级临时目录。 +- 后端收到的仍然是完整、独立、可解析的出征 YAML。 +- 临时运行文件不污染系统或用户方案目录。 + +### 2.4 明确的保存成功语义 + +所有可见保存入口统一遵守以下规则: + +1. 点击按钮不会直接显示成功。 +2. 输入校验必须先通过。 +3. 文件写入、原子替换或设置 IPC 必须明确返回成功。 +4. 更新当前文件身份和保存快照后,才能显示顶部成功提示。 +5. 失败时只显示错误信息,不能同时出现成功提示。 +6. 连续保存会刷新提示计时,提示约 2.4 秒后自动隐藏。 + +### 2.5 保持开发环境可控 + +- `managed` 模式由 GUI 管理 Python 和 AutoWSGR 依赖。 +- `external` 模式使用指定的本地 AutoWSGR 仓库和虚拟环境。 +- `external` 模式不自动安装或更新远端 `autowsgr`。 +- 环境检查会验证实际导入的 `autowsgr.__file__` 是否来自预期目录。 +- 本地仓库路径属于开发配置,不进行便携路径改写。 + +## 3. 页面信息架构 + +GUI 2.0 主导航固定为: + +```text +作战 +计划 + ├─ 舰队规划 + ├─ 出征规划 + ├─ 决战计划(旧) + └─ 计划管理 +设置 + ├─ 系统设置 + └─ 脚本行为 +``` + +顶部导航固定在窗口上方,集中展示: + +- 当前执行任务。 +- 当前进度。 +- 剩余次数。 +- 远征检查倒计时。 +- 后端运行状态。 +- 主导航入口。 + +页面内容在导航下方独立滚动,避免页面较长时丢失任务状态。 + +## 4. 作战页 + +### 4.1 页面定位 + +作战页负责把已经准备好的配置变成任务,并展示执行状态。计划编辑器不再承担 +主要执行入口,用户应先保存 YAML,再在作战页加入任务列表或任务队列。 + +### 4.2 当前任务状态 + +顶部状态区展示: + +- 当前任务名称。 +- 运行、等待、已停止等状态。 +- 已完成次数和总次数。 +- 动态进度条。 +- 远征检查剩余时间。 +- 后端在线状态。 + +没有任务时不会伪造进度,状态栏回到空闲状态。 + +### 4.3 当前舰队预览 + +作战页增加当前舰队预览: + +- 从正在运行的任务请求中读取明确携带的舰队规则。 +- 支持从 `fleet_rules` 或内联计划中的 `fleet_presets[].ships` 提取舰名。 +- 泡澡维修触发队伍切换后,预览同步使用切换后的舰队。 +- 舰名优先使用 `name`,缺少时使用 `search_name`。 +- 使用舰船资料库解析立绘、背景、边框、舰种和稀有度。 +- 复用舰队规划中的舰娘卡片结构。 +- 主页预览不显示左上角编号,减少小尺寸卡片的信息拥挤。 +- 720P 下最多一行展示六张卡片。 +- 没有任务执行时在预览框中央显示“当前无任务执行”。 +- 任务存在但没有明确舰队规则时不展示虚构卡片。 + +只携带 `fleet_id`、没有携带具体舰名的旧任务无法可靠推断游戏内实际队伍, +因此不会猜测并展示错误舰队。 + +### 4.4 任务列表 + +任务列表以分组方式持久化常用任务: + +- 新建任务分组。 +- 修改分组名称。 +- 保存分组。 +- 删除分组。 +- 导入和导出。 +- 加入快捷动作。 +- 加入系统或用户出征计划。 +- 整组加入任务队列。 +- 记录当前激活分组。 + +任务列表中的出征计划优先保存受管身份: + +```text +managedSource + managedFile +``` + +旧数据如果只有路径,会根据 `system_battle_plans` 或 +`user_battle_plans` 推断来源和文件名。 + +显式保存按钮只有在 `task_groups.json` 写入完成后才显示成功提示。 + +### 4.5 任务队列 + +任务队列继续作为实际调度入口,支持: + +- 查看排队顺序。 +- 开始执行。 +- 停止当前任务。 +- 清空队列。 +- 展示任务次数和完成状态。 +- 将受管出征计划在执行前展开为完整运行时 YAML。 +- 在任务状态变化时同步顶部状态与舰队预览。 + +### 4.6 快捷动作 + +快捷动作与任务列表位于同一区域,包括: + +- 收取远征。 +- 收取奖励。 +- 收取建造。 +- 食堂烹饪。 +- 浴室修理。 + +快捷动作继续通过现有后端 API 执行,不强行转换为不存在的 YAML 契约。 + +### 4.7 日志 + +- 通过 WebSocket 接收后端日志。 +- 支持日志等级过滤。 +- 日志等级由设置页保存。 +- 完整用户配置只在调试模式下使用 `debug` 等级输出。 +- 普通模式不打印敏感的完整配置 YAML。 +- 已移除向本机 `127.0.0.1:7777` 发送调试事件的临时代码。 + +## 5. 舰队规划 + +### 5.1 页面定位 + +舰队规划用于生成独立舰队 YAML。用户通过本地舰船图鉴选择主选和备选, +GUI 将可视化状态转换为后端支持的 `ships` 结构。 + +### 5.2 舰娘卡片 + +舰娘卡片由以下层级组成: + +1. 稀有度背景。 +2. 舰船立绘。 +3. 舰种图标。 +4. 左上角编号。 +5. 底部黑色半透明名称背景。 +6. 根据稀有度显示的舰名颜色。 + +卡片在舰船图鉴、主选舰队、备选队列和出征预览之间复用。 +主页的小型预览复用同一结构,但按页面需求隐藏编号。 + +### 5.3 舰船搜索与筛选 + +舰船图鉴支持: + +- 按舰名模糊搜索。 +- 按编号搜索。 +- 舰种多选。 +- 舰型集合筛选。 +- 国籍多选。 +- 按类型、名称或编号排序。 +- 正序与倒序切换。 +- 过滤改造:同一舰船存在改造前后形态时只保留改造形态, + 不会过滤掉本身没有改造形态的舰船。 +- 恢复默认筛选。 +- 筛选状态和排序状态持久化。 + +集合按钮与成员按钮联动: + +- 选择“大型舰”等集合时,激活集合包含的舰种。 +- 取消任意成员后,集合按钮立即取消激活。 +- 后续重新补齐成员不会自动重新点亮集合,除非用户再次主动选择集合。 + +### 5.4 主选位置 + +- 一支舰队最多六个位置。 +- 空位统一整理到右侧。 +- 删除前方主选后,后续完整位置规则向左移动。 +- 移动位置时,主选、等级限制和对应备选队列作为整体移动。 +- 点击已有位置可以替换舰船。 +- 相同舰船不会因为连续点击而重复加入多个位置。 +- 图鉴中已经被主选使用的形态会按同名规则隐藏。 +- 选择同舰的另一形态时执行替换,而不是新增重复位置。 + +### 5.5 备选队列 + +每个位置拥有独立备选队列: + +- 标题显示为 `【主选舰名】的备选队列`。 +- 没有主选时显示 `【位置 X】的备选队列`。 +- 支持增加备选槽位。 +- 新舰船默认进入最左侧空位。 +- 删除第七个及后续备选时,同时收缩多余空槽。 +- 选择已有备选后从图鉴点击舰船会替换当前项。 +- 只有焦点位于尾部空槽时,图鉴点击才执行追加。 +- 支持复制当前备选队列到其他位置。 +- 与目标备选完全一致时禁用复制。 +- 目标已有备选时要求用户确认覆盖。 +- 复制完成后保留当前主选焦点。 + +### 5.6 纯备选位置 + +GUI 支持“没有主选,只有备选”的位置: + +- 删除主选时可以保留其备选队列。 +- 主选卡片位置显示“使用备选队列”占位状态。 +- 纯备选位置不能被当作无效空位自动删除。 +- 只有主选和备选都为空时,整个位置才参与左移整理。 +- 保存时不要求顶层 `name`,但要求 `candidates` 非空。 + +这种结构用于让后端按候选顺序寻找第一个可用舰船。 + +### 5.7 等级限制 + +- 主选位置和备选队列分别维护等级限制。 +- 等级限制跟随位置规则移动。 +- 当前没有主选且备选也为空时,不能开启等级限制。 +- 开关关闭时不输出 `min_level` 或 `max_level`。 +- 最小等级不能大于最大等级。 +- 值域和后端支持范围保持一致。 +- 舰种规则根据舰船资料自动写入,不要求普通用户手工输入。 + +### 5.8 拖拽 + +支持以下拖拽方向: + +- 图鉴到主选。 +- 图鉴到备选。 +- 主选到主选。 +- 备选到备选。 +- 主选到备选。 +- 备选到主选。 + +拖拽原则: + +- 拖到空白尾部时执行追加和自动整理。 +- 拖到已有卡片时根据区域执行交换或替换。 +- 位置移动必须携带对应备选和等级规则。 +- 从图鉴拖入后,焦点切换到实际落位的位置。 +- 动态渲染后恢复图鉴和备选容器原有滚动位置。 + +### 5.9 新建、保存和加载 + +舰队文件具有明确生命周期: + +- “新建”只在存在真实未保存修改时确认。 +- 新建后清空当前文件身份和来源。 +- “保存”更新当前文件。 +- 已加载方案修改名称后,仍按当前文件身份处理更新或改名。 +- 新建同名方案时询问是否覆盖。 +- “加载”显示系统和用户方案列表。 +- 当前文件按 `source + file` 预选。 +- 加载前检查未保存修改。 +- 保存成功后更新当前文件、来源和保存快照。 +- 系统方案修改后保存为用户方案。 + +### 5.10 舰队 YAML + +标准文件名: + +```text +team-{预设名称}.yaml +``` + +普通主选和备选示例: + +```yaml +name: 潜艇周常队 +ships: + - name: U-47 + ship_type: [ss, ssg] + min_level: 100 + max_level: 110 + candidates: + - {name: U-96, ship_type: [ss], min_level: 100, max_level: 110} + - {name: U-1206, ship_type: [ss], min_level: 100, max_level: 110} +``` + +纯备选位置示例: + +```yaml +name: 纯备选示例 +ships: + - candidates: + - {name: U-47, ship_type: [ss]} + - {name: U-96, ship_type: [ss]} +``` + +序列化约束: + +- 空字段不输出 `null`。 +- `ships` 的顺序对应位置顺序。 +- 主选字段分行显示。 +- 备选对象使用紧凑行内格式,避免大型候选池纵向膨胀。 +- `candidates` 必须是对象列表。 +- `ship_type` 使用后端代码值。 +- `fleet_id` 不在独立舰队文件中维护。 + +## 6. 舰船资料库 + +### 6.1 数据结构 + +本地资料库位于 `resource/ship-library/`,包括: + +- `database/ships.sqlite3`:可增量维护的数据源。 +- `manifest.json`:GUI 快速加载的舰船索引。 +- `labels.zh-CN.json`:中文显示标签。 +- `assets/portraits/`:舰船立绘。 +- `assets/backgrounds/`:稀有度背景。 +- `assets/frames/`:稀有度边框。 +- `assets/type-icons/`:舰种图标。 + +当前资料库包含: + +- 894 条有效舰船记录。 +- 894 张舰船立绘。 +- 6 张共享稀有度背景。 +- 6 张共享稀有度边框。 +- 23 张舰种图标。 +- 0 个缺失资源。 + +数据库字段和内部枚举使用英文,GUI 显示标签使用中文。 + +### 6.2 增量更新工具 + +`tools/ship_library/update_ship_library.py` 提供: + +- 从舰 R 百科 Lua 数据模块读取结构化舰船数据。 +- 从舰娘图鉴页读取立绘、背景、边框和舰种图标地址。 +- 使用稳定舰船编号作为主键。 +- 保存数据源版本、哈希和更新时间。 +- 只下载新增、变更或缺失资源。 +- 下载使用临时文件并原子替换。 +- 失效记录在 SQLite 中标记,不直接破坏历史信息。 +- 更新完成后重新生成 GUI manifest。 +- 输出机器可读结果供 Electron IPC 使用。 + +设置页提供“更新舰船数据库”按钮、当前版本状态和更新进度。 +打包配置只携带更新工具本身,不携带无关脚本。 + +## 7. 出征规划 + +### 7.1 页面定位 + +出征规划负责生成地图级出征 YAML,并引用独立舰队方案。页面分为: + +- 左侧出征配置、任务配置和编队管理。 +- 右侧地图节点路线、节点信息和舰队选择/预览。 + +已删除旧引导页,进入后直接编辑。 + +### 7.2 出征配置 + +支持: + +- 章节选择。 +- 地图选择。 +- 战况目标。 +- 维修策略。 +- 维修方式。 +- 泡澡维修相关旧配置。 + +默认维修阈值由现有后端行为处理,不再为每艘船生成重复的默认 50% 阈值。 + +### 7.3 任务配置 + +支持: + +- 执行次数。 +- 轮次间隔。 +- 战利品停止条件。 +- 掉落停止条件。 +- 自定义预设名称。 + +停止条件规则: + +- 开关关闭时保存为禁用值,不展示输入文案。 +- 开关开启后才显示并允许编辑数量。 +- 战利品数量范围为 1 到 50。 +- 掉落数量范围为 1 到 500。 + +### 7.4 编队关联 + +- 从系统和用户舰队方案中选择。 +- 选择卡片默认只预览。 +- 打开卡片右侧关联开关后,才加入当前出征计划。 +- 支持同时关联多个舰队方案。 +- 左侧显示已关联数量和方案名称。 +- 编队预览展示主选、纯备选占位和全部备选。 +- 主选卡片显示独立等级范围。 +- 预览只读,修改必须回到舰队规划。 + +### 7.5 地图与节点 + +- 地图按原始宽高比缩放。 +- 地图尽可能利用容器空间,但不会超出边框。 +- 点击节点打开节点编辑。 +- 未选择节点时显示“点击地图上的节点查看和编辑”。 +- 节点路线和节点信息位于同一大区域。 + +节点编辑支持: + +- 节点启用开关。 +- 终点节点。 +- 阵型单选。 +- 前进。 +- 夜战。 +- 远程打击。 +- 迂回。 +- 迂回失败后 S/L。 +- 最低战果。 +- 索敌规则文本。 + +节点关闭时: + +- 其他编辑控件隐藏。 +- 本次编辑中的值仍保留在前端内存。 +- 保存 YAML 时不输出关闭节点的其他选项。 +- 切换文件或关闭程序后,未保存内存状态自然丢弃。 + +索敌规则输入框提示 `detour`、`retreat` 等现有后端规则用法。 + +### 7.6 新建、保存和加载 + +出征计划与舰队方案使用相同的生命周期模型: + +- 当前文件由 `source + file` 唯一标识。 +- 新建前只在有真实修改时提示。 +- 加载前检查未保存修改。 +- 保存直接更新当前用户文件。 +- 改名保存时创建标准新文件并删除旧用户文件。 +- 同名覆盖需要确认。 +- 系统计划修改后保存为用户计划。 +- 保存成功后更新快照,不再误报未保存。 +- 新建后自动聚焦预设名称输入框。 + +标准文件名: + +```text +bettle-{预设名称}.yaml +``` + +项目继续沿用现有 `bettle-` 拼写,以避免破坏已经持久化的文件身份。 + +### 7.7 编辑态引用与运行态展开 + +编辑态保存: + +```yaml +chapter: 1 +map: 1 +times: 3 +fleet_presets: + - name: 4日驱周常队 +``` + +任务执行前,主进程会: + +1. 根据计划来源和舰队名称查找独立舰队文件。 +2. 优先匹配同来源方案。 +3. 读取并校验舰队 `ships`。 +4. 将舰队完整嵌入 `fleet_presets`。 +5. 保留原计划顶部注释。 +6. 将完整 YAML 写入进程临时目录。 +7. 把临时文件路径传给后端执行。 + +如果引用舰队不存在,执行准备阶段明确失败,不会向后端提交半完整计划。 + +### 7.8 旧计划转换 + +旧计划可能在 `fleet_presets` 中直接包含舰队内容。转换功能会: + +- 读取旧计划。 +- 为每个内嵌舰队生成独立 `team-{名称}.yaml`。 +- 将出征计划中的舰队改为名称引用。 +- 将旧字符串舰名转换为结构化对象。 +- 将旧 `priority` 按顺序转换为主选和 `candidates`。 +- 保留结构化纯备选位置。 +- 检查目标文件冲突。 +- 通过临时文件和原子替换完成多文件写入。 +- 保证再次读取时可以恢复完整运行时 YAML。 + +旧格式不会作为新编辑器的输出格式;转换仅用于一次性迁移。 + +## 8. 计划管理 + +### 8.1 统一清单 + +计划管理读取: + +- 系统出征计划。 +- 用户出征计划。 +- 系统舰队方案。 +- 用户舰队方案。 +- 任务分组。 +- 忽略未关联状态。 + +表格展示: + +- 计划或舰队名称。 +- 来源。 +- 出征计划与舰队关联。 +- 所属任务分组。 +- 当前状态。 +- 可用操作。 + +### 8.2 状态识别 + +能够识别: + +- 出征计划引用了哪些舰队。 +- 舰队被哪些出征计划引用。 +- 出征计划被哪些任务分组引用。 +- 用户舰队未被引用。 +- 出征计划没有关联舰队。 +- 引用舰队文件缺失。 +- YAML 无法读取。 +- 文件名不符合管理规则。 + +“未加入任务分组”只作为信息展示,不自动计入“需要处理”。 + +### 8.3 筛选和搜索 + +支持: + +- 按系统或用户来源筛选。 +- 按出征计划或舰队方案筛选。 +- 搜索计划名称。 +- 搜索舰队名称。 +- 搜索任务分组名称。 +- 仅查看需要处理项目。 + +### 8.4 操作 + +- 跳转到舰队规划并加载指定舰队。 +- 跳转到出征规划并加载指定计划。 +- 删除用户出征计划。 +- 删除用户舰队方案。 +- 忽略不需要处理的未关联提示。 +- 恢复已经忽略的提示。 + +忽略状态写入: + +```json +{ + "plan_management_ignored_unlinked": [] +} +``` + +文件改名时同步迁移忽略键,避免状态丢失。 + +所有动态列表在重新渲染后恢复原滚动位置,避免点击后跳回顶部。 + +## 9. 决战计划(旧) + +GUI 2.0 暂时保留旧决战配置,明确标注为兼容页面: + +- 章节。 +- 快速修理。 +- 两组等级范围。 +- 现有决战筛选和配置。 +- 重置与保存。 + +保存调用主进程设置 IPC。只有 `gui_settings.json` 写入完成并返回规范化结果后, +才显示“决战配置保存成功”。 + +该页面不代表最终统一 YAML 设计。决战流程后续需要从旧直接配置中独立出来, +与普通出征任务形成清晰边界。 + +## 10. 设置页 + +### 10.1 页面结构 + +设置页改为分组列表,标题和备注优先同一行,空间不足时自然换行。 +内容宽度限制在可读范围内并居中,减少大窗口下无意义的横向拉伸。 + +### 10.2 系统设置 + +#### 模拟器与 ADB + +- 模拟器类型。 +- 模拟器路径和浏览按钮。 +- 游戏账号。 +- ADB 地址。 +- 主动连接。 +- 断开连接。 +- 自动检测。 +- 输入框右侧在线、离线或未检测状态。 +- 完整地址和错误信息通过悬停查看。 + +MuMu 12 常用地址为 `127.0.0.1:16384`,但 GUI 不强制覆盖用户输入。 + +#### 自动化设置 + +- 自动远征。 +- 自动战役和战役类型。 +- 自动演习和舰队编号。 +- 自动出征和有序计划列表。 +- 自动胖次及预设参数。 +- 泡澡维修相关配置。 + +自动出征列表使用受管计划选择器,保存文件来源、名称和执行参数。 + +#### 日志与调试 + +- 日志等级。 +- 日志目录。 +- 调试模式。 +- 后端截图保存。 + +调试模式控制敏感完整配置日志,不在普通模式展示。 + +#### 环境配置 + +- Python 路径。 +- Python 浏览和检测。 +- 后端端口。 +- 后端启动模式。 +- 本地 AutoWSGR 仓库路径。 +- CUDA 路径。 +- 当前环境状态。 + +#### 更新与界面 + +- GUI 更新模式。 +- 默认窗口宽度和高度。 +- 记住退出时窗口大小与位置。 +- 更新舰船数据库。 +- 舰船数据库状态。 + +#### 颜色主题 + +- 亮色。 +- 暗色。 +- 跟随系统。 +- 主题强调色。 + +主题和强调色即时应用并持久化。 + +### 10.3 脚本行为 + +#### 全局延迟 + +- 最小延迟。 +- 最大延迟。 +- 输入与滑块联动。 +- 范围为 0 到 10 秒。 +- 最小值不能大于最大值。 +- 用户值写入 `usersettings.yaml`,优先于后端默认值。 + +#### OCR + +- 模型下载源。 +- 加速模式。 +- CUDA 路径。 +- 硬件识别开关。 +- 舰名匹配置信度。 +- 舰名别名。 +- OCR 纠错映射。 + +用户 OCR 规则由后端配置模型读取。无效目标舰名应由后端按 `SHIPNAMES` +校验并跳过,同时输出警告。 + +#### 舰队与脚本配置 + +- 船坞和维修相关行为。 +- 解装行为。 +- 浴室数量。 +- 自定义方案目录。 +- 后端已经开放给用户的其他低风险配置。 + +GUI 保留未知 YAML 字段,避免保存设置时破坏后端新增但当前 GUI 尚未展示的配置。 + +### 10.4 设置保存事务 + +设置同时涉及: + +- `localStorage` 主题状态。 +- 多个 GUI 设置 IPC。 +- `usersettings.yaml`。 +- 自动化调度器状态。 + +保存前会检查所有必需 bridge 接口是否存在。任一接口缺失或写入失败时: + +- 显示保存失败。 +- 不显示顶部成功提示。 +- 建议完整重启 GUI,避免旧 preload 与新渲染代码混用。 + +配置持久化全部成功后才显示“设置保存成功”。保存后的后端重连属于后续动作, +重连失败不会否定已经成功写入磁盘的配置。 + +## 11. 主题、响应式和交互统一 + +### 11.1 亮色主题 + +新增完整亮色主题,覆盖: + +- 页面背景。 +- 卡片和边框。 +- 输入框。 +- 下拉框。 +- 模态框。 +- 任务列表。 +- 舰船卡片文字。 +- 状态颜色。 +- 滚动条。 + +暗色和亮色共享语义变量,避免页面单独硬编码造成对比度不一致。 + +### 11.2 下拉框与开关 + +- 下拉框使用统一半透明背景和高对比文字。 +- 布尔配置统一使用开关样式。 +- 重要筛选不再依赖浏览器默认下拉控件。 +- 开关关闭时关联输入框禁用或隐藏。 + +### 11.3 滚动条 + +- 统一使用约 5px 主题细滚动条。 +- 舰船图鉴、备选列表、任务列表和计划管理保持相同视觉语言。 +- 动态 DOM 重建前记录 `scrollTop` 和 `scrollLeft`。 +- 重建后恢复位置,不因点击、删除或拖拽跳回顶部。 + +### 11.4 分辨率适配 + +- 以 720P 为主要布局基准。 +- 支持更窄窗口,不限制大窗口扩展。 +- 小窗口下工具栏允许分组换行。 +- 舰队主选在 720P 下保持一行六张卡片。 +- 图鉴卡片保持可识别尺寸,宽窗口增加每行数量。 +- 表格在列数较多时使用容器横向滚动,不挤坏操作按钮。 +- 标题、备注和操作按钮保持同一视觉层级。 + +## 12. Electron IPC 与文件安全 + +### 12.1 preload 契约 + +所有新增主进程能力通过 `contextBridge` 暴露明确方法,并在 +`src/types/electronBridge.ts` 中维护对应类型,包括: + +- ADB 检测、连接和断开。 +- 窗口设置。 +- 后端模式和仓库路径。 +- OCR 与 CUDA 设置。 +- 自动化设置。 +- 舰船资料库状态和更新。 +- 舰队方案列出、读取、保存和删除。 +- 出征计划列出、读取、保存、转换和删除。 +- 计划管理。 +- 忽略提示状态。 +- 运行时出征计划展开。 +- 决战兼容设置。 + +### 12.2 路径校验 + +- 文件参数必须是纯文件名,拒绝目录穿越。 +- 舰队文件必须以 `team-` 或兼容的 `team_` 开头。 +- 出征计划必须是 YAML 文件。 +- 新文件名会清除 Windows 非法字符。 +- 文件名长度限制在可维护范围内。 +- 系统和用户来源由枚举值控制,不接受任意目录。 + +### 12.3 原子写入 + +关键 YAML 保存采用: + +1. 在目标目录创建唯一临时文件。 +2. 完整写入内容。 +3. 将临时文件重命名为目标文件。 +4. 替换失败时清理临时状态并返回错误。 + +多文件旧计划转换会先检查冲突,再执行写入,降低只生成一半文件的风险。 + +### 12.4 覆盖和改名 + +- 同名新建要求用户确认。 +- 当前文件原名保存直接覆盖。 +- 用户文件改名后删除旧文件。 +- 系统文件不能因改名流程被删除。 +- 保存结果返回新文件身份,渲染进程据此更新快照。 + +## 13. 后端环境管理 + +### 13.1 managed 模式 + +- 使用 GUI 管理的 Python。 +- 依赖安装到 GUI 自己的 `python/site-packages`。 +- 不写入系统 Python 全局目录。 +- 启动 GUI 管理的 uvicorn。 +- 根据更新模式检查 AutoWSGR 依赖。 +- 验证导入路径位于 GUI 管理目录。 + +### 13.2 external 模式 + +- 使用用户指定 Python,通常是本地 AutoWSGR `.venv`。 +- `backend_repo_path` 必须是包含 `autowsgr/server/main.py` 的仓库根目录。 +- 通过 Python 模块路径加载本地源码。 +- 验证 `autowsgr.__file__` 位于指定仓库。 +- 不混入 GUI 自带 Python 3.12 的二进制依赖。 +- 不检查或升级远端 `autowsgr`。 +- 缺依赖时使用本地仓库本身作为 pip requirement。 + +这保证 Python 3.13 后端虚拟环境不会错误加载 GUI Python 3.12 的二进制包。 + +### 13.3 启动与错误处理 + +- 后端端口可配置。 +- 外部后端模式支持只连接已有服务。 +- 环境检查输出阶段性进度。 +- 错误信息区分 Python、依赖、导入来源和后端连接问题。 +- 启动过程不再发送无关的本地调试 HTTP 请求。 + +## 14. 数据持久化 + +| 文件 | 用途 | +| --- | --- | +| `usersettings.yaml` | AutoWSGR 后端用户配置 | +| `gui_settings.json` | GUI 环境、窗口、主题、调度和页面状态 | +| `task_groups.json` | 作战页任务分组 | +| `resource/user_team_plans/*.yaml` | 用户舰队方案 | +| `resource/user_battle_plans/*.yaml` | 用户出征计划 | + +GUI 2.0 对持久化作出以下约束: + +- 后端配置值优先于代码默认值。 +- GUI 设置和后端 YAML 设置分开保存。 +- 未识别的后端 YAML 字段尽量保留。 +- 用户目录不会被打包为系统资源。 +- 系统资源更新不覆盖用户文件。 +- 当前文件身份不依赖输入框中的显示名称。 +- 未保存判断使用序列化快照,不用单一 `dirty` 点击标志代替真实比较。 + +## 15. 代码结构调整 + +### 15.1 新增主要模块 + +| 模块 | 职责 | +| --- | --- | +| `FleetPlannerView.ts` | 舰队规划、图鉴筛选、拖拽和计划管理 | +| `ShipArtwork.ts` | 舰船资料与卡片资源解析 | +| `TeamPlanListUi.ts` | 舰队加载列表共用逻辑 | +| `FleetPreviewView.ts` | 作战页当前舰队预览 | +| `DecisivePlanView.ts` | 旧决战配置兼容页面 | +| `TaskListLoaderController.ts` | 作战页受管计划选择 | +| `managedPlanReader.ts` | 任务分组中的计划元信息读取 | +| `scrollPosition.ts` | 动态列表滚动位置保存与恢复 | +| `_fleet-planner.scss` | 舰队规划和计划管理样式 | +| `_decisive-plan.scss` | 旧决战页面样式 | +| `_save-notice.scss` | 顶部保存成功提示 | +| `_light.scss` | 亮色主题 | + +### 15.2 主进程扩展 + +`electron/main.ts` 集中增加: + +- GUI 设置规范化。 +- 用户数据目录定位。 +- 舰队 YAML 规范化和序列化。 +- 出征计划引用展开。 +- 旧计划迁移。 +- 计划管理聚合。 +- 文件安全校验。 +- 原子写入。 +- ADB 操作。 +- 舰船资料库更新。 +- 窗口状态持久化。 + +当前实现规模较大,后续可在不改变 IPC 契约的前提下拆分为独立模块; +本次 PR 优先保证完整行为和数据一致性。 + +### 15.3 旧资源清理 + +- 删除旧 `resource/builtin_plans/`,替换为系统出征和系统舰队目录。 +- 删除四个不再自动加载的旧模板示例 JSON。 +- 删除临时 Issue 数据和一次性 PowerShell 脚本。 +- 删除 `.dbg`、Python 缓存和未引用的舰娘卡片原型。 +- `.gitignore` 增加调试目录、Python 缓存和临时调试文档规则。 +- 打包文件列表只包含运行所需 HTML、CSS、编译产物和资源。 + +模板模型和 `templates/templates.json` 路径暂时保留,用于旧任务和用户模板兼容; +删除的是无运行引用的示例文件,不是兼容模型。 + +## 16. 构建与测试 + +### 16.1 构建 + +```powershell +npm run build +``` + +覆盖: + +- 清理旧 `dist`。 +- 编译 SCSS。 +- TypeScript 编译。 +- 渲染进程 esbuild 打包。 + +### 16.2 旧计划转换测试 + +```powershell +npm run test:legacy-plan +``` + +测试在系统临时目录中: + +- 截获真实主进程 IPC handler。 +- 转换旧内嵌舰队计划。 +- 校验普通主选、候选和纯备选结构。 +- 校验计划和舰队文件拆分。 +- 校验冲突处理。 +- 重新加载受管计划。 +- 生成运行时完整 YAML。 +- 不接触真实用户配置。 + +### 16.3 设置持久化测试 + +```powershell +npm run test:settings +``` + +测试使用隐藏 Electron 窗口和临时目录: + +- 渲染全部设置值。 +- 从表单重新收集。 +- 验证非法延迟区间。 +- 调用真实 `ConfigController` 保存逻辑。 +- 模拟完整 preload bridge。 +- 重新读取 `usersettings.yaml` 和 `gui_settings.json`。 +- 验证主题、强调色和调试模式。 +- 验证未知 YAML 字段保留。 +- 不修改项目真实用户设置。 + +### 16.4 静态检查 + +```powershell +git diff --check +``` + +用于检查行尾空白和补丁格式。 + +严格未使用声明检查: + +```powershell +npx tsc --noEmit --noUnusedLocals --noUnusedParameters --pretty false +``` + +当前已知仍有开发残留提示,详见 +`docs/reviews/2026-08-03-workspace-review-pending.md`。默认构建不启用这两个选项。 + +## 17. 已知边界和后续工作 + +### 17.1 出征规划直接执行链 + +`PlanController` 中仍保留一套没有页面入口的直接执行链。当前推荐流程是保存计划后, +从作战页加入任务列表和队列。待主页执行入口稳定后,需要决定: + +- 恢复明确的“加入任务队列”入口并补测试;或 +- 删除无调用的直接执行链。 + +### 17.2 旧后端源码更新链 + +旧的手动源码检查和拉取实现仍有部分跨层残留。它与以下功能不同: + +- GUI 自身的 `electron-updater`。 +- managed 环境中的 AutoWSGR 依赖更新。 +- external 模式下的本地源码联调。 + +后续需要先确定产品策略,再整体恢复或整体删除,不能只清理其中一层。 + +### 17.3 TypeScript 未使用声明 + +严格检查仍可能报告未使用导入、参数和只写字段。当前正常类型编译通过。 +后续应在页面入口和设置策略稳定后逐项判断是补齐功能还是删除声明。 + +### 17.4 决战流程 + +决战页面仍是兼容入口,尚未完成统一 YAML 化。未来应将决战执行器从旧页面配置中 +独立出来,并与普通出征形成平级、可测试的执行模型。 + +### 17.5 当前舰队预览 + +预览只显示任务请求中能够可靠识别的具体舰船。只有 `fleet_id` 的旧任务不会读取 +游戏屏幕或猜测队伍内容。若后端未来提供当前实际舰队状态接口,可再接入实时状态。 + +### 17.6 视觉回归 + +本轮以用户快速目测为主要视觉验收方式。代码侧负责数据结构、保存、加载、 +YAML 往返、IPC 和构建。不同 Windows 缩放比例仍建议在发布前做一次集中视觉回归。 + +## 18. 兼容与迁移说明 + +### 18.1 旧出征计划 + +- 可通过转换入口拆分。 +- 转换前检查文件冲突。 +- 转换后使用标准受管目录和文件名。 +- 新编辑器不继续生成旧字符串候选格式。 + +### 18.2 旧任务分组 + +- 保留路径形式的计划项。 +- 尝试从目录推断系统或用户来源。 +- 保存后逐步迁移到 `managedSource + managedFile`。 + +### 18.3 旧模板 + +- 内置模板继续从 `resource/builtin_templates.json` 读取。 +- 用户模板模型继续支持 `templates/templates.json`。 +- 旧页面中的可见模板库已经移除。 +- 无引用的四个模板示例文件不再保留。 + +### 18.4 旧舰队字段 + +- 新独立舰队不写 `fleet_id`。 +- 读取时可识别有限旧字段用于转换。 +- 新保存严格输出 `name`、`ships` 和位置规则。 +- 不生成 `priority`。 + +## 19. 审查重点 + +建议审查者按以下顺序检查: + +1. `electron/main.ts` 中路径校验、原子写入和运行时展开。 +2. `PlanModel.ts` 与舰队/出征 YAML 往返。 +3. `FleetPlannerView.ts` 的位置、备选和拖拽状态转换。 +4. `PlanController.ts` 的新建、加载、保存、改名和来源身份。 +5. `ConfigModel.ts` 与 `ConfigController.ts` 的字段保留和保存事务。 +6. `SchedulerBinder.ts`、`TaskQueue.ts` 和运行时计划准备。 +7. preload 与 `electronBridge.ts` 的方法签名一致性。 +8. 系统资源和用户目录在开发版、打包版中的定位。 +9. 舰船资料库更新失败时是否保留现有可用数据。 +10. 720P 布局、亮色主题和动态列表滚动位置。 + +不建议仅根据单个文件评估本次改造。舰队保存、出征引用和任务执行跨越: + +```text +View +→ Controller +→ preload bridge +→ Electron IPC +→ 用户 YAML +→ 运行时展开 +→ Scheduler +→ AutoWSGR API +``` + +任何一层缺失都会造成“界面看起来成功,但任务无法正确执行”的问题。 + +## 20. 验收清单 + +### 作战 + +- [ ] 没有任务时显示“当前无任务执行”。 +- [ ] 有明确舰队的任务显示最多六艘舰船。 +- [ ] 主页预览不显示编号。 +- [ ] 任务分组保存失败时不显示成功提示。 +- [ ] 动态列表操作后滚动位置不跳回顶部。 + +### 舰队规划 + +- [ ] 图鉴搜索、筛选、排序和过滤改造正确。 +- [ ] 主选、备选和图鉴之间拖拽正确。 +- [ ] 删除主选时备选按规则保留。 +- [ ] 纯备选位置可以保存和加载。 +- [ ] 等级限制跟随对应位置。 +- [ ] 同名覆盖需要确认。 +- [ ] 改名保存更新正确文件身份。 + +### 出征规划 + +- [ ] 新建、保存和加载具有未保存确认。 +- [ ] 关联多个舰队后可以再次加载。 +- [ ] 节点关闭时不输出节点选项。 +- [ ] 停止条件开关和值正确往返。 +- [ ] 用户计划使用标准文件名。 +- [ ] 执行前可以展开完整舰队。 +- [ ] 舰队缺失时明确失败。 + +### 计划管理 + +- [ ] 系统和用户计划均能列出。 +- [ ] 双向舰队关联正确。 +- [ ] 任务分组关联正确。 +- [ ] 忽略和恢复提示持久化。 +- [ ] 用户计划删除后列表刷新。 +- [ ] 编辑跳转加载正确文件。 + +### 设置 + +- [ ] ADB 检测、连接和断开可用。 +- [ ] managed 与 external 模式行为隔离。 +- [ ] 亮色、暗色和跟随系统正确。 +- [ ] 窗口默认尺寸和退出位置持久化。 +- [ ] OCR、自动化和脚本行为字段保存后可重新读取。 +- [ ] 保存接口缺失或写入失败时不显示成功。 +- [ ] 舰船资料库状态和更新进度可见。 + +### 工程 + +- [ ] `npm run build` 通过。 +- [ ] `npm run test:legacy-plan` 通过。 +- [ ] `npm run test:settings` 通过。 +- [ ] `git diff --check` 通过。 +- [ ] 安装包不包含用户 YAML。 +- [ ] 调试产物和 Python 缓存未进入版本库。 + +## 21. 用户可感知的最终变化 + +GUI 2.0 将原来分散的功能整理为一条明确工作流: + +```text +设置运行环境 +→ 更新舰船资料 +→ 可视化创建舰队 +→ 创建并关联出征计划 +→ 在计划管理检查状态 +→ 加入任务列表 +→ 加入任务队列并执行 +→ 在作战页查看任务、进度、舰队和日志 +``` + +这次改造解决的核心问题不是“增加更多按钮”,而是让每个按钮对应的数据状态、 +文件身份、保存结果和后端输入都能够被明确追踪。用户可以通过图形界面维护 YAML, +同时保留 AutoWSGR 后端模型作为唯一执行标准。 diff --git a/docs/plan-guide.md b/docs/plan-guide.md index 1d3f2ac..f0299fe 100644 --- a/docs/plan-guide.md +++ b/docs/plan-guide.md @@ -1,6 +1,6 @@ # 战斗方案 YAML 编写指南 -本文档介绍如何编写 AutoWSGR-GUI 的战斗方案配置文件。方案文件为 YAML 格式,放置在 `plans/` 目录下,可在 GUI 中导入使用。 +本文档介绍如何编写 AutoWSGR-GUI 的战斗方案配置文件。方案文件为 YAML 格式,GUI 保存的用户方案位于 `resource/user_battle_plans/`,也可以从其他位置导入。 --- diff --git a/docs/reviews/2026-08-03-workspace-review-pending.md b/docs/reviews/2026-08-03-workspace-review-pending.md new file mode 100644 index 0000000..2163a73 --- /dev/null +++ b/docs/reviews/2026-08-03-workspace-review-pending.md @@ -0,0 +1,152 @@ +# GUI 工作区代码审查挂起项 + +> 记录日期:2026-08-03 +> 审查范围:AutoWSGR-GUI 当前工作区全部未提交代码 +> 当前状态:3 组问题挂起,等待相关页面和并行开发稳定后复查 +> 复核结果:两个独立审查线程均确认问题存在 + +## 记录目的 + +本轮审查的目标是清理调试代码、无用代码和可安全精简的结构。 +以下问题暂不修改,不代表问题已经解决,而是相关页面仍在开发, +现在删除可能干扰后续功能接入。 + +```mermaid +flowchart LR + A[发现可清理代码] --> B{相关功能是否稳定} + B -->|否| C[挂起并记录用途] + C --> D[页面与并行开发完成] + D --> E[重新检查调用和严格编译] + E --> F{代码是否仍有用途} + F -->|有| G[补齐入口和测试] + F -->|无| H[执行最小删除] + classDef pending fill:#fff3e0,color:#e65100 + classDef review fill:#bbdefb,color:#0d47a1 + classDef done fill:#c8e6c9,color:#1a5e20 + class C pending + class D,E review + class G,H done +``` + +## 挂起清单 + +| 编号 | 挂起问题 | 挂起原因 | 重新审查条件 | +|---|---|---|---| +| P-01 | 出征规划直接执行链没有调用入口 | 主页任务入口仍在开发,暂时不能判断这套执行链是否还会使用 | 主页任务入口和 YAML 执行方式确定后 | +| P-02 | 已停用的后端源码更新链仍有跨层残留 | 设置页面和更新功能仍在调试,暂时不能决定恢复还是删除 | 设置页面更新策略确定后 | +| P-03 | 严格检查仍有 4 条未使用提示 | 三条属于已挂起功能,一条属于待确认参数 | 当前一轮并行开发完成后 | + +## P-01 出征规划直接执行链 + +### 当前用途 + +这套代码原本用于在出征规划页面直接执行当前方案: + +1. 转换节点规则。 +2. 生成内存战斗计划。 +3. 为未保存方案创建临时 YAML。 +4. 组装舰队、维修和停止条件。 +5. 调用 `Scheduler.addTask()` 加入任务队列。 +6. 切回主页展示执行状态。 + +当前 `executePlan()` 没有按钮、事件绑定或其他代码调用,相关辅助方法只在 +这条封闭执行链中互相调用。 + +代码位置: + +- [节点转换、内存方案和临时文件](../../src/controller/plan/PlanController.ts#L1007-L1078) +- [直接执行和加入任务队列](../../src/controller/plan/PlanController.ts#L1080-L1158) + +### 挂起决定 + +- 当前不删除。 +- 主页任务入口完成后,先确认是否继续支持“出征规划直接加入队列”。 +- 如果保留,需要恢复明确入口并补充方案保存、入队参数和失败处理测试。 +- 如果统一改为从已保存 YAML 执行,则删除 `executePlan()` 及其专用辅助链。 + +## P-02 后端源码更新残留 + +### 当前用途 + +这是一套旧的手动后端源码更新流程,原设计为: + +```text +设置页面检查更新 +→ preload bridge +→ Electron IPC +→ checkForUpdates / pullUpdates +→ 拉取本地 AutoWSGR Git 仓库 +``` + +目前页面调用、preload bridge 和主进程 IPC 已通过注释停用,但以下内容仍保留: + +- 主进程中的未使用导入和注释 IPC: + [main.ts:L16-L17](../../electron/main.ts#L16-L17)、 + [main.ts:L2175-L2201](../../electron/main.ts#L2175-L2201) +- 注释掉的 preload bridge: + [preload.ts:L276-L292](../../electron/preload.ts#L276-L292) +- 保留的 bridge 类型: + [electronBridge.ts:L223-L237](../../src/types/electronBridge.ts#L223-L237) +- 仍然存在的检查和拉取实现: + [installer.ts:L131-L166](../../electron/pythonEnv/installer.ts#L131-L166)、 + [installer.ts:L251](../../electron/pythonEnv/installer.ts#L251) +- 设置页和启动流程中的停用调用: + [AppController.ts:L763-L789](../../src/controller/app/AppController.ts#L763-L789)、 + [envAndUpdates.ts:L88-L108](../../src/controller/startup/envAndUpdates.ts#L88-L108) + +这套旧流程不能和以下仍在使用的功能混为一谈: + +- `electron-updater` 提供的 GUI 自身更新。 +- 环境检查中的 AutoWSGR Python 包更新。 + +### 挂起决定 + +- 当前不删除,也不恢复。 +- 如果后续恢复手动源码更新,需要先定义 `external` 和 `managed` 两种后端模式的更新边界。 +- 如果后续确认不再使用,需要一次性删除导入、IPC、bridge、类型、实现和大段注释。 +- 清理时必须保留 GUI 自动更新和仍在使用的环境依赖更新。 + +## P-03 严格未使用检查 + +检查命令: + +```powershell +npx tsc --noEmit --noUnusedLocals --noUnusedParameters --pretty false +``` + +2026-08-03 最新结果为 4 条提示,全部属于未使用声明,没有发现其他类型错误。 +默认 `npm run build` 不启用这两个严格选项,因此正常构建仍能通过。 + +| 来源 | 数量 | 内容 | +|---|---:|---| +| P-01 | 1 | `executePlan` 没有调用 | +| P-02 | 2 | `checkForUpdates`、`pullUpdates` 导入未使用 | +| 其他开发残留 | 1 | `RepairManager` 的 `fleetId` 参数未使用 | + +前三条需要随 P-01 和 P-02 的功能去留一起处理。`fleetId` 需要先确认泡澡维修流程 +是否仍应按舰队区分,再决定补齐用途或删除参数。 + +### 挂起决定 + +- 当前不做批量清理。 +- 等并行开发稳定后重新运行严格检查,以最新结果为准。 +- 只删除最终版本中仍无调用的声明,不根据本次快照机械修改。 +- 对 `fleetId` 这类可能代表未完成业务逻辑的参数,先判断应该补齐功能还是删除。 + +## 复查清单 + +- [ ] 主页任务入口已经稳定。 +- [ ] 设置页面更新策略已经确定。 +- [ ] 当前一轮并行 Agent 修改已经结束。 +- [ ] 重新搜索 `executePlan` 的调用入口。 +- [ ] 区分旧后端源码更新、GUI 自动更新和环境依赖更新。 +- [ ] 重新运行正常构建和严格未使用检查。 +- [ ] 根据最终代码决定保留、接入或删除。 +- [ ] 更新本文档状态和最新检查结果。 + +## 不属于挂起项 + +- 系统 YAML 只读方案已被否决,不作为后续待办。 +- 后端日志中的 `7777` HTTP 调试请求已经删除。 +- 完整配置 YAML 已改为仅在调试模式下输出 `debug` 日志。 +- `.dbg`、Python 缓存和临时舰娘卡片预览页已经清理。 diff --git a/electron/backend.ts b/electron/backend.ts index 91766dc..a56a113 100644 --- a/electron/backend.ts +++ b/electron/backend.ts @@ -6,7 +6,13 @@ import * as path from 'path'; import * as fs from 'fs'; import { execSync, spawn, ChildProcess } from 'child_process'; import type { BrowserWindow } from 'electron'; -import { ensurePthFile, ensureSslCertForPython, findPython, localSitePackages } from './pythonEnv'; +import { + ensurePthFile, + ensureSslCertForPython, + findPython, + isLocalPython, + localSitePackages, +} from './pythonEnv'; // ════════════════════════════════════════ // Context — 由 main.ts 在启动时注入 @@ -225,6 +231,7 @@ export async function startBackend(): Promise { const guiSettings = readGuiSettings(); const backendStartupMode = guiSettings.backend_startup_mode === 'external' ? 'external' : 'managed'; const localBackendRepo = backendStartupMode === 'external' ? resolveLocalBackendRepoPath() : null; + const useLocalSite = !localBackendRepo || isLocalPython(pythonCmd); const ocrGpuMode = readOcrGpuModeFromSettings(); const configuredCudaRoot = readCudaPathFromSettings(); const saveBackendScreenshots = readSaveBackendScreenshotsFromSettings(); @@ -237,18 +244,29 @@ export async function startBackend(): Promise { // 3. 绕过嵌入式 Python 的 ._pth/PYTHONPATH 限制 const bootstrapParts = [ `import sys, os, site`, - `sp = r'${pyLiteral(localSite)}'`, - `sys.path.insert(0, sp)`, - `site.addsitedir(sp)`, // 处理 .pth 文件,激活 _distutils_hack + ...(useLocalSite + ? [ + `sp = r'${pyLiteral(localSite)}'`, + `sys.path.insert(0, sp)`, + `site.addsitedir(sp)`, // 处理 .pth 文件,激活 _distutils_hack + ] + : []), ...(localBackendRepo ? [`repo = r'${pyLiteral(localBackendRepo)}'`, `sys.path.insert(0, repo)`] : []), `GUI_OCR_GPU_MODE = '${ocrGpuMode}'`, `GUI_SAVE_IMAGES = ${saveBackendScreenshots ? 'True' : 'False'}`, + `from pathlib import Path`, `import autowsgr`, + ...(!localBackendRepo + ? [ + `_autowsgr_file = Path(autowsgr.__file__).resolve()`, + `if not _autowsgr_file.is_relative_to(Path(sp).resolve()):`, + ` raise RuntimeError('GUI 后端来源错误: ' + str(_autowsgr_file))`, + ] + : []), `print('[Bootstrap] autowsgr=' + getattr(autowsgr, '__file__', 'unknown'))`, `print('[Bootstrap] repo_override=' + (r'${pyLiteral(localBackendRepo ?? '')}' or ''))`, `print('[Bootstrap] ocr_gpu_mode=' + GUI_OCR_GPU_MODE)`, `print('[Bootstrap] save_backend_screenshots=' + ('true' if GUI_SAVE_IMAGES else 'false'))`, - `from pathlib import Path`, `import autowsgr.infra.logger as _aw_logger`, `from autowsgr.scheduler import launcher as _aw_launcher`, `import autowsgr.vision.ocr as _aw_ocr`, diff --git a/electron/main.ts b/electron/main.ts index 85fde38..18ca737 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -2,12 +2,14 @@ * Electron 主进程。 * 负责创建窗口、注册 IPC handler。 */ -import { app, BrowserWindow, ipcMain, dialog, shell } from 'electron'; +import { app, BrowserWindow, ipcMain, dialog, screen, shell } from 'electron'; import * as path from 'path'; import * as fs from 'fs'; -import { exec } from 'child_process'; +import { pathToFileURL } from 'url'; +import { exec, execFile, spawn } from 'child_process'; import { promisify } from 'util'; import { autoUpdater, UpdateInfo, ProgressInfo } from 'electron-updater'; +import * as yaml from 'js-yaml'; import { initPythonEnv, clearPythonCache, isAllowedPythonVersion, findPython, checkEnvironment, @@ -15,9 +17,104 @@ import { pullUpdates, } from './pythonEnv'; import { detectEmulator } from './emulatorDetect'; -import { initBackend, getBackendProcess, startBackend, stopBackend, runSetupScript } from './backend'; +import { + buildCudaEnvironment, + initBackend, + getBackendProcess, + startBackend, + stopBackend, + runSetupScript, +} from './backend'; + +/** 启动终端关闭输出管道时,不让 EPIPE 终止 GUI 主进程。 */ +function ignoreBrokenPipe(stream: NodeJS.WriteStream): void { + stream.on('error', (error: NodeJS.ErrnoException) => { + if (error.code !== 'EPIPE') throw error; + }); +} + +ignoreBrokenPipe(process.stdout); +ignoreBrokenPipe(process.stderr); const execAsync = promisify(exec); +const execFileAsync = promisify(execFile); + +function adbExecutable(): string { + const bundledAdb = path.join(appRoot(), 'adb', 'adb.exe'); + return fs.existsSync(bundledAdb) ? bundledAdb : 'adb'; +} + +async function listAdbDevices(): Promise<{ serial: string; status: string }[]> { + const { stdout } = await execFileAsync( + adbExecutable(), + ['devices'], + { windowsHide: true, timeout: 5000, encoding: 'utf8' }, + ); + return String(stdout) + .split(/\r?\n/) + .slice(1) + .map(line => line.trim()) + .filter(Boolean) + .map(line => { + const [serial, status] = line.split(/\s+/); + return { serial, status: status || 'unknown' }; + }); +} + +async function runAdbDeviceCommand( + command: 'connect' | 'disconnect', + rawSerial: string, +): Promise<{ + success: boolean; + serial: string; + status: string; + message: string; +}> { + const serial = String(rawSerial ?? '').trim(); + if (!serial || !/^[A-Za-z0-9._:[\]-]+$/.test(serial)) { + return { + success: false, + serial, + status: 'invalid', + message: 'ADB 地址格式不正确', + }; + } + + try { + const { stdout, stderr } = await execFileAsync( + adbExecutable(), + [command, serial], + { windowsHide: true, timeout: 10000, encoding: 'utf8' }, + ); + const devices = await listAdbDevices(); + const status = devices.find(device => device.serial === serial)?.status; + const success = command === 'connect' + ? status === 'device' + : status === undefined; + return { + success, + serial, + status: status ?? 'disconnected', + message: [stdout, stderr].map(value => String(value).trim()).filter(Boolean).join('\n') + || (success ? '操作成功' : '操作后设备状态未达到预期'), + }; + } catch (error) { + const details = error as { + message?: string; + stdout?: string; + stderr?: string; + }; + return { + success: false, + serial, + status: 'error', + message: [details.stderr, details.stdout, details.message] + .map(value => String(value ?? '').trim()) + .find(Boolean) + || 'ADB 命令执行失败', + }; + } +} /** GUI 设置文件路径(延迟到 app ready 后才有效,先用函数) */ function guiSettingsPath(): string { @@ -42,6 +139,78 @@ function writeGuiSettings(patch: Record): void { fs.writeFileSync(guiSettingsPath(), JSON.stringify(cur, null, 2), 'utf-8'); } +interface WindowBounds { + x: number; + y: number; + width: number; + height: number; +} + +interface WindowPreferences { + defaultWidth: number; + defaultHeight: number; + rememberBounds: boolean; +} + +const DEFAULT_WINDOW_WIDTH = 1280; +const DEFAULT_WINDOW_HEIGHT = 720; +const MIN_WINDOW_WIDTH = 854; +const MIN_WINDOW_HEIGHT = 480; + +function normalizeWindowSize(value: unknown, minimum: number, fallback: number): number { + if (typeof value !== 'number' || !Number.isFinite(value)) return fallback; + return Math.max(minimum, Math.trunc(value)); +} + +/** 默认窗口大小与窗口状态记忆属于 GUI 设置,不写入后端 usersettings.yaml。 */ +function getWindowPreferences(): WindowPreferences { + const settings = readGuiSettings(); + return { + defaultWidth: normalizeWindowSize( + settings.default_window_width, + MIN_WINDOW_WIDTH, + DEFAULT_WINDOW_WIDTH, + ), + defaultHeight: normalizeWindowSize( + settings.default_window_height, + MIN_WINDOW_HEIGHT, + DEFAULT_WINDOW_HEIGHT, + ), + rememberBounds: settings.remember_window_bounds === true, + }; +} + +function readRememberedWindowBounds(): WindowBounds | null { + const raw = readGuiSettings().window_bounds; + if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null; + const bounds = raw as Record; + if ( + typeof bounds.x !== 'number' + || typeof bounds.y !== 'number' + || !Number.isFinite(bounds.x) + || !Number.isFinite(bounds.y) + ) { + return null; + } + return { + x: Math.trunc(bounds.x), + y: Math.trunc(bounds.y), + width: normalizeWindowSize(bounds.width, MIN_WINDOW_WIDTH, DEFAULT_WINDOW_WIDTH), + height: normalizeWindowSize(bounds.height, MIN_WINDOW_HEIGHT, DEFAULT_WINDOW_HEIGHT), + }; +} + +/** 至少保留一块可拖动区域,避免显示器变化后窗口完全落在屏幕外。 */ +function isWindowBoundsVisible(bounds: WindowBounds): boolean { + return screen.getAllDisplays().some(({ workArea }) => { + const visibleWidth = Math.min(bounds.x + bounds.width, workArea.x + workArea.width) + - Math.max(bounds.x, workArea.x); + const visibleHeight = Math.min(bounds.y + bounds.height, workArea.y + workArea.height) + - Math.max(bounds.y, workArea.y); + return visibleWidth >= 160 && visibleHeight >= 80; + }); +} + /** 后端端口:环境变量 > gui_settings.json > 默认 8438 */ function getBackendPort(): number { if (process.env.AUTOWSGR_PORT) { @@ -73,6 +242,166 @@ function getUpdateMode(): 'auto' | 'manual' { type BackendStartupMode = 'managed' | 'external'; type OcrGpuMode = 'auto' | 'cpu' | 'cuda'; +interface GuiAutomationSettings { + expeditionInterval: number; + battleTimes: number; + autoLoot: boolean; + lootPlanIndex: number; + lootStopCount: number; +} + +interface DecisivePlanSettings { + chapter: number; + useQuickRepair: boolean; + level1: string[]; + level2: string[]; +} + +const DEFAULT_DECISIVE_PLAN: DecisivePlanSettings = { + chapter: 6, + useQuickRepair: true, + level1: [ + 'U-47', + 'U-1405', + 'U-1206', + 'U-2540', + 'U-81', + 'U-96', + ], + level2: [ + 'U-505', + '射水鱼', + '大青花鱼', + 'M-296', + '鹦鹉螺', + 'S-49', + 'IIIA', + 'K-21', + 'U-441', + '潜甲', + '潜乙', + '伊-201', + '伊-25', + '鲃鱼', + '伊-400', + '激流', + 'U-4501', + 'U-459', + 'U-14', + 'U-35', + 'K1', + ], +}; + +function normalizeDecisiveShips(value: unknown, fallback: string[]): string[] { + if (!Array.isArray(value)) return [...fallback]; + return value + .filter(item => typeof item === 'string') + .map(item => item.trim()) + .filter((item, index, values) => ( + item.length > 0 + && item.length <= 80 + && values.indexOf(item) === index + )); +} + +function normalizeDecisivePlanSettings(value: unknown): DecisivePlanSettings { + const raw = value && typeof value === 'object' && !Array.isArray(value) + ? value as Record + : {}; + const chapter = Math.trunc(Number(raw.chapter)); + const requestedMainShips = normalizeDecisiveShips( + raw.level1, + DEFAULT_DECISIVE_PLAN.level1, + ); + const mainShips = requestedMainShips.slice(0, 6); + const requestedBackupShips = normalizeDecisiveShips( + raw.level2, + DEFAULT_DECISIVE_PLAN.level2, + ); + const legacyLevel3 = Array.isArray(raw.level3) + ? normalizeDecisiveShips(raw.level3, []) + : []; + const backupShips: string[] = []; + for ( + const name of [ + ...requestedMainShips.slice(6), + ...requestedBackupShips, + ...legacyLevel3, + ] + ) { + if (!mainShips.includes(name) && !backupShips.includes(name)) { + backupShips.push(name); + } + } + return { + chapter: Number.isFinite(chapter) + ? Math.max(1, Math.min(6, chapter)) + : DEFAULT_DECISIVE_PLAN.chapter, + useQuickRepair: typeof raw.use_quick_repair === 'boolean' + ? raw.use_quick_repair + : typeof raw.useQuickRepair === 'boolean' + ? raw.useQuickRepair + : DEFAULT_DECISIVE_PLAN.useQuickRepair, + level1: mainShips, + level2: backupShips, + }; +} + +function getDecisivePlanSettings(): DecisivePlanSettings { + const rawSettings = readGuiSettings(); + const rawPlan = rawSettings.decisive_plan; + const normalized = normalizeDecisivePlanSettings(rawPlan); + if ( + rawPlan + && typeof rawPlan === 'object' + && !Array.isArray(rawPlan) + && ( + Object.prototype.hasOwnProperty.call(rawPlan, 'level3') + || ( + Array.isArray((rawPlan as Record).level1) + && ((rawPlan as Record).level1 as unknown[]).length > 6 + ) + ) + ) { + writeGuiSettings({ + decisive_plan: { + chapter: normalized.chapter, + use_quick_repair: normalized.useQuickRepair, + level1: normalized.level1, + level2: normalized.level2, + }, + }); + } + return normalized; +} + +function getGuiAutomationSettings(): { + exists: boolean; + settings: Partial; +} { + const raw = readGuiSettings().automation; + if (!raw || typeof raw !== 'object' || Array.isArray(raw)) { + return { exists: false, settings: {} }; + } + const value = raw as Record; + const settings: Partial = {}; + if (Number.isFinite(Number(value.expeditionInterval))) { + settings.expeditionInterval = Number(value.expeditionInterval); + } + if (Number.isFinite(Number(value.battleTimes))) { + settings.battleTimes = Number(value.battleTimes); + } + if (typeof value.autoLoot === 'boolean') settings.autoLoot = value.autoLoot; + if (Number.isFinite(Number(value.lootPlanIndex))) { + settings.lootPlanIndex = Number(value.lootPlanIndex); + } + if (Number.isFinite(Number(value.lootStopCount))) { + settings.lootStopCount = Number(value.lootStopCount); + } + return { exists: true, settings }; +} + function getBackendStartupMode(): BackendStartupMode { const settings = readGuiSettings(); return settings.backend_startup_mode === 'external' ? 'external' : 'managed'; @@ -113,7 +442,17 @@ function findCudaRuntimeDll(directory: string): boolean { } } -function validateCudaPath(candidate: string): { valid: boolean; path: string; version: string | null; kind?: 'toolkit' | 'runtime'; error?: string } { +interface CudaValidationResult { + valid: boolean; + path: string; + version: string | null; + kind?: 'toolkit' | 'runtime'; + torchVersion?: string | null; + device?: string | null; + error?: string; +} + +function validateCudaPath(candidate: string): CudaValidationResult { if (!candidate.trim()) return { valid: false, path: '', version: null, error: '路径为空' }; const cudaRoot = normalizeCudaPath(candidate); if (!fs.existsSync(cudaRoot)) return { valid: false, path: cudaRoot, version: null, error: '目录不存在' }; @@ -149,12 +488,112 @@ function validateCudaPath(candidate: string): { valid: boolean; path: string; ve return { valid: true, path: runtimeDir!, version: runtimeVersion, kind: 'runtime' }; } +/** 使用后端实际采用的 Python 环境检测 PyTorch、CUDA 和显卡。 */ +async function detectCudaEnvironment(candidate: string): Promise { + const rawPath = candidate.trim(); + const pathResult = rawPath ? validateCudaPath(rawPath) : null; + if (pathResult && !pathResult.valid) return pathResult; + + const pythonCmd = await findPython(); + if (!pythonCmd) { + return { + valid: false, + path: pathResult?.path ?? '', + version: pathResult?.version ?? null, + kind: pathResult?.kind, + error: '未找到可用的 Python 3.12 或 3.13', + }; + } + + const script = [ + 'import json', + 'try:', + ' import torch', + ' available = bool(torch.cuda.is_available())', + ' result = {', + ' "available": available,', + ' "torch_version": str(torch.__version__),', + ' "cuda_version": getattr(torch.version, "cuda", None),', + ' "device": torch.cuda.get_device_name(0) if available else None,', + ' }', + 'except Exception as exc:', + ' result = {"available": False, "error": str(exc)}', + 'print(json.dumps(result, ensure_ascii=False))', + ].join('\n'); + + try { + const { stdout } = await execFileAsync( + pythonCmd, + ['-c', script], + { + windowsHide: true, + timeout: 20000, + encoding: 'utf8', + env: buildCudaEnvironment(process.env, pathResult?.path ?? null), + }, + ); + const output = String(stdout).trim().split(/\r?\n/).filter(Boolean).at(-1); + if (!output) throw new Error('Python 未返回检测结果'); + const detected = JSON.parse(output) as { + available?: boolean; + torch_version?: string; + cuda_version?: string | null; + device?: string | null; + error?: string; + }; + const version = detected.cuda_version ?? pathResult?.version ?? null; + if (!detected.available) { + return { + valid: false, + path: pathResult?.path ?? '', + version, + kind: pathResult?.kind, + torchVersion: detected.torch_version ?? null, + device: null, + error: detected.error + ? `PyTorch 检测失败:${detected.error}` + : `PyTorch ${detected.torch_version ?? ''} 未检测到可用 CUDA`.replace(/\s+/g, ' ').trim(), + }; + } + return { + valid: true, + path: pathResult?.path ?? '', + version, + kind: pathResult?.kind, + torchVersion: detected.torch_version ?? null, + device: detected.device ?? null, + }; + } catch (error) { + return { + valid: false, + path: pathResult?.path ?? '', + version: pathResult?.version ?? null, + kind: pathResult?.kind, + error: `硬件检测失败:${error instanceof Error ? error.message : String(error)}`, + }; + } +} + function getSaveBackendScreenshots(): boolean { const settings = readGuiSettings(); return settings.save_backend_screenshots === true; } let mainWindow: BrowserWindow | null = null; +let lastWindowBounds: WindowBounds | null = null; + +/** 缓存最后一次正常窗口边界,供窗口销毁后的退出阶段使用。 */ +function captureWindowBounds(win: BrowserWindow | null): void { + if (!win || win.isDestroyed()) return; + lastWindowBounds = win.getNormalBounds(); +} + +/** 仅在用户启用窗口记忆时写入最后一次正常窗口边界。 */ +function persistWindowBounds(): void { + if (getWindowPreferences().rememberBounds && lastWindowBounds) { + writeGuiSettings({ window_bounds: lastWindowBounds }); + } +} /** 是否处于打包后的生产模式 */ function isPackaged(): boolean { @@ -173,7 +612,7 @@ function appRoot(): string { return path.join(__dirname, '..', '..'); } -/** extraResources 目录 (resource/, plans/, setup.bat) */ +/** extraResources 目录 (resource/, setup.bat) */ function resourceRoot(): string { if (isPackaged()) { return process.resourcesPath; @@ -188,19 +627,26 @@ function resolveAppPath(filePath: string): string { if (filePath.startsWith('resource')) { return path.join(resourceRoot(), filePath); } - // plans/ 及其他文件在 appRoot(可写,用户数据不会被覆盖安装覆盖) + // 其他文件在 appRoot(可写,用户数据不会被安装覆盖) return path.join(appRoot(), filePath); } -/** - * 初始化用户方案目录:将 extraResources 中的默认方案 - * 复制到 appRoot/plans(不覆盖已有文件,保留用户自定义方案)。 - */ -function initUserPlansDir(): void { - const bundledDir = path.join(resourceRoot(), 'plans'); - const userDir = path.join(appRoot(), 'plans'); - if (!fs.existsSync(bundledDir)) return; - copyDirNoOverwrite(bundledDir, userDir); +function systemBattlePlansDir(): string { + return path.join(resourceRoot(), 'resource', 'system_battle_plans'); +} + +/** 用户出征方案统一存放在 resource/user_battle_plans。 */ +function userBattlePlansDir(): string { + return path.join( + isPackaged() ? appRoot() : resourceRoot(), + 'resource', + 'user_battle_plans', + ); +} + +/** 初始化用户出征方案目录。 */ +function initUserBattlePlansDir(): void { + fs.mkdirSync(userBattlePlansDir(), { recursive: true }); } /** 递归复制目录,跳过已存在的文件 */ @@ -217,12 +663,1274 @@ function copyDirNoOverwrite(src: string, dest: string): void { } } +interface ShipLibraryStatus { + exists: boolean; + path: string; + generatedAt?: string; + shipCount: number; + assetCount: number; + missingAssets: number; + error?: string; +} + +interface ShipLibraryUpdateResult { + success: boolean; + output?: string; + generated_at?: string; + ship_count?: number; + asset_count?: number; + added?: number; + updated?: number; + removed?: number; + downloaded?: number; + failed?: number; + failures?: string[]; + error?: string; +} + +interface ShipLibraryManifest { + schemaVersion: number; + generatedAt: string; + labels: Record; + typeGroups: Record; + ships: Array>; +} + +/** 当前可写的舰船资料库目录。 */ +function shipLibraryDir(): string { + if (isPackaged()) { + return path.join(app.getPath('userData'), 'ship-library'); + } + return path.join(resourceRoot(), 'resource', 'ship-library'); +} + +/** 打包后将内置资料库复制到用户目录,已有文件不覆盖。 */ +function initUserShipLibraryDir(): void { + if (!isPackaged()) return; + const bundledDir = path.join(resourceRoot(), 'resource', 'ship-library'); + if (fs.existsSync(bundledDir)) { + copyDirNoOverwrite(bundledDir, shipLibraryDir()); + } +} + +const ALLOWED_FLEET_SHIP_TYPES = new Set([ + 'dd', + 'cl', + 'ca', + 'cav', + 'clt', + 'bb', + 'bc', + 'bbv', + 'cv', + 'cvl', + 'av', + 'ss', + 'ssg', + 'cg', + 'cgaa', + 'ddg', + 'ddgaa', + 'bm', + 'cbg', + 'cf', + 'ss_or_ssg', +]); +const TEAM_FILE_PATTERN = /^team[-_][^\\/]+\.ya?ml$/i; +type PlanPresetSource = 'system' | 'user'; +type ManagedBattleResult = 'D' | 'C' | 'B' | 'A' | 'S' | 'SS'; + +interface ManagedBattlePlanFleetSummary { + name: string; + source: PlanPresetSource | 'deleted'; + primaryCount: number; + backupCount: number; +} + +interface ManagedBattlePlanSummary { + file: string; + name: string; + source: PlanPresetSource; + modifiedAt: number; + chapter: number | string; + map: number | string; + times: number; + gap: number; + fleetId: number; + repairMode: number | number[]; + result: ManagedBattleResult | null; + lootCountGe: number; + shipCountGe: number; + fleetCount: number; + nodeCount: number; + fleets: ManagedBattlePlanFleetSummary[]; +} + +interface PlanFileReadError { + file: string; + source: PlanPresetSource; + kind: 'battle' | 'team'; + message: string; +} + +interface UserTeamShipRule { + name: string; + search_name?: string; + ship_type?: string[]; + min_level?: number; + max_level?: number; +} + +interface UserTeamPlanSlot { + name?: string; + search_name?: string; + ship_type?: string[]; + min_level?: number; + max_level?: number; + candidates?: UserTeamShipRule[]; +} + +interface UserTeamPlan { + file?: string; + modifiedAt?: number; + source?: PlanPresetSource; + name: string; + ships: UserTeamPlanSlot[]; +} + +interface LegacyPlanConversionResult { + success: boolean; + canceled?: boolean; + exists?: boolean; + inputPath?: string; + file?: string; + path?: string; + source?: PlanPresetSource; + teamFiles?: string[]; + conflicts?: string[]; + error?: string; +} + +function systemTeamPlansDir(): string { + return path.join(resourceRoot(), 'resource', 'system_team_plans'); +} + +/** 用户编队目录在开发模式下固定为 resource/user_team_plans。 */ +function userTeamPlansDir(): string { + return path.join( + isPackaged() ? appRoot() : resourceRoot(), + 'resource', + 'user_team_plans', + ); +} + +function initUserTeamPlansDir(): void { + fs.mkdirSync(userTeamPlansDir(), { recursive: true }); +} + +function initSystemPlanDirs(): void { + fs.mkdirSync(systemBattlePlansDir(), { recursive: true }); + fs.mkdirSync(systemTeamPlansDir(), { recursive: true }); +} + +function isPlainObject(value: unknown): value is Record { + return Boolean(value) && typeof value === 'object' && !Array.isArray(value); +} + +function positiveInteger(value: unknown, field: string): number | undefined { + if (value === undefined || value === null || value === '') return undefined; + if (!Number.isInteger(value) || Number(value) < 1) { + throw new Error(`${field} 必须是大于或等于 1 的整数`); + } + return Number(value); +} + +function normalizeUserTeamShipTypes( + raw: unknown, + field: string, +): string[] | undefined { + if (raw === undefined || raw === null || raw === '') return undefined; + const values = typeof raw === 'string' ? [raw] : raw; + if (!Array.isArray(values) || values.length === 0) { + throw new Error(`${field} 必须是非空字符串列表`); + } + const result = values.map((value) => { + if (typeof value !== 'string' || !value.trim()) { + throw new Error(`${field} 必须是非空字符串列表`); + } + const shipType = value.trim().toLowerCase(); + if (!ALLOWED_FLEET_SHIP_TYPES.has(shipType)) { + throw new Error(`${field} 不符合后端接口: ${shipType}`); + } + return shipType; + }); + return [...new Set(result)]; +} + +/** 校验一艘主选或备选舰船自己的规则。 */ +function normalizeUserTeamShipRule( + raw: unknown, + field: string, +): UserTeamShipRule { + if (!isPlainObject(raw)) throw new Error(`${field} 必须是对象`); + const allowedKeys = new Set([ + 'name', + 'search_name', + 'ship_type', + 'min_level', + 'max_level', + ]); + if (Object.keys(raw).some(key => !allowedKeys.has(key))) { + throw new Error(`${field} 包含后端不支持的字段`); + } + + if (typeof raw.name !== 'string' || !raw.name.trim()) { + throw new Error(`${field}.name 必须是非空字符串`); + } + const result: UserTeamShipRule = { name: raw.name.trim() }; + if (raw.search_name !== undefined) { + if (typeof raw.search_name !== 'string' || !raw.search_name.trim()) { + throw new Error(`${field}.search_name 必须是非空字符串`); + } + result.search_name = raw.search_name.trim(); + } + const shipTypes = normalizeUserTeamShipTypes( + raw.ship_type, + `${field}.ship_type`, + ); + if (shipTypes) result.ship_type = shipTypes; + const minLevel = positiveInteger(raw.min_level, `${field}.min_level`); + const maxLevel = positiveInteger(raw.max_level, `${field}.max_level`); + if (minLevel !== undefined) result.min_level = minLevel; + if (maxLevel !== undefined) result.max_level = maxLevel; + if ( + minLevel !== undefined + && maxLevel !== undefined + && maxLevel < minLevel + ) { + throw new Error(`${field}.max_level 必须大于或等于 min_level`); + } + return result; +} + +/** 旧 candidates 字符串继承原槽位的舰种和等级限制。 */ +function legacyCandidateRule( + name: string, + raw: Record, +): UserTeamShipRule { + return normalizeUserTeamShipRule({ + name, + ship_type: raw.ship_type, + min_level: raw.min_level, + max_level: raw.max_level, + }, `旧版候选 ${name}`); +} + +/** 校验单个位置;主选可以为空,但位置必须至少包含一艘主选或备选。 */ +function normalizeUserTeamSlot(raw: unknown): UserTeamPlanSlot | null { + if (raw === null) return null; + if (typeof raw === 'string') { + const name = raw.trim(); + if (!name) throw new Error('ships 中的舰名不能为空'); + return { name }; + } + if (!isPlainObject(raw)) throw new Error('ships 中的槽位必须是对象'); + const allowedKeys = new Set([ + 'name', + 'candidates', + 'priority', + 'search_name', + 'ship_type', + 'min_level', + 'max_level', + ]); + if (Object.keys(raw).some(key => !allowedKeys.has(key))) { + throw new Error('槽位包含后端不支持的字段'); + } + + if (raw.candidates !== undefined && !Array.isArray(raw.candidates)) { + throw new Error('candidates 必须是列表'); + } + if (raw.priority !== undefined && !Array.isArray(raw.priority)) { + throw new Error('旧版 priority 必须是列表'); + } + const rawCandidates = ( + raw.candidates ?? raw.priority + ) as unknown[] | undefined; + const legacyNames = rawCandidates?.every( + value => typeof value === 'string', + ) === true + ? rawCandidates.map(value => String(value).trim()) + : null; + + let primaryRaw: Record | null = ( + typeof raw.name === 'string' && raw.name.trim() + ) + ? raw + : null; + let candidatesRaw = rawCandidates ?? []; + if ( + primaryRaw === null + && legacyNames + && legacyNames.length > 0 + && legacyNames.every(Boolean) + ) { + primaryRaw = { ...raw, name: legacyNames[0] }; + candidatesRaw = legacyNames.slice(1); + } + + const candidates = candidatesRaw.map((candidate, index) => { + if (typeof candidate === 'string') { + const name = candidate.trim(); + if (!name) throw new Error(`candidates[${index}] 舰名不能为空`); + return legacyCandidateRule(name, raw); + } + return normalizeUserTeamShipRule( + candidate, + `candidates[${index}]`, + ); + }); + + if (primaryRaw === null) { + if ( + raw.search_name !== undefined + || raw.ship_type !== undefined + || raw.min_level !== undefined + || raw.max_level !== undefined + ) { + throw new Error('没有主选 name 时不能填写主选规则'); + } + if (candidates.length === 0) { + throw new Error('位置至少需要一艘主选或备选舰船'); + } + return { candidates }; + } + + const { + candidates: _ignoredCandidates, + priority: _ignoredPriority, + ...primaryFields + } = primaryRaw; + const result: UserTeamPlanSlot = { + ...normalizeUserTeamShipRule(primaryFields, '主选'), + }; + if (candidates.length > 0) { + result.candidates = candidates; + } + return result; +} + +/** 校验独立编队文件:一个名称对应一支最多六个位置的舰队。 */ +function normalizeUserTeamPlan(raw: unknown): UserTeamPlan { + if (!isPlainObject(raw)) throw new Error('编队 YAML 根节点必须是对象'); + const allowedKeys = new Set(['name', 'fleet_id', 'ships']); + if (Object.keys(raw).some(key => !allowedKeys.has(key))) { + throw new Error('编队 YAML 包含不支持的根字段'); + } + if (typeof raw.name !== 'string' || !raw.name.trim()) { + throw new Error('name 不能为空'); + } + if (!Array.isArray(raw.ships) || raw.ships.length < 1 || raw.ships.length > 6) { + throw new Error('ships 必须包含 1 到 6 个位置'); + } + if (raw.fleet_id !== undefined && ( + !Number.isInteger(raw.fleet_id) + || Number(raw.fleet_id) < 1 + || Number(raw.fleet_id) > 4 + )) { + throw new Error('旧版 fleet_id 必须是 1 到 4'); + } + const ships = raw.ships + .map(normalizeUserTeamSlot) + .filter((slot): slot is UserTeamPlanSlot => slot !== null); + if (ships.length === 0) { + throw new Error('ships 至少需要一个有效位置'); + } + return { name: raw.name.trim(), ships }; +} + +/** 使用行内 YAML 表示列表或备选对象,避免备选较多时纵向膨胀。 */ +function inlineYaml(value: unknown): string { + return yaml.dump(value, { + flowLevel: 0, + lineWidth: -1, + noRefs: true, + sortKeys: false, + }).trim(); +} + +/** 主选分行输出;纯备选位置不写 name,单个备选保持在同一行。 */ +function serializeUserTeamPlan(plan: UserTeamPlan): string { + const lines = [ + `name: ${inlineYaml(plan.name)}`, + 'ships:', + ]; + for (const slot of plan.ships) { + if (slot.name !== undefined) { + lines.push(` - name: ${inlineYaml(slot.name)}`); + if (slot.search_name !== undefined) { + lines.push(` search_name: ${inlineYaml(slot.search_name)}`); + } + if (slot.ship_type !== undefined) { + lines.push(` ship_type: ${inlineYaml(slot.ship_type)}`); + } + if (slot.min_level !== undefined) { + lines.push(` min_level: ${slot.min_level}`); + } + if (slot.max_level !== undefined) { + lines.push(` max_level: ${slot.max_level}`); + } + } + if (slot.candidates?.length) { + lines.push(slot.name === undefined ? ' - candidates:' : ' candidates:'); + for (const candidate of slot.candidates) { + lines.push(` - ${inlineYaml(candidate)}`); + } + } + } + return `${lines.join('\n')}\n`; +} + +function teamFileName(name: string): string { + const safeName = name + .trim() + .replace(/[<>:"/\\|?*\x00-\x1f]/g, '_') + .replace(/[. ]+$/g, '') + .slice(0, 80); + if (!safeName) throw new Error('编队预设名称不能用于文件名'); + return `team-${safeName}.yaml`; +} + +function atomicWrite(filePath: string, content: string): void { + const temporary = `${filePath}.${process.pid}.${Date.now()}.tmp`; + fs.writeFileSync(temporary, content, 'utf-8'); + try { + fs.renameSync(temporary, filePath); + } catch { + if (fs.existsSync(filePath)) fs.unlinkSync(filePath); + fs.renameSync(temporary, filePath); + } +} + +function readUserTeamPlan(filePath: string): UserTeamPlan { + return normalizeUserTeamPlan( + yaml.load(fs.readFileSync(filePath, 'utf-8')), + ); +} + +function userTeamPlanMatches( + filePath: string, + plan: UserTeamPlan, +): boolean { + if (!fs.existsSync(filePath)) return false; + try { + return JSON.stringify(readUserTeamPlan(filePath)) + === JSON.stringify(plan); + } catch { + return false; + } +} + +function buildTeamPlanWrites( + teams: UserTeamPlan[], + directory: string, +): Array<{ + name: string; + file: string; + path: string; + content: string; +}> { + const files = new Set(); + return teams.map((team) => { + const file = teamFileName(team.name); + const normalizedFile = file.toLowerCase(); + if (files.has(normalizedFile)) { + throw new Error( + `舰队名称生成了重复文件名,请修改名称:${team.name}`, + ); + } + files.add(normalizedFile); + return { + name: team.name, + file, + path: path.join(directory, file), + content: serializeUserTeamPlan(team), + }; + }); +} + +/** 列出系统和用户目录中命名、内容均合法的编队文件。 */ +function listTeamPlans(): { + plans: UserTeamPlan[]; + errors: PlanFileReadError[]; +} { + const plans: UserTeamPlan[] = []; + const errors: PlanFileReadError[] = []; + const sources: Array<{ + directory: string; + source: PlanPresetSource; + }> = [ + { directory: systemTeamPlansDir(), source: 'system' }, + { directory: userTeamPlansDir(), source: 'user' }, + ]; + for (const { directory, source } of sources) { + for (const file of yamlFiles(directory)) { + if (!TEAM_FILE_PATTERN.test(file)) { + errors.push({ + file, + source, + kind: 'team', + message: '舰队文件名必须以 team- 或 team_ 开头', + }); + continue; + } + try { + const filePath = path.join(directory, file); + const plan = readUserTeamPlan(filePath); + plans.push({ + ...plan, + file, + modifiedAt: fs.statSync(filePath).mtimeMs, + source, + }); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + errors.push({ file, source, kind: 'team', message }); + } + } + } + return { plans, errors }; +} + +function yamlFiles(directory: string): string[] { + if (!fs.existsSync(directory)) return []; + return fs.readdirSync(directory) + .filter(file => /\.ya?ml$/i.test(file)) + .sort((left, right) => left.localeCompare(right, 'zh-CN')); +} + +function serializeCombatPlan( + root: Record, + originalContent = '', +): string { + const leadingComments: string[] = []; + for (const line of originalContent.split(/\r?\n/)) { + const trimmed = line.trimStart(); + if (trimmed.startsWith('#') || trimmed === '') { + leadingComments.push(line); + continue; + } + break; + } + const body = yaml.dump(root, { + lineWidth: -1, + noCompatMode: true, + noRefs: true, + sortKeys: false, + }); + const prefix = leadingComments.some(line => line.trimStart().startsWith('#')) + ? `${leadingComments.join('\n').replace(/\s+$/, '')}\n` + : ''; + return `${prefix}${body}`; +} + +function findTeamPlan( + name: string, + source: PlanPresetSource, + plans = listTeamPlans().plans, +): UserTeamPlan | null { + return plans.find(plan => ( + plan.name === name && plan.source === source + )) ?? plans.find(plan => plan.name === name) ?? null; +} + +function normalizeCombatPlanFleetPresets( + root: Record, + source: PlanPresetSource, + requireEmbeddedShips: boolean, +): { + mapRoot: Record; + teams: UserTeamPlan[]; +} { + if (!('chapter' in root) || !('map' in root)) { + throw new Error('出征计划必须包含 chapter 和 map'); + } + if (root.fleet_presets === undefined) { + return { + mapRoot: structuredClone(root), + teams: [], + }; + } + if (!Array.isArray(root.fleet_presets)) { + throw new Error('fleet_presets 必须是列表'); + } + + const names = new Set(); + const teams: UserTeamPlan[] = []; + const references = root.fleet_presets.map((rawPreset, index) => { + if (!isPlainObject(rawPreset)) { + throw new Error(`fleet_presets[${index}] 必须是对象`); + } + const name = typeof rawPreset.name === 'string' + ? rawPreset.name.trim() + : ''; + if (!name) { + throw new Error(`fleet_presets[${index}].name 不能为空`); + } + if (names.has(name)) { + throw new Error(`fleet_presets 中存在重复舰队名称:${name}`); + } + names.add(name); + + if (Array.isArray(rawPreset.ships)) { + teams.push(normalizeUserTeamPlan({ + name, + ships: rawPreset.ships, + })); + } else { + if (requireEmbeddedShips) { + throw new Error(`旧计划中的舰队「${name}」缺少 ships`); + } + if (!findTeamPlan(name, source)) { + throw new Error(`找不到舰队「${name}」的独立配置`); + } + } + return { name }; + }); + + return { + mapRoot: { + ...structuredClone(root), + fleet_presets: references, + }, + teams, + }; +} + +function expandCombatPlanRoot( + root: Record, + source: PlanPresetSource, +): Record { + if (!('chapter' in root) || !('map' in root)) { + throw new Error('出征计划必须包含 chapter 和 map'); + } + if (root.fleet_presets === undefined) { + return structuredClone(root); + } + if (!Array.isArray(root.fleet_presets)) { + throw new Error('fleet_presets 必须是列表'); + } + + const listedTeams = listTeamPlans().plans; + const presets = root.fleet_presets.map((rawPreset, index) => { + if (!isPlainObject(rawPreset)) { + throw new Error(`fleet_presets[${index}] 必须是对象`); + } + const name = typeof rawPreset.name === 'string' + ? rawPreset.name.trim() + : ''; + if (!name) { + throw new Error(`fleet_presets[${index}].name 不能为空`); + } + + const sameSourceTeam = listedTeams.find(team => ( + team.name === name && team.source === source + )) ?? null; + const embeddedTeam = Array.isArray(rawPreset.ships) + ? normalizeUserTeamPlan({ + name, + ships: rawPreset.ships, + }) + : null; + const team = sameSourceTeam + ?? embeddedTeam + ?? findTeamPlan(name, source, listedTeams); + if (!team) { + throw new Error(`地图引用的舰队「${name}」不存在`); + } + return { + ...structuredClone(rawPreset), + name, + ships: structuredClone(team.ships), + }; + }); + + return { + ...structuredClone(root), + fleet_presets: presets, + }; +} + +let runtimePlanSequence = 0; + +function runtimeBattlePlansDir(): string { + return path.join( + app.getPath('temp'), + 'AutoWSGR-GUI', + 'runtime_battle_plans', + String(process.pid), + ); +} + +function writeRuntimeCombatPlan( + content: string, + hint: string, +): string { + const parsed = yaml.load(content); + if ( + !isPlainObject(parsed) + || !('chapter' in parsed) + || !('map' in parsed) + ) { + throw new Error('运行时出征计划必须包含 chapter 和 map'); + } + if ( + Array.isArray(parsed.fleet_presets) + && parsed.fleet_presets.some(preset => ( + !isPlainObject(preset) + || !Array.isArray(preset.ships) + )) + ) { + throw new Error('运行时出征计划包含尚未展开的舰队引用'); + } + const directory = runtimeBattlePlansDir(); + fs.mkdirSync(directory, { recursive: true }); + runtimePlanSequence++; + const safeHint = safePlanBaseName(hint) || 'plan'; + const file = `${safeHint}-${Date.now()}-${runtimePlanSequence}.yaml`; + const target = path.join(directory, file); + atomicWrite(target, content); + return target; +} + +function prepareManagedCombatPlan( + source: PlanPresetSource, + file: string, +): { + sourcePath: string; + runtimePath: string; + content: string; +} { + const sourcePath = safeManagedBattlePlanPath(source, file); + if (!sourcePath || !fs.existsSync(sourcePath)) { + throw new Error('出征计划不存在'); + } + const originalContent = fs.readFileSync(sourcePath, 'utf-8'); + const parsed = yaml.load(originalContent); + if (!isPlainObject(parsed)) { + throw new Error('无效的出征计划'); + } + const expanded = expandCombatPlanRoot(parsed, source); + const content = serializeCombatPlan(expanded, originalContent); + return { + sourcePath, + runtimePath: writeRuntimeCombatPlan(content, file), + content, + }; +} + +function managedBattlePlanFromPath( + filePath: string, +): { + source: PlanPresetSource; + file: string; +} | null { + const resolved = path.resolve(filePath); + for (const source of ['system', 'user'] as const) { + const directory = path.resolve( + source === 'system' + ? systemBattlePlansDir() + : userBattlePlansDir(), + ); + if ( + path.dirname(resolved).toLowerCase() === directory.toLowerCase() + && /\.ya?ml$/i.test(path.basename(resolved)) + ) { + return { + source, + file: path.basename(resolved), + }; + } + } + return null; +} + +function safeUserPlanPath(file: string): string | null { + if (path.basename(file) !== file || !/\.ya?ml$/i.test(file)) return null; + return path.join(userBattlePlansDir(), file); +} + +function safeUserTeamPlanPath(file: string): string | null { + if (path.basename(file) !== file || !TEAM_FILE_PATTERN.test(file)) return null; + return path.join(userTeamPlansDir(), file); +} + +function safeManagedBattlePlanPath( + source: PlanPresetSource, + file: string, +): string | null { + if ( + (source !== 'system' && source !== 'user') + || path.basename(file) !== file + || !/\.ya?ml$/i.test(file) + ) { + return null; + } + return path.join( + source === 'system' ? systemBattlePlansDir() : userBattlePlansDir(), + file, + ); +} + +function safeManagedTeamPlanPath( + source: PlanPresetSource, + file: string, +): string | null { + if ( + (source !== 'system' && source !== 'user') + || path.basename(file) !== file + || !TEAM_FILE_PATTERN.test(file) + ) { + return null; + } + return path.join( + source === 'system' ? systemTeamPlansDir() : userTeamPlansDir(), + file, + ); +} + +function ignoredUnlinkedPlanKey( + kind: 'battle' | 'team', + source: PlanPresetSource, + file: string, +): string | null { + const valid = kind === 'battle' + ? safeManagedBattlePlanPath(source, file) + : safeManagedTeamPlanPath(source, file); + return valid + ? `${kind}/${source}/${file}` + : null; +} + +function getIgnoredUnlinkedPlans(): string[] { + const raw = readGuiSettings().plan_management_ignored_unlinked; + if (!Array.isArray(raw)) return []; + return raw.flatMap((value) => { + if (typeof value !== 'string') return []; + if (/^(battle|team)\/(system|user)\/[^/\\]+\.ya?ml$/i.test(value)) { + return [value]; + } + const legacy = /^(system|user)\/([^/\\]+\.ya?ml)$/i.exec(value); + return legacy ? [`battle/${legacy[1]}/${legacy[2]}`] : []; + }); +} + +function writeIgnoredUnlinkedPlans(values: Iterable): string[] { + const normalized = [...new Set(values)].sort((left, right) => ( + left.localeCompare(right, 'zh-CN') + )); + writeGuiSettings({ plan_management_ignored_unlinked: normalized }); + return normalized; +} + +function safePlanBaseName(value: string): string { + return value + .trim() + .replace(/\.ya?ml$/i, '') + .replace(/^bettle-/i, '') + .replace(/[<>:"/\\|?*\x00-\x1f]/g, '_') + .replace(/[. ]+$/g, '') + .slice(0, 100); +} + +/** 读取管理页所需的出征计划、舰队方案及名称关联。 */ +function getPlanManagement(): { + bindings: Array<{ + planFile: string; + planName: string; + source: PlanPresetSource; + teamName: string | null; + }>; + battlePlans: ManagedBattlePlanSummary[]; + teamPlans: Array<{ + file: string; + name: string; + source: PlanPresetSource; + }>; + errors: PlanFileReadError[]; + ignoredUnlinkedPlans: string[]; +} { + const bindings: Array<{ + planFile: string; + planName: string; + source: PlanPresetSource; + teamName: string | null; + }> = []; + const battlePlans: ManagedBattlePlanSummary[] = []; + const errors: PlanFileReadError[] = []; + const listedTeams = listTeamPlans(); + errors.push(...listedTeams.errors); + const sources: Array<{ + directory: string; + source: PlanPresetSource; + }> = [ + { + directory: systemBattlePlansDir(), + source: 'system', + }, + { + directory: userBattlePlansDir(), + source: 'user', + }, + ]; + + sources.forEach(({ directory, source }) => { + yamlFiles(directory).forEach((file) => { + try { + const planPath = path.join(directory, file); + const raw = yaml.load( + fs.readFileSync(planPath, 'utf-8'), + ); + if (!isPlainObject(raw)) { + throw new Error('无效的方案文件'); + } + const root = raw; + const rootName = typeof root.name === 'string' ? root.name.trim() : ''; + const fileName = file.replace(/\.ya?ml$/i, ''); + const standardName = fileName.match(/^bettle-(.+)$/i)?.[1]; + const planName = standardName || rootName || fileName; + const presets = Array.isArray(root.fleet_presets) + ? root.fleet_presets + : []; + const selectedNodes = Array.isArray(root.selected_nodes) + ? root.selected_nodes + : []; + const times = Number(root.times); + const gap = Number(root.gap); + const fleetId = Number(root.fleet_id); + const repairModeValue = Number(root.repair_mode); + const repairModeList = Array.isArray(root.repair_mode) + ? root.repair_mode + .map(value => Number(value)) + .filter(value => Number.isFinite(value)) + : []; + const normalizedResult = typeof root.result === 'string' + ? root.result.trim().toUpperCase() + : ''; + const result = ( + ['D', 'C', 'B', 'A', 'S', 'SS'] as ManagedBattleResult[] + ).includes(normalizedResult as ManagedBattleResult) + ? normalizedResult as ManagedBattleResult + : null; + const stopCondition = isPlainObject(root.stop_condition) + ? root.stop_condition + : {}; + const lootCountGe = Number(stopCondition.loot_count_ge); + const shipCountGe = Number(stopCondition.ship_count_ge); + const fleets = presets.flatMap((preset, index) => { + if (!isPlainObject(preset)) return []; + const name = typeof preset.name === 'string' && preset.name.trim() + ? preset.name.trim() + : `编队 ${index + 1}`; + const sameSourceTeam = listedTeams.plans.find(team => ( + team.name === name && team.source === source + )) ?? null; + const embeddedShips = Array.isArray(preset.ships) + ? preset.ships + : null; + const matchingPlan = sameSourceTeam + ?? (embeddedShips + ? null + : findTeamPlan(name, source, listedTeams.plans)); + const ships = matchingPlan?.ships ?? embeddedShips ?? []; + return [{ + name, + source: ( + matchingPlan?.source ?? 'deleted' + ) as ManagedBattlePlanFleetSummary['source'], + primaryCount: ships.filter(ship => ( + (typeof ship === 'string' && Boolean(ship.trim())) + || ( + isPlainObject(ship) + && typeof ship.name === 'string' + && Boolean(ship.name.trim()) + ) + )).length, + backupCount: ships.reduce((count, ship) => ( + count + ( + isPlainObject(ship) && Array.isArray(ship.candidates) + ? ship.candidates.length + : 0 + ) + ), 0), + }]; + }); + battlePlans.push({ + file, + name: planName, + source, + modifiedAt: fs.statSync(planPath).mtimeMs, + chapter: typeof root.chapter === 'number' || typeof root.chapter === 'string' + ? root.chapter + : '?', + map: typeof root.map === 'number' || typeof root.map === 'string' + ? root.map + : '?', + times: Number.isFinite(times) && times > 0 ? times : 1, + gap: Number.isFinite(gap) && gap >= 0 ? gap : 0, + fleetId: Number.isFinite(fleetId) && fleetId > 0 ? fleetId : 1, + repairMode: repairModeList.length > 0 + ? repairModeList + : Number.isFinite(repairModeValue) + ? repairModeValue + : 1, + result, + lootCountGe: Number.isFinite(lootCountGe) && lootCountGe > 0 + ? lootCountGe + : -1, + shipCountGe: Number.isFinite(shipCountGe) && shipCountGe > 0 + ? shipCountGe + : -1, + fleetCount: fleets.length, + nodeCount: selectedNodes.length, + fleets, + }); + if (presets.length === 0) { + bindings.push({ + planFile: file, + planName, + source, + teamName: null, + }); + return; + } + presets.forEach((preset) => { + const teamName = isPlainObject(preset) && typeof preset.name === 'string' + ? preset.name.trim() || null + : null; + bindings.push({ + planFile: file, + planName, + source, + teamName, + }); + }); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + errors.push({ + file, + source, + kind: 'battle', + message, + }); + } + }); + }); + const teamPlans = listedTeams.plans.map(plan => ({ + file: plan.file ?? '', + name: plan.name, + source: plan.source ?? 'user', + })); + return { + bindings, + battlePlans, + teamPlans, + errors, + ignoredUnlinkedPlans: getIgnoredUnlinkedPlans(), + }; +} + +/** 读取清单,为配置页提供当前资料库状态。 */ +function getShipLibraryStatus(): ShipLibraryStatus { + const directory = shipLibraryDir(); + const manifestPath = path.join(directory, 'manifest.json'); + if (!fs.existsSync(manifestPath)) { + return { + exists: false, + path: directory, + shipCount: 0, + assetCount: 0, + missingAssets: 0, + }; + } + try { + const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as { + generated_at?: unknown; + counts?: Record; + }; + const counts = manifest.counts ?? {}; + return { + exists: true, + path: directory, + generatedAt: typeof manifest.generated_at === 'string' ? manifest.generated_at : undefined, + shipCount: typeof counts.ships === 'number' ? counts.ships : 0, + assetCount: typeof counts.assets === 'number' ? counts.assets : 0, + missingAssets: typeof counts.missing_assets === 'number' ? counts.missing_assets : 0, + }; + } catch (error) { + return { + exists: false, + path: directory, + shipCount: 0, + assetCount: 0, + missingAssets: 0, + error: `资料库清单读取失败: ${error instanceof Error ? error.message : String(error)}`, + }; + } +} + +function shipAssetUrl(relativePath: unknown): string { + if (typeof relativePath !== 'string' || !relativePath) return ''; + const root = path.resolve(shipLibraryDir()); + const absolutePath = path.resolve(root, relativePath); + if (absolutePath !== root && !absolutePath.startsWith(`${root}${path.sep}`)) return ''; + return pathToFileURL(absolutePath).href; +} + +/** 只向渲染进程提供舰队规划需要的清单字段和本地资源 URL。 */ +function getShipLibraryManifest(): ShipLibraryManifest { + const manifestPath = path.join(shipLibraryDir(), 'manifest.json'); + if (!fs.existsSync(manifestPath)) { + throw new Error('舰船资料库尚未建立,请先在配置页更新舰船数据库'); + } + const raw = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as { + schema_version?: unknown; + generated_at?: unknown; + labels?: unknown; + type_groups?: unknown; + ships?: unknown; + }; + if (!Array.isArray(raw.ships)) { + throw new Error('舰船资料库清单格式无效'); + } + return { + schemaVersion: typeof raw.schema_version === 'number' ? raw.schema_version : 0, + generatedAt: typeof raw.generated_at === 'string' ? raw.generated_at : '', + labels: raw.labels && typeof raw.labels === 'object' + ? raw.labels as Record + : {}, + typeGroups: raw.type_groups && typeof raw.type_groups === 'object' + ? raw.type_groups as Record + : {}, + ships: raw.ships.map((entry) => { + const ship = entry && typeof entry === 'object' + ? entry as Record + : {}; + return { + ...ship, + portraitUrl: shipAssetUrl(ship.portrait), + backgroundUrl: shipAssetUrl(ship.background), + frameUrl: shipAssetUrl(ship.frame), + typeIconUrl: shipAssetUrl(ship.type_icon), + }; + }), + }; +} + +function shipLibraryUpdaterPath(): string { + const root = isPackaged() ? resourceRoot() : appRoot(); + return path.join(root, 'tools', 'ship_library', 'update_ship_library.py'); +} + +function sendShipLibraryProgress(message: string): void { + mainWindow?.webContents.send('ship-library-update-progress', { message }); +} + +/** 使用当前 GUI Python 环境执行增量更新,并解析脚本的机器可读结果。 */ +async function runShipLibraryUpdate(): Promise { + const pythonCmd = await findPython(); + if (!pythonCmd) { + return { success: false, error: '找不到可用的 Python 3.12 或 3.13' }; + } + const updaterPath = shipLibraryUpdaterPath(); + if (!fs.existsSync(updaterPath)) { + return { success: false, error: `找不到舰船资料库更新程序: ${updaterPath}` }; + } + + return new Promise((resolve) => { + const child = spawn( + pythonCmd, + [ + updaterPath, + '--output', + shipLibraryDir(), + '--workers', + '8', + '--force-assets', + ], + { cwd: appRoot(), windowsHide: true }, + ); + let stdoutBuffer = ''; + let stderr = ''; + let result: ShipLibraryUpdateResult | null = null; + + const handleLine = (rawLine: string): void => { + const line = rawLine.trim(); + if (!line) return; + if (line.startsWith('PROGRESS sources')) { + sendShipLibraryProgress('正在获取舰R百科数据…'); + } else { + const records = line.match(/^PROGRESS records parsed=(\d+)$/); + const assets = line.match( + /^PROGRESS assets (\d+)\/(\d+) downloaded=(\d+) failed=(\d+)$/, + ); + if (records) { + sendShipLibraryProgress(`已读取 ${records[1]} 艘舰船,正在检查本地资源…`); + } else if (assets) { + sendShipLibraryProgress( + `正在检查资源 ${assets[1]}/${assets[2]},已下载 ${assets[3]},失败 ${assets[4]}`, + ); + } + } + if (line.startsWith('RESULT_JSON=')) { + try { + result = JSON.parse(line.slice('RESULT_JSON='.length)) as ShipLibraryUpdateResult; + } catch { + result = { success: false, error: '更新程序返回了无效结果' }; + } + } + }; + + child.stdout.setEncoding('utf-8'); + child.stdout.on('data', (chunk: string) => { + stdoutBuffer += chunk; + const lines = stdoutBuffer.split(/\r?\n/); + stdoutBuffer = lines.pop() ?? ''; + lines.forEach(handleLine); + }); + child.stderr.setEncoding('utf-8'); + child.stderr.on('data', (chunk: string) => { + stderr += chunk; + }); + child.once('error', (error) => { + resolve({ success: false, error: `更新程序启动失败: ${error.message}` }); + }); + child.once('close', (code) => { + if (stdoutBuffer) handleLine(stdoutBuffer); + resolve(result ?? { + success: false, + error: stderr.trim() || `更新程序异常退出(代码 ${code ?? 'unknown'})`, + }); + }); + }); +} + function createWindow(): BrowserWindow { + const preferences = getWindowPreferences(); + const rememberedBounds = preferences.rememberBounds + ? readRememberedWindowBounds() + : null; + const initialBounds = rememberedBounds && isWindowBoundsVisible(rememberedBounds) + ? rememberedBounds + : null; const win = new BrowserWindow({ - width: 1280, - height: 720, - minWidth: 960, - minHeight: 540, + width: initialBounds?.width ?? preferences.defaultWidth, + height: initialBounds?.height ?? preferences.defaultHeight, + x: initialBounds?.x, + y: initialBounds?.y, + center: initialBounds === null, + minWidth: MIN_WINDOW_WIDTH, + minHeight: MIN_WINDOW_HEIGHT, webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, @@ -242,7 +1950,7 @@ function createWindow(): BrowserWindow { responseHeaders: { ...details.responseHeaders, 'Content-Security-Policy': [ - `default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; connect-src 'self' http://localhost:${BACKEND_PORT} ws://localhost:${BACKEND_PORT}` + `default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; img-src 'self' file: data:; connect-src 'self' http://localhost:${BACKEND_PORT} ws://localhost:${BACKEND_PORT}` ], }, }); @@ -264,6 +1972,13 @@ function createWindow(): BrowserWindow { }); mainWindow = win; + captureWindowBounds(win); + win.on('move', () => captureWindowBounds(win)); + win.on('resize', () => captureWindowBounds(win)); + win.on('close', () => { + captureWindowBounds(win); + persistWindowBounds(); + }); win.on('closed', () => { mainWindow = null; }); return win; } @@ -333,24 +2048,21 @@ ipcMain.handle('detect-emulator', async () => { }); ipcMain.handle('check-adb-devices', async () => { - const adbDir = path.join(appRoot(), 'adb'); - const adbExe = path.join(adbDir, 'adb.exe'); - const adbCmd = fs.existsSync(adbExe) ? adbExe : 'adb'; try { - const { stdout } = await execAsync(`"${adbCmd}" devices`, { windowsHide: true, timeout: 5000 }); - const lines = stdout.split('\n').slice(1); // skip header - return lines - .map(l => l.trim()) - .filter(l => l.length > 0) - .map(l => { - const [serial, status] = l.split(/\s+/); - return { serial, status: status || 'unknown' }; - }); + return await listAdbDevices(); } catch { return []; } }); +ipcMain.handle('connect-adb-device', async (_event, serial: string) => { + return runAdbDeviceCommand('connect', serial); +}); + +ipcMain.handle('disconnect-adb-device', async (_event, serial: string) => { + return runAdbDeviceCommand('disconnect', serial); +}); + ipcMain.on('get-app-version-sync', (event) => { event.returnValue = app.getVersion(); }); @@ -379,6 +2091,73 @@ ipcMain.on('get-save-backend-screenshots-sync', (event) => { event.returnValue = getSaveBackendScreenshots(); }); +ipcMain.on('get-window-preferences-sync', (event) => { + event.returnValue = getWindowPreferences(); +}); + +ipcMain.handle('set-window-preferences', (_event, preferences: Partial) => { + const current = getWindowPreferences(); + writeGuiSettings({ + default_window_width: normalizeWindowSize( + preferences?.defaultWidth, + MIN_WINDOW_WIDTH, + current.defaultWidth, + ), + default_window_height: normalizeWindowSize( + preferences?.defaultHeight, + MIN_WINDOW_HEIGHT, + current.defaultHeight, + ), + remember_window_bounds: preferences?.rememberBounds === true, + }); + return getWindowPreferences(); +}); + +ipcMain.handle('get-gui-automation-settings', () => { + return getGuiAutomationSettings(); +}); + +ipcMain.handle( + 'set-gui-automation-settings', + (_event, settings: GuiAutomationSettings) => { + const normalized: GuiAutomationSettings = { + expeditionInterval: Math.max( + 1, + Math.min(120, Math.trunc(Number(settings?.expeditionInterval) || 15)), + ), + battleTimes: Math.max(1, Math.trunc(Number(settings?.battleTimes) || 3)), + autoLoot: settings?.autoLoot === true, + lootPlanIndex: Math.max(0, Math.trunc(Number(settings?.lootPlanIndex) || 0)), + lootStopCount: Math.max( + 1, + Math.min(50, Math.trunc(Number(settings?.lootStopCount) || 50)), + ), + }; + writeGuiSettings({ automation: normalized }); + return normalized; + }, +); + +ipcMain.handle('get-decisive-plan-settings', () => { + return getDecisivePlanSettings(); +}); + +ipcMain.handle( + 'set-decisive-plan-settings', + (_event, settings: DecisivePlanSettings) => { + const normalized = normalizeDecisivePlanSettings(settings); + writeGuiSettings({ + decisive_plan: { + chapter: normalized.chapter, + use_quick_repair: normalized.useQuickRepair, + level1: normalized.level1, + level2: normalized.level2, + }, + }); + return normalized; + }, +); + ipcMain.handle('set-backend-port', (_event, port: number) => { // 防御性校验:仅在端口为有限数值且位于合法范围时才写入设置 if (typeof port !== 'number' || !Number.isFinite(port)) { @@ -412,8 +2191,8 @@ ipcMain.handle('set-cuda-path', (_event, cudaPath: string | null) => { writeGuiSettings({ cuda_path: normalized }); }); -ipcMain.handle('validate-cuda-path', (_event, cudaPath: string) => { - return validateCudaPath(cudaPath); +ipcMain.handle('validate-cuda-path', async (_event, cudaPath: string) => { + return detectCudaEnvironment(cudaPath); }); ipcMain.handle('set-save-backend-screenshots', (_event, enabled: boolean) => { @@ -462,11 +2241,11 @@ ipcMain.handle('resolve-app-path', (_event, filePath: string) => { }); ipcMain.handle('get-plans-dir', () => { - return resolveAppPath('plans'); + return userBattlePlansDir(); }); ipcMain.handle('list-plan-files', () => { - const dir = resolveAppPath('plans'); + const dir = userBattlePlansDir(); if (!fs.existsSync(dir)) return []; return fs.readdirSync(dir) .filter(f => /\.ya?ml$/i.test(f)) @@ -487,6 +2266,530 @@ ipcMain.handle('check-environment', async () => { return await checkEnvironment(); }); +ipcMain.handle('get-ship-library-status', () => { + return getShipLibraryStatus(); +}); + +ipcMain.handle('get-ship-library-manifest', () => { + return getShipLibraryManifest(); +}); + +ipcMain.handle('save-user-team-plan', ( + _event, + rawPlan: unknown, + overwrite: boolean, + currentFile?: string, + rawSource?: PlanPresetSource, +) => { + try { + const plan = normalizeUserTeamPlan(rawPlan); + const source: PlanPresetSource = rawSource === 'system' ? 'system' : 'user'; + const directory = source === 'system' + ? systemTeamPlansDir() + : userTeamPlansDir(); + const file = teamFileName(plan.name); + const filePath = path.join(directory, file); + let currentPath: string | null = null; + if (currentFile !== undefined) { + if ( + typeof currentFile !== 'string' + || path.basename(currentFile) !== currentFile + || !TEAM_FILE_PATTERN.test(currentFile) + ) { + throw new Error('当前编队文件名不符合规则'); + } + currentPath = path.join(directory, currentFile); + } + const updatesCurrentFile = currentPath !== null + && path.resolve(currentPath).toLowerCase() + === path.resolve(filePath).toLowerCase(); + if ( + fs.existsSync(filePath) + && !updatesCurrentFile + && overwrite !== true + ) { + return { + success: false, + exists: true, + file, + error: '存在同名配置', + }; + } + const content = serializeUserTeamPlan(plan); + atomicWrite(filePath, content); + if ( + currentPath + && !updatesCurrentFile + && fs.existsSync(currentPath) + ) { + fs.unlinkSync(currentPath); + } + return { success: true, file, plan: { ...plan, file, source } }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error), + }; + } +}); + +ipcMain.handle('pick-user-team-plan', async () => { + const directory = userTeamPlansDir(); + const result = await dialog.showOpenDialog({ + title: '加载编队预设', + defaultPath: directory, + properties: ['openFile'], + filters: [{ name: '编队 YAML', extensions: ['yaml', 'yml'] }], + }); + if (result.canceled || result.filePaths.length === 0) { + return { success: false, canceled: true }; + } + + const filePath = path.resolve(result.filePaths[0]); + const file = path.basename(filePath); + if ( + path.dirname(filePath).toLowerCase() !== path.resolve(directory).toLowerCase() + || !TEAM_FILE_PATTERN.test(file) + ) { + return { success: false, error: '当前yaml格式不符合规则' }; + } + try { + const plan = readUserTeamPlan(filePath); + return { + success: true, + file, + plan: { ...plan, file, source: 'user' }, + }; + } catch { + return { success: false, error: '当前yaml格式不符合规则' }; + } +}); + +ipcMain.handle('list-team-plans', () => { + return listTeamPlans(); +}); + +ipcMain.handle('get-plan-management', () => { + return getPlanManagement(); +}); + +ipcMain.handle( + 'set-plan-unlinked-ignored', + ( + _event, + kind: 'battle' | 'team', + source: PlanPresetSource, + file: string, + ignored: boolean, + ) => { + const key = ignoredUnlinkedPlanKey(kind, source, file); + if (!key) return getIgnoredUnlinkedPlans(); + const values = new Set(getIgnoredUnlinkedPlans()); + if (ignored === true) values.add(key); + else values.delete(key); + return writeIgnoredUnlinkedPlans(values); + }, +); + +ipcMain.handle( + 'read-managed-combat-plan', + (_event, source: PlanPresetSource, file: string) => { + try { + const prepared = prepareManagedCombatPlan(source, file); + return { + success: true, + path: prepared.sourcePath, + sourcePath: prepared.sourcePath, + runtimePath: prepared.runtimePath, + content: prepared.content, + source, + }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error), + }; + } + }, +); + +ipcMain.handle( + 'read-combat-plan-file', + (_event, rawPath: string) => { + try { + if (typeof rawPath !== 'string' || !rawPath.trim()) { + throw new Error('出征计划路径不能为空'); + } + const resolved = resolveAppPath(rawPath); + const managed = managedBattlePlanFromPath(resolved); + if (managed) { + const prepared = prepareManagedCombatPlan( + managed.source, + managed.file, + ); + return { + success: true, + path: prepared.runtimePath, + sourcePath: prepared.sourcePath, + runtimePath: prepared.runtimePath, + content: prepared.content, + source: managed.source, + }; + } + if (!fs.existsSync(resolved)) { + throw new Error('出征计划不存在'); + } + return { + success: true, + path: resolved, + sourcePath: resolved, + content: fs.readFileSync(resolved, 'utf-8'), + }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error), + }; + } + }, +); + +ipcMain.handle( + 'prepare-combat-plan-execution', + (_event, content: string, hint: string) => { + try { + if (typeof content !== 'string') { + throw new Error('出征计划内容不合法'); + } + return { + success: true, + path: writeRuntimeCombatPlan( + content, + typeof hint === 'string' ? hint : 'plan', + ), + }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error), + }; + } + }, +); + +ipcMain.handle( + 'convert-legacy-combat-plan', + async ( + _event, + overwrite: boolean, + existingInputPath?: string, + ): Promise => { + let inputPath = existingInputPath; + if (!inputPath) { + const result = await dialog.showOpenDialog({ + title: '选择要转换的旧出征计划', + properties: ['openFile'], + filters: [{ + name: '出征计划 YAML', + extensions: ['yaml', 'yml'], + }], + }); + if (result.canceled || result.filePaths.length === 0) { + return { success: false, canceled: true }; + } + [inputPath] = result.filePaths; + } + + try { + const resolvedInput = path.resolve(inputPath); + if (!/\.ya?ml$/i.test(resolvedInput) || !fs.existsSync(resolvedInput)) { + throw new Error('旧出征计划文件不存在或格式不正确'); + } + const originalContent = fs.readFileSync(resolvedInput, 'utf-8'); + const parsed = yaml.load(originalContent); + if (!isPlainObject(parsed)) { + throw new Error('旧出征计划根节点必须是对象'); + } + const split = normalizeCombatPlanFleetPresets( + parsed, + 'user', + true, + ); + if (split.teams.length === 0) { + throw new Error('旧出征计划必须包含至少一支内嵌舰队'); + } + + const name = safePlanBaseName(path.basename(resolvedInput)); + if (!name) throw new Error('旧出征计划文件名不合法'); + const file = `bettle-${name}.yaml`; + const target = safeUserPlanPath(file); + if (!target) throw new Error('转换后的出征计划名称不合法'); + + const teamWrites = buildTeamPlanWrites( + split.teams, + userTeamPlansDir(), + ); + const conflicts = [ + ...(fs.existsSync(target) ? [`地图:${file}`] : []), + ...teamWrites + .filter(item => fs.existsSync(item.path)) + .map(item => `舰队:${item.name}`), + ]; + if (conflicts.length > 0 && overwrite !== true) { + return { + success: false, + exists: true, + inputPath: resolvedInput, + file, + source: 'user', + teamFiles: teamWrites.map(item => item.file), + conflicts, + error: '用户配置中存在同名文件', + }; + } + + initUserBattlePlansDir(); + initUserTeamPlansDir(); + for (const item of teamWrites) { + atomicWrite(item.path, item.content); + } + atomicWrite( + target, + serializeCombatPlan(split.mapRoot, originalContent), + ); + return { + success: true, + inputPath: resolvedInput, + file, + path: target, + source: 'user', + teamFiles: teamWrites.map(item => item.file), + }; + } catch (error) { + return { + success: false, + inputPath, + error: error instanceof Error ? error.message : String(error), + }; + } + }, +); + +ipcMain.handle( + 'save-managed-combat-plan', + ( + _event, + rawName: string, + content: string, + overwrite: boolean, + currentFile?: string, + rawSource?: PlanPresetSource, + ) => { + try { + const name = typeof rawName === 'string' + ? safePlanBaseName(rawName) + : ''; + if (!name) throw new Error('请先填写预设名称'); + if (typeof content !== 'string') { + throw new Error('出征计划内容不合法'); + } + const parsed = yaml.load(content); + if (!isPlainObject(parsed)) { + throw new Error('出征计划根节点必须是对象'); + } + + const source: PlanPresetSource = rawSource === 'system' + ? 'system' + : 'user'; + const split = normalizeCombatPlanFleetPresets( + parsed, + source, + false, + ); + const file = `bettle-${name}.yaml`; + const target = safeManagedBattlePlanPath(source, file); + if (!target) throw new Error('出征计划名称不合法'); + fs.mkdirSync(path.dirname(target), { recursive: true }); + + let currentPath: string | null = null; + if (currentFile !== undefined) { + currentPath = safeManagedBattlePlanPath(source, currentFile); + if (!currentPath) { + throw new Error('当前出征计划文件名不符合规则'); + } + } + const updatesCurrentFile = currentPath !== null + && path.resolve(currentPath).toLowerCase() + === path.resolve(target).toLowerCase(); + const mapConflict = ( + fs.existsSync(target) + && !updatesCurrentFile + ); + const teamDirectory = source === 'system' + ? systemTeamPlansDir() + : userTeamPlansDir(); + const teamWrites = buildTeamPlanWrites( + split.teams, + teamDirectory, + ).map((item, index) => ({ + ...item, + unchanged: userTeamPlanMatches( + item.path, + split.teams[index], + ), + })); + const conflicts = [ + ...(mapConflict ? [`地图:${file}`] : []), + ...teamWrites + .filter(item => fs.existsSync(item.path) && !item.unchanged) + .map(item => `舰队:${item.name}`), + ]; + if (conflicts.length > 0 && overwrite !== true) { + return { + success: false, + exists: true, + file, + source, + conflicts, + error: '存在同名配置', + }; + } + + fs.mkdirSync(teamDirectory, { recursive: true }); + for (const item of teamWrites) { + if (!item.unchanged) { + atomicWrite(item.path, item.content); + } + } + atomicWrite( + target, + serializeCombatPlan(split.mapRoot, content), + ); + if ( + currentPath + && !updatesCurrentFile + && fs.existsSync(currentPath) + ) { + fs.unlinkSync(currentPath); + } + + if (currentFile && currentFile !== file) { + const oldKey = ignoredUnlinkedPlanKey( + 'battle', + source, + currentFile, + ); + const newKey = ignoredUnlinkedPlanKey('battle', source, file); + const ignored = new Set(getIgnoredUnlinkedPlans()); + if (oldKey && newKey && ignored.delete(oldKey)) { + ignored.add(newKey); + writeIgnoredUnlinkedPlans(ignored); + } + } + return { + success: true, + file, + path: target, + source, + teamFiles: teamWrites.map(item => item.file), + }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error), + }; + } + }, +); + +ipcMain.handle( + 'rename-user-combat-plan', + (_event, file: string, newName: string) => { + const source = safeUserPlanPath(file); + const safeName = safePlanBaseName(newName); + if (!source || !fs.existsSync(source) || !safeName) { + return { success: false, error: '出征计划名称或文件不合法' }; + } + const targetFile = `bettle-${safeName}.yaml`; + const target = safeUserPlanPath(targetFile); + if (!target) return { success: false, error: '出征计划名称不合法' }; + if (source.toLowerCase() !== target.toLowerCase() && fs.existsSync(target)) { + return { success: false, error: '同名出征计划已存在' }; + } + try { + fs.renameSync(source, target); + const oldKey = ignoredUnlinkedPlanKey('battle', 'user', file); + const newKey = ignoredUnlinkedPlanKey('battle', 'user', targetFile); + const ignored = new Set(getIgnoredUnlinkedPlans()); + if (oldKey && newKey && ignored.delete(oldKey)) { + ignored.add(newKey); + writeIgnoredUnlinkedPlans(ignored); + } + return { success: true, file: targetFile }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error), + }; + } + }, +); + +ipcMain.handle('delete-user-combat-plan', (_event, file: string) => { + const target = safeUserPlanPath(file); + if (!target || !fs.existsSync(target)) { + return { success: false, error: '用户出征计划不存在' }; + } + try { + fs.unlinkSync(target); + const key = ignoredUnlinkedPlanKey('battle', 'user', file); + if (key) { + const ignored = new Set(getIgnoredUnlinkedPlans()); + if (ignored.delete(key)) writeIgnoredUnlinkedPlans(ignored); + } + return { success: true }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error), + }; + } +}); + +ipcMain.handle('delete-user-team-plan', (_event, file: string) => { + const target = safeUserTeamPlanPath(file); + if (!target || !fs.existsSync(target)) { + return { success: false, error: '用户舰队方案不存在' }; + } + try { + fs.unlinkSync(target); + const key = ignoredUnlinkedPlanKey('team', 'user', file); + if (key) { + const ignored = new Set(getIgnoredUnlinkedPlans()); + if (ignored.delete(key)) writeIgnoredUnlinkedPlans(ignored); + } + return { success: true }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error), + }; + } +}); + +let shipLibraryUpdateRunning = false; +ipcMain.handle('update-ship-library', async () => { + if (shipLibraryUpdateRunning) { + return { success: false, error: '舰船资料库正在更新,请稍候' }; + } + shipLibraryUpdateRunning = true; + try { + return await runShipLibraryUpdate(); + } finally { + shipLibraryUpdateRunning = false; + } +}); + /* * 测试期接口(后端源码更新)已停用,逻辑保留便于回滚恢复。 ipcMain.handle('check-updates', async () => { @@ -603,6 +2906,8 @@ app.whenReady().then(() => { sendProgress, getConfiguredPythonPath, getUpdateMode, + getBackendStartupMode, + getBackendRepoPath, getTempDir: () => app.getPath('temp'), }); initBackend({ @@ -611,7 +2916,10 @@ app.whenReady().then(() => { BACKEND_PORT, getMainWindow: () => mainWindow, }); - initUserPlansDir(); + initUserBattlePlansDir(); + initUserShipLibraryDir(); + initUserTeamPlansDir(); + initSystemPlanDirs(); initAutoUpdater(); createWindow(); @@ -623,6 +2931,8 @@ app.whenReady().then(() => { }); app.on('before-quit', () => { + captureWindowBounds(mainWindow); + persistWindowBounds(); stopBackend(); }); diff --git a/electron/preload.ts b/electron/preload.ts index b75d86c..aea0a22 100644 --- a/electron/preload.ts +++ b/electron/preload.ts @@ -32,6 +32,49 @@ contextBridge.exposeInMainWorld('electronBridge', { return ipcRenderer.sendSync('get-save-backend-screenshots-sync') as boolean; }, + getWindowPreferences: () => { + return ipcRenderer.sendSync('get-window-preferences-sync') as { + defaultWidth: number; + defaultHeight: number; + rememberBounds: boolean; + }; + }, + + setWindowPreferences: (preferences: { + defaultWidth: number; + defaultHeight: number; + rememberBounds: boolean; + }) => { + return ipcRenderer.invoke('set-window-preferences', preferences); + }, + + getGuiAutomationSettings: () => { + return ipcRenderer.invoke('get-gui-automation-settings'); + }, + + setGuiAutomationSettings: (settings: { + expeditionInterval: number; + battleTimes: number; + autoLoot: boolean; + lootPlanIndex: number; + lootStopCount: number; + }) => { + return ipcRenderer.invoke('set-gui-automation-settings', settings); + }, + + getDecisivePlanSettings: () => { + return ipcRenderer.invoke('get-decisive-plan-settings'); + }, + + setDecisivePlanSettings: (settings: { + chapter: number; + useQuickRepair: boolean; + level1: string[]; + level2: string[]; + }) => { + return ipcRenderer.invoke('set-decisive-plan-settings', settings); + }, + setBackendPort: (port: number) => { return ipcRenderer.invoke('set-backend-port', port); }, @@ -68,6 +111,126 @@ contextBridge.exposeInMainWorld('electronBridge', { return ipcRenderer.invoke('set-update-mode', mode); }, + getShipLibraryStatus: () => { + return ipcRenderer.invoke('get-ship-library-status'); + }, + + getShipLibraryManifest: () => { + return ipcRenderer.invoke('get-ship-library-manifest'); + }, + + updateShipLibrary: () => { + return ipcRenderer.invoke('update-ship-library'); + }, + + onShipLibraryUpdateProgress: (callback: (progress: { message: string }) => void) => { + ipcRenderer.on('ship-library-update-progress', (_event, progress) => callback(progress)); + }, + + saveUserTeamPlan: ( + plan: unknown, + overwrite = false, + currentFile?: string, + source: 'system' | 'user' = 'user', + ) => { + return ipcRenderer.invoke( + 'save-user-team-plan', + plan, + overwrite, + currentFile, + source, + ); + }, + + pickUserTeamPlan: () => { + return ipcRenderer.invoke('pick-user-team-plan'); + }, + + listTeamPlans: () => { + return ipcRenderer.invoke('list-team-plans'); + }, + + getPlanManagement: () => { + return ipcRenderer.invoke('get-plan-management'); + }, + + setPlanUnlinkedIgnored: ( + kind: 'battle' | 'team', + source: 'system' | 'user', + file: string, + ignored: boolean, + ) => { + return ipcRenderer.invoke( + 'set-plan-unlinked-ignored', + kind, + source, + file, + ignored, + ); + }, + + readManagedCombatPlan: ( + source: 'system' | 'user', + file: string, + ) => { + return ipcRenderer.invoke('read-managed-combat-plan', source, file); + }, + + readCombatPlanFile: (filePath: string) => { + return ipcRenderer.invoke('read-combat-plan-file', filePath); + }, + + prepareCombatPlanExecution: ( + content: string, + hint: string, + ) => { + return ipcRenderer.invoke( + 'prepare-combat-plan-execution', + content, + hint, + ); + }, + + convertLegacyCombatPlan: ( + overwrite = false, + inputPath?: string, + ) => { + return ipcRenderer.invoke( + 'convert-legacy-combat-plan', + overwrite, + inputPath, + ); + }, + + saveManagedCombatPlan: ( + name: string, + content: string, + overwrite = false, + currentFile?: string, + source: 'system' | 'user' = 'user', + ) => { + return ipcRenderer.invoke( + 'save-managed-combat-plan', + name, + content, + overwrite, + currentFile, + source, + ); + }, + + renameUserCombatPlan: (file: string, newName: string) => { + return ipcRenderer.invoke('rename-user-combat-plan', file, newName); + }, + + deleteUserCombatPlan: (file: string) => { + return ipcRenderer.invoke('delete-user-combat-plan', file); + }, + + deleteUserTeamPlan: (file: string) => { + return ipcRenderer.invoke('delete-user-team-plan', file); + }, + openDirectoryDialog: (title?: string) => { return ipcRenderer.invoke('open-directory-dialog', title); }, @@ -100,6 +263,14 @@ contextBridge.exposeInMainWorld('electronBridge', { return ipcRenderer.invoke('check-adb-devices'); }, + connectAdbDevice: (serial: string) => { + return ipcRenderer.invoke('connect-adb-device', serial); + }, + + disconnectAdbDevice: (serial: string) => { + return ipcRenderer.invoke('disconnect-adb-device', serial); + }, + getAppRoot: () => { return ipcRenderer.invoke('get-app-root'); }, diff --git a/electron/pythonEnv/context.ts b/electron/pythonEnv/context.ts index d287ec6..f89251d 100644 --- a/electron/pythonEnv/context.ts +++ b/electron/pythonEnv/context.ts @@ -8,6 +8,8 @@ export interface PythonEnvContext { sendProgress: (msg: string) => void; getConfiguredPythonPath: () => string | null; getUpdateMode: () => 'auto' | 'manual'; + getBackendStartupMode: () => 'managed' | 'external'; + getBackendRepoPath: () => string; getTempDir: () => string; } diff --git a/electron/pythonEnv/envCheck.ts b/electron/pythonEnv/envCheck.ts index f9b1b6e..3f249fe 100644 --- a/electron/pythonEnv/envCheck.ts +++ b/electron/pythonEnv/envCheck.ts @@ -8,7 +8,15 @@ import { exec } from 'child_process'; import { promisify } from 'util'; import { getCtx, setCachedPythonCmd } from './context'; import { findPython } from './finder'; -import { type EnvCheckResult, ensurePthFile, localSitePackages, pipEnv, ensurePip, ensureSslCertForPython } from './utils'; +import { + type EnvCheckResult, + ensurePthFile, + localSitePackages, + pipEnv, + ensurePip, + ensureSslCertForPython, + isLocalPython, +} from './utils'; import { autoUpdateAutowsgr, type AutoUpdateDeps } from './updater'; const execAsync = promisify(exec); @@ -21,8 +29,15 @@ const execAsync = promisify(exec); async function ensureVCRedist(): Promise { const ctx = getCtx(); // vcruntime140.dll 存在于 system32 说明已安装 - const dllPath = path.join(process.env.SYSTEMROOT || 'C:\\Windows', 'System32', 'vcruntime140.dll'); - if (fs.existsSync(dllPath)) return; + const systemRoot = process.env.SystemRoot + || process.env.SYSTEMROOT + || process.env.WINDIR; + if ( + systemRoot + && fs.existsSync(path.join(systemRoot, 'System32', 'vcruntime140.dll')) + ) { + return; + } ctx.sendProgress('Microsoft Visual C++ Redistributable is not installed, this may lead to the DLL load failure.'); const redistExe = path.join(ctx.appRoot(), 'redist', 'vc_redist.x64.exe'); @@ -88,9 +103,39 @@ function buildAutoUpdateDeps(): AutoUpdateDeps { }; } +/** 返回调试模式下有效的本地后端仓库根目录。 */ +export function externalBackendRoot(): string | null { + const ctx = getCtx(); + if (ctx.getBackendStartupMode() !== 'external') return null; + + const configured = process.env.AUTOWSGR_BACKEND_REPO?.trim() + || ctx.getBackendRepoPath().trim(); + if (!configured) return null; + + let root = path.resolve(configured); + if ( + path.basename(root).toLowerCase() === 'autowsgr' + && fs.existsSync(path.join(root, '__init__.py')) + && fs.existsSync(path.join(root, 'server', 'main.py')) + ) { + root = path.dirname(root); + } + + return fs.existsSync(path.join(root, 'autowsgr', 'server', 'main.py')) + ? root + : null; +} + function shouldAutoUpdate(): boolean { const ctx = getCtx(); - return ctx.getUpdateMode() !== 'manual'; + return externalBackendRoot() === null + && ctx.getUpdateMode() !== 'manual'; +} + +function autoUpdateSkipMessage(): string { + return externalBackendRoot() + ? '本地后端调试模式:跳过 autowsgr 自动更新检查' + : '手动更新模式:跳过 autowsgr 自动更新检查'; } type CoreDepProbeResult = { @@ -106,13 +151,28 @@ type CoreDepProbeResult = { */ async function probeCoreDependencies(pythonCmd: string): Promise { const ctx = getCtx(); - const spFwd = localSitePackages().replace(/\\/g, '/'); + const backendRoot = externalBackendRoot(); + const expectedRoot = backendRoot || localSitePackages(); + const useLocalSite = !backendRoot || isLocalPython(pythonCmd); + const pythonPath = (value: string): string => value + .replace(/\\/g, '/') + .replace(/'/g, "\\'"); const checkScript = path.join(ctx.getTempDir(), 'autowsgr_depcheck.py'); - fs.writeFileSync(checkScript, [ + const scriptLines = [ 'import json, sys, site', - `sp = '${spFwd}'`, - 'sys.path.insert(0, sp)', - 'site.addsitedir(sp)', + ...(useLocalSite + ? [ + `sp = '${pythonPath(localSitePackages())}'`, + 'sys.path.insert(0, sp)', + 'site.addsitedir(sp)', + ] + : []), + ...(backendRoot + ? [ + `repo = '${pythonPath(backendRoot)}'`, + 'sys.path.insert(0, repo)', + ] + : []), 'r = {}', "checks = [('uvicorn', 'uvicorn'), ('fastapi', 'fastapi'), ('scipy', 'scipy._lib')]", 'for key, mod in checks:', @@ -121,11 +181,15 @@ async function probeCoreDependencies(pythonCmd: string): Promise { writeEnvMarker(marker.pythonCmd, marker.pythonVersion, finalVer); } } else { - ctx.sendProgress('手动更新模式:跳过 autowsgr 自动更新检查'); + ctx.sendProgress(autoUpdateSkipMessage()); } ctx.sendProgress(`环境就绪 (${marker.pythonVersion}, autowsgr ${finalVer}) ✓`); return { @@ -272,7 +353,7 @@ export async function checkEnvironment(): Promise { const updatedVer = await autoUpdateAutowsgr(pythonCmd, buildAutoUpdateDeps()); finalVer = updatedVer || autowsgrVersion; } else { - ctx.sendProgress('手动更新模式:跳过 autowsgr 自动更新检查'); + ctx.sendProgress(autoUpdateSkipMessage()); } writeEnvMarker(pythonCmd, pythonVersion || '', finalVer); } diff --git a/electron/pythonEnv/finder.ts b/electron/pythonEnv/finder.ts index 4265e6c..dca5860 100644 --- a/electron/pythonEnv/finder.ts +++ b/electron/pythonEnv/finder.ts @@ -43,7 +43,7 @@ export async function findPython(): Promise { // 优先使用本地便携版 Python const localPython = path.join(ctx.appRoot(), 'python', 'python.exe'); - if (fs.existsSync(localPython)) { + if (!found && fs.existsSync(localPython)) { try { const { stdout, stderr } = await execAsync(`"${localPython}" --version`, { windowsHide: true }); const verStr = stdout || stderr; @@ -52,7 +52,7 @@ export async function findPython(): Promise { } catch { /* local Python broken */ } } - if (!found && !configured) { // 仅在本地 Python 不可用且无用户配置时回退系统 Python + if (!found) { // 用户配置和本地 Python 均不可用时回退系统 Python // 回退到系统全局 Python // 注意: 必须解析出真实的 .exe 绝对路径,因为 pyenv 等工具使用 .bat shim, // 而 Node.js spawn() 不经过 shell,无法执行 .bat 文件。 diff --git a/electron/pythonEnv/index.ts b/electron/pythonEnv/index.ts index 16c53e7..2dbff73 100644 --- a/electron/pythonEnv/index.ts +++ b/electron/pythonEnv/index.ts @@ -9,7 +9,16 @@ export { type PythonEnvContext, initPythonEnv, clearPythonCache } from './contex export { isAllowedPythonVersion, findPython, findPythonSync } from './finder'; // utils -export { type EnvCheckResult, sysPathInsert, ensurePthFile, pipEnv, localSitePackages, ensurePip, ensureSslCertForPython } from './utils'; +export { + type EnvCheckResult, + sysPathInsert, + ensurePthFile, + pipEnv, + localSitePackages, + ensurePip, + ensureSslCertForPython, + isLocalPython, +} from './utils'; // envCheck export { checkEnvironment } from './envCheck'; diff --git a/electron/pythonEnv/installer.ts b/electron/pythonEnv/installer.ts index be1514c..e0d6f24 100644 --- a/electron/pythonEnv/installer.ts +++ b/electron/pythonEnv/installer.ts @@ -8,7 +8,7 @@ import { promisify } from 'util'; import { getCtx, setCachedPythonCmd } from './context'; import { findPython } from './finder'; import { ensurePthFile, localSitePackages, pipEnv, ensurePip, ensureSslCertForPython } from './utils'; -import { ENV_READY_MARKER } from './envCheck'; +import { ENV_READY_MARKER, externalBackendRoot } from './envCheck'; const execAsync = promisify(exec); @@ -172,6 +172,15 @@ export async function checkForUpdates(): Promise { /** 自动安装依赖 (pip install autowsgr),始终安装到项目目录,不动全局 */ export async function installDependencies(pythonCmd: string): Promise<{ success: boolean; output: string }> { const ctx = getCtx(); + const backendRequirement = ctx.getBackendStartupMode() === 'external' + ? externalBackendRoot() + : AUTOWSGR_REQUIREMENT; + if (!backendRequirement) { + return { + success: false, + output: '本地后端仓库无效,无法安装调试环境依赖', + }; + } // 安装后环境变化,清除标记以便下次重新检查 try { fs.unlinkSync(ENV_READY_MARKER()); } catch { /* ignore */ } @@ -231,7 +240,7 @@ export async function installDependencies(pythonCmd: string): Promise<{ success: '--upgrade', '--no-build-isolation', '--target', targetDir, - AUTOWSGR_REQUIREMENT, + backendRequirement, ]); if (install.code === 0) ctx.sendProgress('后端依赖安装完成 ✓'); else ctx.sendProgress('ERROR 依赖安装失败'); diff --git a/package-lock.json b/package-lock.json index 286f98b..2a44a84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "wsgrgui", - "version": "1.2.4", + "version": "2.0.1-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "wsgrgui", - "version": "1.2.4", + "version": "2.0.1-dev", "dependencies": { "electron-updater": "^6.8.3", "js-yaml": "^4.1.0" diff --git a/package.json b/package.json index 2f1ca6b..b0dd2d2 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,21 @@ { "name": "wsgrgui", - "version": "1.4.1", - "description": "AutoWSGR 图形界面 — MVP", + "version": "2.0.1-dev", + "description": "AutoWSGR YAML 管理与自动化桌面界面", "main": "dist/electron/main.js", "scripts": { "build:css": "sass src/view/styles/main.scss src/view/styles/styles.css --no-source-map --style=expanded", - "clean": "node -e \"fs.rmSync('dist/src',{recursive:true,force:true});fs.rmSync('dist/electron',{recursive:true,force:true});console.log('dist cleaned')\" ", + "clean": "node -e \"fs.rmSync('dist',{recursive:true,force:true});console.log('dist cleaned')\"", + "clean:release": "node -e \"fs.rmSync('release',{recursive:true,force:true});console.log('release cleaned')\"", "build": "npm run clean && npm run build:css && tsc && node scripts/bundle.js", + "test:legacy-plan": "npm run build && electron scripts/test-legacy-plan-conversion.js", + "test:settings": "npm run build && electron scripts/test-settings-persistence.js", "start": "chcp 65001 >nul && npm run build && electron .", "dev": "chcp 65001 >nul && npm run clean && npm run build:css && tsc && node scripts/bundle.js && electron .", "prepare-python": "node scripts/prepare-python.js", "prepare-adb": "node scripts/prepare-adb.js", - "pack": "npm run build && electron-builder --dir", - "dist": "npm run prepare-python && npm run prepare-adb && npm run build && electron-builder" + "pack": "npm run clean:release && npm run build && electron-builder --dir --publish never", + "dist": "npm run clean:release && npm run prepare-python && npm run prepare-adb && npm run build && electron-builder --publish never" }, "devDependencies": { "@types/js-yaml": "^4.0.9", @@ -35,8 +38,8 @@ }, "files": [ "dist/**/*", - "src/view/**/*", - "scripts/**/*", + "src/view/index.html", + "src/view/styles/styles.css", "!node_modules/.cache" ], "extraResources": [ @@ -44,14 +47,9 @@ "from": "resource", "to": "resource", "filter": [ - "**/*" - ] - }, - { - "from": "plans", - "to": "plans", - "filter": [ - "**/*" + "**/*", + "!user_battle_plans/**/*", + "!user_team_plans/**/*" ] }, { @@ -61,6 +59,13 @@ { "from": "debug_deps.bat", "to": "debug_deps.bat" + }, + { + "from": "tools/ship_library", + "to": "tools/ship_library", + "filter": [ + "update_ship_library.py" + ] } ], "extraFiles": [ diff --git "a/resource/builtin_plans/\345\206\263\346\210\230.yaml" "b/resource/builtin_plans/\345\206\263\346\210\230.yaml" deleted file mode 100644 index 299e2c2..0000000 --- "a/resource/builtin_plans/\345\206\263\346\210\230.yaml" +++ /dev/null @@ -1,19 +0,0 @@ -# 决战第 6 章 — 潜艇编队 -# 对应后端 API: POST /api/task/start { type: "decisive" } -# 需根据自己的舰船配置修改 level1 / level2 / flagship_priority - -task_type: decisive -chapter: 6 -level1: - - U-1206 - - U-96 - - U-47 - - 鹦鹉螺 - - 鲃鱼 - - 伊-25 -level2: - - M-296 - - 大青花鱼 - - U-1405 -flagship_priority: - - U-1206 diff --git "a/resource/builtin_plans/\345\221\250\345\270\27010\347\253\240-10-1.yaml" "b/resource/builtin_plans/\345\221\250\345\270\27010\347\253\240-10-1.yaml" deleted file mode 100644 index 5f3e8ed..0000000 --- "a/resource/builtin_plans/\345\221\250\345\270\27010\347\253\240-10-1.yaml" +++ /dev/null @@ -1,46 +0,0 @@ -# 周常第10章 — 地图 10-1 -# 编队: 空想(改型) + 351 + 4条改型潜艇(不限国籍模糊匹配) -# 目标等级: 全员 >= 110 -# 路线: B-D-F-G-H-L-M-O (L 迂回) - -chapter: 10 -map: 1 -selected_nodes: [B, D, F, G, H, L, M, O] -endpoint_nodes: [O] -fleet_id: 2 -fight_condition: 1 -repair_mode: 1 - -node_defaults: - formation: 2 - night: false - proceed: true - -node_args: - L: - formation: 2 - night: false - proceed: true - detour: true - M: - formation: 2 - night: false - proceed: true - long_missile_support: true - O: - formation: 4 - night: true - proceed: true - long_missile_support: true - -fleet_presets: - - name: 空想351潜艇队 - ships: - - { name: 空想·改, min_level: 110 } - - { name: 351, min_level: 110 } - - { ship_type: ss_or_ssg, min_level: 110 } - - { ship_type: ss_or_ssg, min_level: 110 } - - { ship_type: ss_or_ssg, min_level: 110 } - - { ship_type: ss_or_ssg, min_level: 110 } - -times: 3 diff --git "a/resource/builtin_plans/\345\221\250\345\270\2701\347\253\240-1-5.yaml" "b/resource/builtin_plans/\345\221\250\345\270\2701\347\253\240-1-5.yaml" deleted file mode 100644 index 269ec5e..0000000 --- "a/resource/builtin_plans/\345\221\250\345\270\2701\347\253\240-1-5.yaml" +++ /dev/null @@ -1,24 +0,0 @@ -# 周常第1章 — 地图 1-5 -# 编队: 任意3条潜艇/导潜 -# 路线: 直通 Boss (A) - -chapter: 1 -map: 5 -selected_nodes: [A] -endpoint_nodes: [A] -fleet_id: 1 -fight_condition: 1 -repair_mode: 1 - -node_defaults: - formation: 2 - night: false - proceed: true - -fleet_presets: - - name: 潜艇队 - ships: - - { ship_type: ss_or_ssg, min_level: 100 } - - { ship_type: ss_or_ssg, min_level: 100 } - - { ship_type: ss_or_ssg, min_level: 100 } -times: 3 diff --git "a/resource/builtin_plans/\345\221\250\345\270\2702\347\253\240-2-1.yaml" "b/resource/builtin_plans/\345\221\250\345\270\2702\347\253\240-2-1.yaml" deleted file mode 100644 index d29bbfa..0000000 --- "a/resource/builtin_plans/\345\221\250\345\270\2702\347\253\240-2-1.yaml" +++ /dev/null @@ -1,44 +0,0 @@ -# 周常第2章 — 地图 2-1 -# 编队方案: -# 1) SS*4 -# 2) T-23·改 + 3条德国驱逐 -# 3) 岛风·改 + 3条日本驱逐 -# 默认复纵阵 - -chapter: 2 -map: 1 -selected_nodes: [B, D, F] -endpoint_nodes: [F] -fleet_id: 1 -fight_condition: 1 -repair_mode: 1 - -node_defaults: - formation: 2 - night: false - proceed: true - -node_args: - F: - night: true - -fleet_presets: - - name: SS*4 - ships: - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - name: T-23德驱队 - ships: - - { name: T-23·改, min_level: 100 } - - { nation: 德国, ship_type: dd, min_level: 100, priority: ['吕贝克·改', 'Z17·改', 'Z16·改', 'Z46·改', 'Z31·改', 'Z1·改', 'Z22·改', 'Z21·改'] } - - { nation: 德国, ship_type: dd, min_level: 100, priority: ['吕贝克·改', 'Z17·改', 'Z16·改', 'Z46·改', 'Z31·改', 'Z1·改', 'Z22·改', 'Z21·改'] } - - { nation: 德国, ship_type: dd, min_level: 100, priority: ['吕贝克·改', 'Z17·改', 'Z16·改', 'Z46·改', 'Z31·改', 'Z1·改', 'Z22·改', 'Z21·改'] } - - name: 岛风日驱队 - ships: - - { name: 岛风(岛风型驱逐舰)·改, min_level: 100 } - - { nation: 日本, ship_type: dd, min_level: 100, priority: ['岛风(岛风型驱逐舰)·改', '黑潮·改', '阳炎·改', '早春·改'] } - - { nation: 日本, ship_type: dd, min_level: 100, priority: ['岛风(岛风型驱逐舰)·改', '黑潮·改', '阳炎·改', '早春·改'] } - - { nation: 日本, ship_type: dd, min_level: 100, priority: ['岛风(岛风型驱逐舰)·改', '黑潮·改', '阳炎·改', '早春·改'] } -times: 3 diff --git "a/resource/builtin_plans/\345\221\250\345\270\2703\347\253\240-3-1.yaml" "b/resource/builtin_plans/\345\221\250\345\270\2703\347\253\240-3-1.yaml" deleted file mode 100644 index 6c16132..0000000 --- "a/resource/builtin_plans/\345\221\250\345\270\2703\347\253\240-3-1.yaml" +++ /dev/null @@ -1,37 +0,0 @@ -# 周常第3章 — 地图 3-1 -# 编队方案: -# 1) 85工程 + T-23·改 + 2条德国驱逐 -# 2) 85工程 + 岛风·改 + 2条日本驱逐 -# 默认复纵阵 - -chapter: 3 -map: 1 -selected_nodes: [A, B, C, E, F, H, I] -endpoint_nodes: [I] -fleet_id: 1 -fight_condition: 1 -repair_mode: 1 - -node_defaults: - formation: 2 - night: false - proceed: true - -node_args: - I: - night: true - -fleet_presets: - - name: 85工程德驱队 - ships: - - { name: 85工程, min_level: 100 } - - { name: T-23·改, min_level: 100 } - - { nation: 德国, ship_type: dd, min_level: 100, priority: ['吕贝克·改', 'Z17·改', 'Z16·改', 'Z46·改', 'Z31·改', 'Z1·改', 'Z22·改', 'Z21·改'] } - - { nation: 德国, ship_type: dd, min_level: 100, priority: ['吕贝克·改', 'Z17·改', 'Z16·改', 'Z46·改', 'Z31·改', 'Z1·改', 'Z22·改', 'Z21·改'] } - - name: 85工程日驱队 - ships: - - { name: 85工程, min_level: 100 } - - { name: 岛风(岛风型驱逐舰)·改, min_level: 100 } - - { nation: 日本, ship_type: dd, min_level: 100, priority: ['岛风(岛风型驱逐舰)·改', '黑潮·改', '阳炎·改', '早春·改'] } - - { nation: 日本, ship_type: dd, min_level: 100, priority: ['岛风(岛风型驱逐舰)·改', '黑潮·改', '阳炎·改', '早春·改'] } -times: 3 diff --git "a/resource/builtin_plans/\345\221\250\345\270\2703\347\253\240-3-3.yaml" "b/resource/builtin_plans/\345\221\250\345\270\2703\347\253\240-3-3.yaml" deleted file mode 100644 index f9e0d05..0000000 --- "a/resource/builtin_plans/\345\221\250\345\270\2703\347\253\240-3-3.yaml" +++ /dev/null @@ -1,34 +0,0 @@ -# 周常第3章(备选) — 地图 3-3 -# 编队方案同 3-1 -# 默认复纵阵 - -chapter: 3 -map: 3 -endpoint_nodes: [K] -fleet_id: 1 -fight_condition: 1 -repair_mode: 1 - -node_defaults: - formation: 2 - night: false - proceed: true - -node_args: - K: - night: true - -fleet_presets: - - name: 85工程德驱队 - ships: - - { name: 85工程, min_level: 100 } - - { name: T-23·改, min_level: 100 } - - { nation: 德国, ship_type: dd, min_level: 100, priority: ['吕贝克·改', 'Z17·改', 'Z16·改', 'Z46·改', 'Z31·改', 'Z1·改', 'Z22·改', 'Z21·改'] } - - { nation: 德国, ship_type: dd, min_level: 100, priority: ['吕贝克·改', 'Z17·改', 'Z16·改', 'Z46·改', 'Z31·改', 'Z1·改', 'Z22·改', 'Z21·改'] } - - name: 85工程日驱队 - ships: - - { name: 85工程, min_level: 100 } - - { name: 岛风(岛风型驱逐舰)·改, min_level: 100 } - - { nation: 日本, ship_type: dd, min_level: 100, priority: ['岛风(岛风型驱逐舰)·改', '黑潮·改', '阳炎·改', '早春·改'] } - - { nation: 日本, ship_type: dd, min_level: 100, priority: ['岛风(岛风型驱逐舰)·改', '黑潮·改', '阳炎·改', '早春·改'] } -times: 3 diff --git "a/resource/builtin_plans/\345\221\250\345\270\2704\347\253\240-4-1.yaml" "b/resource/builtin_plans/\345\221\250\345\270\2704\347\253\240-4-1.yaml" deleted file mode 100644 index f87bd75..0000000 --- "a/resource/builtin_plans/\345\221\250\345\270\2704\347\253\240-4-1.yaml" +++ /dev/null @@ -1,35 +0,0 @@ -# 周常第4章 — 地图 4-1 -# 编队方案同第3章 -# 默认复纵阵 - -chapter: 4 -map: 1 -selected_nodes: [A, B, C, D, F, G, I] -endpoint_nodes: [I] -fleet_id: 1 -fight_condition: 1 -repair_mode: 1 - -node_defaults: - formation: 2 - night: false - proceed: true - -node_args: - I: - night: true - -fleet_presets: - - name: 85工程德驱队 - ships: - - { name: 85工程, min_level: 100 } - - { name: T-23·改, min_level: 100 } - - { nation: 德国, ship_type: dd, min_level: 100, priority: ['吕贝克·改', 'Z17·改', 'Z16·改', 'Z46·改', 'Z31·改', 'Z1·改', 'Z22·改', 'Z21·改'] } - - { nation: 德国, ship_type: dd, min_level: 100, priority: ['吕贝克·改', 'Z17·改', 'Z16·改', 'Z46·改', 'Z31·改', 'Z1·改', 'Z22·改', 'Z21·改'] } - - name: 85工程日驱队 - ships: - - { name: 85工程, min_level: 100 } - - { name: 岛风(岛风型驱逐舰)·改, min_level: 100 } - - { nation: 日本, ship_type: dd, min_level: 100, priority: ['岛风(岛风型驱逐舰)·改', '黑潮·改', '阳炎·改', '早春·改'] } - - { nation: 日本, ship_type: dd, min_level: 100, priority: ['岛风(岛风型驱逐舰)·改', '黑潮·改', '阳炎·改', '早春·改'] } -times: 3 diff --git "a/resource/builtin_plans/\345\221\250\345\270\2705\347\253\240-5-5.yaml" "b/resource/builtin_plans/\345\221\250\345\270\2705\347\253\240-5-5.yaml" deleted file mode 100644 index f40e5ef..0000000 --- "a/resource/builtin_plans/\345\221\250\345\270\2705\347\253\240-5-5.yaml" +++ /dev/null @@ -1,32 +0,0 @@ -# 周常第5章 — 地图 5-5 -# 编队: SS*6 -# 默认复纵阵 - -chapter: 5 -map: 5 -selected_nodes: [C, F, H, I] -endpoint_nodes: [I] -fleet_id: 1 -fight_condition: 1 -repair_mode: 1 - -node_defaults: - formation: 2 - night: false - proceed: true - -node_args: - I: - formation: 4 - night: true - -fleet_presets: - - name: SS*6 - ships: - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } -times: 3 \ No newline at end of file diff --git "a/resource/builtin_plans/\345\221\250\345\270\2706\347\253\240-6-3.yaml" "b/resource/builtin_plans/\345\221\250\345\270\2706\347\253\240-6-3.yaml" deleted file mode 100644 index c00e036..0000000 --- "a/resource/builtin_plans/\345\221\250\345\270\2706\347\253\240-6-3.yaml" +++ /dev/null @@ -1,31 +0,0 @@ -# 周常第6章(备选) — 地图 6-3 -# 编队: SS*6 -# 默认复纵阵 - -chapter: 6 -map: 3 -selected_nodes: [B, E, H, J] -endpoint_nodes: [J] -fleet_id: 1 -fight_condition: 1 -repair_mode: 1 - -node_defaults: - formation: 2 - night: false - proceed: true - -node_args: - J: - night: true - -fleet_presets: - - name: SS*6 - ships: - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } -times: 3 diff --git "a/resource/builtin_plans/\345\221\250\345\270\2706\347\253\240-6-4.yaml" "b/resource/builtin_plans/\345\221\250\345\270\2706\347\253\240-6-4.yaml" deleted file mode 100644 index ac9c9aa..0000000 --- "a/resource/builtin_plans/\345\221\250\345\270\2706\347\253\240-6-4.yaml" +++ /dev/null @@ -1,41 +0,0 @@ -# 周常第6章 — 地图 6-4 -# 编队方案: -# 1) 克劳塞维茨·改 + T-23·改 + 2条德国驱逐 + 赛尔弗里吉 + 85工程 -# 2) 85工程 + 斯佩伯爵海军上将·改 + 鲃鱼·改 + 岛风·改 + 2条日本驱逐 -# 默认复纵阵 - -chapter: 6 -map: 4 -selected_nodes: [A, C, F, H, J, K] -endpoint_nodes: [K] -fleet_id: 1 -fight_condition: 1 -repair_mode: 1 - -node_defaults: - formation: 2 - night: false - proceed: true - -node_args: - K: - night: true - -fleet_presets: - - name: 克劳塞维茨德系队 - ships: - - { name: 克劳塞维茨·改, min_level: 100 } - - { name: T-23·改, min_level: 100 } - - { nation: 德国, ship_type: dd, min_level: 100, priority: ['吕贝克·改', 'Z17·改', 'Z16·改', 'Z46·改', 'Z31·改', 'Z1·改', 'Z22·改', 'Z21·改'] } - - { nation: 德国, ship_type: dd, min_level: 100, priority: ['吕贝克·改', 'Z17·改', 'Z16·改', 'Z46·改', 'Z31·改', 'Z1·改', 'Z22·改', 'Z21·改'] } - - { name: 赛尔弗里吉, min_level: 100 } - - { name: 85工程, min_level: 100 } - - name: 85工程日系混编 - ships: - - { name: 85工程, min_level: 100 } - - { name: 斯佩伯爵海军上将·改, min_level: 100 } - - { name: 鲃鱼·改, min_level: 100 } - - { name: 岛风(岛风型驱逐舰)·改, min_level: 100 } - - { nation: 日本, ship_type: dd, min_level: 100, priority: ['岛风(岛风型驱逐舰)·改', '黑潮·改', '阳炎·改', '早春·改'] } - - { nation: 日本, ship_type: dd, min_level: 100, priority: ['岛风(岛风型驱逐舰)·改', '黑潮·改', '阳炎·改', '早春·改'] } -times: 3 diff --git "a/resource/builtin_plans/\345\221\250\345\270\2707\347\253\240-7-4.yaml" "b/resource/builtin_plans/\345\221\250\345\270\2707\347\253\240-7-4.yaml" deleted file mode 100644 index e0a2260..0000000 --- "a/resource/builtin_plans/\345\221\250\345\270\2707\347\253\240-7-4.yaml" +++ /dev/null @@ -1,32 +0,0 @@ -# 周常第7章 — 地图 7-4 -# 编队: SS*6 -# 默认复纵阵,Boss(M点)梯形阵+夜战 - -chapter: 7 -map: 4 -selected_nodes: [B, D, E, G, H, L, K, M] -endpoint_nodes: [M] -fleet_id: 1 -fight_condition: 1 -repair_mode: 1 - -node_defaults: - formation: 2 - night: false - proceed: true - -node_args: - M: - formation: 4 - night: true - -fleet_presets: - - name: SS*6 - ships: - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } -times: 3 diff --git "a/resource/builtin_plans/\345\221\250\345\270\2708\347\253\240-8-2.yaml" "b/resource/builtin_plans/\345\221\250\345\270\2708\347\253\240-8-2.yaml" deleted file mode 100644 index ba7b22d..0000000 --- "a/resource/builtin_plans/\345\221\250\345\270\2708\347\253\240-8-2.yaml" +++ /dev/null @@ -1,39 +0,0 @@ -# 周常第8章 — 地图 8-2 -# 编队方案: -# 1) 大淀(苍青幻影) + AIII + 85工程 + 潜艇 -# 2) SS*6 -# 默认复纵阵 - -chapter: 8 -map: 2 -selected_nodes: [B, J, M] -endpoint_nodes: [M] -fleet_id: 1 -fight_condition: 1 -repair_mode: 1 - -node_defaults: - formation: 2 - night: false - proceed: true - -node_args: - M: - night: true - -fleet_presets: - - name: 大淀AIII队 - ships: - - { name: 大淀(苍青幻影), ship_type: cl, min_level: 100 } - - { name: AIII, min_level: 100 } - - { name: 85工程, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - name: SS*6 - ships: - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } - - { ship_type: ss, min_level: 100 } -times: 3 diff --git "a/resource/builtin_plans/\345\221\250\345\270\2709\347\253\240-9-2.yaml" "b/resource/builtin_plans/\345\221\250\345\270\2709\347\253\240-9-2.yaml" deleted file mode 100644 index b66ada4..0000000 --- "a/resource/builtin_plans/\345\221\250\345\270\2709\347\253\240-9-2.yaml" +++ /dev/null @@ -1,103 +0,0 @@ -# 周常第9章 — 地图 9-2 -# 编队同 9-2 捞胖次配队 -# 默认复纵阵 - -chapter: 9 -map: 2 -selected_nodes: - - A - - D - - G - - H - - M - - O -endpoint_nodes: [O] -fleet_id: 1 -fight_condition: 1 -repair_mode: 1 - -node_defaults: - formation: 2 - night: false - proceed: true - -node_args: - A: - detour: true - sl_when_detour_fails: true - D: - detour: true - sl_when_detour_fails: true - G: - detour: true - sl_when_detour_fails: true - H: - detour: true - sl_when_detour_fails: true - M: - detour: true - sl_when_detour_fails: true - O: - formation: 4 - night: true - proceed: true - detour: false - -fleet_presets: - - name: 传统AIII双装母 - ships: - - { name: 飞龙·改, min_level: 100 } - - { name: AIII, min_level: 100 } - - { name: 鞍山·改, min_level: 100 } - - { name: 长春, min_level: 100 } - - { name: 大凤·改, min_level: 100 } - - { name: 不挠(装甲航母), min_level: 100 } - - name: 传统85不挠 - ships: - - { name: 85工程, min_level: 100 } - - { name: 鞍山·改, min_level: 100 } - - { name: 长春, min_level: 100 } - - { name: 飞龙·改, min_level: 100 } - - { name: 济南, min_level: 100 } - - { name: 不挠(装甲航母), min_level: 100 } - - name: 三响岛风 - ships: - - { name: 85工程, min_level: 100 } - - { name: AIII, min_level: 100 } - - { name: 早春·改, min_level: 100 } - - { name: 黑潮·改, min_level: 100 } - - { name: 炽热·改, min_level: 100 } - - { name: 岛风(岛风型驱逐舰)·改, min_level: 100 } - - name: 双响岛风 - ships: - - { name: 85工程, min_level: 100 } - - { name: AIII, min_level: 100 } - - { name: 炽热·改, min_level: 100 } - - { name: 絮弗伦, min_level: 100 } - - { name: 岛风(岛风型驱逐舰)·改, min_level: 100 } - - { name: 黑潮·改, min_level: 100 } - - name: 85AIII四防驱 - ships: - - { name: 85工程, min_level: 100 } - - { name: 不惧(防空导弹驱逐舰), min_level: 100 } - - { name: 炽热·改, min_level: 100 } - - { name: AIII, min_level: 100 } - - { name: 基阿特·改, min_level: 100 } - - { name: 絮弗伦, min_level: 100 } - - name: 传统85AIII零铝 - ships: - - { name: 飞龙·改, min_level: 100 } - - { name: AIII, min_level: 100 } - - { name: 鞍山·改, min_level: 100 } - - { name: 85工程, min_level: 100 } - - { name: 基阿特·改, min_level: 100 } - - { name: 长春, min_level: 100 } - - name: 炽热85AIII双装母 - ships: - - { name: 85工程, min_level: 100 } - - { name: AIII, min_level: 100 } - - { name: 絮弗伦, min_level: 100 } - - { name: 炽热·改, min_level: 100 } - - { name: 不挠(装甲航母), min_level: 100 } - - { name: 大凤·改, min_level: 100 } -times: 3 \ No newline at end of file diff --git "a/resource/builtin_plans/\346\210\230\345\275\271.yaml" "b/resource/builtin_plans/\346\210\230\345\275\271.yaml" deleted file mode 100644 index 0720489..0000000 --- "a/resource/builtin_plans/\346\210\230\345\275\271.yaml" +++ /dev/null @@ -1,6 +0,0 @@ -# 困难航母战役 — 刷 8 次困难航母 -# 对应后端 API: POST /api/task/start { type: "campaign" } - -task_type: campaign -campaign_name: 困难航母 -times: 8 diff --git "a/resource/builtin_plans/\346\215\236\350\203\226\346\254\2412-1.yaml" "b/resource/builtin_plans/\346\215\236\350\203\226\346\254\2412-1.yaml" deleted file mode 100644 index 306b09e..0000000 --- "a/resource/builtin_plans/\346\215\236\350\203\226\346\254\2412-1.yaml" +++ /dev/null @@ -1,15 +0,0 @@ -# 2-1 捞胖次 — 简单的低耗图,适合挂机 -# 默认复纵阵,Boss 梯形阵+夜战 - -chapter: 2 -map: 1 -fleet_id: 1 -fight_condition: 1 -repair_mode: 1 - -node_defaults: - formation: 2 - night: false - proceed: true - -times: 10 diff --git "a/resource/builtin_plans/\346\215\236\350\203\226\346\254\2417-4.yaml" "b/resource/builtin_plans/\346\215\236\350\203\226\346\254\2417-4.yaml" deleted file mode 100644 index 366e243..0000000 --- "a/resource/builtin_plans/\346\215\236\350\203\226\346\254\2417-4.yaml" +++ /dev/null @@ -1,28 +0,0 @@ -# 功能: 7-4 漂流捞胖次 -# 推荐配置: 6 鱼, 选择 1-2 个三级后备弹, 其余大角度 - -chapter: 7 -map: 4 -selected_nodes: [A, B, C, E, D, F, G, H, I, J, L, M, K] -fight_condition: 4 -repair_mode: 1 -fleet_id: 3 - -node_defaults: - enemy_rules: - - [DD + CL <= 1, 4] - - [CVL == 1 and CV == 0, 4] - formation: 2 - night: false - proceed: true - proceed_stop: [2, 2, 2, 2, 2, 2] - -node_args: - M: - enemy_rules: - - [SAP < 1, retreat] - formation: 4 - night: true - I: - enemy_rules: - - [SAP < 1, retreat] diff --git "a/resource/builtin_plans/\346\215\236\350\203\226\346\254\2418-5.yaml" "b/resource/builtin_plans/\346\215\236\350\203\226\346\254\2418-5.yaml" deleted file mode 100644 index b71a523..0000000 --- "a/resource/builtin_plans/\346\215\236\350\203\226\346\254\2418-5.yaml" +++ /dev/null @@ -1,22 +0,0 @@ -# 功能: -# 1)练6鱼 2)捞胖次,电表倒转 -# 3)捞稀有池[鲃鱼、霞飞、尼古拉斯、哥伦比亚、B65、塞班、托戈、吸血鬼、七省联盟、U47、墨尔波墨涅、龙骧、哈曼、留里克、埃德加·居内] -# 带路条件:平均航速<=27,最低航速<=21 -# 推荐配置:6鱼 -# 来源:https://nga.178.com/read.php?tid=16860675 -# MapLevel -chapter: 8 -map: 5 -selected_nodes: - - A - - I -fleet_id: 1 -repair_mode: 1 -node_args: - A: - formation: 4 - night: false - proceed: true - I: - formation: 4 - night: true diff --git "a/resource/builtin_plans/\346\215\236\350\203\226\346\254\2419-2.yaml" "b/resource/builtin_plans/\346\215\236\350\203\226\346\254\2419-2.yaml" deleted file mode 100644 index 88c3025..0000000 --- "a/resource/builtin_plans/\346\215\236\350\203\226\346\254\2419-2.yaml" +++ /dev/null @@ -1,129 +0,0 @@ -# 作战计划: 9-2 捞胖次 -# 迂回点 (A D G H M): 有活动补给舰(AP)梯形阵战斗, 无则迂回 -# E K O: 无活动补给舰撤退, 有则梯形阵战斗 -chapter: 9 -map: 2 -selected_nodes: - - A - - D - - G - - H - - M - - O - - E - - K -endpoint_nodes: - - E - - K - - O -fleet_id: 2 -fight_condition: 1 -repair_mode: 2 -node_defaults: - formation: 4 - night: false - proceed: true -node_args: - A: - enemy_rules: - - - AP >= 1 - - 4 - - - AP < 1 - - detour - D: - enemy_rules: - - - AP >= 1 - - 4 - - - AP < 1 - - detour - G: - enemy_rules: - - - AP >= 1 - - 4 - - - AP < 1 - - detour - H: - enemy_rules: - - - AP >= 1 - - 4 - - - AP < 1 - - detour - M: - enemy_rules: - - - AP >= 1 - - 4 - - - AP < 1 - - detour - E: - enemy_rules: - - - AP < 1 - - retreat - K: - enemy_rules: - - - AP < 1 - - retreat - O: - enemy_rules: - - - AP < 1 - - retreat -fleet_presets: - - name: 传统AIII双装母 - ships: - - 飞龙·改 - - AIII - - 鞍山·改 - - 长春 - - 大凤·改 - - 不挠(装甲航母) - - name: 传统85不挠 - ships: - - 85工程 - - 鞍山·改 - - 长春 - - 飞龙·改 - - 济南 - - 不挠(装甲航母) - - name: 三响岛风 - ships: - - 85工程 - - AIII - - 早春·改 - - 黑潮·改 - - 炽热·改 - - 岛风(岛风型驱逐舰)·改 - - name: 双响岛风 - ships: - - 85工程 - - AIII - - 炽热·改 - - 絮弗伦 - - 岛风(岛风型驱逐舰)·改 - - 黑潮·改 - - name: 85AIII四防驱 - ships: - - 85工程 - - 不惧(防空导弹驱逐舰) - - 炽热·改 - - AIII - - 基阿特·改 - - 絮弗伦 - - name: 传统85AIII零铝 - ships: - - 飞龙·改 - - AIII - - 鞍山·改 - - 85工程 - - 基阿特·改 - - 长春 - - name: 炽热85AIII双装母 - ships: - - 85工程 - - AIII - - 絮弗伦 - - 炽热·改 - - 不挠(装甲航母) - - 大凤·改 -times: 9999 -gap: 0 -stop_condition: - loot_count_ge: 50 diff --git "a/resource/builtin_plans/\346\264\273\345\212\25020260730-E1\347\202\270\351\261\274.yaml" "b/resource/builtin_plans/\346\264\273\345\212\25020260730-E1\347\202\270\351\261\274.yaml" deleted file mode 100644 index ba1da3e..0000000 --- "a/resource/builtin_plans/\346\264\273\345\212\25020260730-E1\347\202\270\351\261\274.yaml" +++ /dev/null @@ -1,8 +0,0 @@ -# 20260730 激斗漩涡 E-1 α 入口示例 -event: "20260730" -chapter: E -map: 1a -selected_nodes: [B] -node_defaults: - proceed: false - formation: 5 diff --git "a/resource/builtin_plans/\346\264\273\345\212\25020260730-E5\345\244\234\346\210\230.yaml" "b/resource/builtin_plans/\346\264\273\345\212\25020260730-E5\345\244\234\346\210\230.yaml" deleted file mode 100644 index 12eb446..0000000 --- "a/resource/builtin_plans/\346\264\273\345\212\25020260730-E5\345\244\234\346\210\230.yaml" +++ /dev/null @@ -1,16 +0,0 @@ -# 20260730 激斗漩涡 E-5 α 入口示例 -event: "20260730" -chapter: E -map: 5a -selected_nodes: [A, B, C, D, F] -node_defaults: - night: true - proceed: true - formation: 4 -node_args: - C: - proceed: false - D: - proceed: false - F: - proceed: false diff --git "a/resource/builtin_plans/\346\264\273\345\212\25020260730-H1\347\202\270\351\261\274.yaml" "b/resource/builtin_plans/\346\264\273\345\212\25020260730-H1\347\202\270\351\261\274.yaml" deleted file mode 100644 index 6d8bc6f..0000000 --- "a/resource/builtin_plans/\346\264\273\345\212\25020260730-H1\347\202\270\351\261\274.yaml" +++ /dev/null @@ -1,8 +0,0 @@ -# 20260730 激斗漩涡 H-1 α 入口示例 -event: "20260730" -chapter: H -map: 1a -selected_nodes: [B] -node_defaults: - proceed: false - formation: 5 diff --git "a/resource/builtin_plans/\346\264\273\345\212\25020260730-H5\345\244\234\346\210\230.yaml" "b/resource/builtin_plans/\346\264\273\345\212\25020260730-H5\345\244\234\346\210\230.yaml" deleted file mode 100644 index eb49c81..0000000 --- "a/resource/builtin_plans/\346\264\273\345\212\25020260730-H5\345\244\234\346\210\230.yaml" +++ /dev/null @@ -1,16 +0,0 @@ -# 20260730 激斗漩涡 H-5 α 入口示例 -event: "20260730" -chapter: H -map: 5a -selected_nodes: [A, B, C, D, F] -node_defaults: - night: true - proceed: true - formation: 4 -node_args: - C: - proceed: false - D: - proceed: false - F: - proceed: false diff --git "a/resource/builtin_plans/\350\207\252\345\212\250\346\274\224\344\271\240.yaml" "b/resource/builtin_plans/\350\207\252\345\212\250\346\274\224\344\271\240.yaml" deleted file mode 100644 index ad11bfa..0000000 --- "a/resource/builtin_plans/\350\207\252\345\212\250\346\274\224\344\271\240.yaml" +++ /dev/null @@ -1,5 +0,0 @@ -# 自动演习 — 使用第 4 舰队挑战所有可用对手 -# 对应后端 API: POST /api/task/start { type: "exercise" } - -task_type: exercise -fleet_id: 4 diff --git a/resource/builtin_templates.json b/resource/builtin_templates.json index 9b0fa1c..744912a 100644 --- a/resource/builtin_templates.json +++ b/resource/builtin_templates.json @@ -7,10 +7,10 @@ "createdAt": "2026-01-01T00:00:00.000Z", "description": "自动刷取战利品(胖次),可选择不同地图方案", "planPaths": [ - "resource/builtin_plans/捞胖次9-2.yaml", - "resource/builtin_plans/捞胖次7-4.yaml", - "resource/builtin_plans/捞胖次8-5.yaml", - "resource/builtin_plans/捞胖次2-1.yaml" + "resource/system_battle_plans/bettle-周常-9-2.yaml", + "resource/system_battle_plans/bettle-周常-7-4.yaml", + "resource/system_battle_plans/bettle-周常-8-2.yaml", + "resource/system_battle_plans/bettle-周常-2-1.yaml" ], "defaultTimes": 99, "defaultStopCondition": { @@ -23,21 +23,19 @@ "type": "normal_fight", "builtin": true, "createdAt": "2026-01-01T00:00:00.000Z", - "description": "每周战斗任务(第1-9章),选择对应章节方案执行", + "description": "每周战斗任务(第1-10章),选择对应章节方案执行", "forceRetry": true, "planPaths": [ - "resource/builtin_plans/周常1章-1-5.yaml", - "resource/builtin_plans/周常2章-2-1.yaml", - "resource/builtin_plans/周常3章-3-1.yaml", - "resource/builtin_plans/周常3章-3-3.yaml", - "resource/builtin_plans/周常4章-4-1.yaml", - "resource/builtin_plans/周常5章-5-5.yaml", - "resource/builtin_plans/周常6章-6-4.yaml", - "resource/builtin_plans/周常6章-6-3.yaml", - "resource/builtin_plans/周常7章-7-4.yaml", - "resource/builtin_plans/周常8章-8-2.yaml", - "resource/builtin_plans/周常9章-9-2.yaml", - "resource/builtin_plans/周常10章-10-1.yaml" + "resource/system_battle_plans/bettle-周常-1-1.yaml", + "resource/system_battle_plans/bettle-周常-2-1.yaml", + "resource/system_battle_plans/bettle-周常-3-1.yaml", + "resource/system_battle_plans/bettle-周常-4-1.yaml", + "resource/system_battle_plans/bettle-周常-5-5.yaml", + "resource/system_battle_plans/bettle-周常-6-4.yaml", + "resource/system_battle_plans/bettle-周常-7-4.yaml", + "resource/system_battle_plans/bettle-周常-8-2.yaml", + "resource/system_battle_plans/bettle-周常-9-2.yaml", + "resource/system_battle_plans/bettle-周常-10-1.yaml" ], "defaultTimes": 3 }, @@ -51,22 +49,6 @@ "fleet_id": 1, "defaultTimes": 1 }, - { - "id": "builtin_event_20260730", - "name": "活动·激斗漩涡", - "type": "event_fight", - "builtin": true, - "createdAt": "2026-07-30T00:00:00.000Z", - "description": "2026-07-30 活动方案(简单/困难 E1、E5)", - "forceRetry": true, - "planPaths": [ - "resource/builtin_plans/活动20260730-E1炸鱼.yaml", - "resource/builtin_plans/活动20260730-E5夜战.yaml", - "resource/builtin_plans/活动20260730-H1炸鱼.yaml", - "resource/builtin_plans/活动20260730-H5夜战.yaml" - ], - "defaultTimes": 1 - }, { "id": "builtin_campaign", "name": "战役", diff --git a/resource/ship-library/assets/backgrounds/rarity-1.webp b/resource/ship-library/assets/backgrounds/rarity-1.webp new file mode 100644 index 0000000000000000000000000000000000000000..1fe19dd10e0a7af31a27ab32834470757ebdae8a GIT binary patch literal 13186 zcmV-|GkwfbNk&F`GXMZrMM6+kP&iC&GXMZDp#VP+O-O9pNRT9y`?~ySx$_UWdwM^F zi2hGNRT2UaAe>brCtabE>Vt$z7}c&?Yu_X-=B&74&m8xejJUX)JKwRdhU zNwdJ>0ZSSMt;Kn>wu|1?{eZN$O*hwzq-;9?x+Fo0*W8^iK$5&x%u6(|*Xr@2=`rbE zb;%9NGs}DzrwvQeLnO8LUPVqsqQ%j-O>m69~W0Q$*ln~Q4rz=Mi_$h z0@%<=a_b0a2YBfkxI3dz`$ogIomFVgFZr?o5vcl0<;NrZ$Ayp};s0}+F$A*7{b?g; z{ZF2YWL6*!2W=Y((j?)JdS>q*LPSi!%naJ3GCFsd-Ox%EwK6?sX@Ny9I7~~g0TiQ@ z;-jKsG-nD>@h&VYGGR{8vgeYWg;}l{P-TaQ;Eh%-N?A$8Dp5<@2UV(V?En?20NDZ} zKk7n3MP_DDL{U*LC|4mKQJH0BElaVt0HT7GytY~*QZqBCqFR6Zb7y?Nf*T3^0P_}J5CS7AA z+0$md`wO58z`BQ?c}0m$3=2IiGj3jwo1FR8Gl1T+6GMgYu=dvP0#)*vTZrO&CE-N9$-vl8t6x5jrxX@4%(2k;?$ zCVR#rJKgBPaVXc}vq15le6D*Jbo*|M+w!ECMe5KJtc?xlr1-Uxu7ZNUz5g!L=c?C1 zzlGHnGk2l3ejnsJN%PYRI!VzQ!T3pjk6y+ZNt8q!+3K^>I?n*=svxVek6<(rOauwP z0oS+oHi?WAhsu7Ods-&|Fmu88udkEX(?{0(Txxu!-pqZJN0dIL^*A!$F7uzq!zMEm zkpLRI0IiJiL&rKJJbK8o{s`JQvQ`2Wgs}FjeLu*`cpq{frcOa#9~VoI00OLzox0w0 zgVZuFOQkZ?F;3$-ljC@rLx<*KG`kH9A%>L=%K*BrPd?m7u*-{>LoTTslv;<^m=*N? z^Z0YpX22Msq5M?56|f1K;NN}pzGwQ74d@#b_$S1|Zjw2Q45C z&!3DdtebHjuKJ!Nx<;{CwEz{C?{CM=8b!5XtaE~$@OKz8Po<=!@VWlaa-LI?S-@>{ zFyOt;)6`rO4ZA&dOlCv?13wFH0a!P?O$uW>M+EAWFTg4qLwkc&CAp+9vR2-xL5@F< zk`N&rE;RY9yv!wRqva8bO{zJiYTk|ufJ^(idds;?bp%0E#k_5H@O=rnZAbTuX-=W< zQOQg%2w(sF14eEY;raf85C%q$u{PZ_$4i1fKPhTU9~{Rx4Gs+a+`KLTfiRT~iD?80$8oUMRtL=x9jIUdRoB&o0L4XP z^s_O|AYv@~x~R;?q=G3!J;hj(Q)~H4SZihjI8@rUP67~sJR;V;Xn_O~pz5BI*~)Fy z&Q#uY5jwQ`F|q*)^j-~2sBKUyHIHK-(29u=h-*Ntb@p~9GfBW&31gdwa0UTdetj+F zgprn}GsnD1!C1fkb#gh$NU6kHDd#EWKn&43?rh97SQ)za%SKa3_6oDd5di1lW@Zj_ z@9X!EQNXy)Nd>*3?3*sRY|GLtlPTC=w&9@({y>S7sK>e=$+o4A=t`ppqkZA2b;v}uLlV{cXA&R z>_`(rddS`qu#c@wj?s3I=>lM@(I-HCGoAF_0TB>^ZlKm2W2m8=_YW_bo6lqP_pKGq zQLRfD*t0{{wwM^X{gP2$-GP{qmjyu1^vqyuqeGm8>Ee`#skqh}G!5ZZ?%g+Jq}mB( zNXV=e*rX_?Fh*Uk!h8xKnR#TZK0x3|rDsl1DCCGzE4Z6oqtn9lTvv`hXc`(9iw(Ig z=w6wIk|cB$;B)C&1Hc7r83?K{-oO5wBqc~)s=-_`7#`p%G|iw3jL@Y3h4Dkv$-|B? zP#>k#nUR%sMKnE3dw%SoL&q2}R4|AEfjZO7S{c&!zP7kKgqL@>ArPn(0eae_ zW~-&Mef9y^?39e!*OXTUw4o6Uwv)MY)oPkStg37ItH3T^iJcnvFzXm(jE8gvT8(}n ziONOo<<*OjQJ{5&h@}fFy8w^sy6~CVZ2S-Jx#O~gn9OD!O&8@rO z`*yb0p4BDNkou;NkgPj6LI^gXX$W|JXy9oN$N)A-J9(4W4zwO$UFuP;ew?aa2y%-` ztMi0{n$wWn2CHU-1UK6|h&4tuObIyOerY`b>U6|_4FX#GpcfW$GgvzvfOkwoC|hR$)O}!j5`oMtIk3zP6sxt< z5Gnw1(UcHc!!WzjZT@-nV5Wt`a)I&EM@dgPPGvKcenah)hL;6r@&u3RxFj0^N z^er6-PX&a9<56^TNl=#x1dbyLfnf5rfj~%*19JD(jKmdu3*2p}NLDSsR@56c1Q1Jj;3=>rRQ8=$&?#16s;fo1QEd!Cy@`k?%| z0(DW8K@(V+R{`F|L`2tthN3w_fKHSug+ zUQ`IQMyHz7pgI}GJa-`nVy=!<^)5grYY+}6UA6D{IrF#)$Jn>m7y45wDyqf)=XI5nCI#n`>;%egE3~ zU;L~xu7*R;j@O)Gh@sT{8Pt6nyh;GAFFn5>_X}CP|DdYqF@UYc#ma^- z5@yVWQ?KdDKNvWj+tOd_L~IHl92@g0RBQiw|LBTpcx_;50%?10AsZ5ifyI@Tcv@&z z12+e>t9ZC9XAW&*$E_;0PLAtGI|{@E!IE2ct_wgSFbF`#^C6`3S*#yMFm1>6IM@oe z4>Vz0tg|sb>H?~Efk5>1b_Ik`5p!K8wZGMLPF(za&LFJw#DD7$?*5-2cT2ze$*hp0 zAmP~{B+4Tv)OF=LH)I6k$HjoF)1Xc2;{jL&(A*Nx1_=}|u9{af7iSE!8Vi5F8Hp-@ zGT()nA^?#Wm&ttst=ssSK`2I=@waaL+zMjH6&68g$OME6L||o`2@_B~?z1mC&Is&C zD%>C)()k=e%C#~#&B}RRkhEvFS^4m@^nvhF`g+Rc=T1E@#~loYHZ70bxYucSJtE7P z=g%^cKNE5RY>*wHeX!b-6COJ;qh~Ky8VA=0Tnie5XnZ*Al&3iUq2uL^^O<)HCT7)A#>h-{M6ehUw7b3 z9s^txa`nJ}`>ncN^TBUOj(`7`zxLpA<;y-M8}RsOdUCxGLPwQukTLOkf0x20on9M z!fgmsg$5+gZ;eF-#3pm+|SaT!6GaFW0eXnsQEnRzfq| z_ORQmNUC1N0FFN|^tle~2E78H6KieSJ^H}&qvFEcz)w&2Pt!_w+j?EaG{-EG3^)YO zhZQY8hAuj)#ZNxW#PvxO&Ax$E0Nr!I$d)DZb&`PWkAv|{+ z*Qg-%Qy8A4_P=jFa{7mFJokW9D(pY~2f5Ed9M8wkeE|we+}k}#s)zOw`G7nP?@Mtv z9lo)Hf*pd943OAg_D6590c;!@el0&U7{w4$LncLzZ(un-crgCoJdZ#;+C4x9mVk|O zCm65CSBTv_Ub`$1Lj@4B=9__mm?LY9ZI}k8KX>|hgOYNHr9g_iW7(kVNA>2D;O8k6 zv3p?jszUpDN^>#$y~-ROC8q7>aS)z9&a1k%L>3cgMnV zxlEtTO+QZuqp}-9?-bBw?Ax4n$M<}1AE^;3JSzrUlNtchFe-xiii_tb6>&}`^s8ymd3i3lLXf^hXF*6(Z?6a^AH-OLH%^<6Zp4qdTtZpPlM zY6UeiYt{APlk(%n5!=`)(sy^=3<5I7kOX4C+mWzQg^=cLF<$O^E)JFVgEVc^QrBTn z$9O@CH=n@^du25R`V()EP1{aF$3;`fT5JCHZG!R9-7ojncdoxObtuK`i9Ei&2#08m zT3=i-$2Lgww&}QEm(QGTp`-9{GZm;$pJqP#{4cdFNG0rZ>)ygZxjCn6+fqZM@kAyE6%T!#&ijB@X-**~3P zR6HF7VBgy|lO_wrcpK8+egAJ8bk!+>4RHrhf`qR2q3=UBBtU@UUgK3NUJkJV=IxsX zBZw_m*Z$e*@3(BPF^`{H5~q>ShY({&kO2BERjP-Y5@0Z1$>8u2$Y2}SdO&dm8?eC& zpmqwS^pOBTfFu%$kor&mw)b0*$j$GcE`@;n=JaeZQ6Ym8oPz0Cd?*kYmk`YLZv7Yo zPtW~^tRUIpc8m~SeiBzNUN0R$1E2ylH^HdprhU*9g8srUG^UNUAyIBlx3p%g#zmB? zh^)$t`28kuR%g;v1qst{daHsEo%$c zwHuP@2AX4TJCb8~tpVs?`)+#ACNtYFnhB630EaCfr66+*rf#i9?IeRSq>D_Iym|FW zn~t>)@|A|9K*eZ>pT}+i=?#GZy<4Fg;~g9< zaN3835E3BUdkiQBs-*|PfDB;3b!-y7(;;IpV|S1wy-ukD=)+>x`quUSyB{DHH%bK% zkfT`kadn$T7lDsp19luEDWz^Yy<;)9smV}R33PV~phCBVOi9&8Gzg*2Tvan0k-;>_%WAozgHLSlYN%F3lBE7xSATq$f0EIpR zWl*1mR@?UU<1rPh8MSv4fR~-dR5C>%(71XDXq~xtWje7O%qjs0{aB}0_Bclpbgi$0 zSWV~Yki+g-!x~*C`|YV?I>1Q#xX*wANOEkLs(wo=1zPJjL}BmoE6~41c zqBFw~re{XEPzcw00^oO&l-0k2#4qV3Qypr{qe^s8ol$qW9Y{=z75xUo1-szyf$n7SdDgzuzAU)E@lD; zpW|L7a`kG(65U!1HRm)ra8UxDb-NK?rnm7jR^xIL{)A`!#%K2*^vHMVS$N7z{60xt z$_QXvC+%RZF6!Vc$QX4Z)2KqOuC?nzxPTzGojXT4o zr|{Bx%8%u0Oi8TWCLip#vsIPdo%tg;pc-(FQ>ij99c(+(^V4HvV4g0=vdzm2|A~fK z-@mzi@{X6(z}<^y4qT|xL0)_O&+H(B;=$}7#mb-%iM{4g5T-#WD}@>{!@L|)7fx5x zJL(6|-!Mii`0(f|KDYg^q?E(U?R?%_kpjA{ymgdBnM zi7S%qyM~&`Aw+=$xVVqQ3ttBu(pCRU+CSeOpKmN$VgCFbU;DKK*q90dy{1k8>PTzS z!dG5D+jveQ^JU!3j0CSq-Q3s{~LIU8@06CPIV~1C-GA6F{t@TZL+l zF;u1)joGDV?OmTarJRQ8E}ySD90P)#Qi*~p;PB@1@l1i50{wEY-}yB|6O?XNHKeJ0 zl>rnGpuPP=Bw<=sC6=WzhnmB7ibT!lANVJIOy^eb;?0%qVA5{$cwOk%SW zf)$8Uw22`;eaBU(mLiM|#8K}{4B&Q-V*~^t3hYk}vMwg+nJJ4x3|1Wp=f`9^!k<$G6#9at;VXZQ0QlV&Ai1*zs0bBaU!WYH<)#=w1xN^Lt}D?Q!NwRz8nH`$ zY=fbjEL`@O|(xca?Z`%xr%0x zIN_0NP_7AKe0z4?bZK}zbQl$naxR}N=j>8$ivgXJ%&rfV+g)-q)q_&6DDm_pbLTTf z*k{ex@XYNL088f)NpbX)grK;CpC9K^uE7)0jVU30i5zpT=4y#!42W<%A4-UFJykp& z&jg_|9v*VN^+aOU=amoUC>%iMwglEku4Qt}{oitbuHVj~2*KJXg`B&TV+ycQrG^oJ zgPsyKs2uC`$cJN+ITjRTZ=Wo8=c9|txCjC{JV?1+m)v~1Zc2x9$S710?9*Z%csO=L zIfRYOc~(FTp-Q~GUT!85p(EfUBB1~rOxK1Y%n*<~QB;@dfi$~>r{hQj3|iVCU?9vG=7oU5hG>k&O#@1yTVcs{ z?}m)iyM<|bk}B*_W3I;n{VMui5Qzj36rhlp`GO~%FwM>A$hzjb_cHhXEKV{a=~M~1 zzu&S~#yFb>gW>T>Tpz9*3)H{lYp*a6by99_+J`V5kkEUz*64jef)3;3tDg;^kG_{6 zk)sDxf+oHHp33dL{DmKDOC}~a_W}%yjQ0yI z!n?<6t^xt|#H&D|>e3ZRG@G)FpQC@Zw^I_VR{j0{EtRp~zqdd1Ck`Ys9artbN?`9% zL45A5C|KaIy?w4K=c!y>HqGYx(g5jKtY*-xel^Az$h2Q+KlTp=WOpm^B_p@Z7S z(}Q=53x;%md+MSlzaBF4+soq_!VF*oI7?7eJ=2KFNFmTtVz4 zCmdNOh!{Y%=!r3a0Lxkeq@w`{=kIO7B!as<7!bPH1(Zv!ss|oPnFM=nf@LBxAk(xA z1j2y?!u)vH*rWuy)&sgyx~VJ+j}LTjEtCRjzusyvo&+m0=>;O$Iu0< zJ1`JHO3701<|s0OAg&QRv;jm+1R=0w8=^67TfaysmQeKA7~3lXY$g(!DhognGDDco zq5W=eVb(7X=USN_FvCU>{xSva2N)#4rU*v@C@Q{ILCW3Es|fa%5oEE8L}Uz*YzJlx zS-_(0vVC8|Py_}s+zf&TrlsoZ&I+ivu7dH zp&0>eIA2u}Ndc%lsAHyr+doi7$X{}wWsOG0!`UT35;is!GAMM}X>_AVKfH^H~`2sSfeoeGRZu$D_ z>)N5mCewN?GBpMvzw)nN?bT{;>;B=*dd5%MAz`M;u`JjnWMi(|!UcE+xV`7Nzg-a$ zr@K*Qc$ha*t{yrq5Phl;0KrHCm|v72@>~35CvRTe*QKJI4sc6^LtKg(64*k{Iq!LCL4n?R*0K%Iov{a#_<{Ll=k< zNlI|skq(5l$K!D$l58=91J8yxs~EHlZufh{;jS7mY>r3XntB--!RWd-LeNRN zdZvIvO+JnH#0V}vu}#-~DQaYF1lj{V0YMVL`N@Mf%}X=3L7N>ck9u>VkL(3EL{o^2 zwMLOy56@baoY4|O4=PG=A2e|Y%&vnaAvOd^5+qBsZ$JGKRuzE}aeQs}Gjbh_?dW?* z^{a{sDG{Q)u1syu&e2d^YD^MCKyYC!lSieVE>+#{z)HhCfdnDxjVJA0ZV@CE3!s?{ z8{!AP<}qL}wpbMr`>4V(CGh|LD#3hh8>3XSa<7!SB2lqi%2By`VTwx}bUEJ$xV?XR zWeVo1dl!HZO#L|rs{G|&bIe~><8r8WGzQQbAjL(nqtdND{VQ*}uYUDw0mZ5~qBL~L z^@I0ISZ~keFou-ISko|$_`1J;?hpTi@#@~0%zvPN*Tc6EhIZAi1Ur=3l4?fd*LUIM z=#Yf49tp#K{q2uiHEjLmFmLa__r}3-jEohPuHYO)yz8cxke%#$?a-8 zpx>VqP&*)%%!OUg>H*<+4AETu{`{|B#!|YJ1F7p0u{xy{O*&OVF6kj@(jAQ@FNZ_l zrmuSA{O9g`Za1x7mVpHOSN>H!3rL^T>E`4Z@vJX-3^D=QuDGsS7~O#K5B>6EEYnou zvmv!6LNF4jrE!el`c=FA&~oh^#pSh0gb&Hp`{yI`ozC%eaz7MJjDPOkPi5o_@ykq# ziwf@b?wSFDg!Z(*2GIS|P?}2!Y@bamuePf#5sJ3?d|e=Wm|hK5N3UivXrs!3mV)U?EWH2-U1D+viWe zBbRbIoouV?qPhKl+xI$$*4&N6B_j!fklH6nA7$2m{j!~V!+hF)1Y)_hzU*pG5l%^n zq$G7MIC+(HetG<=unDxwJJz~%HEmx!Ids(?hLdovO}7hE`HC}a;efqvUFQImn;Cj+ zKi4oTR@J6BnpLZ7hyPUD2Do_Jw7s+JRWzrY`0bR+546FpQgB%aj?|TI)3G!*yA{}*`1VVhxx8o*>#(@N!pq=Di zXH2JD&5BD`50*IC64+ilB&es4&4)|^C5c|!B59wH0QUZ*z}g6GNbK5&OqR*r`L-+q z2)Lx0BWPu2$(GobBY?IB1k!ho^PE5uK5ftLkIZND>F;^75sn3z;KfOf^@Z*fY)#8z zv!wZ}t;>v7R%5G>rXdR#gV~kyRZ( zgOA_6OX$khMLJ4^C2b30HHYmhk_2X-Hrq_Hd4NO`{BV17^2oBwO}Q9H1BNuE93+sW z{RSk#Ru+Pzj*`fy;k+Vr?9WecKw>_Bu7hJEWHP(+LmvT++okxB&fJ{q4nu)6x8ae6)+NUT z%!m_nV}Ho{l9s+2P*jjv0+7sWGJqUMu$fhTeV^upgkXC&Y#SCoY%wNM%LW8!qbpov zuWPd=4KW9^D#~;#4(O7w+9Hr`a~m^BAl1H`07MDLF#DczbC3||5UOsP_AIaiT8r6W zVFaA8i31=>dy58+W5s3!f<26N>HrbHbC}JHE`0SRfeEypXPMopBL`7h3VnfbN4`re3eT~!khFal}6Kiy>wgQ}{;4uo5ux27wX0diDHV9LofE4$TP!VH!9#fDqui61N<@@VNb<=Z(kSZfQP3 z5@r4ibs0$SXqDov^{AOv`d1JZCwZw#^@nE2YG?q+FpR*Tynd4 z3L+$xxoi11etlBf3F%kHh}d`sD4iKkaAE2sEDz#H5)DZLkTH@FVB_&up8ZSAN1_CB z8?8VxYTG#e#$X|yftWGX(V&f$x~{Ka&~14bP8=|iI}8D-nlRv5|yM6<~9aoE__Y{oAi)`gpetaTaM}%60flr zu+jq%dq4Z%d%(EwZ_S0#4%}{42p|M<07)oU zH^t^~7Z8A~aNv9a!tt;`B3_a}COzZamDz1B_QxMX*JswLU zwilgEy}Tv~^Rh^K&$Rk2tRVn?0fgSe07rTteUt>ukv$o=3(}tUHh^!wr;8DU5CwZz zQi}k2vpJU1ore+}PL}}?(w^H-zjpHQ=p2Cn#Xbq<99T(6NRM2o`w%_PA_?%zJ*5gO z6oH~glTI1Xj^p=UopGtl)5@w4x4-K5`5lskB%K-^0#uu?xm^zOE|8FPGv>&*4uQ0t z1R!iY&uJ!l4$(^DaE^y)_HyU)3g-LOkVZmKA;=9Ff+g8$VDI?Dio@fb?TsItk|o zVm>WNPXvwyWE(RBe|`r>7EBVJKW0N(yWg5%ur2CI+caMG+$Nm`t+_hYVe_(fulu~6nFDHzo;m>V$ z5T|2vHIk}KaDar__up^AHXGr=4ge5#oUq0TRxAla< z>W0SH?>7B+o~UBF{cOWXP|N8*U?ilTiu)CSwrpb>ddtnodvk0e)41eD0Owdz*)~}{$`OY&{MVsf3FyKp-0!ipRom{WN$|km9F(8nH5QX~y?L6kb+x8>4 zI)&-Ud>Wmi(NKt^n>b3LedQ}n=lEoGyj*q>6*?a(*L^_35wOj~tf1Iyz)p@lbs69^ zNT`%$>~Bx5UiVMP-BF z(D3|GaHh_GXqZEJFDF`edG|^yT?yWxJr@u**0}a>|Ipj<@pJFKUT>e7!oJ~uelcAo zAw7Pc-*cRel)oL8Z)AaCI_X^JS)rkPx_S~1Paif%mDIF7Hy}xH6QkGlU9}%aKYc0ggIPrU6)B(ShxLiI-o$h)9wX zXxKkL&yNP#cbv0CrW243D~Svc33Jm3q5&l41!U!bUNP9-JYS%&nmfs$U(m37M!;6; zuv3|y ztR#^@5E6o*XLH9`TZtbVgHkD{6ykl=}2i89k!_t5R zk8P14s|_uTwz9r{kPDV^O5W}o?TxdGwpw(bWfOJ*0+q-#{MhpG&$(NB`u&b-V$4yG{a$-XyRE|e zOyt6sNtR~dt$Jk?aQwrSNThg2=2$Zim!Ahniy*16fXqgue_ht8{pETuJ?a>>*ZwL~ zYkjUI|Jr5uhD>4t`DXuC$#qsbZ6WJxB&c_mylb&W>yP}%vH)_9;KAzu1L^01S`LXaE2J literal 0 HcmV?d00001 diff --git a/resource/ship-library/assets/backgrounds/rarity-2.webp b/resource/ship-library/assets/backgrounds/rarity-2.webp new file mode 100644 index 0000000000000000000000000000000000000000..4077a336d566464e485e82efcae032fe95493baf GIT binary patch literal 28136 zcmV(&CmzM_O7eD=x`d@S=XeJF)ji#~Ed1c+-1=banNA0sutfwD=|G>-shVLKp!&L*X1w zsQ~~kg7y9Q5OCD*Wct?dcnLE6nqicHq3Hqu-g;?0xTXSyJT>Dnv9E&EH1H-}sR01U zRxfyQOrB;8>s1KD>;Vu6000QRxW0L>hsY)yOhYkd%oqk#1Q7rLLOkbwLTHNP05fKQ z@0J2Kv_Yv<8s5Yy3Ycw`qPWN$4DWFM;M(3qiI*V|XEs5lLZSl)0Kj1GK(NPco)fKk zowyh)3NQv>0`C*rY@)3c>6(t&W$6MJFjxQp?IBMjdQCbapn-i)ix%id*bzbm31kC+ z0zxA}oN)kvTp=Ql31cjgYGdvo>uj8`ndA1j&GnIwH|}i&0RWi^j&0a)T=sJep$}zp zzs_l!F~K+sog*^>9Gpze*kEu`F2aUFZEBB>PYfAA zp@E~g(y@-g)fPhF9|uB;f{-hO6qQ>x%o71#e-VUQ44~2$=zO5k5&{6k(|&RY0w59Z&GR#TfEjM_ZO_Rt2?G0rq_UZ)+I zU08W10N}Ve>B=UFB)-k|(DclvnF9;B0FDOi)AF?_{ul~PO#%MPcljv4E-YkWYqSjl z#SYZGeKT;D7k3#NW0mN;#mRzNYXHE6DuN6`((m;OV9t*2Xv5aDq}B)kaQsV>g^*X0 z-x?gF{;mPuwzthbgrWdIQG^_8vl)C&SPc>gQrXIOFU-XOu>=6UtdrVf_*e>9%5j6K zOz*;$UAG>u*sf;`0I*JSRT>@zt9%7AP4;9@CEj*z*CPNxrZ!gkN}%cx_Q_Q2Uk;d}*ajeQm;s zK5bLBvD=g~*lU|gmELEoY{9p}AnuAN(sz`+0-}mjV(K%V7$l zOB09JNRNk(q3^-S0kbkYItl_0yr!&=WsB_q}N!RcV!=LAm&qhTW*)Wx-f!Z{tDV61TZ z!FPZ)7LIi=hI``_P80N6PvKOB6^wKRV>oQw9mXnX^rvz@dWinM+v6NMGFHIce{;a2YwsNKeMN_k)jh z(70O#W4MnUoW}7bNs=Skwrz>1MP^kkurchxrv113-;3P|jM1pd3^(;HNs=W=l5G)@ z=Cy8p{r}&*CAhFuZQG8`IzNn=>}YMlR8=ERnluw<*=uzsR43b8z-S|x-!lPx_WxUL z*_txOT&t?~(bo6>2HnnX5K2hN(#df$KTw8X%g^9Cg+TQ>4 z^b5e+T`RyX+&FcRwB^RBaa~V}oRuCzYwzAqh&^&%!@}L2fwNPJjU+jeB=^XkW6xiI zF^^AG27WW~@FER~OOSfG z^ z1b)yDGBIVP65Ln>T9Rg*Lu^3%LJz!2I)iM&cs~wb?LdcF9U_Tom+U1q3aOmJo9wVt z07j9;T!u)Orb!kvrlv4rH`9N!-p9YbD){|bW?4Xz*@Ti_L*ppo1G0zP(Cps~|A>F# zp5aHOoFF44E=Og;mB9D-{s$X$kQpF^Dk!t2+>%{`3V2a^_=fswhZ9pHn%aOzWmnsa z?ZGIKC4!TM;0kz?wY%g>jmST?7gzp1B^o>Meje^O96RD)vWJ8BW6DF#x0#3aw|{Jr z{*ox3<9{Q-`51Dc^(jDsxl0iSunx#)Ni+?+Q5GHSNuCQ^0%%qqkL++)4o%D;p!AM{ zV$`3?^M%s?gZ~$(0z0;)fx=lz_ke69vj7X)mp(HX+Qt}P8qzeo z)NnA3b1iE+tf#V*-opZ> znp&5pAhtkvEda>G0Md$}T%GEFEFfV~?K)VP_Tvr94RN0>qL3WOM>V4YD_8_oa3oBs zFV6GOj83;&iFSyzXDDOAK(7%B(3{=B>d^TD6x^jL4g#U$Wn9&Z(fqFqCKh83j zFb?iBLY{s>2s;uarM|r6aSu2+I3^T5_e|>7B6oqZgvum^z!I~Cp84E^L zHBGE0I%F{btYQpNNs*Nv5LgUdH!Nqov;u5uhqG@?jY8yj5K!Clq#+f762|rJT%cawq@>F!cm&cqBPN0`-7YKuWYT*4|&<=SMiQY^Znk539Q(N7A{Gc2b7@#go&5=c) zQUyS}fF+X^`gsaU?1)N4U?i0Qpb|~Qs)}Y^Ghtmo(K55r-?=}r{{H;OXAcLH#%VBet)_>N~<`xV}ffksUQ9H^=XMw>b#aW`@WODk$!XupaDVx8p{N zDOK@2kWrU`5Vw#SsS_yjhxD-j|8=_H`g8*a&qDG}(D6y(e~Uj5Rx-gLAH~pn(My91 z5%XNtlNd`KE=qxe5(GG?whbyEFppxg8mk4`c9HFeV~1ocpHgC6N?<^#0@U1KRd!At zDji|20f_cz`b(bHOrb_uyHg)y!nat=0Hv++>a#;K`XYDb%K~t)CnRsZ&?sFC)|Amv zqAqHRvhab_23Mq-Nl?}o7DmbV z66QFd2gl-p1%jbmem0LIpATV(1z~o*ZVAN{DVFp6SycME=9JwPV zL+$`pz294A>wW4x*tKdM}g9@%|+$KnX4v9u_|LYaIGM z-Vv%87a`yjzn~$Vf`L$C7@PwMWKxiwR&k)LJn~vc$LqJVA7V+*(C`u+1ht=3NQ0@# zQj^A5#Rvef@%oM*z+d6*z{!;}D}P3{#w-d(j8%tvtflLgZSg{q_y6>S=qEy1nny8~+-wh&ybLd%MIUWDdkGdbAqSW~Fu% z)=~>%HP4fHqu|0PEDkBH z7$EL4P)egh4>w4qn!MT+qGwoyACp+ifcQq({e%#KxGDoDSNSNpuB(eblMoJy#ScEu zuaUiR1=ALHTSc<_-*dm!Ksw*rwhOko2-MLvIYB((CgH`IQV_vqOT%8_iC87<(kln) z4Xq~4ZYAs709qK#B+G)86m;EKWzP!)IGBf8l*9mFUD0JzM@RUQ_(K+=TL>KzH4@w# z(l?slReCL0I)>82o#_-1VE5wt%ijBuCxwD_(rq^c)lxNs!IrT!tB`l`A(Lw{Kp-fW zkc3E7yT+@6MKOr9*DN>Jx}ut^KeWCITR7{|T?+!%JQ+;N*;oc{lB1HnW8)-hVE~|@ zh?_f#O3?={YW$-RT|;)9K#%o3{vy3Gxpf`05xZacgt^sJc*42BW#sX8QS^|bRI?=8 z9>->9P&YabafTcbhYwr>`9fe2R$zX-!i9F>9M5EY+3J8elD|`CRU8S5dF#Mi9_{{t zxWciMUrYzxI4iqXnREm90eb|szs|rU?gRdX@_RzG15uy=0GzE@_+YO%5@37HRsVfc97668J zLTRwx(feq!5Y)Q@*CmmND{<1;8_$5)5a&avFUOa4j?(9UVAqCx+v#Bz@XvTh1K#xcK#yV%#IuBm}yMOYajBL6VVFkMF7@(f>2fRIQNkmw5 z(8R^+_@px`+kwb~5CKpO;D95n<<3s}fiub)d9~2$Vsx+!ztYdk7(~=aVzIt1lABzB zJcPlJSc9tzs4i+zTeXfrAQ^gRQ!58iJ($(0Kt}Ob@5_!%XPX zv~!RaODSdSc`pc{AnDR^#&HME)ESdc&$2?Nf?}&Ga4C%LDNXgJ#-c7IUtBYjF4hEQ{*&jXuR?X)4wbs3fVK-L?4Sa{J1r~*+N)tVFdi+=*fC`I( z_=At(`oLNOpb#*fjxTFsY28jHQIKjY$aW0-KyciXJ6p86Zf|Sml+BU-v%%4XH*7er zxL{8u#LnQJF4u48c~`D3z199_WejnOl5Mk<3+k49FrZ z34ipsy;TWHCIP^mkKilK!V|RscY(Ir)rUTUJEagZg% zMW#SiHF?p?TN4q1DkmZkZ=K|K_$7ou1qvQ=Z%m%Hpuqfo%~1hro7y*~1Yuj5YDb-Y zrEExZHzgn+E<>(c0MZ^F9}c>B&jNxC2rXLg!bgxf0NyhoHKR&*t99N)P&T4Si>Iw? zufmS!Y)P+?Z}1;kH;|!-tY&B9H(pR)*z>VEpSc2Vuwp}ZH8-)NW~zK;Di|yTXb6Wi z0PHbv+I9}FZ9l~87DI`w8EUnK$Q{Q$u?heRK>DsekDR>R0SchE%R7E(OiKdz(eFG8 znl>bAS&@hckMl1xFC*d+`>+-Zx39G2_uiw9Ik2_Kb?yX z7@&@A<2H=2$3k{ZLiX6Au**l{uL~3gig|9k{dIpaYbAM6z%4P1^sLE|!uN9-_i zTnmGP}g9%RdXDz zoOHm-E07{c2gEOe&VnY>UUyq)v}`A922Ud?>R zR?=mqMPzKP%0*{(Qi7ANa`SOuPc?$27%pthGa(4}2tUW$*^Z&f*sx^tNktWN0 zjf-4^833>|SdSfQhw7jlyYaBEjY#<#S1`Ehmj+a$fP=~Njte^NFPoh>7r3U@$rCB=B zeIOX#GczctO5_9nY@Z5O*Gn5qD=}C;NfXdYJ+fNco3$77d~O^bPeqn&o?9BE+=Gi0 z3WWKw8{oAL*9-{73O%jN2IH)?*botBxpY|kt?u!UHUJ?(jAD5*-+5~rRzi{xY_*h~ z(O25FiS))TPmo*KYSpTy_q~mzRggA1^HI z;p}1GQ6+dR9>N4)9Huh7ylvw|c6ii^T@H0egq zyu#MZ09zRG(@XJh+!uRM1=d>^ys|JjSQ;8}1FJXdf|)Stn4D=wBYNaBY32@j(;!DH zCNVm^Zzw0ym54w@D6m$X>*4<40c1lqE3u};Q8Q(wk9t*0PiYA2h2YZS zqU#_1@P1--EUWFBh8~U=Y^~iI>J0{4Q!rVorQT^!*%8ig1JMZxYkMR%CZ*p_ho#5 z+TL=0A0Ej#N~N!=P$;n&lmrkJVA3`7h91N6FK8~(CNVIdQor|iT3Qr<1fJ-4Qu8VmKlvq*F;oV(}kElA{v1z2KT@$a2bn^nJoiD8%y)1~2gs+vIN7^|8 z9=r}0<;YwUgVM!&f`kL5l9CY;5mu(PJYUA=c4+n$Jf}J;OU_bZJGBH7R#+>6UIR4$ z^cyXUHVvbU{pd57^P%;MsC(r{vK_9{Z0UkHN=ZSU+uXSvgJKa+X67q;T{oxg(H`2( ze_`_wT9@Z}_sRV(NpjRo9H=vDt1%+L02l&PfQ%^&@OAd(hTbcdm^voSCTf^6w1$Lv zSplsDvv0h8aIeo=S%2Di0mkBuFM<9xZphwPASx!;00m7zl86MNg?u7EM4<010EY zQY#|lU3vlEn}wmB2Y(PaP%PbF2ju*g>#)xe6>sc6agrXavTE0_Wx@_k+T8pomnP%Suq zova*;QWCLX-dSjBSx}@?TmYXqkCTmeQme}Rordv|l05T_UVq{ra0_Uk_npSE8mj$E z-cd0ggl-MtJ9?2r9P#Wt*=>R8If@y2^}d077Cjq;1m=zajEx~MpJU?ynQ2y4T?d>! zcd@W$wx+LOK{9nMi@OImZ|18`8mb)t(D^+31T{P;G1`f~!mvtPL7P{eZaGC^y348| zM35Q4i}dfnMdq4@z?ovkoUm?-Zk|Z+%o}$2U)daxSQS7txcS-)8pTa*t7VyCwjq!Y zRxDf*Jh4uG4L6`pW-Y6nyUU%a0VvQ(BMmhz3w(~40TsFwh1Zogbb0}IhCqD*sGPeI zZ|Jy1^CkZtsP_hkFh@RrkUQ=jL)sH4RM>2ZY9!VgBY;K$9U$GPRjdpZhHOqgl9h2q z?n^V{mfcHggvegmo%fIdtDyCnRWma0yX4Xo0}KpEkS-SWA$&vAfm&;bhCx5d?{nMo zmF8APB=Irm5+^1(Wnv_Co`JYP3(sbOgxR{aIb;@1cKb~5FheU%;3(J;qb9nFb7ZDb znt8c%|Dd~XXG+Tj2wPhjeZU7VAMmg=l^}UTAR_Cq+iQOpoC7vR$G4b>E+?;gPdK@k zsIU%~|B%~1+8gjOyOi=&RnM5l1W15Zrdp>=sP{iN1LuHzu)FD{xZ=%A`P+A7SP@%#t@x5QGZ>KDkgH8Z21cC@l%uPY~x&DQ3Yg*BF9x-POswdgX z$@u|+Tx-$RukSNymOu2(Vt}!!sj8XJGlNG_5D<9UTyOv4^R~>TbZMU)3;?rgB@T6C z-_Q+=%sBy}(hLj$2PX(q5t!ONtclDc`bNo9V-PS=D<@W1AS8)O*zN@FeElQ1+MjWS ziZS0{Q*p2=-nZVj!JpU{C>|l@bkr zA!z06v~!>+kP?Zt3IJ|qnz}aQ{hGbO&<|Jx*8qTYKw%o+td8jB7*yBQDF6lp1Xa-_ zuzNY|*cdQKf@GT?K7^5B06w?Y zVyy)*5DSGlC{m=c(E!`<6>MSN_)wl~76qt2u1MhIX%_)RfVDMFD=F`UkOlyddRl8m zimD@Jcyv;;UGQ`O5F*^7hs>$V;ABh)D9s>yQdc6_9q!D&sIyrBO7*d3Sqs)LRs_J- z8o<2b4PjAmhY+$Ke6V~mm7*w;w#Eo-tgX)lY9Uh~G*#0bcu93q&B4a2+a21Ii6me` zaH0{p0aYuT-m&4$W8IH5hQTlLG(=08voUjonO% zI={_Wahtsl8DwR!F$OTkP%>ckudsTRE=p}8T%n;rN|cgml#s!6x^ylYu~}o$3X8u` zbKEY<%)1xe0*yL1>f z3Ia4fTF`o3Lty$c?SH7-ocR|y6u3Y5D*)BUlF5R`YY`TW*cz0>%f0*3Is&-|1eMhs z%w1{lnpRK~e`;4yBIaTpvY0GGw+n7H3M%IWoflXB=SRyQlKVUl`Bd2J4MG)07!(2C zM#HAbC%M_?cqTM(PH!s!R5$9N#Amo3x`Ti#Z|L%a`zR1dT2YK3A`P@0T{k{F{G=0s zYQv{z7NR21ZrdsV9v360-4-Dv>V+{6KK4ekQfF@#DejHx%) zF%JvkU$LN%(KmmNwOwbidwqHF-8cJ!@!vcG=S3_vL$SlWTQOK zsCPDvvJur;BksUo)yk<0w^!fEcc-O-o@QVrWIU=pZFh&Os**$%fT#fjT!VFC<=Nye zl%)Vz4#emDpKnB%CGr{oa9>_R{e2#33+1)K!{rJH;CTTTwSgFdfiS6KZ$KWk`T5Ns zZ9vMK?CM|iweC1kZU%sI*JO)0(z#LOQ&zsm@lwG|2#|X?t^kyv7^2x?|2HC^Sw%EY z@%cU7^>MewR^~F9(?0QosrPI1=EdbMw?p#Sy6|s`XP}`F^4zO#r7p}6pNSdDotDnf zr)Htm{=kMuuFRU8aSgiqH2aPkJp=xl$=*A_dLSJD>b=Ed53V-H_WZ}sGP_9sKhF!y zLA57IhmNLkZ}~3c>UyO|zwYb14K++t1Bu-EV>HA-S)#CmI@hGbdTO$+dtukoPvt`e zo+=rbu#@!^p5YKO3~lqm**vMVG|6-R4errr8Q?0|xnqFZ`D!N>p@GE6{{P&KcHayD zbBBB>W`Ng*rtua4GH^?u$==?<&Rgr?Yx*}IR79^J&Loc9dvP6nQa)NMy2nH3d1;3edX8|#nfNiO0QLh|x zs54=|1O?V?UgzGEx_ae6jgLc~`zG&eIYU$c*0WTo<~5(Xw_I~Qxqo>7v(wVYd;kUj zVB2<=fpC%%sDKWZSCkuxMexRq$6%#}YT-@w(D5A}2=aDLB!%6Xdk`cy^z66*Pt8UP zPPr>aNbUvZGdbeD0-00Rt~P3)4v(sRccu2_g-fsYsmFT}2Iyg?57#iU@pZHEli&OO z^#P!z)2e5^h_e>Jz$s))1Zu^BR=4rw8}v%Ibnv+I$a(Gws?dU9!4| zZ-hmHBg}a09@#}PhtSo!Fjd5R=bWo+1F7qsSNmT*{PGXn`@TQ-chKC3H@X3w?*Phl zUEms2)-XTHi+FK!!DqblnvEg4+sax2C=FLNiD~Y{cErVkmr`4vqGIQFe&W$;m*N`- zat|OQOMK&!(M!Bt@sJ#FEQt{VM>Sd!4j`5Rdgf17wYW+F%~C)G2&?(P)sG4vtBZhS zS=k_u+z2s%a(Shba#gpmTx@&IcAmgn+XVOTBMVSKMeVs&#=IvB_UzTnIcT*<_H522 zn-+ZsU&5YT=bAq`%6QWhaQY;)U#Ft1-Ks;4Y*Z*3Y=6zp`8@aU7I$#CUuhqMR^9s` zKmx51Mz5*b85F)Zj-2Cc8ZZ)c)h_RGe!=1uHo?l1Yh#n_^lPjJ$ABF_ z%eVT^0YE`(yDN51tBx!*OVc#T+{|_IiZ4jL5x1Zcp{Ga{ z=9C8B&HW|$$bVG)lDx9UFo>})&;uY*n?${%yrE|jQ@f>%a~7pX(><3m%E0Rp20nEl z*K9pMZe|YCHlNOb0c?uFQ9AQbUQrHUicHF-2uty3-%7B|HdE`&W<1dYd_Q38Bg4DR zQ&ngZokfGOGuo<0XBOlXs^R-X?hi792gfokbIhwTdS~2MAWN96v*ZY94V9ScC8j}5 zUmd7-Q{L3&5?`v|Svp!W_z|$1c;X zMz1-eBw;3z8835-mZ3g`6p{*>%4mWVgYBPcJVfZFEi1WY3sYSuZbZ03^|< zJqmS2t{^<$q6Q+k9zb_!G`j9tp4;h5r}NArE4FRr&aUusj5;+iC9oShzdcpvIa&h-;7qx`x?OWSD@Oh(7mHibvky{w8@!kykxtPh4gq%9wSc;BXSq zg0*Z{(0rZ@?^6j5$O%IUQ0m1i6cAY#b59YRqJ8lCeC7m*0+Mr)g+eMc001tL$l&76 zMl0u`QI8~cW~w?1iGu@X#u(lj0DwUO#W>Hih}_@7gPemW6BSxypnQzR^q3~GwmK=u z$fyjf2|)75g=)OXs;({oWKgu{Ks1U_UDsYDw1V@W^O(*sXg+ZFet}g04AAcMRd#tC zl*+o4bK$ifNm?)f3M8(~8#=_L#Bfi(gvY(a^0N$__NzX0$1~<_XL;4d z0dpZ`sVQa+Fw_D$T5JLGp+7ntxjt;}4o?R_YD(i_gX)^~l9{o(-{+7Nqq5{(WKY}$ ziW22t%kyNknZ)S@gF5H%3U0TAo_GoI7k)d)ej2*p`~h2NE^5$?l%OPV$YJdyk*f1& z0JOOGk>z35^Bxm7^E^(IXaqGq>1g>kaX1CA1Ff+LL=#Fn-`!11W{ITJKUtfZ}#+)qc3l%f)jC%u~ptA}x>qm|d3^sDp+QNtT{kKhH zvMl9!?e*vHj0G~1_boy3Qp!m{jI{zt0+99;7zWhUh0*LczRMJO0W&O4y~;%p37?2cwkugmdyY!D}m>n z0=14Q