@lf_maple/koishi-plugin-phi-plugin-full 0.1.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (629) hide show
  1. package/LICENSE +22 -0
  2. package/core/.github/ISSUE_TEMPLATE/bug.yaml +133 -0
  3. package/core/.github/ISSUE_TEMPLATE/config.yml +1 -0
  4. package/core/.github/ISSUE_TEMPLATE/enhancement.yml +44 -0
  5. package/core/.vscode/c_cpp_properties.json +18 -0
  6. package/core/.vscode/launch.json +24 -0
  7. package/core/.vscode/settings.json +59 -0
  8. package/core/CHANGELOG.md +184 -0
  9. package/core/LICENSE +674 -0
  10. package/core/README.md +330 -0
  11. package/core/README_en.md +285 -0
  12. package/core/apps/Dan.js +129 -0
  13. package/core/apps/RankList.js +322 -0
  14. package/core/apps/aliasProposal.js +223 -0
  15. package/core/apps/apiSetting.js +592 -0
  16. package/core/apps/b19.js +1329 -0
  17. package/core/apps/botClient.js +64 -0
  18. package/core/apps/chart.js +692 -0
  19. package/core/apps/guessGame/guessIll.js +821 -0
  20. package/core/apps/guessGame/guessLetter.js +831 -0
  21. package/core/apps/guessGame/guessTips.js +254 -0
  22. package/core/apps/guessGame/letterGameUtils.js +74 -0
  23. package/core/apps/guessGame.js +214 -0
  24. package/core/apps/help.js +117 -0
  25. package/core/apps/manage.js +288 -0
  26. package/core/apps/market.js +243 -0
  27. package/core/apps/money.js +1064 -0
  28. package/core/apps/phisong.js +1418 -0
  29. package/core/apps/session.js +664 -0
  30. package/core/apps/setting.js +468 -0
  31. package/core/apps/update.js +541 -0
  32. package/core/apps/user.js +968 -0
  33. package/core/components/Config.js +249 -0
  34. package/core/components/Data.js +304 -0
  35. package/core/components/FileWatcherRegistry.js +102 -0
  36. package/core/components/Logger.js +11 -0
  37. package/core/components/ProcessCleanup.js +113 -0
  38. package/core/components/Version.js +56 -0
  39. package/core/components/YamlReader.js +157 -0
  40. package/core/components/baseClass.js +287 -0
  41. package/core/components/common.js +47 -0
  42. package/core/components/index.js +13 -0
  43. package/core/components/platform/index.js +79 -0
  44. package/core/components/platform/koishi.js +800 -0
  45. package/core/components/platform/koishiDatabaseRedis.js +391 -0
  46. package/core/components/platform/memoryRedis.js +209 -0
  47. package/core/components/platform/types.d.ts +272 -0
  48. package/core/components/platform/yunzai.js +604 -0
  49. package/core/components/segment.js +4 -0
  50. package/core/config/config//350/277/231/351/207/214/346/230/257/351/205/215/347/275/256/346/226/207/344/273/266/347/233/256/345/275/225.txt +0 -0
  51. package/core/config/default_config/banGroup.yaml +14 -0
  52. package/core/config/default_config/config.yaml +159 -0
  53. package/core/config/default_config/nickconfig.yaml +6 -0
  54. package/core/config/default_config/otherinfo.yaml +51 -0
  55. package/core/guoba.support.js +597 -0
  56. package/core/index.js +85 -0
  57. package/core/lib/AES.js +40 -0
  58. package/core/lib/Base64.js +22 -0
  59. package/core/lib/ByteReader.js +168 -0
  60. package/core/lib/GameProgress.js +37 -0
  61. package/core/lib/GameRecord.js +47 -0
  62. package/core/lib/GameSettings.js +24 -0
  63. package/core/lib/GameUser.js +19 -0
  64. package/core/lib/Level.js +6 -0
  65. package/core/lib/LevelRecord.js +9 -0
  66. package/core/lib/PhigrosUser.js +135 -0
  67. package/core/lib/SaveManager.js +117 -0
  68. package/core/lib/Summary.js +47 -0
  69. package/core/lib/TapTap/CompleteQRCodeData.js +27 -0
  70. package/core/lib/TapTap/LCHelper.js +81 -0
  71. package/core/lib/TapTap/TapTapHelper.js +170 -0
  72. package/core/lib/TapTap/getQRcode.js +61 -0
  73. package/core/lib/Util.js +30 -0
  74. package/core/lib/getQRcode.js +73 -0
  75. package/core/lib/http.js +105 -0
  76. package/core/model/README.md +3 -0
  77. package/core/model/api/aliasProposalService.js +151 -0
  78. package/core/model/api/apiVersion.js +67 -0
  79. package/core/model/api/autoSeekApi.js +165 -0
  80. package/core/model/api/botApiAuth.js +208 -0
  81. package/core/model/api/botSyncService.js +78 -0
  82. package/core/model/api/gameRecordPayload.js +24 -0
  83. package/core/model/api/makeRequest.js +1004 -0
  84. package/core/model/api/makeRequestFnc.js +17 -0
  85. package/core/model/api/phiApiClient.js +53 -0
  86. package/core/model/api/phiApiErrors.js +121 -0
  87. package/core/model/filesystem/getFile.js +256 -0
  88. package/core/model/filesystem/path.js +84 -0
  89. package/core/model/game/Chart.js +57 -0
  90. package/core/model/game/LevelRecordInfo.js +109 -0
  91. package/core/model/game/SongsInfo.js +46 -0
  92. package/core/model/game/b30Analysis.js +93 -0
  93. package/core/model/game/chartParser/Chart.js +23 -0
  94. package/core/model/game/chartParser/JudgeLine.js +38 -0
  95. package/core/model/game/chartParser/base/JudgeLineEvent.js +99 -0
  96. package/core/model/game/chartParser/base/Note.js +44 -0
  97. package/core/model/game/chartParser/base/SpeedEvent.js +25 -0
  98. package/core/model/game/chartParser/base/baseType.js +2 -0
  99. package/core/model/game/constNum.js +215 -0
  100. package/core/model/game/fCompute.js +711 -0
  101. package/core/model/game/getChartTag.js +140 -0
  102. package/core/model/game/getComment.js +132 -0
  103. package/core/model/game/getInfo.js +1069 -0
  104. package/core/model/game/getRksRank.js +77 -0
  105. package/core/model/game/markdown.js +77 -0
  106. package/core/model/integrations/Vika.js +103 -0
  107. package/core/model/integrations/getInfoFromTap.js +80 -0
  108. package/core/model/render/getPic.js +79 -0
  109. package/core/model/render/picmodle.js +496 -0
  110. package/core/model/render/progress-bar.js +44 -0
  111. package/core/model/render/puppeteer.js +431 -0
  112. package/core/model/render/renderPressureHistory.js +71 -0
  113. package/core/model/render/send.js +94 -0
  114. package/core/model/save/Save.js +953 -0
  115. package/core/model/save/analyzeSaveHistory.js +413 -0
  116. package/core/model/save/getBackup.js +328 -0
  117. package/core/model/save/getSave.js +90 -0
  118. package/core/model/save/getSaveFromApi.js +46 -0
  119. package/core/model/save/saveHistory.js +586 -0
  120. package/core/model/save/scoreHistory.js +101 -0
  121. package/core/model/theme/catalog.js +192 -0
  122. package/core/model/theme/installGuard.js +275 -0
  123. package/core/model/theme/installLock.js +174 -0
  124. package/core/model/theme/installer.js +398 -0
  125. package/core/model/theme/manager.js +408 -0
  126. package/core/model/theme/marketClient.js +294 -0
  127. package/core/model/theme/paths.js +42 -0
  128. package/core/model/theme/policy.js +54 -0
  129. package/core/model/theme/recovery.js +167 -0
  130. package/core/model/theme/useService.js +187 -0
  131. package/core/model/type/aliasProposal.d.ts +45 -0
  132. package/core/model/type/type.js +420 -0
  133. package/core/model/user/apiPermission.js +62 -0
  134. package/core/model/user/getBanGroup.js +120 -0
  135. package/core/model/user/getNotes.js +48 -0
  136. package/core/model/user/pluginData.js +101 -0
  137. package/core/model/user/userCredentialStore.js +154 -0
  138. package/core/model/user/userCredentials.js +860 -0
  139. package/core/package.json +60 -0
  140. package/core/resources/0608badSave/save.json +1 -0
  141. package/core/resources/LICENSE +201 -0
  142. package/core/resources/html/analyzeSaveHistory/analyzeSaveHistory.art +220 -0
  143. package/core/resources/html/analyzeSaveHistory/analyzeSaveHistory.css +345 -0
  144. package/core/resources/html/analyzeSaveHistory/analyzeSaveHistory.html +434 -0
  145. package/core/resources/html/arcgrosB19/arcgros.png +0 -0
  146. package/core/resources/html/arcgrosB19/arcgrosB19-orz.html +276 -0
  147. package/core/resources/html/arcgrosB19/arcgrosB19.art +168 -0
  148. package/core/resources/html/arcgrosB19/arcgrosB19.css +637 -0
  149. package/core/resources/html/atlas/atlas-orz.html +313 -0
  150. package/core/resources/html/atlas/atlas.art +194 -0
  151. package/core/resources/html/atlas/atlas.css +695 -0
  152. package/core/resources/html/avatar/-SURREALISM-.png +0 -0
  153. package/core/resources/html/avatar/Alkaid.png +0 -0
  154. package/core/resources/html/avatar/Aphasia.png +0 -0
  155. package/core/resources/html/avatar/Artificial Existence.png +0 -0
  156. package/core/resources/html/avatar/Bonus Time.png +0 -0
  157. package/core/resources/html/avatar/Burn.png +0 -0
  158. package/core/resources/html/avatar/Cereris1.png +0 -0
  159. package/core/resources/html/avatar/Cereris2.png +0 -0
  160. package/core/resources/html/avatar/Cereris3.png +0 -0
  161. package/core/resources/html/avatar/Christmas -2019.png +0 -0
  162. package/core/resources/html/avatar/Cipher1.png +0 -0
  163. package/core/resources/html/avatar/Class Memories.png +0 -0
  164. package/core/resources/html/avatar/Credits.png +0 -0
  165. package/core/resources/html/avatar/Dash.png +0 -0
  166. package/core/resources/html/avatar/Dlyrotz.png +0 -0
  167. package/core/resources/html/avatar/Doppelganger1.png +0 -0
  168. package/core/resources/html/avatar/Doppelganger2.png +0 -0
  169. package/core/resources/html/avatar/Drop it.png +0 -0
  170. package/core/resources/html/avatar/Energy Synergy Matrix1.png +0 -0
  171. package/core/resources/html/avatar/Energy Synergy Matrix2.png +0 -0
  172. package/core/resources/html/avatar/Energy Synergy Matrix3.png +0 -0
  173. package/core/resources/html/avatar/Engine x Start!! (melody mix).png +0 -0
  174. package/core/resources/html/avatar/Engine x Start!! extra 1 -by cycats.png +0 -0
  175. package/core/resources/html/avatar/Eradication Catastrophe.png +0 -0
  176. package/core/resources/html/avatar/FULi AUTO SHOOTER extra 1 -by cycats.png +0 -0
  177. package/core/resources/html/avatar/FULi AUTO SHOOTER.png +0 -0
  178. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/264-Special1.png +0 -0
  179. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/264-Special2.png +0 -0
  180. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2641.png +0 -0
  181. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2642.png +0 -0
  182. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2643.png +0 -0
  183. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2644.png +0 -0
  184. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2645.png +0 -0
  185. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2646.png +0 -0
  186. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2647.png +0 -0
  187. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2648.png +0 -0
  188. package/core/resources/html/avatar/Feast/350/277/234/344/270/234/344/271/213/345/256/2649.png +0 -0
  189. package/core/resources/html/avatar/Find_Me.png +0 -0
  190. package/core/resources/html/avatar/Geopelia 1 -by cycats.png +0 -0
  191. package/core/resources/html/avatar/Geopelia 2 -by cycats.png +0 -0
  192. package/core/resources/html/avatar/Geopelia 3 -by /344/275/225/345/221/265.png +0 -0
  193. package/core/resources/html/avatar/Geopelia in WEPLAY -by /346/265/267/344/272/247.png +0 -0
  194. package/core/resources/html/avatar/Gino-AprilFool.png +0 -0
  195. package/core/resources/html/avatar/Glaciaxion.png +0 -0
  196. package/core/resources/html/avatar/HumaN.png +0 -0
  197. package/core/resources/html/avatar/Indelible Scar.png +0 -0
  198. package/core/resources/html/avatar/Introduction.png +0 -0
  199. package/core/resources/html/avatar/Khronostasis Katharsis.png +0 -0
  200. package/core/resources/html/avatar/MARENOL.png +0 -0
  201. package/core/resources/html/avatar/Marenol extra 1 -by /345/226/265n/350/221/265.png +0 -0
  202. package/core/resources/html/avatar/Non-Melodic Ragez (MUG Edit).png +0 -0
  203. package/core/resources/html/avatar/Non-Melodic Ragez extra 1 -by cycats.png +0 -0
  204. package/core/resources/html/avatar/Oblivion +0 -0
  205. package/core/resources/html/avatar/OblivionPHIN.png +0 -0
  206. package/core/resources/html/avatar/Para.png +0 -0
  207. package/core/resources/html/avatar/Pixel Rebelz1.png +0 -0
  208. package/core/resources/html/avatar/Pixel Rebelz2.png +0 -0
  209. package/core/resources/html/avatar/Pixel Rebelz3.png +0 -0
  210. package/core/resources/html/avatar/RIPPER extra 1 -by cycats.png +0 -0
  211. package/core/resources/html/avatar/RIPPER extra 2 -by /344/275/225/345/221/265.png +0 -0
  212. package/core/resources/html/avatar/Sein.png +0 -0
  213. package/core/resources/html/avatar/ShineAfter-/346/260/264/351/235/222-Special.png +0 -0
  214. package/core/resources/html/avatar/ShineAfter-/346/260/264/351/235/222-Special2.png +0 -0
  215. package/core/resources/html/avatar/ShineAfter-/346/260/264/351/235/222-/346/231/256/351/200/232.png +0 -0
  216. package/core/resources/html/avatar/ShineAfter-/346/260/264/351/235/222-/346/233/262/347/273/230Ver.png +0 -0
  217. package/core/resources/html/avatar/ShineAfter-/351/270/240-Special.png +0 -0
  218. package/core/resources/html/avatar/ShineAfter-/351/270/240-/346/231/256/351/200/232.png +0 -0
  219. package/core/resources/html/avatar/ShineAfter-/351/270/240-/346/233/262/347/273/230Ver.png +0 -0
  220. package/core/resources/html/avatar/ShineAfter-/351/270/240/345/222/214/346/260/264/351/235/222-Special.png +0 -0
  221. package/core/resources/html/avatar/Snow Desert.png +0 -0
  222. package/core/resources/html/avatar/Sparkle New Life.png +0 -0
  223. package/core/resources/html/avatar/Sultan Rage.png +0 -0
  224. package/core/resources/html/avatar/Winter /342/206/221cube/342/206/223.png +0 -0
  225. package/core/resources/html/avatar/Xenolith.png +0 -0
  226. package/core/resources/html/avatar/[PRAW].png +0 -0
  227. package/core/resources/html/avatar/dB doll.png +0 -0
  228. package/core/resources/html/avatar/ripper.png +0 -0
  229. package/core/resources/html/avatar//343/202/202/343/201/272/343/202/202/343/201/2721.png +0 -0
  230. package/core/resources/html/avatar//343/202/202/343/201/272/343/202/202/343/201/2722.png +0 -0
  231. package/core/resources/html/avatar//344/270/207/345/220/250/345/214/277/345/220/215/344/277/241.png +0 -0
  232. package/core/resources/html/avatar//344/272/221/345/245/263/345/255/251 extra 1 -by /345/276/241/345/235/202/346/236/234/345/255/220.png +0 -0
  233. package/core/resources/html/avatar//344/272/221/345/245/263/345/255/251.png +0 -0
  234. package/core/resources/html/avatar//345/205/211.png +0 -0
  235. package/core/resources/html/avatar//345/274/200/345/277/203/347/227/2051.png +0 -0
  236. package/core/resources/html/avatar//345/274/200/345/277/203/347/227/2052.png +0 -0
  237. package/core/resources/html/avatar//346/260/264/351/235/222-/344/270/200/345/221/250/345/271/264/347/233/270/350/201/232.png +0 -0
  238. package/core/resources/html/avatar//346/267/267/344/271/261-Confusion.png +0 -0
  239. package/core/resources/html/avatar//347/213/202/345/226/234/350/230/255/350/210/2361.png +0 -0
  240. package/core/resources/html/avatar//347/213/202/345/226/234/350/230/255/350/210/2362.png +0 -0
  241. package/core/resources/html/avatar//347/223/267/345/262/201-Special.png +0 -0
  242. package/core/resources/html/avatar//347/223/267/345/262/2011.png +0 -0
  243. package/core/resources/html/avatar//347/223/267/345/262/2012.png +0 -0
  244. package/core/resources/html/avatar//347/223/267/345/262/2013.png +0 -0
  245. package/core/resources/html/avatar//347/223/267/345/262/2014.png +0 -0
  246. package/core/resources/html/avatar//347/223/267/345/262/2015.png +0 -0
  247. package/core/resources/html/avatar//347/223/267/345/262/2016.png +0 -0
  248. package/core/resources/html/avatar//347/223/267/345/262/2017.png +0 -0
  249. package/core/resources/html/avatar//347/233/217/350/214/227-Special.png +0 -0
  250. package/core/resources/html/avatar//347/233/217/350/214/2271.png +0 -0
  251. package/core/resources/html/avatar//347/233/217/350/214/2272.png +0 -0
  252. package/core/resources/html/avatar//347/233/217/350/214/2273.png +0 -0
  253. package/core/resources/html/avatar//350/217/257/347/201/257/347/210/2611.png +0 -0
  254. package/core/resources/html/avatar//350/217/257/347/201/257/347/210/2612.png +0 -0
  255. package/core/resources/html/avatar//350/220/244/347/201/253/350/231/253/343/201/256/346/200/2501.png +0 -0
  256. package/core/resources/html/avatar//350/220/244/347/201/253/350/231/253/343/201/256/346/200/2502.png +0 -0
  257. package/core/resources/html/avatar//351/235/222/350/212/275-Special.png +0 -0
  258. package/core/resources/html/avatar//351/235/222/350/212/275.png +0 -0
  259. package/core/resources/html/avatar//351/243/216/345/261/277.png +0 -0
  260. package/core/resources/html/avatar//351/270/240-AprilFool.png +0 -0
  261. package/core/resources/html/avatar//351/270/240-/344/270/200/345/221/250/345/271/264/347/233/270/350/201/232.png +0 -0
  262. package/core/resources/html/b19/b19.art +490 -0
  263. package/core/resources/html/b19/b19.css +1261 -0
  264. package/core/resources/html/b19/b19666.art +350 -0
  265. package/core/resources/html/b19/b19666.css +1409 -0
  266. package/core/resources/html/b19/b19666.html +481 -0
  267. package/core/resources/html/b19/b19title.css +120 -0
  268. package/core/resources/html/b19/best19.html +853 -0
  269. package/core/resources/html/b19/dss2-orz.html +428 -0
  270. package/core/resources/html/b19/dss2.art +298 -0
  271. package/core/resources/html/b19/dss2.css +776 -0
  272. package/core/resources/html/b19/res/666.jpeg +0 -0
  273. package/core/resources/html/chap/chap-orz.html +93 -0
  274. package/core/resources/html/chap/chap.art +87 -0
  275. package/core/resources/html/chap/chap.css +365 -0
  276. package/core/resources/html/chartImg/chartImg.art +169 -0
  277. package/core/resources/html/chartImg/chartImg.css +439 -0
  278. package/core/resources/html/chartImg/echarts-wordcloud.min.js +3 -0
  279. package/core/resources/html/chartImg/echarts.js +85796 -0
  280. package/core/resources/html/chartImg/img/Drag.png +0 -0
  281. package/core/resources/html/chartImg/img/DragHL.png +0 -0
  282. package/core/resources/html/chartImg/img/Flick.png +0 -0
  283. package/core/resources/html/chartImg/img/FlickHL.png +0 -0
  284. package/core/resources/html/chartImg/img/Hold.png +0 -0
  285. package/core/resources/html/chartImg/img/HoldHL.png +0 -0
  286. package/core/resources/html/chartImg/img/Hold_End.png +0 -0
  287. package/core/resources/html/chartImg/img/Hold_Head.png +0 -0
  288. package/core/resources/html/chartImg/img/Hold_HeadHL.png +0 -0
  289. package/core/resources/html/chartImg/img/Tap.png +0 -0
  290. package/core/resources/html/chartImg/img/TapHL.png +0 -0
  291. package/core/resources/html/chartInfo/chartInfo-orz.html +250 -0
  292. package/core/resources/html/chartInfo/chartInfo.art +222 -0
  293. package/core/resources/html/chartInfo/chartInfo.css +265 -0
  294. package/core/resources/html/chartInfo/echarts-wordcloud.min.js +3 -0
  295. package/core/resources/html/chartInfo/echarts.js +85796 -0
  296. package/core/resources/html/clg/clg-orz.html +218 -0
  297. package/core/resources/html/clg/clg.art +88 -0
  298. package/core/resources/html/clg/clg.css +230 -0
  299. package/core/resources/html/clg/demo.jpg +0 -0
  300. package/core/resources/html/common/common.css +319 -0
  301. package/core/resources/html/common/css/playerInfo.css +136 -0
  302. package/core/resources/html/common/font/Aldrich-Regular.ttf +0 -0
  303. package/core/resources/html/common/font/HIMALAYA.TTF +0 -0
  304. package/core/resources/html/common/font/NotoColorEmoji-Regular.ttf +0 -0
  305. package/core/resources/html/common/font/NotoSans-Regular.ttf +0 -0
  306. package/core/resources/html/common/font/NotoSansArabic.ttf +0 -0
  307. package/core/resources/html/common/font/NotoSansCanadianAboriginal.ttf +0 -0
  308. package/core/resources/html/common/font/NotoSansJP.ttf +0 -0
  309. package/core/resources/html/common/font/NotoSansKannada.ttf +0 -0
  310. package/core/resources/html/common/font/NotoSansMath-Regular.ttf +0 -0
  311. package/core/resources/html/common/font/NotoSansSymbols2.ttf +0 -0
  312. package/core/resources/html/common/font/phi.ttf +0 -0
  313. package/core/resources/html/common/font//345/220/236/345/274/245/346/201/260/344/277/212.ttf +0 -0
  314. package/core/resources/html/common/layout/default.art +324 -0
  315. package/core/resources/html/common/layout/elem.art +21 -0
  316. package/core/resources/html/common/theme/snow/snow.css +17 -0
  317. package/core/resources/html/common/theme/snow/snow.js +19 -0
  318. package/core/resources/html/common/theme/star/star.js +201 -0
  319. package/core/resources/html/common/theme/topText/topText.css +15 -0
  320. package/core/resources/html/common/theme/topText/topText.js +30 -0
  321. package/core/resources/html/difficultyHistory/difficultyHistory-orz.html +361 -0
  322. package/core/resources/html/difficultyHistory/difficultyHistory.art +102 -0
  323. package/core/resources/html/difficultyHistory/difficultyHistory.css +205 -0
  324. package/core/resources/html/guess/guess-orz.html +50 -0
  325. package/core/resources/html/guess/guess.art +51 -0
  326. package/core/resources/html/guess/guess.css +33 -0
  327. package/core/resources/html/help/help-orz.html +73 -0
  328. package/core/resources/html/help/help.art +84 -0
  329. package/core/resources/html/help/help.css +266 -0
  330. package/core/resources/html/historyB30/historyB30-orz.html +168 -0
  331. package/core/resources/html/historyB30/historyB30.art +143 -0
  332. package/core/resources/html/historyB30/historyB30.css +270 -0
  333. package/core/resources/html/ill/ill-orz.html +21 -0
  334. package/core/resources/html/ill/ill.art +23 -0
  335. package/core/resources/html/ill/ill.css +79 -0
  336. package/core/resources/html/jrrp/ShineAfter.removebg.png +0 -0
  337. package/core/resources/html/jrrp/jrrp-orz.html +68 -0
  338. package/core/resources/html/jrrp/jrrp.art +58 -0
  339. package/core/resources/html/jrrp/jrrp.css +251 -0
  340. package/core/resources/html/list/list-orz.html +35 -0
  341. package/core/resources/html/list/list.art +67 -0
  342. package/core/resources/html/list/list.css +259 -0
  343. package/core/resources/html/lvsco/demo.jpg +0 -0
  344. package/core/resources/html/lvsco/lvsco-orz.html +334 -0
  345. package/core/resources/html/lvsco/lvsco.art +314 -0
  346. package/core/resources/html/lvsco/lvsco.css +706 -0
  347. package/core/resources/html/market/detail.art +44 -0
  348. package/core/resources/html/market/market.art +86 -0
  349. package/core/resources/html/market/market.css +64 -0
  350. package/core/resources/html/newSong/newSong.art +34 -0
  351. package/core/resources/html/newSong/newSong.css +48 -0
  352. package/core/resources/html/newSong/newSong.html +23 -0
  353. package/core/resources/html/newnotice/newnotice.art +47 -0
  354. package/core/resources/html/newnotice/newnotice.css +83 -0
  355. package/core/resources/html/otherimg/0.png +0 -0
  356. package/core/resources/html/otherimg/1.png +0 -0
  357. package/core/resources/html/otherimg/2.png +0 -0
  358. package/core/resources/html/otherimg/3.png +0 -0
  359. package/core/resources/html/otherimg/4.png +0 -0
  360. package/core/resources/html/otherimg/5.png +0 -0
  361. package/core/resources/html/otherimg/A.png +0 -0
  362. package/core/resources/html/otherimg/B.png +0 -0
  363. package/core/resources/html/otherimg/C.png +0 -0
  364. package/core/resources/html/otherimg/F.png +0 -0
  365. package/core/resources/html/otherimg/FC.png +0 -0
  366. package/core/resources/html/otherimg/NEW.png +0 -0
  367. package/core/resources/html/otherimg/Phigros_Icon_3.0.0.png +0 -0
  368. package/core/resources/html/otherimg/S.png +0 -0
  369. package/core/resources/html/otherimg/Star1.png +0 -0
  370. package/core/resources/html/otherimg/Star2.png +0 -0
  371. package/core/resources/html/otherimg/V.png +0 -0
  372. package/core/resources/html/otherimg/callback.png +0 -0
  373. package/core/resources/html/otherimg/chapHelp.png +0 -0
  374. package/core/resources/html/otherimg/dan_code.png +0 -0
  375. package/core/resources/html/otherimg/data.png +0 -0
  376. package/core/resources/html/otherimg/helpDoc.png +0 -0
  377. package/core/resources/html/otherimg/nickSuggest.png +0 -0
  378. package/core/resources/html/otherimg/phi.png +0 -0
  379. package/core/resources/html/otherimg/phigros.png +0 -0
  380. package/core/resources/html/otherimg/snow1.png +0 -0
  381. package/core/resources/html/otherimg/snow2.png +0 -0
  382. package/core/resources/html/otherimg/snow3.png +0 -0
  383. package/core/resources/html/otherimg/snow4.png +0 -0
  384. package/core/resources/html/otherimg/title.png +0 -0
  385. package/core/resources/html/rand/rand-orz.html +62 -0
  386. package/core/resources/html/rand/rand.art +59 -0
  387. package/core/resources/html/rand/rand.css +257 -0
  388. package/core/resources/html/rankingList/rankingList-orz.html +456 -0
  389. package/core/resources/html/rankingList/rankingList.art +171 -0
  390. package/core/resources/html/rankingList/rankingList.css +570 -0
  391. package/core/resources/html/rankingList-old/rankingList-orz.html +300 -0
  392. package/core/resources/html/rankingList-old/rankingList.art +89 -0
  393. package/core/resources/html/rankingList-old/rankingList.css +265 -0
  394. package/core/resources/html/score/score-orz.html +625 -0
  395. package/core/resources/html/score/score.art +249 -0
  396. package/core/resources/html/score/score.css +435 -0
  397. package/core/resources/html/score/scoreOld-orz.html +128 -0
  398. package/core/resources/html/score/scoreOld.art +230 -0
  399. package/core/resources/html/score/scoreOld.css +475 -0
  400. package/core/resources/html/score/scoreRankList-orz.html +613 -0
  401. package/core/resources/html/score/scoreRankList.art +231 -0
  402. package/core/resources/html/score/scoreRankList.css +197 -0
  403. package/core/resources/html/setting/setting-orz.html +123 -0
  404. package/core/resources/html/setting/setting.art +72 -0
  405. package/core/resources/html/setting/setting.css +170 -0
  406. package/core/resources/html/setting/userSetting-orz.html +132 -0
  407. package/core/resources/html/setting/userSetting.art +48 -0
  408. package/core/resources/html/setting/userSetting.css +160 -0
  409. package/core/resources/html/sign/sign-orz.html +262 -0
  410. package/core/resources/html/sign/sign.art +163 -0
  411. package/core/resources/html/sign/sign.css +706 -0
  412. package/core/resources/html/suggest/suggest.art +271 -0
  413. package/core/resources/html/suggest/suggest.css +300 -0
  414. package/core/resources/html/table/table-orz.html +228 -0
  415. package/core/resources/html/table/table.art +163 -0
  416. package/core/resources/html/table/table.css +401 -0
  417. package/core/resources/html/tasks/tasks-orz.html +83 -0
  418. package/core/resources/html/tasks/tasks.art +118 -0
  419. package/core/resources/html/tasks/tasks.css +334 -0
  420. package/core/resources/html/update/update-orz.html +735 -0
  421. package/core/resources/html/update/update.art +259 -0
  422. package/core/resources/html/update/update.css +676 -0
  423. package/core/resources/html/userinfo/userinfo-old-orz.html +408 -0
  424. package/core/resources/html/userinfo/userinfo-old.art +233 -0
  425. package/core/resources/html/userinfo/userinfo-old.css +466 -0
  426. package/core/resources/html/userinfo/userinfo-orz.html +543 -0
  427. package/core/resources/html/userinfo/userinfo.art +288 -0
  428. package/core/resources/html/userinfo/userinfo.css +757 -0
  429. package/core/resources/info/DLC/arc.json +412 -0
  430. package/core/resources/info/DLC/chunithm.json +1172 -0
  431. package/core/resources/info/DLC/dynamix.json +455 -0
  432. package/core/resources/info/DLC/fanshi.json +132 -0
  433. package/core/resources/info/DLC/lanota.json +412 -0
  434. package/core/resources/info/DLC/maimai.json +1110 -0
  435. package/core/resources/info/DLC/orz.json +158 -0
  436. package/core/resources/info/DLC/rizline.json +40 -0
  437. package/core/resources/info/DLC/rotaeno.json +159 -0
  438. package/core/resources/info/DLC/ryceam.json +53 -0
  439. package/core/resources/info/avatar.txt +109 -0
  440. package/core/resources/info/chaplist.yaml +102 -0
  441. package/core/resources/info/help/api.json +83 -0
  442. package/core/resources/info/help.json +436 -0
  443. package/core/resources/info/info.csv +315 -0
  444. package/core/resources/info/infolist.json +1758 -0
  445. package/core/resources/info/jrrp.json +92 -0
  446. package/core/resources/info/nicklist.yaml +2373 -0
  447. package/core/resources/info/notesInfo.json +1 -0
  448. package/core/resources/info/notice.json +11 -0
  449. package/core/resources/info/oldInfo/100/change.csv +218 -0
  450. package/core/resources/info/oldInfo/100/info.json +7 -0
  451. package/core/resources/info/oldInfo/101/change.csv +218 -0
  452. package/core/resources/info/oldInfo/101/info.json +7 -0
  453. package/core/resources/info/oldInfo/102/change.csv +223 -0
  454. package/core/resources/info/oldInfo/102/info.json +7 -0
  455. package/core/resources/info/oldInfo/103/change.csv +224 -0
  456. package/core/resources/info/oldInfo/103/info.json +7 -0
  457. package/core/resources/info/oldInfo/104/change.csv +225 -0
  458. package/core/resources/info/oldInfo/104/info.json +7 -0
  459. package/core/resources/info/oldInfo/105/change.csv +228 -0
  460. package/core/resources/info/oldInfo/105/info.json +7 -0
  461. package/core/resources/info/oldInfo/106/change.csv +229 -0
  462. package/core/resources/info/oldInfo/106/info.json +7 -0
  463. package/core/resources/info/oldInfo/108/change.csv +233 -0
  464. package/core/resources/info/oldInfo/108/info.json +7 -0
  465. package/core/resources/info/oldInfo/109/change.csv +235 -0
  466. package/core/resources/info/oldInfo/109/info.json +7 -0
  467. package/core/resources/info/oldInfo/110/change.csv +235 -0
  468. package/core/resources/info/oldInfo/110/info.json +7 -0
  469. package/core/resources/info/oldInfo/111/change.csv +242 -0
  470. package/core/resources/info/oldInfo/111/info.json +7 -0
  471. package/core/resources/info/oldInfo/112/change.csv +242 -0
  472. package/core/resources/info/oldInfo/112/info.json +7 -0
  473. package/core/resources/info/oldInfo/113/change.csv +244 -0
  474. package/core/resources/info/oldInfo/113/info.json +7 -0
  475. package/core/resources/info/oldInfo/115/change.csv +247 -0
  476. package/core/resources/info/oldInfo/115/info.json +7 -0
  477. package/core/resources/info/oldInfo/116/change.csv +249 -0
  478. package/core/resources/info/oldInfo/116/info.json +7 -0
  479. package/core/resources/info/oldInfo/118/change.csv +252 -0
  480. package/core/resources/info/oldInfo/118/info.json +7 -0
  481. package/core/resources/info/oldInfo/119/change.csv +255 -0
  482. package/core/resources/info/oldInfo/119/info.json +7 -0
  483. package/core/resources/info/oldInfo/120/change.csv +255 -0
  484. package/core/resources/info/oldInfo/120/info.json +7 -0
  485. package/core/resources/info/oldInfo/121/change.csv +257 -0
  486. package/core/resources/info/oldInfo/121/info.json +7 -0
  487. package/core/resources/info/oldInfo/122/change.csv +260 -0
  488. package/core/resources/info/oldInfo/122/info.json +7 -0
  489. package/core/resources/info/oldInfo/123/change.csv +260 -0
  490. package/core/resources/info/oldInfo/123/info.json +7 -0
  491. package/core/resources/info/oldInfo/124/change.csv +262 -0
  492. package/core/resources/info/oldInfo/124/info.json +7 -0
  493. package/core/resources/info/oldInfo/125/change.csv +266 -0
  494. package/core/resources/info/oldInfo/125/info.json +7 -0
  495. package/core/resources/info/oldInfo/126/change.csv +269 -0
  496. package/core/resources/info/oldInfo/126/info.json +7 -0
  497. package/core/resources/info/oldInfo/127/change.csv +270 -0
  498. package/core/resources/info/oldInfo/127/info.json +7 -0
  499. package/core/resources/info/oldInfo/128/change.csv +273 -0
  500. package/core/resources/info/oldInfo/128/info.json +7 -0
  501. package/core/resources/info/oldInfo/129/change.csv +274 -0
  502. package/core/resources/info/oldInfo/129/info.json +7 -0
  503. package/core/resources/info/oldInfo/130/change.csv +275 -0
  504. package/core/resources/info/oldInfo/130/info.json +7 -0
  505. package/core/resources/info/oldInfo/131/change.csv +278 -0
  506. package/core/resources/info/oldInfo/131/info.json +7 -0
  507. package/core/resources/info/oldInfo/132/change.csv +280 -0
  508. package/core/resources/info/oldInfo/132/info.json +7 -0
  509. package/core/resources/info/oldInfo/133/change.csv +284 -0
  510. package/core/resources/info/oldInfo/133/info.json +7 -0
  511. package/core/resources/info/oldInfo/134/change.csv +286 -0
  512. package/core/resources/info/oldInfo/134/info.json +7 -0
  513. package/core/resources/info/oldInfo/135/change.csv +290 -0
  514. package/core/resources/info/oldInfo/135/info.json +7 -0
  515. package/core/resources/info/oldInfo/136/change.csv +290 -0
  516. package/core/resources/info/oldInfo/136/info.json +7 -0
  517. package/core/resources/info/oldInfo/137/change.csv +293 -0
  518. package/core/resources/info/oldInfo/137/info.json +7 -0
  519. package/core/resources/info/oldInfo/138/change.csv +295 -0
  520. package/core/resources/info/oldInfo/138/info.json +7 -0
  521. package/core/resources/info/oldInfo/139/change.csv +295 -0
  522. package/core/resources/info/oldInfo/139/info.json +7 -0
  523. package/core/resources/info/oldInfo/140/change.csv +298 -0
  524. package/core/resources/info/oldInfo/140/info.json +7 -0
  525. package/core/resources/info/oldInfo/141/change.csv +300 -0
  526. package/core/resources/info/oldInfo/141/info.json +7 -0
  527. package/core/resources/info/oldInfo/142/change.csv +302 -0
  528. package/core/resources/info/oldInfo/142/info.json +7 -0
  529. package/core/resources/info/oldInfo/143/change.csv +303 -0
  530. package/core/resources/info/oldInfo/143/info.json +7 -0
  531. package/core/resources/info/oldInfo/144/change.csv +303 -0
  532. package/core/resources/info/oldInfo/144/info.json +7 -0
  533. package/core/resources/info/oldInfo/145/change.csv +305 -0
  534. package/core/resources/info/oldInfo/145/info.json +7 -0
  535. package/core/resources/info/oldInfo/146/change.csv +305 -0
  536. package/core/resources/info/oldInfo/146/info.json +7 -0
  537. package/core/resources/info/oldInfo/148/change.csv +307 -0
  538. package/core/resources/info/oldInfo/148/info.json +7 -0
  539. package/core/resources/info/oldInfo/149/change.csv +307 -0
  540. package/core/resources/info/oldInfo/149/info.json +7 -0
  541. package/core/resources/info/oldInfo/151/change.csv +309 -0
  542. package/core/resources/info/oldInfo/151/info.json +7 -0
  543. package/core/resources/info/oldInfo/152/change.csv +312 -0
  544. package/core/resources/info/oldInfo/152/info.json +7 -0
  545. package/core/resources/info/oldInfo/153/change.csv +313 -0
  546. package/core/resources/info/oldInfo/153/info.json +7 -0
  547. package/core/resources/info/oldInfo/154/change.csv +315 -0
  548. package/core/resources/info/oldInfo/154/info.json +7 -0
  549. package/core/resources/info/oldInfo/92/change.csv +204 -0
  550. package/core/resources/info/oldInfo/92/info.json +7 -0
  551. package/core/resources/info/oldInfo/93/change.csv +206 -0
  552. package/core/resources/info/oldInfo/93/info.json +7 -0
  553. package/core/resources/info/oldInfo/94/change.csv +209 -0
  554. package/core/resources/info/oldInfo/94/info.json +7 -0
  555. package/core/resources/info/oldInfo/95/change.csv +211 -0
  556. package/core/resources/info/oldInfo/95/info.json +7 -0
  557. package/core/resources/info/oldInfo/96/change.csv +216 -0
  558. package/core/resources/info/oldInfo/96/info.json +7 -0
  559. package/core/resources/info/oldInfo/98/change.csv +216 -0
  560. package/core/resources/info/oldInfo/98/info.json +7 -0
  561. package/core/resources/info/oldInfo/99/change.csv +217 -0
  562. package/core/resources/info/oldInfo/99/info.json +7 -0
  563. package/core/resources/info/oldNotesInfo.json +1 -0
  564. package/core/resources/info/sentences.json +1 -0
  565. package/core/resources/info/spinfo.json +362 -0
  566. package/core/resources/info/tips.txt +278 -0
  567. package/core/resources/otherill//351/233/252/351/231/215SP.png +0 -0
  568. package/core/resources/song-select.html +535 -0
  569. package/core/resources/themes/README.md +24 -0
  570. package/core/resources/themes/milthm/A.png +0 -0
  571. package/core/resources/themes/milthm/B.png +0 -0
  572. package/core/resources/themes/milthm/C.png +0 -0
  573. package/core/resources/themes/milthm/F.png +0 -0
  574. package/core/resources/themes/milthm/FC.png +0 -0
  575. package/core/resources/themes/milthm/S.png +0 -0
  576. package/core/resources/themes/milthm/V.png +0 -0
  577. package/core/resources/themes/milthm/arcgrosB19.css +36 -0
  578. package/core/resources/themes/milthm/b19.art +464 -0
  579. package/core/resources/themes/milthm/b19.css +1314 -0
  580. package/core/resources/themes/milthm/bg.png +0 -0
  581. package/core/resources/themes/milthm/clg.css +37 -0
  582. package/core/resources/themes/milthm/difficultyHistory.css +42 -0
  583. package/core/resources/themes/milthm/font.ttf +0 -0
  584. package/core/resources/themes/milthm/help.css +36 -0
  585. package/core/resources/themes/milthm/historyB30.css +48 -0
  586. package/core/resources/themes/milthm/info.yaml +45 -0
  587. package/core/resources/themes/milthm/list.css +39 -0
  588. package/core/resources/themes/milthm/phi.png +0 -0
  589. package/core/resources/themes/milthm/setting.css +37 -0
  590. package/core/resources/themes/milthm/sign.css +81 -0
  591. package/core/resources/themes/milthm/suggest.css +40 -0
  592. package/core/resources/themes/milthm/table.css +54 -0
  593. package/core/resources/themes/milthm/update.css +68 -0
  594. package/core/tests/aliasProposalService.test.js +82 -0
  595. package/core/tests/apiAccountDeletion.test.js +125 -0
  596. package/core/tests/apiPermission.test.js +44 -0
  597. package/core/tests/apiVersion.test.js +55 -0
  598. package/core/tests/b30Analysis.test.js +38 -0
  599. package/core/tests/backgroundIllustration.test.js +21 -0
  600. package/core/tests/botApiAuthRecovery.test.js +148 -0
  601. package/core/tests/botSyncService.test.js +42 -0
  602. package/core/tests/fileWatcherRegistry.test.js +44 -0
  603. package/core/tests/gameRecordPayload.test.js +34 -0
  604. package/core/tests/guessLetter.test.js +79 -0
  605. package/core/tests/makeRequestHandling.test.js +118 -0
  606. package/core/tests/marketOverflow.test.js +31 -0
  607. package/core/tests/platformTemplateCache.test.js +92 -0
  608. package/core/tests/pluginDataThemePreference.test.js +36 -0
  609. package/core/tests/processCleanup.test.js +58 -0
  610. package/core/tests/puppeteerShutdown.test.js +17 -0
  611. package/core/tests/renderPressureHistory.test.js +59 -0
  612. package/core/tests/saveStats.test.js +26 -0
  613. package/core/tests/themeInstallGuard.test.js +289 -0
  614. package/core/tests/themeManager.test.js +625 -0
  615. package/core/tests/themeManagerInit.test.js +11 -0
  616. package/core/tests/themeMarket.test.js +855 -0
  617. package/core/tests/themePageRouting.test.js +431 -0
  618. package/core/tests/themePolicy.test.js +28 -0
  619. package/core/tests/themeStorageRecovery.test.js +192 -0
  620. package/core/tests/userCredentialModuleBoundaries.test.js +41 -0
  621. package/core/tests/userCredentials.test.js +285 -0
  622. package/core/tsconfig.json +32 -0
  623. package/core/types/vendor.d.ts +14 -0
  624. package/lib/index.cjs +358 -0
  625. package/lib/index.d.cts +182 -0
  626. package/lib/index.d.ts +182 -0
  627. package/lib/index.js +320 -0
  628. package/package.json +74 -0
  629. package/readme.md +3 -0
@@ -0,0 +1,187 @@
1
+ import crypto from 'node:crypto'
2
+ import Config from '../../components/Config.js'
3
+ import themeManager from './manager.js'
4
+ import themePolicy from './policy.js'
5
+ import {
6
+ authorizeThemeDownload,
7
+ downloadThemeArchive,
8
+ getAvailableMarketTheme,
9
+ ThemeMarketClientError,
10
+ } from './marketClient.js'
11
+ import {
12
+ installMarketArchive,
13
+ isMarketThemeCached,
14
+ marketWorkPath,
15
+ assertMarketInstallTarget,
16
+ recoverAllMarketInstalls,
17
+ recoverMarketInstall,
18
+ withMarketInstallLock,
19
+ } from './installer.js'
20
+ import { getPhiApiUserMessage, hasPhiApiUserMessage, isApiConnectionError } from '../api/phiApiErrors.js'
21
+ import {
22
+ assertFreshMarketInstallCapacity,
23
+ freshInstallRateLimiter,
24
+ marketInstallCoordinator,
25
+ } from './installGuard.js'
26
+ import { isApiCapabilityConfigured } from '../user/apiPermission.js'
27
+
28
+ const SLUG_RE = /^[a-z][a-z0-9_-]{0,119}$/
29
+
30
+ /** @param {string} themeId */
31
+ async function waitForThemeRegistration(themeId) {
32
+ themeManager.scan()
33
+ for (let attempt = 0; attempt < 20; attempt++) {
34
+ const theme = themeManager.getTheme(themeId)
35
+ if (theme?.marketInstalled) return theme
36
+ await new Promise(resolve => setTimeout(resolve, 50))
37
+ }
38
+ throw new ThemeMarketClientError('theme_registry_refresh_failed')
39
+ }
40
+
41
+ /**
42
+ * Authorize and install the latest compatible release. The authorization is
43
+ * still required on a cache hit so revoked Bot/theme access cannot be bypassed.
44
+ * @param {string} themeId
45
+ * @param {{requesterId?:string}} [options]
46
+ */
47
+ export function installLatestMarketTheme(themeId, options = {}) {
48
+ return marketInstallCoordinator.schedule(themeId, () => withMarketInstallLock(async () => {
49
+ const recoveryFailures = await recoverAllMarketInstalls()
50
+ if (recoveryFailures.length) throw new ThemeMarketClientError('theme_install_recovery_failed')
51
+ await recoverMarketInstall(themeId)
52
+ await assertMarketInstallTarget(themeId)
53
+ let freshInstallPrepared = false
54
+ for (let authorizationCycle = 0; authorizationCycle < 2; authorizationCycle++) {
55
+ const requestId = crypto.randomUUID()
56
+ const download = await authorizeThemeDownload(themeId, requestId)
57
+ if (await isMarketThemeCached(themeId, download)) {
58
+ const theme = await waitForThemeRegistration(themeId)
59
+ return { cached: true, version: download.version, theme }
60
+ }
61
+
62
+ if (!freshInstallPrepared) {
63
+ const capacity = await assertFreshMarketInstallCapacity(themeId)
64
+ if (capacity.fresh) await freshInstallRateLimiter.consume(String(options.requesterId || ''))
65
+ freshInstallPrepared = true
66
+ }
67
+
68
+ const archivePath = marketWorkPath(`download-${themeId}-${requestId}.zip`)
69
+ try {
70
+ await downloadThemeArchive(download, archivePath)
71
+ await installMarketArchive(themeId, download, archivePath)
72
+ const theme = await waitForThemeRegistration(themeId)
73
+ return { cached: false, version: download.version, theme }
74
+ } catch (error) {
75
+ if (/** @type {any} */ (error)?.code === 'theme_download_url_expired' && authorizationCycle === 0) continue
76
+ throw error
77
+ }
78
+ }
79
+ throw new ThemeMarketClientError('theme_download_url_expired')
80
+ }))
81
+ }
82
+
83
+ export class ThemeUseService {
84
+ /**
85
+ * @param {{getTheme?:typeof getAvailableMarketTheme, install?:typeof installLatestMarketTheme, marketEnabled?:()=>boolean}} [dependencies]
86
+ */
87
+ constructor(dependencies = {}) {
88
+ this.getTheme = dependencies.getTheme || getAvailableMarketTheme
89
+ this.install = dependencies.install || installLatestMarketTheme
90
+ this.marketEnabled = dependencies.marketEnabled
91
+ || (() => isApiCapabilityConfigured('customTheme'))
92
+ }
93
+
94
+ /** @param {any} theme @param {any} [detail] */
95
+ cachedMarketTheme(theme, detail = null) {
96
+ return {
97
+ cached: true,
98
+ local: false,
99
+ offline: true,
100
+ version: theme.marketVersion || '',
101
+ theme,
102
+ detail,
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Use a local theme offline, or validate and update a market-installed theme online.
108
+ * @param {string} themeId
109
+ * @param {{requesterId?:string}} [options]
110
+ */
111
+ async use(themeId, options = {}) {
112
+ const localTheme = themeManager.getTheme(themeId)
113
+ if (localTheme && themeManager.isCustomTheme(themeId)) {
114
+ if (!themeManager.isThemeAvailable(themeId)) {
115
+ throw new ThemeMarketClientError('theme_not_allowed_by_bot', 403)
116
+ }
117
+ if (!localTheme.marketInstalled) {
118
+ return {
119
+ cached: true,
120
+ local: true,
121
+ offline: true,
122
+ version: '',
123
+ theme: localTheme,
124
+ detail: null,
125
+ }
126
+ }
127
+ if (!SLUG_RE.test(themeId)) throw new ThemeMarketClientError('theme_slug_invalid', 400)
128
+ if (!this.marketEnabled()) return this.cachedMarketTheme(localTheme)
129
+ }
130
+ if (!SLUG_RE.test(themeId)) throw new ThemeMarketClientError('theme_slug_invalid', 400)
131
+ // 市场策略同样约束首次下载:本地尚未安装的 slug 也必须先通过 Bot 黑/白名单,
132
+ // 否则被拉黑的主题仍可触发下载并占用配额。
133
+ if (!themePolicy.isAllowed(themeId)) {
134
+ throw new ThemeMarketClientError('theme_not_allowed_by_bot', 403)
135
+ }
136
+ if (!this.marketEnabled()) {
137
+ throw new ThemeMarketClientError('custom_theme_api_disabled', 403)
138
+ }
139
+ let detail
140
+ try {
141
+ detail = await this.getTheme(themeId)
142
+ } catch (error) {
143
+ if (localTheme?.marketInstalled && isApiConnectionError(error)) {
144
+ return this.cachedMarketTheme(localTheme)
145
+ }
146
+ throw error
147
+ }
148
+ try {
149
+ const result = await this.install(themeId, options)
150
+ return { ...result, local: false, offline: false, detail }
151
+ } catch (error) {
152
+ if (localTheme?.marketInstalled && isApiConnectionError(error)) {
153
+ return this.cachedMarketTheme(localTheme, detail)
154
+ }
155
+ throw error
156
+ }
157
+ }
158
+ }
159
+
160
+ /** @param {any} error */
161
+ export function marketThemeErrorMessage(error) {
162
+ if (hasPhiApiUserMessage(error)) return getPhiApiUserMessage(error)
163
+ /** @type {Record<string, string>} */
164
+ const local = {
165
+ theme_slug_invalid: '主题 slug 格式无效。',
166
+ theme_market_origin_invalid: '主题市场下载来源配置无效,请联系 Bot 主人。',
167
+ theme_download_url_expired: '主题下载链接已失效,请稍后重试。',
168
+ theme_download_url_untrusted: '主题商店返回了不受信任的下载地址。',
169
+ theme_download_unavailable: '主题包暂时无法下载,请稍后重试。',
170
+ theme_package_integrity_failed: '主题包完整性校验失败,已停止安装。',
171
+ theme_package_reserved_id: '该主题 ID 与插件内置主题冲突,无法安装。',
172
+ theme_conflicts_with_local_theme: '同名本地主题不是市场安装版本,已拒绝覆盖。',
173
+ theme_not_allowed_by_bot: 'Bot 主人的主题策略不允许使用该主题。',
174
+ theme_install_busy: '主题安装队列繁忙,请稍后重试。',
175
+ theme_install_queue_full: '当前等待安装的主题过多,请稍后再试。',
176
+ theme_install_rate_limited: '你在一小时内安装的新主题过多,请稍后再试。',
177
+ theme_install_count_quota_exceeded: '此 Bot 已安装的市场主题数量达到上限,请联系 Bot 主人清理后再试。',
178
+ theme_install_disk_quota_exceeded: '此 Bot 的市场主题存储空间已达到上限,请联系 Bot 主人清理后再试。',
179
+ theme_install_recovery_failed: '主题安装恢复未完成,请联系 Bot 主人检查主题目录后再试。',
180
+ theme_install_rate_state_invalid: '主题安装限频状态异常,请联系 Bot 主人检查主题目录。',
181
+ theme_registry_refresh_failed: '主题已写入,但注册表刷新失败,请联系 Bot 主人检查。',
182
+ custom_theme_api_disabled: 'Bot 主人已关闭自定义主题功能。',
183
+ }
184
+ return local[String(error?.code || '')] || '主题下载或启用失败,请稍后重试。'
185
+ }
186
+
187
+ export default new ThemeUseService()
@@ -0,0 +1,45 @@
1
+ import type { PlatformEvent, PlatformUserId } from '../../components/platform/types.js'
2
+
3
+ export type AliasProposalStatus =
4
+ | 'submitted'
5
+ | 'rejected_private'
6
+ | 'public_review_requested'
7
+ | 'public_voting'
8
+ | 'vote_passed'
9
+ | 'approved'
10
+ | 'public_review_denied'
11
+ | 'rejected_final'
12
+
13
+ export type AliasVoteValue = 1 | -1 | 0
14
+
15
+ export interface AliasProposalRecord {
16
+ id: string
17
+ alias: string
18
+ songId: string
19
+ status: AliasProposalStatus
20
+ source?: 'web' | 'bot'
21
+ note?: string | null
22
+ createdAt: string
23
+ updatedAt: string
24
+ votingStartedAt?: string | null
25
+ votingEndsAt?: string | null
26
+ resolvedAt?: string | null
27
+ votesUp: number
28
+ votesDown: number
29
+ voteScore: number
30
+ myVote?: 1 | -1 | null
31
+ publicReviewReason?: string | null
32
+ publicReviewStatus?: 'pending' | 'allowed' | 'denied' | null
33
+ publicReviewDecisionNote?: string | null
34
+ }
35
+
36
+ export interface AliasProposalCreateInput {
37
+ songId: string
38
+ alias: string
39
+ note?: string
40
+ }
41
+
42
+ export type AliasBotEvent = PlatformEvent & {
43
+ user_id: PlatformUserId
44
+ self_id?: PlatformUserId
45
+ }
@@ -0,0 +1,420 @@
1
+ /**
2
+ * @typedef {string & { readonly brand: unique symbol }} idString 曲目id
3
+ * @typedef {string & { readonly brand: unique symbol }} idStringWithout0 曲目id
4
+ * @typedef {string & { readonly brand: unique symbol }} songString 曲目名称
5
+ * @typedef {string & { readonly brand: unique symbol }} chartsTagString 谱面标签
6
+ * @typedef {'category' | 'detail'} chartsTagNodeKind 谱面标签节点类型,category 为分类标签,detail 为细分标签
7
+ * @typedef {'primary' | 'secondary'} chartsTagVoteKind 谱面标签投票类型,primary 为主要票,secondary 为次要票
8
+ * @typedef {string & { readonly brand: unique symbol }} phigrosToken phigrosToken
9
+ * @typedef {string & { readonly brand: unique symbol }} apiToken apiToken
10
+ * @typedef {string & { readonly brand: unique symbol }} apiUserId apiId
11
+ * @typedef {string & { readonly brand: unique symbol }} phigrosObjectId phigrosObjectId
12
+ * @typedef {'EZ' | 'HD' | 'IN' | 'AT'} levelKind 有效难度分级
13
+ * @typedef {'EZ' | 'HD' | 'IN' | 'AT' | 'LEGACY'} allLevelKind 全部难度分级
14
+ * @typedef {'tap' | 'drag' | 'hold' | 'flick'} noteKind note分类
15
+ * @typedef { "NEW" | "F" | "C" | "B" | "A" | "S" | "V" | "FC" | "phi" } ratingKind
16
+ **/
17
+
18
+ /**
19
+ * @typedef {'help'
20
+ * | 'tkhelp'
21
+ * | 'bind'
22
+ * | 'unbind'
23
+ * | 'b19'
24
+ * | 'p30'
25
+ * | 'lmtAcc'
26
+ * | 'arcgrosB19'
27
+ * | 'update'
28
+ * | 'info'
29
+ * | 'list'
30
+ * | 'singlescore'
31
+ * | 'lvscore'
32
+ * | 'chap'
33
+ * | 'achievement'
34
+ * | 'suggest'
35
+ * | 'analyze2025SaveHistory'
36
+ * | 'hisb30'
37
+ * | 'bestn'
38
+ * | 'data'
39
+ * | 'song'
40
+ * | 'ill'
41
+ * | 'chart'
42
+ * | 'tag'
43
+ * | 'addtag'
44
+ * | 'retag'
45
+ * | 'search'
46
+ * | 'alias'
47
+ * | 'randmic'
48
+ * | 'randClg'
49
+ * | 'table'
50
+ * | 'comment'
51
+ * | 'recallComment'
52
+ * | 'myComment'
53
+ * | 'comrks'
54
+ * | 'rankList'
55
+ * | 'godList'
56
+ * | 'tips'
57
+ * | 'newSong'
58
+ * | 'tipgame'
59
+ * | 'guessgame'
60
+ * | 'ltrgame'
61
+ * | 'sign'
62
+ * | 'send'
63
+ * | 'tasks'
64
+ * | 'retask'
65
+ * | 'jrrp'
66
+ * | 'theme'
67
+ * | 'dan'
68
+ * | 'danupdate'
69
+ * | 'setApiToken'
70
+ * | 'tokenList'
71
+ * | 'auth'
72
+ * | 'clearApiData'
73
+ * | 'updateHistory'
74
+ * } allFnc 全部指令
75
+ */
76
+
77
+ /**
78
+ * 渲染设置
79
+ * @typedef {'onLinePhiIllUrl'} onLinePhiIllUrl 在线曲绘来源
80
+ * @typedef {'githubProxy'} githubProxy GitHub代理
81
+ * @typedef {'downIllUrl'} downIllUrl 下载曲绘来源
82
+ * @typedef {'renderScale'} renderScale 渲染精度
83
+ * @typedef {'randerQuality'} randerQuality 渲染质量
84
+ * @typedef {'timeout'} timeout 渲染超时时间
85
+ * @typedef {'waitingTimeout'} waitingTimeout 等待超时时间
86
+ * @typedef {'renderNum'} renderNum 并行渲染数量
87
+ * @typedef {'commentsAPage'} commentsAPage 每页最大渲染评论数量
88
+ * @typedef {'B19MaxNum'} B19MaxNum B19最大限制
89
+ * @typedef {'HistoryDayNum'} HistoryDayNum 历史成绩单日数量
90
+ * @typedef {'HistoryScoreDate'} HistoryScoreDate 历史成绩展示天数
91
+ * @typedef {'HistoryScoreNum'} HistoryScoreNum 历史成绩展示数量
92
+ * @typedef {'listScoreMaxNum'} listScoreMaxNum /list 最大数量
93
+ * 系统设置
94
+ * @typedef {'defaultGlobal'} defaultGlobal 默认使用国际服
95
+ * @typedef {'watchInfoPath'} watchInfoPath 监听信息文件
96
+ * @typedef {'allowComment'} allowComment 曲目评论
97
+ * @typedef {'allowChartTag'} allowChartTag 曲目标签
98
+ * @typedef {'autoPullPhiIll'} autoPullPhiIll 自动更新曲绘
99
+ * @typedef {'isGuild'} isGuild 频道模式
100
+ * @typedef {'TapTapLoginQRcode'} TapTapLoginQRcode 绑定二维码
101
+ * @typedef {'WordB19Img'} WordB19Img 文字版B19曲绘图片
102
+ * @typedef {'WordSuggImg'} WordSuggImg Suggest曲绘图片
103
+ * @typedef {'cmdhead'} cmdhead 命令头
104
+ * @typedef {'openPhiPluginApi'} openPhiPluginApi 是否启用Phigros联合查分API地址
105
+ * @typedef {'enableCustomThemeApi'} enableCustomThemeApi 是否启用自定义主题 API
106
+ * @typedef {'enableScoreStatisticsApi'} enableScoreStatisticsApi 是否启用免认证查分统计 API
107
+ * @typedef {'enableOnlineScoreApi'} enableOnlineScoreApi 是否启用需认证在线查分 API
108
+ * @typedef {'themeMarketDownloadOrigin'} themeMarketDownloadOrigin 主题市场下载来源
109
+ * @typedef {'debug'} debug 输出测试日志
110
+ * @typedef {'otherinfo'} otherinfo 曲库
111
+ * @typedef {'mutiNickWaitTimeOut'} mutiNickWaitTimeOut 多个曲目回复序号等待时长
112
+ * @typedef {'chartPath'} chartPath 谱面路径
113
+ * 猜曲绘设置
114
+ * @typedef {'GuessTipCd'} GuessTipCd 提示间隔
115
+ * @typedef {'GuessTipRecall'} GuessTipRecall 猜曲绘撤回
116
+ * 开字母设置
117
+ * @typedef {'LetterNum'} LetterNum 字母条数
118
+ * @typedef {'LetterMarkdown'} LetterMarkdown Markdown格式
119
+ * @typedef {'LetterIllustration'} LetterIllustration 发送曲绘
120
+ * @typedef {'LetterRevealCd'} LetterRevealCd 字母提示间隔
121
+ * @typedef {'LetterGuessCd'} LetterGuessCd 字母开启间隔
122
+ * @typedef {'LetterTipCd'} LetterTipCd 字母提示间隔
123
+ * @typedef {'LetterTimeLength'} LetterTimeLength 猜字母最长时长
124
+ * 提示猜歌设置
125
+ * @typedef {'GuessTipsTipCD'} GuessTipsTipCD 提示冷却
126
+ * @typedef {'GuessTipsTipNum'} GuessTipsTipNum 提示条数
127
+ * @typedef {'GuessTipsTimeout'} GuessTipsTimeout 游戏时长
128
+ * @typedef {'GuessTipsAnsTime'} GuessTipsAnsTime 额外时间
129
+ * 其他设置
130
+ * @typedef {'VikaToken'} VikaToken VikaToken
131
+ * @typedef {'apiBotClientId'} apiBotClientId API签发的Bot clientId
132
+ * @typedef {'apiBotClientSecret'} apiBotClientSecret API签发的Bot HMAC secret
133
+ * @typedef {'apiBotSecretVersion'} apiBotSecretVersion Bot HMAC secret版本
134
+ *
135
+ * @typedef {onLinePhiIllUrl
136
+ * |githubProxy
137
+ * |downIllUrl
138
+ * |renderScale
139
+ * |randerQuality
140
+ * |timeout
141
+ * |waitingTimeout
142
+ * |renderNum
143
+ * |commentsAPage
144
+ * |B19MaxNum
145
+ * |HistoryDayNum
146
+ * |HistoryScoreDate
147
+ * |HistoryScoreNum
148
+ * |listScoreMaxNum
149
+ * |defaultGlobal
150
+ * |watchInfoPath
151
+ * |allowComment
152
+ * |allowChartTag
153
+ * |autoPullPhiIll
154
+ * |isGuild
155
+ * |TapTapLoginQRcode
156
+ * |WordB19Img
157
+ * |WordSuggImg
158
+ * |cmdhead
159
+ * |openPhiPluginApi
160
+ * |enableCustomThemeApi
161
+ * |enableScoreStatisticsApi
162
+ * |enableOnlineScoreApi
163
+ * |themeMarketDownloadOrigin
164
+ * |debug
165
+ * |otherinfo
166
+ * |mutiNickWaitTimeOut
167
+ * |chartPath
168
+ * |GuessTipCd
169
+ * |GuessTipRecall
170
+ * |LetterNum
171
+ * |LetterMarkdown
172
+ * |LetterIllustration
173
+ * |LetterRevealCd
174
+ * |LetterGuessCd
175
+ * |LetterTipCd
176
+ * |LetterTimeLength
177
+ * |GuessTipsTipCD
178
+ * |GuessTipsTipNum
179
+ * |GuessTipsTimeout
180
+ * |GuessTipsAnsTime
181
+ * |VikaToken
182
+ * |apiBotClientId
183
+ * |apiBotClientSecret
184
+ * |apiBotSecretVersion
185
+ * } configName 全部设置
186
+ */
187
+
188
+
189
+ /**
190
+ * @typedef {object} ori_record
191
+ * @property {number} score
192
+ * @property {number} acc
193
+ * @property {boolean} fc
194
+ */
195
+
196
+ /**
197
+ * @typedef {object} playerInfo
198
+ * @property {{ '*': {write: boolean, read: boolean} }} ACL
199
+ * @property {object} authData
200
+ * @property {object} authData.taptap
201
+ * @property {string} authData.taptap.access_token
202
+ * @property {string} authData.taptap.avatar taptap头像
203
+ * @property {string} authData.taptap.gender
204
+ * @property {string} authData.taptap.kid
205
+ * @property {string} authData.taptap.mac_algorithm
206
+ * @property {string} authData.taptap.mac_key
207
+ * @property {string} authData.taptap.name
208
+ * @property {string} authData.taptap.openid
209
+ * @property {string} authData.taptap.scope
210
+ * @property {string} authData.taptap.token_type
211
+ * @property {string} authData.taptap.unionid
212
+ * @property {string} avatar taptap头像
213
+ * @property {string} createdAt '2022-09-03T10:21:42.783Z'
214
+ * @property {boolean} emailVerified
215
+ * @property {boolean} mobilePhoneVerified
216
+ * @property {string} nickname 游戏昵称
217
+ * @property {phigrosObjectId} objectId
218
+ * @property {phigrosToken} sessionToken
219
+ * @property {string} shortId
220
+ * @property {string} updatedAt
221
+ * @property {string} username
222
+ *
223
+ * @typedef {object} gameFile
224
+ * @property {string} __type 文件类型
225
+ * @property {string} bucket 存档bucket
226
+ * @property {string} createdAt 存档创建时间 2023-10-05T07:41:24.503Z
227
+ * @property {string} key gamesaves/{32}/.save
228
+ * @property {object} metaData metaData
229
+ * @property {string} mime_type mime_type
230
+ * @property {string} name ".save"
231
+ * @property {string} objectId 存档id {24}
232
+ * @property {string} provider provider
233
+ * @property {string} updatedAt 存档更新时间 2023-10-05T07:41:24.503Z
234
+ * @property {string} url https://rak3ffdi.tds1.tapfiles.cn/gamesaves/{32}/.save
235
+ *
236
+ * @typedef {object} modifiedAt
237
+ * @property {string} __type
238
+ * @property {Date} iso
239
+ *
240
+ * @typedef {object} summary
241
+ * @property {string} updatedAt 插件获取存档时间 2023 Oct.06 11:46:33
242
+ * @property {number} saveVersion 存档版本
243
+ * @property {number} challengeModeRank 课题分
244
+ * @property {number} rankingScore rks
245
+ * @property {number} gameVersion 客户端版本号
246
+ * @property {string} avatar 头像
247
+ * @property {number[]} cleared 完成曲目数量
248
+ * @property {number[]} fullCombo FC曲目数量
249
+ * @property {number[]} phi AP曲目数量
250
+ *
251
+ * @typedef {object} saveInfo
252
+ * @property {Date} createdAt 账户创建时间 2022-09-03T10:21:48.613Z
253
+ * @property {gameFile} gameFile
254
+ * @property {modifiedAt} modifiedAt 存档上传时间 {__type:"Date", "iso": "2023-10-06T03:46:33.000Z"}
255
+ * @property {string} name
256
+ * @property {string} objectId 存档id {24}
257
+ * @property {summary} summary
258
+ * @property {Date} updatedAt 存档更新时间 2023-10-06T03:46:33.000Z
259
+ * @property {{'__type': "Pointer", 'className': "_User", 'objectId': string}} user
260
+ * @property {string} PlayerId
261
+ *
262
+ * @typedef {object} gameProgress
263
+ * @property {boolean} isFirstRun
264
+ * @property {boolean} legacyChapterFinished
265
+ * @property {boolean} alreadyShowCollectionTip
266
+ * @property {boolean} alreadyShowAutoUnlockINTip
267
+ * @property {string} completed
268
+ * @property {number} songUpdateInfo
269
+ * @property {number} challengeModeRank
270
+ * @property {number[]} money
271
+ * @property {number} unlockFlagOfSpasmodic
272
+ * @property {number} unlockFlagOfIgallta
273
+ * @property {number} unlockFlagOfRrharil
274
+ * @property {number} flagOfSongRecordKey
275
+ * @property {number} randomVersionUnlocked
276
+ * @property {boolean} chapter8UnlockBegin
277
+ * @property {boolean} chapter8UnlockSecondPhase
278
+ * @property {boolean} chapter8Passed
279
+ * @property {number} chapter8SongUnlocked
280
+ *
281
+ * @typedef {object} gameuser
282
+ * @property {string} name
283
+ * @property {string} version
284
+ * @property {boolean} showPlayerId
285
+ * @property {string} selfIntro
286
+ * @property {string} avatar
287
+ * @property {string} background
288
+ * @property {string} CLGMOD
289
+ *
290
+ * @typedef {Record<idString, (ori_record | null)[]>} gameRecord
291
+ *
292
+ * @typedef {object} oriSave
293
+ * @property {phigrosToken} session
294
+ * @property {apiUserId} [apiId]
295
+ * @property {boolean} global
296
+ * @property {saveInfo} saveInfo
297
+ * @property {playerInfo} playerInfo
298
+ * @property {number} Recordver
299
+ * @property {gameProgress} gameProgress
300
+ * @property {gameuser} gameuser
301
+ * @property {gameRecord} gameRecord
302
+ */
303
+
304
+ /**
305
+ * 基础历史记录结构
306
+ * @template T
307
+ * @typedef {object} BaseHistoryObject<T>
308
+ * @property {string} date - 日期 ISO格式
309
+ * @property {T} value - 值
310
+ */
311
+
312
+ /**
313
+ * 单条成绩详细记录
314
+ * @typedef {[acc: string, score: number, date: string, fc: number | boolean]} ScoreDetail
315
+ * 0 - acc
316
+ * 1 - score
317
+ * 2 - 记录日期
318
+ * 3 - fc
319
+ */
320
+
321
+ /**
322
+ *
323
+ * @typedef {Partial<Record<allLevelKind, ScoreDetail[]>>} songRecordHistory
324
+ */
325
+
326
+ /**
327
+ * @typedef {Record<idString, songRecordHistory>} scoreHistoryObject
328
+ */
329
+
330
+ /**
331
+ * 玩家存档历史数据对象
332
+ * @typedef {Object} saveHistoryObject
333
+ * @property {BaseHistoryObject<number[]>[]} [data] - 成绩记录数组(包含日期和五个数值的元组)
334
+ * @property {BaseHistoryObject<number>[]} [rks] - RKS(评级分数)历史记录数组
335
+ * @property {scoreHistoryObject} [scoreHistory] - 成绩历史数据(按歌曲ID和难度分类的详细记录)
336
+ * @property {BaseHistoryObject<number>[]} [challengeModeRank] - 课题模式排名记录
337
+ * @property {number} [version] - 数据版本号
338
+ */
339
+
340
+ /**
341
+ * @typedef {Object} TapTapUpdateItem
342
+ * @property {string} version_label
343
+ * @property {number} update_date
344
+ * @property {{ text: string }} whatsnew
345
+ * @property {number} version_code
346
+ */
347
+
348
+ /**
349
+ * @typedef {Object} TapTapUpdateResponse
350
+ * @property {{ list: TapTapUpdateItem[] }} data
351
+ * @property {number} now
352
+ * @property {boolean} success
353
+ */
354
+
355
+ /**
356
+ * @typedef {Object} TapTapNoticeItem
357
+ * @property {'moment'} type
358
+ * @property {string} identification
359
+ * @property {TapTapNoticeMoment} moment
360
+ */
361
+
362
+ /**
363
+ * @typedef {Object} TapTapNoticeMoment
364
+ * @property {string} id_str
365
+ * @property {number} created_time
366
+ * @property {number} edited_time
367
+ * @property {number} publish_time
368
+ * @property {boolean} is_official
369
+ * @property {TapTapNoticeAuthor} author
370
+ * @property {TapTapNoticeTopic} topic
371
+ * @property {TapTapNoticeStat} stat
372
+ * @property {TapTapNoticeSharing} sharing
373
+ */
374
+
375
+ /**
376
+ * @typedef {Object} TapTapNoticeAuthor
377
+ * @property {{ id: number, title: string }} app
378
+ * @property {{ id: number, name: string, avatar: string }} user
379
+ */
380
+
381
+ /**
382
+ * @typedef {Object} TapTapNoticeTopic
383
+ * @property {string} id_str
384
+ * @property {string} title
385
+ * @property {string} summary
386
+ * @property {TapTapNoticeImage[]} images
387
+ */
388
+
389
+ /**
390
+ * @typedef {Object} TapTapNoticeImage
391
+ * @property {string} url
392
+ * @property {string} medium_url
393
+ * @property {string} small_url
394
+ * @property {string} original_url
395
+ * @property {number} width
396
+ * @property {number} height
397
+ */
398
+
399
+ /**
400
+ * @typedef {Object} TapTapNoticeStat
401
+ * @property {number} pv_total
402
+ * @property {number} ups
403
+ * @property {number} comments
404
+ * @property {number} favorites
405
+ */
406
+
407
+ /**
408
+ * @typedef {Object} TapTapNoticeSharing
409
+ * @property {string} url
410
+ * @property {string} title
411
+ * @property {string} description
412
+ * @property {TapTapNoticeImage} [image]
413
+ */
414
+
415
+ /**
416
+ * @typedef {Object} TapTapNoticeResponse
417
+ * @property {{ list: TapTapNoticeItem[], total: number, next_page: string }} data
418
+ * @property {number} now
419
+ * @property {boolean} success
420
+ */