diff --git a/WebSourceCode/index.html b/WebSourceCode/index.html index 1e1e567..0bf8303 100644 --- a/WebSourceCode/index.html +++ b/WebSourceCode/index.html @@ -1,13 +1,16 @@ - - - - - 我的乐库 - - -
- - - + + + + + + 我的乐库 + + + +
+ + + + \ No newline at end of file diff --git a/WebSourceCode/src/Netease/CHANGELOG.MD b/WebSourceCode/src/Netease/CHANGELOG.MD new file mode 100644 index 0000000..969ca29 --- /dev/null +++ b/WebSourceCode/src/Netease/CHANGELOG.MD @@ -0,0 +1,1134 @@ +# 更新日志 +### 4.12.2 | 2023.09.12 +- 新增 `播客声音列表`接口 +- 修复anonymous_token路径异常 #1795 + +### 4.12.1 | 2023.09.10 +- 补充 `get/userids`(根据nickname获取userid) 接口 + +### 4.12.0 | 2023.09.10 +- 听歌识曲接口完善, 补充demo页面 + +- NMTID 动态添加 #1792 + +- weapi ua 固定 + +### 4.11.3 | 2023.09.09 +- 返回内容的`code`统一处理 + +- 单元测试问题修复 + +- song/url 返回排序处理 #1792 + + +### 4.11.2 | 2023.09.09 +- 修复`vercel`无文件创建权限问题 + +### 4.11.1 | 2023.09.08 +- `anonymous_token` 配置抽离 + +- `anonymous_token` 生成稳定性问题修复 + +### 4.11.0 | 2023.09.07 +- 新增 `播客搜索`,`播客上传声音`接口 #1789 + + +### 4.10.2 | 2023.09.04 +- 修复docker缺失文件问题 #1791 + +### 4.10.1 | 2023.08.21 +- 补充匿名登录username算法, anonymous_token 动态生成 + +### 4.10.0 | 2023.08.21 +- 禁用NMTID, 恢复手机登录和邮箱登录 #1788 +- 状态码判断完善,补充verify相关接口 #1783 +- 增加对带用户名密码的代理支持 #1787 + +### 4.9.2 | 2023.08.15 +- 补充 `/vip/info/v2` 接口 + +### 4.9.1 | 2023.08.15 +- `/vip/info` 接口增加`uid`参数 + +### 4.9.0 | 2023.07.20 +- 新增沉浸环绕声音质,修改部分文案以同步客户端更改 #1760 + +- 增加对鲸云臻音、鲸云母带音质的支持 #1731 + +- 新增星评馆简要评论获取接口 #1770 + +- 更新 song_detail 返回值类型 #1772 + +- NodeJS 环境要求提高至 v14 + +### 4.8.11 | 2023.05.29 +- 支持headers不携带cookie信息 + +### 4.8.10 | 2023.04.07 +- 补充私信和通知接口 + +### 4.8.9 | 2023.01.18 +- 补充一起听相关接口 #1677 + +### 4.8.8 | 2023.01.18 +- 补充腾讯云serverless部署说明 + +- 添加逐字歌词接口 #1669 + +- CloudSearch接口使用eapi代替weapi #1670 + +- axios 相关代码调整 + +### 4.8.7 | 2023.01.04 +- 手机登录问题修复 [#1658] + +### 4.8.6 | 2023.01.02 +- 手机登录问题修复 [#1658] + +### 4.8.5 | 2022.12.28 +- 手机登录问题修复 [#1661] + +### 4.8.4 | 2022.12.19 +- 邮箱登录问题修复 + +### 4.8.3 | 2022.12.19 +- 修复了手机号登录接口 [#1653] + +- 增加若干曲风相关接口 [#1623] + +### 4.8.2 | 2022.09.13 +- 修复 song/url 接口提示网络拥堵的问题 + +- 单元测试修复 + +### 4.8.1 | 2022.09.12 +- 解决网络拥堵提示问题 + +### 4.7.0 | 2022.09.02 +- 新增 API: 新版音乐链接获取 [#1583] + +- 新增 API: 歌曲百科简要信息 [#1596] + +- 新增 API: 乐谱相关 API [#1596] + +- ResourceType 补充 [#1497] + +### 4.6.7 | 2022.07.17 +- 音乐是否可用接口更新 #1544 + +- 获取精品歌单接口更新描述 #1544 + +### 4.6.6 | 2022.06.20 +- npx 方式运行完善和增加文档说明 + +### 4.6.5 | 2022.06.19 +- 修复npx使用路径错误 + +### 4.6.4 | 2022.06.15 +- 修复歌单收藏/取消收藏歌曲接口报错问题 #1551 + +### 4.6.3 | 2022.06.15 +- 修复 npm 包文件缺失的问题 + +### 4.6.2 | 2022.05.30 +- 修复测试不通过的问题 + +### 4.6.1 | 2022.05.29 +- 修复请求接口提示需要验证的问题,增加游客登录接口,服务启动更新游客cookie + +### 4.6.0 | 2022.05.29 +- 修复请求接口提示需要验证的问题 [#1541](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1541) + +### 4.5.14 | 2022.05.06 +- 修复获取歌单所有歌曲接口分页问题 [#1524](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1524) + +- 增加支持罗马音歌词返回 [#1523](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1523) + +### 4.5.12 | 2022.04.15 +- 新增`黑胶时光机`接口 [#1511](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1511) + +### 4.5.11 | 2022.04.06 +- 修复云盘接口mimetype获取错误 [#1503](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1503) + +### 4.5.10 | 2022.03.28 +- 修复了若干问题 + +- 新增`歌单更新播放量`接口 + +### 4.5.9 | 2022.03.20 +- 修复云盘上传接口部分文件名格式上传失败的问题 + +- 新增 `/inner/version` 接口,用于获取当前版本号 + +### 4.5.8 | 2022.03.05 +- 新增歌手粉丝数量接口[#1485](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1485) + +- 新增音乐人任务(新)接口 + +- 更新 `appver` + +### 4.5.6 | 2022.02.12 +- 歌单封面上传接口缺失参数时返回状态码修正 + +### 4.5.6 | 2022.02.09 +- 新增重复昵称检测接口 [#1469](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1469) + +### 4.5.5 | 2022.02.09 +- 搜索接口支持搜索声音 + +### 4.5.4 | 2022.02.09 +- 修复云盘上传无法获取到文件的问题 + +### 4.5.3 | 2022.02.04 +- 增加签到进度接口 [#1462](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1462) + +### 4.5.2 | 2022.01.28 +- 入口文件优化 [#1457](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1457) + +### 4.5.0 | 2022.01.27 + +- app.js 重构[#1453](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1453) + +- 修复 pkg 打包问题 + +### 4.3.0 | 2022.01.22 + +- fix: 发送/删除评论、点赞失败 [#1446](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1446) + +- 增加二进制文件 node 标识 [#1440](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1440) + +- 获取歌单所有歌曲增加 offset 偏移量设置[#1435](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1435) + +### 4.2.0 | 2021.11.23 + +- 合并相同接口(发送文本动态,使用`/share/resource`接口代替);增加歌手视频接口;增加创建共享歌单的用法 [#1402](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1402) + +- 新增最近播放-歌曲,最近播放-视频,最近播放-声音,最近播放-歌单,最近播放-专辑,最近播放-播客等接口 + +### 4.1.1 | 2021.11.20 + +- 添加乐签信息接口 [#1365](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1365) + +### 4.1.0 | 2021.11.20 + +- 修复新版评论返回参数错误问题 [#1393](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1393) [#1377](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1377) + +- 新增获取歌单所有歌曲的 API [#1397](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1397) + +- 新增发送文本动态接口, 获取客户端歌曲下载链接 url 接口 [#1391](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1391) + +### 4.0.23 | 2021.9.15 + +- 修复文件上传设置问题 [#1355](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1355) + +- 修复 interface 不完整问题 [#1356](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1356) + +### 4.0.22 | 2021.9.08 + +- 修复 URI malformed 错误 [#1347](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1347) + +### 4.0.21 | 2021.9.04 + +- 修复云盘上传失败问题 #1332 + +- 修复调用不存在的接口导致 API 崩溃的问题 #1345 + +- 修复代理设置问题 #1343 + +- 新增歌曲相关视频接口(歌曲相关视频 公开隐私歌单) [#1337](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1337) + +### 4.0.20 | 2021.8.20 + +- 手机登录增加验证码登录方式 [#1328](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1328) + +### 4.0.19 | 2021.8.10 + +- 修复若干问题 + +### 4.0.17 | 2021.7.16 + +- 修复若干问题 + +### 4.0.16 | 2021.6.2 + +- 新增歌手粉丝,数字专辑详情,数字专辑销量,音乐人数据概况,音乐人播放趋势,音乐人任务,账号云豆数,领取云豆等接口 [#1252](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1252) + +### 4.0.15 | 2021.5.29 + +- 新增已购单曲,获取 mlog 播放地址,将 mlog id 转为视频 id,vip 成长值,vip 成长值获取记录,vip 任务,领取 vip 成长值等接口 [#1248](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1248) + +### 4.0.14 | 2021.5.28 + +- 增加云贝推歌接口,云贝推歌历史记录接口 [#1246](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1246) + +### 4.0.13 | 2021.5.24 + +- 修复解析问题,改善 Docker 支持 [#1241](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1241) + +### 4.0.12 | 2021.5.1 + +- 首页-发现接口增加 cursor 参数,refresh 默认设为 false [#1217](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1217) + +- 更新`song/detail` 接口 + +### 4.0.11 | 2021.4.26 + +- 新增云盘歌曲信息匹配纠正接口 [#1212](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1212) + +### 4.0.10 | 2021.4.09 + +- 新增用户历史评论接口 [#1197](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1197) + +### 4.0.9 | 2021.3.13 + +- 新增一起听状态接口 [#1170](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1170) + +### 4.0.8 | 2021.2.27 + +- 加入 vercel 配置文件,支持 vercel 部署 + +### 4.0.7 | 2021.2.27 + +- 更新红心接口,修复红心接口 460 错误问题 [#1151](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1151) + +- 更新发送验证码接口 + +- 注册接口添加 countrycode 参数 [#1152](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1152) + +- 新增绑定手机接口 [#1152](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1152) + +- 更新 song/detail 接口 [#1143](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1143) + +- 用户粉丝接口修改分页参数 [#1161](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1161) + +### 4.0.6 | 2021.2.20 + +- 修复 eapi 接口无法正确解密 response 的问题 [#1138](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1138) + +### 4.0.5 | 2021.2.19 + +- 修复红心接口默认不红心的问题 [#1126](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1126) + +### 4.0.4 | 2021.2.18 + +- 移除云村热评接口(官方下架) [#1111](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1111) +- 更新 app version + +### 4.0.3 | 2021.1.28 + +- 修复云盘接口中文音乐信息乱码的问题 [#1108](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1108) + +### 4.0.2 | 2021.1.18 + +- 修复未绑定手机号对歌单添加或删除歌曲无响应的问题 [#1099](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1099) + +### 4.0.1 | 2021.1.09 + +- 新增歌单详情动态接口 [#1088](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1088) + +### 4.0.0 | 2021.1.03 + +- 新增云盘上传接口,新增二维码登录相关接口和相关 demo(http://localhost:3000/qrlogin.html, http://localhost:3000/cloud.html),更新 d.ts + +- 升级部分接口加密方法("linuxapi" 都替换到了"api") + +- 更新 `login/status` 接口(返回字段和之前不一样) + +### 3.47.5 | 2020.12.20 + +- 更新 appver [#1060](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1060) + +### 3.47.4 | 2020.12.03 + +- 修复收藏的专栏接口无法调用的问题 [#1042](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1042) + +### 3.47.3 | 2020.11.22 + +- 新增歌手详情接口 [#1035](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1035) + +### 3.47.2 | 2020.11.15 + +- 新增关注歌手新歌/新 MV 接口 [#1028](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1028) + +### 3.47.1 | 2020.11.14 + +- 修复使用 post 请求取消喜欢音乐会失败的问题 [#1024](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1024) + +- 新增抱一抱评论和评论抱一抱列表接口 [#1016](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1016) + +- 新增收藏的专栏接口[#1026](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1026) + +### 3.46.1 | 2020.11.7 + +- 修复私信音乐接口出现风险提示的问题 + +### 3.46.0 | 2020.11.7 + +- 添加私信音乐接口 [#1016](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1016) + +- 添加最近联系人接口 + +- 修复用户动态数量不准确问题 [#1010](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1010) + +- 修复 cloudsearch 接口分页问题 [#1015](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1015) + +### 3.45.3 | 2020.11.1 + +- `相似歌手`,`首页-发现-圆形图标入口列表`接口增加匿名 token[#877](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/877) [#988](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/988) + +- 修复`音乐 url`接口 POST 方式手动传入 cookie 报错问题 [#1005](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1005) + +### 3.45.2 | 2020.10.26 + +- 云贝完成任务接口增加`depositCode`参数 + +### 3.45.1 | 2020.10.25 + +- 修复代理配置失效的问题 [#992](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/992) + +- 修复新碟上架不返回周数据的问题,修复推荐新音乐接口返回数量问题,并添加 limit 参数支持 [#981](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/981) + +- 添加`云贝`相关接口 [#985](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/985) + +- 添加`用户账号信息`接口 + +- 替换接口文件所有 http url 为 https + +### 3.44.0 | 2020.10.17 + +- 更新`电台详情`,`电台节目详情`接口 [#977](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/977) + +#### Breaking change + +- `电台详情`接口更新后数据结构有变化 + +### 3.43.0 | 2020.10.16 + +- 新增`电台订阅者列表`接口 [#971](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/971) + +### 3.42.4 | 2020.10.07 + +- 修复新评论接口分页参数问题 + +### 3.42.3 | 2020.10.05 + +- 修复新评论接口分页参数问题 + +### 3.42.2 | 2020.10.05 + +- 更新歌单详情接口 + +### 3.42.1 | 2020.10.04 + +- 新增`用户绑定信息`,`用户绑定手机`,`新版评论`,`点赞过的视频`,`收藏视频到视频歌单`,`删除视频歌单里的视频`,`最近播放的视频`,`音乐日历`等接口 + +- 创建歌单接口增加`type`参数,可创建视频歌单 + +### 3.41.2 | 2020.09.20 + +- 更新`获取音乐 url`接口,未登录状态返回试听片段 [#897](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/897) + +### 3.41.1 | 2020.09.19 + +- 新增`电台个性推荐接口` [#824](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/824) + +### 3.41.0 | 2020.09.19 + +- 新增`精品歌单标签列表`接口 [#921](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/921) + +- 新增`用户等级信息`接口 [#929](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/929) + +- 增加新接口的 d.ts 文件,修复登录接口的 d.ts 的 countrycode 为非可选属性的错误 + +### 3.40.1 | 2020.09.13 + +- 更新 TypeScript 声明 [#928](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/928) + +### 3.40.0 | 2020.09.12 + +- 新增 TypeScript 声明文件 [#908](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/908) +- 更改随机 UA 相关逻辑[#922](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/922) + +### 3.39.0 | 2020.08.23 + +- 新增`cloudsearch`接口[#893](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/893) +- `mv 地址`接口修改分辨率参数 [#883](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/883) +- 修复新碟上架接口分页问题 [#892](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/892) + +### 3.38.0 | 2020.08.09 + +- 新增`楼层评论`,`歌手全部歌曲`接口 [#864](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/864) [#867](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/867) +- 支持收藏 VIP 或付费歌曲到歌单 [#860](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/860) +- 支持手动传入`realIP` [#863](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/863) + +### 3.37.2 | 2020.08.04 + +- 修复依赖问题 + +### 3.37.0 | 2020.08.03 + +- 新增`更新头像`,`歌单封面上传`接口和相关例子 [#403](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/403) [#857](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/857) +- 加入`axios`依赖 + +### 3.36.0 | 2020.07.26 + +- 新增`全部新碟`,`数字专辑-新碟上架`,`数字专辑&数字单曲-榜单`,`数字专辑-语种风格馆`,`数字专辑详情`接口 [#852](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/852) +- 更新`新碟上架`接口,修改传入参数,返回数据结构有变化 + +### 3.35.0 | 2020.07.18 + +- 新增`首页-发现`,`首页-发现-圆形图标入口列表`接口 [#851](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/851) + +### 3.34.2 | 2020.07.13 + +- 修复`获取用户播放记录`接口参数错误问题 [#849](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/849) + +- 增加`国家编码列表`接口 [#841](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/841) + +### 3.34.1 | 2020.07.06 + +- 登录接口增加 `md5_password` 参数 [#839](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/839) + +### 3.34.0 | 2020.06.25 + +- 排行榜接口废弃 idx 参数,只支持 id 参数,修复返回数据异常问题 [#830](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/830) +- 新增`获取历史日推可用日期列表`,`获取历史日推详细数据` 接口 + +### 3.33.2 | 2020.06.23 + +- 更新每日推荐接口 [#826](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/826) + +### 3.33.1 | 2020.06.15 + +- 修复直接调用时传入 cookie 不生效的问题 [#822](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/822) + +### 3.33.0 | 2020.06.10 + +- 歌手榜支持地区参数 [#818](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/818) +- 新增视频分类列表,推荐视频,获取全部视频列表接口 [#816](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/816) +- 内置 apicache,修复不能在 NodeJS v13 版本使用的问题 [#817](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/817) + +### 3.32.3 | 2020.06.07 + +- 修复 Nodejs 下 cookie 使用格式问题 [#812](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/812) + +### 3.32.2 | 2020.06.05 + +- 新增独家放送列表接口 [#808](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/808) + +### 3.32.1 | 2020.06.03 + +- 新增歌曲排序接口 + +### 3.32.0 | 2020.06.03 + +- 更新排行榜接口,支持传入榜单 id +- 新增榜单顺序调整接口 [#806](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/806) +- 完善错误提示信息 + +### 3.31.1 | 2020.05.19 + +- 修复`cookie`没返回的问题 [#778](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/778) + +### 3.31.0 | 2020.05.18 + +- 支持 `Node.js` 调用,参考`module_example` 文件夹下的 `test.js` + +### 3.30.0 | 2020.05.17 + +- 登录接口返回内容增加`cookie`字段,支持手动传入 cookie + +### 3.29.1 | 2020.05.13 + +- 调整通知接口分页参数 [#761](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/761) + +### 3.29.0 | 2020.05.11 + +- 支持批量删除歌单 [#760](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/760) + +### 3.28.0 | 2020.05.05 + +- 新增获取 mv 点赞转发评论数数据接口 +- 新增获取视频点赞转发评论数数据接口 + +### 3.27.0 | 2020.04.20 + +- 新增购买专辑接口 by [TimonPeng](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/740) + +### 3.26.0 | 2020.04.08 + +#### Breaking change + +- 更新歌手分类列表接口参数,因`cat`参数失效,调整为`type`和`area`参数 + +### 3.25.4 | 2020.03.18 + +- 更新歌词,歌手分类列表接口 + +- 更新文档 + +### 3.25.3 | 2019.11.08 + +- 升级依赖,去除多余依赖 + +- 优化 `test.html` + +### 3.25.2 | 2019.11.07 + +- 修复邮箱登录状态码错误,增加相关提示 [#633](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/633) + +### 3.25.0 | 2019.11.06 + +- 新增 `云村热评` 接口[#626](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/626) + +- 新增 `歌手热门50首歌曲` 接口 + +- 新增`电台24小时节目榜`,`电台24小时主播榜`, `电台最热主播榜`,`电台主播新人榜`,`电台付费精品榜` 接口 [#606](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/606) + +- 调整 `歌手分类列表 ` 接口参数 [#624](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/624) + +### 3.24.2 | 2019.10.28 + +- 修改默认绑定 HOST [#620](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/620) + +### 3.24.1 | 2019.10.25 + +- 修改默认绑定 HOST [#615](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/615) + +### 3.24.0 | 2019.10.22 + +- 新增`类别热门电台` 接口 [#607](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/607) + +### 3.23.0 | 2019.10.16 + +- 修复电台 banner 接口无数据问题[#601](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/601) + +- 更新排行榜 [#602](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/602) + +- 新增`电台排行榜`,`新晋电台榜`,`热门电台榜`接口 [#604](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/604) + +### 3.22.4 | 2019.09.26 + +- 修复私信历史记录分页参数问题,更新文档 [#599](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/599) + +### 3.22.3 | 2019.09.24 + +- 手机号码检测: 添加国家码作为参数,方便检测国外手机号码 [#598](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/598) + +### 3.22.2 | 2019.09.18 + +- 排行榜参数更新,更新文档[#592](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/592) + +### 3.22.1 | 2019.09.12 + +- 支持回复评论[#589](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/589) + +### 3.22.0 | 2019.08.25 + +- 支持 CORS 预检 [#564](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/564) [#578](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/578) + +### 3.21.1 | 2019.08.21 + +- 修复推荐歌单和网易出品 mv 参数错误,更新文档 [#571](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/571) [#572](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/572) + +### 3.21.0 | 2019.08.20 + +- 新增`歌单删除接口`[#570](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/570) + +### 3.20.0 | 2019.08.06 + +- 新增`更新歌单描述`,`更新歌单名`,`更新歌单标签`,`默认搜索关键词` 接口,更新文档[#547](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/547) + +### 3.19.0 | 2019.07.24 + +- 新增`检测手机号码是否已注册`和`初始化昵称`接口[#540](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/540) + +### 3.18.6 | 2019.07.15 + +- 修复注册异常的问题 [#532](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/532) + +### 3.18.5 | 2019.07.14 + +- 修复部分歌曲无法获得播放链接的问题 [#531](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/531) + +### 3.18.3 | 2019.07.04 + +- 修复全部 mv`/mv/all` 接口分页参数错误的问题 [#524](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/524) + +### 3.18.2 | 2019.07.03 + +- 修复听歌打卡接口 `/scrobble` 失效问题 + +### 3.18.1 | 2019.06.30 + +- 评论接口增加 `before` 参数以获取超过 5000 条评论数据 [#521](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/521) + +- 修复 `/msg/comments` 传入参数和文档描述不一致问题 + +### 3.18.0 | 2019.06.29 + +- 新增 `更换绑定手机接口` + +#### Breaking change + +1. 调整注册接口由 `/captch/register` 修改为 `/register/cellphone` + +2. 调整发送短信接口由 `/captch/sent` 修改为 `/captcha/sent` + +3. 调整短信验证接口由 `/captch/verify` 修改为 `/captcha/verify` + +### 3.17.0 | 2019.06.29 + +- 新增 `专辑动态信息` `热搜列表(详细)` 接口,更新文档 + +### 3.16.0 | 2019.06.27 + +- 新增 `收藏/取消收藏专辑` 接口 + +- 调整歌曲评论接口使用客户端版本接口 + +### 3.15.0 | 2019.06.16 + +- 新增`获取视频标签列表`,`网易出品`,`全部mv`接口, `最新 mv` 和 `mv 排行` 接口加入地区参数,更新文档 + +### 3.14.0 | 2019.06.10 + +- 获取用户粉丝列表接口修改请求参数,更新文档 + +### 3.13.1 | 2019.06.09 + +- 修复获取用户粉丝列表接口只能获取 1000 个的问题 + +### 3.13.0 | 2019.05.19 + +- 新增 eapi 算法 (via:[#491](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/491)) + +- 新增 batch 批量请求接口 (via:[#491](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/491)) + +- 用户动态增加分页参数 + +### 3.12.0 | 2019.05.10 + +- 增加`私信内容、我的数字专辑`接口 + +### 3.11.0 | 2019.05.09 + +- 增加`通知-私信、通知-评论、通知-@我、通知-通知、设置、云盘数据详情`接口 + +### 3.10.2 | 2019.05.09 + +- 增加`分享歌曲、歌单、mv、电台、电台节目到动态`接口 + +### 3.10.1 | 2019.05.08 + +- 增加转发动态接口 + +- 增加删除动态接口 + +### 3.9.0 | 2019.05.03 + +- 新增 云盘歌曲删除, 热门话题, 电台 - 推荐类型, 电台 - 非热门类型, 电台 - 今日优选, 心动模式/智能播放等接口 + +- 更新文档:banner 接口 增加 `type` 参数; 获取动态消息接口增加 `pagesize` 和 `lasttime` 参数; 电台 - 付费精选接口修改默认`limit`为 30 + +### 3.8.1 | 2019.04.24 + +- 修复歌词接口出错问题 + +### 3.8.0 | 2019.04.14 + +- 增加注册,发送验证码,校验验证码接口 via:[https://github.com/Binaryify/NeteaseCloudMusicApi/pull/460](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/460) @[KongValley](https://github.com/KongValley) + +### 3.7.1 | 2019.04.09 + +- 修复登录 460 问题 + +### 3.7.0 | 2019.03.20 + +- 修复喜欢音乐接口参数判断问题 + +- 增加歌单收藏者列表接口 + +### 3.6.0 | 2019.03.15 + +- 调整动态评论获取接口 url,使之和其他评论获取接口更统一 + +### 3.5.0 | 2019.03.14 + +- 增加获取动态评论接口 + +- 支持给动态点赞 + +- 支持给动态评论点赞 + +- 支持给动态发送/删除评论 + +### 3.4.0 | 2019.01.29 + +- 增加已收藏专辑列表接口 + +### 3.3.0 | 2019.01.27 + +- 增加视频标签下的视频获取接口 + +- 增加 pac 代理支持 + +### 3.2.0 | 2019.01.19 + +- 增加获取首页新碟上架数据以及更新听歌排行 + +- 更新搜索建议接口 + +### 3.1.0 | 2019.01.06 + +- 修复评论接口返回 460 Cheating 的问题 + +- 新增`已收藏MV`接口,更新文档 + +### 3.0.9 | 2018.12.15 + +- 修复关注异常的问题 #399 + +### 3.0.8 | 2018.12.12 + +- 更新文档 #386 #394 + +- 优化电台节目接口 + +### 3.0.7 | 2018.11.21 + +- 修复歌单详情列表,排行榜,所有榜单失效的问题,更新文档 #380 #381 + +### 3.0.4 | 2018.11.15 + +- 修复 `/song/url` 接口无法返回多个音乐数据的问题 + +### 3.0.3 | 2018.11.09 + +- 修复取消喜欢歌曲失败问题 [#360](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/360) + +- 补充已喜欢音乐列表接口说明文档 [#370](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/370) + +- 默认关闭 debug 模式 [#365](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/365) + +- 更新 Dockerfile 文件 [#367](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/367) + +### 3.0.1 | 2018.10.21 + +- 合并 PR([#351](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/351)) + +- 文档增加 `/top/song` 接口 + +- `/banner` 换成 linux api,返回结构有所变动 + +- `/check/music` 已知 bug 修复 + +### 3.0.0 | 2018.10.14 + +#### 整体 + +- 完善文档,增加之前没写进文档的接口说明 + +- 重写 createRequest 返回 Promise 对象 + +- 模块化路由 + +- 模块化, 剥离 res,req, 方便导出调用 + +- 增加 cookie-parser + +##### 参数修改 + +- `/song/detail` 增加多 id 支持 + +- `/toplist/detail` 移除参数 + +- `/resource/like` 增加参数 `type` + +- `/top/playlist/highquality` 增加分页参数 `before` + +##### 统一参数 + +- `/artist/sub` 与 `artist/unsub` 合并, 用`query.t` + +- `/follow` 中 `query.type` 换成 `query.t` + +- `/comment` 中 `query.action` 换成 `query.t` + +##### URL 重命名 + +- `/video` 改为 `video/url` + +- `/mv` 改为 `mv/detail` + +- `/music/url` 改为 `/song/url` + +##### 转发逻辑修改 + +- `/toplist/artist` 换成 weapi + +- `/mv/url` 去除了 pipe + +##### BUG 修复 + +- `/playlist/create`, `/playlist/update` 被判欺骗,增加 cookie + +##### 路由增删 + +- 删除 `/recommend/dislike` + +- 增加 `/video/sub` (收藏视频), `/mv/sub` (收藏 MV) + +- 增加 `/video/detail` (视频详情) + +- 增加 `/related/allvideo` (相关视频) + +### 2.20.5 | 2018.09.29 + +修复非法参数 403 #335, 修复代理错误 #334 + +### 2.20.4 | 2018.09.27 + +修复点赞失效的问题 + +### 2.20.3 | 2018.09.26 + +- 增加退出登录接口 +- 修正 /check/music 的检查逻辑 +- 优化 Cookies 设置 +- 重构单元测试 + + [by @nondanee](https://github.com/nondanee) + +- 增加 301 需要登录提示信息 + +- 更新文档 + +### 2.20.2 | 2018.09.22 + +增加热门评论和视频评论接口,更新文档 + +### 2.20.1 | 2018.09.17 + +优化版本检查功能 + +### 2.20.0 | 2018.09.06 + +新增版本检查功能 + +### 2.19.0 | 2018.08.29 + +新增获取视频数据接口,新增发送/删除评论接口,修复登录状态接口问题,完善文档 #301,感谢 @izhenyuls + +### 2.17.0 | 2018.08.28 + +新增登录状态查询接口 #302 ,完善文档,完善路由注册 #297 + +### 2.16.0 | 2018.08.09 + +- Fixed #288,#289,#290 + +解决歌曲 URL 请求被判 Cheating,修复私信接收异常 #291 + +### 2.15.0 | 2018.07.30 + +新增相关歌单推荐和付费精选接口,增加歌手列表接口按首字母索引查找参数 + +### 2.14.0 | 2018.07.03 + +修复无法使用邮箱问题 + +### 2.13.0 | 2018.06.05 + +增加自动注册路由的功能,简化路由注册逻辑 + +### 2.12.0 | 2018.05.27 + +更新文档,优化歌单详情接口 + +### 2.11.1 | 2018.05.24 + +更新文档,优化`/dj/program`接口 + +### 2.11.0 | 2018.05.21 + +增加收藏歌手列表&订阅电台列表 + +### 2.10.0 | 2018.05.17 + +歌单操作调整为批量操作 + +### 2.9.9 | 2018.05.16 + +Bug 修复 + +### 2.9.8 | 2018.05.10 + +新增歌手分类列表,收藏/取消收藏歌手接口,新增更新用户信息,更新歌单接口 + +### 2.9.6 | 2018.05.08 + +新增发送私信相关接口,新增新建歌单,收藏/取消收藏歌单接口 + +### 2.9.4 | 2018.05.04 + +新增热搜接口,更新 banner 接口 + +### 2.9.2 | 2018.02.28 + +修复登录失败会崩溃的问题 + +### 2.9.1 | 2018.01.26 + +docker 构建文件的一些增强以及增加访问日志和调试输出 + +### 2.8.9 | 2018.01.24 + +修复歌单详情数据不完整的问题,更新依赖 + +### 2.8.8 | 2018.01.22 + +修复排行榜数据不完整的问题 , 优化部分代码 , 更新文档部分描述 + +### 2.8.6 | 2018.01.16 + +修复歌单详情接口数据不完整的问题 + +### 2.8.5 | 2018.01.16 + +修复评论点赞失败的问题 + +### 2.8.4 | 2018.01.15 + +优化 cookie 设置 + +### 2.8.3 | 2018.01.12 + +优化部分功能和文档 + +### 2.8.2 | 2018.01.05 + +增加 Dockerfile,支持以 Docker 容器模式运行 + +### 2.8.1 | 2018.01.04 + +添加了 proxy 功能 + +### 2.8.0 | 2018.01.04 + +用 'request' 重写了请求函数 + +### 2.7.9 | 2017.12.11 + +更新排行榜接口 , 新增云音乐 ACG 音乐榜 , 云音乐嘻哈榜 + +### 2.7.7 | 2017.11.27 + +更新 / 修复排行榜接口 , 更新 / 修复推荐歌单接口 + +### 2.7.7 | 2017.11.27 + +更新 / 修复排行榜接口 , 更新 / 修复推荐歌单接口 + +### 2.7.2 | 2017.9.7 + +修复搜索接口 offset 参数失效问题 + +### 2.7.0 | 2017.8.21 + +优化刷新登录代码 + +### 2.6.5 | 2017.7.16 + +优化 CORS 设置 + +### 2.6.4 | 2017.7.16 + +添加缓存机制和随机 UA 机制 感谢[@u3u](https://github.com/u3u) +[issue:77](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/77) 优化请求 +代码 感谢 [@huhuime](https://github.com/huhuime) +[issue:83](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/83) + +### 2.6.2 | 2017.7.16 + +修复垃圾桶接口 + +### 2.6.1 | 2017.7.16 + +修复红心接口 + +### 2.6.0 | 2017.6.25 + +修复签到接口 + +### 2.5.9 | 2017.6.14 + +增加启动说明页 + +### 2.5.8 | 2017.6.1 + +修复若干细节问题 + +### 2.5.7 | 2017.5.22 + +修复若干问题 + +### 2.5.6 | 2017.5.14 + +增加动态消息接口 + +### 2.5.5 | 2017.5.10 + +修复 mv 排行榜接口崩溃问题 + +### 2.5.4 | 2017.5.5 + +新增点赞接口 , 更新文档 + +### 2.5.3 | 2017.5.2 + +修复歌手单曲数据空白问题和文档获取歌手单曲 url 描述问题 , 更新文档 + +### 2.5.0 | 2017.4.29 + +增加 mv/ 专辑 / 歌单评论接口 , 增加云盘相关接口 , 增加获取用户动态 / 信息接口 , +增加关注 / 粉丝列表接口 , 增加收藏歌单接口 , 增加相似 mv/ 歌曲 / 用户接口 , 增加 +banner 接口 , 增加刷新登录接口 , 增加电台相关接口 , 补充评论接口 , 更新文档 + +### 2.4.6 | 2017.4.21 + +增加播放 mv 接口 , 更新文档 + +### 2.4.5 | 2017.4.20 + +增加歌手专辑 , 歌手单曲等接口 , 修复 /album 接口描述错误 , 更新文档 + +### 2.4.0 | 2017.4.20 + +增加歌单(网友精选碟 ), 新碟上架 , 热门歌手等接口 , 更新文档 + +### 2.3.4 | 2017.4.20 + +增加歌曲详情接口 , 更新文档 + +### 2.3.0 | 2017.4.15 + +增加排行榜接口 , 更新文档 + +### 2.2.0 |2017.4.14 + +增加私人 FM, 喜欢歌曲 , 垃圾桶 , 每日签到等接口 , 更新文档 + +### 2.1.3 | 2017.4.6 + +改善文档 + +### 2.1.0 | 2017.4.6 + +增加获取评论接口以及对应单元测试 , 增加更新日志 + +### 2.0.0 | 2017.4.1 + +版本升级到 2.0. 增加使用文档 , 完成项目重构 , 增加更完善的单元测试 , 升级 api 到 +v2+, 支持登录并获取用户信息和创建的歌单 , 可通过获取音乐 url 接口获取用户歌单里 +的的音乐 , 获取每日推荐歌单和每日推荐音乐 diff --git a/WebSourceCode/src/Netease/Dockerfile b/WebSourceCode/src/Netease/Dockerfile new file mode 100644 index 0000000..cbc1d55 --- /dev/null +++ b/WebSourceCode/src/Netease/Dockerfile @@ -0,0 +1,16 @@ +FROM node:lts-alpine + +RUN apk add --no-cache tini + +ENV NODE_ENV production +USER node + +WORKDIR /app + +COPY --chown=node:node . ./ + +RUN npm i --omit=dev --ignore-scripts + +EXPOSE 3000 + +CMD [ "/sbin/tini", "--", "node", "app.js" ] diff --git a/WebSourceCode/src/Netease/LICENSE b/WebSourceCode/src/Netease/LICENSE new file mode 100644 index 0000000..638a26f --- /dev/null +++ b/WebSourceCode/src/Netease/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013-2022 Binaryify + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/WebSourceCode/src/Netease/README.MD b/WebSourceCode/src/Netease/README.MD new file mode 100644 index 0000000..a5a5566 --- /dev/null +++ b/WebSourceCode/src/Netease/README.MD @@ -0,0 +1,428 @@ +# 网易云音乐 API + +网易云音乐 Node.js API service + +

+Version +License +devDependencies +devDependencies + +

+ + +## 灵感来自 + +[disoul/electron-cloud-music](https://github.com/disoul/electron-cloud-music) + +[darknessomi/musicbox](https://github.com/darknessomi/musicbox) + +[sqaiyan/netmusic-node](https://github.com/sqaiyan/netmusic-node) + +[greats3an/pyncm](https://github.com/greats3an/pyncm) + + +## 环境要求 + +需要 NodeJS 14+ 环境 + +## 安装 + +```shell +$ git clone git@github.com:Binaryify/NeteaseCloudMusicApi.git +$ cd NeteaseCloudMusicApi +$ npm install +``` + +或者 + +```shell +$ git clone https://github.com/Binaryify/NeteaseCloudMusicApi.git +$ cd NeteaseCloudMusicApi +$ npm install +``` + +## 运行 +调用前务必阅读文档的`调用前须知` + +```shell +$ node app.js +``` + +服务器启动默认端口为 3000,若不想使用 3000 端口,可使用以下命令: Mac/Linux + +```shell +$ PORT=4000 node app.js +``` + +windows 下使用 git-bash 或者 cmder 等终端执行以下命令: + +```shell +$ set PORT=4000 && node app.js +``` + +## Vercel 部署 + +v4.0.8 加入了 Vercel 配置文件,可以直接在 Vercel 下部署了,不需要自己的服务器 + +### 操作方法 + +1. fork 此项目 +2. 在 Vercel 官网点击 `New Project` +3. 点击 `Import Git Repository` 并选择你 fork 的此项目并点击`import` +4. 点击 `PERSONAL ACCOUNT` 的 `select` +5. 直接点`Continue` +6. `PROJECT NAME`自己填,`FRAMEWORK PRESET` 选 `Other` 然后直接点 `Deploy` 接着等部署完成即可 + +## 腾讯云 serverless 部署 +因 `Vercel` 在国内访问太慢,在此提供腾讯云 serverless 部署方法(注意:腾讯云 serverless 并不是免费的,前三个月有免费额度,之后收费) +### 操作方法 +1. fork 此项目 +2. 在腾讯云serverless应用管理页面( https://console.cloud.tencent.com/sls ),点击`新建应用` +3. 顶部`创建方式`选择 `Web 应用` +4. 选择 `Express框架`,点击底部`下一步按钮` +5. 输入`应用名`,上传方式选择`代码仓库`,进行GitHub授权(如已授权可跳过这一步),代码仓库选择刚刚fork的项目 +6. 启动文件填入: +``` +#!/bin/bash +export PORT=9000 +/var/lang/node16/bin/node app.js +``` +7. 点击`完成`,等待部署完成,点击`资源列表`的 `API网关` 里的 `URL`,正常情况会打开文档地址,点击文档`例子`可查看接口调用效果 + +## 可以在Node.js调用 + +v3.31.0后支持Node.js调用,导入的方法为`module`内的文件名,返回内容包含`status`和`body`,`status`为状态码,`body`为请求返回内容,参考`module_example` 文件夹下的 `test.js` + +```js +const { login_cellphone, user_cloud } = require('NeteaseCloudMusicApi') +async function main() { + try { + const result = await login_cellphone({ + phone: '手机号', + password: '密码' + }) + console.log(result) + const result2 = await user_cloud({ + cookie: result.body.cookie // 凭证 + }) + console.log(result2.body) + + } catch (error) { + console.log(error) + } +} +main() +``` + +## 支持 TypeScript + +```ts +// test.ts +import { banner } from 'NeteaseCloudMusicApi' +banner({ type:0 }).then(res=>{ + console.log(res) +}) +``` + + +## 使用文档 + +[文档地址](https://binaryify.github.io/NeteaseCloudMusicApi) + +[文档地址2](https://neteasecloudmusicapi.vercel.app) + +![文档](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/docs.png) + + +## 功能特性 + +1. 登录 +2. 刷新登录 +3. 发送验证码 +4. 校验验证码 +5. 注册(修改密码) +6. 获取用户信息 , 歌单,收藏,mv, dj 数量 +7. 获取用户歌单 +8. 获取用户电台 +9. 获取用户关注列表 +10. 获取用户粉丝列表 +11. 获取用户动态 +12. 获取用户播放记录 +13. 获取精品歌单 +14. 获取歌单详情 +15. 搜索 +16. 搜索建议 +17. 获取歌词 +18. 歌曲评论 +19. 收藏单曲到歌单 +20. 专辑评论 +21. 歌单评论 +22. mv 评论 +23. 电台节目评论 +24. banner +25. 获取歌曲详情 +26. 获取专辑内容 +27. 获取歌手单曲 +28. 获取歌手 mv +29. 获取歌手专辑 +30. 获取歌手描述 +31. 获取相似歌手 +32. 获取相似歌单 +33. 相似 mv +34. 获取相似音乐 +35. 获取最近 5 个听了这首歌的用户 +36. 获取每日推荐歌单 +37. 获取每日推荐歌曲 +38. 私人 FM +39. 签到 +40. 喜欢音乐 +41. 垃圾桶 +42. 歌单 ( 网友精选碟 ) +43. 新碟上架 +44. 热门歌手 +45. 最新 mv +46. 推荐 mv +47. 推荐歌单 +48. 推荐新音乐 +49. 推荐电台 +50. 推荐节目 +51. 独家放送 +52. mv 排行 +53. 获取 mv 数据 +54. 播放 mv/视频 +55. 排行榜 +56. 歌手榜 +57. 云盘 +58. 电台 - 推荐 +59. 电台 - 分类 +60. 电台 - 分类推荐 +61. 电台 - 订阅 +62. 电台 - 详情 +63. 电台 - 节目 +64. 给评论点赞 +65. 获取动态 +66. 热搜列表(简略) +67. 发送私信 +68. 发送私信歌单 +69. 新建歌单 +70. 收藏/取消收藏歌单 +71. 歌单分类 +72. 收藏的歌手列表 +73. 订阅的电台列表 +74. 相关歌单推荐 +75. 付费精选接口 +76. 音乐是否可用检查接口 +77. 登录状态 +78. 获取视频播放地址 +79. 发送/删除评论 +80. 热门评论 +81. 视频评论 +82. 退出登录 +83. 所有榜单 +84. 所有榜单内容摘要 +85. 收藏视频 +86. 收藏 MV +87. 视频详情 +88. 相关视频 +89. 关注用户 +90. 新歌速递 +91. 喜欢音乐列表(无序) +92. 收藏的 MV 列表 +93. 获取最新专辑 +94. 听歌打卡 +95. 获取视频标签/分类下的视频 +96. 已收藏专辑列表 +97. 获取动态评论 +98. 歌单收藏者列表 +99. 云盘歌曲删除 +100. 热门话题 +101. 电台 - 推荐类型 +102. 电台 - 非热门类型 +103. 电台 - 今日优选 +104. 心动模式/智能播放 +105. 转发动态 +106. 删除动态 +107. 分享歌曲、歌单、mv、电台、电台节目到动态 +108. 通知-私信 +109. 通知-评论 +110. 通知-@我 +111. 通知-通知 +112. 设置 +113. 云盘数据详情 +114. 私信内容 +115. 我的数字专辑 +116. batch批量请求接口 +117. 获取视频标签列表 +118. 全部mv +119. 网易出品mv +120. 收藏/取消收藏专辑 +121. 专辑动态信息 +122. 热搜列表(详细) +123. 更换绑定手机 +124. 检测手机号码是否已注册 +125. 初始化昵称 +126. 更新歌单描述 +127. 更新歌单名 +128. 更新歌单标签 +129. 默认搜索关键词 +130. 删除歌单 +131. 电台banner +132. 用户电台 +133. 热门电台 +134. 电台 - 节目详情 +135. 电台 - 节目榜 +136. 电台 - 新晋电台榜/热门电台榜 +137. 类别热门电台 +138. 云村热评 +139. 电台24小时节目榜 +140. 电台24小时主播榜 +141. 电台最热主播榜 +142. 电台主播新人榜 +143. 电台付费精品榜 +144. 歌手热门50首歌曲 +145. 购买数字专辑 +146. 获取 mv 点赞转发评论数数据 +147. 获取视频点赞转发评论数数据 +148. 调整歌单顺序 +149. 调整歌曲顺序 +150. 独家放送列表 +151. 获取推荐视频 +152. 获取视频分类列表 +153. 获取全部视频列表接口 +154. 获取历史日推可用日期列表 +155. 获取历史日推详细数据 +156. 国家编码列表 +157. 首页-发现 +158. 首页-发现-圆形图标入口列表 +159. 数字专辑-全部新碟 +160. 数字专辑-热门新碟 +161. 数字专辑&数字单曲-榜单 +162. 数字专辑-语种风格馆 +163. 数字专辑详情 +164. 更新头像 +165. 歌单封面上传 +166. 楼层评论 +167. 歌手全部歌曲 +168. 精品歌单标签列表 +169. 用户等级信息 +170. 电台个性推荐 +171. 用户绑定信息 +172. 用户绑定手机 +173. 新版评论 +174. 点赞过的视频 +175. 收藏视频到视频歌单 +176. 删除视频歌单里的视频 +177. 最近播放的视频 +178. 音乐日历 +179. 电台订阅者列表 +180. 云贝签到信息 +181. 云贝签到 +182. 云贝所有任务 +183. 云贝todo任务 +184. 云贝今日签到信息 +185. 云贝完成任务 +186. 云贝收入 +187. 云贝支出 +188. 云贝账户信息 +189. 账号信息 +190. 最近联系人 +191. 私信音乐 +192. 抱一抱评论 +193. 评论抱一抱列表 +194. 收藏的专栏 +195. 关注歌手新歌 +196. 关注歌手新MV +197. 歌手详情 +198. 云盘上传 +199. 二维码登录 +200. 话题详情 +201. 话题详情热门动态 +202. 歌单详情动态 +203. 绑定手机 +204. 一起听状态 +205. 用户历史评论 +206. 云盘歌曲信息匹配纠正 +207. 云贝推歌 +208. 云贝推歌历史记录 +209. 已购单曲 +210. 获取mlog播放地址 +211. 将mlog id转为视频id +212. vip成长值 +213. vip成长值获取记录 +214. vip任务 +215. 领取vip成长值 +216. 歌手粉丝 +217. 数字专辑详情 +218. 数字专辑销量 +219. 音乐人数据概况 +220. 音乐人播放趋势 +221. 音乐人任务 +222. 账号云豆数 +223. 领取云豆 +224. 获取 VIP 信息 +225. 音乐人签到 +226. 发送文本动态 +227. 获取客户端歌曲下载 url +228. 获取歌单所有歌曲 +229. 乐签信息 +230. 最近播放-歌曲 +231. 最近播放-视频 +232. 最近播放-声音 +233. 最近播放-歌单 +234. 最近播放-专辑 +235. 最近播放-播客 +236. 签到进度 +237. 重复昵称检测 +238. 歌手粉丝数量 +239. 音乐人任务(新) +240. 内部版本接口 +241. 歌单更新播放量 +242. 黑胶时光机 +243. 音乐百科 - 简要信息 +244. 乐谱列表 +245. 乐谱内容 +246. 曲风列表 +247. 曲风偏好 +248. 曲风详情 +249. 曲风-歌曲 +250. 曲风-专辑 +251. 曲风-歌单 +252. 曲风-歌手 +253. 私信和通知接口 +254. 回忆坐标 +255. 播客搜索 +256. 播客声音上传 +257. 验证接口-二维码生成 +258. 验证接口-二维码检测 +259. 听歌识曲 +260. 根据nickname获取userid接口 + +## 更新日志 + +[changelog](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/CHANGELOG.MD) + +## 单元测试 + +```shell +$ npm test +``` + +![单元测试](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/screenshot1.png) +![单元测试](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/screenshot2.png) + +## SDK + +| 语言 | 作者 | 地址 | 类型 | +| :--: | :-----------------------------------------: | :----------------------------------------------------------: | :----: | +| Java | [JackuXL](https://github.com/JackuXL) | [https://github.com/JackuXL/NeteaseCloudMusicApi-SDK](https://github.com/JackuXL/NeteaseCloudMusicApi-SDK) | 第三方 | +| Java | [1015770492](https://github.com/1015770492) | https://github.com/1015770492/yumbo-music-utils | 第三方 | + +## 贡献者 + +![](https://opencollective.com/NeteaseCloudMusicApi/contributors.svg?width=890) + + +## License + +[The MIT License (MIT)](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/LICENSE) diff --git a/WebSourceCode/src/Netease/app.js b/WebSourceCode/src/Netease/app.js new file mode 100755 index 0000000..1c662e0 --- /dev/null +++ b/WebSourceCode/src/Netease/app.js @@ -0,0 +1,18 @@ +#!/usr/bin/env node +const fs = require('fs') +const path = require('path') +const tmpPath = require('os').tmpdir() + +async function start() { + // 检测是否存在 anonymous_token 文件,没有则生成 + if (!fs.existsSync(path.resolve(tmpPath, 'anonymous_token'))) { + fs.writeFileSync(path.resolve(tmpPath, 'anonymous_token'), '', 'utf-8') + } + // 启动时更新anonymous_token + const generateConfig = require('./generateConfig') + await generateConfig() + require('./server').serveNcmApi({ + checkVersion: true, + }) +} +start() diff --git a/WebSourceCode/src/Netease/docs/.nojekyll b/WebSourceCode/src/Netease/docs/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/WebSourceCode/src/Netease/docs/README.md b/WebSourceCode/src/Netease/docs/README.md new file mode 100644 index 0000000..d48261b --- /dev/null +++ b/WebSourceCode/src/Netease/docs/README.md @@ -0,0 +1,4298 @@ +# NeteaseCloudMusicApi + +网易云音乐 NodeJS 版 API + +## 灵感来自 + +[disoul/electron-cloud-music](https://github.com/disoul/electron-cloud-music) + +[darknessomi/musicbox](https://github.com/darknessomi/musicbox) + +[sqaiyan/netmusic-node](https://github.com/sqaiyan/netmusic-node) + +## 工作原理 + +跨站请求伪造 (CSRF), 伪造请求头 , 调用官方 API + +## 功能特性 + +1. 登录 +2. 刷新登录 +3. 发送验证码 +4. 校验验证码 +5. 注册(修改密码) +6. 获取用户信息 , 歌单,收藏,mv, dj 数量 +7. 获取用户歌单 +8. 获取用户电台 +9. 获取用户关注列表 +10. 获取用户粉丝列表 +11. 获取用户动态 +12. 获取用户播放记录 +13. 获取精品歌单 +14. 获取歌单详情 +15. 搜索 +16. 搜索建议 +17. 获取歌词 +18. 歌曲评论 +19. 收藏单曲到歌单 +20. 专辑评论 +21. 歌单评论 +22. mv 评论 +23. 电台节目评论 +24. banner +25. 获取歌曲详情 +26. 获取专辑内容 +27. 获取歌手单曲 +28. 获取歌手 mv +29. 获取歌手专辑 +30. 获取歌手描述 +31. 获取相似歌手 +32. 获取相似歌单 +33. 相似 mv +34. 获取相似音乐 +35. 获取最近 5 个听了这首歌的用户 +36. 获取每日推荐歌单 +37. 获取每日推荐歌曲 +38. 私人 FM +39. 签到 +40. 喜欢音乐 +41. 垃圾桶 +42. 歌单 ( 网友精选碟 ) +43. 新碟上架 +44. 热门歌手 +45. 最新 mv +46. 推荐 mv +47. 推荐歌单 +48. 推荐新音乐 +49. 推荐电台 +50. 推荐节目 +51. 独家放送 +52. mv 排行 +53. 获取 mv 数据 +54. 播放 mv/视频 +55. 排行榜 +56. 歌手榜 +57. 云盘 +58. 电台 - 推荐 +59. 电台 - 分类 +60. 电台 - 分类推荐 +61. 电台 - 订阅 +62. 电台 - 详情 +63. 电台 - 节目 +64. 给评论点赞 +65. 获取动态 +66. 热搜列表(简略) +67. 发送私信 +68. 发送私信歌单 +69. 新建歌单 +70. 收藏/取消收藏歌单 +71. 歌单分类 +72. 收藏的歌手列表 +73. 订阅的电台列表 +74. 相关歌单推荐 +75. 付费精选接口 +76. 音乐是否可用检查接口 +77. 登录状态 +78. 获取视频播放地址 +79. 发送/删除评论 +80. 热门评论 +81. 视频评论 +82. 退出登录 +83. 所有榜单 +84. 所有榜单内容摘要 +85. 收藏视频 +86. 收藏 MV +87. 视频详情 +88. 相关视频 +89. 关注用户 +90. 新歌速递 +91. 喜欢音乐列表(无序) +92. 收藏的 MV 列表 +93. 获取最新专辑 +94. 听歌打卡 +95. 获取视频标签/分类下的视频 +96. 已收藏专辑列表 +97. 获取动态评论 +98. 歌单收藏者列表 +99. 云盘歌曲删除 +100. 热门话题 +101. 电台 - 推荐类型 +102. 电台 - 非热门类型 +103. 电台 - 今日优选 +104. 心动模式/智能播放 +105. 转发动态 +106. 删除动态 +107. 分享歌曲、歌单、mv、电台、电台节目到动态 +108. 通知-私信 +109. 通知-评论 +110. 通知-@我 +111. 通知-通知 +112. 设置 +113. 云盘数据详情 +114. 私信内容 +115. 我的数字专辑 +116. batch 批量请求接口 +117. 获取视频标签列表 +118. 全部 mv +119. 网易出品 mv +120. 收藏/取消收藏专辑 +121. 专辑动态信息 +122. 热搜列表(详细) +123. 更换绑定手机 +124. 检测手机号码是否已注册 +125. 初始化昵称 +126. 更新歌单描述 +127. 更新歌单名 +128. 更新歌单标签 +129. 默认搜索关键词 +130. 删除歌单 +131. 电台 banner +132. 用户电台 +133. 热门电台 +134. 电台 - 节目详情 +135. 电台 - 节目榜 +136. 电台 - 新晋电台榜/热门电台榜 +137. 类别热门电台 +138. 云村热评(官方下架,暂不能用) +139. 电台 24 小时节目榜 +140. 电台 24 小时主播榜 +141. 电台最热主播榜 +142. 电台主播新人榜 +143. 电台付费精品榜 +144. 歌手热门 50 首歌曲 +145. 购买数字专辑 +146. 获取 mv 点赞转发评论数数据 +147. 获取视频点赞转发评论数数据 +148. 调整歌单顺序 +149. 调整歌曲顺序 +150. 独家放送列表 +151. 获取推荐视频 +152. 获取视频分类列表 +153. 获取全部视频列表接口 +154. 获取历史日推可用日期列表 +155. 获取历史日推详细数据 +156. 国家编码列表 +157. 首页-发现 +158. 首页-发现-圆形图标入口列表 +159. 全部新碟 +160. 数字专辑-新碟上架 +161. 数字专辑&数字单曲-榜单 +162. 数字专辑-语种风格馆 +163. 数字专辑详情 +164. 更新头像 +165. 歌单封面上传 +166. 楼层评论 +167. 歌手全部歌曲 +168. 精品歌单标签列表 +169. 用户等级信息 +170. 电台个性推荐 +171. 用户绑定信息 +172. 用户绑定手机 +173. 新版评论 +174. 点赞过的视频 +175. 收藏视频到视频歌单 +176. 删除视频歌单里的视频 +177. 最近播放的视频 +178. 音乐日历 +179. 电台订阅者列表 +180. 云贝签到信息 +181. 云贝签到 +182. 云贝所有任务 +183. 云贝 todo 任务 +184. 云贝今日签到信息 +185. 云贝完成任务 +186. 云贝收入 +187. 云贝支出 +188. 云贝账户信息 +189. 账号信息 +190. 最近联系人 +191. 私信音乐 +192. 抱一抱评论 +193. 评论抱一抱列表 +194. 收藏的专栏 +195. 关注歌手新歌 +196. 关注歌手新 MV +197. 歌手详情 +198. 云盘上传 +199. 二维码登录 +200. 话题详情 +201. 话题详情热门动态 +202. 歌单详情动态 +203. 绑定手机 +204. 一起听状态 +205. 用户历史评论 +206. 云盘歌曲信息匹配纠正 +207. 云贝推歌 +208. 云贝推歌历史记录 +209. 已购单曲 +210. 获取 mlog 播放地址 +211. 将 mlog id 转为视频 id +212. vip 成长值 +213. vip 成长值获取记录 +214. vip 任务 +215. 领取 vip 成长值 +216. 歌手粉丝 +217. 数字专辑详情 +218. 数字专辑销量 +219. 音乐人数据概况 +220. 音乐人播放趋势 +221. 音乐人任务 +222. 账号云豆数 +223. 领取云豆 +224. 获取 VIP 信息 +225. 音乐人签到 +226. 获取客户端歌曲下载 url +227. 获取歌单所有歌曲 +228. 乐签信息 +229. 获取歌手视频 +230. 最近播放-歌曲 +231. 最近播放-视频 +232. 最近播放-声音 +233. 最近播放-歌单 +234. 最近播放-专辑 +235. 最近播放-播客 +236. 签到进度 +237. 重复昵称检测 +238. 歌手粉丝数量 +239. 音乐人任务(新) +240. 内部版本接口 +241. 歌单更新播放量 +242. 黑胶时光机 +243. 音乐百科 - 简要信息 +244. 乐谱列表 +245. 乐谱内容 +246. 曲风列表 +247. 曲风偏好 +248. 曲风详情 +249. 曲风-歌曲 +250. 曲风-专辑 +251. 曲风-歌单 +252. 曲风-歌手 +253. 私信和通知接口 +254. 回忆坐标 +255. 播客搜索 +256. 播客声音上传 +257. 验证接口-二维码生成 +258. 验证接口-二维码检测 +259. 听歌识曲 +260. 根据nickname获取userid接口 +261. 播客声音列表 + +## 安装 + +```shell +$ git clone git@github.com:Binaryify/NeteaseCloudMusicApi.git +$ cd NeteaseCloudMusicApi +$ npm install +``` + +## 运行 + +```shell +$ node app.js +``` + +服务器启动默认端口为 3000, 若不想使用 3000 端口 , 可使用以下命令 : Mac/Linux + +```shell +$ PORT=4000 node app.js +``` + +windows 下使用 git-bash 或者 cmder 等终端执行以下命令 : + +```shell +$ set PORT=4000 && node app.js +``` + +服务器启动默认 host 为 localhost,如果需要更改, 可使用以下命令 : Mac/Linux + +```shell +$ HOST=127.0.0.1 node app.js +``` + +windows 下使用 git-bash 或者 cmder 等终端执行以下命令 : + +```shell +$ set HOST=127.0.0.1 && node app.js +``` + +### npx 方式运行 +支持 npx 方式运行,会自动安装依赖和运行 +``` +npx NeteaseCloudMusicApi +``` +如果需要更新,可使用 `npx NeteaseCloudMusicApi@版本号` 方式运行 + +或者运行 +``` +npx NeteaseCloudMusicApi@latest + +``` +此命令每次执行都会使用最新版 + +## Vercel 部署 + +v4.0.8 加入了 Vercel 配置文件,可以直接在 Vercel 下部署了,不需要自己的服务器(访问 Vercel 部署的接口,需要额外加一个 realIP 参数,如 `/song/url?id=191254&realIP=116.25.146.177`) + +不能正常访问的,绑定下国内备案过的域名,之后即可正常访问 + +### 操作方法 + +1. fork 此项目 +2. 在 Vercel 官网点击 `New Project` +3. 点击 `Import Git Repository` 并选择你 fork 的此项目并点击`import` +4. 点击 `PERSONAL ACCOUNT` 的 `select` +5. 直接点`Continue` +6. `PROJECT NAME`自己填,`FRAMEWORK PRESET` 选 `Other` 然后直接点 `Deploy` 接着等部署完成即可 + + +## 腾讯云 serverless 部署 +因 `Vercel` 在国内访问太慢(不绑定自己的域名的情况下),在此提供腾讯云 serverless 部署方法(注意:腾讯云 serverless 并不是免费的,前三个月有免费额度,之后收费) +### 操作方法 +1. fork 此项目 +2. 在腾讯云serverless应用管理页面( https://console.cloud.tencent.com/sls ),点击`新建应用` +3. 顶部`创建方式`选择 `Web 应用` +4. 选择 `Express框架`,点击底部`下一步按钮` +5. 输入`应用名`,上传方式选择`代码仓库`,进行GitHub授权(如已授权可跳过这一步),代码仓库选择刚刚fork的项目 +6. 启动文件填入: +``` +#!/bin/bash +export PORT=9000 +/var/lang/node16/bin/node app.js +``` +7. 点击`完成`,等待部署完成,点击`资源列表`的 `API网关` 里的 `URL`,正常情况会打开文档地址,点击文档`例子`可查看接口调用效果 + +## 可以使用代理 + +在 query 参数中加上 proxy=your-proxy 即可让这一次的请求使用 proxy + +```javascript +// 例子 +const url = `http://localhost:3000/song/url?id=33894312&proxy=http://121.196.226.246:84` +fetch(url).then(function () { + // do what you want +}) + +// 结果 +// {"data":[{"id":33894312,"url":"http://m10.music.126.net/20180104125640/930a968b3fb04908b733506b3833e60b/ymusic/0fd6/4f65/43ed/a8772889f38dfcb91c04da915b301617.mp3","br":320000,"size":10691439,"md5":"a8772889f38dfcb91c04da915b301617","code":200,"expi":1200,"type":"mp3","gain":-2.0E-4,"fee":0,"uf":null,"payed":0,"flag":0,"canExtend":false}],"code": 200} +``` + +v3.3.0 后支持使用 PAC 代理,如 `?proxy=http://192.168.0.1/proxy.pac` + +## 可以在 Node.js 调用 + +v3.31.0 后支持 Node.js 调用,导入的方法为`module`内的文件名,返回内容包含`status`和`body`,`status`为状态码,`body`为请求返回内容,参考`module_example` 文件夹下的 `test.js` + +```js +const { login_cellphone, user_cloud } = require('NeteaseCloudMusicApi') +async function main() { + try { + const result = await login_cellphone({ + phone: '手机号', + password: '密码', + }) + console.log(result) + const result2 = await user_cloud({ + cookie: result.body.cookie, // 凭证 + }) + console.log(result2.body) + } catch (error) { + console.log(error) + } +} +main() +``` + +## 支持 TypeScript + +```ts +// test.ts +import { banner } from 'NeteaseCloudMusicApi' +banner({ type: 0 }).then((res) => { + console.log(res) +}) +``` + +## 更新到 v3.0 说明 + +!>2018.10.14 更新到 3.0.0,使用了模块化机制,因为部分接口参数和 url 做了调整,如还不想升级到 3.0.0,请查看 [v2 的文档](http://binaryify.github.io/NeteaseCloudMusicApi/#/v2), [更新日志](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/CHANGELOG.MD), [2.0+下载地址](https://github.com/Binaryify/NeteaseCloudMusicApi/releases/tag/v2.20.5), 同时 2.0+ 将不再维护 + +## Docker 容器运行 + +> 注意: 在 docker 中运行的时候, 由于使用了 request 来发请求, 所以会检查几个 proxy 相关的环境变量(如下所列), 这些环境变量 会影响到 request 的代理, 详情请参考[request 的文档](https://github.com/request/request#proxies), 如果这些环境变量 指向的代理不可用, 那么就会造成错误, 所以在使用 docker 的时候一定要注意这些环境变量. 不过, 要是你在 query 中加上了 proxy 参数, 那么环境变量会被覆盖, 就会用你通过 proxy 参数提供的代理了. + +request 相关的环境变量 + +1. http_proxy +2. https_proxy +3. HTTP_PROXY +4. HTTPS_PROXY +5. no_proxy +6. NO_PROXY + +```shell +docker pull binaryify/netease_cloud_music_api + +docker run -d -p 3000:3000 --name netease_cloud_music_api binaryify/netease_cloud_music_api + + +// 或者 +docker run -d -p 3000:3000 binaryify/netease_cloud_music_api + +// 去掉或者设置相关的环境变量 + +docker run -d -p 3000:3000 --name netease_cloud_music_api -e http_proxy= -e https_proxy= -e no_proxy= -e HTTP_PROXY= -e HTTPS_PROXY= -e NO_PROXY= binaryify/netease_cloud_music_api + +// 或者 +docker run -d -p 3000:3000 -e http_proxy= -e https_proxy= -e no_proxy= -e HTTP_PROXY= -e HTTPS_PROXY= -e NO_PROXY= binaryify/netease_cloud_music_api +``` + +> 以下是自行 build docker 镜像方式 + +``` +$ git clone https://github.com/Binaryify/NeteaseCloudMusicApi && cd NeteaseCloudMusicApi + +$ sudo docker build . -t netease-music-api + +$ sudo docker run -d -p 3000:3000 netease-music-api +``` + +## 接口文档 + +### 调用前须知 + +!> 本项目不提供线上 demo,请不要轻易信任使用他人提供的公开服务,以免发生安全问题,泄露自己的账号和密码 + +!> 为使用方便,降低门槛, 文档示例接口直接使用了 GET 请求,本项目同时支持 GET/POST 请按实际需求使用 (POST 请求 url 必须添加时间戳,使每次请求 url 不一样,不然请求会被缓存) + +!> 由于接口做了缓存处理 ( 缓存 2 分钟,不缓存数据极容易引起网易服务器高频 ip 错误 , 可在 app.js 设置 , 可能会导致登录后获取不到 cookie), **相同的 url** 会在两分钟内只向网易服务器发一次请求 , 如果遇到不需要缓 +存结果的接口 , 可在请求 url 后面加一个时间戳参数使 url 不同 , 例子 : +`/simi/playlist?id=347230×tamp=1503019930000` (之所以加入缓存机制是因为项目早期没有缓存机制,很多 issues 都是报 IP 高频,请按自己需求改造缓存中间件(app.js),源码不复杂) + +!> 不要频繁调登录接口,不然可能会被风控,登录状态还存在就不要重复调登录接口 + +!> 如果是跨域请求 , 请在所有请求带上 `xhrFields: { withCredentials: true }` (axios 为 `withCredentials: true`, Fetch API 为 `fetch(url, { credentials: 'include' })`), 或直接手动传入 cookie (参见 `登录`), 否则 +可能会因为没带上 cookie 导致 301, 具体例子可看 `public/test.html`, 访问`http://localhost:3000/test.html`(默认端口的话) 例子使用 jQuery 和 axios + +!> 301 错误基本都是没登录就调用了需要登录的接口,如果登录了还是提示 301, 基本都是缓存把数据缓存起来了,解决方法是加时间戳或者等待 2 分钟或者重启服务重新登录后再调用接口,可自行改造缓存方法 + +!> 部分接口如登录接口不能调用太频繁 , 否则可能会触发 503 错误或者 ip 高频错误 ,若需频繁调用 , 需要准备 IP 代理池 (更新:已加入缓存机制,但仍需注意). + +!> 本项目仅供学习使用,请尊重版权,请勿利用此项目从事商业行为或进行破坏版权行为 + +!> 文档可能会有缓存 , 如果文档版本和 github 上的版本不一致,请清除缓存再查看 + +!> 由于网易限制,此项目在国外服务器或部分国内云服务上使用会受到限制,如 `460 cheating异常`,如需解决 , 可使用`realIP`参数,传进国内IP解决,如:`?realIP=116.25.146.177` +即可解决 + +!> 图片加上 `?param=宽y高` 可控制图片尺寸,如 `http://p4.music.126.net/JzNK4a5PjjPIXAgVlqEc5Q==/109951164154280311.jpg?param=200y200`, `http://p4.music.126.net/JzNK4a5PjjPIXAgVlqEc5Q==/109951164154280311.jpg?param=50y50` + +!> 分页接口返回字段里有`more`,more 为 true 则为有下一页 + +!> 如果不需要接口headers携带cookies信息,可以加上noCookie参数,如`?noCookie=true` + +### 登录 + +说明 : 登录有三个接口,建议使用`encodeURIComponent`对密码编码或者使用`POST`请求,避免某些特殊字符无法解析,如`#`(`#`在 url 中会被识别为 hash,而不是 query) + +不要频繁调登录接口,不然可能会被风控,登录状态还存在就不要重复调登录接口 + +~~因网易增加了网易云盾验证,密码登录暂时不要使用,尽量使用短信验证码登录和二维码登录,否则调用某些接口会触发需要验证的错误~~ + +#### 1. 手机登录 + +**必选参数 :** +`phone`: 手机号码 + +`password`: 密码 + +**可选参数 :** +`countrycode`: 国家码,用于国外手机号登录,例如美国传入:`1` + +`md5_password`: md5 加密后的密码,传入后 `password` 参数将失效 + +`captcha`: 验证码,使用 [`/captcha/sent`](#发送验证码)接口传入手机号获取验证码,调用此接口传入验证码,可使用验证码登录,传入后 `password` 参数将失效 + +**接口地址 :** `/login/cellphone` + +**调用例子 :** `/login/cellphone?phone=xxx&password=yyy` `/login/cellphone?phone=xxx&md5_password=yyy` `/login/cellphone?phone=xxx&captcha=1234` + +#### 2. 邮箱登录 + +**必选参数 :** + +`email`: 163 网易邮箱 + +`password`: 密码 + +**可选参数 :** + +`md5_password`: md5 加密后的密码,传入后 `password` 将失效 + +**接口地址 :** `/login` + +**调用例子 :** `/login?email=xxx@163.com&password=yyy` + +完成登录后 , 会在浏览器保存一个 Cookies 用作登录凭证 , 大部分 API 都需要用到这个 +Cookies,非跨域情况请求会自动带上 Cookies,跨域情况参考`调用前须知` + +v3.30.0 后支持手动传入 cookie,登录接口返回内容新增 `cookie` 字段,保存到本地后,get 请求带上`?cookie=xxx` (先使用 `encodeURIComponent()` 编码 cookie 值) 或者 post 请求 body 带上 `cookie` 即可,如:`/user/cloud?cookie=xxx` 或者 + +``` +{ + ..., + cookie:"xxx" +} +``` + +#### 3. 二维码登录 + +说明: 二维码登录涉及到 3 个接口,调用务必带上时间戳,防止缓存 + +##### 1. 二维码 key 生成接口 + +说明: 调用此接口可生成一个 key + +**接口地址 :** `/login/qr/key` + +##### 2. 二维码生成接口 + +说明: 调用此接口传入上一个接口生成的 key 可生成二维码图片的 base64 和二维码信息,可使用 base64 展示图片,或者使用二维码信息内容自行使用第三方二维码生成库渲染二维码 + +必选参数: `key`,由第一个接口生成 + +可选参数: `qrimg` 传入后会额外返回二维码图片 base64 编码 + +**接口地址 :** `/login/qr/create` + +**调用例子 :** `/login/qr/create?key=xxx` + +##### 3. 二维码检测扫码状态接口 + +说明: 轮询此接口可获取二维码扫码状态,800 为二维码过期,801 为等待扫码,802 为待确认,803 为授权登录成功(803 状态码下会返回 cookies),如扫码后返回502,则需加上noCookie参数,如`&noCookie=true` + +必选参数: `key`,由第一个接口生成 + +**接口地址 :** `/login/qr/check` + +**调用例子 :** `/login/qr/check?key=xxx` + +调用可参考项目文件例子`/public/qrlogin.html` (访问地址:http://localhost:3000/qrlogin.html) + + +#### 3. 游客登录 +说明 : 直接调用此接口, 可获取游客cookie,如果遇到其他接口未登录状态报400状态码需要验证的错误,可使用此接口获取游客cookie避免报错 + +**接口地址 :** `/register/anonimous` + + +#### 注意 + +调用登录接口的速度比调用其他接口慢 , 因为登录过程调用了加密算法 + +### 刷新登录 + +说明 : 调用此接口 , 可刷新登录状态,返回内容包含新的cookie(不支持刷新二维码登录的cookie) + +**调用例子 :** `/login/refresh` + +### 发送验证码 + +说明 : 调用此接口 ,传入手机号码, 可发送验证码 + +**必选参数 :** `phone`: 手机号码 + +**可选参数 :** +`ctcode`: 国家区号,默认 86 即中国 + +**接口地址 :** `/captcha/sent` + +**调用例子 :** `/captcha/sent?phone=13xxx` + +### 验证验证码 + +说明 : 调用此接口 ,传入手机号码和验证码, 可校验验证码是否正确 + +**必选参数 :** `phone`: 手机号码 + +`captcha`: 验证码 + +**可选参数 :** + +`ctcode`: 国家区号,默认 86 即中国 + +**接口地址 :** `/captcha/verify` + +**调用例子 :** `/captcha/verify?phone=13xxx&captcha=1597` + +### 注册(修改密码) + +说明 : 调用此接口 ,传入手机号码和验证码,密码,昵称, 可注册网易云音乐账号(同时可修改密码) + +**必选参数 :** + +`captcha`: 验证码 + +`phone` : 手机号码 + +`password`: 密码 + +`nickname`: 昵称 + +**可选参数 :** + +`countrycode`: 国家码,用于国外手机号,例如美国传入:`1` ,默认 86 即中国 + +**接口地址 :** `/register/cellphone` + +**调用例子 :** `/register/cellphone?phone=13xxx&password=xxxxx&captcha=1234&nickname=binary1345` + +### 检测手机号码是否已注册 + +说明 : 调用此接口 ,可检测手机号码是否已注册 +**必选参数 :** +`phone` : 手机号码 + +**可选参数 :** +`countrycode`: 国家码,用于国外手机号,例如美国传入:`1` ,默认 86 即中国 + +**接口地址 :** `/cellphone/existence/check` + +**调用例子 :** `/cellphone/existence/check?phone=13xxx` + +### 初始化昵称 + +说明 : 刚注册的账号(需登录),调用此接口 ,可初始化昵称 +**必选参数 :** +`nickname` : 昵称 + +**接口地址 :** `/activate/init/profile` + +**调用例子 :** `/activate/init/profile?nickname=testUser2019` + +### 重复昵称检测 + +说明 : 调用此接口 ,可检测昵称是否重复,并提供备用昵称 +**必选参数 :** +`nickname` : 昵称 + +**接口地址 :** `/nickname/check` + +**调用例子 :** `/nickname/check?nickname=binaryify` + + +### 更换绑定手机 + +说明 : 调用此接口 ,可更换绑定手机(流程:先发送验证码到原手机号码,再发送验证码到新手机号码然后再调用此接口) + +**必选参数 :** +`oldcaptcha`: 原手机验证码 + +`captcha`: 新手机验证码 + +`phone` : 手机号码 + +`ctcode` : 国家区号,默认 86 即中国 + +**接口地址 :** `/rebind` + +**调用例子 :** `/rebind?phone=xxx&oldcaptcha=1234&captcha=5678` + +### 退出登录 + +说明 : 调用此接口 , 可退出登录 + +**调用例子 :** `/logout` + +### 登录状态 + +说明 : 调用此接口,可获取登录状态 + +**接口地址 :** `/login/status` + +### 获取用户详情 + +说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户详情 + +**必选参数 :** `uid` : 用户 id + +**接口地址 :** `/user/detail` + +**调用例子 :** `/user/detail?uid=32953014` + +### 获取账号信息 + +说明 : 登录后调用此接口 ,可获取用户账号信息 + +**接口地址 :** `/user/account` + +**调用例子 :** `/user/account` + +### 获取用户信息 , 歌单,收藏,mv, dj 数量 + +说明 : 登录后调用此接口 , 可以获取用户信息 + +**接口地址 :** `/user/subcount` + +**调用例子 :** `/user/subcount` + +### 获取用户等级信息 + +说明 : 登录后调用此接口 , 可以获取用户等级信息,包含当前登录天数,听歌次数,下一等级需要的登录天数和听歌次数,当前等级进度,对应 https://music.163.com/#/user/level + +**接口地址 :** `/user/level` + +**调用例子 :** `/user/level` + +### 获取用户绑定信息 + +说明 : 登录后调用此接口 , 可以获取用户绑定信息 + +**必选参数 :** `uid` : 用户 id + +**接口地址 :** `/user/binding` + +**调用例子 :** `/user/binding?uid=32953014` + +### 用户绑定手机 + +说明 : 登录后调用此接口 , 可以更换绑定手机 + +**必选参数 :** + +`phone` : 手机号码 + +`oldcaptcha`: 原手机号码的验证码 + +`captcha`:新手机号码的验证码 + +**可选参数 :** + +`countrycode`: 国家地区代码,默认 86 + +**接口地址 :** `/user/replacephone` + +**调用例子 :** `/user/replacephone?phone=xxx&captcha=1234&oldcaptcha=2345` + +### 更新用户信息 + +说明 : 登录后调用此接口 , 传入相关信息,可以更新用户信息 + +**必选参数 :** + +``` +gender: 性别 0:保密 1:男性 2:女性 + +birthday: 出生日期,时间戳 unix timestamp + +nickname: 用户昵称 + +province: 省份id + +city: 城市id + +signature:用户签名 +``` + +**接口地址 :** `/user/update` + +**调用例子 :** `/user/update?gender=0&signature=测试签名&city=440300&nickname=binary&birthday=1525918298004&province=440000` + +### 更新头像 + +说明 : 登录后调用此接口,使用`'Content-Type': 'multipart/form-data'`上传图片 formData(name 为'imgFile'),可更新头像(参考: https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/public/avatar_update.html ),支持命令行调用,参考module_example目录下`avatar_upload.js` + +**可选参数 :** + +`imgSize` : 图片尺寸,默认为 300 + +`imgX` : 水平裁剪偏移,方形图片可不传,默认为 0 +`imgY` : 垂直裁剪偏移,方形图片可不传,默认为 0 + +**接口地址 :** `/avatar/upload` + +**调用例子 :** `/avatar/upload?imgSize=200` + +### 私信和通知接口 + +说明 : 登录后调用此接口,可获取私信和通知数量信息 + +**接口地址 :** `/pl/count` + +**调用例子 :** `/pl/count` + +### 国家编码列表 + +说明 : 调用此接口,可获取国家编码列表 + +**接口地址 :** `/countries/code/list` + +### 获取用户歌单 + +说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户歌单 + +**必选参数 :** `uid` : 用户 id + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +**接口地址 :** `/user/playlist` + +**调用例子 :** `/user/playlist?uid=32953014` + +返回数据如下图 : +![用户歌单](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E7%94%A8%E6%88%B7%E6%AD%8C%E5%8D%95.png) + +### 更新歌单 + +说明 : 登录后调用此接口,可以更新用户歌单 + +**必选参数 :** + +``` +id:歌单id + +name:歌单名字 + +desc:歌单描述 + +tags:歌单tag ,多个用 `;` 隔开,只能用官方规定标签 +``` + +**接口地址 :** `/playlist/update` + +**调用例子 :** `/playlist/update?id=24381616&name=新歌单&desc=描述&tags=欧美` + +### 更新歌单描述 + +说明 : 登录后调用此接口,可以单独更新用户歌单描述 + +**必选参数 :** + +``` +id:歌单id + +desc:歌单描述 + +``` + +**接口地址 :** `/playlist/desc/update` + +**调用例子 :** `/playlist/desc/update?id=24381616&desc=描述` + +### 更新歌单名 + +说明 : 登录后调用此接口,可以单独更新用户歌单名 + +**必选参数 :** + +``` +id: 歌单id + +name: 歌单名 + +``` + +**接口地址 :** `/playlist/name/update` + +**调用例子 :** `/playlist/name/update?id=24381616&name=歌单名` + +### 更新歌单标签 + +说明 : 登录后调用此接口,可以单独更新用户歌单标签 + +**必选参数 :** + +``` +id: 歌单id + +tags: 歌单标签 + +``` + +**接口地址 :** `/playlist/tags/update` + +**调用例子 :** `/playlist/tags/update?id=24381616&tags=学习` + +### 歌单封面上传 + +说明 : 登录后调用此接口,使用`'Content-Type': 'multipart/form-data'`上传图片 formData(name 为'imgFile'),可更新歌单封面(参考:https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/public/playlist_cover_update.html) + +**必选参数 :** +`id`: 歌单 id 3143833470 + +**可选参数 :** + +`imgSize` : 图片尺寸,默认为 300 + +`imgX` : 水平裁剪偏移,方形图片可不传,默认为 0 +`imgY` : 垂直裁剪偏移,方形图片可不传,默认为 0 + +**接口地址 :** `/playlist/cover/update` + +**调用例子 :** `/playlist/cover/update?id=3143833470&imgSize=200` + +### 调整歌单顺序 + +说明 : 登录后调用此接口,可以根据歌单 id 顺序调整歌单顺序 + +**必选参数 :** + +`ids`: 歌单 id 列表 + +**接口地址 :** `/playlist/order/update` + +**调用例子 :** `/playlist/order/update?ids=[111,222]` + +### 调整歌曲顺序 + +说明 : 登录后调用此接口,可以根据歌曲 id 顺序调整歌曲顺序 + +**必选参数 :** +`pid`: 歌单 id + +`ids`: 歌曲 id 列表 + +**接口地址 :** `/song/order/update` + +**调用例子 :** `/song/order/update?pid=2039116066&ids=[5268328,1219871]` + +### 获取用户历史评论 + +说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户历史评论 + +**必选参数 :** `uid` : 用户 id + +**可选参数 :** + +`limit` : 返回数量 , 默认为 10 + +`time`: 上一条数据的 time,第一页不需要传,默认为 0 + +**接口地址 :** `/user/comment/history` + +**调用例子 :** `/user/comment/history?uid=32953014` `/user/comment/history?uid=32953014&limit=1&time=1616217577564` (需要换成自己的用户 id) + +### 获取用户电台 + +说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户电台 + +**必选参数 :** `uid` : 用户 id + +**接口地址 :** `/user/dj` + +**调用例子 :** `/user/dj?uid=32953014` + +### 获取用户关注列表 + +说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户关注列表 + +**必选参数 :** `uid` : 用户 id + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 ,如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +**接口地址 :** `/user/follows` + +**调用例子 :** `/user/follows?uid=32953014` + +### 获取用户粉丝列表 + +说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户粉丝列表 + +**必选参数 :** `uid` : 用户 id + +**可选参数 :** +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 ,如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +**接口地址 :** `/user/followeds` + +**调用例子 :** `/user/followeds?uid=32953014` `/user/followeds?uid=416608258&limit=1` `/user/followeds?uid=416608258&limit=1&offset=1` + +### 获取用户动态 + +说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户动态 + +**必选参数 :** `uid` : 用户 id + +**可选参数 :** `limit` : 返回数量 , 默认为 30 + +`lasttime` : 返回数据的 `lasttime` ,默认-1,传入上一次返回结果的 lasttime,将会返回下一页的数据 + +**接口地址 :** `/user/event` + +**调用例子 :** `/user/event?uid=32953014` `/user/event?uid=32953014&limit=1&lasttime=1558011138743` + +返回结果的`type`参数对应: + +``` +18 分享单曲 +19 分享专辑 +17、28 分享电台节目 +22 转发 +39 发布视频 +35、13 分享歌单 +24 分享专栏文章 +41、21 分享视频 +``` + +### 转发用户动态 + +说明 : 登录后调用此接口 ,可以转发用户动态 + +**必选参数 :** `uid` : 用户 id + +`evId` : 动态 id + +`forwards` : 转发的评论 + +**接口地址 :** `/event/forward` + +**调用例子 :** `/event/forward?evId=6712917601&uid=32953014&forwards=测试内容` + +### 删除用户动态 + +说明 : 登录后调用此接口 ,可以删除用户动态 + +**必选参数 :** `evId` : 动态 id + +**接口地址 :** `/event/del` + +**调用例子 :** `/event/del?evId=6712917601` + +### 分享文本、歌曲、歌单、mv、电台、电台节目到动态 + +说明 : 登录后调用此接口 ,可以分享文本、歌曲、歌单、mv、电台、电台节目,专辑到动态 + +**必选参数 :** `id` : 资源 id (歌曲,歌单,mv,电台,电台节目对应 id) + +**可选参数 :** `type`: 资源类型,默认歌曲 song,可传 `song`,`playlist`,`mv`,`djradio`,`djprogram`, `album` + +`msg`: 内容,140 字限制,支持 emoji,@用户名(`/user/follows`接口获取的用户名,用户名后和内容应该有空格),图片暂不支持 + +**接口地址 :** `/share/resource` + +**调用例子 :** `/share/resource?id=1297494209&msg=测试` `/share/resource?type=djradio&id=336355127` `/share/resource?type=djprogram&id=2061034798` `/share/resource?type=djprogram&id=2061034798&msg=测试@binaryify 测试` `/share/resource?type=noresource&msg=测试` + +### 获取动态评论 + +说明 : 登录后调用此接口 , 可以获取动态下评论 + +**必选参数 :** `threadId` : 动态 id,可通过 `/event`,`/user/event` 接口获取 + +**接口地址 :** `/comment/event` + +**调用例子 :** `/comment/event?threadId=A_EV_2_6559519868_32953014` + +### 关注/取消关注用户 + +说明 : 登录后调用此接口 , 传入用户 id, 和操作 t,可关注/取消关注用户 + +**必选参数 :** + +`id` : 用户 id + +`t` : `1`为关注,其他为取消关注 + +**接口地址 :** `/follow` + +**调用例子 :** `/follow?id=32953014&t=1` + +### 获取用户播放记录 + +说明 : 登录后调用此接口 , 传入用户 id, 可获取用户播放记录 + +**必选参数 :** `uid` : 用户 id + +**可选参数 :** `type` : type=1 时只返回 weekData, type=0 时返回 allData + +**接口地址 :** `/user/record` + +**调用例子 :** `/user/record?uid=32953014&type=1` + +### 获取热门话题 + +说明 : 调用此接口 , 可获取热门话题 + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +**接口地址 :** `/hot/topic` + +**调用例子 :** `/hot/topic?limit=30&offset=30` + +### 获取话题详情 + +说明 : 调用此接口 , 可获取话题详情 + +**接口地址 :** `/topic/detail` + +**调用例子 :** `/topic/detail?actid=111551188` + +### 获取话题详情热门动态 + +说明 : 调用此接口 , 可获取话题详情热门动态 + +**接口地址 :** `/topic/detail/event/hot` + +**调用例子 :** `/topic/detail/event/hot?actid=111551188` + +### 云村热评(官方下架,暂不能用) + +说明 : 登录后调用此接口 , 可获取云村热评 + +**接口地址 :** `/comment/hotwall/list` + +**调用例子 :** `/comment/hotwall/list` + +### 心动模式/智能播放 + +说明 : 登录后调用此接口 , 可获取心动模式/智能播放列表 +**必选参数 :** `id` : 歌曲 id + +`pid` : 歌单 id + +**可选参数 :** +`sid` : 要开始播放的歌曲的 id + +**接口地址 :** `/playmode/intelligence/list` + +**调用例子 :** `/playmode/intelligence/list?id=33894312&pid=24381616` , `/playmode/intelligence/list?id=33894312&pid=24381616&sid=36871368` + +### 获取动态消息 + +说明 : 调用此接口 , 可获取各种动态 , 对应网页版网易云,朋友界面里的各种动态消息 +,如分享的视频,音乐,照片等! + +**必选参数 :** +`pagesize` : 每页数据,默认 20 + +`lasttime` : 返回数据的 `lasttime` ,默认-1,传入上一次返回结果的 lasttime,将会返回下一页的数据 + +**接口地址 :** `/event` + +**调用例子 :** `/event?pagesize=30&lasttime=1556740526369` + +### 歌手分类列表 + +说明 : 调用此接口,可获取歌手分类列表 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 +: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 +`initial`: 按首字母索引查找参数,如 `/artist/list?type=1&area=96&initial=b` 返回内容将以 name 字段开头为 b 或者拼音开头为 b 为顺序排列, 热门传-1,#传 0 + +`type` 取值: + +``` +-1:全部 +1:男歌手 +2:女歌手 +3:乐队 +``` + +`area` 取值: + +``` +-1:全部 +7华语 +96欧美 +8:日本 +16韩国 +0:其他 +``` + +**接口地址 :** `/artist/list` + +**调用例子 :** `/artist/list?type=1&area=96&initial=b` `/artist/list?type=2&area=2&initial=b` + +### 收藏/取消收藏歌手 + +说明 : 调用此接口,可收藏歌手 + +**必选参数 :** + +`id` : 歌手 id + +`t`:操作,1 为收藏,其他为取消收藏 + +**接口地址 :** `/artist/sub` + +**调用例子 :** `/artist/sub?id=6452&t=1` + +### 歌手热门 50 首歌曲 + +说明 : 调用此接口,可获取歌手热门 50 首歌曲 + +**必选参数 :** + +`id` : 歌手 id + +**接口地址 :** `/artist/top/song` + +**调用例子 :** `/artist/top/song?id=6452` + +### 歌手全部歌曲 + +说明 : 调用此接口,可获取歌手全部歌曲 +**必选参数 :** + +`id` : 歌手 id + +**可选参数 :** + +`order` : `hot` ,`time` 按照热门或者时间排序 + +`limit`: 取出歌单数量 , 默认为 50 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*50, 其中 50 为 limit 的值 + +**接口地址 :** `/artist/songs` + +**调用例子 :** `/artist/songs?id=6452` + +### 收藏的歌手列表 + +说明 : 调用此接口,可获取收藏的歌手列表 + +**可选参数 :** + +`limit`: 取出歌单数量 , 默认为 25 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*25, 其中 25 为 limit 的值 + +**接口地址 :** `/artist/sublist` + +**调用例子 :** `/artist/sublist` + +### 收藏的专栏 + +说明 : 调用此接口,可获取收藏的专栏 + +**可选参数 :** + +`limit`: 取出歌单数量 , 默认为 50 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*50, 其中 50 为 limit 的值 + +**接口地址 :** `/topic/sublist` + +**调用例子 :** `/topic/sublist?limit=2&offset=1` + +### 收藏视频 + +说明 : 调用此接口,可收藏视频 + +**必选参数 :** + +`id` : 视频 id + +`t` : 1 为收藏,其他为取消收藏 + +**接口地址 :** `/video/sub` + +**调用例子 :** `/video/sub` + +### 收藏/取消收藏 MV + +说明 : 调用此接口,可收藏/取消收藏 MV + +**必选参数 :** + +`mvid` : MV id + +`t` : 1 为收藏,其他为取消收藏 + +**接口地址 :** `/mv/sub` + +**调用例子 :** `/mv/sub` + +### 收藏的 MV 列表 + +说明 : 调用此接口,可获取收藏的 MV 列表 + +**接口地址 :** `/mv/sublist` + +**调用例子 :** `/mv/sublist` + +### 歌单分类 + +说明 : 调用此接口,可获取歌单分类,包含 category 信息 + +**接口地址 :** `/playlist/catlist` + +**调用例子 :** `/playlist/catlist` + +### 热门歌单分类 + +说明 : 调用此接口,可获取歌单分类,包含 category 信息 + +**接口地址 :** `/playlist/hot` + +**调用例子 :** `/playlist/hot` + +### 歌单 ( 网友精选碟 ) + +说明 : 调用此接口 , 可获取网友精选碟歌单 + +**可选参数 :** `order`: 可选值为 'new' 和 'hot', 分别对应最新和最热 , 默认为 +'hot' + +`cat`: tag, 比如 " 华语 "、" 古风 " 、" 欧美 "、" 流行 ", 默认为 +"全部",可从歌单分类接口获取(/playlist/catlist) + +`limit`: 取出歌单数量 , 默认为 50 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*50, 其中 50 为 limit 的值 + +**接口地址 :** `/top/playlist` + +**调用例子 :** `/top/playlist?limit=10&order=new` + +### 精品歌单标签列表 + +说明 : 调用此接口 , 可获取精品歌单标签列表 + +**接口地址 :** `/playlist/highquality/tags` + +**调用例子 :** `/playlist/highquality/tags` + +### 获取精品歌单 + +说明 : 调用此接口 , 可获取精品歌单 + +**可选参数 :** `cat`: tag, 比如 " 华语 "、" 古风 " 、" 欧美 "、" 流行 ", 默认为 +"全部",可从精品歌单标签列表接口获取(`/playlist/highquality/tags`) + +`limit`: 取出歌单数量 , 默认为 50 + +`before`: 分页参数,取上一页最后一个歌单的 `updateTime` 获取下一页数据 + +**接口地址 :** `/top/playlist/highquality` + +**调用例子 :** `/top/playlist/highquality?before=1503639064232&limit=3` + +### 相关歌单推荐 + +说明 : 调用此接口,传入歌单 id 可获取相关歌单(对应页面 [https://music.163.com/#/playlist?id=1](https://music.163.com/#/playlist?id=1)) + +**必选参数 :** `id` : 歌单 id + +**接口地址 :** `/related/playlist` + +**调用例子 :** `/related/playlist?id=1` + +### 获取歌单详情 + +说明 : 歌单能看到歌单名字, 但看不到具体歌单内容 , 调用此接口 , 传入歌单 id, 可 +以获取对应歌单内的所有的音乐(未登录状态只能获取不完整的歌单,登录后是完整的),但是返回的 trackIds 是完整的,tracks 则是不完整的,可拿全部 trackIds 请求一次 `song/detail` 接口获取所有歌曲的详情 ([https://github.com/Binaryify/NeteaseCloudMusicApi/issues/452](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/452)) + +**必选参数 :** `id` : 歌单 id + +**可选参数 :** `s` : 歌单最近的 s 个收藏者,默认为 8 + +**接口地址 :** `/playlist/detail` + +**调用例子 :** `/playlist/detail?id=24381616` + +### 获取歌单所有歌曲 + +说明 : 由于网易云接口限制,歌单详情只会提供 10 首歌,通过调用此接口,传入对应的歌单`id`,即可获得对应的所有歌曲 + +**必选参数 :** `id` : 歌单 id + +**可选参数 :** `limit` : 限制获取歌曲的数量,默认值为当前歌单的歌曲数量 + +**可选参数 :** `offset` : 默认值为0 + +**接口地址 :** `/playlist/track/all` + +**调用例子 :** `/playlist/track/all?id=24381616&limit=10&offset=1` + +> 注:关于`offset`,你可以这样理解,假设你当前的歌单有200首歌 +> +> 你传入limit=50&offset=0等价于limit=50,你会得到第1-50首歌曲 + +> 你传入limit=50&offset=50,你会得到第51-100首歌曲 + +> 如果你设置limit=50&offset=100,你就会得到第101-150首歌曲 + + +### 歌单详情动态 + +说明 : 调用后可获取歌单详情动态部分,如评论数,是否收藏,播放数 + +**必选参数 :** `id` : 歌单 id + +**接口地址 :** `/playlist/detail/dynamic` + +**调用例子 :** `/playlist/detail/dynamic?id=24381616` + + +### 歌单更新播放量 + +说明 : 调用后可更新歌单播放量 + +**必选参数 :** `id` : 歌单 id + +**接口地址 :** `/playlist/update/playcount` + +**调用例子 :** `/playlist/update/playcount?id=24381616` + + + + +### 获取音乐 url + +说明 : 使用歌单详情接口后 , 能得到的音乐的 id, 但不能得到的音乐 url, 调用此接口, 传入的音乐 id( 可多个 , 用逗号隔开 ), 可以获取对应的音乐的 url,未登录状态或者非会员返回试听片段(返回字段包含被截取的正常歌曲的开始时间和结束时间) + +> 注 : 部分用户反馈获取的 url 会 403,[hwaphon](https://github.com/hwaphon)找到的解决方案是当获取到音乐的 id 后,将 https://music.163.com/song/media/outer/url?id=id.mp3 以 src 赋予 Audio 即可播放 + +**必选参数 :** `id` : 音乐 id + +**可选参数 :** `br`: 码率,默认设置了 999000 即最大码率,如果要 320k 则可设置为 320000,其他类推 + +**接口地址 :** `/song/url` + +**调用例子 :** `/song/url?id=33894312` `/song/url?id=405998841,33894312` + +### 获取音乐 url - 新版 + +说明 : 使用注意事项同上 + +**必选参数 :** `id` : 音乐 id + `level`: 播放音质等级, 分为 `standard` => `标准`,`higher` => `较高`, `exhigh`=>`极高`, +`lossless`=>`无损`, `hires`=>`Hi-Res`, `jyeffect` => `高清环绕声`, `sky` => `沉浸环绕声`, +`jymaster` => `超清母带` + +**接口地址 :** `/song/url/v1` + +**调用例子 :** `/song/url/v1?id=33894312&level=exhigh` `/song/url/v1?id=405998841,33894312&level=lossless` + +### 音乐是否可用 + +说明: 调用此接口,传入歌曲 id, 可获取音乐是否可用,返回 `{ success: true, message: 'ok' }` 或者 `{ success: false, message: '亲爱的,暂无版权' }` + +**必选参数 :** `id` : 歌曲 id + +**可选参数** : `br`: 码率,默认设置了 999000 即最大码率,如果要 320k 则可设置为 320000,其他类推 + +**接口地址 :** `/check/music` + +**调用例子 :** `/check/music?id=33894312` + +### 搜索 + +说明 : 调用此接口 , 传入搜索关键词可以搜索该音乐 / 专辑 / 歌手 / 歌单 / 用户 , +关键词可以多个 , 以空格隔开 , 如 " 周杰伦 搁浅 "( 不需要登录 ), 可通过 `/song/url` 接口传入歌曲 id 获取具体的播放链接 + +**必选参数 :** `keywords` : 关键词 + +**可选参数 :** `limit` : 返回数量 , 默认为 30 `offset` : 偏移数量,用于分页 , 如 +: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +`type`: 搜索类型;默认为 1 即单曲 , 取值意义 : 1: 单曲, 10: 专辑, 100: 歌手, 1000: +歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频, 1018:综合, 2000:声音(搜索声音返回字段格式会不一样) + +**接口地址 :** `/search` 或者 `/cloudsearch`(更全) + +**调用例子 :** `/search?keywords=海阔天空` `/cloudsearch?keywords=海阔天空` + +### 默认搜索关键词 + +说明 : 调用此接口 , 可获取默认搜索关键词 + +**接口地址 :** `/search/default` + +### 热搜列表(简略) + +说明 : 调用此接口,可获取热门搜索列表 + +**接口地址 :** `/search/hot` + +**调用例子 :** `/search/hot` + +### 热搜列表(详细) + +说明 : 调用此接口,可获取热门搜索列表 + +**接口地址 :** `/search/hot/detail` + +**调用例子 :** `/search/hot/detail` + +### 搜索建议 + +说明 : 调用此接口 , 传入搜索关键词可获得搜索建议 , 搜索结果同时包含单曲 , 歌手 , 歌单信息 + +**必选参数 :** `keywords` : 关键词 + +**可选参数 :** `type` : 如果传 'mobile' 则返回移动端数据 + +**接口地址 :** `/search/suggest` + +**调用例子 :** `/search/suggest?keywords=海阔天空` `/search/suggest?keywords=海阔天空&type=mobile` + +### 搜索多重匹配 + +说明 : 调用此接口 , 传入搜索关键词可获得搜索结果 + +**必选参数 :** `keywords` : 关键词 + +**接口地址 :** `/search/multimatch` + +**调用例子 :** `/search/multimatch?keywords=海阔天空` + +### 新建歌单 + +说明 : 调用此接口 , 传入歌单名字可新建歌单 + +**必选参数 :** `name` : 歌单名 + +**可选参数 :** + +`privacy` : 是否设置为隐私歌单,默认否,传'10'则设置成隐私歌单 + +`type` : 歌单类型,默认'NORMAL',传 'VIDEO'则为视频歌单,传 'SHARED'则为共享歌单 + +**接口地址 :** `/playlist/create` + +**调用例子 :** `/playlist/create?name=测试歌单`,`/playlist/create?name=test&type=VIDEO` + +### 删除歌单 + +说明 : 调用此接口 , 传入歌单 id 可删除歌单 + +**必选参数 :** `id` : 歌单 id,可多个,用逗号隔开 + +**接口地址 :** `/playlist/delete` + +**调用例子 :** `/playlist/delete?id=2947311456` , `/playlist/delete?id=5013464397,5013427772` + +### 收藏/取消收藏歌单 + +说明 : 调用此接口 , 传入类型和歌单 id 可收藏歌单或者取消收藏歌单 + +**必选参数 :** + +`t` : 类型,1:收藏,2:取消收藏 +`id` : 歌单 id + +**接口地址 :** `/playlist/subscribe` + +**调用例子 :** `/playlist/subscribe?t=1&id=106697785` `/playlist/subscribe?t=2&id=106697785` + +### 歌单收藏者 + +说明 : 调用此接口 , 传入歌单 id 可获取歌单的所有收藏者 +**必选参数 :** + +`id` : 歌单 id + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +**接口地址 :** `/playlist/subscribers` + +**调用例子 :** `/playlist/subscribers?id=544215255&limit=30` + +### 对歌单添加或删除歌曲 + +说明 : 调用此接口 , 可以添加歌曲到歌单或者从歌单删除某首歌曲 ( 需要登录 ) + +**必选参数 :** + +`op`: 从歌单增加单曲为 add, 删除为 del + +`pid`: 歌单 id +`tracks`: 歌曲 id,可多个,用逗号隔开 + +**接口地址 :** `/playlist/tracks` + +**调用例子 :** `/playlist/tracks?op=add&pid=24381616&tracks=347231` ( 对应把歌曲添加到 ' 我 ' 的歌单 , 测试的时候请把这里的 pid 换成你自己的, id 和 tracks 不对可能会报 502 错误) + +### 收藏视频到视频歌单 + +说明 : 调用此接口 , 可收藏视频到视频歌单 ( 需要登录 ) + +**必选参数 :** + +`pid` : 歌单 id + +`ids` : 视频 id,支持多个,用`,`隔开 + +**接口地址 :** `/playlist/track/add` + +**调用例子 :** `/playlist/track/add?pid=5271999357&ids=186041` + +### 删除视频歌单里的视频 + +说明 : 调用此接口 , 可删除视频歌单里的视频 ( 需要登录 ) +**必选参数 :** + +`pid` : 歌单 id + +`ids` : 视频 id,支持多个,用`,`隔开 + +**接口地址 :** `/playlist/track/delete` + +**调用例子 :** `/playlist/track/delete?pid=5271999357&ids=186041` + +### 最近播放的视频 + +说明 : 调用此接口 , 可获取最近播放的视频 ( 需要登录 ) + +**接口地址 :** `/playlist/video/recent` + +**调用例子 :** `/playlist/video/recent` + +### 获取歌词 + +说明 : 调用此接口 , 传入音乐 id 可获得对应音乐的歌词 ( 不需要登录 ) + +**必选参数 :** `id`: 音乐 id + +**接口地址 :** `/lyric` + +**调用例子 :** `/lyric?id=33894312` + +返回数据如下图 : +![获取歌词](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E6%AD%8C%E8%AF%8D.png) + +### 获取逐字歌词 + +说明 : 此接口的 `yrc` 字段即为逐字歌词 (可能有歌曲不包含逐字歌词) + + +**必选参数 :** `id`: 音乐 id + +**接口地址 :** `/lyric/new` + +**调用例子 :** `/lyric/new?id=1824020871` + + +相关讨论可见: [Issue](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1667) + +**歌词格式解析 :** + +当逐字歌词适用时,`yrc`的`lyric`字段包括形式如下的内容 +* (可能存在)JSON 歌曲元数据 +``` +{"t":0,"c":[{"tx":"作曲: "},{"tx":"柳重言","li":"http://p1.music.126.net/Icj0IcaOjH2ZZpyAM-QGoQ==/6665239487822533.jpg","or":"orpheus://nm/artist/home?id=228547&type=artist"}]} +{"t":5403,"c":[{"tx":"编曲: "},{"tx":"Alex San","li":"http://p1.music.126.net/pSbvYkrzZ1RFKqoh-fA9AQ==/109951166352922615.jpg","or":"orpheus://nm/artist/home?id=28984845&type=artist"}]} +{"t":10806,"c":[{"tx":"制作人: "},{"tx":"王菲","li":"http://p1.music.126.net/1KQVD6XWbs5IAV0xOj1ZIA==/18764265441342019.jpg","or":"orpheus://nm/artist/home?id=9621&type=artist"},{"tx":"/"},{"tx":"梁荣骏","li":"http://p1.music.126.net/QrD8drwrRcegfKLPoiiG2Q==/109951166288436155.jpg","or":"orpheus://nm/artist/home?id=189294&type=artist"}]} +``` +该字段不一定出现;可能出现的数据意义有: +- `t` : 数据显示开始时间戳 (毫秒) +- `c` : 元数据list +- `tx`: 文字段 +- `li`: 艺术家、歌手头像图url +- `or`:云音乐app内路径;例中作用即打开艺术家主页 +* 逐字歌词 +``` +[16210,3460](16210,670,0)还(16880,410,0)没... + ~~~~1 ~~~2 ~~~~3 ~~4 5 ~6 (...) +``` +由标号解释: +1. 歌词行显示开始时间戳 (毫秒) +2. 歌词行显示总时长(毫秒) +3. 逐字显示开始时间戳 (毫秒) +4. 逐字显示时长 (厘秒/0.01s) +5. 未知 +6. 文字 + +`yrc`的`version`字段貌似与`lyric`字段格式无关 + +### 新歌速递 + +说明 : 调用此接口 , 可获取新歌速递 + +**必选参数 :** + +`type`: 地区类型 id,对应以下: + +``` +全部:0 + +华语:7 + +欧美:96 + +日本:8 + +韩国:16 +``` + +**接口地址 :** `/top/song` + +**调用例子 :** `/top/song?type=96` + +### 首页-发现 + +说明 : 调用此接口 , 可获取 APP 首页信息 + +**接口地址 :** `/homepage/block/page` + +**可选参数 :** `refresh`: 是否刷新数据,默认为 false + +`cursor`: 上一条数据返回的 cursor + +### 首页-发现-圆形图标入口列表 + +说明 : 调用此接口 , 可获取 APP 首页圆形图标入口列表 + +**接口地址 :** `/homepage/dragon/ball` + +### 歌曲评论 + +说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该音乐的所有评论 ( 不需要登录 ) + +**必选参数 :** `id`: 音乐 id + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +`before`: 分页参数,取上一页最后一项的 `time` 获取下一页数据(获取超过 5000 条评论的时候需要用到) + +**接口地址 :** `/comment/music` + +**调用例子 :** `/comment/music?id=186016&limit=1` 对应晴天评论 + +返回数据如下图 : +![获取评论](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/comment.png) + +### 楼层评论 + +说明 : 调用此接口 , 传入资源 parentCommentId 和资源类型 type 和资源 id 参数, 可获得该资源的歌曲楼层评论 + +**必选参数 :** +`parentCommentId`: 楼层评论 id + +`id` : 资源 id + +`type`: 数字 , 资源类型 , 对应歌曲 , mv, 专辑 , 歌单 , 电台, 视频对应以下类型 + +``` +0: 歌曲 + +1: mv + +2: 歌单 + +3: 专辑 + +4: 电台节目 + +5: 视频 + +6: 动态 + +7: 电台 +``` + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`time`: 分页参数,取上一页最后一项的 `time` 获取下一页数据 + +**接口地址 :** `/comment/floor` + +**调用例子 :** `/comment/floor?parentCommentId=1438569889&id=29764564&type=0` + +### 专辑评论 + +说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该专辑的所有评论 ( 不需要 +登录 ) + +**必选参数 :** `id`: 专辑 id + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +`before`: 分页参数,取上一页最后一项的 `time` 获取下一页数据(获取超过 5000 条评论的时候需要用到) + +**接口地址 :** `/comment/album` + +**调用例子 :** `/comment/album?id=32311` + +### 歌单评论 + +说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该歌单的所有评论 ( 不需要 +登录 ) + +**必选参数 :** `id`: 歌单 id + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +`before`: 分页参数,取上一页最后一项的 `time` 获取下一页数据(获取超过 5000 条评论的时候需要用到) + +**接口地址 :** `/comment/playlist` + +**调用例子 :** `/comment/playlist?id=705123491` + +### mv 评论 + +说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 mv 的所有评论 ( 不需要 +登录 ) + +**必选参数 :** `id`: mv id + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +`before`: 分页参数,取上一页最后一项的 `time` 获取下一页数据(获取超过 5000 条评论的时候需要用到) + +**接口地址 :** `/comment/mv` + +**调用例子 :** `/comment/mv?id=5436712` + +### 电台节目评论 + +说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 电台节目 的所有评论 ( +不需要登录 ) + +**必选参数 :** `id`: 电台节目的 id + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +`before`: 分页参数,取上一页最后一项的 `time` 获取下一页数据(获取超过 5000 条评论的时候需要用到) + +**接口地址 :** `/comment/dj` + +**调用例子 :** `/comment/dj?id=794062371` + +### 视频评论 + +说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 视频 的所有评论 ( +不需要登录 ) + +**必选参数 :** `id`: 视频的 id + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +`before`: 分页参数,取上一页最后一项的 `time` 获取下一页数据(获取超过 5000 条评论的时候需要用到) + +**接口地址 :** `/comment/video` + +**调用例子 :** `/comment/video?id=89ADDE33C0AAE8EC14B99F6750DB954D` + +### 热门评论 + +说明 : 调用此接口 , 传入 type, 资源 id 可获得对应资源热门评论 ( 不需要登录 ) + +**必选参数 :** + +`id` : 资源 id + +`type`: 数字 , 资源类型 , 对应歌曲 , mv, 专辑 , 歌单 , 电台, 视频对应以下类型 + +``` +0: 歌曲 + +1: mv + +2: 歌单 + +3: 专辑 + +4: 电台节目 + +5: 视频 + +6: 动态 + +7: 电台 +``` + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +`before`: 分页参数,取上一页最后一项的 `time` 获取下一页数据(获取超过 5000 条评论的时候需要用到) + +**接口地址 :** `/comment/hot` + +**调用例子 :** `/comment/hot?id=186016&type=0` + +### 新版评论接口 + +说明 : 调用此接口 , 传入资源类型和资源 id,以及排序方式,可获取对应资源的评论 + +**必选参数 :** +`id` : 资源 id, 如歌曲 id,mv id + +`type`: 数字 , 资源类型 , 对应歌曲 , mv, 专辑 , 歌单 , 电台, 视频对应以下类型 + +``` +0: 歌曲 + +1: mv + +2: 歌单 + +3: 专辑 + +4: 电台节目 + +5: 视频 + +6: 动态 + +7: 电台 +``` + +**可选参数 :** +`pageNo`:分页参数,第 N 页,默认为 1 + +`pageSize`:分页参数,每页多少条数据,默认 20 + +`sortType`: 排序方式, 1:按推荐排序, 2:按热度排序, 3:按时间排序 + +`cursor`: 当`sortType`为 3 时且页数不是第一页时需传入,值为上一条数据的 time + +**接口地址 :** `/comment/new` + +**调用例子 :** `/comment/new?type=0&id=1407551413&sortType=3`, `/comment/new?type=0&id=1407551413&sortType=3&cursor=1602072870260&pageSize=20&pageNo=2` + +### 给评论点赞 + +说明 : 调用此接口 , 传入 type, 资源 id, 和评论 id cid 和 是否点赞参数 t 即可给对 +应评论点赞 ( 需要登录 ) + +**必选参数 :** `id` : 资源 id, 如歌曲 id,mv id + +`cid` : 评论 id + +`t` : 是否点赞 , 1 为点赞 ,0 为取消点赞 + +`type`: 数字 , 资源类型 , 对应歌曲 , mv, 专辑 , 歌单 , 电台, 视频对应以下类型 + +``` +0: 歌曲 + +1: mv + +2: 歌单 + +3: 专辑 + +4: 电台节目 + +5: 视频 + +6: 动态 + +7: 电台 +``` + +**接口地址 :** `/comment/like` + +**调用例子 :** `/comment/like?id=29178366&cid=12840183&t=1&type=0` 对应给 [https://music.163.com/#/song?id=29178366](https://music.163.com/#/song?id=29178366) 最热门的评论点赞 + +注意: 动态点赞不需要传入 id 参数,需要传入动态的 `threadId` 参数,如:`/comment/like?type=6&cid=1419532712&threadId=A_EV_2_6559519868_32953014&t=0`, `threadId` 可通过 `/event`,`/user/event` 接口获取 + +### 抱一抱评论 + +说明 : 调用此接口,可抱一抱评论 + +**必选参数 :** + +`uid`: 用户 id + +`cid`: 评论 id + +`sid`: 资源 id + +**接口地址 :** `/hug/comment` + +**调用例子 :** `/hug/comment?uid=285516405&cid=1167145843&sid=863481066` + +### 评论抱一抱列表 + +说明 : 调用此接口,可获取评论抱一抱列表 + +**必选参数 :** + +`uid`: 用户 id + +`cid`: 评论 id + +`sid`: 资源 id + +**可选参数 :** + +`page`: 页数 + +`cursor`: 上一页返回的 cursor,默认-1,第一页不需要传 + +`idCursor`: 上一页返回的 idCursor,默认-1,第一页不需要传 + +`pageSize` : 每页页数,默认 100 + +**接口地址 :** `/comment/hug/list` + +**调用例子 :** `/comment/hug/list?uid=285516405&cid=1167145843&sid=863481066&pageSize=2&page=1` + +### 发送/删除评论 + +说明 : 调用此接口,可发送评论或者删除评论 + +**接口地址 :** `/comment` + +1. 发送评论 + + **必选参数** + + `t`:1 发送, 2 回复 + + `type`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型 + + ``` + 0: 歌曲 + + 1: mv + + 2: 歌单 + + 3: 专辑 + + 4: 电台 + + 5: 视频 + + 6: 动态 + ``` + + `id`:对应资源 id + + `content` :要发送的内容 + + `commentId` :回复的评论 id (回复评论时必填) + + **调用例子** : `/comment?t=1&type=1&id=5436712&content=test` (往广岛之恋 mv 发送评论: test) + + 注意:如给动态发送评论,则不需要传 id,需要传动态的 `threadId`,如:`/comment?t=1&type=6&threadId=A_EV_2_6559519868_32953014&content=test` + +2. 删除评论 + + **必选参数** + + `t`:0 删除 + + `type`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型 + + + ``` + 0: 歌曲 + + 1: mv + + 2: 歌单 + + 3: 专辑 + + 4: 电台节目 + + 5: 视频 + + 6: 动态 + + 7: 电台 + + ``` + + `id`:对应资源 id + `content` :内容 id,可通过 `/comment/mv` 等接口获取 + + **调用例子** : `/comment?t=0&type=1&id=5436712&commentId=1535550516319` (在广岛之恋 mv 删除评论) + + 注意:如给动态删除评论,则不需要传 id,需要传动态的 `threadId`,如:`/comment?t=0&type=6&threadId=A_EV_2_6559519868_32953014&commentId=1419516382` + +### banner + +说明 : 调用此接口 , 可获取 banner( 轮播图 ) 数据 + +**可选参数 :** + +`type`:资源类型,对应以下类型,默认为 0 即 PC + +``` +0: pc + +1: android + +2: iphone + +3: ipad +``` + +**接口地址 :** `/banner` + +**调用例子 :** `/banner`, `/banner?type=2` + +### 资源点赞( MV,电台,视频) + +说明 : 调用此接口 , 可对 MV,电台,视频点赞 + +**必选参数 :** + +`type`:资源类型,对应以下类型 + + +``` +0: 歌曲 + +1: mv + +2: 歌单 + +3: 专辑 + +4: 电台节目 + +5: 视频 + +6: 动态 + +7: 电台 +``` + + +`t`: 操作,1 为点赞,其他为取消点赞 + +`id`: 资源 id + + +**接口地址 :** `/resource/like` + +**调用例子 :** `/resource/like?t=1&type=1&id=5436712` + +注意:如给动态点赞,不需要传入 id,需要传入 `threadId`,可通过 `event`,`/user/event` 接口获取,如: +`/resource/like?t=1&type=6&threadId=A_EV_2_6559519868_32953014` + + +### 获取点赞过的视频 + +说明 : 调用此接口, 可获取获取点赞过的视频 + +**接口地址 :** `/playlist/mylike` + +**调用例子 :** `/playlist/mylike` + +### 获取歌曲详情 + +说明 : 调用此接口 , 传入音乐 id(支持多个 id, 用 `,` 隔开), 可获得歌曲详情(dt为歌曲时长) + +**必选参数 :** `ids`: 音乐 id, 如 `ids=347230` + +**接口地址 :** `/song/detail` + +**调用例子 :** `/song/detail?ids=347230`,`/song/detail?ids=347230,347231` + +返回字段说明(感谢 [@tuxzz](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1121#issuecomment-774438040) 整理): + +``` +name: String, 歌曲标题 +id: u64, 歌曲ID +pst: 0,功能未知 +t: enum, + 0: 一般类型 + 1: 通过云盘上传的音乐,网易云不存在公开对应 + 如果没有权限将不可用,除了歌曲长度以外大部分信息都为null。 + 可以通过 `/api/v1/playlist/manipulate/tracks` 接口添加到播放列表。 + 如果添加到“我喜欢的音乐”,则仅自己可见,除了长度以外各种信息均为未知,且无法播放。 + 如果添加到一般播放列表,虽然返回code 200,但是并没有效果。 + 网页端打开会看到404画面。 + 属于这种歌曲的例子: https://music.163.com/song/1345937107 + 2: 通过云盘上传的音乐,网易云存在公开对应 + 如果没有权限则只能看到信息,但无法直接获取到文件。 + 可以通过 `/api/v1/playlist/manipulate/tracks` 接口添加到播放列表。 + 如果添加到“我喜欢的音乐”,则仅自己可见,且无法播放。 + 如果添加到一般播放列表,则自己会看到显示“云盘文件”,且云盘会多出其对应的网易云公开歌曲。其他人看到的是其对应的网易云公开歌曲。 + 网页端打开会看到404画面。 + 属于这种歌曲的例子: https://music.163.com/song/435005015 +ar: Vec, 歌手列表 +alia: Vec, + 别名列表,第一个别名会被显示作副标题 + 例子: https://music.163.com/song/536623501 +pop: 小数,常取[0.0, 100.0]中离散的几个数值, 表示歌曲热度 +st: 0: 功能未知 +rt: Option, None、空白字串、或者类似`600902000007902089`的字符串,功能未知 +fee: enum, + 0: 免费或无版权 + 1: VIP 歌曲 + 4: 购买专辑 + 8: 非会员可免费播放低音质,会员可播放高音质及下载 + fee 为 1 或 8 的歌曲均可单独购买 2 元单曲 +v: u64, 常为[1, ?]任意数字, 代表歌曲当前信息版本 +version: u64, 常为[1, ?]任意数字, 代表歌曲当前信息版本 +crbt: Option, None或字符串表示的十六进制,功能未知 +cf: Option, 空白字串或者None,功能未知 +al: Album, 专辑,如果是DJ节目(dj_type != 0)或者无专辑信息(single == 1),则专辑id为0 +dt: u64, 歌曲时长 +sq: Option, 无损质量文件信息 +h: Option, 高质量文件信息 +m: Option, 中质量文件信息 +l: Option, 低质量文件信息 +a: Option<未知>, 常为None, 功能未知 +cd: Option, None或如"04", "1/2", "3", "null"的字符串,表示歌曲属于专辑中第几张CD,对应音频文件的Tag +no: u32, 表示歌曲属于CD中第几曲,0表示没有这个字段,对应音频文件的Tag +rtUrl: Option, 常为None, 功能未知 +rtUrls: Vec, 常为空列表, 功能未知 +djId: u64, + 0: 不是DJ节目 + 其他:是DJ节目,表示DJ ID +copyright: u32, 0, 1, 2: 功能未知 +s_id: u64, 对于t == 2的歌曲,表示匹配到的公开版本歌曲ID +mark: u64, 功能未知 +originCoverType: enum + 0: 未知 + 1: 原曲 + 2: 翻唱 +originSongSimpleData: Option, 对于翻唱曲,可选提供原曲简单格式的信息 +single: enum, + 0: 有专辑信息或者是DJ节目 + 1: 未知专辑 +noCopyrightRcmd: Option, 不能判断出歌曲有无版权 +mv: u64, 非零表示有MV ID +rtype: 常为0,功能未知 +rurl: Option, 常为None,功能未知 +mst: u32, 偶尔为0, 常为9,功能未知 +cp: u64, 功能未知 +publishTime: i64, 毫秒为单位的Unix时间戳 +pc: 云盘歌曲信息,如果不存在该字段,则为非云盘歌曲 +``` + +### 获取专辑内容 + +说明 : 调用此接口 , 传入专辑 id, 可获得专辑内容 + +**必选参数 :** `id`: 专辑 id + +**接口地址 :** `/album` + +**调用例子 :** `/album?id=32311` + +### 专辑动态信息 + +说明 : 调用此接口 , 传入专辑 id, 可获得专辑动态信息,如是否收藏,收藏数,评论数,分享数 + +**必选参数 :** `id`: 专辑 id + +**接口地址 :** `/album/detail/dynamic` + +**调用例子 :** `/album/detail/dynamic?id=32311` + +### 收藏/取消收藏专辑 + +说明 : 调用此接口,可收藏/取消收藏专辑 + +**必选参数 :** + +`id` : 专辑 id + +`t` : 1 为收藏,其他为取消收藏 + +**接口地址 :** `/album/sub` + +**调用例子 :** `/album/sub?t=1` `/album/sub?t=0` + +### 获取已收藏专辑列表 + +说明 : 调用此接口 , 可获得已收藏专辑列表 + +**可选参数 :** +`limit`: 取出数量 , 默认为 25 + +`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*25, 其中 25 为 limit 的值 , 默认 +为 0 + +**接口地址 :** `/album/sublist` + +**调用例子 :** `/album/sublist` ( 周杰伦 ) + +### 获取歌手单曲 + +说明 : 调用此接口 , 传入歌手 id, 可获得歌手部分信息和热门歌曲 + +**必选参数 :** `id`: 歌手 id, 可由搜索接口获得 + +**接口地址 :** `/artists` + +**调用例子 :** `/artists?id=6452` + +返回数据如下图 : +![获取歌手单曲](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/artists.png) + +### 获取歌手 mv + +说明 : 调用此接口 , 传入歌手 id, 可获得歌手 mv 信息 , 具体 mv 播放地址可调 +用`/mv`传入此接口获得的 mvid 来拿到 , 如 : +`/artist/mv?id=6452`,`/mv?mvid=5461064` + +**必选参数 :** `id`: 歌手 id, 可由搜索接口获得 + +**接口地址 :** `/artist/mv` + +**调用例子 :** `/artist/mv?id=6452` + +### 获取歌手专辑 + +说明 : 调用此接口 , 传入歌手 id, 可获得歌手专辑内容 + +**必选参数 :** `id`: 歌手 id + +**可选参数 :** `limit`: 取出数量 , 默认为 30 + +`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认 +为 0 + +**接口地址 :** `/artist/album` + +**调用例子 :** `/artist/album?id=6452&limit=5` ( 周杰伦 ) + +返回数据如下图 : +![获取专辑内容](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/artist_album.png) + +### 获取歌手描述 + +说明 : 调用此接口 , 传入歌手 id, 可获得歌手描述 + +**必选参数 :** `id`: 歌手 id + +**接口地址 :** `/artist/desc` + +**调用例子 :** `/artist/desc?id=6452` ( 周杰伦 ) + +### 获取歌手详情 + +说明 : 调用此接口 , 传入歌手 id, 可获得获取歌手详情 + +**必选参数 :** `id`: 歌手 id + +**接口地址 :** `/artist/detail` + +**调用例子 :** `/artist/detail?id=11972054` (Billie Eilish) + +### 获取相似歌手 + +说明 : 调用此接口 , 传入歌手 id, 可获得相似歌手 + +**必选参数 :** `id`: 歌手 id + +**接口地址 :** `/simi/artist` + +**调用例子 :** `/simi/artist?id=6452` ( 对应和周杰伦相似歌手 ) + +### 获取相似歌单 + +说明 : 调用此接口 , 传入歌曲 id, 可获得相似歌单 + +**必选参数 :** `id`: 歌曲 id + +**接口地址 :** `/simi/playlist` + +**调用例子 :** `/simi/playlist?id=347230` ( 对应 ' 光辉岁月 ' 相似歌单 ) + +### 相似 mv + +说明 : 调用此接口 , 传入 `mvid` 可获取相似 mv + +**必选参数 :** `mvid`: mv id + +**接口地址 :** `/simi/mv` + +**调用例子 :** `/simi/mv?mvid=5436712` + +### 获取相似音乐 + +说明 : 调用此接口 , 传入歌曲 id, 可获得相似歌曲 + +**必选参数 :** `id`: 歌曲 id + +**接口地址 :** `/simi/song` + +**调用例子 :** `/simi/song?id=347230` ( 对应 ' 光辉岁月 ' 相似歌曲 ) + +### 获取最近 5 个听了这首歌的用户 + +说明 : 调用此接口 , 传入歌曲 id, 最近 5 个听了这首歌的用户 + +**必选参数 :** `id`: 歌曲 id + +**接口地址 :** `/simi/user` + +**调用例子 :** `/simi/user?id=347230` ( 对应 ' 光辉岁月 ' 相似歌曲 ) + +### 获取每日推荐歌单 + +说明 : 调用此接口 , 可获得每日推荐歌单 ( 需要登录 ) + +**接口地址 :** `/recommend/resource` + +**调用例子 :** `/recommend/resource` + +返回数据如下图 : +![每日推荐歌单](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E6%8E%A8%E8%8D%90%E6%AD%8C%E5%8D%95.png) + +### 获取每日推荐歌曲 + +说明 : 调用此接口 , 可获得每日推荐歌曲 ( 需要登录 ) + +**接口地址 :** `/recommend/songs` + +**调用例子 :** `/recommend/songs` + +返回数据如下图 : +![每日推荐歌曲](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E6%8E%A8%E8%8D%90%E6%AD%8C%E6%9B%B2.png) + +### 获取历史日推可用日期列表 + +说明 : 调用此接口 , 可获得历史日推可用日期列表 + +**接口地址 :** `/history/recommend/songs` + +**调用例子 :** `/history/recommend/songs` + +### 获取历史日推详情数据 + +说明 : 调用此接口 ,传入当日日期, 可获得当日历史日推数据 + +**必选参数 :** `date`: 日期,通过历史日推可用日期列表接口获取,不能任意日期 + +**接口地址 :** `/history/recommend/songs/detail` + +**调用例子 :** `/history/recommend/songs/detail?date=2020-06-21` + +### 私人 FM + +说明 : 私人 FM( 需要登录 ) + +**接口地址 :** `/personal_fm` + +**调用例子 :** `/personal_fm` + +返回数据如下图 : + +![私人 FM](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/personal_fm.png) + +### 签到 + +说明 : 调用此接口 , 传入签到类型 ( 可不传 , 默认安卓端签到 ), 可签到 ( 需要登录 +), 其中安卓端签到可获得 3 点经验 , web/PC 端签到可获得 2 点经验 + +**可选参数 :** `type`: 签到类型 , 默认 0, 其中 0 为安卓端签到 ,1 为 web/PC 签到 + +**接口地址 :** `/daily_signin` + +**调用例子 :** `/daily_signin` + +返回数据如下图 : + +![签到成功](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/signinSuccess.png) + +![签到失败](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/signinError.png) + +### 乐签信息 + +说明 : 调用此接口, 可获取乐签信息 + +**接口地址 :** `/sign/happy/info` + +### 喜欢音乐 + +说明 : 调用此接口 , 传入音乐 id, 可喜欢该音乐 + +**必选参数 :** `id`: 歌曲 id + +**可选参数 :** `like`: 布尔值 , 默认为 true 即喜欢 , 若传 false, 则取消喜欢 + +**接口地址 :** `/like` + +**调用例子 :** `/like?id=347230` + +返回数据如下图 : + +![喜欢成功](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/like.png) + +喜欢成功则返回数据的 code 为 200, 其余为失败 + +![喜欢成功截图](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/likeSuccess.png) + +### 喜欢音乐列表 + +说明 : 调用此接口 , 传入用户 id, 可获取已喜欢音乐 id 列表(id 数组) + +**必选参数 :** `uid`: 用户 id + +**接口地址 :** `/likelist` + +**调用例子 :** `/likelist?uid=32953014` + +### 垃圾桶 + +说明 : 调用此接口 , 传入音乐 id, 可把该音乐从私人 FM 中移除至垃圾桶 + +**必选参数 :** `id`: 歌曲 id + +**接口地址 :** `/fm_trash` + +**调用例子 :** `/fm_trash?id=347230` + +返回数据如下图 : + +![移除成功](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/fm_trash.png) + +### 新碟上架 + +说明 : 调用此接口 , 可获取新碟上架列表 , 如需具体音乐信息需要调用获取专辑列表接 +口 `/album` , 然后传入 id, 如 `/album?id=32311` + +**可选参数 :** + + + +`area`: ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本 + +`type` : new:全部 hot:热门,默认为 new + +`year` : 年,默认本年 + +`month` : 月,默认本月 + +**接口地址 :** `/top/album` + +**调用例子 :** `/top/album?offset=0&limit=30&year=2019&month=6` + +### 全部新碟 + +说明 : 登录后调用此接口 ,可获取全部新碟 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +`area` : ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本 + +**接口地址 :** `/album/new` + +**调用例子 :** `/album/new?area=KR&limit=10` + +### 最新专辑 + +说明 : 调用此接口 ,获取云音乐首页新碟上架数据 + +**接口地址 :** `/album/newest` + +**调用例子 :** `/album/newest` + +### 听歌打卡 + +说明 : 调用此接口 , 传入音乐 id, 来源 id,歌曲时间 time,更新听歌排行数据 + +**必选参数 :** `id`: 歌曲 id, `sourceid`: 歌单或专辑 id + +**可选参数 :** `time`: 歌曲播放时间,单位为秒 + +**接口地址 :** `/scrobble` + +**调用例子 :** `/scrobble?id=518066366&sourceid=36780169&time=291` + +### 热门歌手 + +说明 : 调用此接口 , 可获取热门歌手数据 + +**可选参数 :** `limit`: 取出数量 , 默认为 50 + +`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*50, 其中 50 为 limit 的值 , 默认 +为 0 + +**接口地址 :** `/top/artists` + +**调用例子 :** `/top/artists?offset=0&limit=30` + +返回数据如下图 : + +![热门歌手](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/top_artists.png) + +### 全部 mv + +说明 : 调用此接口 , 可获取全部 mv + +**可选参数 :** +`area`: 地区,可选值为全部,内地,港台,欧美,日本,韩国,不填则为全部 +`type`: 类型,可选值为全部,官方版,原生,现场版,网易出品,不填则为全部 + +`order`: 排序,可选值为上升最快,最热,最新,不填则为上升最快 + +`limit`: 取出数量 , 默认为 30 + +`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*50, 其中 50 为 limit 的值 , 默认 +为 0 + +**接口地址 :** `/mv/all` + +**调用例子 :** `/mv/all?area=港台` + +### 最新 mv + +说明 : 调用此接口 , 可获取最新 mv + +**可选参数 :** `area`: 地区,可选值为全部,内地,港台,欧美,日本,韩国,不填则为全部 + +**可选参数 :** `limit`: 取出数量 , 默认为 30 + +**接口地址 :** `/mv/first` + +**调用例子 :** `/mv/first?limit=10` + +### 网易出品 mv + +说明 : 调用此接口 , 可获取网易出品 mv + +**可选参数 :** `limit`: 取出数量 , 默认为 30 + +`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认 +为 0 + +**接口地址 :** `/mv/exclusive/rcmd` + +**调用例子 :** `/mv/exclusive/rcmd?limit=10` + +### 推荐 mv + +说明 : 调用此接口 , 可获取推荐 mv + +**接口地址 :** `/personalized/mv` + +**调用例子 :** `/personalized/mv` + +### 推荐歌单 + +说明 : 调用此接口 , 可获取推荐歌单 + +**可选参数 :** `limit`: 取出数量 , 默认为 30 (不支持 offset) + +**接口地址 :** `/personalized` + +**调用例子 :** `/personalized?limit=1` + +### 推荐新音乐 + +说明 : 调用此接口 , 可获取推荐新音乐 + +**可选参数 :** `limit`: 取出数量 , 默认为 10 (不支持 offset) + +**接口地址 :** `/personalized/newsong` + +**调用例子 :** `/personalized/newsong` + +### 推荐电台 + +说明 : 调用此接口 , 可获取推荐电台 + +**接口地址 :** `/personalized/djprogram` + +**调用例子 :** `/personalized/djprogram` + +### 推荐节目 + +说明 : 调用此接口 , 可获取推荐电台 + +**接口地址 :** `/program/recommend` + +**可选参数 :** +`limit`: 取出数量 , 默认为 10 + +`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*10, 其中 10 为 limit 的值 , 默认 +为 0 + +**调用例子 :** `/program/recommend?limit=5` + +### 独家放送(入口列表) + +说明 : 调用此接口 , 可获取独家放送 + +**接口地址 :** `/personalized/privatecontent` + +**调用例子 :** `/personalized/privatecontent` + +### 独家放送列表 + +说明 : 调用此接口 , 可获取独家放送列表 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 60 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*60, 其中 60 为 limit 的值 , 默认为 0 + +**接口地址 :** `/personalized/privatecontent/list` + +**调用例子 :** `/personalized/privatecontent/list?limit=1&offset=2` + +### mv 排行 + +说明 : 调用此接口 , 可获取 mv 排行 + +**可选参数 :** `limit`: 取出数量 , 默认为 30 + +`area`: 地区,可选值为内地,港台,欧美,日本,韩国,不填则为全部 + +`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认 +为 0 + +**接口地址 :** `/top/mv` + +**调用例子 :** `/top/mv?limit=10` + +### 获取 mv 数据 + +说明 : 调用此接口 , 传入 mvid ( 在搜索音乐的时候传 type=1004 获得 ) , 可获取对应 +MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等数据 , 其中 mv 视频 +网易做了防盗链处理 , 可能不能直接播放 , 需要播放的话需要调用 ' mv 地址' 接口 + +**必选参数 :** `mvid`: mv 的 id + +**接口地址 :** `/mv/detail` + +**调用例子 :** `/mv/detail?mvid=5436712` + +返回数据如下图 : + +![mv 数据](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/mv.png) + +### 获取 mv 点赞转发评论数数据 + +说明 : 调用此接口 , 传入 mvid ( 在搜索音乐的时候传 type=1004 获得 ) , 可获取对应 +MV 点赞转发评论数数据 + +**必选参数 :** `mvid`: mv 的 id + +**接口地址 :** `/mv/detail/info` + +**调用例子 :** `/mv/detail/info?mvid=5436712` + +### mv 地址 + +说明 : 调用此接口 , 传入 mv id,可获取 mv 播放地址 + +**必选参数 :** `id`: mv id + +**可选参数 :** `r`: 分辨率,默认 1080,可从 `/mv/detail` 接口获取分辨率列表 + +**接口地址 :** `/mv/url` + +**调用例子 :** + +`/mv/url?id=5436712` `/mv/url?id=10896407&r=1080` + +### 获取视频标签列表 + +说明 : 调用此接口 , 可获取视频标签列表 + +**接口地址 :** `/video/group/list` + +**调用例子 :** `/video/group/list` + +### 获取视频分类列表 + +说明 : 调用此接口 , 可获取视频分类列表 + +**接口地址 :** `/video/category/list` + +**调用例子 :** `/video/category/list` + +### 获取视频标签/分类下的视频 + +说明 : 调用此接口 , 传入标签/分类`id`,可获取到相关的视频,分页参数只能传入 offset + +**必选参数 :** `id`: videoGroup 的 id + +**可选参数 :** `offset`: 默认 0 + +**接口地址 :** `/video/group` + +**调用例子 :** `/video/group?id=9104` + +### 获取全部视频列表 + +说明 : 调用此接口,可获取视频分类列表,分页参数只能传入 offset + +**可选参数 :** `offset`: 默认 0 + +**接口地址 :** `/video/timeline/all` + +**调用例子 :** `/video/timeline/all` + +### 获取推荐视频 + +说明 : 调用此接口, 可获取推荐视频,分页参数只能传入 offset + +**可选参数 :** `offset`: 默认 0 + +**接口地址 :** `/video/timeline/recommend` + +**调用例子 :** `/video/timeline/recommend?offset=10` + +### 相关视频 + +说明 : 调用此接口 , 可获取相关视频 + +**必选参数 :** `id`: 视频 的 id + +**接口地址 :** `/related/allvideo` + +**调用例子 :** `/related/allvideo?id=89ADDE33C0AAE8EC14B99F6750DB954D` + +### 视频详情 + +说明 : 调用此接口 , 可获取视频详情 + +**必选参数 :** `id`: 视频 的 id + +**接口地址 :** `/video/detail` + +**调用例子 :** `/video/detail?id=89ADDE33C0AAE8EC14B99F6750DB954D` + +### 获取视频点赞转发评论数数据 + +说明 : 调用此接口 , 传入 vid ( 视频 id ) , 可获取对应视频点赞转发评论数数据 +**必选参数 :** `vid`: 视频 id + +**接口地址 :** `/video/detail/info` + +**调用例子 :** `/video/detail/info?vid=89ADDE33C0AAE8EC14B99F6750DB954D` + +### 获取视频播放地址 + +说明 : 调用此接口 , 传入视频 id,可获取视频播放地址 + +**必选参数 :** `id`: 视频 的 id + +**接口地址 :** `/video/url` + +**调用例子 :** `/video/url?id=89ADDE33C0AAE8EC14B99F6750DB954D` + +### 所有榜单 + +说明 : 调用此接口,可获取所有榜单 +**接口地址 :** `/toplist` + +**调用例子 :** `/toplist` + +### 排行榜详情 + +说明: 请使用[歌单详情](#获取歌单详情)接口,传入排行榜 id 获取排行榜详情数据(排行榜也是歌单的一种) + +~~说明 : 调用此接口 , 传入榜单 id, 可获取不同排行榜数据(v3.34.0 之后不再支持 idx 参数)~~ + +~~**必选参数 :** `id`: 榜单 id,通过所有榜单接口获取~~ + +~~**接口地址 :** `/top/list`~~ + +~~**调用例子 :** `/top/list?id=2809577409`~~ + +### 所有榜单内容摘要 + +说明 : 调用此接口,可获取所有榜单内容摘要 + +**接口地址 :** `/toplist/detail` + +**调用例子 :** `/toplist/detail` + +### 歌手榜 + +说明 : 调用此接口 , 可获取排行榜中的歌手榜 + +**可选参数 :** + +``` +type : 地区 +1: 华语 +2: 欧美 +3: 韩国 +4: 日本 +``` + +**接口地址 :** `/toplist/artist` + +**调用例子 :** `/toplist/artist` + +### 云盘 + +说明 : 登录后调用此接口 , 可获取云盘数据 , 获取的数据没有对应 url, 需要再调用一 +次 `/song/url` 获取 url + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*200, 其中 200 为 limit 的值 , 默认为 0 + +**接口地址 :** `/user/cloud` + +**调用例子 :** `/user/cloud` + +### 云盘数据详情 + +说明 : 登录后调用此接口 , 传入云盘歌曲 id,可获取云盘数据详情 + +**必选参数 :** `id`: 歌曲 id,可多个,用逗号隔开 + +**接口地址 :** `/user/cloud/detail` + +**调用例子 :** `/user/cloud/detail?id=5374627` + +### 云盘歌曲删除 + +说明 : 登录后调用此接口 , 可删除云盘歌曲 + +**必选参数 :** `id`: 歌曲 id,可多个,用逗号隔开 + +**接口地址 :** `/user/cloud/del` + +**调用例子 :** `/user/cloud/del` + +### 云盘上传 + +说明 : 登录后调用此接口,使用`'Content-Type': 'multipart/form-data'`上传 mp3 formData(name 为'songFile'),可上传歌曲到云盘 + +参考: https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/public/cloud.html + +访问地址: http://localhost:3000/cloud.html) + +支持命令行调用,参考 module_example 目录下`song_upload.js` + +**接口地址 :** `/cloud` + +**调用例子 :** `/cloud` + +### 云盘歌曲信息匹配纠正 + +说明 : 登录后调用此接口,可对云盘歌曲信息匹配纠正,如需取消匹配,asid 需要传 0 + +**必选参数 :** +`uid`: 用户 id + +`sid`: 云盘的歌曲 id + +`asid`: 要匹配的歌曲 id + +**接口地址 :** `/cloud/match` + +**调用例子 :** `/cloud/match?uid=32953014&sid=aaa&asid=bbb` `/cloud/match?uid=32953014&sid=bbb&asid=0` + +### 电台 banner + +说明 : 调用此接口,可获取电台 banner + +**接口地址 :** `/dj/banner` + +**调用例子 :** `/dj/banner` + +### 电台个性推荐 + +说明 : 调用此接口,可获取电台个性推荐列表 +**可选参数 :** + +`limit` : 返回数量,默认为 6,总条数最多 6 条 + +**接口地址 :** `/dj/personalize/recommend` + +**调用例子 :** `/dj/personalize/recommend?limit=5` + +### 电台订阅者列表 + +说明 : 调用此接口,可获取电台订阅者列表 +**必选参数 :** `id`: 电台 id + +**可选参数 :** +`time` : 分页参数,默认-1,传入上一次返回结果的 time,将会返回下一页的数据 + +`limit` : 返回数量,默认为 20 + +**接口地址 :** `/dj/subscriber` + +**调用例子 :** `/dj/subscriber?id=335425050` , `/dj/subscriber?id=335425050&time=1602761825390` + +### 用户电台 + +说明 : 调用此接口, 传入用户 id 可获取用户创建的电台 + +**必选参数 :** `uid`: 用户 id + +**接口地址 :** `/user/audio` + +**调用例子 :** `/user/audio?uid=32953014` + +### 热门电台 + +说明 : 调用此接口,可获取热门电台 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 +**接口地址 :** `/dj/hot` + +**调用例子 :** `/dj/hot` + +### 电台 - 节目榜 + +说明 : 登录后调用此接口 , 可获得电台节目榜 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 100 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*100, 其中 100 为 limit 的值 , 默认为 0 + +**接口地址 :** `/dj/program/toplist` + +**调用例子 :** `/dj/program/toplist?limit=1` + +### 电台 - 付费精品 + +说明 : 调用此接口,可获取付费精品电台 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 100 (不支持 offset) + +**接口地址 :** `/dj/toplist/pay` + +**调用例子 :** `/dj/toplist/pay?limit=30` + +### 电台 - 24 小时节目榜 + +说明 : 调用此接口,可获取 24 小时节目榜 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 100 (不支持 offset) + +**接口地址 :** `/dj/program/toplist/hours` + +**调用例子 :** `/dj/program/toplist/hours?limit=1` + +### 电台 - 24 小时主播榜 + +说明 : 调用此接口,可获取 24 小时主播榜 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 100 (不支持 offset) + +**接口地址 :** `/dj/toplist/hours` + +**调用例子 :** `/dj/toplist/hours?limit=30` + +### 电台 - 主播新人榜 + +说明 : 调用此接口,可获取主播新人榜 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 100 (不支持 offset) + +**接口地址 :** `/dj/toplist/newcomer` + +**调用例子 :** `/dj/toplist/newcomer?limit=30` + +### 电台 - 最热主播榜 + +说明 : 调用此接口,可获取最热主播榜 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 100 (不支持 offset) + +**接口地址 :** `/dj/toplist/popular` + +**调用例子 :** `/dj/toplist/popular?limit=30` + +### 电台 - 新晋电台榜/热门电台榜 + +说明 : 登录后调用此接口 , 可获得新晋电台榜/热门电台榜 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 100 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*100, 其中 100 为 limit 的值 , 默认为 0 + +`type`: 榜单类型, `new` 为新晋电台榜,`hot`为热门电台榜 + +**接口地址 :** `/dj/toplist` + +**调用例子 :** `/dj/toplist?type=hot` `/dj/toplist?type=new&limit=1` + +### 电台 - 类别热门电台 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +`cateId`: 类别 id,可通过 `/dj/category/recommend` 接口获取 + +**接口地址 :** `/dj/radio/hot` + +**调用例子 :** `/dj/radio/hot?cateId=2001`(创作|翻唱) `/dj/radio/hot?cateId=10002` (3D|电子) + +### 电台 - 推荐 + +说明 : 登录后调用此接口 , 可获得推荐电台 + +**接口地址 :** `/dj/recommend` + +**调用例子 :** `/dj/recommend` + +### 电台 - 分类 + +说明 : 登录后调用此接口 , 可获得电台类型 + +**接口地址 :** `/dj/catelist` + +**调用例子 :** `/dj/catelist` + +### 电台 - 分类推荐 + +说明 : 登录后调用此接口 , 传入分类,可获得对应类型电台列表 + +**必选参数 :** `type`: 电台类型 , 数字 , 可通过`/dj/catelist`获取 , 对应关系为 +id 对应 此接口的 type, name 对应类型 + +**接口地址 :** `/dj/recommend/type` + +**调用例子 :** `/dj/recommend/type?type=1`(明星做主播) `/dj/recommend/type?type=2001` (创作|翻唱) + +### 电台 - 订阅 + +说明 : 登录后调用此接口 , 传入`rid`, 可订阅 dj,dj 的 `rid` 可通过搜索指定 +type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009` + +**必选参数 :** `rid`: 电台 的 id + +**接口地址 :** `/dj/sub` + +**调用例子 :** `/dj/sub?rid=336355127&t=1` ( 对应关注 ' 代码时间 ') +`/dj/sub?rid=336355127&t=0` ( 对应取消关注 ' 代码时间 ') + +### 电台的订阅列表 + +说明 : 登录后调用此接口 , 可获取订阅的电台列表 + +**接口地址 :** `/dj/sublist` + +**调用例子 :** `/dj/sublist` + +### 电台 - 付费精选 + +说明 : 可以获取付费精选的电台列表 , 传入 `limit` 和 `offset` 可以进行分页 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +**接口地址 :** `/dj/paygift` + +**调用例子 :** `/dj/paygift?limit=10&offset=20` + +### 电台 - 非热门类型 + +说明 : 登录后调用此接口, 可获得电台非热门类型 + +**接口地址 :** `/dj/category/excludehot` + +**调用例子 :** `/dj/category/excludehot` + +### 电台 - 推荐类型 + +说明 : 登录后调用此接口, 可获得电台推荐类型 + +**接口地址 :** `/dj/category/recommend` + +**调用例子 :** `/dj/category/recommend` + +### 电台 - 今日优选 + +说明 : 登录后调用此接口, 可获得电台今日优选 + +**接口地址 :** `/dj/today/perfered` + +**调用例子 :** `/dj/today/perfered` + +### 电台 - 详情 + +说明 : 登录后调用此接口 , 传入`rid`, 可获得对应电台的详情介绍 + +**必选参数 :** `rid`: 电台 的 id + +**接口地址 :** `/dj/detail` + +**调用例子 :** `/dj/detail?rid=336355127` ( 对应 ' 代码时间 ' 的详情介绍 ) + +### 电台 - 节目 + +说明 : 登录后调用此接口 , 传入`rid`, 可查看对应电台的电台节目以及对应的 id, 需要 +注意的是这个接口返回的 mp3Url 已经无效 , 都为 null, 但是通过调用 `/song/url` 这 +个接口 , 传入节目 id 仍然能获取到节目音频 , 如 `/song/url?id=478446370` 获取代 +码时间的一个节目的音频 + +**必选参数 :** `rid`: 电台 的 id + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +`asc` : 排序方式,默认为 `false` (新 => 老 ) 设置 `true` 可改为 老 => 新 + +**接口地址 :** `/dj/program` + +**调用例子 :** `/dj/program?rid=336355127&limit=40` ( 对应 ' 代码时间 ' 的节目列表 ) + +### 电台 - 节目详情 + +说明 : 调用此接口传入电台节目 id,可获得电台节目详情 + +**必选参数 :** `id`: 电台节目 的 id + +**接口地址 :** `/dj/program/detail` + +**调用例子 :** `/dj/program/detail?id=1367665101` + +### 通知 - 私信 + +说明 : 登录后调用此接口 ,可获取私信 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +**接口地址 :** `/msg/private` + +**调用例子 :** `/msg/private?limit=3` + +### 发送私信 + +说明 : 登录后调用此接口 , 传入用户 id 和要发送的信息, 可以发送私信,返回内容为历史私信,包含带歌单的私信信息(注:不能发送私信给自己) + +**必选参数 :** + +`user_ids` : 用户 id,多个需用逗号隔开 + +`msg` : 要发送的信息 + +**接口地址 :** `/send/text` + +**调用例子 :** `/send/text?user_ids=32953014&msg=test`,`/send/text?user_ids=32953014,475625142&msg=test` + +### 发送私信(带歌曲) + +说明 : 登录后调用此接口 , 传入用户 id 和要发送的信息,音乐 id, 可以发送音乐私信,返回内容为历史私信 + +**必选参数 :** + +`user_ids` : 用户 id,多个需用逗号隔开 + +`id` : 要发送音乐的 id + +`msg` : 要发送的信息 + +**接口地址 :** `/send/song` + +**调用例子 :** `/send/song?user_ids=1&id=351318&msg=测试` + +### 发送私信(带专辑) + +说明 : 登录后调用此接口 , 传入用户 id 和要发送的信息,专辑 id, 可以发送专辑私信,返回内容为消息 id + +**必选参数 :** + +`user_ids` : 用户 id,多个需用逗号隔开 + +`id` : 要发送专辑的 id + +`msg` : 要发送的信息 + +**接口地址 :** `/send/album` + +**调用例子 :** `/send/album?user_ids=1&id=351318&msg=测试` + +### 发送私信(带歌单) + +说明 : 登录后调用此接口 , 传入用户 id 和要发送的信息和歌单 id, 可以发送带歌单的私信(注:不能发送重复的歌单) + +**必选参数 :** + +`user_ids` : 用户 id,多个需用逗号隔开 + +`msg` : 要发送的信息 + +**接口地址 :** `/send/playlist` + +**调用例子 :** `/send/playlist?msg=test&user_ids=475625142&playlist=705123491`,`/send/playlist?msg=test2&user_ids=475625142,32953014&playlist=705123493` + +### 最近联系人 + +说明 : 登录后调用此接口 ,可获取最接近联系人 + +**接口地址 :** `/msg/recentcontact` + +**调用例子 :** `/msg/recentcontact` + +### 私信内容 + +说明 : 登录后调用此接口 , 可获取私信内容 + +**必选参数 :** +`uid` : 用户 id + +**可选参数 :** +`limit` : 返回数量 , 默认为 30 + +`before` : 分页参数,取上一页最后一项的 `time` 获取下一页数据 + +**接口地址 :** +`/msg/private/history` + +**调用例子 :** +`/msg/private/history?uid=9003` (云音乐小秘书) + +### 通知 - 评论 + +说明 : 登录后调用此接口 ,可获取评论 + +**必选参数 :** `uid`: 用户 的 id,只能和登录账号的 id 一致 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`before` : 分页参数,取上一页最后一个歌单的 `updateTime` 获取下一页数据 + +**接口地址 :** `/msg/comments` + +**调用例子 :** `/msg/comments?uid=32953014` + +### 通知 - @我 + +说明 : 登录后调用此接口 ,可获取@我数据 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +**接口地址 :** `/msg/forwards` + +**调用例子 :** `/msg/forwards?limit=3` + +### 通知 - 通知 + +说明 : 登录后调用此接口 ,可获取通知 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`lasttime` : 返回数据的 `time` ,默认-1,传入上一次返回结果的 time,将会返回下一页的数据 + +**接口地址 :** `/msg/notices` + +**调用例子 :** `/msg/notices?limit=3` + +### 设置 + +说明 : 登录后调用此接口 ,可获取用户设置 + +**接口地址 :** `/setting` + +**调用例子 :** `/setting` + +### 数字专辑-新碟上架 + +说明 : 调用此接口 ,可获取数字专辑-新碟上架 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 +**接口地址 :** `/album/list` + +**调用例子 :** `/album/list?limit=10` + +### 数字专辑&数字单曲-榜单 + +说明 : 调用此接口 ,可获取数字专辑&数字单曲-榜单 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +`albumType` : 为数字专辑,1 为数字单曲 + +`type` : daily:日榜,week:周榜,year:年榜,total:总榜 + +**接口地址 :** `/album_songsaleboard` + +**调用例子 :** `/album/songsaleboard?type=year&year=2020&albumType=0` + +### 数字专辑-语种风格馆 + +说明 : 调用此接口 ,可获取语种风格馆数字专辑列表 + +**可选参数 :** + +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +`area` 地区 Z_H:华语,E_A:欧美,KR:韩国,JP:日本 + +**接口地址 :** `/album/list/style` + +**调用例子 :** `/album/list/style?area=Z_H&offset=2` + +### 数字专辑详情 + +说明 : 调用此接口 ,传入数字专辑 id 可获取数字专辑详情(和歌单详情有差异) + +**接口地址 :** `/album/detail` + +**调用例子 :** `/album/detail?id=84547195` + +### 我的数字专辑 + +说明 : 登录后调用此接口 ,可获取我的数字专辑 + +**接口地址 :** `/digitalAlbum/purchased` + +**调用例子 :** `/digitalAlbum/purchased?limit=10` + +### 购买数字专辑 + +说明 : 登录后调用此接口 ,可获取购买数字专辑的地址,把地址生成二维码后,可扫描购买专辑 + +**必选参数 :** + +`id` : 专辑的 id + +`payment` : 支付方式, 0 为支付宝 3 为微信 + +`quantity` : 购买的数量 + +**接口地址 :** `/digitalAlbum/ordering` + +**调用例子 :** `/digitalAlbum/ordering?id=86286082&payment=3&quantity=1` + +### 音乐日历 + +说明 : 登录后调用此接口,传入开始和结束时间,可获取音乐日历 + +**接口地址 :** `/calendar` + +**调用例子 :** `/calendar?startTime=1606752000000&endTime=1609430399999` + +### 云贝 + +说明 : 登录后调用此接口可获取云贝签到信息(连续签到天数,第二天全部可获得的云贝) + +**接口地址 :** `/yunbei` + +**调用例子 :** `/yunbei` + +### 云贝今日签到信息 + +说明 : 登录后调用此接口可获取云贝今日签到信息(今日签到获取的云贝数) + +**接口地址 :** `/yunbei/today` + +**调用例子 :** `/yunbei/today` + +### 云贝签到 + +说明 : 登录后调用此接口可进行云贝签到 + +**接口地址 :** `/yunbei/sign` + +**调用例子 :** `/yunbei/sign` + +### 云贝账户信息 + +说明 :登录后调用此接口可获取云贝账户信息(账户云贝数) + +**接口地址 :** `/yunbei/info` + +**调用例子 :** `/yunbei/info` + +### 云贝所有任务 + +说明 :登录后调用此接口可获取云贝所有任务 + +**接口地址 :** `/yunbei/tasks` + +**调用例子 :** `/yunbei/tasks` + +### 云贝 todo 任务 + +说明 :登录后调用此接口可获取云贝 todo 任务 + +**接口地址 :** `/yunbei/tasks/todo` + +**调用例子 :** `/yunbei/tasks/todo` + +### 云贝完成任务 + +**必选参数 :** + +`userTaskId` : 任务 id + +**可选参数 :** + +`depositCode`: 任务 depositCode + +**接口地址 :** `/yunbei/task/finish` + +**调用例子 :** `/yunbei/task/finish?userTaskId=5146243240&depositCode=0` + +### 云贝收入 + +说明 :登录后调用此接口可获取云贝收入 + +**可选参数 :** `limit`: 取出评论数量 , 默认为 10 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*10, 其中 10 为 limit 的值 + +**接口地址 :** `/yunbei/tasks/receipt` + +**调用例子 :** `/yunbei/tasks/receipt?limit=1` + +### 云贝支出 + +说明 :登录后调用此接口可获取云贝支出 + +**可选参数 :** `limit`: 取出评论数量 , 默认为 10 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*10, 其中 10 为 limit 的值 +**接口地址 :** `/yunbei/tasks/expense` + +**调用例子 :** `/yunbei/tasks/expense?limit=1` + +### 关注歌手新歌 + +说明 :登录后调用此接口可获取关注歌手新歌 + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`before`: 上一页数据返回的 publishTime 的数据 + +**接口地址 :** `/artist/new/song` + +**调用例子 :** `/artist/new/song?limit=1` `/artist/new/song?limit=1&before=1602777625000` + +### 关注歌手新 MV + +说明 :登录后调用此接口可获取关注歌手新 MV + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`before`: 上一页数据返回的 publishTime 的数据 + +**接口地址 :** `/artist/new/mv` + +**调用例子 :** `/artist/new/mv?limit=1` `/artist/new/mv?limit=1&before=1602777625000` + +### 一起听相关 + +一起听相关参见此 Issue: [#1676](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1676) + +主机模式: + +代码可参考: https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/public/listen_together_host.html + +访问地址: http://localhost:3000/listen_together_host.html + +从机模式: 待整理 + +### batch 批量请求接口 + +说明 : 登录后调用此接口 ,传入接口和对应原始参数(原始参数非文档里写的参数,需参考源码),可批量请求接口 + +**接口地址 :** `/batch` + +**调用例子 :** 使用 GET 方式:`/batch?/api/v2/banner/get={"clientType":"pc"}` 使用 POST 方式传入参数:`{ "/api/v2/banner/get": {"clientType":"pc"} }` + +### 云贝推歌 + +说明 : 登录后调用此接口 , 传入歌曲 id, 可以进行云贝推歌 + +**必选参数 :** `id` : 歌曲 id + +**可选参数 :** `reason` : 推歌理由 + +`yunbeiNum`: 云贝数量,默认10 + +**接口地址 :** `/yunbei/rcmd/song` + +**调用例子 :** `/yunbei/rcmd/song?id=65528` `/yunbei/rcmd/song?id=65528&reason=人间好声音推荐给你听` + +### 云贝推歌历史记录 + +说明 : 登录后调用此接口 , 可以获得云贝推歌历史记录 + +**可选参数 :** `size` : 返回数量 , 默认为 20 + +`cursor` : 返回数据的 cursor, 默认为 '' , 传入上一次返回结果的 cursor,将会返回下一页的数据 + +**接口地址 :** `/yunbei/rcmd/song/history` + +**调用例子 :** `/yunbei/rcmd/song/history?size=10` + +### 已购单曲 + +说明 :登录后调用此接口可获取已购买的单曲 + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*10, 其中 10 为 limit 的值 + +**接口地址 :** `/song/purchased` + +**调用例子 :** `/song/purchased?limit=10` + +### 获取 mlog 播放地址 + +说明 : 调用此接口 , 传入 mlog id, 可获取 mlog 播放地址 + +**必选参数 :** `id` : mlog id + +**可选参数 :** `res`: 分辨率 , 默认为 1080 + +**接口地址 :** `/mlog/url` + +**调用例子 :** `/mlog/url?id=a1qOVPTWKS1ZrK8` + +### 将 mlog id 转为视频 id + +说明 : 调用此接口 , 传入 mlog id, 可获取 video id,然后通过`video/url` 获取播放地址 + +**必选参数 :** `id` : mlog id + +**接口地址 :** `/mlog/to/video` + +**调用例子 :** `/mlog/to/video?id=a1qOVPTWKS1ZrK8` + +### vip 成长值 + +说明 : 登录后调用此接口 , 可获取当前会员成长值 + +**接口地址 :** `/vip/growthpoint` + +**调用例子 :** `/vip/growthpoint` + +### vip 成长值获取记录 + +说明 :登录后调用此接口可获取会员成长值领取记录 + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*10, 其中 10 为 limit 的值 + +**接口地址 :** `/vip/growthpoint/details` + +**调用例子 :** `/vip/growthpoint/details?limit=10` + +### vip 任务 + +说明 : 登录后调用此接口 , 可获取会员任务 + +**接口地址 :** `/vip/tasks` + +**调用例子 :** `/vip/tasks` + +### 领取 vip 成长值 + +说明 : 登录后调用此接口 , 可获取已完成的会员任务的成长值奖励 + +**必选参数 :** `ids` : 通过`/vip/tasks`获取到的`unGetIds` + +**接口地址 :** `/vip/growthpoint/get` + +**调用例子 :** `/vip/growthpoint/get?ids=7043206830_7` `/vip/growthpoint/get?ids=8613118351_1,8607552957_1` + +### 歌手粉丝 + +说明 : 调用此接口 , 传入歌手 id, 可获取歌手粉丝 +**必选参数 :** `id` : 歌手 id + + +**接口地址 :** `/artist/fans` + +**调用例子 :** `/artist/fans?id=2116&limit=10&offset=0` + +### 歌手粉丝数量 + +说明 : 调用此接口 , 传入歌手 id, 可获取歌手粉丝数量 + + +**必选参数 :** `id` : 歌手 id + +**可选参数 :** `limit`: 取出粉丝数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*10, 其中 10 为 limit 的值 + +**接口地址 :** `/artist/follow/count` + +**调用例子 :** `/artist/follow/count?id=2116` + +### 数字专辑详情 + +说明 : 调用此接口 , 传入专辑 id, 可获取数字专辑信息 + +**必选参数 :** `id` : 专辑 id + +**接口地址 :** `/digitalAlbum/detail` + +**调用例子 :** `/digitalAlbum/detail?id=120605500` + +### 数字专辑销量 + +说明 : 调用此接口 , 传入专辑 id, 可获取数字专辑销量 + +**必选参数 :** `ids` : 专辑 id, 支持多个,用`,`隔开 + +**接口地址 :** `/digitalAlbum/sales` + +**调用例子 :** `/digitalAlbum/sales?ids=120605500` `/digitalAlbum/sales?ids=120605500,125080528` + +### 音乐人数据概况 + +说明 : 音乐人登录后调用此接口 , 可获取统计数据概况 + +**接口地址 :** `/musician/data/overview` + +**调用例子 :** `/musician/data/overview` + +### 音乐人播放趋势 + +说明 : 音乐人登录后调用此接口 , 可获取歌曲播放趋势 + +**必选参数 :** `startTime` : 开始时间 + +`endTime` : 结束时间 + +**接口地址 :** `/musician/play/trend` + +**调用例子 :** `/musician/play/trend?startTime=2021-05-24&endTime=2021-05-30` + +### 音乐人任务 + +说明 : 音乐人登录后调用此接口 , 可获取音乐人任务。返回的数据中`status`字段为任务状态,0 表示任务未开始,10 表示任务正在进行中,20 表示任务完成,但未领取云豆,100 表示任务完成,并且已经领取了相应的云豆(貌似只能获取到做过的任务了) + +**接口地址 :** `/musician/tasks` + +**调用例子 :** `/musician/tasks` + +### 音乐人任务(新) + +说明 : 音乐人登录后调用此接口 , 可获取音乐人任务。返回的数据中`status`字段为任务状态,0 表示任务未开始,10 表示任务正在进行中,20 表示任务完成,但未领取云豆,100 表示任务完成,并且已经领取了相应的云豆 + +**接口地址 :** `/musician/tasks/new` + +**调用例子 :** `/musician/tasks/new` + +### 账号云豆数 + +说明 : 音乐人登录后调用此接口 , 可获取账号云豆数 + +**接口地址 :** `/musician/cloudbean` + +**调用例子 :** `/musician/cloudbean` + +### 领取云豆 + +说明 : 音乐人登录后调用此接口 , 可领取已完成的音乐人任务的云豆奖励 + +**必选参数 :** `id` : 任务 id,通过`/musician/tasks`获取到的`userMissionId`即为任务 id + +`period` : 通过`/musician/tasks`获取 + +**接口地址 :** `/musician/cloudbean/obtain` + +**调用例子 :** `/musician/cloudbean/obtain?id=7036416928&period=1` + +### 获取 VIP 信息 + +说明: 登录后调用此接口,可获取当前 VIP 信息。 + +**可选参数 :** `uid` : 用户 id + +**接口地址 :** `/vip/info` + +**调用例子 :** `/vip/info`, `/vip/info?uid=32953014` + + +### 获取 VIP 信息(app端) + +说明: 登录后调用此接口,可获取当前 VIP 信息。 + +**可选参数 :** `uid` : 用户 id + +**接口地址 :** `/vip/info/v2` + +**调用例子 :** `/vip/info/v2`, `/vip/info/v2?uid=32953014` + + + +### 音乐人签到 + +说明: 音乐人登录后调用此接口,可以完成“登录音乐人中心”任务,然后通过`/musician/cloudbean/obtain`接口可以领取相应的云豆。 + +**接口地址 :** `/musician/sign` + +**调用例子 :** `/musician/sign` + +### 歌曲相关视频 + +说明: 可以调用此接口获取歌曲相关视频 (区别于 MV), 有些歌曲没有 MV 但是有用户上传的与此歌曲相关的 Mlog。 此功能仅在 网易云音乐 APP 上存在。 + +请注意:此接口偶尔会在相关视频后返回不相关视频,请合理使用。 + +**必选参数 :** `songid` : 歌曲 ID + +**可选参数 :** `mvid` : 如果定义,此 mvid 对应的 MV 将会作为第一个返回。 +`limit` : 取出的 Mlog 数量, 不包含第一个 mvid + +**接口地址 :** `/mlog/music/rcmd` + +### 公开隐私歌单 + +说明: 可以调用此接口将当前用户的隐私歌单公开。 + +**必选参数 :** `id` : 歌单 ID + +**接口地址 :** `/playlist/privacy` + +### 获取客户端歌曲下载 url + +说明 : 使用 `/song/url` 接口获取的是歌曲试听 url, 但存在部分歌曲在非 VIP 账号上可以下载无损音质而不能试听无损音质, 使用此接口可使非 VIP 账号获取这些歌曲的无损音频 + +**必选参数 :** `id` : 音乐 id (仅支持单首歌曲) + +**可选参数 :** `br` : 码率, 默认设置了 999000 即最大码率, 如果要 320k 则可设置为 320000, 其他类推 + +**接口地址 :** `/song/download/url` + +### 获取歌手视频 + +说明 : 调用此接口 , 传入歌手 id, 可获得歌手视频 + +**必选参数 :** `id` : 歌手 id + +**可选参数 :** `size` : 返回数量 , 默认为 10 + +`cursor` : 返回数据的 cursor, 默认为 0 , 传入上一次返回结果的 cursor,将会返回下一页的数据 + +`order` : 排序方法, 0 表示按时间排序, 1 表示按热度排序, 默认为 0 + +**接口地址 :** `/artist/video` + +**调用例子 :** `/artist/video?id=2116` + +### 最近播放-歌曲 + +说明 : 调用此接口 , 可获得最近播放-歌曲 + +**可选参数 :** `limit` : 返回数量 , 默认为 100 + +**接口地址 :** `/record/recent/song` + +**调用例子 :** `/record/recent/song?limit=1` + +### 最近播放-视频 + +说明 : 调用此接口 , 可获得最近播放-视频 + +**可选参数 :** `limit` : 返回数量 , 默认为 100 + +**接口地址 :** `/record/recent/video` + +**调用例子 :** `/record/recent/video?limit=1` + +### 最近播放-声音 + +说明 : 调用此接口 , 可获得最近播放-声音 + +**可选参数 :** `limit` : 返回数量 , 默认为 100 + +**接口地址 :** `/record/recent/voice` + +**调用例子 :** `/record/recent/voice?limit=1` + +### 最近播放-歌单 + +说明 : 调用此接口 , 可获得最近播放-歌单 + +**可选参数 :** `limit` : 返回数量 , 默认为 100 + +**接口地址 :** `/record/recent/playlist` + +**调用例子 :** `/record/recent/playlist?limit=1` + +### 最近播放-专辑 + +说明 : 调用此接口 , 可获得最近播放-专辑 + +**可选参数 :** `limit` : 返回数量 , 默认为 100 + +**接口地址 :** `/record/recent/album` + +**调用例子 :** `/record/recent/album?limit=1` + +### 最近播放-播客 + +说明 : 调用此接口 , 可获得最近播放-播客 + +**可选参数 :** `limit` : 返回数量 , 默认为 100 + +**接口地址 :** `/record/recent/dj` + +**调用例子 :** `/record/recent/dj?limit=1` + +### 签到进度 + +说明 : 调用此接口 , 可获得签到进度 + +**可选参数 :** `moduleId` : 模块 id,默认为 '1207signin-1207signin' + +**接口地址 :** `/signin/progress` + +**调用例子 :** `/signin/progress?moduleId=1207signin-1207signin` + +### 内部版本接口 + +说明 : 调用此接口 , 可获得内部版本号(从package.json读取) + +**接口地址 :** `/inner/version` + +**调用例子 :** `/inner/version` + +### 黑胶时光机 + +说明 : 调用此接口 , 可获得黑胶时光机数据 + +**可选参数 :** `startTime` : 开始时间 +`endTime` : 结束时间 +`limit` : 返回数量 , 默认为 60 + +**接口地址 :** `/vip/timemachine` + +**调用例子 :** `/vip/timemachine` `/vip/timemachine?startTime=1638288000000&endTime=1640966399999&limit=10`(2021年12月) `/vip/timemachine?startTime=1609430400&endTime=1640966399999&limit=60`(2021年) + +### 音乐百科 - 简要信息 + +说明: 调用此接口可以获取歌曲的音乐百科简要信息 + +由于此接口返回内容过于复杂, 请按需取用 + +**接口地址:** `/song/wiki/summary` + +**必选参数:** `id`: 歌曲 ID + +**调用例子:** `/song/wiki/summary?id=1958384591` + +### 乐谱列表 + +说明: 调用此接口可以获取歌曲的乐谱列表 + +**接口地址:** `/sheet/list` + +**必选参数:** `id`: 歌曲 ID + +**调用例子:** `/sheet/list?id=1815684465` + +### 乐谱内容 + +说明: 登录后调用此接口获取乐谱的内容 + +**接口地址:** `/sheet/preview` + +**必选参数:** `id`: **乐谱** ID + +**调用例子:** `/sheet/preview?id=143190` + +### 曲风列表 + +说明: 调用此接口获取曲风列表及其对应的 `tagId` + +**接口地址:** `/style/list` + +**调用例子:** `/style/list` + +### 曲风偏好 + +说明: 登录后调用此接口获取我的曲风偏好 + +**接口地址:** `/style/preference` + +**调用例子:** `/style/preference` + +### 曲风详情 + +说明: 调用此接口可以获取该曲风的描述信息 + +**接口地址:** `/style/detail` + +**必选参数:** `tagId`: 曲风 ID + +**调用例子:** `/style/detail?tagId=1000` + +### 曲风-歌曲 + +说明: 调用此接口可以获取该曲风对应的歌曲 + +**接口地址:** `/style/song` + +**必选参数:** `tagId`: 曲风 ID + +**可选参数 :** `size` : 返回数量 , 默认为 20 + +`cursor` : 返回数据的 cursor, 默认为 0 , 传入上一次返回结果的 cursor,将会返回下一页的数据 + +`sort`: 排序方式,0: 按热度排序,1: 按时间排序 + +**调用例子:** `/style/song?tagId=1000` `/style/song?tagId=1010&sort=1` + +### 曲风-专辑 + +说明: 调用此接口可以获取该曲风对应的专辑 + +**接口地址:** `/style/album` + +**必选参数:** `tagId`: 曲风 ID + +**可选参数 :** `size` : 返回数量 , 默认为 20 + +`cursor` : 返回数据的 cursor, 默认为 0 , 传入上一次返回结果的 cursor,将会返回下一页的数据 + +`sort`: 排序方式,0: 按热度排序,1: 按时间排序 + +**调用例子:** `/style/album?tagId=1000` `/style/album?tagId=1010&sort=1` + +### 曲风-歌单 + +说明: 调用此接口可以获取该曲风对应的歌单 + +**接口地址:** `/style/playlist` + +**必选参数:** `tagId`: 曲风 ID + +**可选参数 :** `size` : 返回数量 , 默认为 20 + +`cursor` : 返回数据的 cursor, 默认为 0 , 传入上一次返回结果的 cursor,将会返回下一页的数据 + +**调用例子:** `/style/playlist?tagId=1000` + +### 曲风-歌手 + +说明: 调用此接口可以获取该曲风对应的歌手 + +**接口地址:** `/style/artist` + +**必选参数:** `tagId`: 曲风 ID + +**可选参数 :** `size` : 返回数量 , 默认为 20 + +`cursor` : 返回数据的 cursor, 默认为 0 , 传入上一次返回结果的 cursor,将会返回下一页的数据 + +**调用例子:** `/style/artist?tagId=1000` + +### 云村星评馆 - 简要评论 + +说明: 调用此接口可以获取首页推荐的星评馆评论信息 + +**接口地址:** `/starpick/comments/summary` + +### 私人 DJ + +说明: 调用此接口可以获取私人 DJ 的推荐内容 (包括 DJ 声音和推荐歌曲) + +**接口地址:** `/aidj/content/rcmd` + +**可选参数:** `longitude` `latitude` : 当前的经纬度 + +### 回忆坐标 + +说明: 可以获取当前歌曲的回忆坐标信息 (见手机 APP 百科页的回忆坐标功能) + +**接口地址:** `/music/first/listen/info` + +**必选参数:** `id` : 歌曲 ID + +### 播客列表 + +说明: 可以获取播客列表 + +**接口地址:** `/voicelist/search` + +**可选参数:** + +`limit`: 取出歌单数量 , 默认为 200 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*200, 其中 200 为 limit 的值 + +`podcastName`: 播客名称 + +### 播客声音列表 + +说明: 可以获取播客里的声音 + +**接口地址:** `/voicelist/list` + +**必选参数:** +`voiceListId`: 播客id + +**可选参数:** +`limit`: 取出歌单数量 , 默认为 200 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*200, 其中 200 为 limit 的值 + +### 播客上传声音 +说明: 可以上传声音到播客,例子在 `/public/voice_upload.html` 访问地址: /voice_upload.html + +**接口地址:** `/voice/upload` + +**必选参数:** +`voiceListId`: 播客 id + +`coverImgId`: 播客封面 + +`categoryId`: 分类id + +`secondCategoryId`:次级分类id + +`description`: 声音介绍 + + +**可选参数:** +`songName`: 声音名称 + +`privacy`: 设为隐私声音,播客如果是隐私博客,则必须设为1 + +`publishTime`:默认立即发布,定时发布的话需传入时间戳 + +`autoPublish`: 是否发布动态,是则传入1 + +`autoPublishText`: 动态文案 + +`orderNo`: 排序,默认为1 + +`composedSongs`: 包含歌曲(歌曲id),多个用逗号隔开 + +### 验证接口-二维码生成 +说明: 进行某些操作,如关注用户,可能会触发验证,可调用这个接口生成二维码,使用app扫码后可解除验证 + +**接口地址:** `/verify/getQr` + +**必选参数:** + +`vid`: 触发验证后,接口返回的verifyId + +`type`:触发验证后,接口返回的verifyType + +`token`:触发验证后,接口返回的verifyToken + +`evid`:触发验证后,接口返回的params的event_id + +`sign`:触发验证后,接口返回的params的sign + +### 验证接口-二维码检测 +说明: 使用此接口,传入`/verify/getQr`接口返回的`qr`字符串,可检测二维码扫描状态 + +**接口地址:** `/verify/qrcodestatus` + +**必选参数:** + +`qr`: `/verify/getQr`接口返回的`qr`字符串 + +返回结果说明: + +qrCodeStatus:0,detailReason:0 二维码生成成功 + +qrCodeStatus:0,detailReason:303 账号不一致 + +qrCodeStatus:10,detailReason:0 二维码已扫描,并且手机号相同 + +qrCodeStatus:20,detailReason:0 验证成功qrCodeStatus:21,detailReason:0 二维码已失效 + +### 听歌识曲 +说明: 使用此接口,上传音频文件或者麦克风采集声音可识别对应歌曲信息,具体调用例子参考 `/audio_match_demo/index.html` (项目文件: `public/audio_match_demo/index.html`) + +**接口地址:** `/audio/match` + +**必选参数:** + +`duration`: 音频时长,单位秒 + +`audioFP`: 音频指纹,参考项目调用例子获取 + +### 根据nickname获取userid +说明: 使用此接口,传入用户昵称,可获取对应的用户id,支持批量获取,多个昵称用`分号(;)`隔开 + +**必选参数:** + +`nicknames`: 用户昵称,多个用分号(;)隔开 + +**接口地址:** `/get/userids` + +**调用例子:** `/get/userids?nicknames=binaryify` `/get/userids?nicknames=binaryify;binaryify2` + + +## 离线访问此文档 + +此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问 + +## 关于此文档 + +此文档由 [docsify](https://github.com/QingWei-Li/docsify/) 生成 docsify 是一个动态生成文档网站的工具。不同于 GitBook、Hexo 的地方是它不会生成将 .md 转成 .html 文件,所有转换工作都是在运行时进行。 + +## License + +[The MIT License (MIT)](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/LICENSE) diff --git a/WebSourceCode/src/Netease/docs/_coverpage.md b/WebSourceCode/src/Netease/docs/_coverpage.md new file mode 100644 index 0000000..e65dce2 --- /dev/null +++ b/WebSourceCode/src/Netease/docs/_coverpage.md @@ -0,0 +1,13 @@ +# 网易云音乐 API + +> 网易云音乐 NodeJS 版 API + +- 全部接口已升级到最新 +- 具备登录接口,多达200多个接口 +- 更完善的文档 + + +[GitHub](https://github.com/Binaryify/NeteaseCloudMusicApi) +[Get Started](#neteasecloudmusicapi) + +![color](#ffffff) diff --git a/WebSourceCode/src/Netease/docs/favicon.ico b/WebSourceCode/src/Netease/docs/favicon.ico new file mode 100644 index 0000000..2e28d04 Binary files /dev/null and b/WebSourceCode/src/Netease/docs/favicon.ico differ diff --git a/WebSourceCode/src/Netease/docs/icon.png b/WebSourceCode/src/Netease/docs/icon.png new file mode 100644 index 0000000..92eda4c Binary files /dev/null and b/WebSourceCode/src/Netease/docs/icon.png differ diff --git a/WebSourceCode/src/Netease/docs/index.html b/WebSourceCode/src/Netease/docs/index.html new file mode 100644 index 0000000..966c514 --- /dev/null +++ b/WebSourceCode/src/Netease/docs/index.html @@ -0,0 +1,46 @@ + + + + + + + 网易云音乐 NodeJS 版 API + + + + + + + + + +
+ + + + + + + + diff --git a/WebSourceCode/src/Netease/docs/sw.js b/WebSourceCode/src/Netease/docs/sw.js new file mode 100644 index 0000000..a50f9ba --- /dev/null +++ b/WebSourceCode/src/Netease/docs/sw.js @@ -0,0 +1,90 @@ +/* =========================================================== + * docsify sw.js + * =========================================================== + * Copyright 2016 @huxpro + * Licensed under Apache 2.0 + * Register service worker. + * ========================================================== */ + +const RUNTIME = 'docsify' +const HOSTNAME_WHITELIST = [ + self.location.hostname, + 'fonts.gstatic.com', + 'fonts.googleapis.com', + 'unpkg.com', +] + +// The Util Function to hack URLs of intercepted requests +const getFixedUrl = (req) => { + var now = Date.now() + var url = new URL(req.url) + + // 1. fixed http URL + // Just keep syncing with location.protocol + // fetch(httpURL) belongs to active mixed content. + // And fetch(httpRequest) is not supported yet. + url.protocol = self.location.protocol + + // 2. add query for caching-busting. + // Github Pages served with Cache-Control: max-age=600 + // max-age on mutable content is error-prone, with SW life of bugs can even extend. + // Until cache mode of Fetch API landed, we have to workaround cache-busting with query string. + // Cache-Control-Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=453190 + if (url.hostname === self.location.hostname) { + url.search += (url.search ? '&' : '?') + 'cache-bust=' + now + } + return url.href +} + +/** + * @Lifecycle Activate + * New one activated when old isnt being used. + * + * waitUntil(): activating ====> activated + */ +self.addEventListener('activate', (event) => { + event.waitUntil(self.clients.claim()) +}) + +/** + * @Functional Fetch + * All network requests are being intercepted here. + * + * void respondWith(Promise r) + */ +self.addEventListener('fetch', (event) => { + // Skip some of cross-origin requests, like those for Google Analytics. + if (HOSTNAME_WHITELIST.indexOf(new URL(event.request.url).hostname) > -1) { + // Stale-while-revalidate + // similar to HTTP's stale-while-revalidate: https://www.mnot.net/blog/2007/12/12/stale + // Upgrade from Jake's to Surma's: https://gist.github.com/surma/eb441223daaedf880801ad80006389f1 + const cached = caches.match(event.request) + const fixedUrl = getFixedUrl(event.request) + const fetched = fetch(fixedUrl, { cache: 'no-store' }) + const fetchedCopy = fetched.then((resp) => resp.clone()) + + // Call respondWith() with whatever we get first. + // If the fetch fails (e.g disconnected), wait for the cache. + // If there’s nothing in cache, wait for the fetch. + // If neither yields a response, return offline pages. + event.respondWith( + Promise.race([fetched.catch((_) => cached), cached]) + .then((resp) => resp || fetched) + .catch((_) => { + /* eat any errors */ + }), + ) + + // Update the cache with the version we fetched (only for ok status) + event.waitUntil( + Promise.all([fetchedCopy, caches.open(RUNTIME)]) + .then( + ([response, cache]) => + response.ok && cache.put(event.request, response), + ) + .catch((_) => { + /* eat any errors */ + }), + ) + } +}) diff --git a/WebSourceCode/src/Netease/docs/v2.md b/WebSourceCode/src/Netease/docs/v2.md new file mode 100644 index 0000000..08ba02f --- /dev/null +++ b/WebSourceCode/src/Netease/docs/v2.md @@ -0,0 +1,1430 @@ +# NeteaseCloudMusicApi + +网易云音乐 NodeJS 版 API + +## 灵感来自 + +[disoul/electron-cloud-music](https://github.com/disoul/electron-cloud-music) + +[darknessomi/musicbox](https://github.com/darknessomi/musicbox) + +[sqaiyan/netmusic-node](https://github.com/sqaiyan/netmusic-node) + +## 工作原理 + +跨站请求伪造 (CSRF), 伪造请求头 , 调用官方 API + +## 功能特性 + +1. 登录 +2. 刷新登录 +3. 获取用户信息 , 歌单,收藏,mv, dj 数量 +4. 获取用户歌单 +5. 获取用户电台 +6. 获取用户关注列表 +7. 获取用户粉丝列表 +8. 获取用户动态 +9. 获取用户播放记录 +10. 获取精品歌单 +11. 获取歌单详情 +12. 搜索 +13. 搜索建议 +14. 获取歌词 +15. 歌曲评论 +16. 收藏单曲到歌单 +17. 专辑评论 +18. 歌单评论 +19. mv 评论 +20. 电台节目评论 +21. banner +22. 获取歌曲详情 +23. 获取专辑内容 +24. 获取歌手单曲 +25. 获取歌手 mv +26. 获取歌手专辑 +27. 获取歌手描述 +28. 获取相似歌手 +29. 获取相似歌单 +30. 相似 mv +31. 获取相似音乐 +32. 获取最近 5 个听了这首歌的用户 +33. 获取每日推荐歌单 +34. 获取每日推荐歌曲 +35. 私人 FM +36. 签到 +37. 喜欢音乐 +38. 垃圾桶 +39. 歌单 ( 网友精选碟 ) +40. 新碟上架 +41. 热门歌手 +42. 最新 mv +43. 推荐 mv +44. 推荐歌单 +45. 推荐新音乐 +46. 推荐电台 +47. 推荐节目 +48. 独家放送 +49. mv 排行 +50. 获取 mv 数据 +51. 播放 mv/视频 +52. 排行榜 +53. 歌手榜 +54. 云盘 +55. 电台 - 推荐 +56. 电台 - 分类 +57. 电台 - 分类推荐 +58. 电台 - 订阅 +59. 电台 - 详情 +60. 电台 - 节目 +61. 给评论点赞 +62. 获取动态 +63. 获取热搜 +64. 发送私信 +65. 发送私信歌单 +66. 新建歌单 +67. 收藏/取消收藏歌单 +68. 歌单分类 +69. 收藏的歌手列表 +70. 订阅的电台列表 +71. 相关歌单推荐 +72. 付费精选接口 +73. 音乐是否可用检查接口 +74. 登录状态 +75. 获取视频数据 +76. 发送/删除评论 +77. 热门评论 +78. 视频评论 +79. 退出登录 + +## 安装 + +```shell +$ git clone git@github.com:Binaryify/NeteaseCloudMusicApi.git +$ npm install +``` + +## 运行 + +```shell +$ node app.js +``` + +服务器启动默认端口为 3000, 若不想使用 3000 端口 , 可使用以下命令 : Mac/Linux + +```shell +$ PORT=4000 node app.js +``` + +windows 下使用 git-bash 或者 cmder 等终端执行以下命令 : + +```shell +$ set PORT=4000 && node app.js +``` + +## 可以使用代理 + +在 query 参数中加上 proxy=your-proxy 即可让这一次的请求使用 proxy + +```javascript +// 例子 +const url = `http://localhost:3000/music/url?id=33894312&proxy=http://121.196.226.246:84` +fetch(url).then(function() { + // do what you want +}) + +// 结果 +// {"data":[{"id":33894312,"url":"http://m10.music.126.net/20180104125640/930a968b3fb04908b733506b3833e60b/ymusic/0fd6/4f65/43ed/a8772889f38dfcb91c04da915b301617.mp3","br":320000,"size":10691439,"md5":"a8772889f38dfcb91c04da915b301617","code":200,"expi":1200,"type":"mp3","gain":-2.0E-4,"fee":0,"uf":null,"payed":0,"flag":0,"canExtend":false}],"code": 200} +``` + +## Docker 容器运行 + +> 注意: 在 docker 中运行的时候, 由于使用了 request 来发请求, 所以会检查几个 +> proxy 相关的环境变量(如下所列), 这些环境变量 会影响到 request 的代理, 详情请参 +> 考[request 的文档](https://github.com/request/request#proxies), 如果这些环境变 +> 量 指向的代理不可用, 那么就会造成错误, 所以在使用 docker 的时候一定要注意这些 +> 环境变量. 不过, 要是你在 query 中加上了 proxy 参数, 那么环境变量会被覆盖, 就会 +> 用你通过 proxy 参数提供的代理了. + +request 相关的环境变量 + +1. http_proxy +2. https_proxy +3. HTTP_PROXY +4. HTTPS_PROXY +5. no_proxy +6. NO_PROXY + +```shell +docker pull twesix/netease-cloud-music +docker run -d -p 3000:3000 --name netease-cloud-music twesix/netease-music-api + +// 去掉或者设置相关的环境变量 +docker run -d -p 3000:3000 --name netease-cloud-music -e http_proxy= -e https_proxy= -e no_proxy= -e HTTP_PROXY= -e HTTPS_PROXY= -e NO_PROXY= netease-cloud-music +``` + +> 由于 docker 镜像更新不是很及时,推荐自己 build, 以下为 build 镜像的方式 + +``` +$ git clone https://github.com/Binaryify/NeteaseCloudMusicApi && cd NeteaseCloudMusicApi +$ sudo docker build . -t netease-music-api +$ sudo docker run -d -p 3000:3000 netease-music-api +``` + +## 接口文档 + +### 调用前须知 + +!> 为使用方便,降低门槛,登录接口直接使用了 get 明文请求,请按实际需求对源码修改 + +!> 由于接口做了缓存处理 ( 缓存 2 分钟 , 可在 app.js 设置 , 可能会导致登录后获取不 +到 cookie), 相同的 url 会在两分钟内只向网易服务器发一次请求 , 如果遇到不需要缓 +存结果的接口 , 可在请求 url 后面加一个时间戳参数使 url 不同 , 例子 : +`/simi/playlist?id=347230×tamp=1503019930000` + +!> 如果是跨域请求 , 请在所有请求带上 `xhrFields: { withCredentials: true }` 否则 +可能会因为没带上 cookie 导致 301, 具体例子可看 `public/test.html`, 例子使用 jQuery, axios 版本也类似 + +!> 301 错误基本都是没登录就调用了需要登录的接口,如果登录了还是提示 301, 基本都是缓存把数据缓存起来了,解决方法是等待 2 分钟或者重启服务重新登录后再调用接口 + +!> 部分接口如登录接口不能调用太频繁 , 否则可能会触发 503 错误或者 ip 高频错误 ,若需频繁调用 , 需要准备 IP 代理池 (更新:已加入缓存机制,但仍需注意). + +!> 本项目仅供学习使用 , 文档可能会有缓存 , 如果文档版本和 github 上的版本不一致,请清除缓存再查看 + +!> 由于网易限制,此项目在国外服务器上使用会受到限制,如需解决 , 可使用大陆服务器或者使用代理 , 感谢 [@hiyangguo](https://github.com/hiyangguo)提出的[解决方法](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/29#issuecomment-298358438): +在 'util.js' 的 'headers' 处增加 `X-Real-IP':'211.161.244.70' // 任意国内 IP` +即可解决 + +### 登录 + +说明 : 登录有两个接口 + +#### 1. 手机登录 + +**必选参数 :** `phone`: 手机号码 `password`: 密码 + +**接口地址 :** `/login/cellphone` + +**调用例子 :** `/login/cellphone?phone=xxx&password=yyy` + +#### 2. 邮箱登录 + +~~ 注意 : 此接口被网易和谐了 , 待修复 , 暂时使用手机登录 (2017.05.20)~~ + +> 更新 : 此接口已经可以正常使用(2018.07.03) + +**必选参数 :** `email`: 163 网易邮箱 `password`: 密码 + +**接口地址 :** `/login` + +**调用例子 :** `/login?email=xxx@163.com&password=yyy` + +返回数据如下图 : +![登录](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E7%99%BB%E5%BD%95.png) + +完成登录后 , 会在浏览器保存一个 Cookies 用作登录凭证 , 大部分 API 都需要用到这个 +Cookies + +#### 注意 + +调用登录接口的速度比调用其他接口慢 , 因为登录过程调用了加密算法 + +### 刷新登录 + +说明 : 调用此接口 , 可刷新登录状态 + +**调用例子 :** `/login/refresh` + +### 退出登录 + +说明 : 调用此接口 , 可退出登录 + +**调用例子 :** `/logout` + +### 登录状态 + +说明 : 调用此接口,可获取登录状态 + +**接口地址 :** `/login/status` +返回数据如下图: +![数据](https://ws2.sinaimg.cn/large/006tNbRwgy1fup6q18kk6j316i0nw0wa.jpg) + +### 获取用户详情 + +说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户详情 + +**必选参数 :** `uid` : 用户 id + +**接口地址 :** `/user/detail` + +**调用例子 :** `/user/detail?uid=32953014` + +### 获取用户信息 , 歌单,收藏,mv, dj 数量 + +说明 : 登录后调用此接口 , 可以获取用户信息 + +**接口地址 :** `/user/subcount` + +**调用例子 :** `/user/subcount` + +### 更新用户信息 + +说明 : 登录后调用此接口 , 传入相关信息,可以更新用户信息 + +**必选参数 :** + +``` +gender: 性别 0:保密 1:男性 2:女性 +birthday: 出生日期,时间戳 unix timestamp +nickname: 用户昵称 +province: 省份id +city: 城市id +signature:用户签名 +``` + +**接口地址 :** `/user/subcount` + +**调用例子 :** `/user/update/?gender=0&signature=测试签名&city=440300&nickname=binary&birthday=1525918298004&province=440000` + +### 获取用户歌单 + +说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户歌单 + +**必选参数 :** `uid` : 用户 id + +**接口地址 :** `/user/playlist` + +**调用例子 :** `/user/playlist?uid=32953014` + +返回数据如下图 : +![用户歌单](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E7%94%A8%E6%88%B7%E6%AD%8C%E5%8D%95.png) + +### 更新歌单 + +说明 : 登录后调用此接口,可以更新用户歌单 +参数: + +``` +id:歌单id +name:歌单名字 +desc:歌单描述 +tags:歌单tag +``` + +**接口地址 :** `/playlist/update` + +**调用例子 :** `/playlist/update/?id=24381616&name=新歌单&desc=描述&tags=学习` + +### 发送私信 + +说明 : 登录后调用此接口 , 传入用户 id 和要发送的信息, 可以发送私信,返回内容为历史私信,包含带歌单的私信信息(注:不能发送私信给自己) + +**必选参数 :** + +`user_ids` : 用户 id,多个需用逗号隔开 + +`msg` : 要发送的信息 + +**接口地址 :** `/send/text` + +**调用例子 :** `/send/text?user_ids=32953014&msg=test`,`/send/text?user_ids=32953014,475625142&msg=test` +返回数据如下图: +![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr3p3hfeudj31kw1aek2e.jpg) + +### 发送私信(带歌单) + +说明 : 登录后调用此接口 , 传入用户 id 和要发送的信息和歌单 id, 可以发送带歌单的私信(注:不能发送重复的歌单) + +**必选参数 :** + +`user_ids` : 用户 id,多个需用逗号隔开 + +`msg` : 要发送的信息 + +**接口地址 :** `/send/playlist` + +**调用例子 :** `/send/playlist?msg=test&user_ids=475625142&playlist=705123491`,`/send/playlist?msg=test2&user_ids=475625142,32953014&playlist=705123493` +返回数据如下图: +![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr3p1z7qmcj30v409adg5.jpg) + +### 获取用户电台 + +说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户电台 + +**必选参数 :** `uid` : 用户 id + +**接口地址 :** `/user/dj` + +**调用例子 :** `/user/dj?uid=32953014` + +### 获取用户关注列表 + +说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户关注列表 + +**必选参数 :** `uid` : 用户 id + +**可选参数 :** +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 +: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +**接口地址 :** `/user/follows` + +**调用例子 :** `/user/follows?uid=32953014` + +### 获取用户粉丝列表 + +说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户粉丝列表 + +**必选参数 :** `uid` : 用户 id + +**可选参数 :** `limit` : 返回数量 , 默认为 30 `offset` : 偏移数量,用于分页 , 如 +: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +**接口地址 :** `/user/followeds` + +**调用例子 :** `/user/followeds?uid=32953014` + +### 获取用户动态 + +说明 : 登录后调用此接口 , 传入用户 id, 可以获取用户动态 + +**必选参数 :** `uid` : 用户 id + +**接口地址 :** `/user/event` + +**调用例子 :** `/user/event?uid=32953014` + +### 获取用户播放记录 + +说明 : 登录后调用此接口 , 传入用户 id, 可获取用户播放记录 + +**必选参数 :** `uid` : 用户 id + +**可选参数 :** `type` : type=1 时只返回 weekData, type=0 时返回 allData + +**接口地址 :** `/user/record` + +**调用例子 :** `/user/record?uid=32953014&type=1` + +### 获取动态消息 + +说明 : 调用此接口 , 可获取各种动态 , 对应网页版网易云,朋友界面里的各种动态消息 +,如分享的视频,音乐,照片等! + +**必选参数 :** 未知 + +**接口地址 :** `/event` + +**调用例子 :** `/event` + +### 歌手分类列表 + +说明 : 调用此接口,可获取歌手分类列表 +**必选参数 :** `cat` : 即 category Code,歌手类型,默认 1001,返回华语男歌手数据 +**可选参数 :** +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 +: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 +`initial`: 按首字母索引查找参数,如 `/artist/list?cat=1001&initial=b` 返回内容将以 name 字段开头为 b 或者拼音开头为 b 为顺序排列 + +category Code 取值: + +``` +入驻歌手 5001 +华语男歌手 1001 +华语女歌手 1002 +华语组合/乐队 1003 +欧美男歌手 2001 +欧美女歌手 2002 +欧美组合/乐队 2003 +日本男歌手 6001 +日本女歌手 6002 +日本组合/乐队 6003 +韩国男歌手 7001 +韩国女歌手 7002 +韩国组合/乐队 7003 +其他男歌手 4001 +其他女歌手 4002 +其他组合/乐队 4003 +``` + +**接口地址 :** `/artist/list` + +**调用例子 :** `/artist/list?cat=1001` + +返回数据如下图: +![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr60g9zps9j31kw1bpk4n.jpg) + +### 收藏歌手 + +说明 : 调用此接口,可收藏歌手 +**必选参数 :** `artistId` : 歌手 id + +**接口地址 :** `/artist/sub` + +**调用例子 :** `/artist/sub?id=6452` + +### 取消收藏歌手 + +说明 : 调用此接口,可取消收藏歌手 +**必选参数 :** `artistId` : 歌手 id + +**接口地址 :** `/artist/unsub` + +**调用例子 :** `/artist/unsub?id=6452` + +### 收藏的歌手列表 + +说明 : 调用此接口,可获取收藏的歌手列表 + +**接口地址 :** `/artist/sublist` + +**调用例子 :** `/artist/sublist` + +### 歌单分类 + +说明 : 调用此接口,可获取歌单分类,包含 category 信息 + +**接口地址 :** `/playlist/catlist` + +**调用例子 :** `/playlist/catlist` + +### 热门歌单分类 + +说明 : 调用此接口,可获取歌单分类,包含 category 信息 + +**接口地址 :** `/playlist/hot` + +**调用例子 :** `/playlist/hot` + +### 歌单 ( 网友精选碟 ) + +说明 : 调用此接口 , 可获取网友精选碟歌单 + +**可选参数 :** `order`: 可选值为 'new' 和 'hot', 分别对应最新和最热 , 默认为 +'hot' + +`cat`:`cat`: tag, 比如 " 华语 "、" 古风 " 、" 欧美 "、" 流行 ", 默认为 +"全部",可从歌单分类接口获取(/playlist/catlist) + +**接口地址 :** `/top/playlist` + +**调用例子 :** `/top/playlist?limit=10&order=new` + +返回数据如下图 : + +![精选碟](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/top_playlist.png) +![对应位置](https://ws2.sinaimg.cn/large/006tKfTcgy1fr3wnpyg6jj317e0vcqdc.jpg) +![返回数据](https://ws4.sinaimg.cn/large/006tKfTcgy1fr3wqs5lw9j31ic1re4c4.jpg) + +### 获取精品歌单 + +说明 : 调用此接口 , 可获取精品歌单 + +**可选参数 :** `cat`: tag, 比如 " 华语 "、" 古风 " 、" 欧美 "、" 流行 ", 默认为 +"全部",可从歌单分类接口获取(/playlist/catlist) + +`limit`: 取出歌单数量 , 默认为 20 + +**接口地址 :** `/top/playlist/highquality` + +**调用例子 :** `/top/playlist/highquality?limit=30` + +### 相关歌单推荐 + +说明 : 调用此接口,传入歌单 id 可获取相关歌单(对应页面 [https://music.163.com/#/playlist?id=1](https://music.163.com/#/playlist?id=1)) + +**必选参数 :** `id` : 歌单 id + +**接口地址 :** `/related/playlist` + +**调用例子 :** `/related/playlist?id=1` + + +### 获取歌单详情 + +说明 : 歌单能看到歌单名字 , 但看不到具体歌单内容 , 调用此接口 , 传入歌单 id, 可 +以获取对应歌单内的所有的音乐 + +**必选参数 :** `id` : 歌单 id + +**可选参数 :** `s` : 歌单最近的 s 个收藏者 + +**接口地址 :** `/playlist/detail` + +**调用例子 :** `/playlist/detail?id=24381616` + +返回数据如下图 : +![歌单详情](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E6%AD%8C%E5%8D%95%E8%AF%A6%E6%83%85.png) + +### 获取音乐 url + +说明 : 使用歌单详情接口后 , 能得到的音乐的 id, 但不能得到的音乐 url, 调用此接口 +, 传入的音乐 id( 可多个 , 用逗号隔开 ), 可以获取对应的音乐的 url( 不需要登录 ) + +> 注 : 部分用户反馈获取的 url 会 403,[hwaphon](https://github.com/hwaphon)找到的 +> 解决方案是当获取到音乐的 id 后,将 +> https://music.163.com/song/media/outer/url?id=id.mp3 以 src 赋予 Audio 即可播放 + +**必选参数 :** `id` : 音乐 id + +**可选参数 :** `br`: 码率,默认设置了 999000 即最大码率,如果要 320k 则可设置为 320000,其他类推 + +**接口地址 :** `/music/url` + +**调用例子 :** `/music/url?id=33894312` `/music/url?id=405998841,33894312` + +返回数据如下图 : +![音乐 url](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E9%9F%B3%E4%B9%90%20url.png) + +### 音乐是否可用 + +说明: 调用此接口,传入歌曲 id, 可获取音乐是否可用,返回 `{ success: true, message: 'ok' }` 或者 `{ success: false, message: '亲爱的,暂无版权' }` + +**必选参数 :** `id` : 歌曲 id + +**可选参数** : `br`: 码率,默认设置了 999000 即最大码率,如果要 320k 则可设置为 320000,其他类推 + +**接口地址 :** `/check/music` + +**调用例子 :** `/check/music?id=33894312` + +### 搜索 + +说明 : 调用此接口 , 传入搜索关键词可以搜索该音乐 / 专辑 / 歌手 / 歌单 / 用户 , +关键词可以多个 , 以空格隔开 , 如 " 周杰伦 搁浅 "( 不需要登录 ), 搜索获取的 +mp3url 不能直接用 , 可通过 `/music/url` 接口传入歌曲 id 获取具体的播放链接 + +**必选参数 :** `keywords` : 关键词 + +**可选参数 :** `limit` : 返回数量 , 默认为 30 `offset` : 偏移数量,用于分页 , 如 +: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +`type`: 搜索类型;默认为 1 即单曲 , 取值意义 : 1: 单曲, 10: 专辑, 100: 歌手, 1000: +歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频 + +**接口地址 :** `/search` + +**调用例子 :** `/search?keywords= 海阔天空` + +返回数据如下图 : +![搜索音乐](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E6%90%9C%E7%B4%A2.png) + +### 热搜 + +说明 : 调用此接口,可获取热门搜索列表 + +**接口地址 :** `/search/hot` + +**调用例子 :** `/search/hot` + +### 搜索建议 + +说明 : 调用此接口 , 传入搜索关键词可获得搜索建议 , 搜索结果同时包含单曲 , 歌手 , +歌单 ,mv 信息 + +**必选参数 :** `keywords` : 关键词 + +**可选参数 :** +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 +: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +`type`: 搜索类型;默认为 1 即单曲 , 取值意义 : 1: 单曲 10: 专辑 100: 歌手 1000: +歌单 1002: 用户 1004: MV 1006: 歌词 1009: 电台 + +**接口地址 :** `/search/suggest` + +**调用例子 :** `/search/suggest?keywords= 海阔天空` + +### 搜索多重匹配 + +说明 : 调用此接口 , 传入搜索关键词可获得搜索结果 + +**必选参数 :** `keywords` : 关键词 + +**接口地址 :** `/search/multimatch` + +**调用例子 :** `/search/multimatch?keywords= 海阔天空` + +### 新建歌单 + +说明 : 调用此接口 , 传入歌单名字可新建歌单 + +**必选参数 :** `name` : 歌单名 + +**接口地址 :** `/playlist/create` + +**调用例子 :** `/playlist/create?name=测试歌单` + +返回数据如下图: +![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr3va885z5j31a617qwjy.jpg) + +### 收藏/取消收藏歌单 + +说明 : 调用此接口 , 传入类型和歌单 id 可收藏歌单或者取消收藏歌单 + +**必选参数 :** +`t` : 类型,1:收藏,2:取消收藏 +`id` : 歌单 id + +**接口地址 :** `/playlist/subscribe` + +**调用例子 :** `/playlist/subscribe?t=1&id=106697785` `/playlist/subscribe?t=2&id=106697785` + +返回数据如下图: +![数据](https://ws1.sinaimg.cn/large/006tKfTcgy1fr3vdwx0hvj30s405u74b.jpg) + +### 对歌单添加或删除歌曲 + +说明 : 调用此接口 , 可以添加歌曲到歌单或者从歌单删除某首歌曲 ( 需要登录 ) + +**必选参数 :** +`op`: 从歌单增加单曲为 add, 删除为 del + +`pid`: 歌单 id +`tracks`: 歌曲 id,可多个,用逗号隔开 + +**接口地址 :** `/playlist/tracks` + +**调用例子 :** `/playlist/tracks?op=add&pid=24381616&tracks=347231` ( 对应把歌曲添加到 ' 我 ' 的歌单 , 测试的时候请把这里的 pid 换成你自己的, id 和 tracks 不对可能会报 502 错误) + +### 获取歌词 + +说明 : 调用此接口 , 传入音乐 id 可获得对应音乐的歌词 ( 不需要登录 ) + +**必选参数 :** `id`: 音乐 id + +**接口地址 :** `/lyric` + +**调用例子 :** `/lyric?id=33894312` + +返回数据如下图 : +![获取歌词](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E6%AD%8C%E8%AF%8D.png) + +### 歌曲评论 + +说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该音乐的所有评论 ( 不需要 +登录 ) + +**必选参数 :** `id`: 音乐 id + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +**接口地址 :** `/comment/music` + +**调用例子 :** `/comment/music?id=186016&limit=1` 对应晴天评论 + +返回数据如下图 : +![获取评论](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/comment.png) + +### 专辑评论 + +说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该专辑的所有评论 ( 不需要 +登录 ) + +**必选参数 :** `id`: 专辑 id + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +**接口地址 :** `/comment/album` + +**调用例子 :** `/comment/album?id=32311` + +### 歌单评论 + +说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该歌单的所有评论 ( 不需要 +登录 ) + +**必选参数 :** `id`: 歌单 id + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +**接口地址 :** `/comment/playlist` + +**调用例子 :** `/comment/playlist?id=705123491` + +### mv 评论 + +说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 mv 的所有评论 ( 不需要 +登录 ) + +**必选参数 :** `id`: mv id + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +**接口地址 :** `/comment/mv` + +**调用例子 :** `/comment/mv?id=5436712` + +### 电台节目评论 + +说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 电台节目 的所有评论 ( +不需要登录 ) + +**必选参数 :** `id`: 电台节目的 id + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +**接口地址 :** `/comment/dj` + +**调用例子 :** `/comment/dj?id=794062371` + +### 视频评论 + +说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该 视频 的所有评论 ( +不需要登录 ) + +**必选参数 :** `id`: 视频的 id + +**可选参数 :** `limit`: 取出评论数量 , 默认为 20 + +`offset`: 偏移数量 , 用于分页 , 如 :( 评论页数 -1)\*20, 其中 20 为 limit 的值 + +**接口地址 :** `/comment/video` + +**调用例子 :** `/comment/video?id=89ADDE33C0AAE8EC14B99F6750DB954D` + +### 热门评论 + +说明 : 调用此接口 , 传入 type, 资源 id 可获得对应资源热门评论 ( 不需要登录 ) + +**必选参数 :** + +`id` : 资源 id + +`type`: 数字 , 资源类型 , 对应歌曲 , mv, 专辑 , 歌单 , 电台, 视频对应以下类型 + +``` +0: 歌曲 +1: mv +2: 歌单 +3: 专辑 +4: 电台 +5: 视频 +``` + +**接口地址 :** `/comment/hot` + +**调用例子 :** `/comment/hot?id=186016&type=0` + +### 给评论点赞 + +说明 : 调用此接口 , 传入 type, 资源 id, 和评论 id cid 和 是否点赞参数 t 即可给对 +应评论点赞 ( 需要登录 ) + +**必选参数 :** `id` : 资源 id, 如歌曲 id,mv id + +`cid` : 评论 id + +`t` : 是否点赞 ,1 为点赞 ,0 为取消点赞 + +`type`: 数字 , 资源类型 , 对应歌曲 , mv, 专辑 , 歌单 , 电台, 视频对应以下类型 + +``` +0: 歌曲 +1: mv +2: 歌单 +3: 专辑 +4: 电台 +5: 视频 +``` + +**接口地址 :** `comment/like` + +**调用例子 :** `/comment/like?id=29178366&cid=12840183&t=1&type=0` 对应给 [https://music.163.com/#/song?id=29178366](https://music.163.com/#/song?id=29178366) 最热门的评论点赞 + +### 发送/删除评论 + +说明 : 调用此接口,可发送评论或者删除评论 + +**接口地址 :** `/comment` + +1. 发送评论 + + **必选参数** + `action`:1 发送 + + `type`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型 + + ``` + 0: 歌曲 + 1: mv + 2: 歌单 + 3: 专辑 + 4: 电台 + 5: 视频 + ``` + + `id`:对应资源 id + + `content` :要发送的内容 + + **调用例子** : `/comment?action=1&type=1&id=5436712&content=test` (往广岛之恋 mv 发送评论: test) + +2. 删除评论 + + **必选参数** + `action`:0 删除 + + `type`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型 + + ``` + 0: 歌曲 + 1: mv + 2: 歌单 + 3: 专辑 + 4: 电台 + 5: 视频 + ``` + + `id`:对应资源 id + `content` :内容 id,可通过 `/comment/mv` 等接口获取 + + **调用例子** : `/comment?action=0&type=1&id=5436712&commentId=1535550516319` (在广岛之恋 mv 删除评论) + +### banner + +说明 : 调用此接口 , 可获取 banner( 轮播图 ) 数据注 : 因参数未知 , 只能获取比较旧 +的数据 , 如果有知道参数的小伙伴 , 可提交 PR + +**接口地址 :** `/banner` + +**调用例子 :** `/banner` + +### 获取歌曲详情 + +说明 : 调用此接口 , 传入音乐 id, 可获得歌曲详情(注意:歌曲封面现在需要通过专辑内容接口获取) + +**必选参数 :** `ids`: 音乐 id, 如 `ids=347230` + +**接口地址 :** `/song/detail` + +**调用例子 :** `/song/detail?ids=347230` + +返回数据如下图 : +![获取歌曲详情](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/songDetail.png) + +### 获取专辑内容 + +说明 : 调用此接口 , 传入专辑 id, 可获得专辑内容 + +**必选参数 :** `id`: 专辑 id + +**接口地址 :** `/album` + +**调用例子 :** `/album?id=32311` + +返回数据如下图 : +![获取专辑内容](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E4%B8%93%E8%BE%91.png) + +### 获取歌手单曲 + +说明 : 调用此接口 , 传入歌手 id, 可获得歌手部分信息和热门歌曲 + +**必选参数 :** `id`: 歌手 id, 可由搜索接口获得 + +**接口地址 :** `/artists` + +**调用例子 :** `/artists?id=6452` + +返回数据如下图 : +![获取歌手单曲](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/artists.png) + +### 获取歌手 mv + +说明 : 调用此接口 , 传入歌手 id, 可获得歌手 mv 信息 , 具体 mv 播放地址可调 +用`/mv`传入此接口获得的 mvid 来拿到 , 如 : +`/artist/mv?id=6452`,`/mv?mvid=5461064` + +**必选参数 :** `id`: 歌手 id, 可由搜索接口获得 + +**接口地址 :** `/artist/mv` + +**调用例子 :** `/artist/mv?id=6452` + +### 获取歌手专辑 + +说明 : 调用此接口 , 传入歌手 id, 可获得歌手专辑内容 + +**必选参数 :** `id`: 歌手 id + +**可选参数 :** `limit`: 取出数量 , 默认为 50 + +`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*50, 其中 50 为 limit 的值 , 默认 +为 0 + +**接口地址 :** `/artist/album` + +**调用例子 :** `/artist/album?id=6452&limit=30` ( 周杰伦 ) + +返回数据如下图 : +![获取专辑内容](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/artist_album.png) + +### 获取歌手描述 + +说明 : 调用此接口 , 传入歌手 id, 可获得歌手描述 + +**必选参数 :** `id`: 歌手 id + +**接口地址 :** `/artist/desc` + +**调用例子 :** `/artist/desc?id=6452` ( 周杰伦 ) + +### 获取相似歌手 + +说明 : 调用此接口 , 传入歌手 id, 可获得相似歌手 + +**必选参数 :** `id`: 歌手 id + +**接口地址 :** `/simi/artist` + +**调用例子 :** `/simi/artist?id=6452` ( 对应和周杰伦相似歌手 ) + +### 获取相似歌单 + +说明 : 调用此接口 , 传入歌曲 id, 可获得相似歌单 + +**必选参数 :** `id`: 歌曲 id + +**接口地址 :** `/simi/playlist` + +**调用例子 :** `/simi/playlist?id=347230` ( 对应 ' 光辉岁月 ' 相似歌单 ) + +### 相似 mv + +说明 : 调用此接口 , 传入 `mvid` 可获取相似 mv + +**必选参数 :** `mvid`: mv id + +**接口地址 :** `/simi/mv` + +**调用例子 :** `/simi/mv?mvid=5436712` + +### 获取相似音乐 + +说明 : 调用此接口 , 传入歌曲 id, 可获得相似歌曲 + +**必选参数 :** `id`: 歌曲 id + +**接口地址 :** `/simi/song` + +**调用例子 :** `/simi/song?id=347230` ( 对应 ' 光辉岁月 ' 相似歌曲 ) + +### 获取最近 5 个听了这首歌的用户 + +说明 : 调用此接口 , 传入歌曲 id, 最近 5 个听了这首歌的用户 + +**必选参数 :** `id`: 歌曲 id + +**接口地址 :** `/simi/user` + +**调用例子 :** `/simi/user?id=347230` ( 对应 ' 光辉岁月 ' 相似歌曲 ) + +### 获取每日推荐歌单 + +说明 : 调用此接口 , 可获得每日推荐歌单 ( 需要登录 ) + +**接口地址 :** `/recommend/resource` + +**调用例子 :** `/recommend/resource` + +返回数据如下图 : +![每日推荐歌单](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E6%8E%A8%E8%8D%90%E6%AD%8C%E5%8D%95.png) + +### 获取每日推荐歌曲 + +说明 : 调用此接口 , 可获得每日推荐歌曲 ( 需要登录 ) + +**接口地址 :** `/recommend/songs` + +**调用例子 :** `/recommend/songs` + +返回数据如下图 : +![每日推荐歌曲](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/%E6%8E%A8%E8%8D%90%E6%AD%8C%E6%9B%B2.png) + +### 私人 FM + +说明 : 私人 FM( 需要登录 ) + +**接口地址 :** `/personal_fm` + +**调用例子 :** `/personal_fm` + +返回数据如下图 : + +![私人 FM](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/personal_fm.png) + +### 签到 + +说明 : 调用此接口 , 传入签到类型 ( 可不传 , 默认安卓端签到 ), 可签到 ( 需要登录 +), 其中安卓端签到可获得 3 点经验 , web/PC 端签到可获得 2 点经验 + +**可选参数 :** `type`: 签到类型 , 默认 0, 其中 0 为安卓端签到 ,1 为 web/PC 签到 + +**接口地址 :** `/daily_signin` + +**调用例子 :** `/daily_signin` + +返回数据如下图 : + +![签到成功](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/signinSuccess.png) + +![签到失败](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/signinError.png) + +### 喜欢音乐 + +说明 : 调用此接口 , 传入音乐 id, 可喜欢该音乐 + +**必选参数 :** `id`: 歌曲 id + +**可选参数 :** `like`: 布尔值 , 默认为 true 即喜欢 , 若传 false, 则取消喜欢 + +**接口地址 :** `/like` + +**调用例子 :** `/like?id=347230` + +返回数据如下图 : + +![喜欢成功](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/like.png) + +喜欢成功则返回数据的 code 为 200, 其余为失败 + +![喜欢成功截图](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/likeSuccess.png) + +### 垃圾桶 + +说明 : 调用此接口 , 传入音乐 id, 可把该音乐从私人 FM 中移除至垃圾桶 + +**必选参数 :** `id`: 歌曲 id + +**接口地址 :** `/fm_trash` + +**调用例子 :** `/fm_trash?id=347230` + +返回数据如下图 : + +![移除成功](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/fm_trash.png) + +### 新碟上架 + +说明 : 调用此接口 , 可获取新碟上架列表 , 如需具体音乐信息需要调用获取专辑列表接 +口 `/album` , 然后传入 id, 如 `/album?id=32311&limit=30` + +**可选参数 :** `limit`: 取出数量 , 默认为 50 + +`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*50, 其中 50 为 limit 的值 , 默认 +为 0 + +**接口地址 :** `/top/album` + +**调用例子 :** `/top/album?offset=0&limit=30` + +返回数据如下图 : + +![新碟上架](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/new_albums.png) + +### 热门歌手 + +说明 : 调用此接口 , 可获取热门歌手数据 + +**可选参数 :** `limit`: 取出数量 , 默认为 50 + +`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*50, 其中 50 为 limit 的值 , 默认 +为 0 + +**接口地址 :** `/top/artists` + +**调用例子 :** `/top/artists?offset=0&limit=30` + +返回数据如下图 : + +![热门歌手](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/top_artists.png) + +### 最新 mv + +说明 : 调用此接口 , 可获取最新 mv + +**可选参数 :** `limit`: 取出数量 , 默认为 30 + +**接口地址 :** `/mv/first` + +**调用例子 :** `/mv/first?limit=10` + +### 推荐 mv + +说明 : 调用此接口 , 可获取推荐 mv + +**接口地址 :** `/personalized/mv` + +**调用例子 :** `/personalized/mv` + +### 推荐歌单 + +说明 : 调用此接口 , 可获取推荐歌单 + +**接口地址 :** `/personalized` + +**调用例子 :** `/personalized` + +### 推荐新音乐 + +说明 : 调用此接口 , 可获取推荐新音乐 + +**接口地址 :** `/personalized/newsong` + +**调用例子 :** `/personalized/newsong` + +### 推荐电台 + +说明 : 调用此接口 , 可获取推荐电台 + +**接口地址 :** `/personalized/djprogram` + +**调用例子 :** `/personalized/djprogram` + +### 推荐节目 + +说明 : 调用此接口 , 可获取推荐电台 + +**接口地址 :** `/program/recommend` + +**调用例子 :** `/program/recommend` + +### 独家放送 + +说明 : 调用此接口 , 可获取独家放送 + +**接口地址 :** `/personalized/privatecontent` + +**调用例子 :** `/personalized/privatecontent` + +### mv 排行 + +说明 : 调用此接口 , 可获取 mv 排行 + +**可选参数 :** `limit`: 取出数量 , 默认为 30 + +`offset`: 偏移数量 , 用于分页 , 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认 +为 0 + +**接口地址 :** `top/mv` + +**调用例子 :** `top/mv?limit=10` + +### 获取 mv 数据 + +说明 : 调用此接口 , 传入 mvid ( 在搜索音乐的时候传 type=1004 获得 ) , 可获取对应 +MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等数据 , 其中 mv 视频 +网易做了防盗链处理 , 可能不能直接播放 , 需要播放的话需要调用 ' 播放 mv/视频' 接口 + +**必选参数 :** `mvid`: mv 的 id + +**接口地址 :** `/mv` + +**调用例子 :** `/mv?mvid=5436712` + +返回数据如下图 : + +![热门歌手](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/mv.png) + +### 获取视频数据 + +说明 : 调用此接口 , 传入视频的 id ( 在搜索音乐的时候传 type=1014 获得 ) , 可获取对应 +视频数据,其中视频网易做了防盗链处理 , 可能不能直接播放 , 需要播放的话需要调用 ' 播放 mv/视频' 接口 + +**必选参数 :** `id`: 视频 的 id + +**接口地址 :** `/video` + +**调用例子 :** `/video?id=89ADDE33C0AAE8EC14B99F6750DB954D` + +返回数据如下图 : + +![视频数据](https://ws1.sinaimg.cn/large/006tNbRwgy1fuqdv10p5rj31kw0da76y.jpg) + +### 播放 mv/视频 + +说明 : 调用此接口 , 传入 mv/视频 地址 , 可播放 mv/视频, 也可将接口嵌入 video 标签使用 , 由 +于使用了 'pipe', 进度条无法通过拖动进度条控制进度 , 如有解决方案可提出 PR 或者自 +行改造 + +**可选参数 :** `url`: mv/视频 的 地址 + +**接口地址 :** `/mv/url` + +**调用例子 :** +`/mv/url?url=http://v4.music.126.net/20170422034915/c98eab2f5e2c85fc8de2ab3f0f8ed1c6/web/cloudmusic/MjQ3NDQ3MjUw/89a6a279dc2acfcd068b45ce72b1f560/533e4183a709699d566180ed0cd9abe9.mp4` + +如下图 : + +![播放视频](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/play_mv.png) + +### 排行榜 + +说明 : 调用此接口 , 传入数字 idx, 可获取不同排行榜 + +**必选参数 :** `idx`: 对象 key, 对应以下排行榜 + +``` +"0": 云音乐新歌榜, +"1": 云音乐热歌榜, +"2": 网易原创歌曲榜, +"3": 云音乐飙升榜, +"4": 云音乐电音榜, +"5": UK排行榜周榜, +"6": 美国Billboard周榜 +"7": KTV嗨榜, +"8": iTunes榜, +"9": Hit FM Top榜, +"10": 日本Oricon周榜 +"11": 韩国Melon排行榜周榜, +"12": 韩国Mnet排行榜周榜, +"13": 韩国Melon原声周榜, +"14": 中国TOP排行榜(港台榜), +"15": 中国TOP排行榜(内地榜) +"16": 香港电台中文歌曲龙虎榜, +"17": 华语金曲榜, +"18": 中国嘻哈榜, +"19": 法国 NRJ EuroHot 30周榜, +"20": 台湾Hito排行榜, +"21": Beatport全球电子舞曲榜, +"22": 云音乐ACG音乐榜, +"23": 云音乐嘻哈榜 +``` + +**接口地址 :** `/top/list` + +**调用例子 :** `/top/list?idx=6` + +返回数据如下图 : + +![排行榜](https://raw.githubusercontent.com/Binaryify/NeteaseCloudMusicApi/master/static/top_list.png) + +### 歌手榜 + +说明 : 调用此接口 , 可获取 PC 版排行榜中的歌手榜 + +**接口地址 :** `/toplist/artist` + +**调用例子 :** `/toplist/artist` + +### 云盘 + +说明 : 登录后调用此接口 , 可获取云盘数据 , 获取的数据没有对应 url, 需要再调用一 +次 `/music/url` 获取 url + +**接口地址 :** `/user/cloud` + +**调用例子 :** `/user/cloud` + +### 电台 - 推荐 + +说明 : 登录后调用此接口 , 可获得推荐电台 + +**接口地址 :** `/dj/recommend` + +**调用例子 :** `/dj/recommend` + +### 电台 - 分类 + +说明 : 登录后调用此接口 , 可获得电台类型 + +**接口地址 :** `/dj/catelist` + +**调用例子 :** `/dj/catelist` + +### 电台 - 分类推荐 + +说明 : 登录后调用此接口 , 可获得推荐电台 + +**必选参数 :** `type`: 电台类型 , 数字 , 可通过`/dj/catelist`获取 , 对应关系为 +id 对应 此接口的 type, name 对应类型意义 + +**接口地址 :** `/dj/recommend/type` + +**调用例子 :** `/dj/recommend/type?type=1` + +### 电台 - 订阅 + +说明 : 登录后调用此接口 , 传入`rid`, 可订阅 dj,dj 的 `rid` 可通过搜索指定 +type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009` + +**必选参数 :** `rid`: 电台 的 id + +**接口地址 :** `/dj/sub` + +**调用例子 :** `/dj/sub?rid=336355127&t=1` ( 对应关注 ' 代码时间 ') +`/dj/sub?rid=336355127&t=0` ( 对应取消关注 ' 代码时间 ') + +### 电台的订阅列表 + +说明 : 登录后调用此接口 , 可获取订阅的电台列表 + +**接口地址 :** `/dj/sublist` + +**调用例子 :** `/dj/sublist` + +### 电台 - 付费精选 + +说明 : 可以获取付费精选的电台列表 , 传入 `limit` 和 `offset` 可以进行分页 + +**接口地址 :** `/dj/paygift` + +**调用例子 :** `/dj/paygift?limit=10&offset=20` + +### 电台 - 详情 + +说明 : 登录后调用此接口 , 传入`rid`, 可获得对应电台的详情介绍 + +**必选参数 :** `rid`: 电台 的 id + +**接口地址 :** `/dj/detail?rid=336355127` + +**调用例子 :** `/dj/detail?rid=336355127` ( 对应 ' 代码时间 ' 的详情介绍 ) + +### 电台 - 节目 + +说明 : 登录后调用此接口 , 传入`rid`, 可查看对应电台的电台节目以及对应的 id, 需要 +注意的是这个接口返回的 mp3Url 已经无效 , 都为 null, 但是通过调用 `/music/url` 这 +个接口 , 传入节目 id 仍然能获取到节目音频 , 如 `/music/url?id=478446370` 获取代 +码时间的一个节目的音频 + +**必选参数 :** `rid`: 电台 的 id + +**可选参数 :** +`limit` : 返回数量 , 默认为 30 + +`offset` : 偏移数量,用于分页 , 如 +: 如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0 + +**接口地址 :** `/dj/program` + +**调用例子 :** `/dj/program?rid=336355127&limit=40` ( 对应 ' 代码时间 ' 的节目列表 ) + +## 离线访问此文档 + +此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问 + +## 关于此文档 + +此文档由 [docsify](https://github.com/QingWei-Li/docsify/) 生成 docsify 是一个动 +态生成文档网站的工具。不同于 GitBook、Hexo 的地方是它不会生成将 .md 转成 .html +文件,所有转换工作都是在运行时进行。 + +## License + +[The MIT License (MIT)](https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/LICENSE) diff --git a/WebSourceCode/src/Netease/examples/get_static_moddef.js b/WebSourceCode/src/Netease/examples/get_static_moddef.js new file mode 100644 index 0000000..f430aed --- /dev/null +++ b/WebSourceCode/src/Netease/examples/get_static_moddef.js @@ -0,0 +1,22 @@ +const fsPromises = require('fs/promises') +const path = require('path') +const server = require('../server') + +const exportFile = path.join(__dirname, 'moddef.json') + +async function main() { + const def = await server.getModulesDefinitions( + path.join(__dirname, '..', 'module'), + { + 'daily_signin.js': '/daily_signin', + 'fm_trash.js': '/fm_trash', + 'personal_fm.js': '/personal_fm', + }, + false, + ) + + fsPromises.writeFile(exportFile, JSON.stringify(def, null, 4)) + console.log(`👍 Get your own definition at: ${exportFile}`) +} + +main() diff --git a/WebSourceCode/src/Netease/generateConfig.js b/WebSourceCode/src/Netease/generateConfig.js new file mode 100644 index 0000000..4e149d7 --- /dev/null +++ b/WebSourceCode/src/Netease/generateConfig.js @@ -0,0 +1,23 @@ +const fs = require('fs') +const path = require('path') +const { register_anonimous } = require('./main') +const { cookieToJson } = require('./util/index') + +const tmpPath = require('os').tmpdir() +async function generateConfig() { + try { + const res = await register_anonimous() + const cookie = res.body.cookie + if (cookie) { + const cookieObj = cookieToJson(cookie) + fs.writeFileSync( + path.resolve(tmpPath, 'anonymous_token'), + cookieObj.MUSIC_A, + 'utf-8', + ) + } + } catch (error) { + console.log(error) + } +} +module.exports = generateConfig diff --git a/WebSourceCode/src/Netease/index.js b/WebSourceCode/src/Netease/index.js new file mode 100644 index 0000000..39d0ba3 --- /dev/null +++ b/WebSourceCode/src/Netease/index.js @@ -0,0 +1 @@ +require('./app.js') diff --git a/WebSourceCode/src/Netease/interface.d.ts b/WebSourceCode/src/Netease/interface.d.ts new file mode 100644 index 0000000..c3f50b4 --- /dev/null +++ b/WebSourceCode/src/Netease/interface.d.ts @@ -0,0 +1,1797 @@ +export interface RequestBaseConfig { + cookie?: string + realIP?: string // IPv4/IPv6 filled in X-Real-IP + proxy?: string // HTTP proxy +} + +export interface MultiPageConfig { + limit?: string | number + offset?: string | number +} + +export interface ImageUploadConfig { + imgFile: { + name: string + data: string | Buffer + } + imgSize?: number + imgX?: number + imgY?: number +} + +export interface APIBaseResponse { + code: number + cookie: string + [index: string]: unknown +} + +export interface Response { + status: number // The Http Response Code + body: Body // API Response body + cookie: string[] +} + +export const enum SubAction { + sub = 1, + unsub = 0, +} + +export function activate_init_profile( + params: { nickname: string } & RequestBaseConfig, +): Promise + +export function album( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export function album_detail( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export function album_detail_dynamic( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export const enum AlbumListArea { + all = 'ALL', + zh = 'ZH', + ea = 'EA', + kr = 'KR', + jp = 'JP', +} + +export const enum ListOrder { + hot = 'hot', + new = 'new', +} + +export function album_list( + params: { area?: AlbumListArea; type: string } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export const enum AlbumListStyleArea { + zh = 'Z_H', + ea = 'E_A', + kr = 'KR', + jp = 'JP', +} + +export function album_list_style( + params: { area?: AlbumListStyleArea } & MultiPageConfig & RequestBaseConfig, +): Promise + +export function album_new( + params: { area?: AlbumListArea } & MultiPageConfig & RequestBaseConfig, +): Promise + +export function album_newest(params: RequestBaseConfig): Promise + +export const enum AlbumSongsaleboardType { + daily = 'daily', + week = 'week', + year = 'year', + total = 'total', +} + +export const enum AlbumSongsaleboardAlbumType { + album = 0, + single = 1, +} + +export function album_songsaleboard( + params: { + albumType?: AlbumSongsaleboardAlbumType // 0 为数字专辑,1 为数字单曲 + type?: AlbumSongsaleboardType + year?: string | number // 年份,默认本年。 type 为 year 时有效 + } & RequestBaseConfig, +): Promise + +export function album_sub( + params: { + id: string | number + t: SubAction + } & RequestBaseConfig, +): Promise + +export function album_sublist( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function artist_album( + params: { id: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise + +export function artist_desc( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export const enum ArtistListArea { + zh = 'Z_H', + ea = 'E_A', + kr = 'KR', + jp = 'JP', +} + +export const enum ArtistArea { + all = '-1', + zh = '7', + ea = '96', + ja = '8', + kr = '16', + other = '0', +} + +export const enum ArtistType { + male = '1', + female = '2', + band = '3', +} + +export function artist_list( + params: { + area: ArtistArea + initial?: + | 'a' + | 'b' + | 'c' + | 'd' + | 'e' + | 'f' + | 'g' + | 'h' + | 'i' + | 'j' + | 'k' + | 'l' + | 'm' + | 'n' + | 'o' + | 'p' + | 'q' + | 'r' + | 's' + | 't' + | 'u' + | 'v' + | 'w' + | 'x' + | 'y' + | 'z' + | 'A' + | 'B' + | 'C' + | 'D' + | 'E' + | 'F' + | 'G' + | 'H' + | 'I' + | 'J' + | 'K' + | 'L' + | 'M' + | 'N' + | 'O' + | 'P' + | 'Q' + | 'R' + | 'S' + | 'T' + | 'U' + | 'V' + | 'W' + | 'X' + | 'Y' + | 'Z' + type?: ArtistType + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function artist_mv( + params: { id: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise + +export const enum ArtistSongsOrder { + hot = 'hot', + time = 'time', +} + +export function artist_songs( + params: { + id: string | number + order?: ArtistSongsOrder + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function artist_sub( + params: { id: string | number; t: SubAction } & RequestBaseConfig, +): Promise + +export function artist_sublist( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function artist_top_song( + params: { + id: string | number + } & RequestBaseConfig, +): Promise + +export function artists( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export function audio_match( + params: { + duration: string | number + audioFP: string | number + } & RequestBaseConfig, +): Promise + +export function avatar_upload( + params: ImageUploadConfig & RequestBaseConfig, +): Promise + +export const enum BannerType { + pc = 0, + android = 1, + iphone = 2, + ipad = 3, +} + +export function banner( + params: { type?: BannerType } & RequestBaseConfig, +): Promise + +export function batch( + params: { [index: string]: unknown } & RequestBaseConfig, +): Promise + +export function captcha_sent( + params: { cellphone: string; ctcode?: number | string } & RequestBaseConfig, +): Promise + +export function captcha_verify( + params: { + ctcode?: number | string + cellphone: number | string + captcha: string + } & RequestBaseConfig, +): Promise + +export function cellphone_existence_check( + params: { + cellphone: number | string + countrycode: number | string + } & RequestBaseConfig, +): Promise + +export function check_music( + params: { id: string | number; br: string | number } & RequestBaseConfig, +): Promise + +export const enum SearchType { + single = 1, + album = 10, + artist = 100, + playlist = 1000, + user = 1002, + mv = 1004, + lyric = 1006, + dj = 1009, + video = 1014, + complex = 1018, +} + +export function cloudsearch( + params: { + keywords: string + type?: SearchType + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export const enum CommentType { + song = 0, + mv = 1, + playlist = 2, + album = 3, + dj = 4, + video = 5, + event = 6, +} + +export const enum CommentAction { + add = 1, + delete = 0, + reply = 2, +} + +export function comment( + params: { + id: string | number + type: CommentType + t: CommentAction.delete + commentId: string | number + } & RequestBaseConfig, +): Promise + +export function comment( + params: { + type: CommentType.event + t: CommentAction.delete + threadId: string + commentId: string | number + } & RequestBaseConfig, +): Promise + +export function comment( + params: { + id: string | number + type: CommentType + t: CommentAction.add + content: string | number + } & RequestBaseConfig, +): Promise + +export function comment( + params: { + type: CommentType.event + t: CommentAction.add + threadId: string + content: string | number + } & RequestBaseConfig, +): Promise + +export function comment( + params: { + id: string | number + type: CommentType + t: CommentAction.reply + content: string | number + commentId: string | number + } & RequestBaseConfig, +): Promise + +export function comment( + params: { + type: CommentType.event + t: CommentAction.reply + threadId: string + content: string | number + commentId: string | number + } & RequestBaseConfig, +): Promise + +export function comment_album( + params: { + id: string | number + before?: string | number + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function comment_dj( + params: { + id: string | number + before?: string | number + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function comment_event( + params: { + threadId: string + before?: string | number + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function comment_floor( + params: { + id: string | number + parentCommentId: string | number + type: CommentType + limit?: string | number + time?: string | number + } & RequestBaseConfig, +): Promise + +export function comment_hot( + params: { + id: string | number + type: CommentType + before?: string | number + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function comment_hotwall_list( + params: RequestBaseConfig, +): Promise + +export function comment_like( + params: { + id: string | number + type: CommentType + t: SubAction + cid: string | number + threadId?: string + } & RequestBaseConfig, +): Promise + +export function comment_music( + params: { + id: string | number + before?: string | number + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function comment_mv( + params: { + id: string | number + before?: string | number + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function comment_playlist( + params: { + id: string | number + + before?: string | number + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function comment_video( + params: { + id: string | number + before?: string | number + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function countries_code_list( + params: RequestBaseConfig, +): Promise + +export const enum DailySigninType { + android = 0, + pc = 1, +} + +export function daily_signin( + params: { type?: DailySigninType } & RequestBaseConfig, +): Promise + +export function digitalAlbum_ordering( + params: { + payment: string + id: string | number + quantity: string + } & RequestBaseConfig, +): Promise + +export function digitalAlbum_purchased( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function dj_banner(params: RequestBaseConfig): Promise + +export function dj_category_excludehot( + params: RequestBaseConfig, +): Promise + +export function dj_category_recommend( + params: RequestBaseConfig, +): Promise + +export function dj_catelist(params: RequestBaseConfig): Promise + +export function dj_detail( + params: { rid: string | number } & RequestBaseConfig, +): Promise + +export function dj_hot( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function dj_paygift( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function dj_personalize_recommend( + params: { limit?: string | number } & RequestBaseConfig, +): Promise + +export function dj_program( + params: { + rid: string | number + asc: 'true' | 1 | 'false' | 0 + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function dj_program_detail( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export function dj_program_toplist( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function dj_program_toplist_hours( + params: { limit?: string | number } & RequestBaseConfig, +): Promise + +export function dj_radio_hot( + params: { + cateId: string | number + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function dj_recommend(params: RequestBaseConfig): Promise + +/* + 有声书 10001 + 知识技能 453050 + 商业财经 453051 + 人文历史 11 + 外语世界 13 + 亲子宝贝 14 + 创作|翻唱 2001 + 音乐故事 2 + 3D|电子 10002 + 相声曲艺 8 + 情感调频 3 + 美文读物 6 + 脱口秀 5 + 广播剧 7 + 二次元 3001 + 明星做主播 1 + 娱乐|影视 4 + 科技科学 453052 + 校园|教育 4001 + 旅途|城市 12 +*/ + +export function dj_recommend_type( + params: { type: number } & RequestBaseConfig, +): Promise + +export function dj_sub( + params: { t: SubAction; rid: string | number } & RequestBaseConfig, +): Promise + +export function dj_sublist( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function dj_today_perfered( + params: { page?: string | number } & RequestBaseConfig, +): Promise + +export function dj_toplist( + params: { type?: ListOrder } & MultiPageConfig & RequestBaseConfig, +): Promise + +export function dj_toplist_hours( + params: { limit?: string | number } & RequestBaseConfig, +): Promise + +export function dj_toplist_newcomer( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function dj_toplist_pay( + params: { limit?: string | number } & RequestBaseConfig, +): Promise + +export function dj_toplist_popular( + params: { limit?: string | number } & RequestBaseConfig, +): Promise + +export function event( + params: { pagesize?: number; lasttime?: number } & RequestBaseConfig, +): Promise + +export function event_del( + params: { evId: string | number } & RequestBaseConfig, +): Promise + +export function event_forward( + params: { + forwords: string + evId: string | number + uid: string | number + } & RequestBaseConfig, +): Promise + +export function fm_trash( + params: { id: string | number; time?: string | number } & RequestBaseConfig, +): Promise + +export function follow( + params: { t: SubAction; id: string | number } & RequestBaseConfig, +): Promise + +export function history_recommend_songs( + params: RequestBaseConfig, +): Promise + +export function history_recommend_songs_detail( + params: { date?: string } & RequestBaseConfig, +): Promise + +export function homepage_block_page( + params: { + refresh?: 'true' | 'false' | boolean + cursor?: string + } & RequestBaseConfig, +): Promise + +export function homepage_dragon_ball( + params: RequestBaseConfig, +): Promise + +export function hot_topic( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function like( + params: { + like?: 'true' | 'false' | boolean + id: string | number + alg?: string + time?: string | number + } & RequestBaseConfig, +): Promise + +export function likelist( + params: { uid: string | number } & RequestBaseConfig, +): Promise + +export function login( + params: { email: string; password: string } & RequestBaseConfig, +): Promise + +export function login( + params: { email: string; md5_password: string } & RequestBaseConfig, +): Promise + +export function login_cellphone( + params: { + phone: number | string + countrycode?: number | string + password: string + } & RequestBaseConfig, +): Promise + +export function login_cellphone( + params: { + phone: number | string + countrycode?: number | string + md5_password: string + } & RequestBaseConfig, +): Promise + +export function login_cellphone( + params: { + phone: number | string + countrycode?: number | string + captcha: number | string + } & RequestBaseConfig, +): Promise + +export function login_refresh(params: RequestBaseConfig): Promise + +export function login_status(params: RequestBaseConfig): Promise + +export function logout(params: RequestBaseConfig): Promise + +export function lyric( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export function lyric_new( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export function msg_comments( + params: { + uid: string | number + before?: string | number + limit?: string | number + } & RequestBaseConfig, +): Promise + +export function msg_forwards( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function msg_notices( + params: { + limit?: string | number + lasttime?: string | number + } & RequestBaseConfig, +): Promise + +export function msg_private( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function msg_private_history( + params: { + before?: string | number + limit?: string | number + uid: string | number + } & RequestBaseConfig, +): Promise + +export const enum MvArea { + all = '全部', + zh = '内地', + hk = '港台', + ea = '欧美', + kr = '韩国', + jp = '日本', +} + +export const enum MvType { + all = '全部', + offical = '官方版', + raw = '原生', + live = '现场版', + netease = '网易出品', +} + +export const enum MvOrder { + trend = '上升最快', + hot = '最热', + new = '最新', +} + +export function mv_all( + params: { + area?: MvArea + type?: MvType + order?: MvOrder + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function mv_detail( + params: { mvid?: string | number } & RequestBaseConfig, +): Promise + +export function mv_detail_info( + params: { mvid: string | number } & RequestBaseConfig, +): Promise + +export function mv_exclusive_rcmd( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function mv_first( + params: { area?: MvArea; limit?: string | number } & RequestBaseConfig, +): Promise + +export function mv_sub( + params: { t: SubAction; mvid: string | number } & RequestBaseConfig, +): Promise + +export function mv_sublist( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function mv_url( + params: { id?: string | number; r?: string | number } & RequestBaseConfig, +): Promise + +export function personal_fm(params: RequestBaseConfig): Promise + +export function personalized( + params: { limit?: string | number } & RequestBaseConfig, +): Promise + +export function personalized_djprogram( + params: RequestBaseConfig, +): Promise + +export function personalized_mv(params: RequestBaseConfig): Promise + +export function personalized_newsong( + params: { + area?: string | number + limit?: string | number + } & RequestBaseConfig, +): Promise + +export function personalized_privatecontent( + params: RequestBaseConfig, +): Promise + +export function personalized_privatecontent_list( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function playlist_catlist(params: RequestBaseConfig): Promise + +export function playlist_cover_update( + params: { id: string } & ImageUploadConfig & RequestBaseConfig, +): Promise + +export function playlist_create( + params: { + name: string + privacy: 0 | 10 + type?: PlaylistType + } & RequestBaseConfig, +): Promise + +export function playlist_delete( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export function playlist_desc_update( + params: { id: string | number; desc: string } & RequestBaseConfig, +): Promise + +export function playlist_detail( + params: { id: string | number; s?: string | number } & RequestBaseConfig, +): Promise + +export function playlist_highquality_tags( + params: RequestBaseConfig, +): Promise + +export function playlist_hot(params: RequestBaseConfig): Promise + +export function playlist_name_update( + params: { id: string | number; name: string } & RequestBaseConfig, +): Promise + +export function playlist_order_update( + params: { ids: string } & RequestBaseConfig, +): Promise + +export function playlist_subscribe( + params: { t: SubAction; id: string | number } & RequestBaseConfig, +): Promise + +export function playlist_subscribers( + params: { id?: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise + +export function playlist_tags_update( + params: { id: string | number; tags: string } & RequestBaseConfig, +): Promise + +export function playlist_tracks( + params: { + op: 'add' | 'del' + pid: string | number + tracks: string + } & RequestBaseConfig, +): Promise + +export function playlist_update( + params: { + id: string | number + name: string + desc?: string + tags?: string + } & RequestBaseConfig, +): Promise + +export function playmode_intelligence_list( + params: { + id: string | number + pid: string | number + sid?: string | number + count?: string | number + } & RequestBaseConfig, +): Promise + +export function program_recommend( + params: { type: string } & MultiPageConfig & RequestBaseConfig, +): Promise + +export function rebind( + params: { + captcha: string + phone: string + oldcaptcha: string + ctcode?: number | string + } & RequestBaseConfig, +): Promise + +export function recommend_resource(params: RequestBaseConfig): Promise + +export function recommend_songs(params: RequestBaseConfig): Promise + +export function register_cellphone( + params: { + captcha: string + phone: string + password: string + nickname: string + } & RequestBaseConfig, +): Promise + +export function related_allvideo( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export function related_playlist( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export const enum ResourceType { + mv = 1, + dj = 4, + video = 5, + event = 6, +} +type PlaylistType = 'NROMAL' | 'VIDEO' + +export function resource_like( + params: { + t: SubAction + type: ResourceType + id?: string | number + threadId?: string + } & RequestBaseConfig, +): Promise + +export function scrobble( + params: { + id: string | number + sourceid: string | number + time: string | number + } & RequestBaseConfig, +): Promise + +export function search( + params: { + keywords: string + type?: SearchType + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function search_default(params: RequestBaseConfig): Promise + +export function search_hot(params: RequestBaseConfig): Promise + +export function search_hot_detail(params: RequestBaseConfig): Promise + +export function search_multimatch( + params: { type?: number; keywords: string } & RequestBaseConfig, +): Promise + +export const enum SearchSuggestType { + mobile = 'mobile', + web = 'web', +} + +export function search_suggest( + params: { keywords: string; type?: SearchSuggestType } & RequestBaseConfig, +): Promise + +export function send_playlist( + params: { + playlist: string | number + msg: string + user_ids: string + } & RequestBaseConfig, +): Promise + +export function send_text( + params: { msg: string; user_ids: string } & RequestBaseConfig, +): Promise + +export function setting(params: RequestBaseConfig): Promise + +export const enum ShareResourceType { + song = 'song', + playlist = 'playlist', + mv = 'mv', + djprogram = 'djprogram', + djradio = 'djradio', +} + +export function share_resource( + params: { + type?: ShareResourceType + msg?: string + id?: string | number + } & RequestBaseConfig, +): Promise + +export function simi_artist( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export function simi_mv( + params: { mvid: string | number } & RequestBaseConfig, +): Promise + +export function simi_playlist( + params: { id: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise + +export function simi_song( + params: { id: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise + +export function simi_user( + params: { id: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise + +export function song_detail( + params: { ids: string } & RequestBaseConfig, +): Promise< + Response<{ + songs: SongDetail[] + privileges: unknown[] + code: number + }> +> + +type SongDetail = { + name: string + id: number + pst: number + t: number + ar: SongDetailArtist[] + alia: string[] + pop: number + st: number + rt: string | null + fee: SongDetailFee + v: number + crbt: string | null + cf: string + al: SongDetailAlbum + dt: number + h: SongDetailQuality | null + m: SongDetailQuality | null + l: SongDetailQuality | null + sq: SongDetailQuality | null + hr: unknown + a: unknown | null + cd: string + no: number + rtUrl: unknown | null + ftype: number + rtUrls: unknown[] + djId: number + copyright: SongDetailCopyright + s_id: number + mark: number + originCoverType: SongDetailOriginCoverType + originSongSimpleData: unknown | null + tagPicList: unknown | null + resourceState: boolean + version: number + songJumpInfo: unknown | null + entertainmentTags: unknown | null + awardTags: unknown | null + single: number + noCopyrightRcmd: unknown | null + mv: number + rtype: number + rurl: unknown | null + mst: number + cp: number + publishTime: number +} + +type SongDetailArtist = { + id: number + name: string + tns: unknown[] + alias: unknown[] +} + +type SongDetailFee = 0 | 1 | 4 | 8 + +type SongDetailAlbum = { + id: number + name: string + picUrl: string + tns: unknown[] + pic: number +} + +type SongDetailQuality = { + br: number + fid: number + size: number + vd: number + sr: number +} + +type SongDetailCopyright = 0 | 1 | 2 + +type SongDetailOriginCoverType = 0 | 1 | 2 + +export function song_order_update( + params: { pid: string | number; ids: string } & RequestBaseConfig, +): Promise + +export function song_url( + params: { id: string | number; br?: string | number } & RequestBaseConfig, +): Promise + +export const enum SoundQualityType { + standard = 'standard', + exhigh = 'exhigh', + lossless = 'lossless', + hires = 'hires', +} + +export function song_url_v1( + params: { id: string | number; level: SoundQualityType } & RequestBaseConfig, +): Promise + +export function top_album( + params: { + area?: AlbumListArea + type?: ListOrder + year?: string + mouth?: string + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function top_artists( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function top_list( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export function top_mv( + params: { area?: MvArea } & MultiPageConfig & RequestBaseConfig, +): Promise + +export function top_playlist( + params: { cat?: string; order?: ListOrder } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function top_playlist_highquality( + params: { + cat?: string + before?: string | number + limit?: string | number + } & RequestBaseConfig, +): Promise + +export const enum TopSongType { + all = 0, + zh = 7, + ea = 96, + kr = 16, + ja = 8, +} + +export function top_song( + params: { type: TopSongType } & RequestBaseConfig, +): Promise + +export function toplist(params: RequestBaseConfig): Promise + +export const enum ToplistArtistType { + zh = 1, + ea = 2, + kr = 3, + ja = 4, +} + +export function toplist_artist( + params: { type?: ToplistArtistType } & RequestBaseConfig, +): Promise + +export function toplist_detail(params: RequestBaseConfig): Promise + +export function user_audio( + params: { uid: string | number } & RequestBaseConfig, +): Promise + +export function user_cloud( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function user_cloud_del( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export function user_cloud_detail( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export function user_detail( + params: { uid: string | number } & RequestBaseConfig, +): Promise + +export function user_dj( + params: { uid: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise + +export function user_event( + params: { + lasttime?: string | number + limit?: string | number + uid: string | number + } & RequestBaseConfig, +): Promise + +export function user_followeds( + params: { + uid: string | number + lasttime?: string | number + limit?: string | number + } & RequestBaseConfig, +): Promise + +export function user_follows( + params: { uid: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise + +export function user_level(params: RequestBaseConfig): Promise + +export function user_playlist( + params: { uid: string | number } & MultiPageConfig & RequestBaseConfig, +): Promise + +export const enum UserRecordType { + all = 0, + weekly = 1, +} + +export function user_record( + params: { uid: string | number; type?: UserRecordType } & RequestBaseConfig, +): Promise + +export function user_subcount(params: RequestBaseConfig): Promise + +export function user_update( + params: { + birthday: string + city: string + gender: string + nickname: string + province: string + signature: string + } & RequestBaseConfig, +): Promise + +export function video_category_list( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function video_detail( + params: { id: string } & RequestBaseConfig, +): Promise + +export function video_detail_info( + params: { vid: string } & RequestBaseConfig, +): Promise + +export function video_group( + params: { id: string; offset?: string | number } & RequestBaseConfig, +): Promise + +export function video_group_list(params: RequestBaseConfig): Promise + +export function video_sub( + params: { t?: SubAction; id: string } & RequestBaseConfig, +): Promise + +export function video_timeline_all( + params: { offset?: string | number } & RequestBaseConfig, +): Promise + +export function video_timeline_recommend( + params: { offset?: string | number } & RequestBaseConfig, +): Promise + +export function video_url( + params: { id: string | number; res?: number } & RequestBaseConfig, +): Promise + +export function weblog( + params: { data?: { [index: string]: unknown } } & RequestBaseConfig, +): Promise + +export function playlist_mylike( + params: { + time?: number | string + limit: number | string + } & RequestBaseConfig, +): Promise + +export function playlist_track_add( + params: { pid?: number | string; ids: number | string } & RequestBaseConfig, +): Promise + +export function playlist_track_delete( + params: { pid?: number | string; ids: number | string } & RequestBaseConfig, +): Promise + +export function comment_new( + params: { + type?: number | string + id: number | string + pageNo?: number | string + pageSize?: number | string + sortType?: number | string + } & RequestBaseConfig, +): Promise + +export function calendar( + params: { + startTime?: number | string + endTime: number | string + } & RequestBaseConfig, +): Promise + +export function playlist_video_recent( + params: RequestBaseConfig, +): Promise + +export function user_binding( + params: { uid?: number | string } & RequestBaseConfig, +): Promise + +export function user_replacephone( + params: { + phone: number | string + captcha: number | string + oldcaptcha: number | string + countrycode?: number | string + } & RequestBaseConfig, +): Promise + +export function user_safe(params: RequestBaseConfig): Promise + +export function dj_subscriber( + params: { + id: number | string + limit?: number | string + time?: number | string + } & RequestBaseConfig, +): Promise + +export function user_account(params: RequestBaseConfig): Promise + +export function yunbei(params: RequestBaseConfig): Promise + +export function yunbei_info(params: RequestBaseConfig): Promise + +export function yunbei_sign(params: RequestBaseConfig): Promise + +export function yunbei_receipt( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function yunbei_expense( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function yunbei_tasks(params: RequestBaseConfig): Promise + +export function yunbei_today(params: RequestBaseConfig): Promise + +export function yunbei_tasks_todo(params: RequestBaseConfig): Promise + +export function yunbei_task_finish( + params: { + userTaskId: number | string + depositCode?: number | string + } & RequestBaseConfig, +): Promise + +export function msg_recentcontact(params: RequestBaseConfig): Promise + +export function hug_comment( + params: { + uid: number | string + cid: number | string + sid: number | string + } & RequestBaseConfig, +): Promise + +export function comment_hug_list( + params: { + page: number | string + cursor: number | string + idCursor: number | string + pageSize?: number | string + } & RequestBaseConfig, +): Promise + +export function topic_sublist( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function topic_sublist( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function artist_new_mv( + params: { + limit?: number | string + startTimestamp?: number | string + } & RequestBaseConfig, +): Promise + +export function artist_new_song( + params: { + limit?: number | string + startTimestamp?: number | string + } & RequestBaseConfig, +): Promise + +export function artist_detail( + params: { + id: number | string + } & RequestBaseConfig, +): Promise + +export function cloud( + params: { + songFile: { + name: string + data: Buffer + } + } & RequestBaseConfig, +): Promise + +export function topic_detail( + params: { + actid?: number | string + } & RequestBaseConfig, +): Promise + +export function topic_detail_event_hot( + params: { + actid?: number | string + } & RequestBaseConfig, +): Promise + +export function login_qr_key(params: RequestBaseConfig): Promise + +export function login_qr_create( + params: { + key?: number | string + qrimg?: boolean | string + } & RequestBaseConfig, +): Promise + +export function login_qr_check( + params: { + key?: number | string + } & RequestBaseConfig, +): Promise + +export function playlist_detail_dynamic( + params: { id: string | number } & RequestBaseConfig, +): Promise + +export function user_bindingcellphone( + params: { + phone: number | string + captcha: number | string + countrycode?: number | string + password?: string + } & RequestBaseConfig, +): Promise + +export function listen_together_status( + params: RequestBaseConfig, +): Promise + +export function user_comment_history( + params: { + limit?: number | string + uid: number | string + time?: number | string + } & RequestBaseConfig, +): Promise + +export function cloud_match( + params: { + uid: number | string + sid: number | string + asid: number | string + } & RequestBaseConfig, +): Promise + +export function yunbei_rcmd_song( + params: { + id: number | string + reason?: number | string + } & RequestBaseConfig, +): Promise + +export function yunbei_rcmd_song_history( + params: { + size?: number | string + cursor?: number | string + } & RequestBaseConfig, +): Promise + +export function song_purchased( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function mlog_url( + params: { + id?: number | string + res?: number | string + } & RequestBaseConfig, +): Promise + +export function mlog_to_video( + params: { + id?: number | string + } & RequestBaseConfig, +): Promise + +export function vip_growthpoint(params: RequestBaseConfig): Promise + +export function vip_growthpoint_details( + params: MultiPageConfig & RequestBaseConfig, +): Promise + +export function vip_tasks(params: RequestBaseConfig): Promise + +export function vip_growthpoint_get( + params: { + ids?: number | string + } & RequestBaseConfig, +): Promise + +export function artist_fans( + params: { id: number | string } & MultiPageConfig & RequestBaseConfig, +): Promise + +export function digitalAlbum_detail( + params: { + id: number | string + } & RequestBaseConfig, +): Promise + +export function digitalAlbum_sales( + params: { + ids: number | string + } & RequestBaseConfig, +): Promise + +export function musician_data_overview( + params: RequestBaseConfig, +): Promise + +export function musician_play_trend( + params: { + startTime: number | string + endTime: number | string + } & RequestBaseConfig, +): Promise + +export function musician_tasks(params: RequestBaseConfig): Promise + +export function musician_cloudbean(params: RequestBaseConfig): Promise + +export function musician_cloudbean_obtain( + params: { + id: number | string + period: number | string + } & RequestBaseConfig, +): Promise + +export function vip_info( + params: { + uid?: number | string + } & RequestBaseConfig, +): Promise + +export function vip_info_v2( + params: { + uid?: number | string + } & RequestBaseConfig, +): Promise + +export function musician_sign(params: RequestBaseConfig): Promise + +export function song_download_url( + params: { + id: number | string + br?: number | string + } & RequestBaseConfig, +): Promise + +export function playlist_track_all( + params: { + id: number | string + s?: number | string + } & MultiPageConfig & + RequestBaseConfig, +): Promise + +export function artist_video( + params: { + id: number | string + size?: number | string + cursor?: number | string + order?: number | string + } & RequestBaseConfig, +): Promise + +export function sign_happy_info(params: RequestBaseConfig): Promise + +export function record_recent_song( + params: { + limit?: number | string + } & RequestBaseConfig, +): Promise + +export function record_recent_video( + params: { + limit?: number | string + } & RequestBaseConfig, +): Promise + +export function record_recent_voice( + params: { + limit?: number | string + } & RequestBaseConfig, +): Promise + +export function record_recent_playlist( + params: { + limit?: number | string + } & RequestBaseConfig, +): Promise + +export function record_recent_album( + params: { + limit?: number | string + } & RequestBaseConfig, +): Promise + +export function record_recent_dj( + params: { + limit?: number | string + } & RequestBaseConfig, +): Promise + +export function signin_progress( + params: { + moduleId?: string + } & RequestBaseConfig, +): Promise + +export function nickname_check( + params: { + nickname: string + } & RequestBaseConfig, +): Promise + +export function musician_tasks_new(params: RequestBaseConfig): Promise + +export function playlist_update_playcount( + params: { + id?: number | string + } & RequestBaseConfig, +): Promise + +export function vip_timemachine( + params: { + startTime?: number | string + endTime?: number | string + limit?: number | string + } & RequestBaseConfig, +): Promise + +export function song_wiki_summary( + params: { + id: number | string + } & RequestBaseConfig, +): Promise + +export function sheet_list( + params: { + id: number | string + abTest?: 'a' | 'b' + } & RequestBaseConfig, +): Promise + +export function sheet_preview( + params: { + id: number | string + } & RequestBaseConfig, +): Promise + +export function style_list(params: RequestBaseConfig): Promise + +export function style_preference(params: RequestBaseConfig): Promise + +export function style_detail( + params: { + tagId: number | string + } & RequestBaseConfig, +): Promise + +export function style_song( + params: { + tagId: number | string + size?: number | string + cursor?: number | string + sort?: number | string + } & RequestBaseConfig, +): Promise + +export function style_album( + params: { + tagId: number | string + size?: number | string + cursor?: number | string + sort?: number | string + } & RequestBaseConfig, +): Promise + +export function style_playlist( + params: { + tagId: number | string + size?: number | string + cursor?: number | string + } & RequestBaseConfig, +): Promise + +export function style_artist( + params: { + tagId: number | string + size?: number | string + cursor?: number | string + } & RequestBaseConfig, +): Promise + +export function pl_count(params: RequestBaseConfig): Promise + +export function get_userids( + params: { + nicknames: string + } & RequestBaseConfig, +): Promise diff --git a/WebSourceCode/src/Netease/issue_template.md b/WebSourceCode/src/Netease/issue_template.md new file mode 100644 index 0000000..3b7bcb8 --- /dev/null +++ b/WebSourceCode/src/Netease/issue_template.md @@ -0,0 +1,29 @@ +## 环境 +- 系统/平台: <你的系统和平台> + +- nodejs 版本: <你的 NodeJS 版本号> + +- API版本:<运行的云音乐 API 的版本号, 对应 package.json 里面的 version> + +## 出现问题 +<出现的问题> + +## 重现步骤 +<重现步骤> + +## 期待效果 +<现在的效果,期待的效果> + + + +>先看文档有没有相关说明,调用前须知必看 + +>先在 issues 搜一下是否有相似问题,没有再发,否则直接关闭 + +>不处理别人搭建的线上服务的问题,此项目不提供任何线上服务,请自行搭建 + +>重现步骤尽量详细,不能含糊不清,包含请求地址和对应参数以及操作过程描述,不是每个人都喜欢猜别人遇到了什么问题和找参数一个个试,也比较浪费时间 + +>如果不是提建议,提 issues 如果不照着模版来将不会优先处理或直接关闭 + +>460 cheating 的问题把 `utils/request.js` 里面的 `headers['X-Real-IP']` 的注释取消掉就好 diff --git a/WebSourceCode/src/Netease/main.js b/WebSourceCode/src/Netease/main.js new file mode 100644 index 0000000..b6fc81b --- /dev/null +++ b/WebSourceCode/src/Netease/main.js @@ -0,0 +1,49 @@ +const fs = require('fs') +const path = require('path') +const tmpPath = require('os').tmpdir() +const { cookieToJson } = require('./util') + +if (!fs.existsSync(path.resolve(tmpPath, 'anonymous_token'))) { + fs.writeFileSync(path.resolve(tmpPath, 'anonymous_token'), '', 'utf-8') +} + +let firstRun = true +/** @type {Record} */ +let obj = {} +fs.readdirSync(path.join(__dirname, 'module')) + .reverse() + .forEach((file) => { + if (!file.endsWith('.js')) return + let fileModule = require(path.join(__dirname, 'module', file)) + let fn = file.split('.').shift() || '' + obj[fn] = function (data = {}) { + if (typeof data.cookie === 'string') { + data.cookie = cookieToJson(data.cookie) + } + return fileModule( + { + ...data, + cookie: data.cookie ? data.cookie : {}, + }, + async (...args) => { + if (firstRun) { + firstRun = false + const generateConfig = require('./generateConfig') + await generateConfig() + } + // 待优化 + const request = require('./util/request') + + return request(...args) + }, + ) + } + }) + +/** + * @type {Record & import("./server")} + */ +module.exports = { + ...require('./server'), + ...obj, +} diff --git a/WebSourceCode/src/Netease/main.test.js b/WebSourceCode/src/Netease/main.test.js new file mode 100644 index 0000000..2a7a6ca --- /dev/null +++ b/WebSourceCode/src/Netease/main.test.js @@ -0,0 +1,18 @@ +const assert = require('assert') +const main = require('./main') + +describe('methods in server.js', () => { + it('has serveNcmApi', () => { + assert.strictEqual(typeof main.serveNcmApi, 'function') + }) + + it('has getModulesDefinitions', () => { + assert.strictEqual(typeof main.getModulesDefinitions, 'function') + }) +}) + +describe('methods in module', () => { + it('has activate_init_profile', () => { + assert.strictEqual(typeof main.activate_init_profile, 'function') + }) +}) diff --git a/WebSourceCode/src/Netease/module/activate_init_profile.js b/WebSourceCode/src/Netease/module/activate_init_profile.js new file mode 100644 index 0000000..0fe48ba --- /dev/null +++ b/WebSourceCode/src/Netease/module/activate_init_profile.js @@ -0,0 +1,19 @@ +// 初始化名字 + +module.exports = (query, request) => { + const data = { + nickname: query.nickname, + } + return request( + 'POST', + `https://music.163.com/eapi/activate/initProfile`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/activate/initProfile', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/aidj_content_rcmd.js b/WebSourceCode/src/Netease/module/aidj_content_rcmd.js new file mode 100644 index 0000000..8c463c7 --- /dev/null +++ b/WebSourceCode/src/Netease/module/aidj_content_rcmd.js @@ -0,0 +1,37 @@ +// 私人 DJ + +// 实际请求参数如下, 部分内容省略, 敏感信息已进行混淆 +// 可按需修改此 API 的代码 +/* {"extInfo":"{\"lastRequestTimestamp\":1692358373509,\"lbsInfoList\":[{\"lat\":40.23076381,\"lon\":129.07545186,\"time\":1692358543},{\"lat\":40.23076381,\"lon\":129.07545186,\"time\":1692055283}],\"listenedTs\":false,\"noAidjToAidj\":true}","header":"{}","e_r":true} */ + +module.exports = (query, request) => { + var extInfo = {} + if (query.latitude != undefined) { + extInfo.lbsInfoList = [ + { + lat: query.latitude, + lon: query.longitude, + time: Date.parse(new Date()) / 1000, + }, + ] + } + extInfo.noAidjToAidj = false + extInfo.lastRequestTimestamp = new Date().getTime() + extInfo.listenedTs = false + const data = { + extInfo: JSON.stringify(extInfo), + } + console.log(data) + return request( + 'POST', + `https://interface3.music.163.com/eapi/aidj/content/rcmd/info`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/aidj/content/rcmd/info', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/album.js b/WebSourceCode/src/Netease/module/album.js new file mode 100644 index 0000000..bc5e086 --- /dev/null +++ b/WebSourceCode/src/Netease/module/album.js @@ -0,0 +1,15 @@ +// 专辑内容 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/album/${query.id}`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/album_detail.js b/WebSourceCode/src/Netease/module/album_detail.js new file mode 100644 index 0000000..a26fef3 --- /dev/null +++ b/WebSourceCode/src/Netease/module/album_detail.js @@ -0,0 +1,17 @@ +// 数字专辑详情 +module.exports = (query, request) => { + const data = { + id: query.id, + } + return request( + 'POST', + `https://music.163.com/weapi/vipmall/albumproduct/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/album_detail_dynamic.js b/WebSourceCode/src/Netease/module/album_detail_dynamic.js new file mode 100644 index 0000000..3d08e64 --- /dev/null +++ b/WebSourceCode/src/Netease/module/album_detail_dynamic.js @@ -0,0 +1,17 @@ +// 专辑动态信息 +module.exports = (query, request) => { + const data = { + id: query.id, + } + return request( + 'POST', + `https://music.163.com/api/album/detail/dynamic`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/album_list.js b/WebSourceCode/src/Netease/module/album_list.js new file mode 100644 index 0000000..fe70dd8 --- /dev/null +++ b/WebSourceCode/src/Netease/module/album_list.js @@ -0,0 +1,21 @@ +// 数字专辑-新碟上架 +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + area: query.area || 'ALL', //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本 + type: query.type, + } + return request( + 'POST', + `https://music.163.com/weapi/vipmall/albumproduct/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/album_list_style.js b/WebSourceCode/src/Netease/module/album_list_style.js new file mode 100644 index 0000000..8b92a7a --- /dev/null +++ b/WebSourceCode/src/Netease/module/album_list_style.js @@ -0,0 +1,20 @@ +// 数字专辑-语种风格馆 +module.exports = (query, request) => { + const data = { + limit: query.limit || 10, + offset: query.offset || 0, + total: true, + area: query.area || 'Z_H', //Z_H:华语,E_A:欧美,KR:韩国,JP:日本 + } + return request( + 'POST', + `https://music.163.com/weapi/vipmall/appalbum/album/style`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/album_new.js b/WebSourceCode/src/Netease/module/album_new.js new file mode 100644 index 0000000..b4652d3 --- /dev/null +++ b/WebSourceCode/src/Netease/module/album_new.js @@ -0,0 +1,15 @@ +// 全部新碟 +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + area: query.area || 'ALL', //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本 + } + return request('POST', `https://music.163.com/weapi/album/new`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/album_newest.js b/WebSourceCode/src/Netease/module/album_newest.js new file mode 100644 index 0000000..fe1f650 --- /dev/null +++ b/WebSourceCode/src/Netease/module/album_newest.js @@ -0,0 +1,15 @@ +// 最新专辑 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/api/discovery/newAlbum`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/album_songsaleboard.js b/WebSourceCode/src/Netease/module/album_songsaleboard.js new file mode 100644 index 0000000..a797418 --- /dev/null +++ b/WebSourceCode/src/Netease/module/album_songsaleboard.js @@ -0,0 +1,24 @@ +// 数字专辑&数字单曲-榜单 +module.exports = (query, request) => { + let data = { + albumType: query.albumType || 0, //0为数字专辑,1为数字单曲 + } + const type = query.type || 'daily' // daily,week,year,total + if (type === 'year') { + data = { + ...data, + year: query.year, + } + } + return request( + 'POST', + `https://music.163.com/api/feealbum/songsaleboard/${type}/type`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/album_sub.js b/WebSourceCode/src/Netease/module/album_sub.js new file mode 100644 index 0000000..65c6b24 --- /dev/null +++ b/WebSourceCode/src/Netease/module/album_sub.js @@ -0,0 +1,14 @@ +// 收藏/取消收藏专辑 + +module.exports = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub' + const data = { + id: query.id, + } + return request('POST', `https://music.163.com/api/album/${query.t}`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/album_sublist.js b/WebSourceCode/src/Netease/module/album_sublist.js new file mode 100644 index 0000000..5d01578 --- /dev/null +++ b/WebSourceCode/src/Netease/module/album_sublist.js @@ -0,0 +1,15 @@ +// 已收藏专辑列表 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 25, + offset: query.offset || 0, + total: true, + } + return request('POST', `https://music.163.com/weapi/album/sublist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/artist_album.js b/WebSourceCode/src/Netease/module/artist_album.js new file mode 100644 index 0000000..92a04a7 --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_album.js @@ -0,0 +1,20 @@ +// 歌手专辑列表 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + } + return request( + 'POST', + `https://music.163.com/weapi/artist/albums/${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/artist_desc.js b/WebSourceCode/src/Netease/module/artist_desc.js new file mode 100644 index 0000000..c67d707 --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_desc.js @@ -0,0 +1,18 @@ +// 歌手介绍 + +module.exports = (query, request) => { + const data = { + id: query.id, + } + return request( + 'POST', + `https://music.163.com/weapi/artist/introduction`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/artist_detail.js b/WebSourceCode/src/Netease/module/artist_detail.js new file mode 100644 index 0000000..8bbb9d9 --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_detail.js @@ -0,0 +1,15 @@ +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/api/artist/head/info/get`, + { + id: query.id, + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/artist_fans.js b/WebSourceCode/src/Netease/module/artist_fans.js new file mode 100644 index 0000000..700eac0 --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_fans.js @@ -0,0 +1,15 @@ +// 歌手粉丝 + +module.exports = (query, request) => { + const data = { + id: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + } + return request('POST', `https://music.163.com/weapi/artist/fans/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/artist_follow_count.js b/WebSourceCode/src/Netease/module/artist_follow_count.js new file mode 100644 index 0000000..93afda2 --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_follow_count.js @@ -0,0 +1,18 @@ +// 歌手粉丝数量 + +module.exports = (query, request) => { + const data = { + id: query.id, + } + return request( + 'POST', + `https://music.163.com/weapi/artist/follow/count/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/artist_list.js b/WebSourceCode/src/Netease/module/artist_list.js new file mode 100644 index 0000000..fe95864 --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_list.js @@ -0,0 +1,37 @@ +// 歌手分类 + +/* + type 取值 + 1:男歌手 + 2:女歌手 + 3:乐队 + + area 取值 + -1:全部 + 7华语 + 96欧美 + 8:日本 + 16韩国 + 0:其他 + + initial 取值 a-z/A-Z +*/ + +module.exports = (query, request) => { + const data = { + initial: isNaN(query.initial) + ? (query.initial || '').toUpperCase().charCodeAt() || undefined + : query.initial, + offset: query.offset || 0, + limit: query.limit || 30, + total: true, + type: query.type || '1', + area: query.area, + } + return request('POST', `https://music.163.com/api/v1/artist/list`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/artist_mv.js b/WebSourceCode/src/Netease/module/artist_mv.js new file mode 100644 index 0000000..8decc04 --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_mv.js @@ -0,0 +1,16 @@ +// 歌手相关MV + +module.exports = (query, request) => { + const data = { + artistId: query.id, + limit: query.limit, + offset: query.offset, + total: true, + } + return request('POST', `https://music.163.com/weapi/artist/mvs`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/artist_new_mv.js b/WebSourceCode/src/Netease/module/artist_new_mv.js new file mode 100644 index 0000000..d385e35 --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_new_mv.js @@ -0,0 +1,19 @@ +module.exports = (query, request) => { + query.cookie.os = 'ios' + query.cookie.appver = '8.7.01' + const data = { + limit: query.limit || 20, + startTimestamp: query.before || Date.now(), + } + return request( + 'POST', + `https://music.163.com/api/sub/artist/new/works/mv/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/artist_new_song.js b/WebSourceCode/src/Netease/module/artist_new_song.js new file mode 100644 index 0000000..41fbde5 --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_new_song.js @@ -0,0 +1,19 @@ +module.exports = (query, request) => { + query.cookie.os = 'ios' + query.cookie.appver = '8.7.01' + const data = { + limit: query.limit || 20, + startTimestamp: query.before || Date.now(), + } + return request( + 'POST', + `https://music.163.com/api/sub/artist/new/works/song/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/artist_songs.js b/WebSourceCode/src/Netease/module/artist_songs.js new file mode 100644 index 0000000..533e1e5 --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_songs.js @@ -0,0 +1,17 @@ +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + id: query.id, + private_cloud: 'true', + work_type: 1, + order: query.order || 'hot', //hot,time + offset: query.offset || 0, + limit: query.limit || 100, + } + return request('POST', `https://music.163.com/api/v1/artist/songs`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/artist_sub.js b/WebSourceCode/src/Netease/module/artist_sub.js new file mode 100644 index 0000000..ff46b04 --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_sub.js @@ -0,0 +1,20 @@ +// 收藏与取消收藏歌手 + +module.exports = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub' + const data = { + artistId: query.id, + artistIds: '[' + query.id + ']', + } + return request( + 'POST', + `https://music.163.com/weapi/artist/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/artist_sublist.js b/WebSourceCode/src/Netease/module/artist_sublist.js new file mode 100644 index 0000000..c4adf40 --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_sublist.js @@ -0,0 +1,15 @@ +// 关注歌手列表 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 25, + offset: query.offset || 0, + total: true, + } + return request('POST', `https://music.163.com/weapi/artist/sublist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/artist_top_song.js b/WebSourceCode/src/Netease/module/artist_top_song.js new file mode 100644 index 0000000..c86136e --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_top_song.js @@ -0,0 +1,12 @@ +// 歌手热门 50 首歌曲 +module.exports = (query, request) => { + const data = { + id: query.id, + } + return request('POST', `https://music.163.com/api/artist/top/song`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/artist_video.js b/WebSourceCode/src/Netease/module/artist_video.js new file mode 100644 index 0000000..735fe07 --- /dev/null +++ b/WebSourceCode/src/Netease/module/artist_video.js @@ -0,0 +1,24 @@ +// 歌手相关视频 + +module.exports = (query, request) => { + const data = { + artistId: query.id, + page: JSON.stringify({ + size: query.size || 10, + cursor: query.cursor || 0, + }), + tab: 0, + order: query.order || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/mlog/artist/video`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/artists.js b/WebSourceCode/src/Netease/module/artists.js new file mode 100644 index 0000000..3f29e7f --- /dev/null +++ b/WebSourceCode/src/Netease/module/artists.js @@ -0,0 +1,15 @@ +// 歌手单曲 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/artist/${query.id}`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/audio_match.js b/WebSourceCode/src/Netease/module/audio_match.js new file mode 100644 index 0000000..8ec30b0 --- /dev/null +++ b/WebSourceCode/src/Netease/module/audio_match.js @@ -0,0 +1,25 @@ +function createRandomString(len) { + const str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + let result = '' + for (let i = len; i > 0; --i) + result += str[Math.floor(Math.random() * str.length)] + return result +} +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + algorithmCode: 'shazam_v2', + times: 1, + sessionId: createRandomString(16), + duration: Number(query.duration), + from: 'recognize-song', + decrypt: '1', + rawdata: query.audioFP, + } + return request('POST', `https://music.163.com/api/music/audio/match`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/avatar_upload.js b/WebSourceCode/src/Netease/module/avatar_upload.js new file mode 100644 index 0000000..94f018b --- /dev/null +++ b/WebSourceCode/src/Netease/module/avatar_upload.js @@ -0,0 +1,27 @@ +const uploadPlugin = require('../plugins/upload') +module.exports = async (query, request) => { + const uploadInfo = await uploadPlugin(query, request) + const res = await request( + 'POST', + `https://music.163.com/weapi/user/avatar/upload/v1`, + { + imgid: uploadInfo.imgId, + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + return { + status: 200, + body: { + code: 200, + data: { + ...uploadInfo, + ...res.body, + }, + }, + } +} diff --git a/WebSourceCode/src/Netease/module/banner.js b/WebSourceCode/src/Netease/module/banner.js new file mode 100644 index 0000000..00f52c9 --- /dev/null +++ b/WebSourceCode/src/Netease/module/banner.js @@ -0,0 +1,17 @@ +// 首页轮播图 + +module.exports = (query, request) => { + const type = + { + 0: 'pc', + 1: 'android', + 2: 'iphone', + 3: 'ipad', + }[query.type || 0] || 'pc' + return request( + 'POST', + `https://music.163.com/api/v2/banner/get`, + { clientType: type }, + { crypto: 'api', proxy: query.proxy, realIP: query.realIP }, + ) +} diff --git a/WebSourceCode/src/Netease/module/batch.js b/WebSourceCode/src/Netease/module/batch.js new file mode 100644 index 0000000..2e95070 --- /dev/null +++ b/WebSourceCode/src/Netease/module/batch.js @@ -0,0 +1,19 @@ +// 批量请求接口 + +module.exports = (query, request) => { + const data = { + e_r: true, + } + Object.keys(query).forEach((i) => { + if (/^\/api\//.test(i)) { + data[i] = query[i] + } + }) + return request('POST', `https://music.163.com/eapi/batch`, data, { + crypto: 'eapi', + proxy: query.proxy, + url: '/api/batch', + cookie: query.cookie, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/calendar.js b/WebSourceCode/src/Netease/module/calendar.js new file mode 100644 index 0000000..61bc387 --- /dev/null +++ b/WebSourceCode/src/Netease/module/calendar.js @@ -0,0 +1,12 @@ +module.exports = (query, request) => { + const data = { + startTime: query.startTime || Date.now(), + endTime: query.endTime || Date.now(), + } + return request('POST', `https://music.163.com/api/mcalendar/detail`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/captcha_sent.js b/WebSourceCode/src/Netease/module/captcha_sent.js new file mode 100644 index 0000000..076dcbb --- /dev/null +++ b/WebSourceCode/src/Netease/module/captcha_sent.js @@ -0,0 +1,14 @@ +// 发送验证码 + +module.exports = (query, request) => { + const data = { + ctcode: query.ctcode || '86', + cellphone: query.phone, + } + return request('POST', `https://music.163.com/api/sms/captcha/sent`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/captcha_verify.js b/WebSourceCode/src/Netease/module/captcha_verify.js new file mode 100644 index 0000000..990ce27 --- /dev/null +++ b/WebSourceCode/src/Netease/module/captcha_verify.js @@ -0,0 +1,20 @@ +// 校验验证码 + +module.exports = (query, request) => { + const data = { + ctcode: query.ctcode || '86', + cellphone: query.phone, + captcha: query.captcha, + } + return request( + 'POST', + `https://music.163.com/weapi/sms/captcha/verify`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/cellphone_existence_check.js b/WebSourceCode/src/Netease/module/cellphone_existence_check.js new file mode 100644 index 0000000..c4912ae --- /dev/null +++ b/WebSourceCode/src/Netease/module/cellphone_existence_check.js @@ -0,0 +1,20 @@ +// 检测手机号码是否已注册 + +module.exports = (query, request) => { + const data = { + cellphone: query.phone, + countrycode: query.countrycode, + } + return request( + 'POST', + `https://music.163.com/eapi/cellphone/existence/check`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/cellphone/existence/check', + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/check_music.js b/WebSourceCode/src/Netease/module/check_music.js new file mode 100644 index 0000000..1e25f13 --- /dev/null +++ b/WebSourceCode/src/Netease/module/check_music.js @@ -0,0 +1,35 @@ +// 歌曲可用性 + +module.exports = (query, request) => { + const data = { + ids: '[' + parseInt(query.id) + ']', + br: parseInt(query.br || 999000), + } + return request( + 'POST', + `https://music.163.com/weapi/song/enhance/player/url`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ).then((response) => { + let playable = false + if (response.body.code == 200) { + if (response.body.data[0].code == 200) { + playable = true + } + } + if (playable) { + response.body = { success: true, message: 'ok' } + return response + } else { + // response.status = 404 + response.body = { success: false, message: '亲爱的,暂无版权' } + return response + // return Promise.reject(response) + } + }) +} diff --git a/WebSourceCode/src/Netease/module/cloud.js b/WebSourceCode/src/Netease/module/cloud.js new file mode 100644 index 0000000..361161e --- /dev/null +++ b/WebSourceCode/src/Netease/module/cloud.js @@ -0,0 +1,159 @@ +const mm = require('music-metadata') +const uploadPlugin = require('../plugins/songUpload') +const md5 = require('md5') +module.exports = async (query, request) => { + let ext = 'mp3' + if (query.songFile.name.indexOf('flac') > -1) { + ext = 'flac' + } + const filename = query.songFile.name + .replace('.' + ext, '') + .replace(/\s/g, '') + .replace(/\./g, '_') + query.cookie.os = 'pc' + query.cookie.appver = '2.9.7' + const bitrate = 999000 + if (!query.songFile) { + return Promise.reject({ + status: 500, + body: { + msg: '请上传音乐文件', + code: 500, + }, + }) + } + if (!query.songFile.md5) { + // 命令行上传没有md5和size信息,需要填充 + query.songFile.md5 = md5(query.songFile.data) + query.songFile.size = query.songFile.data.byteLength + } + const res = await request( + 'POST', + `https://interface.music.163.com/api/cloud/upload/check`, + { + bitrate: String(bitrate), + ext: '', + length: query.songFile.size, + md5: query.songFile.md5, + songId: '0', + version: 1, + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + let artist = '' + let album = '' + let songName = '' + try { + const metadata = await mm.parseBuffer( + query.songFile.data, + query.songFile.mimetype, + ) + const info = metadata.common + + if (info.title) { + songName = info.title + } + if (info.album) { + album = info.album + } + if (info.artist) { + artist = info.artist + } + // if (metadata.native.ID3v1) { + // metadata.native.ID3v1.forEach((item) => { + // // console.log(item.id, item.value) + // if (item.id === 'title') { + // songName = item.value + // } + // if (item.id === 'artist') { + // artist = item.value + // } + // if (item.id === 'album') { + // album = item.value + // } + // }) + // // console.log({ + // // songName, + // // album, + // // songName, + // // }) + // } + // console.log({ + // songName, + // album, + // songName, + // }) + } catch (error) { + console.log(error) + } + const tokenRes = await request( + 'POST', + `https://music.163.com/weapi/nos/token/alloc`, + { + bucket: '', + ext: ext, + filename: filename, + local: false, + nos_product: 3, + type: 'audio', + md5: query.songFile.md5, + }, + { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy }, + ) + + if (res.body.needUpload) { + const uploadInfo = await uploadPlugin(query, request) + // console.log('uploadInfo', uploadInfo.body.result.resourceId) + } + // console.log(tokenRes.body.result) + const res2 = await request( + 'POST', + `https://music.163.com/api/upload/cloud/info/v2`, + { + md5: query.songFile.md5, + songid: res.body.songId, + filename: query.songFile.name, + song: songName || filename, + album: album || '未知专辑', + artist: artist || '未知艺术家', + bitrate: String(bitrate), + resourceId: tokenRes.body.result.resourceId, + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + // console.log({ res2, privateCloud: res2.body.privateCloud }) + // console.log(res.body.songId, 'songid') + const res3 = await request( + 'POST', + `https://interface.music.163.com/api/cloud/pub/v2`, + { + songid: res2.body.songId, + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + // console.log({ res3 }) + return { + status: 200, + body: { + ...res.body, + ...res3.body, + // ...uploadInfo, + }, + cookie: res.cookie, + } +} diff --git a/WebSourceCode/src/Netease/module/cloud_match.js b/WebSourceCode/src/Netease/module/cloud_match.js new file mode 100644 index 0000000..98fc8aa --- /dev/null +++ b/WebSourceCode/src/Netease/module/cloud_match.js @@ -0,0 +1,20 @@ +module.exports = (query, request) => { + query.cookie.os = 'ios' + query.cookie.appver = '8.7.01' + const data = { + userId: query.uid, + songId: query.sid, + adjustSongId: query.asid, + } + return request( + 'POST', + `https://music.163.com/api/cloud/user/song/match`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/cloudsearch.js b/WebSourceCode/src/Netease/module/cloudsearch.js new file mode 100644 index 0000000..8815a16 --- /dev/null +++ b/WebSourceCode/src/Netease/module/cloudsearch.js @@ -0,0 +1,23 @@ +// 搜索 + +module.exports = (query, request) => { + const data = { + s: query.keywords, + type: query.type || 1, // 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频 + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + } + return request( + 'POST', + `https://interface.music.163.com/eapi/cloudsearch/pc`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/cloudsearch/pc', + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/comment.js b/WebSourceCode/src/Netease/module/comment.js new file mode 100644 index 0000000..389e9e3 --- /dev/null +++ b/WebSourceCode/src/Netease/module/comment.js @@ -0,0 +1,36 @@ +const { resourceTypeMap } = require('../util/config.json') +// 发送与删除评论 + +module.exports = (query, request) => { + query.cookie.os = 'android' + query.t = { + 1: 'add', + 0: 'delete', + 2: 'reply', + }[query.t] + query.type = resourceTypeMap[query.type] + const data = { + threadId: query.type + query.id, + } + + if (query.type == 'A_EV_2_') { + data.threadId = query.threadId + } + if (query.t == 'add') data.content = query.content + else if (query.t == 'delete') data.commentId = query.commentId + else if (query.t == 'reply') { + data.commentId = query.commentId + data.content = query.content + } + return request( + 'POST', + `https://music.163.com/weapi/resource/comments/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/comment_album.js b/WebSourceCode/src/Netease/module/comment_album.js new file mode 100644 index 0000000..d701d2d --- /dev/null +++ b/WebSourceCode/src/Netease/module/comment_album.js @@ -0,0 +1,22 @@ +// 专辑评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/R_AL_3_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/comment_dj.js b/WebSourceCode/src/Netease/module/comment_dj.js new file mode 100644 index 0000000..70b7dbf --- /dev/null +++ b/WebSourceCode/src/Netease/module/comment_dj.js @@ -0,0 +1,22 @@ +// 电台评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/A_DJ_1_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/comment_event.js b/WebSourceCode/src/Netease/module/comment_event.js new file mode 100644 index 0000000..460a560 --- /dev/null +++ b/WebSourceCode/src/Netease/module/comment_event.js @@ -0,0 +1,20 @@ +// 获取动态评论 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/${query.threadId}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/comment_floor.js b/WebSourceCode/src/Netease/module/comment_floor.js new file mode 100644 index 0000000..de28470 --- /dev/null +++ b/WebSourceCode/src/Netease/module/comment_floor.js @@ -0,0 +1,21 @@ +const { resourceTypeMap } = require('../util/config.json') +module.exports = (query, request) => { + query.type = resourceTypeMap[query.type] + const data = { + parentCommentId: query.parentCommentId, + threadId: query.type + query.id, + time: query.time || -1, + limit: query.limit || 20, + } + return request( + 'POST', + `https://music.163.com/api/resource/comment/floor/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/comment_hot.js b/WebSourceCode/src/Netease/module/comment_hot.js new file mode 100644 index 0000000..4858678 --- /dev/null +++ b/WebSourceCode/src/Netease/module/comment_hot.js @@ -0,0 +1,24 @@ +const { resourceTypeMap } = require('../util/config.json') +// 热门评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + query.type = resourceTypeMap[query.type] + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/hotcomments/${query.type}${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/comment_hug_list.js b/WebSourceCode/src/Netease/module/comment_hug_list.js new file mode 100644 index 0000000..eaf535f --- /dev/null +++ b/WebSourceCode/src/Netease/module/comment_hug_list.js @@ -0,0 +1,27 @@ +const { resourceTypeMap } = require('../util/config.json') +module.exports = (query, request) => { + query.cookie.os = 'ios' + query.cookie.appver = '8.7.01' + query.type = resourceTypeMap[query.type || 0] + const threadId = query.type + query.sid + const data = { + targetUserId: query.uid, + commentId: query.cid, + cursor: query.cursor || '-1', + threadId: threadId, + pageNo: query.page || 1, + idCursor: query.idCursor || -1, + pageSize: query.pageSize || 100, + } + return request( + 'POST', + `https://music.163.com/api/v2/resource/comments/hug/list`, + data, + { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/comment_like.js b/WebSourceCode/src/Netease/module/comment_like.js new file mode 100644 index 0000000..fa382a8 --- /dev/null +++ b/WebSourceCode/src/Netease/module/comment_like.js @@ -0,0 +1,26 @@ +const { resourceTypeMap } = require('../util/config.json') +// 点赞与取消点赞评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + query.t = query.t == 1 ? 'like' : 'unlike' + query.type = resourceTypeMap[query.type] + const data = { + threadId: query.type + query.id, + commentId: query.cid, + } + if (query.type == 'A_EV_2_') { + data.threadId = query.threadId + } + return request( + 'POST', + `https://music.163.com/weapi/v1/comment/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/comment_music.js b/WebSourceCode/src/Netease/module/comment_music.js new file mode 100644 index 0000000..9fbc8f1 --- /dev/null +++ b/WebSourceCode/src/Netease/module/comment_music.js @@ -0,0 +1,22 @@ +// 歌曲评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + } + return request( + 'POST', + `https://music.163.com/api/v1/resource/comments/R_SO_4_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/comment_mv.js b/WebSourceCode/src/Netease/module/comment_mv.js new file mode 100644 index 0000000..979c035 --- /dev/null +++ b/WebSourceCode/src/Netease/module/comment_mv.js @@ -0,0 +1,22 @@ +// MV评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/R_MV_5_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/comment_new.js b/WebSourceCode/src/Netease/module/comment_new.js new file mode 100644 index 0000000..ec221dc --- /dev/null +++ b/WebSourceCode/src/Netease/module/comment_new.js @@ -0,0 +1,48 @@ +const { resourceTypeMap } = require('../util/config.json') +// 评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + query.type = resourceTypeMap[query.type] + const threadId = query.type + query.id + const pageSize = query.pageSize || 20 + const pageNo = query.pageNo || 1 + let sortType = Number(query.sortType) || 99 + if (sortType === 1) { + sortType = 99 + } + let cursor = '' + switch (sortType) { + case 99: + cursor = (pageNo - 1) * pageSize + break + case 2: + cursor = 'normalHot#' + (pageNo - 1) * pageSize + break + case 3: + cursor = query.cursor || '0' + break + default: + break + } + const data = { + threadId: threadId, + pageNo, + showInner: query.showInner || true, + pageSize, + cursor: cursor, + sortType: sortType, //99:按推荐排序,2:按热度排序,3:按时间排序 + } + return request( + 'POST', + `https://music.163.com/api/v2/resource/comments`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/v2/resource/comments', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/comment_playlist.js b/WebSourceCode/src/Netease/module/comment_playlist.js new file mode 100644 index 0000000..52fc544 --- /dev/null +++ b/WebSourceCode/src/Netease/module/comment_playlist.js @@ -0,0 +1,22 @@ +// 歌单评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/A_PL_0_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/comment_video.js b/WebSourceCode/src/Netease/module/comment_video.js new file mode 100644 index 0000000..ae015a9 --- /dev/null +++ b/WebSourceCode/src/Netease/module/comment_video.js @@ -0,0 +1,22 @@ +// 视频评论 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + rid: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + beforeTime: query.before || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/v1/resource/comments/R_VI_62_${query.id}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/countries_code_list.js b/WebSourceCode/src/Netease/module/countries_code_list.js new file mode 100644 index 0000000..15a76b6 --- /dev/null +++ b/WebSourceCode/src/Netease/module/countries_code_list.js @@ -0,0 +1,16 @@ +// 国家编码列表 +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://interface3.music.163.com/eapi/lbs/countries/v1`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/lbs/countries/v1', + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/daily_signin.js b/WebSourceCode/src/Netease/module/daily_signin.js new file mode 100644 index 0000000..2bb7dee --- /dev/null +++ b/WebSourceCode/src/Netease/module/daily_signin.js @@ -0,0 +1,20 @@ +// 签到 + +/* + 0为安卓端签到 3点经验, 1为网页签到,2点经验 + 签到成功 {'android': {'point': 3, 'code': 200}, 'web': {'point': 2, 'code': 200}} + 重复签到 {'android': {'code': -2, 'msg': '重复签到'}, 'web': {'code': -2, 'msg': '重复签到'}} + 未登录 {'android': {'code': 301}, 'web': {'code': 301}} +*/ + +module.exports = (query, request) => { + const data = { + type: query.type || 0, + } + return request('POST', `https://music.163.com/weapi/point/dailyTask`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/digitalAlbum_detail.js b/WebSourceCode/src/Netease/module/digitalAlbum_detail.js new file mode 100644 index 0000000..a3ed02d --- /dev/null +++ b/WebSourceCode/src/Netease/module/digitalAlbum_detail.js @@ -0,0 +1,18 @@ +// 数字专辑详情 + +module.exports = (query, request) => { + const data = { + id: query.id, + } + return request( + 'POST', + `https://music.163.com/weapi/vipmall/albumproduct/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/digitalAlbum_ordering.js b/WebSourceCode/src/Netease/module/digitalAlbum_ordering.js new file mode 100644 index 0000000..471d95b --- /dev/null +++ b/WebSourceCode/src/Netease/module/digitalAlbum_ordering.js @@ -0,0 +1,27 @@ +// 购买数字专辑 + +module.exports = (query, request) => { + const data = { + business: 'Album', + paymentMethod: query.payment, + digitalResources: JSON.stringify([ + { + business: 'Album', + resourceID: query.id, + quantity: query.quantity, + }, + ]), + from: 'web', + } + return request( + 'POST', + `https://music.163.com/api/ordering/web/digital`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/digitalAlbum_purchased.js b/WebSourceCode/src/Netease/module/digitalAlbum_purchased.js new file mode 100644 index 0000000..362dee1 --- /dev/null +++ b/WebSourceCode/src/Netease/module/digitalAlbum_purchased.js @@ -0,0 +1,20 @@ +// 我的数字专辑 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + } + return request( + 'POST', + `https://music.163.com/api/digitalAlbum/purchased`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/digitalAlbum_sales.js b/WebSourceCode/src/Netease/module/digitalAlbum_sales.js new file mode 100644 index 0000000..89da320 --- /dev/null +++ b/WebSourceCode/src/Netease/module/digitalAlbum_sales.js @@ -0,0 +1,18 @@ +// 数字专辑销量 + +module.exports = (query, request) => { + const data = { + albumIds: query.ids, + } + return request( + 'POST', + `https://music.163.com/weapi/vipmall/albumproduct/album/query/sales`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_banner.js b/WebSourceCode/src/Netease/module/dj_banner.js new file mode 100644 index 0000000..1ec17ba --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_banner.js @@ -0,0 +1,17 @@ +// 电台banner + +module.exports = (query, request) => { + const data = {} + query.cookie.os = 'pc' + return request( + 'POST', + `https://music.163.com/weapi/djradio/banner/get`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_category_excludehot.js b/WebSourceCode/src/Netease/module/dj_category_excludehot.js new file mode 100644 index 0000000..cfd4266 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_category_excludehot.js @@ -0,0 +1,15 @@ +// 电台非热门类型 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/djradio/category/excludehot`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_category_recommend.js b/WebSourceCode/src/Netease/module/dj_category_recommend.js new file mode 100644 index 0000000..a0e4bf1 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_category_recommend.js @@ -0,0 +1,15 @@ +// 电台推荐类型 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/djradio/home/category/recommend`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_catelist.js b/WebSourceCode/src/Netease/module/dj_catelist.js new file mode 100644 index 0000000..8866be4 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_catelist.js @@ -0,0 +1,15 @@ +// 电台分类列表 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/djradio/category/get`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_detail.js b/WebSourceCode/src/Netease/module/dj_detail.js new file mode 100644 index 0000000..941024b --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_detail.js @@ -0,0 +1,13 @@ +// 电台详情 + +module.exports = (query, request) => { + const data = { + id: query.rid, + } + return request('POST', `https://music.163.com/api/djradio/v2/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/dj_hot.js b/WebSourceCode/src/Netease/module/dj_hot.js new file mode 100644 index 0000000..5f7e30f --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_hot.js @@ -0,0 +1,14 @@ +// 热门电台 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + } + return request('POST', `https://music.163.com/weapi/djradio/hot/v1`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/dj_paygift.js b/WebSourceCode/src/Netease/module/dj_paygift.js new file mode 100644 index 0000000..4424ab9 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_paygift.js @@ -0,0 +1,19 @@ +// 付费电台 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/djradio/home/paygift/list?_nmclfl=1`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_personalize_recommend.js b/WebSourceCode/src/Netease/module/dj_personalize_recommend.js new file mode 100644 index 0000000..b8d7570 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_personalize_recommend.js @@ -0,0 +1,17 @@ +// 电台个性推荐 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/api/djradio/personalize/rcmd`, + { + limit: query.limit || 6, + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_program.js b/WebSourceCode/src/Netease/module/dj_program.js new file mode 100644 index 0000000..a0fa646 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_program.js @@ -0,0 +1,21 @@ +// 电台节目列表 +const { toBoolean } = require('../util') +module.exports = (query, request) => { + const data = { + radioId: query.rid, + limit: query.limit || 30, + offset: query.offset || 0, + asc: toBoolean(query.asc), + } + return request( + 'POST', + `https://music.163.com/weapi/dj/program/byradio`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_program_detail.js b/WebSourceCode/src/Netease/module/dj_program_detail.js new file mode 100644 index 0000000..70f3d2e --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_program_detail.js @@ -0,0 +1,13 @@ +// 电台节目详情 + +module.exports = (query, request) => { + const data = { + id: query.id, + } + return request('POST', `https://music.163.com/api/dj/program/detail`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/dj_program_toplist.js b/WebSourceCode/src/Netease/module/dj_program_toplist.js new file mode 100644 index 0000000..898cf9d --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_program_toplist.js @@ -0,0 +1,14 @@ +// 电台节目榜 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + offset: query.offset || 0, + } + return request('POST', `https://music.163.com/api/program/toplist/v1`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/dj_program_toplist_hours.js b/WebSourceCode/src/Netease/module/dj_program_toplist_hours.js new file mode 100644 index 0000000..4547636 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_program_toplist_hours.js @@ -0,0 +1,18 @@ +// 电台24小时节目榜 +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + // 不支持 offset + } + return request( + 'POST', + `https://music.163.com/api/djprogram/toplist/hours`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_radio_hot.js b/WebSourceCode/src/Netease/module/dj_radio_hot.js new file mode 100644 index 0000000..30e0b42 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_radio_hot.js @@ -0,0 +1,15 @@ +// 类别热门电台 + +module.exports = (query, request) => { + const data = { + cateId: query.cateId, + limit: query.limit || 30, + offset: query.offset || 0, + } + return request('POST', `https://music.163.com/api/djradio/hot`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/dj_recommend.js b/WebSourceCode/src/Netease/module/dj_recommend.js new file mode 100644 index 0000000..e23b056 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_recommend.js @@ -0,0 +1,15 @@ +// 精选电台 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/djradio/recommend/v1`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_recommend_type.js b/WebSourceCode/src/Netease/module/dj_recommend_type.js new file mode 100644 index 0000000..6f3df61 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_recommend_type.js @@ -0,0 +1,41 @@ +// 精选电台分类 + +/* + 有声书 10001 + 知识技能 453050 + 商业财经 453051 + 人文历史 11 + 外语世界 13 + 亲子宝贝 14 + 创作|翻唱 2001 + 音乐故事 2 + 3D|电子 10002 + 相声曲艺 8 + 情感调频 3 + 美文读物 6 + 脱口秀 5 + 广播剧 7 + 二次元 3001 + 明星做主播 1 + 娱乐|影视 4 + 科技科学 453052 + 校园|教育 4001 + 旅途|城市 12 +*/ + +module.exports = (query, request) => { + const data = { + cateId: query.type, + } + return request( + 'POST', + `https://music.163.com/weapi/djradio/recommend`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_sub.js b/WebSourceCode/src/Netease/module/dj_sub.js new file mode 100644 index 0000000..cec5ad7 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_sub.js @@ -0,0 +1,19 @@ +// 订阅与取消电台 + +module.exports = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub' + const data = { + id: query.rid, + } + return request( + 'POST', + `https://music.163.com/weapi/djradio/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_sublist.js b/WebSourceCode/src/Netease/module/dj_sublist.js new file mode 100644 index 0000000..6d4bcf2 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_sublist.js @@ -0,0 +1,20 @@ +// 订阅电台列表 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + } + return request( + 'POST', + `https://music.163.com/weapi/djradio/get/subed`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_subscriber.js b/WebSourceCode/src/Netease/module/dj_subscriber.js new file mode 100644 index 0000000..0760834 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_subscriber.js @@ -0,0 +1,16 @@ +// 电台详情 + +module.exports = (query, request) => { + const data = { + time: query.time || '-1', + id: query.id, + limit: query.limit || '20', + total: 'true', + } + return request('POST', `https://music.163.com/api/djradio/subscriber`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/dj_today_perfered.js b/WebSourceCode/src/Netease/module/dj_today_perfered.js new file mode 100644 index 0000000..a4881c8 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_today_perfered.js @@ -0,0 +1,18 @@ +// 电台今日优选 + +module.exports = (query, request) => { + const data = { + page: query.page || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/djradio/home/today/perfered`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_toplist.js b/WebSourceCode/src/Netease/module/dj_toplist.js new file mode 100644 index 0000000..cbe04d7 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_toplist.js @@ -0,0 +1,18 @@ +// 新晋电台榜/热门电台榜 +const typeMap = { + new: 0, + hot: 1, +} +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + offset: query.offset || 0, + type: typeMap[query.type || 'new'] || '0', //0为新晋,1为热门 + } + return request('POST', `https://music.163.com/api/djradio/toplist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/dj_toplist_hours.js b/WebSourceCode/src/Netease/module/dj_toplist_hours.js new file mode 100644 index 0000000..8c8b6a3 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_toplist_hours.js @@ -0,0 +1,14 @@ +// 电台24小时主播榜 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + // 不支持 offset + } + return request('POST', `https://music.163.com/api/dj/toplist/hours`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/dj_toplist_newcomer.js b/WebSourceCode/src/Netease/module/dj_toplist_newcomer.js new file mode 100644 index 0000000..8f28511 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_toplist_newcomer.js @@ -0,0 +1,18 @@ +// 电台新人榜 +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + offset: query.offset || 0, + } + return request( + 'POST', + `https://music.163.com/api/dj/toplist/newcomer`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_toplist_pay.js b/WebSourceCode/src/Netease/module/dj_toplist_pay.js new file mode 100644 index 0000000..5e6caf3 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_toplist_pay.js @@ -0,0 +1,18 @@ +// 付费精品 +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + // 不支持 offset + } + return request( + 'POST', + `https://music.163.com/api/djradio/toplist/pay`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/dj_toplist_popular.js b/WebSourceCode/src/Netease/module/dj_toplist_popular.js new file mode 100644 index 0000000..fcb0b33 --- /dev/null +++ b/WebSourceCode/src/Netease/module/dj_toplist_popular.js @@ -0,0 +1,14 @@ +// 电台最热主播榜 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + // 不支持 offset + } + return request('POST', `https://music.163.com/api/dj/toplist/popular`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/event.js b/WebSourceCode/src/Netease/module/event.js new file mode 100644 index 0000000..b975ab7 --- /dev/null +++ b/WebSourceCode/src/Netease/module/event.js @@ -0,0 +1,14 @@ +// 动态 + +module.exports = (query, request) => { + const data = { + pagesize: query.pagesize || 20, + lasttime: query.lasttime || -1, + } + return request('POST', `https://music.163.com/weapi/v1/event/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/event_del.js b/WebSourceCode/src/Netease/module/event_del.js new file mode 100644 index 0000000..8f17ebe --- /dev/null +++ b/WebSourceCode/src/Netease/module/event_del.js @@ -0,0 +1,13 @@ +// 删除动态 + +module.exports = (query, request) => { + const data = { + id: query.evId, + } + return request('POST', `https://music.163.com/eapi/event/delete`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/event_forward.js b/WebSourceCode/src/Netease/module/event_forward.js new file mode 100644 index 0000000..f4eddc4 --- /dev/null +++ b/WebSourceCode/src/Netease/module/event_forward.js @@ -0,0 +1,16 @@ +// 转发动态 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + forwards: query.forwards, + id: query.evId, + eventUserId: query.uid, + } + return request('POST', `https://music.163.com/weapi/event/forward`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/fm_trash.js b/WebSourceCode/src/Netease/module/fm_trash.js new file mode 100644 index 0000000..a2019d7 --- /dev/null +++ b/WebSourceCode/src/Netease/module/fm_trash.js @@ -0,0 +1,20 @@ +// 垃圾桶 + +module.exports = (query, request) => { + const data = { + songId: query.id, + } + return request( + 'POST', + `https://music.163.com/weapi/radio/trash/add?alg=RT&songId=${ + query.id + }&time=${query.time || 25}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/follow.js b/WebSourceCode/src/Netease/module/follow.js new file mode 100644 index 0000000..d14acf0 --- /dev/null +++ b/WebSourceCode/src/Netease/module/follow.js @@ -0,0 +1,17 @@ +// 关注与取消关注用户 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + query.t = query.t == 1 ? 'follow' : 'delfollow' + return request( + 'POST', + `https://music.163.com/weapi/user/${query.t}/${query.id}`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/get_userids.js b/WebSourceCode/src/Netease/module/get_userids.js new file mode 100644 index 0000000..8edcf57 --- /dev/null +++ b/WebSourceCode/src/Netease/module/get_userids.js @@ -0,0 +1,11 @@ +module.exports = (query, request) => { + const data = { + nicknames: query.nicknames, + } + return request('POST', `https://music.163.com/api/user/getUserIds`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/history_recommend_songs.js b/WebSourceCode/src/Netease/module/history_recommend_songs.js new file mode 100644 index 0000000..de282c0 --- /dev/null +++ b/WebSourceCode/src/Netease/module/history_recommend_songs.js @@ -0,0 +1,17 @@ +// 历史每日推荐歌曲 + +module.exports = (query, request) => { + query.cookie.os = 'ios' + const data = {} + return request( + 'POST', + `https://music.163.com/api/discovery/recommend/songs/history/recent`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/history_recommend_songs_detail.js b/WebSourceCode/src/Netease/module/history_recommend_songs_detail.js new file mode 100644 index 0000000..d98c869 --- /dev/null +++ b/WebSourceCode/src/Netease/module/history_recommend_songs_detail.js @@ -0,0 +1,19 @@ +// 历史每日推荐歌曲详情 + +module.exports = (query, request) => { + query.cookie.os = 'ios' + const data = { + date: query.date || '', + } + return request( + 'POST', + `https://music.163.com/api/discovery/recommend/songs/history/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/homepage_block_page.js b/WebSourceCode/src/Netease/module/homepage_block_page.js new file mode 100644 index 0000000..f214a6d --- /dev/null +++ b/WebSourceCode/src/Netease/module/homepage_block_page.js @@ -0,0 +1,19 @@ +// 首页-发现 block page +// 这个接口为移动端接口,首页-发现页,数据结构可以参考 https://github.com/hcanyz/flutter-netease-music-api/blob/master/lib/src/api/uncategorized/bean.dart#L259 HomeBlockPageWrap +// query.refresh 是否刷新数据 +module.exports = (query, request) => { + query.cookie.os = 'ios' + query.cookie.appver = '8.7.01' + const data = { refresh: query.refresh || false, cursor: query.cursor } + return request( + 'POST', + `https://music.163.com/api/homepage/block/page`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/homepage_dragon_ball.js b/WebSourceCode/src/Netease/module/homepage_dragon_ball.js new file mode 100644 index 0000000..b6a1da7 --- /dev/null +++ b/WebSourceCode/src/Netease/module/homepage_dragon_ball.js @@ -0,0 +1,21 @@ +// 首页-发现 dragon ball +// 这个接口为移动端接口,首页-发现页(每日推荐、歌单、排行榜 那些入口) +// 数据结构可以参考 https://github.com/hcanyz/flutter-netease-music-api/blob/master/lib/src/api/uncategorized/bean.dart#L290 HomeDragonBallWrap +// !需要登录或者游客登录,非登录返回 [] +module.exports = (query, request) => { + const data = {} + query.cookie.os = 'ios' + query.cookie.appver = '8.7.01' + return request( + 'POST', + `https://music.163.com/eapi/homepage/dragon/ball/static`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/homepage/dragon/ball/static', + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/hot_topic.js b/WebSourceCode/src/Netease/module/hot_topic.js new file mode 100644 index 0000000..f901492 --- /dev/null +++ b/WebSourceCode/src/Netease/module/hot_topic.js @@ -0,0 +1,14 @@ +//热门话题 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 20, + offset: query.offset || 0, + } + return request('POST', `https://music.163.com/api/act/hot`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/hug_comment.js b/WebSourceCode/src/Netease/module/hug_comment.js new file mode 100644 index 0000000..fc88f13 --- /dev/null +++ b/WebSourceCode/src/Netease/module/hug_comment.js @@ -0,0 +1,23 @@ +const { resourceTypeMap } = require('../util/config.json') +module.exports = (query, request) => { + query.cookie.os = 'ios' + query.cookie.appver = '8.7.01' + query.type = resourceTypeMap[query.type || 0] + const threadId = query.type + query.sid + const data = { + targetUserId: query.uid, + commentId: query.cid, + threadId: threadId, + } + return request( + 'POST', + `https://music.163.com/api/v2/resource/comments/hug/listener`, + data, + { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/inner_version.js b/WebSourceCode/src/Netease/module/inner_version.js new file mode 100644 index 0000000..bc9694c --- /dev/null +++ b/WebSourceCode/src/Netease/module/inner_version.js @@ -0,0 +1,15 @@ +const pkg = require('../package.json') +module.exports = (query, request) => { + return new Promise((resolve) => { + return resolve({ + code: 200, + status: 200, + body: { + code: 200, + data: { + version: pkg.version, + }, + }, + }) + }) +} diff --git a/WebSourceCode/src/Netease/module/like.js b/WebSourceCode/src/Netease/module/like.js new file mode 100644 index 0000000..e13e785 --- /dev/null +++ b/WebSourceCode/src/Netease/module/like.js @@ -0,0 +1,19 @@ +// 红心与取消红心歌曲 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + query.cookie.appver = '2.9.7' + query.like = query.like == 'false' ? false : true + const data = { + alg: 'itembased', + trackId: query.id, + like: query.like, + time: '3', + } + return request('POST', `https://music.163.com/api/radio/like`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/likelist.js b/WebSourceCode/src/Netease/module/likelist.js new file mode 100644 index 0000000..abb4680 --- /dev/null +++ b/WebSourceCode/src/Netease/module/likelist.js @@ -0,0 +1,13 @@ +// 喜欢的歌曲(无序) + +module.exports = (query, request) => { + const data = { + uid: query.uid, + } + return request('POST', `https://music.163.com/weapi/song/like/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/listentogether_end.js b/WebSourceCode/src/Netease/module/listentogether_end.js new file mode 100644 index 0000000..b5299ca --- /dev/null +++ b/WebSourceCode/src/Netease/module/listentogether_end.js @@ -0,0 +1,19 @@ +// 一起听 结束房间 + +module.exports = (query, request) => { + const data = { + roomId: query.roomId, + } + return request( + 'POST', + `http://interface.music.163.com/eapi/listen/together/end/v2`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/listen/together/end/v2', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/listentogether_heatbeat.js b/WebSourceCode/src/Netease/module/listentogether_heatbeat.js new file mode 100644 index 0000000..fc9dd65 --- /dev/null +++ b/WebSourceCode/src/Netease/module/listentogether_heatbeat.js @@ -0,0 +1,22 @@ +// 一起听 发送心跳 + +module.exports = (query, request) => { + const data = { + roomId: query.roomId, + songId: query.songId, + playStatus: query.playStatus, + progress: query.progress, + } + return request( + 'POST', + `http://interface.music.163.com/eapi/listen/together/heartbeat`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/listen/together/heartbeat', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/listentogether_play_command.js b/WebSourceCode/src/Netease/module/listentogether_play_command.js new file mode 100644 index 0000000..e236af4 --- /dev/null +++ b/WebSourceCode/src/Netease/module/listentogether_play_command.js @@ -0,0 +1,27 @@ +// 一起听 发送播放状态 + +module.exports = (query, request) => { + const data = { + roomId: query.roomId, + commandInfo: JSON.stringify({ + commandType: query.commandType, + progress: query.progress || 0, + playStatus: query.playStatus, + formerSongId: query.formerSongId, + targetSongId: query.targetSongId, + clientSeq: query.clientSeq, + }), + } + return request( + 'POST', + `http://interface.music.163.com/eapi/listen/together/play/command/report`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/listen/together/play/command/report', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/listentogether_room_check.js b/WebSourceCode/src/Netease/module/listentogether_room_check.js new file mode 100644 index 0000000..2cec49b --- /dev/null +++ b/WebSourceCode/src/Netease/module/listentogether_room_check.js @@ -0,0 +1,19 @@ +// 一起听 房间情况 + +module.exports = (query, request) => { + const data = { + roomId: query.roomId, + } + return request( + 'POST', + `http://interface.music.163.com/eapi/listen/together/room/check`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/listen/together/room/check', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/listentogether_room_create.js b/WebSourceCode/src/Netease/module/listentogether_room_create.js new file mode 100644 index 0000000..9af2a63 --- /dev/null +++ b/WebSourceCode/src/Netease/module/listentogether_room_create.js @@ -0,0 +1,19 @@ +// 一起听创建房间 + +module.exports = (query, request) => { + const data = { + refer: 'songplay_more', + } + return request( + 'POST', + `http://interface.music.163.com/eapi/listen/together/room/create`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/listen/together/room/create', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/listentogether_status.js b/WebSourceCode/src/Netease/module/listentogether_status.js new file mode 100644 index 0000000..61fd902 --- /dev/null +++ b/WebSourceCode/src/Netease/module/listentogether_status.js @@ -0,0 +1,15 @@ +// 一起听状态 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/api/listen/together/status/get`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/listentogether_sync_list_command.js b/WebSourceCode/src/Netease/module/listentogether_sync_list_command.js new file mode 100644 index 0000000..11de18c --- /dev/null +++ b/WebSourceCode/src/Netease/module/listentogether_sync_list_command.js @@ -0,0 +1,32 @@ +// 一起听 更新播放列表 + +module.exports = (query, request) => { + const data = { + roomId: query.roomId, + playlistParam: JSON.stringify({ + commandType: query.commandType, + version: [ + { + userId: query.userId, + version: query.version, + }, + ], + anchorSongId: '', + anchorPosition: -1, + randomList: query.randomList.split(','), + displayList: query.displayList.split(','), + }), + } + return request( + 'POST', + `http://interface.music.163.com/eapi/listen/together/sync/list/command/report`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/listen/together/sync/list/command/report', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/listentogether_sync_playlist_get.js b/WebSourceCode/src/Netease/module/listentogether_sync_playlist_get.js new file mode 100644 index 0000000..57fa86b --- /dev/null +++ b/WebSourceCode/src/Netease/module/listentogether_sync_playlist_get.js @@ -0,0 +1,19 @@ +// 一起听 当前列表获取 + +module.exports = (query, request) => { + const data = { + roomId: query.roomId, + } + return request( + 'POST', + `http://interface.music.163.com/eapi/listen/together/sync/playlist/get`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/listen/together/sync/playlist/get', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/login.js b/WebSourceCode/src/Netease/module/login.js new file mode 100644 index 0000000..2a43a78 --- /dev/null +++ b/WebSourceCode/src/Netease/module/login.js @@ -0,0 +1,43 @@ +// 邮箱登录 + +const crypto = require('crypto') + +module.exports = async (query, request) => { + query.cookie.os = 'ios' + query.cookie.appver = '8.7.01' + const data = { + username: query.email, + password: + query.md5_password || + crypto.createHash('md5').update(query.password).digest('hex'), + rememberLogin: 'true', + } + let result = await request('POST', `https://music.163.com/api/login`, data, { + crypto: 'weapi', + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) + if (result.body.code === 502) { + return { + status: 200, + body: { + msg: '账号或密码错误', + code: 502, + message: '账号或密码错误', + }, + } + } + if (result.body.code === 200) { + result = { + status: 200, + body: { + ...result.body, + cookie: result.cookie.join(';'), + }, + cookie: result.cookie, + } + } + return result +} diff --git a/WebSourceCode/src/Netease/module/login_cellphone.js b/WebSourceCode/src/Netease/module/login_cellphone.js new file mode 100644 index 0000000..e7374b4 --- /dev/null +++ b/WebSourceCode/src/Netease/module/login_cellphone.js @@ -0,0 +1,42 @@ +// 手机登录 + +const crypto = require('crypto') + +module.exports = async (query, request) => { + query.cookie.os = 'ios' + query.cookie.appver = '8.7.01' + const data = { + phone: query.phone, + countrycode: query.countrycode || '86', + captcha: query.captcha, + [query.captcha ? 'captcha' : 'password']: query.captcha + ? query.captcha + : query.md5_password || + crypto.createHash('md5').update(query.password).digest('hex'), + rememberLogin: 'true', + } + let result = await request( + 'POST', + `https://music.163.com/weapi/login/cellphone`, + data, + { + crypto: 'weapi', + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + + if (result.body.code === 200) { + result = { + status: 200, + body: { + ...result.body, + cookie: result.cookie.join(';'), + }, + cookie: result.cookie, + } + } + return result +} diff --git a/WebSourceCode/src/Netease/module/login_qr_check.js b/WebSourceCode/src/Netease/module/login_qr_check.js new file mode 100644 index 0000000..9c396e2 --- /dev/null +++ b/WebSourceCode/src/Netease/module/login_qr_check.js @@ -0,0 +1,34 @@ +module.exports = async (query, request) => { + const data = { + key: query.key, + type: 1, + } + try { + let result = await request( + 'POST', + `https://music.163.com/weapi/login/qrcode/client/login`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + result = { + status: 200, + body: { + ...result.body, + cookie: result.cookie.join(';'), + }, + cookie: result.cookie, + } + return result + } catch (error) { + return { + status: 200, + body: {}, + cookie: result.cookie, + } + } +} diff --git a/WebSourceCode/src/Netease/module/login_qr_create.js b/WebSourceCode/src/Netease/module/login_qr_create.js new file mode 100644 index 0000000..aeb6943 --- /dev/null +++ b/WebSourceCode/src/Netease/module/login_qr_create.js @@ -0,0 +1,18 @@ +const QRCode = require('qrcode') + +module.exports = (query, request) => { + return new Promise(async (resolve) => { + const url = `https://music.163.com/login?codekey=${query.key}` + return resolve({ + code: 200, + status: 200, + body: { + code: 200, + data: { + qrurl: url, + qrimg: query.qrimg ? await QRCode.toDataURL(url) : '', + }, + }, + }) + }) +} diff --git a/WebSourceCode/src/Netease/module/login_qr_key.js b/WebSourceCode/src/Netease/module/login_qr_key.js new file mode 100644 index 0000000..bbee4be --- /dev/null +++ b/WebSourceCode/src/Netease/module/login_qr_key.js @@ -0,0 +1,24 @@ +module.exports = async (query, request) => { + const data = { + type: 1, + } + const result = await request( + 'POST', + `https://music.163.com/weapi/login/qrcode/unikey`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + return { + status: 200, + body: { + data: result.body, + code: 200, + }, + cookie: result.cookie, + } +} diff --git a/WebSourceCode/src/Netease/module/login_refresh.js b/WebSourceCode/src/Netease/module/login_refresh.js new file mode 100644 index 0000000..5649ae6 --- /dev/null +++ b/WebSourceCode/src/Netease/module/login_refresh.js @@ -0,0 +1,27 @@ +// 登录刷新 + +module.exports = async (query, request) => { + let result = await request( + 'POST', + `https://music.163.com/weapi/login/token/refresh`, + {}, + { + crypto: 'weapi', + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + if (result.body.code === 200) { + result = { + status: 200, + body: { + ...result.body, + cookie: result.cookie.join(';'), + }, + cookie: result.cookie, + } + } + return result +} diff --git a/WebSourceCode/src/Netease/module/login_status.js b/WebSourceCode/src/Netease/module/login_status.js new file mode 100644 index 0000000..23286bc --- /dev/null +++ b/WebSourceCode/src/Netease/module/login_status.js @@ -0,0 +1,26 @@ +module.exports = async (query, request) => { + const data = {} + let result = await request( + 'POST', + `https://music.163.com/weapi/w/nuser/account/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + if (result.body.code === 200) { + result = { + status: 200, + body: { + data: { + ...result.body, + }, + }, + cookie: result.cookie, + } + } + return result +} diff --git a/WebSourceCode/src/Netease/module/logout.js b/WebSourceCode/src/Netease/module/logout.js new file mode 100644 index 0000000..a92ce47 --- /dev/null +++ b/WebSourceCode/src/Netease/module/logout.js @@ -0,0 +1,16 @@ +// 退出登录 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/logout`, + {}, + { + crypto: 'weapi', + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/lyric.js b/WebSourceCode/src/Netease/module/lyric.js new file mode 100644 index 0000000..b9bec0a --- /dev/null +++ b/WebSourceCode/src/Netease/module/lyric.js @@ -0,0 +1,24 @@ +// 歌词 + +module.exports = (query, request) => { + query.cookie.os = 'ios' + + const data = { + id: query.id, + tv: -1, + lv: -1, + rv: -1, + kv: -1, + } + return request( + 'POST', + `https://music.163.com/api/song/lyric?_nmclfl=1`, + data, + { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/lyric_new.js b/WebSourceCode/src/Netease/module/lyric_new.js new file mode 100644 index 0000000..91752ed --- /dev/null +++ b/WebSourceCode/src/Netease/module/lyric_new.js @@ -0,0 +1,27 @@ +// 新版歌词 - 包含逐字歌词 + +module.exports = (query, request) => { + const data = { + id: query.id, + cp: false, + tv: 0, + lv: 0, + rv: 0, + kv: 0, + yv: 0, + ytv: 0, + yrv: 0, + } + return request( + 'POST', + `https://interface3.music.163.com/eapi/song/lyric/v1`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/song/lyric/v1', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/mlog_music_rcmd.js b/WebSourceCode/src/Netease/module/mlog_music_rcmd.js new file mode 100644 index 0000000..a4e00bb --- /dev/null +++ b/WebSourceCode/src/Netease/module/mlog_music_rcmd.js @@ -0,0 +1,23 @@ +// 歌曲相关视频 + +module.exports = (query, request) => { + const data = { + id: query.mvid || 0, + type: 2, + rcmdType: 20, + limit: query.limit || 10, + extInfo: JSON.stringify({ songId: query.songid }), + } + return request( + 'POST', + `https://interface.music.163.com/eapi/mlog/rcmd/feed/list`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/mlog/rcmd/feed/list', + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/mlog_to_video.js b/WebSourceCode/src/Netease/module/mlog_to_video.js new file mode 100644 index 0000000..54b279e --- /dev/null +++ b/WebSourceCode/src/Netease/module/mlog_to_video.js @@ -0,0 +1,18 @@ +// 将mlog id转为video id + +module.exports = (query, request) => { + const data = { + mlogId: query.id, + } + return request( + 'POST', + `https://music.163.com/weapi/mlog/video/convert/id`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/mlog_url.js b/WebSourceCode/src/Netease/module/mlog_url.js new file mode 100644 index 0000000..f7223e0 --- /dev/null +++ b/WebSourceCode/src/Netease/module/mlog_url.js @@ -0,0 +1,15 @@ +// mlog链接 + +module.exports = (query, request) => { + const data = { + id: query.id, + resolution: query.res || 1080, + type: 1, + } + return request('POST', `https://music.163.com/weapi/mlog/detail/v1`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/msg_comments.js b/WebSourceCode/src/Netease/module/msg_comments.js new file mode 100644 index 0000000..76bab8f --- /dev/null +++ b/WebSourceCode/src/Netease/module/msg_comments.js @@ -0,0 +1,22 @@ +// 评论 + +module.exports = (query, request) => { + const data = { + beforeTime: query.before || '-1', + limit: query.limit || 30, + total: 'true', + uid: query.uid, + } + + return request( + 'POST', + `https://music.163.com/api/v1/user/comments/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/msg_forwards.js b/WebSourceCode/src/Netease/module/msg_forwards.js new file mode 100644 index 0000000..f89dc98 --- /dev/null +++ b/WebSourceCode/src/Netease/module/msg_forwards.js @@ -0,0 +1,15 @@ +// @我 + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + limit: query.limit || 30, + total: 'true', + } + return request('POST', `https://music.163.com/api/forwards/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/msg_notices.js b/WebSourceCode/src/Netease/module/msg_notices.js new file mode 100644 index 0000000..9208168 --- /dev/null +++ b/WebSourceCode/src/Netease/module/msg_notices.js @@ -0,0 +1,14 @@ +// 通知 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + time: query.lasttime || -1, + } + return request('POST', `https://music.163.com/api/msg/notices`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/msg_private.js b/WebSourceCode/src/Netease/module/msg_private.js new file mode 100644 index 0000000..a30751c --- /dev/null +++ b/WebSourceCode/src/Netease/module/msg_private.js @@ -0,0 +1,15 @@ +// 私信 + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + limit: query.limit || 30, + total: 'true', + } + return request('POST', `https://music.163.com/api/msg/private/users`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/msg_private_history.js b/WebSourceCode/src/Netease/module/msg_private_history.js new file mode 100644 index 0000000..0a83b02 --- /dev/null +++ b/WebSourceCode/src/Netease/module/msg_private_history.js @@ -0,0 +1,21 @@ +// 私信内容 + +module.exports = (query, request) => { + const data = { + userId: query.uid, + limit: query.limit || 30, + time: query.before || 0, + total: 'true', + } + return request( + 'POST', + `https://music.163.com/api/msg/private/history`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/msg_recentcontact.js b/WebSourceCode/src/Netease/module/msg_recentcontact.js new file mode 100644 index 0000000..cb17c3a --- /dev/null +++ b/WebSourceCode/src/Netease/module/msg_recentcontact.js @@ -0,0 +1,16 @@ +// 最近联系 + +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/api/msg/recentcontact/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/music_first_listen_info.js b/WebSourceCode/src/Netease/module/music_first_listen_info.js new file mode 100644 index 0000000..c1f58f8 --- /dev/null +++ b/WebSourceCode/src/Netease/module/music_first_listen_info.js @@ -0,0 +1,18 @@ +// 回忆坐标 + +module.exports = (query, request) => { + const data = { + songId: query.id, + } + return request( + 'POST', + `https://interface3.music.163.com/api/content/activity/music/first/listen/info`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/musician_cloudbean.js b/WebSourceCode/src/Netease/module/musician_cloudbean.js new file mode 100644 index 0000000..e85a285 --- /dev/null +++ b/WebSourceCode/src/Netease/module/musician_cloudbean.js @@ -0,0 +1,11 @@ +// 账号云豆数 + +module.exports = (query, request) => { + const data = {} + return request('POST', `https://music.163.com/weapi/cloudbean/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/musician_cloudbean_obtain.js b/WebSourceCode/src/Netease/module/musician_cloudbean_obtain.js new file mode 100644 index 0000000..2320278 --- /dev/null +++ b/WebSourceCode/src/Netease/module/musician_cloudbean_obtain.js @@ -0,0 +1,19 @@ +// 领取云豆 + +module.exports = (query, request) => { + const data = { + userMissionId: query.id, + period: query.period, + } + return request( + 'POST', + `https://music.163.com/weapi/nmusician/workbench/mission/reward/obtain/new`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/musician_data_overview.js b/WebSourceCode/src/Netease/module/musician_data_overview.js new file mode 100644 index 0000000..b96d03e --- /dev/null +++ b/WebSourceCode/src/Netease/module/musician_data_overview.js @@ -0,0 +1,16 @@ +// 音乐人数据概况 + +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/weapi/creator/musician/statistic/data/overview/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/musician_play_trend.js b/WebSourceCode/src/Netease/module/musician_play_trend.js new file mode 100644 index 0000000..d8f14fe --- /dev/null +++ b/WebSourceCode/src/Netease/module/musician_play_trend.js @@ -0,0 +1,19 @@ +// 音乐人歌曲播放趋势 + +module.exports = (query, request) => { + const data = { + startTime: query.startTime, + endTime: query.endTime, + } + return request( + 'POST', + `https://music.163.com/weapi/creator/musician/play/count/statistic/data/trend/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/musician_sign.js b/WebSourceCode/src/Netease/module/musician_sign.js new file mode 100644 index 0000000..6d5717a --- /dev/null +++ b/WebSourceCode/src/Netease/module/musician_sign.js @@ -0,0 +1,16 @@ +// 音乐人签到 + +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/weapi/creator/user/access`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/musician_tasks.js b/WebSourceCode/src/Netease/module/musician_tasks.js new file mode 100644 index 0000000..cb98c93 --- /dev/null +++ b/WebSourceCode/src/Netease/module/musician_tasks.js @@ -0,0 +1,16 @@ +// 获取音乐人任务 + +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/weapi/nmusician/workbench/mission/cycle/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/musician_tasks_new.js b/WebSourceCode/src/Netease/module/musician_tasks_new.js new file mode 100644 index 0000000..fd4953e --- /dev/null +++ b/WebSourceCode/src/Netease/module/musician_tasks_new.js @@ -0,0 +1,16 @@ +// 获取音乐人任务 + +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/api/nmusician/workbench/mission/stage/list `, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/mv_all.js b/WebSourceCode/src/Netease/module/mv_all.js new file mode 100644 index 0000000..85c1c46 --- /dev/null +++ b/WebSourceCode/src/Netease/module/mv_all.js @@ -0,0 +1,20 @@ +// 全部MV + +module.exports = (query, request) => { + const data = { + tags: JSON.stringify({ + 地区: query.area || '全部', + 类型: query.type || '全部', + 排序: query.order || '上升最快', + }), + offset: query.offset || 0, + total: 'true', + limit: query.limit || 30, + } + return request('POST', `https://interface.music.163.com/api/mv/all`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/mv_detail.js b/WebSourceCode/src/Netease/module/mv_detail.js new file mode 100644 index 0000000..e1b0152 --- /dev/null +++ b/WebSourceCode/src/Netease/module/mv_detail.js @@ -0,0 +1,13 @@ +// MV详情 + +module.exports = (query, request) => { + const data = { + id: query.mvid, + } + return request('POST', `https://music.163.com/api/v1/mv/detail`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/mv_detail_info.js b/WebSourceCode/src/Netease/module/mv_detail_info.js new file mode 100644 index 0000000..b758a46 --- /dev/null +++ b/WebSourceCode/src/Netease/module/mv_detail_info.js @@ -0,0 +1,19 @@ +// MV 点赞转发评论数数据 + +module.exports = (query, request) => { + const data = { + threadid: `R_MV_5_${query.mvid}`, + composeliked: true, + } + return request( + 'POST', + `https://music.163.com/api/comment/commentthread/info`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/mv_exclusive_rcmd.js b/WebSourceCode/src/Netease/module/mv_exclusive_rcmd.js new file mode 100644 index 0000000..aee8b2d --- /dev/null +++ b/WebSourceCode/src/Netease/module/mv_exclusive_rcmd.js @@ -0,0 +1,19 @@ +// 网易出品 + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + limit: query.limit || 30, + } + return request( + 'POST', + `https://interface.music.163.com/api/mv/exclusive/rcmd`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/mv_first.js b/WebSourceCode/src/Netease/module/mv_first.js new file mode 100644 index 0000000..ae61ad9 --- /dev/null +++ b/WebSourceCode/src/Netease/module/mv_first.js @@ -0,0 +1,21 @@ +// 最新MV + +module.exports = (query, request) => { + const data = { + // 'offset': query.offset || 0, + area: query.area || '', + limit: query.limit || 30, + total: true, + } + return request( + 'POST', + `https://interface.music.163.com/weapi/mv/first`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/mv_sub.js b/WebSourceCode/src/Netease/module/mv_sub.js new file mode 100644 index 0000000..249998e --- /dev/null +++ b/WebSourceCode/src/Netease/module/mv_sub.js @@ -0,0 +1,15 @@ +// 收藏与取消收藏MV + +module.exports = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub' + const data = { + mvId: query.mvid, + mvIds: '["' + query.mvid + '"]', + } + return request('POST', `https://music.163.com/weapi/mv/${query.t}`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/mv_sublist.js b/WebSourceCode/src/Netease/module/mv_sublist.js new file mode 100644 index 0000000..2118c41 --- /dev/null +++ b/WebSourceCode/src/Netease/module/mv_sublist.js @@ -0,0 +1,20 @@ +// 已收藏MV列表 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 25, + offset: query.offset || 0, + total: true, + } + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/allvideo/sublist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/mv_url.js b/WebSourceCode/src/Netease/module/mv_url.js new file mode 100644 index 0000000..1b8c518 --- /dev/null +++ b/WebSourceCode/src/Netease/module/mv_url.js @@ -0,0 +1,19 @@ +// MV链接 + +module.exports = (query, request) => { + const data = { + id: query.id, + r: query.r || 1080, + } + return request( + 'POST', + `https://music.163.com/weapi/song/enhance/play/mv/url`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/nickname_check.js b/WebSourceCode/src/Netease/module/nickname_check.js new file mode 100644 index 0000000..a51f82c --- /dev/null +++ b/WebSourceCode/src/Netease/module/nickname_check.js @@ -0,0 +1,16 @@ +module.exports = (query, request) => { + const data = { + nickname: query.nickname, + } + return request( + 'POST', + `https://music.163.com/api/nickname/duplicated`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/personal_fm.js b/WebSourceCode/src/Netease/module/personal_fm.js new file mode 100644 index 0000000..72ee1fb --- /dev/null +++ b/WebSourceCode/src/Netease/module/personal_fm.js @@ -0,0 +1,15 @@ +// 私人FM + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/radio/get`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/personalized.js b/WebSourceCode/src/Netease/module/personalized.js new file mode 100644 index 0000000..38a44ca --- /dev/null +++ b/WebSourceCode/src/Netease/module/personalized.js @@ -0,0 +1,21 @@ +// 推荐歌单 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + // offset: query.offset || 0, + total: true, + n: 1000, + } + return request( + 'POST', + `https://music.163.com/weapi/personalized/playlist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/personalized_djprogram.js b/WebSourceCode/src/Netease/module/personalized_djprogram.js new file mode 100644 index 0000000..aa31dd3 --- /dev/null +++ b/WebSourceCode/src/Netease/module/personalized_djprogram.js @@ -0,0 +1,15 @@ +// 推荐电台 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/personalized/djprogram`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/personalized_mv.js b/WebSourceCode/src/Netease/module/personalized_mv.js new file mode 100644 index 0000000..362c9b3 --- /dev/null +++ b/WebSourceCode/src/Netease/module/personalized_mv.js @@ -0,0 +1,15 @@ +// 推荐MV + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/personalized/mv`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/personalized_newsong.js b/WebSourceCode/src/Netease/module/personalized_newsong.js new file mode 100644 index 0000000..2af12a3 --- /dev/null +++ b/WebSourceCode/src/Netease/module/personalized_newsong.js @@ -0,0 +1,21 @@ +// 推荐新歌 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + type: 'recommend', + limit: query.limit || 10, + areaId: query.areaId || 0, + } + return request( + 'POST', + `https://music.163.com/api/personalized/newsong`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/personalized_privatecontent.js b/WebSourceCode/src/Netease/module/personalized_privatecontent.js new file mode 100644 index 0000000..5633738 --- /dev/null +++ b/WebSourceCode/src/Netease/module/personalized_privatecontent.js @@ -0,0 +1,15 @@ +// 独家放送 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/personalized/privatecontent`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/personalized_privatecontent_list.js b/WebSourceCode/src/Netease/module/personalized_privatecontent_list.js new file mode 100644 index 0000000..f9ff49e --- /dev/null +++ b/WebSourceCode/src/Netease/module/personalized_privatecontent_list.js @@ -0,0 +1,20 @@ +// 独家放送列表 + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + total: 'true', + limit: query.limit || 60, + } + return request( + 'POST', + `https://music.163.com/api/v2/privatecontent/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/pl_count.js b/WebSourceCode/src/Netease/module/pl_count.js new file mode 100644 index 0000000..78423c7 --- /dev/null +++ b/WebSourceCode/src/Netease/module/pl_count.js @@ -0,0 +1,10 @@ +// 数字专辑-新碟上架 +module.exports = (query, request) => { + const data = {} + return request('POST', `https://music.163.com/weapi/pl/count`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/playlist_catlist.js b/WebSourceCode/src/Netease/module/playlist_catlist.js new file mode 100644 index 0000000..9b148f6 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_catlist.js @@ -0,0 +1,15 @@ +// 全部歌单分类 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/playlist/catalogue`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_cover_update.js b/WebSourceCode/src/Netease/module/playlist_cover_update.js new file mode 100644 index 0000000..62142c8 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_cover_update.js @@ -0,0 +1,37 @@ +const uploadPlugin = require('../plugins/upload') +module.exports = async (query, request) => { + if (!query.imgFile) { + return { + status: 400, + body: { + code: 400, + msg: 'imgFile is required', + }, + } + } + const uploadInfo = await uploadPlugin(query, request) + const res = await request( + 'POST', + `https://music.163.com/weapi/playlist/cover/update`, + { + id: query.id, + coverImgId: uploadInfo.imgId, + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + return { + status: 200, + body: { + code: 200, + data: { + ...uploadInfo, + ...res.body, + }, + }, + } +} diff --git a/WebSourceCode/src/Netease/module/playlist_create.js b/WebSourceCode/src/Netease/module/playlist_create.js new file mode 100644 index 0000000..f33f5f0 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_create.js @@ -0,0 +1,16 @@ +// 创建歌单 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + name: query.name, + privacy: query.privacy, //0 为普通歌单,10 为隐私歌单 + type: query.type || 'NORMAL', // NORMAL|VIDEO|SHARED + } + return request('POST', `https://music.163.com/api/playlist/create`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/playlist_delete.js b/WebSourceCode/src/Netease/module/playlist_delete.js new file mode 100644 index 0000000..d388a0e --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_delete.js @@ -0,0 +1,14 @@ +// 删除歌单 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + ids: '[' + query.id + ']', + } + return request('POST', `https://music.163.com/weapi/playlist/remove`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/playlist_desc_update.js b/WebSourceCode/src/Netease/module/playlist_desc_update.js new file mode 100644 index 0000000..bebd9bb --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_desc_update.js @@ -0,0 +1,20 @@ +// 更新歌单描述 + +module.exports = (query, request) => { + const data = { + id: query.id, + desc: query.desc, + } + return request( + 'POST', + `https://interface3.music.163.com/eapi/playlist/desc/update`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/playlist/desc/update', + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_detail.js b/WebSourceCode/src/Netease/module/playlist_detail.js new file mode 100644 index 0000000..39718f7 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_detail.js @@ -0,0 +1,15 @@ +// 歌单详情 + +module.exports = (query, request) => { + const data = { + id: query.id, + n: 100000, + s: query.s || 8, + } + return request('POST', `https://music.163.com/api/v6/playlist/detail`, data, { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/playlist_detail_dynamic.js b/WebSourceCode/src/Netease/module/playlist_detail_dynamic.js new file mode 100644 index 0000000..e3362d2 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_detail_dynamic.js @@ -0,0 +1,20 @@ +// 初始化名字 + +module.exports = (query, request) => { + const data = { + id: query.id, + n: 100000, + s: query.s || 8, + } + return request( + 'POST', + `https://music.163.com/api/playlist/detail/dynamic`, + data, + { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_highquality_tags.js b/WebSourceCode/src/Netease/module/playlist_highquality_tags.js new file mode 100644 index 0000000..0848c52 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_highquality_tags.js @@ -0,0 +1,15 @@ +// 精品歌单 tags +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/api/playlist/highquality/tags`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_hot.js b/WebSourceCode/src/Netease/module/playlist_hot.js new file mode 100644 index 0000000..6c085e4 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_hot.js @@ -0,0 +1,15 @@ +// 热门歌单分类 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/playlist/hottags`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_mylike.js b/WebSourceCode/src/Netease/module/playlist_mylike.js new file mode 100644 index 0000000..779b507 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_mylike.js @@ -0,0 +1,17 @@ +module.exports = (query, request) => { + const data = { + time: query.time || '-1', + limit: query.limit || '12', + } + return request( + 'POST', + `https://music.163.com/api/mlog/playlist/mylike/bytime/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_name_update.js b/WebSourceCode/src/Netease/module/playlist_name_update.js new file mode 100644 index 0000000..ae53946 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_name_update.js @@ -0,0 +1,20 @@ +// 更新歌单名 + +module.exports = (query, request) => { + const data = { + id: query.id, + name: query.name, + } + return request( + 'POST', + `https://interface3.music.163.com/eapi/playlist/update/name`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/playlist/update/name', + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_order_update.js b/WebSourceCode/src/Netease/module/playlist_order_update.js new file mode 100644 index 0000000..268c6ea --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_order_update.js @@ -0,0 +1,19 @@ +// 编辑歌单顺序 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + ids: query.ids, + } + return request( + 'POST', + `https://music.163.com/api/playlist/order/update`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_privacy.js b/WebSourceCode/src/Netease/module/playlist_privacy.js new file mode 100644 index 0000000..ded2819 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_privacy.js @@ -0,0 +1,20 @@ +// 公开隐私歌单 + +module.exports = (query, request) => { + const data = { + id: query.id, + privacy: 0, + } + return request( + 'POST', + `https://interface.music.163.com/eapi/playlist/update/privacy`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/playlist/update/privacy', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_subscribe.js b/WebSourceCode/src/Netease/module/playlist_subscribe.js new file mode 100644 index 0000000..e0cce16 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_subscribe.js @@ -0,0 +1,19 @@ +// 收藏与取消收藏歌单 + +module.exports = (query, request) => { + query.t = query.t == 1 ? 'subscribe' : 'unsubscribe' + const data = { + id: query.id, + } + return request( + 'POST', + `https://music.163.com/weapi/playlist/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_subscribers.js b/WebSourceCode/src/Netease/module/playlist_subscribers.js new file mode 100644 index 0000000..04260cb --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_subscribers.js @@ -0,0 +1,20 @@ +// 歌单收藏者 + +module.exports = (query, request) => { + const data = { + id: query.id, + limit: query.limit || 20, + offset: query.offset || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/playlist/subscribers`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_tags_update.js b/WebSourceCode/src/Netease/module/playlist_tags_update.js new file mode 100644 index 0000000..44de8c6 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_tags_update.js @@ -0,0 +1,20 @@ +// 更新歌单标签 + +module.exports = (query, request) => { + const data = { + id: query.id, + tags: query.tags, + } + return request( + 'POST', + `https://interface3.music.163.com/eapi/playlist/tags/update`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/playlist/tags/update', + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_track_add.js b/WebSourceCode/src/Netease/module/playlist_track_add.js new file mode 100644 index 0000000..c2391f3 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_track_add.js @@ -0,0 +1,20 @@ +module.exports = async (query, request) => { + query.cookie.os = 'pc' + query.ids = query.ids || '' + const data = { + id: query.pid, + tracks: JSON.stringify( + query.ids.split(',').map((item) => { + return { type: 3, id: item } + }), + ), + } + console.log(data) + + return request('POST', `https://music.163.com/api/playlist/track/add`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/playlist_track_all.js b/WebSourceCode/src/Netease/module/playlist_track_all.js new file mode 100644 index 0000000..12bd9df --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_track_all.js @@ -0,0 +1,43 @@ +// 通过传过来的歌单id拿到所有歌曲数据 +// 支持传递参数limit来限制获取歌曲的数据数量 例如: /playlist/track/all?id=7044354223&limit=10 + +module.exports = (query, request) => { + const data = { + id: query.id, + n: 100000, + s: query.s || 8, + } + //不放在data里面避免请求带上无用的数据 + let limit = parseInt(query.limit) || Infinity + let offset = parseInt(query.offset) || 0 + + return request('POST', `https://music.163.com/api/v6/playlist/detail`, data, { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }).then((res) => { + let trackIds = res.body.playlist.trackIds + let idsData = { + c: + '[' + + trackIds + .slice(offset, offset + limit) + .map((item) => '{"id":' + item.id + '}') + .join(',') + + ']', + } + + return request( + 'POST', + `https://music.163.com/api/v3/song/detail`, + idsData, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + }) +} diff --git a/WebSourceCode/src/Netease/module/playlist_track_delete.js b/WebSourceCode/src/Netease/module/playlist_track_delete.js new file mode 100644 index 0000000..54ef409 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_track_delete.js @@ -0,0 +1,26 @@ +// 收藏单曲到歌单 从歌单删除歌曲 + +module.exports = async (query, request) => { + query.cookie.os = 'pc' + query.ids = query.ids || '' + const data = { + id: query.id, + tracks: JSON.stringify( + query.ids.split(',').map((item) => { + return { type: 3, id: item } + }), + ), + } + + return request( + 'POST', + `https://music.163.com/api/playlist/track/delete`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_tracks.js b/WebSourceCode/src/Netease/module/playlist_tracks.js new file mode 100644 index 0000000..716b8fe --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_tracks.js @@ -0,0 +1,56 @@ +// 收藏单曲到歌单 从歌单删除歌曲 + +module.exports = async (query, request) => { + // query.cookie.os = 'pc' + const tracks = query.tracks.split(',') + const data = { + op: query.op, // del,add + pid: query.pid, // 歌单id + trackIds: JSON.stringify(tracks), // 歌曲id + imme: 'true', + } + + try { + const res = await request( + 'POST', + `https://music.163.com/weapi/playlist/manipulate/tracks`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + return { + status: 200, + body: { + ...res, + }, + } + } catch (error) { + if (error.body.code === 512) { + return request( + 'POST', + `https://music.163.com/api/playlist/manipulate/tracks`, + { + op: query.op, // del,add + pid: query.pid, // 歌单id + trackIds: JSON.stringify([...tracks, ...tracks]), + imme: 'true', + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + } else { + return { + status: 200, + body: error.body, + } + } + } +} diff --git a/WebSourceCode/src/Netease/module/playlist_update.js b/WebSourceCode/src/Netease/module/playlist_update.js new file mode 100644 index 0000000..085d195 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_update.js @@ -0,0 +1,18 @@ +// 编辑歌单 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + query.desc = query.desc || '' + query.tags = query.tags || '' + const data = { + '/api/playlist/desc/update': `{"id":${query.id},"desc":"${query.desc}"}`, + '/api/playlist/tags/update': `{"id":${query.id},"tags":"${query.tags}"}`, + '/api/playlist/update/name': `{"id":${query.id},"name":"${query.name}"}`, + } + return request('POST', `https://music.163.com/weapi/batch`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/playlist_update_playcount.js b/WebSourceCode/src/Netease/module/playlist_update_playcount.js new file mode 100644 index 0000000..4bf5e30 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_update_playcount.js @@ -0,0 +1,18 @@ +// 歌单打卡 + +module.exports = (query, request) => { + const data = { + id: query.id, + } + return request( + 'POST', + `https://music.163.com/api/playlist/update/playcount`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playlist_video_recent.js b/WebSourceCode/src/Netease/module/playlist_video_recent.js new file mode 100644 index 0000000..1430211 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playlist_video_recent.js @@ -0,0 +1,14 @@ +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/api/playlist/video/recent`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playmode_intelligence_list.js b/WebSourceCode/src/Netease/module/playmode_intelligence_list.js new file mode 100644 index 0000000..81b61ba --- /dev/null +++ b/WebSourceCode/src/Netease/module/playmode_intelligence_list.js @@ -0,0 +1,22 @@ +// 智能播放 + +module.exports = (query, request) => { + const data = { + songId: query.id, + type: 'fromPlayOne', + playlistId: query.pid, + startMusicId: query.sid || query.id, + count: query.count || 1, + } + return request( + 'POST', + `https://music.163.com/weapi/playmode/intelligence/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/playmode_song_vector.js b/WebSourceCode/src/Netease/module/playmode_song_vector.js new file mode 100644 index 0000000..0eb72a0 --- /dev/null +++ b/WebSourceCode/src/Netease/module/playmode_song_vector.js @@ -0,0 +1,19 @@ +// 云随机播放 +const crypto = require('crypto') +module.exports = (query, request) => { + const data = { + ids: query.ids, + } + return request( + 'POST', + `https://interface3.music.163.com/eapi/playmode/song/vector/get`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/playmode/song/vector/get', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/program_recommend.js b/WebSourceCode/src/Netease/module/program_recommend.js new file mode 100644 index 0000000..bd63e7a --- /dev/null +++ b/WebSourceCode/src/Netease/module/program_recommend.js @@ -0,0 +1,20 @@ +// 推荐节目 + +module.exports = (query, request) => { + const data = { + cateId: query.type, + limit: query.limit || 10, + offset: query.offset || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/program/recommend/v1`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/rebind.js b/WebSourceCode/src/Netease/module/rebind.js new file mode 100644 index 0000000..053bcba --- /dev/null +++ b/WebSourceCode/src/Netease/module/rebind.js @@ -0,0 +1,21 @@ +// 更换手机 + +module.exports = (query, request) => { + const data = { + captcha: query.captcha, + phone: query.phone, + oldcaptcha: query.oldcaptcha, + ctcode: query.ctcode || '86', + } + return request( + 'POST', + `https://music.163.com/api/user/replaceCellphone`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/recommend_resource.js b/WebSourceCode/src/Netease/module/recommend_resource.js new file mode 100644 index 0000000..3465087 --- /dev/null +++ b/WebSourceCode/src/Netease/module/recommend_resource.js @@ -0,0 +1,15 @@ +// 每日推荐歌单 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/discovery/recommend/resource`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/recommend_songs.js b/WebSourceCode/src/Netease/module/recommend_songs.js new file mode 100644 index 0000000..f83481e --- /dev/null +++ b/WebSourceCode/src/Netease/module/recommend_songs.js @@ -0,0 +1,17 @@ +// 每日推荐歌曲 + +module.exports = (query, request) => { + query.cookie.os = 'ios' + const data = {} + return request( + 'POST', + `https://music.163.com/api/v3/discovery/recommend/songs`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/record_recent_album.js b/WebSourceCode/src/Netease/module/record_recent_album.js new file mode 100644 index 0000000..804bc19 --- /dev/null +++ b/WebSourceCode/src/Netease/module/record_recent_album.js @@ -0,0 +1,16 @@ +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + } + return request( + 'POST', + `https://music.163.com/api/play-record/album/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/record_recent_dj.js b/WebSourceCode/src/Netease/module/record_recent_dj.js new file mode 100644 index 0000000..6bd6062 --- /dev/null +++ b/WebSourceCode/src/Netease/module/record_recent_dj.js @@ -0,0 +1,16 @@ +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + } + return request( + 'POST', + `https://music.163.com/api/play-record/djradio/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/record_recent_playlist.js b/WebSourceCode/src/Netease/module/record_recent_playlist.js new file mode 100644 index 0000000..d9a7d3d --- /dev/null +++ b/WebSourceCode/src/Netease/module/record_recent_playlist.js @@ -0,0 +1,16 @@ +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + } + return request( + 'POST', + `https://music.163.com/api/play-record/playlist/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/record_recent_song.js b/WebSourceCode/src/Netease/module/record_recent_song.js new file mode 100644 index 0000000..275caaa --- /dev/null +++ b/WebSourceCode/src/Netease/module/record_recent_song.js @@ -0,0 +1,16 @@ +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + } + return request( + 'POST', + `https://music.163.com/api/play-record/song/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/record_recent_video.js b/WebSourceCode/src/Netease/module/record_recent_video.js new file mode 100644 index 0000000..5a22b96 --- /dev/null +++ b/WebSourceCode/src/Netease/module/record_recent_video.js @@ -0,0 +1,16 @@ +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + } + return request( + 'POST', + `https://music.163.com/api/play-record/newvideo/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/record_recent_voice.js b/WebSourceCode/src/Netease/module/record_recent_voice.js new file mode 100644 index 0000000..43f5b1c --- /dev/null +++ b/WebSourceCode/src/Netease/module/record_recent_voice.js @@ -0,0 +1,16 @@ +module.exports = (query, request) => { + const data = { + limit: query.limit || 100, + } + return request( + 'POST', + `https://music.163.com/api/play-record/voice/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/register_anonimous.js b/WebSourceCode/src/Netease/module/register_anonimous.js new file mode 100644 index 0000000..b735df3 --- /dev/null +++ b/WebSourceCode/src/Netease/module/register_anonimous.js @@ -0,0 +1,48 @@ +// 游客登录 +const crypto = require('crypto') +const ID_XOR_KEY_1 = Buffer.from('3go8&$833h0k(2)2') + +function cloudmusic_dll_encode_id(some_id) { + const xored = Buffer.from( + [...some_id].map( + (c, idx) => c.charCodeAt(0) ^ ID_XOR_KEY_1[idx % ID_XOR_KEY_1.length], + ), + ) + const digest = crypto.createHash('md5').update(xored).digest() + return digest.toString('base64') +} + +module.exports = async (query, request) => { + query.cookie.os = 'iOS' + const deviceId = `NMUSIC` + const encodedId = Buffer.from( + `${deviceId} ${cloudmusic_dll_encode_id(deviceId)}`, + ) + const username = encodedId.toString('base64') + const data = { + /* A base64 encoded string. */ + username: username, + } + let result = await request( + 'POST', + `https://music.163.com/api/register/anonimous`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + if (result.body.code === 200) { + result = { + status: 200, + body: { + ...result.body, + cookie: result.cookie.join(';'), + }, + cookie: result.cookie, + } + } + return result +} diff --git a/WebSourceCode/src/Netease/module/register_cellphone.js b/WebSourceCode/src/Netease/module/register_cellphone.js new file mode 100644 index 0000000..d03c51a --- /dev/null +++ b/WebSourceCode/src/Netease/module/register_cellphone.js @@ -0,0 +1,19 @@ +// 注册账号 +const crypto = require('crypto') + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + captcha: query.captcha, + phone: query.phone, + password: crypto.createHash('md5').update(query.password).digest('hex'), + nickname: query.nickname, + countrycode: query.countrycode || '86', + } + return request('POST', `https://music.163.com/api/register/cellphone`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/related_allvideo.js b/WebSourceCode/src/Netease/module/related_allvideo.js new file mode 100644 index 0000000..e75a8c4 --- /dev/null +++ b/WebSourceCode/src/Netease/module/related_allvideo.js @@ -0,0 +1,19 @@ +// 相关视频 + +module.exports = (query, request) => { + const data = { + id: query.id, + type: /^\d+$/.test(query.id) ? 0 : 1, + } + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/v1/allvideo/rcmd`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/related_playlist.js b/WebSourceCode/src/Netease/module/related_playlist.js new file mode 100644 index 0000000..02e580f --- /dev/null +++ b/WebSourceCode/src/Netease/module/related_playlist.js @@ -0,0 +1,39 @@ +// 相关歌单 + +module.exports = (query, request) => { + return request( + 'GET', + `https://music.163.com/playlist?id=${query.id}`, + {}, + { + ua: 'pc', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ).then((response) => { + try { + const pattern = + /
[\s\S]*?[\s\S]*?]*>([^<]+?)<\/a>[\s\S]*?]*>([^<]+?)<\/a>/g + let result, + playlists = [] + while ((result = pattern.exec(response.body)) != null) { + playlists.push({ + creator: { + userId: result[4].slice('/user/home?id='.length), + nickname: result[5], + }, + coverImgUrl: result[1].slice(0, -'?param=50y50'.length), + name: result[3], + id: result[2].slice('/playlist?id='.length), + }) + } + response.body = { code: 200, playlists: playlists } + return response + } catch (err) { + response.status = 500 + response.body = { code: 500, msg: err.stack } + return Promise.reject(response) + } + }) +} diff --git a/WebSourceCode/src/Netease/module/resource_like.js b/WebSourceCode/src/Netease/module/resource_like.js new file mode 100644 index 0000000..37299b5 --- /dev/null +++ b/WebSourceCode/src/Netease/module/resource_like.js @@ -0,0 +1,24 @@ +// 点赞与取消点赞资源 +const { resourceTypeMap } = require('../util/config.json') +module.exports = (query, request) => { + query.cookie.os = 'android' + query.t = query.t == 1 ? 'like' : 'unlike' + query.type = resourceTypeMap[query.type] + const data = { + threadId: query.type + query.id, + } + if (query.type === 'A_EV_2_') { + data.threadId = query.threadId + } + return request( + 'POST', + `https://music.163.com/weapi/resource/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/scrobble.js b/WebSourceCode/src/Netease/module/scrobble.js new file mode 100644 index 0000000..5c0eb98 --- /dev/null +++ b/WebSourceCode/src/Netease/module/scrobble.js @@ -0,0 +1,28 @@ +// 听歌打卡 + +module.exports = (query, request) => { + const data = { + logs: JSON.stringify([ + { + action: 'play', + json: { + download: 0, + end: 'playend', + id: query.id, + sourceId: query.sourceid, + time: query.time, + type: 'song', + wifi: 0, + source: 'list', + }, + }, + ]), + } + + return request('POST', `https://music.163.com/weapi/feedback/weblog`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/search.js b/WebSourceCode/src/Netease/module/search.js new file mode 100644 index 0000000..d114aaf --- /dev/null +++ b/WebSourceCode/src/Netease/module/search.js @@ -0,0 +1,30 @@ +// 搜索 + +module.exports = (query, request) => { + if (query.type && query.type == '2000') { + const data = { + keyword: query.keywords, + scene: 'normal', + limit: query.limit || 30, + offset: query.offset || 0, + } + return request('POST', `https://music.163.com/api/search/voice/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) + } + const data = { + s: query.keywords, + type: query.type || 1, // 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频 + limit: query.limit || 30, + offset: query.offset || 0, + } + return request('POST', `https://music.163.com/weapi/search/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/search_default.js b/WebSourceCode/src/Netease/module/search_default.js new file mode 100644 index 0000000..b573254 --- /dev/null +++ b/WebSourceCode/src/Netease/module/search_default.js @@ -0,0 +1,16 @@ +// 默认搜索关键词 + +module.exports = (query, request) => { + return request( + 'POST', + `https://interface3.music.163.com/eapi/search/defaultkeyword/get`, + {}, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/search/defaultkeyword/get', + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/search_hot.js b/WebSourceCode/src/Netease/module/search_hot.js new file mode 100644 index 0000000..75c95a6 --- /dev/null +++ b/WebSourceCode/src/Netease/module/search_hot.js @@ -0,0 +1,14 @@ +// 热门搜索 + +module.exports = (query, request) => { + const data = { + type: 1111, + } + return request('POST', `https://music.163.com/weapi/search/hot`, data, { + crypto: 'weapi', + ua: 'mobile', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/search_hot_detail.js b/WebSourceCode/src/Netease/module/search_hot_detail.js new file mode 100644 index 0000000..aae7c7e --- /dev/null +++ b/WebSourceCode/src/Netease/module/search_hot_detail.js @@ -0,0 +1,15 @@ +// 热搜列表 +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/weapi/hotsearchlist/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/search_multimatch.js b/WebSourceCode/src/Netease/module/search_multimatch.js new file mode 100644 index 0000000..6e4c0e8 --- /dev/null +++ b/WebSourceCode/src/Netease/module/search_multimatch.js @@ -0,0 +1,19 @@ +// 多类型搜索 + +module.exports = (query, request) => { + const data = { + type: query.type || 1, + s: query.keywords || '', + } + return request( + 'POST', + `https://music.163.com/weapi/search/suggest/multimatch`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/search_suggest.js b/WebSourceCode/src/Netease/module/search_suggest.js new file mode 100644 index 0000000..e78b255 --- /dev/null +++ b/WebSourceCode/src/Netease/module/search_suggest.js @@ -0,0 +1,19 @@ +// 搜索建议 + +module.exports = (query, request) => { + const data = { + s: query.keywords || '', + } + let type = query.type == 'mobile' ? 'keyword' : 'web' + return request( + 'POST', + `https://music.163.com/weapi/search/suggest/` + type, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/send_album.js b/WebSourceCode/src/Netease/module/send_album.js new file mode 100644 index 0000000..d6693a5 --- /dev/null +++ b/WebSourceCode/src/Netease/module/send_album.js @@ -0,0 +1,18 @@ +// 私信专辑 + +module.exports = (query, request) => { + query.cookie.os = 'ios' + query.cookie.appver = '8.7.01' + const data = { + id: query.id, + msg: query.msg || '', + type: 'album', + userIds: '[' + query.user_ids + ']', + } + return request('POST', `https://music.163.com/api/msg/private/send`, data, { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/send_playlist.js b/WebSourceCode/src/Netease/module/send_playlist.js new file mode 100644 index 0000000..a1d9bd4 --- /dev/null +++ b/WebSourceCode/src/Netease/module/send_playlist.js @@ -0,0 +1,17 @@ +// 私信歌单 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + id: query.playlist, + type: 'playlist', + msg: query.msg, + userIds: '[' + query.user_ids + ']', + } + return request('POST', `https://music.163.com/weapi/msg/private/send`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/send_song.js b/WebSourceCode/src/Netease/module/send_song.js new file mode 100644 index 0000000..b2ce0a2 --- /dev/null +++ b/WebSourceCode/src/Netease/module/send_song.js @@ -0,0 +1,18 @@ +// 私信歌曲 + +module.exports = (query, request) => { + query.cookie.os = 'ios' + query.cookie.appver = '8.7.01' + const data = { + id: query.id, + msg: query.msg || '', + type: 'song', + userIds: '[' + query.user_ids + ']', + } + return request('POST', `https://music.163.com/api/msg/private/send`, data, { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/send_text.js b/WebSourceCode/src/Netease/module/send_text.js new file mode 100644 index 0000000..a13ad35 --- /dev/null +++ b/WebSourceCode/src/Netease/module/send_text.js @@ -0,0 +1,16 @@ +// 私信 + +module.exports = (query, request) => { + query.cookie.os = 'pc' + const data = { + type: 'text', + msg: query.msg, + userIds: '[' + query.user_ids + ']', + } + return request('POST', `https://music.163.com/weapi/msg/private/send`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/setting.js b/WebSourceCode/src/Netease/module/setting.js new file mode 100644 index 0000000..7dd8279 --- /dev/null +++ b/WebSourceCode/src/Netease/module/setting.js @@ -0,0 +1,11 @@ +// 设置 + +module.exports = (query, request) => { + const data = {} + return request('POST', `https://music.163.com/api/user/setting`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/share_resource.js b/WebSourceCode/src/Netease/module/share_resource.js new file mode 100644 index 0000000..80b7a5e --- /dev/null +++ b/WebSourceCode/src/Netease/module/share_resource.js @@ -0,0 +1,20 @@ +// 分享歌曲到动态 + +module.exports = (query, request) => { + const data = { + type: query.type || 'song', // song,playlist,mv,djprogram,djradio,noresource + msg: query.msg || '', + id: query.id || '', + } + return request( + 'POST', + `https://music.163.com/weapi/share/friends/resource`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/sheet_list.js b/WebSourceCode/src/Netease/module/sheet_list.js new file mode 100644 index 0000000..c19f5d6 --- /dev/null +++ b/WebSourceCode/src/Netease/module/sheet_list.js @@ -0,0 +1,20 @@ +// 乐谱列表 +const crypto = require('crypto') +module.exports = (query, request) => { + const data = { + id: query.id, + abTest: query.ab || 'b', + } + return request( + 'POST', + `https://interface3.music.163.com/eapi/music/sheet/list/v1`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/music/sheet/list/v1', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/sheet_preview.js b/WebSourceCode/src/Netease/module/sheet_preview.js new file mode 100644 index 0000000..7ad7636 --- /dev/null +++ b/WebSourceCode/src/Netease/module/sheet_preview.js @@ -0,0 +1,19 @@ +// 乐谱预览 +const crypto = require('crypto') +module.exports = (query, request) => { + const data = { + id: query.id, + } + return request( + 'POST', + `https://interface3.music.163.com/eapi//music/sheet/preview/info?id=${query.id}`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api//music/sheet/preview/info', // 我没写错! 他们就是这么请求的! + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/sign_happy_info.js b/WebSourceCode/src/Netease/module/sign_happy_info.js new file mode 100644 index 0000000..576c958 --- /dev/null +++ b/WebSourceCode/src/Netease/module/sign_happy_info.js @@ -0,0 +1,9 @@ +module.exports = (query, request) => { + const data = {} + return request('POST', `https://music.163.com/api/sign/happy/info`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/signin_progress.js b/WebSourceCode/src/Netease/module/signin_progress.js new file mode 100644 index 0000000..ff052c6 --- /dev/null +++ b/WebSourceCode/src/Netease/module/signin_progress.js @@ -0,0 +1,18 @@ +// 签到进度 + +module.exports = (query, request) => { + const data = { + moduleId: query.moduleId || '1207signin-1207signin', + } + return request( + 'POST', + `https://music.163.com/weapi/act/modules/signin/v2/progress`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/simi_artist.js b/WebSourceCode/src/Netease/module/simi_artist.js new file mode 100644 index 0000000..569618e --- /dev/null +++ b/WebSourceCode/src/Netease/module/simi_artist.js @@ -0,0 +1,18 @@ +// 相似歌手 +const config = require('../util/config.json') +module.exports = (query, request) => { + const data = { + artistid: query.id, + } + return request( + 'POST', + `https://music.163.com/weapi/discovery/simiArtist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/simi_mv.js b/WebSourceCode/src/Netease/module/simi_mv.js new file mode 100644 index 0000000..6dd1c5f --- /dev/null +++ b/WebSourceCode/src/Netease/module/simi_mv.js @@ -0,0 +1,13 @@ +// 相似MV + +module.exports = (query, request) => { + const data = { + mvid: query.mvid, + } + return request('POST', `https://music.163.com/weapi/discovery/simiMV`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/simi_playlist.js b/WebSourceCode/src/Netease/module/simi_playlist.js new file mode 100644 index 0000000..11052df --- /dev/null +++ b/WebSourceCode/src/Netease/module/simi_playlist.js @@ -0,0 +1,20 @@ +// 相似歌单 + +module.exports = (query, request) => { + const data = { + songid: query.id, + limit: query.limit || 50, + offset: query.offset || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/discovery/simiPlaylist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/simi_song.js b/WebSourceCode/src/Netease/module/simi_song.js new file mode 100644 index 0000000..58b3be9 --- /dev/null +++ b/WebSourceCode/src/Netease/module/simi_song.js @@ -0,0 +1,20 @@ +// 相似歌曲 + +module.exports = (query, request) => { + const data = { + songid: query.id, + limit: query.limit || 50, + offset: query.offset || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/v1/discovery/simiSong`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/simi_user.js b/WebSourceCode/src/Netease/module/simi_user.js new file mode 100644 index 0000000..65a96d1 --- /dev/null +++ b/WebSourceCode/src/Netease/module/simi_user.js @@ -0,0 +1,20 @@ +// 相似用户 + +module.exports = (query, request) => { + const data = { + songid: query.id, + limit: query.limit || 50, + offset: query.offset || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/discovery/simiUser`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/song_detail.js b/WebSourceCode/src/Netease/module/song_detail.js new file mode 100644 index 0000000..338fddc --- /dev/null +++ b/WebSourceCode/src/Netease/module/song_detail.js @@ -0,0 +1,14 @@ +// 歌曲详情 + +module.exports = (query, request) => { + query.ids = query.ids.split(/\s*,\s*/) + const data = { + c: '[' + query.ids.map((id) => '{"id":' + id + '}').join(',') + ']', + } + return request('POST', `https://music.163.com/api/v3/song/detail`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/song_download_url.js b/WebSourceCode/src/Netease/module/song_download_url.js new file mode 100644 index 0000000..73eccc9 --- /dev/null +++ b/WebSourceCode/src/Netease/module/song_download_url.js @@ -0,0 +1,20 @@ +// 获取客户端歌曲下载链接 + +module.exports = (query, request) => { + const data = { + id: query.id, + br: parseInt(query.br || 999000), + } + return request( + 'POST', + `https://interface.music.163.com/eapi/song/enhance/download/url`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/song/enhance/download/url', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/song_order_update.js b/WebSourceCode/src/Netease/module/song_order_update.js new file mode 100644 index 0000000..0dfb416 --- /dev/null +++ b/WebSourceCode/src/Netease/module/song_order_update.js @@ -0,0 +1,22 @@ +// 更新歌曲顺序 + +module.exports = (query, request) => { + const data = { + pid: query.pid, + trackIds: query.ids, + op: 'update', + } + + return request( + 'POST', + `http://interface.music.163.com/api/playlist/manipulate/tracks`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/playlist/desc/update', + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/song_purchased.js b/WebSourceCode/src/Netease/module/song_purchased.js new file mode 100644 index 0000000..c86dfa1 --- /dev/null +++ b/WebSourceCode/src/Netease/module/song_purchased.js @@ -0,0 +1,19 @@ +// 已购单曲 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 20, + offset: query.offset || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/single/mybought/song/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/song_url.js b/WebSourceCode/src/Netease/module/song_url.js new file mode 100644 index 0000000..7a2baef --- /dev/null +++ b/WebSourceCode/src/Netease/module/song_url.js @@ -0,0 +1,33 @@ +// 歌曲链接 +module.exports = async (query, request) => { + query.cookie.os = 'pc' + const ids = query.id.split(',') + const data = { + ids: JSON.stringify(ids), + br: parseInt(query.br || 999000), + } + const res = await request( + 'POST', + `https://interface3.music.163.com/eapi/song/enhance/player/url`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/song/enhance/player/url', + }, + ) + // 根据id排序 + const result = res.body.data + result.sort((a, b) => { + return ids.indexOf(String(a.id)) - ids.indexOf(String(b.id)) + }) + return { + status: 200, + body: { + code: 200, + data: result, + }, + } +} diff --git a/WebSourceCode/src/Netease/module/song_url_v1.js b/WebSourceCode/src/Netease/module/song_url_v1.js new file mode 100644 index 0000000..5c15bf8 --- /dev/null +++ b/WebSourceCode/src/Netease/module/song_url_v1.js @@ -0,0 +1,30 @@ +// 歌曲链接 - v1 +// 此版本不再采用 br 作为音质区分的标准 +// 而是采用 standard, exhigh, lossless, hires, jyeffect(高清环绕声), sky(沉浸环绕声), jymaster(超清母带) 进行音质判断 + +const crypto = require('crypto') +module.exports = (query, request) => { + query.cookie.os = 'android' + query.cookie.appver = '8.10.05' + const data = { + ids: '[' + query.id + ']', + level: query.level, + encodeType: 'flac', + } + if (data.level == 'sky') { + data.immerseType = 'c51' + } + console.log(data) + return request( + 'POST', + `https://interface.music.163.com/eapi/song/enhance/player/url/v1`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/song/enhance/player/url/v1', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/song_wiki_summary.js b/WebSourceCode/src/Netease/module/song_wiki_summary.js new file mode 100644 index 0000000..f6b5203 --- /dev/null +++ b/WebSourceCode/src/Netease/module/song_wiki_summary.js @@ -0,0 +1,19 @@ +// 音乐百科基础信息 +const crypto = require('crypto') +module.exports = (query, request) => { + const data = { + songId: query.id, + } + return request( + 'POST', + `https://interface3.music.163.com/eapi/music/wiki/home/song/get`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + url: '/api/song/play/about/block/page', + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/starpick_comments_summary.js b/WebSourceCode/src/Netease/module/starpick_comments_summary.js new file mode 100644 index 0000000..ae31608 --- /dev/null +++ b/WebSourceCode/src/Netease/module/starpick_comments_summary.js @@ -0,0 +1,22 @@ +// 云村星评馆 - 简要评论列表 +module.exports = (query, request) => { + const data = { + cursor: JSON.stringify({ + offset: 0, + blockCodeOrderList: ['HOMEPAGE_BLOCK_NEW_HOT_COMMENT'], + refresh: true, + }), + } + return request( + 'POST', + `https://interface3.music.163.com/eapi/homepage/block/page`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/homepage/block/page', + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/style_album.js b/WebSourceCode/src/Netease/module/style_album.js new file mode 100644 index 0000000..826d3d0 --- /dev/null +++ b/WebSourceCode/src/Netease/module/style_album.js @@ -0,0 +1,21 @@ +// 曲风-专辑 + +module.exports = (query, request) => { + const data = { + cursor: query.cursor || 0, + size: query.size || 20, + tagId: query.tagId, + sort: query.sort || 0, + } + return request( + 'POST', + `https://music.163.com/api/style-tag/home/album`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/style_artist.js b/WebSourceCode/src/Netease/module/style_artist.js new file mode 100644 index 0000000..109cac8 --- /dev/null +++ b/WebSourceCode/src/Netease/module/style_artist.js @@ -0,0 +1,21 @@ +// 曲风-歌手 + +module.exports = (query, request) => { + const data = { + cursor: query.cursor || 0, + size: query.size || 20, + tagId: query.tagId, + sort: 0, + } + return request( + 'POST', + `https://music.163.com/api/style-tag/home/artist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/style_detail.js b/WebSourceCode/src/Netease/module/style_detail.js new file mode 100644 index 0000000..bf4e4dd --- /dev/null +++ b/WebSourceCode/src/Netease/module/style_detail.js @@ -0,0 +1,18 @@ +// 曲风详情 + +module.exports = (query, request) => { + const data = { + tagId: query.tagId, + } + return request( + 'POST', + `https://music.163.com/api/style-tag/home/head`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/style_list.js b/WebSourceCode/src/Netease/module/style_list.js new file mode 100644 index 0000000..991b675 --- /dev/null +++ b/WebSourceCode/src/Netease/module/style_list.js @@ -0,0 +1,11 @@ +// 曲风列表 + +module.exports = (query, request) => { + const data = {} + return request('POST', `https://music.163.com/api/tag/list/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/style_playlist.js b/WebSourceCode/src/Netease/module/style_playlist.js new file mode 100644 index 0000000..73f8231 --- /dev/null +++ b/WebSourceCode/src/Netease/module/style_playlist.js @@ -0,0 +1,21 @@ +// 曲风-歌单 + +module.exports = (query, request) => { + const data = { + cursor: query.cursor || 0, + size: query.size || 20, + tagId: query.tagId, + sort: 0, + } + return request( + 'POST', + `https://music.163.com/api/style-tag/home/playlist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/style_preference.js b/WebSourceCode/src/Netease/module/style_preference.js new file mode 100644 index 0000000..373846e --- /dev/null +++ b/WebSourceCode/src/Netease/module/style_preference.js @@ -0,0 +1,16 @@ +// 曲风偏好 + +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/api/tag/my/preference/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/style_song.js b/WebSourceCode/src/Netease/module/style_song.js new file mode 100644 index 0000000..077c0b3 --- /dev/null +++ b/WebSourceCode/src/Netease/module/style_song.js @@ -0,0 +1,21 @@ +// 曲风-歌曲 + +module.exports = (query, request) => { + const data = { + cursor: query.cursor || 0, + size: query.size || 20, + tagId: query.tagId, + sort: query.sort || 0, + } + return request( + 'POST', + `https://music.163.com/api/style-tag/home/song`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/top_album.js b/WebSourceCode/src/Netease/module/top_album.js new file mode 100644 index 0000000..d220297 --- /dev/null +++ b/WebSourceCode/src/Netease/module/top_album.js @@ -0,0 +1,27 @@ +// 新碟上架 + +module.exports = (query, request) => { + const date = new Date() + + const data = { + area: query.area || 'ALL', // //ALL:全部,ZH:华语,EA:欧美,KR:韩国,JP:日本 + limit: query.limit || 50, + offset: query.offset || 0, + type: query.type || 'new', + year: query.year || date.getFullYear(), + month: query.month || date.getMonth() + 1, + total: false, + rcmd: true, + } + return request( + 'POST', + `https://music.163.com/api/discovery/new/albums/area`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/top_artists.js b/WebSourceCode/src/Netease/module/top_artists.js new file mode 100644 index 0000000..a1a40b6 --- /dev/null +++ b/WebSourceCode/src/Netease/module/top_artists.js @@ -0,0 +1,15 @@ +// 热门歌手 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 50, + offset: query.offset || 0, + total: true, + } + return request('POST', `https://music.163.com/weapi/artist/top`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/top_list.js b/WebSourceCode/src/Netease/module/top_list.js new file mode 100644 index 0000000..c33b251 --- /dev/null +++ b/WebSourceCode/src/Netease/module/top_list.js @@ -0,0 +1,30 @@ +// 排行榜 +module.exports = (query, request) => { + query.cookie.os = 'pc' + if (query.idx) { + return Promise.resolve({ + status: 500, + body: { + code: 500, + msg: '不支持此方式调用,只支持id调用', + }, + }) + } + + const data = { + id: query.id, + n: '500', + s: '0', + } + return request( + 'POST', + `https://interface3.music.163.com/api/playlist/v4/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/top_mv.js b/WebSourceCode/src/Netease/module/top_mv.js new file mode 100644 index 0000000..2dc7c22 --- /dev/null +++ b/WebSourceCode/src/Netease/module/top_mv.js @@ -0,0 +1,16 @@ +// MV排行榜 + +module.exports = (query, request) => { + const data = { + area: query.area || '', + limit: query.limit || 30, + offset: query.offset || 0, + total: true, + } + return request('POST', `https://music.163.com/weapi/mv/toplist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/top_playlist.js b/WebSourceCode/src/Netease/module/top_playlist.js new file mode 100644 index 0000000..4f41edb --- /dev/null +++ b/WebSourceCode/src/Netease/module/top_playlist.js @@ -0,0 +1,17 @@ +// 分类歌单 + +module.exports = (query, request) => { + const data = { + cat: query.cat || '全部', // 全部,华语,欧美,日语,韩语,粤语,小语种,流行,摇滚,民谣,电子,舞曲,说唱,轻音乐,爵士,乡村,R&B/Soul,古典,民族,英伦,金属,朋克,蓝调,雷鬼,世界音乐,拉丁,另类/独立,New Age,古风,后摇,Bossa Nova,清晨,夜晚,学习,工作,午休,下午茶,地铁,驾车,运动,旅行,散步,酒吧,怀旧,清新,浪漫,性感,伤感,治愈,放松,孤独,感动,兴奋,快乐,安静,思念,影视原声,ACG,儿童,校园,游戏,70后,80后,90后,网络歌曲,KTV,经典,翻唱,吉他,钢琴,器乐,榜单,00后 + order: query.order || 'hot', // hot,new + limit: query.limit || 50, + offset: query.offset || 0, + total: true, + } + return request('POST', `https://music.163.com/weapi/playlist/list`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/top_playlist_highquality.js b/WebSourceCode/src/Netease/module/top_playlist_highquality.js new file mode 100644 index 0000000..a704652 --- /dev/null +++ b/WebSourceCode/src/Netease/module/top_playlist_highquality.js @@ -0,0 +1,21 @@ +// 精品歌单 + +module.exports = (query, request) => { + const data = { + cat: query.cat || '全部', // 全部,华语,欧美,韩语,日语,粤语,小语种,运动,ACG,影视原声,流行,摇滚,后摇,古风,民谣,轻音乐,电子,器乐,说唱,古典,爵士 + limit: query.limit || 50, + lasttime: query.before || 0, // 歌单updateTime + total: true, + } + return request( + 'POST', + `https://music.163.com/api/playlist/highquality/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/top_song.js b/WebSourceCode/src/Netease/module/top_song.js new file mode 100644 index 0000000..4b37d38 --- /dev/null +++ b/WebSourceCode/src/Netease/module/top_song.js @@ -0,0 +1,21 @@ +// 新歌速递 + +module.exports = (query, request) => { + const data = { + areaId: query.type || 0, // 全部:0 华语:7 欧美:96 日本:8 韩国:16 + // limit: query.limit || 100, + // offset: query.offset || 0, + total: true, + } + return request( + 'POST', + `https://music.163.com/weapi/v1/discovery/new/songs`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/topic_detail.js b/WebSourceCode/src/Netease/module/topic_detail.js new file mode 100644 index 0000000..e0dd006 --- /dev/null +++ b/WebSourceCode/src/Netease/module/topic_detail.js @@ -0,0 +1,11 @@ +module.exports = (query, request) => { + const data = { + actid: query.actid, + } + return request('POST', `https://music.163.com/api/act/detail`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/topic_detail_event_hot.js b/WebSourceCode/src/Netease/module/topic_detail_event_hot.js new file mode 100644 index 0000000..a979b6f --- /dev/null +++ b/WebSourceCode/src/Netease/module/topic_detail_event_hot.js @@ -0,0 +1,11 @@ +module.exports = (query, request) => { + const data = { + actid: query.actid, + } + return request('POST', `https://music.163.com/api/act/event/hot`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/topic_sublist.js b/WebSourceCode/src/Netease/module/topic_sublist.js new file mode 100644 index 0000000..153b298 --- /dev/null +++ b/WebSourceCode/src/Netease/module/topic_sublist.js @@ -0,0 +1,15 @@ +// 收藏的专栏 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 50, + offset: query.offset || 0, + total: true, + } + return request('POST', `https://music.163.com/api/topic/sublist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/toplist.js b/WebSourceCode/src/Netease/module/toplist.js new file mode 100644 index 0000000..c690241 --- /dev/null +++ b/WebSourceCode/src/Netease/module/toplist.js @@ -0,0 +1,15 @@ +// 所有榜单介绍 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/api/toplist`, + {}, + { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/toplist_artist.js b/WebSourceCode/src/Netease/module/toplist_artist.js new file mode 100644 index 0000000..825a649 --- /dev/null +++ b/WebSourceCode/src/Netease/module/toplist_artist.js @@ -0,0 +1,16 @@ +// 歌手榜 + +module.exports = (query, request) => { + const data = { + type: query.type || 1, + limit: 100, + offset: 0, + total: true, + } + return request('POST', `https://music.163.com/weapi/toplist/artist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/toplist_detail.js b/WebSourceCode/src/Netease/module/toplist_detail.js new file mode 100644 index 0000000..e194e03 --- /dev/null +++ b/WebSourceCode/src/Netease/module/toplist_detail.js @@ -0,0 +1,15 @@ +// 所有榜单内容摘要 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/toplist/detail`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/user_account.js b/WebSourceCode/src/Netease/module/user_account.js new file mode 100644 index 0000000..0eff002 --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_account.js @@ -0,0 +1,9 @@ +module.exports = (query, request) => { + const data = {} + return request('POST', `https://music.163.com/api/nuser/account/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/user_audio.js b/WebSourceCode/src/Netease/module/user_audio.js new file mode 100644 index 0000000..b63e700 --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_audio.js @@ -0,0 +1,18 @@ +// 用户创建的电台 + +module.exports = (query, request) => { + const data = { + userId: query.uid, + } + return request( + 'POST', + `https://music.163.com/weapi/djradio/get/byuser`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/user_binding.js b/WebSourceCode/src/Netease/module/user_binding.js new file mode 100644 index 0000000..559b4b5 --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_binding.js @@ -0,0 +1,14 @@ +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/api/v1/user/bindings/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/user_bindingcellphone.js b/WebSourceCode/src/Netease/module/user_bindingcellphone.js new file mode 100644 index 0000000..abe1c98 --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_bindingcellphone.js @@ -0,0 +1,21 @@ +module.exports = (query, request) => { + const data = { + phone: query.phone, + countrycode: query.countrycode || '86', + captcha: query.captcha, + password: query.password + ? crypto.createHash('md5').update(query.password).digest('hex') + : '', + } + return request( + 'POST', + `https://music.163.com/api/user/bindingCellphone`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/user_cloud.js b/WebSourceCode/src/Netease/module/user_cloud.js new file mode 100644 index 0000000..3134960 --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_cloud.js @@ -0,0 +1,14 @@ +// 云盘数据 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + } + return request('POST', `https://music.163.com/api/v1/cloud/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/user_cloud_del.js b/WebSourceCode/src/Netease/module/user_cloud_del.js new file mode 100644 index 0000000..7a5577b --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_cloud_del.js @@ -0,0 +1,13 @@ +// 云盘歌曲删除 + +module.exports = (query, request) => { + const data = { + songIds: [query.id], + } + return request('POST', `https://music.163.com/weapi/cloud/del`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/user_cloud_detail.js b/WebSourceCode/src/Netease/module/user_cloud_detail.js new file mode 100644 index 0000000..45f1b5a --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_cloud_detail.js @@ -0,0 +1,19 @@ +// 云盘数据详情 + +module.exports = (query, request) => { + const id = query.id.replace(/\s/g, '').split(',') + const data = { + songIds: id, + } + return request( + 'POST', + `https://music.163.com/weapi/v1/cloud/get/byids`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/user_comment_history.js b/WebSourceCode/src/Netease/module/user_comment_history.js new file mode 100644 index 0000000..339be30 --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_comment_history.js @@ -0,0 +1,22 @@ +module.exports = (query, request) => { + query.cookie.os = 'ios' + query.cookie.appver = '8.7.01' + const data = { + compose_reminder: 'true', + compose_hot_comment: 'true', + limit: query.limit || 10, + user_id: query.uid, + time: query.time || 0, + } + return request( + 'POST', + `https://music.163.com/api/comment/user/comment/history`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/user_detail.js b/WebSourceCode/src/Netease/module/user_detail.js new file mode 100644 index 0000000..b3da340 --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_detail.js @@ -0,0 +1,15 @@ +// 用户详情 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/v1/user/detail/${query.uid}`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/user_dj.js b/WebSourceCode/src/Netease/module/user_dj.js new file mode 100644 index 0000000..45a6a3a --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_dj.js @@ -0,0 +1,19 @@ +// 用户电台节目 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 30, + offset: query.offset || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/dj/program/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/user_event.js b/WebSourceCode/src/Netease/module/user_event.js new file mode 100644 index 0000000..521b0dd --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_event.js @@ -0,0 +1,23 @@ +// 用户动态 + +module.exports = (query, request) => { + query.cookie.os = 'ios' + query.cookie.appver = '8.7.01' + const data = { + getcounts: true, + time: query.lasttime || -1, + limit: query.limit || 30, + total: false, + } + return request( + 'POST', + `https://music.163.com/api/event/get/${query.uid}`, + data, + { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/user_followeds.js b/WebSourceCode/src/Netease/module/user_followeds.js new file mode 100644 index 0000000..678477a --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_followeds.js @@ -0,0 +1,23 @@ +// 关注TA的人(粉丝) + +module.exports = (query, request) => { + const data = { + userId: query.uid, + time: '0', + limit: query.limit || 30, + offset: query.offset || 0, + getcounts: 'true', + } + return request( + 'POST', + `https://music.163.com/eapi/user/getfolloweds/${query.uid}`, + data, + { + crypto: 'eapi', + cookie: query.cookie, + proxy: query.proxy, + url: '/api/user/getfolloweds', + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/user_follows.js b/WebSourceCode/src/Netease/module/user_follows.js new file mode 100644 index 0000000..cff742f --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_follows.js @@ -0,0 +1,20 @@ +// TA关注的人(关注) + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + limit: query.limit || 30, + order: true, + } + return request( + 'POST', + `https://music.163.com/weapi/user/getfollows/${query.uid}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/user_level.js b/WebSourceCode/src/Netease/module/user_level.js new file mode 100644 index 0000000..107a45f --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_level.js @@ -0,0 +1,11 @@ +// 类别热门电台 + +module.exports = (query, request) => { + const data = {} + return request('POST', `https://music.163.com/weapi/user/level`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/user_playlist.js b/WebSourceCode/src/Netease/module/user_playlist.js new file mode 100644 index 0000000..51a7c45 --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_playlist.js @@ -0,0 +1,16 @@ +// 用户歌单 + +module.exports = (query, request) => { + const data = { + uid: query.uid, + limit: query.limit || 30, + offset: query.offset || 0, + includeVideo: true, + } + return request('POST', `https://music.163.com/api/user/playlist`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/user_record.js b/WebSourceCode/src/Netease/module/user_record.js new file mode 100644 index 0000000..8f5f2cc --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_record.js @@ -0,0 +1,14 @@ +// 听歌排行 + +module.exports = (query, request) => { + const data = { + uid: query.uid, + type: query.type || 0, // 1: 最近一周, 0: 所有时间 + } + return request('POST', `https://music.163.com/weapi/v1/play/record`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/user_replacephone.js b/WebSourceCode/src/Netease/module/user_replacephone.js new file mode 100644 index 0000000..feed2fe --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_replacephone.js @@ -0,0 +1,19 @@ +module.exports = (query, request) => { + const data = { + phone: query.phone, + captcha: query.captcha, + oldcaptcha: query.oldcaptcha, + countrycode: query.countrycode || '86', + } + return request( + 'POST', + `https://music.163.com/api/user/replaceCellphone`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/user_subcount.js b/WebSourceCode/src/Netease/module/user_subcount.js new file mode 100644 index 0000000..cfa53ab --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_subcount.js @@ -0,0 +1,15 @@ +// 收藏计数 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/subcount`, + {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/user_update.js b/WebSourceCode/src/Netease/module/user_update.js new file mode 100644 index 0000000..96c7af1 --- /dev/null +++ b/WebSourceCode/src/Netease/module/user_update.js @@ -0,0 +1,24 @@ +// 编辑用户信息 + +module.exports = (query, request) => { + const data = { + avatarImgId: '0', + birthday: query.birthday, + city: query.city, + gender: query.gender, + nickname: query.nickname, + province: query.province, + signature: query.signature, + } + return request( + 'POST', + `https://music.163.com/weapi/user/profile/update`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/verify_getQr.js b/WebSourceCode/src/Netease/module/verify_getQr.js new file mode 100644 index 0000000..7322267 --- /dev/null +++ b/WebSourceCode/src/Netease/module/verify_getQr.js @@ -0,0 +1,42 @@ +module.exports = async (query, request) => { + const data = { + verifyConfigId: query.vid, + verifyType: query.type, + token: query.token, + params: JSON.stringify({ + event_id: query.evid, + sign: query.sign, + }), + size: 150, + } + + const res = await request( + 'POST', + `https://music.163.com/weapi/frontrisk/verify/getqrcode`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + const result = `https://st.music.163.com/encrypt-pages?qrCode=${ + res.body.data.qrCode + }&verifyToken=${query.token}&verifyId=${query.vid}&verifyType=${ + query.type + }¶ms=${JSON.stringify({ + event_id: query.evid, + sign: query.sign, + })}` + return { + status: 200, + body: { + code: 200, + data: { + qrCode: res.body.data.qrCode, + qrurl: result, + }, + }, + } +} diff --git a/WebSourceCode/src/Netease/module/verify_qrcodestatus.js b/WebSourceCode/src/Netease/module/verify_qrcodestatus.js new file mode 100644 index 0000000..6263bdd --- /dev/null +++ b/WebSourceCode/src/Netease/module/verify_qrcodestatus.js @@ -0,0 +1,17 @@ +module.exports = async (query, request) => { + const data = { + qrCode: query.qr, + } + const res = await request( + 'POST', + `https://music.163.com/weapi/frontrisk/verify/qrcodestatus`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) + return res +} diff --git a/WebSourceCode/src/Netease/module/video_category_list.js b/WebSourceCode/src/Netease/module/video_category_list.js new file mode 100644 index 0000000..88c13c7 --- /dev/null +++ b/WebSourceCode/src/Netease/module/video_category_list.js @@ -0,0 +1,20 @@ +// 视频分类列表 + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + total: 'true', + limit: query.limit || 99, + } + return request( + 'POST', + `https://music.163.com/api/cloudvideo/category/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/video_detail.js b/WebSourceCode/src/Netease/module/video_detail.js new file mode 100644 index 0000000..63507ae --- /dev/null +++ b/WebSourceCode/src/Netease/module/video_detail.js @@ -0,0 +1,18 @@ +// 视频详情 + +module.exports = (query, request) => { + const data = { + id: query.id, + } + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/v1/video/detail`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/video_detail_info.js b/WebSourceCode/src/Netease/module/video_detail_info.js new file mode 100644 index 0000000..4a163ae --- /dev/null +++ b/WebSourceCode/src/Netease/module/video_detail_info.js @@ -0,0 +1,19 @@ +// 视频点赞转发评论数数据 + +module.exports = (query, request) => { + const data = { + threadid: `R_VI_62_${query.vid}`, + composeliked: true, + } + return request( + 'POST', + `https://music.163.com/api/comment/commentthread/info`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/video_group.js b/WebSourceCode/src/Netease/module/video_group.js new file mode 100644 index 0000000..9c39129 --- /dev/null +++ b/WebSourceCode/src/Netease/module/video_group.js @@ -0,0 +1,21 @@ +// 视频标签/分类下的视频 + +module.exports = (query, request) => { + const data = { + groupId: query.id, + offset: query.offset || 0, + need_preview_url: 'true', + total: true, + } + return request( + 'POST', + `https://music.163.com/api/videotimeline/videogroup/otherclient/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/video_group_list.js b/WebSourceCode/src/Netease/module/video_group_list.js new file mode 100644 index 0000000..22acdc7 --- /dev/null +++ b/WebSourceCode/src/Netease/module/video_group_list.js @@ -0,0 +1,16 @@ +// 视频标签列表 + +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/api/cloudvideo/group/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/video_sub.js b/WebSourceCode/src/Netease/module/video_sub.js new file mode 100644 index 0000000..562a7c2 --- /dev/null +++ b/WebSourceCode/src/Netease/module/video_sub.js @@ -0,0 +1,19 @@ +// 收藏与取消收藏视频 + +module.exports = (query, request) => { + query.t = query.t == 1 ? 'sub' : 'unsub' + const data = { + id: query.id, + } + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/video/${query.t}`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/video_timeline_all.js b/WebSourceCode/src/Netease/module/video_timeline_all.js new file mode 100644 index 0000000..b05a46c --- /dev/null +++ b/WebSourceCode/src/Netease/module/video_timeline_all.js @@ -0,0 +1,22 @@ +// 全部视频列表 + +module.exports = (query, request) => { + const data = { + groupId: 0, + offset: query.offset || 0, + need_preview_url: 'true', + total: true, + } + // /api/videotimeline/otherclient/get + return request( + 'POST', + `https://music.163.com/api/videotimeline/otherclient/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/video_timeline_recommend.js b/WebSourceCode/src/Netease/module/video_timeline_recommend.js new file mode 100644 index 0000000..1ca218a --- /dev/null +++ b/WebSourceCode/src/Netease/module/video_timeline_recommend.js @@ -0,0 +1,17 @@ +// 推荐视频 + +module.exports = (query, request) => { + const data = { + offset: query.offset || 0, + filterLives: '[]', + withProgramInfo: 'true', + needUrl: '1', + resolution: '480', + } + return request('POST', `https://music.163.com/api/videotimeline/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/video_url.js b/WebSourceCode/src/Netease/module/video_url.js new file mode 100644 index 0000000..b564f8a --- /dev/null +++ b/WebSourceCode/src/Netease/module/video_url.js @@ -0,0 +1,19 @@ +// 视频链接 + +module.exports = (query, request) => { + const data = { + ids: '["' + query.id + '"]', + resolution: query.res || 1080, + } + return request( + 'POST', + `https://music.163.com/weapi/cloudvideo/playurl`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/vip_growthpoint.js b/WebSourceCode/src/Netease/module/vip_growthpoint.js new file mode 100644 index 0000000..e035c5a --- /dev/null +++ b/WebSourceCode/src/Netease/module/vip_growthpoint.js @@ -0,0 +1,16 @@ +// 会员成长值 + +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/weapi/vipnewcenter/app/level/growhpoint/basic`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/vip_growthpoint_details.js b/WebSourceCode/src/Netease/module/vip_growthpoint_details.js new file mode 100644 index 0000000..be9c927 --- /dev/null +++ b/WebSourceCode/src/Netease/module/vip_growthpoint_details.js @@ -0,0 +1,19 @@ +// 会员成长值领取记录 + +module.exports = (query, request) => { + const data = { + limit: query.limit || 20, + offset: query.offset || 0, + } + return request( + 'POST', + `https://music.163.com/weapi/vipnewcenter/app/level/growth/details`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/vip_growthpoint_get.js b/WebSourceCode/src/Netease/module/vip_growthpoint_get.js new file mode 100644 index 0000000..69ae94b --- /dev/null +++ b/WebSourceCode/src/Netease/module/vip_growthpoint_get.js @@ -0,0 +1,18 @@ +// 领取会员成长值 + +module.exports = (query, request) => { + const data = { + taskIds: query.ids, + } + return request( + 'POST', + `https://music.163.com/weapi/vipnewcenter/app/level/task/reward/get`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/vip_info.js b/WebSourceCode/src/Netease/module/vip_info.js new file mode 100644 index 0000000..b50df74 --- /dev/null +++ b/WebSourceCode/src/Netease/module/vip_info.js @@ -0,0 +1,17 @@ +// 获取 VIP 信息 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/music-vip-membership/front/vip/info`, + { + userId: query.uid || '', + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/vip_info_v2.js b/WebSourceCode/src/Netease/module/vip_info_v2.js new file mode 100644 index 0000000..6d00c1a --- /dev/null +++ b/WebSourceCode/src/Netease/module/vip_info_v2.js @@ -0,0 +1,17 @@ +// 获取 VIP 信息 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/api/music-vip-membership/client/vip/info`, + { + userId: query.uid || '', + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/vip_tasks.js b/WebSourceCode/src/Netease/module/vip_tasks.js new file mode 100644 index 0000000..256e67a --- /dev/null +++ b/WebSourceCode/src/Netease/module/vip_tasks.js @@ -0,0 +1,16 @@ +// 会员任务 + +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/weapi/vipnewcenter/app/level/task/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/vip_timemachine.js b/WebSourceCode/src/Netease/module/vip_timemachine.js new file mode 100644 index 0000000..660520c --- /dev/null +++ b/WebSourceCode/src/Netease/module/vip_timemachine.js @@ -0,0 +1,22 @@ +// 黑胶时光机 + +module.exports = (query, request) => { + const data = {} + if (query.startTime && query.endTime) { + data.startTime = query.startTime + data.endTime = query.endTime + data.type = 1 + data.limit = query.limit || 60 + } + return request( + 'POST', + `https://music.163.com/weapi/vipmusic/newrecord/weekflow`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/voice_upload.js b/WebSourceCode/src/Netease/module/voice_upload.js new file mode 100644 index 0000000..b340348 --- /dev/null +++ b/WebSourceCode/src/Netease/module/voice_upload.js @@ -0,0 +1,171 @@ +const { default: axios } = require('axios') +var xml2js = require('xml2js') + +var parser = new xml2js.Parser(/* options */) +function createDupkey() { + // 格式:3b443c7c-a87f-468d-ba38-46d407aaf23a + var s = [] + var hexDigits = '0123456789abcdef' + for (var i = 0; i < 36; i++) { + s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1) + } + s[14] = '4' // bits 12-15 of the time_hi_and_version field to 0010 + s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1) // bits 6-7 of the clock_seq_hi_and_reserved to 01 + s[8] = s[13] = s[18] = s[23] = '-' + return s.join('') +} +module.exports = async (query, request) => { + let ext = 'mp3' + if (query.songFile.name.indexOf('flac') > -1) { + ext = 'flac' + } + const filename = + query.songName || + query.songFile.name + .replace('.' + ext, '') + .replace(/\s/g, '') + .replace(/\./g, '_') + // query.cookie.os = 'pc' + // query.cookie.appver = '2.9.7' + if (!query.songFile) { + return Promise.reject({ + status: 500, + body: { + msg: '请上传音频文件', + code: 500, + }, + }) + } + + const tokenRes = await request( + 'POST', + `https://music.163.com/weapi/nos/token/alloc`, + { + bucket: 'ymusic', + ext: ext, + filename: filename, + local: false, + nos_product: 0, + type: 'other', + }, + { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy }, + ) + + const objectKey = tokenRes.body.result.objectKey.replace('/', '%2F') + const docId = tokenRes.body.result.docId + const res = await axios({ + method: 'post', + url: `https://ymusic.nos-hz.163yun.com/${objectKey}?uploads`, + headers: { + 'x-nos-token': tokenRes.body.result.token, + 'X-Nos-Meta-Content-Type': 'audio/mpeg', + }, + data: null, + }) + // return xml + const res2 = await parser.parseStringPromise(res.data) + + const res3 = await axios({ + method: 'put', + url: `https://ymusic.nos-hz.163yun.com/${objectKey}?partNumber=1&uploadId=${res2.InitiateMultipartUploadResult.UploadId[0]}`, + headers: { + 'x-nos-token': tokenRes.body.result.token, + 'Content-Type': 'audio/mpeg', + }, + data: query.songFile.data, + }) + + // get etag + const etag = res3.headers.etag + + // 文件处理 + await axios({ + method: 'post', + url: `https://ymusic.nos-hz.163yun.com/${objectKey}?uploadId=${res2.InitiateMultipartUploadResult.UploadId[0]}`, + headers: { + 'Content-Type': 'text/plain;charset=UTF-8', + 'X-Nos-Meta-Content-Type': 'audio/mpeg', + 'x-nos-token': tokenRes.body.result.token, + }, + data: ` + 1${etag} + `, + }) + + // preCheck + await request( + 'post', + `https://interface.music.163.com/weapi/voice/workbench/voice/batch/upload/preCheck`, + { + dupkey: createDupkey(), + voiceData: JSON.stringify([ + { + name: filename, + autoPublish: query.autoPublish == 1 ? true : false, + autoPublishText: query.autoPublishText || '', + description: query.description, + voiceListId: query.voiceListId, + coverImgId: query.coverImgId, + dfsId: docId, + categoryId: query.categoryId, + secondCategoryId: query.secondCategoryId, + composedSongs: query.composedSongs + ? query.composedSongs.split(',') + : [], + privacy: query.privacy == 1 ? true : false, + publishTime: query.publishTime || 0, + orderNo: query.orderNo || 1, + }, + ]), + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + headers: { + 'x-nos-token': tokenRes.body.result.token, + }, + }, + ) + const result = await request( + 'post', + `https://interface.music.163.com/weapi/voice/workbench/voice/batch/upload/v2`, + { + dupkey: createDupkey(), + voiceData: JSON.stringify([ + { + name: filename, + autoPublish: query.autoPublish == 1 ? true : false, + autoPublishText: query.autoPublishText || '', + description: query.description, + voiceListId: query.voiceListId, + coverImgId: query.coverImgId, + dfsId: docId, + categoryId: query.categoryId, + secondCategoryId: query.secondCategoryId, + composedSongs: query.composedSongs + ? query.composedSongs.split(',') + : [], + privacy: query.privacy == 1 ? true : false, + publishTime: query.publishTime || 0, + orderNo: query.orderNo || 1, + }, + ]), + }, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + headers: { + 'x-nos-token': tokenRes.body.result.token, + }, + }, + ) + return { + status: 200, + body: { + code: 200, + data: result.body.data, + }, + } +} diff --git a/WebSourceCode/src/Netease/module/voicelist_list.js b/WebSourceCode/src/Netease/module/voicelist_list.js new file mode 100644 index 0000000..29daaa4 --- /dev/null +++ b/WebSourceCode/src/Netease/module/voicelist_list.js @@ -0,0 +1,18 @@ +module.exports = (query, request) => { + const data = { + limit: query.limit || '200', + offset: query.offset || '0', + voiceListId: query.voiceListId, + } + return request( + 'POST', + `https://interface.music.163.com/weapi/voice/workbench/voices/by/voicelist`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/voicelist_search.js b/WebSourceCode/src/Netease/module/voicelist_search.js new file mode 100644 index 0000000..ebf236b --- /dev/null +++ b/WebSourceCode/src/Netease/module/voicelist_search.js @@ -0,0 +1,19 @@ +module.exports = (query, request) => { + const data = { + fee: '-1', + limit: query.limit || '200', + offset: query.offset || '0', + podcastName: query.podcastName || '', + } + return request( + 'POST', + `https://interface.music.163.com/weapi/voice/workbench/voicelist/search`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/weblog.js b/WebSourceCode/src/Netease/module/weblog.js new file mode 100644 index 0000000..1b593e3 --- /dev/null +++ b/WebSourceCode/src/Netease/module/weblog.js @@ -0,0 +1,15 @@ +// 操作记录 + +module.exports = (query, request) => { + return request( + 'POST', + `https://music.163.com/weapi/feedback/weblog`, + query.data || {}, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/yunbei.js b/WebSourceCode/src/Netease/module/yunbei.js new file mode 100644 index 0000000..b2bee9a --- /dev/null +++ b/WebSourceCode/src/Netease/module/yunbei.js @@ -0,0 +1,10 @@ +module.exports = (query, request) => { + const data = {} + // /api/point/today/get + return request('POST', `https://music.163.com/api/point/signed/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/yunbei_expense.js b/WebSourceCode/src/Netease/module/yunbei_expense.js new file mode 100644 index 0000000..50b6f95 --- /dev/null +++ b/WebSourceCode/src/Netease/module/yunbei_expense.js @@ -0,0 +1,17 @@ +module.exports = (query, request) => { + const data = { + limit: query.limit || 10, + offset: query.offset || 0, + } + return request( + 'POST', + `https://music.163.com/store/api/point/expense`, + data, + { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/yunbei_info.js b/WebSourceCode/src/Netease/module/yunbei_info.js new file mode 100644 index 0000000..68ea2bf --- /dev/null +++ b/WebSourceCode/src/Netease/module/yunbei_info.js @@ -0,0 +1,9 @@ +module.exports = (query, request) => { + const data = {} + return request('POST', `https://music.163.com/api/v1/user/info`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/yunbei_rcmd_song.js b/WebSourceCode/src/Netease/module/yunbei_rcmd_song.js new file mode 100644 index 0000000..e41841c --- /dev/null +++ b/WebSourceCode/src/Netease/module/yunbei_rcmd_song.js @@ -0,0 +1,22 @@ +// 云贝推歌 + +module.exports = (query, request) => { + const data = { + songId: query.id, + reason: query.reason || '好歌献给你', + scene: '', + fromUserId: -1, + yunbeiNum: query.yunbeiNum || 10, + } + return request( + 'POST', + `https://music.163.com/weapi/yunbei/rcmd/song/submit`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/yunbei_rcmd_song_history.js b/WebSourceCode/src/Netease/module/yunbei_rcmd_song_history.js new file mode 100644 index 0000000..224a4f8 --- /dev/null +++ b/WebSourceCode/src/Netease/module/yunbei_rcmd_song_history.js @@ -0,0 +1,21 @@ +// 云贝推歌历史记录 + +module.exports = (query, request) => { + const data = { + page: JSON.stringify({ + size: query.size || 20, + cursor: query.cursor || '', + }), + } + return request( + 'POST', + `https://music.163.com/weapi/yunbei/rcmd/song/history/list`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/yunbei_receipt.js b/WebSourceCode/src/Netease/module/yunbei_receipt.js new file mode 100644 index 0000000..5eb04ca --- /dev/null +++ b/WebSourceCode/src/Netease/module/yunbei_receipt.js @@ -0,0 +1,17 @@ +module.exports = (query, request) => { + const data = { + limit: query.limit || 10, + offset: query.offset || 0, + } + return request( + 'POST', + `https://music.163.com/store/api/point/receipt`, + data, + { + crypto: 'api', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/yunbei_sign.js b/WebSourceCode/src/Netease/module/yunbei_sign.js new file mode 100644 index 0000000..9765f6d --- /dev/null +++ b/WebSourceCode/src/Netease/module/yunbei_sign.js @@ -0,0 +1,11 @@ +module.exports = (query, request) => { + const data = { + type: '0', + } + return request('POST', `https://music.163.com/api/point/dailyTask`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module/yunbei_task_finish.js b/WebSourceCode/src/Netease/module/yunbei_task_finish.js new file mode 100644 index 0000000..0988ae9 --- /dev/null +++ b/WebSourceCode/src/Netease/module/yunbei_task_finish.js @@ -0,0 +1,17 @@ +module.exports = (query, request) => { + const data = { + userTaskId: query.userTaskId, + depositCode: query.depositCode || '0', + } + return request( + 'POST', + `https://music.163.com/api/usertool/task/point/receive`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/yunbei_tasks.js b/WebSourceCode/src/Netease/module/yunbei_tasks.js new file mode 100644 index 0000000..fdc2d43 --- /dev/null +++ b/WebSourceCode/src/Netease/module/yunbei_tasks.js @@ -0,0 +1,14 @@ +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/api/usertool/task/list/all`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/yunbei_tasks_todo.js b/WebSourceCode/src/Netease/module/yunbei_tasks_todo.js new file mode 100644 index 0000000..a294484 --- /dev/null +++ b/WebSourceCode/src/Netease/module/yunbei_tasks_todo.js @@ -0,0 +1,14 @@ +module.exports = (query, request) => { + const data = {} + return request( + 'POST', + `https://music.163.com/api/usertool/task/todo/query`, + data, + { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }, + ) +} diff --git a/WebSourceCode/src/Netease/module/yunbei_today.js b/WebSourceCode/src/Netease/module/yunbei_today.js new file mode 100644 index 0000000..5b542bf --- /dev/null +++ b/WebSourceCode/src/Netease/module/yunbei_today.js @@ -0,0 +1,9 @@ +module.exports = (query, request) => { + const data = {} + return request('POST', `https://music.163.com/api/point/today/get`, data, { + crypto: 'weapi', + cookie: query.cookie, + proxy: query.proxy, + realIP: query.realIP, + }) +} diff --git a/WebSourceCode/src/Netease/module_example/avatar_upload.js b/WebSourceCode/src/Netease/module_example/avatar_upload.js new file mode 100644 index 0000000..39ea5e5 --- /dev/null +++ b/WebSourceCode/src/Netease/module_example/avatar_upload.js @@ -0,0 +1,20 @@ +const { avatar_upload, login_cellphone } = require('../main') +const fs = require('fs') +const path = require('path') + +async function main() { + const result = await login_cellphone({ + phone: '手机号', + password: '密码', + }) + const filePath = './test.jpg' + await avatar_upload({ + imgFile: { + name: path.basename(filePath), + data: fs.readFileSync(filePath), + }, + imgSize: 1012, //图片尺寸,需要正方形图片 + cookie: result.body.cookie, + }) +} +main() diff --git a/WebSourceCode/src/Netease/module_example/multi_song_upload.js b/WebSourceCode/src/Netease/module_example/multi_song_upload.js new file mode 100644 index 0000000..8e4a8d3 --- /dev/null +++ b/WebSourceCode/src/Netease/module_example/multi_song_upload.js @@ -0,0 +1,104 @@ +const { cloud, login_cellphone } = require('../main') +const fs = require('fs') +const path = require('path') +const yargs = require('yargs') + +const MUSIC_FILE_EXTENSIONS = new Set(['.mp3', '.flac']) + +function getAllMusicFiles(dir, arrayOfFiles) { + arrayOfFiles = arrayOfFiles || [] + + fs.readdirSync(dir).forEach((file) => { + let fullPath = path.join(dir, file) + if (fs.lstatSync(fullPath).isDirectory()) { + getAllMusicFiles(fullPath, arrayOfFiles) + } else { + if (MUSIC_FILE_EXTENSIONS.has(path.extname(fullPath))) { + arrayOfFiles.push(fullPath) + } + } + }) + + return arrayOfFiles +} + +async function uploadArrayOfFile(token, arrayOfFiles) { + let failedFiles = [] + let failed = 0 + const fileCount = arrayOfFiles.length + for (let k in arrayOfFiles) { + const file = arrayOfFiles[k] + try { + await cloud({ + songFile: { + name: path.basename(file), + data: fs.readFileSync(file), + }, + cookie: token.body.cookie, + }) + } catch (error) { + console.log(error) + failed += 1 + failedFiles.push(file) + } + console.log(`Uploaded ${k + 1}/${fileCount} songs`) + } + return { failedFiles, failed } +} + +function getParsedArgs() { + return yargs(process.argv.slice(2)) + .option('country_code', { + default: '86', + describe: 'The country code of your phone number', + type: 'string', + }) + .option('phone_number', { + demandOption: true, + describe: 'Your phone number', + type: 'string', + }) + .option('password', { + demandOption: true, + describe: 'Your password', + type: 'string', + }) + .option('file', { + describe: 'The absolute path to the single music file to be uploaded', + type: 'string', + }) + .option('dir', { + describe: 'The absolute to the directory of music files to be uploaded', + type: 'string', + }) + .conflicts('file', 'dir') + .help() + .alias('help', 'h').argv +} + +async function main() { + const args = getParsedArgs() + const token = await login_cellphone({ + countrycode: args.country_code, + phone: args.phone_number, + password: args.password, + }) + const files = args.file ? [args.file] : getAllMusicFiles(args.dir) + const fileCount = files.length + + console.log(`Found ${fileCount} files, uploading...`) + let res = await uploadArrayOfFile(token, files) + if (res.failed) { + console.log(`Failed to upload ${res.failed} songs, retrying...`) + res = await uploadArrayOfFile(token, res.failedFiles) + } + + console.log(`Uploaded ${fileCount - res.failed} songs`) + console.log( + `Failed to upload ${res.failed} songs, you can reupload the files below`, + ) + for (let k in res.failedFiles) { + console.log(res.failedFiles[k]) + } +} +main() diff --git a/WebSourceCode/src/Netease/module_example/song_upload.js b/WebSourceCode/src/Netease/module_example/song_upload.js new file mode 100644 index 0000000..6973301 --- /dev/null +++ b/WebSourceCode/src/Netease/module_example/song_upload.js @@ -0,0 +1,23 @@ +const { cloud, login_cellphone } = require('../main') +const fs = require('fs') +const path = require('path') + +async function main() { + const result = await login_cellphone({ + phone: '手机号', + password: '密码', + }) + const filePath = './test.mp3' + try { + await cloud({ + songFile: { + name: path.basename(filePath), + data: fs.readFileSync(filePath), + }, + cookie: result.body.cookie, + }) + } catch (error) { + console.log(error, 'error') + } +} +main() diff --git a/WebSourceCode/src/Netease/module_example/test.jpg b/WebSourceCode/src/Netease/module_example/test.jpg new file mode 100644 index 0000000..790c2e7 Binary files /dev/null and b/WebSourceCode/src/Netease/module_example/test.jpg differ diff --git a/WebSourceCode/src/Netease/module_example/test.js b/WebSourceCode/src/Netease/module_example/test.js new file mode 100644 index 0000000..1a019d7 --- /dev/null +++ b/WebSourceCode/src/Netease/module_example/test.js @@ -0,0 +1,31 @@ +const { + login_cellphone, + user_cloud, + album_sublist, + song_url, +} = require('../main') +async function test() { + try { + const result = await login_cellphone({ + phone: '手机号', + password: '密码', + }) + console.log(result) + const result2 = await user_cloud({ + cookie: result.body.cookie, + }) + console.log(result2.body) + const result3 = await album_sublist({ + cookie: result.body.cookie, + }) + console.log(result3.body) + const result4 = await song_url({ + cookie: result.body.cookie, + id: 33894312, + }) + console.log(result4.body) + } catch (error) { + console.log(error) + } +} +test() diff --git a/WebSourceCode/src/Netease/module_example/test.mp3 b/WebSourceCode/src/Netease/module_example/test.mp3 new file mode 100644 index 0000000..e85b76e Binary files /dev/null and b/WebSourceCode/src/Netease/module_example/test.mp3 differ diff --git a/WebSourceCode/src/Netease/module_example/test.ts b/WebSourceCode/src/Netease/module_example/test.ts new file mode 100644 index 0000000..c5c1751 --- /dev/null +++ b/WebSourceCode/src/Netease/module_example/test.ts @@ -0,0 +1,9 @@ +import { banner, lyric } from 'NeteaseCloudMusicApi' +banner({ type: 0 }).then((res) => { + console.log(res) +}) +lyric({ + id: '33894312', +}).then((res) => { + console.log(res) +}) diff --git a/WebSourceCode/src/Netease/package-lock.json b/WebSourceCode/src/Netease/package-lock.json new file mode 100644 index 0000000..0c0f55e --- /dev/null +++ b/WebSourceCode/src/Netease/package-lock.json @@ -0,0 +1,5170 @@ +{ + "name": "NeteaseCloudMusicApi", + "version": "4.10.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/generator": { + "version": "7.18.2", + "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.18.2.tgz", + "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", + "dev": true, + "requires": { + "@babel/types": "^7.18.2", + "@jridgewell/gen-mapping": "^0.3.0", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true + }, + "@babel/parser": { + "version": "7.18.4", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.18.4.tgz", + "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==", + "dev": true + }, + "@babel/types": { + "version": "7.18.4", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.18.4.tgz", + "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + }, + "@eslint/eslintrc": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", + "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.2.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", + "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@tokenizer/token": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.1.1.tgz", + "integrity": "sha512-XO6INPbZCxdprl+9qa/AAbFFOMzzwqYxpjPgLICrMD6C2FCw6qfJOPcBk6JqqPLSaZ/Qx87qn4rpPmPMwaAK6w==" + }, + "@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==" + }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/busboy": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-0.3.2.tgz", + "integrity": "sha512-iEvdm9Z9KdSs/ozuh1Z7ZsXrOl8F4M/CLMXPZHr3QuJ4d6Bjn+HBMC5EMKpwpAo8oi8iK9GZfFoHaIMrrZgwVw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-fileupload": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/express-fileupload/-/express-fileupload-1.2.2.tgz", + "integrity": "sha512-sWU1EVFfLsdAginKVrkwTRbRPnbn7dawxEFEBgaRDcpNFCUuksZtASaAKEhqwEIg6fSdeTyI6dIUGl3thhrypg==", + "dev": true, + "requires": { + "@types/busboy": "^0", + "@types/express": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "@types/mocha": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz", + "integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==", + "dev": true + }, + "@types/node": { + "version": "16.11.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.19.tgz", + "integrity": "sha512-BPAcfDPoHlRQNKktbsbnpACGdypPFBuX4xQlsWDE7B8XXcfII+SpOLay3/qZmCLb39kV5S1RTYwXdkx2lwLYng==" + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "@types/readable-stream": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.9.tgz", + "integrity": "sha512-sqsgQqFT7HmQz/V5jH1O0fvQQnXAJO46Gg9LRO/JPfjmVmGUlcx831TZZO3Y3HtWhIkzf3kTsNT0Z0kzIhIvZw==", + "requires": { + "@types/node": "*", + "safe-buffer": "*" + } + }, + "@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.0.0.tgz", + "integrity": "sha512-T6V6fCD2U0YesOedvydTnrNtsC8E+c2QzpawIpDdlaObX0OX5dLo7tLU5c64FhTZvA1Xrdim+cXDI7NPsVx8Cg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "5.0.0", + "@typescript-eslint/scope-manager": "5.0.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.0.0.tgz", + "integrity": "sha512-Dnp4dFIsZcPawD6CT1p5NibNUQyGSEz80sULJZkyhyna8AEqArmfwMwJPbmKzWVo4PabqNVzHYlzmcdLQWk+pg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "5.0.0", + "@typescript-eslint/types": "5.0.0", + "@typescript-eslint/typescript-estree": "5.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.0.0.tgz", + "integrity": "sha512-B6D5rmmQ14I1fdzs71eL3DAuvnPHTY/t7rQABrL9BLnx/H51Un8ox1xqYAchs0/V2trcoyxB1lMJLlrwrJCDgw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.0.0", + "@typescript-eslint/types": "5.0.0", + "@typescript-eslint/typescript-estree": "5.0.0", + "debug": "^4.3.1" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.0.0.tgz", + "integrity": "sha512-5RFjdA/ain/MDUHYXdF173btOKncIrLuBmA9s6FJhzDrRAyVSA+70BHg0/MW6TE+UiKVyRtX91XpVS0gVNwVDQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.0.0", + "@typescript-eslint/visitor-keys": "5.0.0" + } + }, + "@typescript-eslint/types": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.0.0.tgz", + "integrity": "sha512-dU/pKBUpehdEqYuvkojmlv0FtHuZnLXFBn16zsDmlFF3LXkOpkAQ2vrKc3BidIIve9EMH2zfTlxqw9XM0fFN5w==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.0.0.tgz", + "integrity": "sha512-V/6w+PPQMhinWKSn+fCiX5jwvd1vRBm7AX7SJQXEGQtwtBvjMPjaU3YTQ1ik2UF1u96X7tsB96HMnulG3eLi9Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.0.0", + "@typescript-eslint/visitor-keys": "5.0.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.0.0.tgz", + "integrity": "sha512-yRyd2++o/IrJdyHuYMxyFyBhU762MRHQ/bAGQeTnN3pGikfh+nEmM61XTqaDH1XDp53afZ+waXrk0ZvenoZ6xw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.0.0", + "eslint-visitor-keys": "^3.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz", + "integrity": "sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==", + "dev": true + } + } + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "acorn-es7-plugin": { + "version": "1.1.7", + "resolved": "https://registry.npm.taobao.org/acorn-es7-plugin/download/acorn-es7-plugin-1.1.7.tgz", + "integrity": "sha1-8u4fMiipDurRJF+asZIusucdM2s=", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npm.taobao.org/agent-base/download/agent-base-6.0.2.tgz?cache=0&sync_timestamp=1603480100923&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fagent-base%2Fdownload%2Fagent-base-6.0.2.tgz", + "integrity": "sha1-Sf/1hXfP7j83F2/qtMIuAPhtf3c=", + "dev": true, + "requires": { + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", + "dev": true + } + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/amdefine/download/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npm.taobao.org/ansi-colors/download/ansi-colors-4.1.1.tgz", + "integrity": "sha1-y7muJWv3UK8eqzRPIpqif+lLo0g=", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmmirror.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "array-filter": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/array-filter/download/array-filter-1.0.0.tgz", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=", + "dev": true + }, + "array-find": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/array-find/download/array-find-1.0.0.tgz", + "integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz?cache=0&sync_timestamp=1574313384951&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "requires": { + "tslib": "^2.0.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "axios": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.2.2.tgz", + "integrity": "sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "basic-ftp": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.3.tgz", + "integrity": "sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz?cache=0&sync_timestamp=1601898189928&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrace-expansion%2Fdownload%2Fbrace-expansion-1.1.11.tgz", + "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz", + "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "requires": { + "streamsearch": "^1.1.0" + } + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "call-matcher": { + "version": "1.1.0", + "resolved": "https://registry.npm.taobao.org/call-matcher/download/call-matcher-1.1.0.tgz", + "integrity": "sha1-I7LBvHqDlMi+KGCdd929V4ZoBDI=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "deep-equal": "^1.0.0", + "espurify": "^1.6.0", + "estraverse": "^4.0.0" + } + }, + "call-signature": { + "version": "0.0.2", + "resolved": "https://registry.npm.taobao.org/call-signature/download/call-signature-0.0.2.tgz", + "integrity": "sha1-qEq8glpV70yysCi9dOIFpluaSZY=", + "dev": true + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npm.taobao.org/callsites/download/callsites-3.1.0.tgz", + "integrity": "sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M=", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz", + "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz", + "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz", + "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz", + "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611709087&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz", + "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz", + "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz", + "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npm.taobao.org/convert-source-map/download/convert-source-map-1.7.0.tgz?cache=0&sync_timestamp=1573003637425&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconvert-source-map%2Fdownload%2Fconvert-source-map-1.7.0.tgz", + "integrity": "sha1-F6LLiC1/d9NJBYXizmxSRCSjpEI=", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npm.taobao.org/core-js/download/core-js-2.6.11.tgz?cache=0&sync_timestamp=1586450269267&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-2.6.11.tgz", + "integrity": "sha1-OIMUafmSK97Y7iHJ3EaYXgOZMIw=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.3.tgz", + "integrity": "sha1-9zqFudXUHQRVUcF34ogtSshXKKY=", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/d/download/d-1.0.1.tgz", + "integrity": "sha1-hpgJU3LVjb7jRv/Qxwk/mfj561o=", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "data-uri-to-buffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-5.0.1.tgz", + "integrity": "sha512-a9l6T1qqDogvvnw0nKlfZzqsyikEBZBClF39V3TFoKhDtGBqHu2HkuomJc02j5zft8zrUaXEuoicLeW54RkzPg==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dev": true, + "requires": { + "mimic-response": "^2.0.0" + } + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/deep-equal/download/deep-equal-1.1.1.tgz", + "integrity": "sha1-tcmMlCzv+vfLBR4k4UNKJaLmB2o=", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmmirror.com/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npm.taobao.org/deep-is/download/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npm.taobao.org/define-properties/download/define-properties-1.1.3.tgz", + "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "degenerator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.0.tgz", + "integrity": "sha512-pdRxyYVe0unlUE/eeXBxFdB8w8J7QNNf7hFE/BKOAlTCz0bkF9h1MC82ii0r1ypqB/PTKYDbg4K9SZT9yfd9Fg==", + "requires": { + "ast-types": "^0.13.4", + "escodegen": "^1.14.3", + "esprima": "^4.0.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "diff-match-patch": { + "version": "1.0.5", + "resolved": "https://registry.npm.taobao.org/diff-match-patch/download/diff-match-patch-1.0.5.tgz", + "integrity": "sha1-q7WE1fEM0Rlt/FWqA3AVkq4/ezc=", + "dev": true + }, + "dijkstrajs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz", + "integrity": "sha1-082BIh4+pAdCz83lVtTpnpjdxxs=" + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0" + } + }, + "domutils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", + "dev": true, + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" + } + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npm.taobao.org/eastasianwidth/download/eastasianwidth-0.2.0.tgz", + "integrity": "sha1-aWzi7Aqg5uqTo5f/zySqeEDIJ8s=", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "empower": { + "version": "1.3.1", + "resolved": "https://registry.npm.taobao.org/empower/download/empower-1.3.1.tgz", + "integrity": "sha1-dol5y7s21x2PXtqrZj3qy52rkWw=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "empower-core": "^1.2.0" + } + }, + "empower-assert": { + "version": "1.1.0", + "resolved": "https://registry.npm.taobao.org/empower-assert/download/empower-assert-1.1.0.tgz", + "integrity": "sha1-jTJ/vmmoivkN2pjRv8mCnSok/WI=", + "dev": true, + "requires": { + "estraverse": "^4.2.0" + } + }, + "empower-core": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/empower-core/download/empower-core-1.2.0.tgz", + "integrity": "sha1-zj+ySE1Rh/opwj+6g0Swsv31YBw=", + "dev": true, + "requires": { + "call-signature": "0.0.2", + "core-js": "^2.0.0" + } + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "dev": true + }, + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npm.taobao.org/es-abstract/download/es-abstract-1.18.0-next.1.tgz?cache=0&sync_timestamp=1601502719982&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fes-abstract%2Fdownload%2Fes-abstract-1.18.0-next.1.tgz", + "integrity": "sha1-bjoKS9pxflAjqzuOkL7DYQjSLGg=", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npm.taobao.org/es-to-primitive/download/es-to-primitive-1.2.1.tgz", + "integrity": "sha1-5VzUyc3BiLzvsDs2bHNjI/xciYo=", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npm.taobao.org/es5-ext/download/es5-ext-0.10.53.tgz", + "integrity": "sha1-k8WjrP2+8nUiCtcmRK0C7hg2jeE=", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npm.taobao.org/es6-iterator/download/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npm.taobao.org/es6-map/download/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npm.taobao.org/es6-set/download/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + }, + "dependencies": { + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npm.taobao.org/es6-symbol/download/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + } + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npm.taobao.org/es6-symbol/download/es6-symbol-3.1.3.tgz", + "integrity": "sha1-utXTwbzawoJp9MszHkMceKxwXRg=", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npm.taobao.org/es6-weak-map/download/es6-weak-map-2.0.3.tgz", + "integrity": "sha1-ttofFswswNm+Q+a9v8Xn383zHVM=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escallmatch": { + "version": "1.5.0", + "resolved": "https://registry.npm.taobao.org/escallmatch/download/escallmatch-1.5.0.tgz", + "integrity": "sha1-UAmdhugJGwkt+N37w/mm+wWgJNA=", + "dev": true, + "requires": { + "call-matcher": "^1.0.0", + "esprima": "^2.0.0" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npm.taobao.org/esprima/download/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + } + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npm.taobao.org/escodegen/download/escodegen-1.14.3.tgz?cache=0&sync_timestamp=1596669832613&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescodegen%2Fdownload%2Fescodegen-1.14.3.tgz", + "integrity": "sha1-TnuB+6YVgdyXWC7XjKt/Do1j9QM=", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npm.taobao.org/escope/download/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.7.0.tgz", + "integrity": "sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.0.5", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.2.0", + "espree": "^9.3.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "eslint-scope": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", + "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", + "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", + "dev": true + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + } + } + }, + "eslint-config-prettier": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "dev": true + }, + "eslint-plugin-html": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-7.1.0.tgz", + "integrity": "sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg==", + "dev": true, + "requires": { + "htmlparser2": "^8.0.1" + } + }, + "eslint-plugin-prettier": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", + "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npm.taobao.org/eslint-scope/download/eslint-scope-5.1.1.tgz?cache=0&sync_timestamp=1599933651660&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-scope%2Fdownload%2Feslint-scope-5.1.1.tgz", + "integrity": "sha1-54blmmbLkrP2wfsNUIqrF0hI9Iw=", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/eslint-visitor-keys/download/eslint-visitor-keys-2.0.0.tgz?cache=0&sync_timestamp=1597435068105&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-visitor-keys%2Fdownload%2Feslint-visitor-keys-2.0.0.tgz", + "integrity": "sha1-If3I+82ceVzAMh8FY3AglXUVEag=", + "dev": true + }, + "espower": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/espower/download/espower-2.1.2.tgz", + "integrity": "sha1-gk+IeI+f7fTPD5KPXhG7kHzpuRg=", + "dev": true, + "requires": { + "array-find": "^1.0.0", + "escallmatch": "^1.5.0", + "escodegen": "^1.7.0", + "escope": "^3.3.0", + "espower-location-detector": "^1.0.0", + "espurify": "^1.3.0", + "estraverse": "^4.1.0", + "source-map": "^0.5.0", + "type-name": "^2.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "espower-loader": { + "version": "1.2.2", + "resolved": "https://registry.npm.taobao.org/espower-loader/download/espower-loader-1.2.2.tgz", + "integrity": "sha1-7bRsPFmga6yOpzppXIblxaC8gto=", + "dev": true, + "requires": { + "convert-source-map": "^1.1.0", + "espower-source": "^2.0.0", + "minimatch": "^3.0.0", + "source-map-support": "^0.4.0", + "xtend": "^4.0.0" + } + }, + "espower-location-detector": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/espower-location-detector/download/espower-location-detector-1.0.0.tgz", + "integrity": "sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU=", + "dev": true, + "requires": { + "is-url": "^1.2.1", + "path-is-absolute": "^1.0.0", + "source-map": "^0.5.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "espower-source": { + "version": "2.3.0", + "resolved": "https://registry.npm.taobao.org/espower-source/download/espower-source-2.3.0.tgz", + "integrity": "sha1-Q+k7LBivUAGL2xvqehJx9KHBJfQ=", + "dev": true, + "requires": { + "acorn": "^5.0.0", + "acorn-es7-plugin": "^1.0.10", + "convert-source-map": "^1.1.1", + "empower-assert": "^1.0.0", + "escodegen": "^1.10.0", + "espower": "^2.1.1", + "estraverse": "^4.0.0", + "merge-estraverse-visitors": "^1.0.0", + "multi-stage-sourcemap": "^0.2.1", + "path-is-absolute": "^1.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "acorn": { + "version": "5.7.4", + "resolved": "https://registry.npm.taobao.org/acorn/download/acorn-5.7.4.tgz", + "integrity": "sha1-Po2KmUfQWZoXltECJddDL0pKz14=", + "dev": true + } + } + }, + "espree": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", + "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", + "dev": true, + "requires": { + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", + "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npm.taobao.org/esprima/download/esprima-4.0.1.tgz", + "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=" + }, + "espurify": { + "version": "1.8.1", + "resolved": "https://registry.npm.taobao.org/espurify/download/espurify-1.8.1.tgz", + "integrity": "sha1-V0bGwatC0wLeEL0dW/fw6MBRUFY=", + "dev": true, + "requires": { + "core-js": "^2.0.0" + } + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npm.taobao.org/esrecurse/download/esrecurse-4.3.0.tgz?cache=0&sync_timestamp=1598898255610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fesrecurse%2Fdownload%2Fesrecurse-4.3.0.tgz", + "integrity": "sha1-eteWTWeauyi+5yzsY3WLHF0smSE=", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npm.taobao.org/estraverse/download/estraverse-5.2.0.tgz?cache=0&sync_timestamp=1596642998635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festraverse%2Fdownload%2Festraverse-5.2.0.tgz", + "integrity": "sha1-MH30JUfmzHMk088DwVXVzbjFOIA=", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npm.taobao.org/estraverse/download/estraverse-4.3.0.tgz?cache=0&sync_timestamp=1596642998635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festraverse%2Fdownload%2Festraverse-4.3.0.tgz", + "integrity": "sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0=" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npm.taobao.org/esutils/download/esutils-2.0.3.tgz", + "integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npm.taobao.org/event-emitter/download/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true + }, + "express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "express-fileupload": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.4.0.tgz", + "integrity": "sha512-RjzLCHxkv3umDeZKeFeMg8w7qe0V09w3B7oGZprr/oO2H/ISCgNzuqzn7gV3HRWb37GjRk429CCpSLS2KNTqMQ==", + "requires": { + "busboy": "^1.6.0" + } + }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npm.taobao.org/ext/download/ext-1.4.0.tgz", + "integrity": "sha1-ia56BxWPedNVF4gpBDJAd+Q3kkQ=", + "dev": true, + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/type/download/type-2.1.0.tgz?cache=0&sync_timestamp=1598016585110&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftype%2Fdownload%2Ftype-2.1.0.tgz", + "integrity": "sha1-m9wixkjPjPht0j0yM2pBz7ZHXj8=", + "dev": true + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npm.taobao.org/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-type": { + "version": "16.5.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", + "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "requires": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + }, + "dependencies": { + "@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" + }, + "token-types": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.0.tgz", + "integrity": "sha512-P0rrp4wUpefLncNamWIef62J0v0kQR/GfDVji9WKY7GDCWy5YbVSrKUTam07iWPZQGy0zWNOfstYTykMmPNR7w==", + "requires": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + } + } + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz", + "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "dev": true + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz", + "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/functional-red-black-tree/download/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmmirror.com/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npm.taobao.org/get-caller-file/download/get-caller-file-2.0.5.tgz", + "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34=" + }, + "get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "get-uri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.1.tgz", + "integrity": "sha512-7ZqONUVqaabogsYNWlYj0t3YZaL6dhuEueZXGF+/YVmf6dHmaFg8/6psJKqhx9QykIDKzpGcy2cn4oV4YC7V/Q==", + "requires": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^5.0.1", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmmirror.com/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", + "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.4.tgz", + "integrity": "sha1-Ila94U02MpWMRl68ltxGfKB6Kfs=" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npm.taobao.org/has/download/has-1.0.3.tgz", + "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "htmlparser2": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", + "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "entities": "^4.3.0" + } + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "http-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "requires": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "dependencies": { + "agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "requires": { + "debug": "^4.3.4" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npm.taobao.org/https-proxy-agent/download/https-proxy-agent-5.0.0.tgz?cache=0&sync_timestamp=1581106803611&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttps-proxy-agent%2Fdownload%2Fhttps-proxy-agent-5.0.0.tgz", + "integrity": "sha1-4qkFQqu2inYuCghQ9sntrf2FBrI=", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz", + "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz", + "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", + "dev": true + } + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "husky": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", + "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz?cache=0&sync_timestamp=1594184264130&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ficonv-lite%2Fdownload%2Ficonv-lite-0.4.24.tgz", + "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npm.taobao.org/import-fresh/download/import-fresh-3.2.1.tgz", + "integrity": "sha1-Yz/2GFBueTr1rJG/SLcmd+FcvmY=", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npm.taobao.org/indexof/download/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "intelli-espower-loader": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/intelli-espower-loader/-/intelli-espower-loader-1.1.0.tgz", + "integrity": "sha512-GmnpIM5tRU5n8R4bQAcu2gJMlfRukrtklbE1auRN8qGK9KSLboGdmHSLSLLnIHKrnRmgWRBXNqy5sIOrbT2l8g==", + "dev": true, + "requires": { + "espower-loader": "^1.0.0" + } + }, + "into-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/into-stream/-/into-stream-6.0.0.tgz", + "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", + "dev": true, + "requires": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + } + }, + "ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npm.taobao.org/is-arguments/download/is-arguments-1.0.4.tgz", + "integrity": "sha1-P6+WbHy6D/Q3+zH2JQCC/PBEjPM=", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npm.taobao.org/is-callable/download/is-callable-1.2.2.tgz?cache=0&sync_timestamp=1600719276620&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-callable%2Fdownload%2Fis-callable-1.2.2.tgz", + "integrity": "sha1-x8ZxXNItTdtI0+GZcCI6zquwgNk=", + "dev": true + }, + "is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npm.taobao.org/is-date-object/download/is-date-object-1.0.2.tgz?cache=0&sync_timestamp=1576729165697&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-date-object%2Fdownload%2Fis-date-object-1.0.2.tgz", + "integrity": "sha1-vac28s2P0G0yhE53Q7+nSUw7/X4=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npm.taobao.org/is-extglob/download/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/is-negative-zero/download/is-negative-zero-2.0.0.tgz", + "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz", + "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/is-regex/download/is-regex-1.1.1.tgz?cache=0&sync_timestamp=1596555762356&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-regex%2Fdownload%2Fis-regex-1.1.1.tgz", + "integrity": "sha1-xvmKrMVG9s7FRooHt7FTq1ZKV7k=", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npm.taobao.org/is-symbol/download/is-symbol-1.0.3.tgz", + "integrity": "sha1-OOEBS55jKb4N6dJKQU/XRB7GGTc=", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npm.taobao.org/is-url/download/is-url-1.2.4.tgz", + "integrity": "sha1-BKTfRtKMTP89c9Af8Gq+sxihqlI=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npm.taobao.org/levn/download/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lilconfig": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz", + "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==", + "dev": true + }, + "lint-staged": { + "version": "12.1.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.1.7.tgz", + "integrity": "sha512-bltv/ejiLWtowExpjU+s5z8j1Byjg9AlmaAjMmqNbIicY69u6sYIwXGg0dCn0TlkrrY2CphtHIXAkbZ+1VoWQQ==", + "dev": true, + "requires": { + "cli-truncate": "^3.1.0", + "colorette": "^2.0.16", + "commander": "^8.3.0", + "debug": "^4.3.3", + "execa": "^5.1.1", + "lilconfig": "2.0.4", + "listr2": "^3.13.5", + "micromatch": "^4.0.4", + "normalize-path": "^3.0.0", + "object-inspect": "^1.11.1", + "string-argv": "^0.3.1", + "supports-color": "^9.2.1", + "yaml": "^1.10.2" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz", + "integrity": "sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==", + "dev": true + }, + "cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "requires": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + } + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + } + }, + "string-width": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.0.tgz", + "integrity": "sha512-7x54QnN21P+XL/v8SuNKvfgsUre6PXpN7mc77N3HlZv+f1SBRGmjxtOud2Z6FZ8DmdkD/IdjCaf9XXbnqmTZGQ==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, + "requires": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "requires": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "merge-estraverse-visitors": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/merge-estraverse-visitors/download/merge-estraverse-visitors-1.0.0.tgz", + "integrity": "sha1-65aDOLXe1c7tgs7AMH3sui2OqZQ=", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmmirror.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "mocha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "multi-stage-sourcemap": { + "version": "0.2.1", + "resolved": "https://registry.npm.taobao.org/multi-stage-sourcemap/download/multi-stage-sourcemap-0.2.1.tgz", + "integrity": "sha1-sJ/IWG6qF/gdV1xK0C4Pej9rEQU=", + "dev": true, + "requires": { + "source-map": "^0.1.34" + }, + "dependencies": { + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.1.43.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "multistream": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/multistream/-/multistream-4.1.0.tgz", + "integrity": "sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==", + "dev": true, + "requires": { + "once": "^1.4.0", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "music-metadata": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/music-metadata/-/music-metadata-7.6.0.tgz", + "integrity": "sha512-XSBNmv+4JwithIharDmqwEVGLqEQ62nvrpSJAc5OQcgciSlTjjZLxmAQRic1AofiMB4t45D4MS4mwGk/5PeVeQ==", + "requires": { + "content-type": "^1.0.4", + "debug": "^4.3.1", + "file-type": "^16.1.0", + "media-typer": "^1.1.0", + "strtok3": "^6.0.4", + "token-types": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "nanoid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true + }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==" + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/next-tick/download/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "node-abi": { + "version": "2.30.1", + "resolved": "https://registry.npmmirror.com/node-abi/-/node-abi-2.30.1.tgz", + "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", + "dev": true, + "requires": { + "semver": "^5.4.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "node-fetch": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/normalize-path/download/normalize-path-3.0.0.tgz", + "integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, + "object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" + }, + "object-is": { + "version": "1.1.3", + "resolved": "https://registry.npm.taobao.org/object-is/download/object-is-1.1.3.tgz?cache=0&sync_timestamp=1601502788762&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject-is%2Fdownload%2Fobject-is-1.1.3.tgz", + "integrity": "sha1-LjueZVYBN0Ve471irsTZCi6hzIE=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/object-keys/download/object-keys-1.1.1.tgz", + "integrity": "sha1-HEfyct8nfzsdrwYWd9nILiMixg4=", + "dev": true + }, + "object.assign": { + "version": "4.1.1", + "resolved": "https://registry.npm.taobao.org/object.assign/download/object.assign-4.1.1.tgz?cache=0&sync_timestamp=1599844927493&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject.assign%2Fdownload%2Fobject.assign-4.1.1.tgz", + "integrity": "sha1-MDhnpmbN1Bk27N7fsfjz4ypHjN0=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.0", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npm.taobao.org/optionator/download/optionator-0.8.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Foptionator%2Fdownload%2Foptionator-0.8.3.tgz", + "integrity": "sha1-hPodA2/p08fiHZmIS2ARZ+yPtJU=", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + }, + "dependencies": { + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + } + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "pac-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.0.tgz", + "integrity": "sha512-t4tRAMx0uphnZrio0S0Jw9zg3oDbz1zVhQ/Vy18FjLfP1XOLNUEjaVxYCYRI6NS+BsMBXKIzV6cTLOkO9AtywA==", + "requires": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.1" + }, + "dependencies": { + "agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "requires": { + "debug": "^4.3.4" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "https-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz", + "integrity": "sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==", + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "pac-resolver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz", + "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==", + "requires": { + "degenerator": "^5.0.0", + "ip": "^1.1.8", + "netmask": "^2.0.2" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/parent-module/download/parent-module-1.0.1.tgz", + "integrity": "sha1-aR0nCeeMefrjoVZiJFLQB2LKqqI=", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npm.taobao.org/path-key/download/path-key-3.1.1.tgz", + "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/path-type/download/path-type-4.0.0.tgz", + "integrity": "sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs=", + "dev": true + }, + "peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==" + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "pkg": { + "version": "5.8.0", + "resolved": "https://registry.npmmirror.com/pkg/-/pkg-5.8.0.tgz", + "integrity": "sha512-8h9PUDYFi+LOMLbIyGRdP21g08mAtHidSpofSrf8LWhxUWGHymaRzcopEGiynB5EhQmZUKM6PQ9kCImV2TpdjQ==", + "dev": true, + "requires": { + "@babel/generator": "7.18.2", + "@babel/parser": "7.18.4", + "@babel/types": "7.18.4", + "chalk": "^4.1.2", + "fs-extra": "^9.1.0", + "globby": "^11.1.0", + "into-stream": "^6.0.0", + "is-core-module": "2.9.0", + "minimist": "^1.2.6", + "multistream": "^4.1.0", + "pkg-fetch": "3.4.2", + "prebuild-install": "6.1.4", + "resolve": "^1.22.0", + "stream-meter": "^1.0.4" + }, + "dependencies": { + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "pkg-fetch": { + "version": "3.4.2", + "resolved": "https://registry.npmmirror.com/pkg-fetch/-/pkg-fetch-3.4.2.tgz", + "integrity": "sha512-0+uijmzYcnhC0hStDjm/cl2VYdrmVVBpe7Q8k9YBojxmR5tG8mvR9/nooQq3QSXiQqORDVOTY3XqMEqJVIzkHA==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "fs-extra": "^9.1.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.6", + "progress": "^2.0.3", + "semver": "^7.3.5", + "tar-fs": "^2.1.1", + "yargs": "^16.2.0" + }, + "dependencies": { + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmmirror.com/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + } + } + }, + "pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==" + }, + "power-assert": { + "version": "1.6.1", + "resolved": "https://registry.npm.taobao.org/power-assert/download/power-assert-1.6.1.tgz", + "integrity": "sha1-soy8Aq6Aiv0UMdDNUJOjmsWlsf4=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "empower": "^1.3.1", + "power-assert-formatter": "^1.4.1", + "universal-deep-strict-equal": "^1.2.1", + "xtend": "^4.0.0" + } + }, + "power-assert-context-formatter": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-context-formatter/download/power-assert-context-formatter-1.2.0.tgz", + "integrity": "sha1-j75yaSKI7FpyA83yFci4OKYGHSo=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "power-assert-context-traversal": "^1.2.0" + } + }, + "power-assert-context-reducer-ast": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-context-reducer-ast/download/power-assert-context-reducer-ast-1.2.0.tgz", + "integrity": "sha1-x8ocnjmm+3F/esX+nnbhkr9SXfM=", + "dev": true, + "requires": { + "acorn": "^5.0.0", + "acorn-es7-plugin": "^1.0.12", + "core-js": "^2.0.0", + "espurify": "^1.6.0", + "estraverse": "^4.2.0" + }, + "dependencies": { + "acorn": { + "version": "5.7.4", + "resolved": "https://registry.npm.taobao.org/acorn/download/acorn-5.7.4.tgz", + "integrity": "sha1-Po2KmUfQWZoXltECJddDL0pKz14=", + "dev": true + } + } + }, + "power-assert-context-traversal": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-context-traversal/download/power-assert-context-traversal-1.2.0.tgz", + "integrity": "sha1-9ucUVLr2QN5cHJwnA0n1yasLLpQ=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "estraverse": "^4.1.0" + } + }, + "power-assert-formatter": { + "version": "1.4.1", + "resolved": "https://registry.npm.taobao.org/power-assert-formatter/download/power-assert-formatter-1.4.1.tgz", + "integrity": "sha1-XcEl7VCj37HdomwZNH879Y7CiEo=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "power-assert-context-formatter": "^1.0.7", + "power-assert-context-reducer-ast": "^1.0.7", + "power-assert-renderer-assertion": "^1.0.7", + "power-assert-renderer-comparison": "^1.0.7", + "power-assert-renderer-diagram": "^1.0.7", + "power-assert-renderer-file": "^1.0.7" + } + }, + "power-assert-renderer-assertion": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-renderer-assertion/download/power-assert-renderer-assertion-1.2.0.tgz", + "integrity": "sha1-Pbb/zaEGs3vB4GQyrQ10imgrFHo=", + "dev": true, + "requires": { + "power-assert-renderer-base": "^1.1.1", + "power-assert-util-string-width": "^1.2.0" + } + }, + "power-assert-renderer-base": { + "version": "1.1.1", + "resolved": "https://registry.npm.taobao.org/power-assert-renderer-base/download/power-assert-renderer-base-1.1.1.tgz", + "integrity": "sha1-lqZQxv0F7hvB9mtUrWFELIs/Y+s=", + "dev": true + }, + "power-assert-renderer-comparison": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-renderer-comparison/download/power-assert-renderer-comparison-1.2.0.tgz", + "integrity": "sha1-5PiBEyJaab6KpYbq0FrvmUYsBJU=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "diff-match-patch": "^1.0.0", + "power-assert-renderer-base": "^1.1.1", + "stringifier": "^1.3.0", + "type-name": "^2.0.1" + } + }, + "power-assert-renderer-diagram": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-renderer-diagram/download/power-assert-renderer-diagram-1.2.0.tgz", + "integrity": "sha1-N/ZuhULlZ3xbWObXKwHA2aMOIhk=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "power-assert-renderer-base": "^1.1.1", + "power-assert-util-string-width": "^1.2.0", + "stringifier": "^1.3.0" + } + }, + "power-assert-renderer-file": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-renderer-file/download/power-assert-renderer-file-1.2.0.tgz", + "integrity": "sha1-P0vr2eFFXXXPKsVB57tRWofUzks=", + "dev": true, + "requires": { + "power-assert-renderer-base": "^1.1.1" + } + }, + "power-assert-util-string-width": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/power-assert-util-string-width/download/power-assert-util-string-width-1.2.0.tgz", + "integrity": "sha1-bgbV41gbuHbF03fFMQn/+pW9kaA=", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0" + } + }, + "prebuild-install": { + "version": "6.1.4", + "resolved": "https://registry.npmmirror.com/prebuild-install/-/prebuild-install-6.1.4.tgz", + "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", + "dev": true, + "requires": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.21.0", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/prelude-ls/download/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qrcode": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.4.4.tgz", + "integrity": "sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q==", + "requires": { + "buffer": "^5.4.3", + "buffer-alloc": "^1.2.0", + "buffer-from": "^1.1.1", + "dijkstrajs": "^1.0.1", + "isarray": "^2.0.1", + "pngjs": "^3.3.0", + "yargs": "^13.2.4" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==" + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true + } + } + }, + "readable-web-to-node-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.0.tgz", + "integrity": "sha512-HNmLb3n0SteGAs8HQlErYPGeO+y7cvL/mVUKtXeUkl0iCZ/2GIgKGrCFHyS7UXFnO8uc9U+0y3pYIzAPsjFfvA==", + "requires": { + "@types/readable-stream": "^2.3.9", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npm.taobao.org/regexp.prototype.flags/download/regexp.prototype.flags-1.3.0.tgz?cache=0&sync_timestamp=1576388141321&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregexp.prototype.flags%2Fdownload%2Fregexp.prototype.flags-1.3.0.tgz", + "integrity": "sha1-erqJs8E6ZFCdq888qNn7ub31y3U=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npm.taobao.org/es-abstract/download/es-abstract-1.17.7.tgz?cache=0&sync_timestamp=1601502719982&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fes-abstract%2Fdownload%2Fes-abstract-1.17.7.tgz", + "integrity": "sha1-pN5hsvZpifx0IWdsHLl4dXOs5Uw=", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npm.taobao.org/require-directory/download/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/resolve-from/download/resolve-from-4.0.0.tgz", + "integrity": "sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY=", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.2.tgz", + "integrity": "sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz", + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" + }, + "safe-decode-uri-component": { + "version": "1.2.1", + "resolved": "https://registry.nlark.com/safe-decode-uri-component/download/safe-decode-uri-component-1.2.1.tgz", + "integrity": "sha1-3dMMV+Z5ejsGcYiDk6SYS0VOISk=" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz", + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/shebang-command/download/shebang-command-2.0.0.tgz", + "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-3.0.0.tgz", + "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true + }, + "simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dev": true, + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + } + } + }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + }, + "socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "requires": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "dependencies": { + "ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + } + } + }, + "socks-proxy-agent": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.1.tgz", + "integrity": "sha512-59EjPbbgg8U3x62hhKOFVAmySQUcfRQ4C7Q/D5sEHnZTQRrQlNKINks44DMR1gwXp0p4LaVIeccX2KHTTcHVqQ==", + "requires": { + "agent-base": "^7.0.1", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "dependencies": { + "agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "requires": { + "debug": "^4.3.4" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.6.1.tgz", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "optional": true + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npm.taobao.org/source-map-support/download/source-map-support-0.4.18.tgz?cache=0&sync_timestamp=1587719289626&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map-support%2Fdownload%2Fsource-map-support-0.4.18.tgz", + "integrity": "sha1-Aoam3ovkJkEzhZTpfM6nXwosWF8=", + "dev": true, + "requires": { + "source-map": "^0.5.6" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, + "stream-meter": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/stream-meter/-/stream-meter-1.0.4.tgz", + "integrity": "sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ==", + "dev": true, + "requires": { + "readable-stream": "^2.1.4" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" + }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + } + } + }, + "string.prototype.trimend": { + "version": "1.0.2", + "resolved": "https://registry.npm.taobao.org/string.prototype.trimend/download/string.prototype.trimend-1.0.2.tgz?cache=0&sync_timestamp=1603219618123&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.trimend%2Fdownload%2Fstring.prototype.trimend-1.0.2.tgz", + "integrity": "sha1-bd2ah5a8cUtImjriIkaiCPN7+kY=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "string.prototype.trimstart": { + "version": "1.0.2", + "resolved": "https://registry.npm.taobao.org/string.prototype.trimstart/download/string.prototype.trimstart-1.0.2.tgz?cache=0&sync_timestamp=1603219618047&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.trimstart%2Fdownload%2Fstring.prototype.trimstart-1.0.2.tgz", + "integrity": "sha1-ItRdqBAVMJzQzdeXh+iRn8XGE+c=", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "stringifier": { + "version": "1.4.0", + "resolved": "https://registry.npm.taobao.org/stringifier/download/stringifier-1.4.0.tgz", + "integrity": "sha1-1wRYFWf0UmJl0A7Y7LNUoCw/7Cg=", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "traverse": "^0.6.6", + "type-name": "^2.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npm.taobao.org/strip-json-comments/download/strip-json-comments-3.1.1.tgz?cache=0&sync_timestamp=1594567532500&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-json-comments%2Fdownload%2Fstrip-json-comments-3.1.1.tgz", + "integrity": "sha1-MfEoGzgyYwQ0gxwxDAHMzajL4AY=", + "dev": true + }, + "strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "requires": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + }, + "dependencies": { + "@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" + } + } + }, + "supports-color": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.1.tgz", + "integrity": "sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ==", + "dev": true + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz", + "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "token-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-2.0.0.tgz", + "integrity": "sha512-WWvu8sGK8/ZmGusekZJJ5NM6rRVTTDO7/bahz4NGiSDb/XsmdYBn6a1N/bymUHuWYTWeuLUg98wUzvE4jPdCZw==", + "requires": { + "@tokenizer/token": "^0.1.0", + "ieee754": "^1.1.13" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npm.taobao.org/traverse/download/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "dev": true + }, + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npm.taobao.org/tunnel/download/tunnel-0.0.6.tgz", + "integrity": "sha1-cvExSzSlsZLbASMk3yzFh8pH+Sw=" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npm.taobao.org/type/download/type-1.2.0.tgz?cache=0&sync_timestamp=1598016585110&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftype%2Fdownload%2Ftype-1.2.0.tgz", + "integrity": "sha1-hI3XaY2vo+VKbEeedZxLw/GIR6A=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npm.taobao.org/type-check/download/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "type-name": { + "version": "2.0.2", + "resolved": "https://registry.npm.taobao.org/type-name/download/type-name-2.0.2.tgz", + "integrity": "sha1-7+fUEj2KxSr/9/QMfk3sUmYAj7Q=", + "dev": true + }, + "typescript": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "dev": true + }, + "universal-deep-strict-equal": { + "version": "1.2.2", + "resolved": "https://registry.npm.taobao.org/universal-deep-strict-equal/download/universal-deep-strict-equal-1.2.2.tgz", + "integrity": "sha1-DaSsL3PP95JMgfpN4BjKViyisKc=", + "dev": true, + "requires": { + "array-filter": "^1.0.0", + "indexof": "0.0.1", + "object-keys": "^1.0.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npm.taobao.org/unpipe/download/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/utils-merge/download/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npm.taobao.org/which/download/which-2.0.2.tgz?cache=0&sync_timestamp=1574116720213&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-2.0.2.tgz", + "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmmirror.com/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npm.taobao.org/word-wrap/download/word-wrap-1.2.3.tgz", + "integrity": "sha1-YQY29rH3A4kb00dxzLF/uTtHB5w=" + }, + "workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npm.taobao.org/wrappy/download/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npm.taobao.org/xtend/download/xtend-4.0.2.tgz", + "integrity": "sha1-u3J3n1+kZRhrH0OPZ0+jR/2121Q=", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + }, + "yargs": { + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.1.1.tgz", + "integrity": "sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/WebSourceCode/src/Netease/package.json b/WebSourceCode/src/Netease/package.json new file mode 100644 index 0000000..919f141 --- /dev/null +++ b/WebSourceCode/src/Netease/package.json @@ -0,0 +1,98 @@ +{ + "name": "NeteaseCloudMusicApi", + "version": "4.12.2", + "description": "网易云音乐 NodeJS 版 API", + "scripts": { + "start": "node app.js", + "test": "mocha -r intelli-espower-loader -t 60000 server.test.js main.test.js --exit", + "lint": "eslint \"**/*.{js,ts}\"", + "lint-fix": "eslint --fix \"**/*.{js,ts}\"", + "prepare": "husky install", + "pkgwin": "pkg . -t node14-win-x64 -C GZip -o bin/app --no-bytecode", + "pkglinux": "pkg . -t node14-linux-x64 -C GZip -o bin/app --no-bytecode", + "pkgmacos": "pkg . -t node14-macos-x64 -C GZip -o bin/app --no-bytecode" + }, + "bin": "./app.js", + "pkg": { + "scripts": "module/*.js", + "assets": [ + "node_modules/axios", + "node_modules/express", + "node_modules/express-fileupload", + "node_modules/md5", + "node_modules/music-metadata", + "node_modules/pac-proxy-agent", + "node_modules/qrcode", + "node_modules/safe-decode-uri-component", + "node_modules/tunnel", + "node_modules/yargs", + "node_modules/tslib", + "node_modules/vm2", + "module", + "public" + ] + }, + "keywords": [ + "网易云音乐", + "网易云", + "音乐", + "网易云音乐nodejs" + ], + "main": "main.js", + "types": "./interface.d.ts", + "engines": { + "node": ">=12" + }, + "lint-staged": { + "*.js": [ + "eslint --fix", + "git add" + ] + }, + "author": "binaryify", + "license": "MIT", + "files": [ + "module", + "util", + "plugins", + "main.d.ts", + "interface.d.ts", + "module_types", + "server.js", + "generateConfig.js", + "public" + ], + "dependencies": { + "axios": "^1.2.2", + "express": "^4.17.1", + "express-fileupload": "^1.1.9", + "md5": "^2.3.0", + "music-metadata": "^7.5.3", + "pac-proxy-agent": "^7.0.0", + "qrcode": "^1.4.4", + "safe-decode-uri-component": "^1.2.1", + "tunnel": "^0.0.6", + "xml2js": "^0.6.2", + "yargs": "^17.1.1" + }, + "devDependencies": { + "@types/express": "^4.17.13", + "@types/express-fileupload": "^1.2.2", + "@types/mocha": "^9.1.0", + "@types/node": "16.11.19", + "@typescript-eslint/eslint-plugin": "5.0.0", + "@typescript-eslint/parser": "5.0.0", + "eslint": "8.7.0", + "eslint-config-prettier": "8.5.0", + "eslint-plugin-html": "7.1.0", + "eslint-plugin-prettier": "4.0.0", + "husky": "7.0.4", + "intelli-espower-loader": "1.1.0", + "lint-staged": "12.1.7", + "mocha": "10.0.0", + "pkg": "^5.8.0", + "power-assert": "1.6.1", + "prettier": "2.7.1", + "typescript": "4.5.2" + } +} diff --git a/WebSourceCode/src/Netease/plugins/songUpload.js b/WebSourceCode/src/Netease/plugins/songUpload.js new file mode 100644 index 0000000..fc59700 --- /dev/null +++ b/WebSourceCode/src/Netease/plugins/songUpload.js @@ -0,0 +1,50 @@ +const { default: axios } = require('axios') +module.exports = async (query, request) => { + let ext = 'mp3' + if (query.songFile.name.indexOf('flac') > -1) { + ext = 'flac' + } + const filename = query.songFile.name + .replace('.' + ext, '') + .replace(/\s/g, '') + .replace(/\./g, '_') + // 获取key和token + const tokenRes = await request( + 'POST', + `https://music.163.com/weapi/nos/token/alloc`, + { + bucket: 'jd-musicrep-privatecloud-audio-public', + ext: ext, + filename: filename, + local: false, + nos_product: 3, + type: 'audio', + md5: query.songFile.md5, + }, + { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy }, + ) + + // 上传 + const objectKey = tokenRes.body.result.objectKey.replace('/', '%2F') + try { + await axios({ + method: 'post', + url: `http://45.127.129.8/jd-musicrep-privatecloud-audio-public/${objectKey}?offset=0&complete=true&version=1.0`, + headers: { + 'x-nos-token': tokenRes.body.result.token, + 'Content-MD5': query.songFile.md5, + 'Content-Type': 'audio/mpeg', + 'Content-Length': String(query.songFile.size), + }, + data: query.songFile.data, + maxContentLength: Infinity, + maxBodyLength: Infinity, + }) + } catch (error) { + console.log('error', error.response) + throw error.response + } + return { + ...tokenRes, + } +} diff --git a/WebSourceCode/src/Netease/plugins/upload.js b/WebSourceCode/src/Netease/plugins/upload.js new file mode 100644 index 0000000..a403553 --- /dev/null +++ b/WebSourceCode/src/Netease/plugins/upload.js @@ -0,0 +1,48 @@ +const { default: axios } = require('axios') +module.exports = async (query, request) => { + const data = { + bucket: 'yyimgs', + ext: 'jpg', + filename: query.imgFile.name, + local: false, + nos_product: 0, + return_body: `{"code":200,"size":"$(ObjectSize)"}`, + type: 'other', + } + // 获取key和token + const res = await request( + 'POST', + `https://music.163.com/weapi/nos/token/alloc`, + data, + { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy }, + ) + // 上传图片 + const res2 = await axios({ + method: 'post', + url: `https://nosup-hz1.127.net/yyimgs/${res.body.result.objectKey}?offset=0&complete=true&version=1.0`, + headers: { + 'x-nos-token': res.body.result.token, + 'Content-Type': 'image/jpeg', + }, + data: query.imgFile.data, + }) + // 获取裁剪后图片的id + const imgSize = query.imgSize || 300 + const imgX = query.imgX || 0 + const imgY = query.imgY || 0 + const res3 = await request( + 'POST', + `https://music.163.com/upload/img/op?id=${res.body.result.docId}&op=${imgX}y${imgY}y${imgSize}y${imgSize}`, + {}, + { crypto: 'weapi', cookie: query.cookie, proxy: query.proxy }, + ) + + return { + // ...res.body.result, + // ...res2.data, + // ...res3.body, + url_pre: 'https://p1.music.126.net/' + res.body.result.objectKey, + url: res3.body.url, + imgId: res3.body.id, + } +} diff --git a/WebSourceCode/src/Netease/public/audio_match_demo/afp.js b/WebSourceCode/src/Netease/public/audio_match_demo/afp.js new file mode 100644 index 0000000..605e599 --- /dev/null +++ b/WebSourceCode/src/Netease/public/audio_match_demo/afp.js @@ -0,0 +1,1664 @@ +// https://fn.music.163.com/g/chrome-extension-home-page-beta/ +let AudioFingerprintRuntime = (() => { + var n, o = void 0 !== o ? o : {},i = {}; + for (n in o) + o.hasOwnProperty(n) && (i[n] = o[n]); + var read_, readAsync, readBinary, c, f, l = [], + p = "./this.program", + ENVIRONMENT_IS_WEB = "object" == typeof window, + ENVIRONMENT_IS_WORKER = "function" == typeof importScripts, + ENVIRONMENT_IS_NODE = "object" == typeof process && "object" == typeof process.versions && "string" == typeof process.versions.node, + m = ""; + ENVIRONMENT_IS_NODE ? ( + m = ENVIRONMENT_IS_WORKER ? path.dirname(m) + "/" : "//", + read_ = function shell_read(t, e) { + return c || (c = fs), + f || (f = path), + t = f.normalize(t), + c.readFileSync(t, e ? null : "utf8") + }, + readBinary = function(t) { + var e = read_(t, !0); + return e.buffer || (e = new Uint8Array(e)), + T(e.buffer), + e + } + , + u = function (t, e, n) { + c || (c = r(194)), + f || (f = r(997)), + t = f.normalize(t), + c.readFile(t, (function(t, r) { + t ? n(t) : e(r.buffer) + })) + }, + process.argv.length > 1 && (p = process.argv[1].replace(/\\/g, "/")), + l = process.argv.slice(2), + process.on("uncaughtException", (function(t) { + if (!(t instanceof ExitStatus)) + throw t + })), + process.on("unhandledRejection", (function(t) { + throw t + })), + function logExceptionOnExit(t, e) { + if (_) + throw process.exitCode = t, + e; + var r; + (r = e) instanceof ExitStatus || g("exiting due to exception: " + r), + process.exit(t) + }, + o.inspect = function() { + return "[Emscripten Module object]" + } + ) : (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && (ENVIRONMENT_IS_WORKER ? m = self.location.href : "undefined" != typeof document && document.currentScript && (m = document.currentScript.src), + m = 0 !== m.indexOf("blob:") ? m.substr(0, m.replace(/[?#].*/, "").lastIndexOf("/") + 1) : "", + read_ = function(t) { + var e = new XMLHttpRequest; + return e.open("GET", t, !1), + e.send(null), + e.responseText + }, + ENVIRONMENT_IS_WORKER && (readBinary = function(t) { + var e = new XMLHttpRequest; + return e.open("GET", t, !1), + e.responseType = "arraybuffer", + e.send(null), + new Uint8Array(e.response) + }), + readAsync = function(t, e, r) { + var n = new XMLHttpRequest; + n.open("GET", t, !0), + n.responseType = "arraybuffer", + n.onload = function() { + 200 == n.status || 0 == n.status && n.response ? e(n.response) : r() + }, + n.onerror = r, + n.send(null) + } + ); + var v = o.print || console.log.bind(console), + g = o.printErr || console.warn.bind(console); + for (n in i) + i.hasOwnProperty(n) && (o[n] = i[n]); + i = null, + o.arguments && (l = o.arguments), + o.thisProgram && (p = o.thisProgram), + o.quit && o.quit; + var w; + o.wasmBinary && (w = o.wasmBinary); + var b, _ = o.noExitRuntime || !0; + "object" != typeof WebAssembly && abort("no native wasm support detected"); + var C = !1; + + function T(t, e) { + t || abort("Assertion failed: " + e) + } + var UTF8Decoder = "undefined" != typeof TextDecoder ? new TextDecoder("utf8") : void 0; + + function UTF8ArrayToString(heap, idx, maxBytesToRead) { + var endIdx = idx + maxBytesToRead; + var endPtr = idx; + while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr; + if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) { + return UTF8Decoder.decode(heap.subarray(idx, endPtr)) + } else { + var str = ""; + while (idx < endPtr) { + var u0 = heap[idx++]; + if (!(u0 & 128)) { + str += String.fromCharCode(u0); + continue + } + var u1 = heap[idx++] & 63; + if ((u0 & 224) == 192) { + str += String.fromCharCode((u0 & 31) << 6 | u1); + continue + } + var u2 = heap[idx++] & 63; + if ((u0 & 240) == 224) { + u0 = (u0 & 15) << 12 | u1 << 6 | u2 + } else { + u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[idx++] & 63 + } + if (u0 < 65536) { + str += String.fromCharCode(u0) + } else { + var ch = u0 - 65536; + str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023) + } + } + } + return str + } + + function UTF8ToString(ptr, maxBytesToRead) { + return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "" + } + function UTF8ToString(t, e) { + return t ? UTF8ArrayToString(O, t, e) : "" + } + + + function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { + if (!(maxBytesToWrite > 0)) return 0; + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; + for (var i = 0; i < str.length; ++i) { + var u = str.charCodeAt(i); + if (u >= 55296 && u <= 57343) { + var u1 = str.charCodeAt(++i); + u = 65536 + ((u & 1023) << 10) | u1 & 1023 + } + if (u <= 127) { + if (outIdx >= endIdx) break; + heap[outIdx++] = u + } else if (u <= 2047) { + if (outIdx + 1 >= endIdx) break; + heap[outIdx++] = 192 | u >> 6; + heap[outIdx++] = 128 | u & 63 + } else if (u <= 65535) { + if (outIdx + 2 >= endIdx) break; + heap[outIdx++] = 224 | u >> 12; + heap[outIdx++] = 128 | u >> 6 & 63; + heap[outIdx++] = 128 | u & 63 + } else { + if (outIdx + 3 >= endIdx) break; + heap[outIdx++] = 240 | u >> 18; + heap[outIdx++] = 128 | u >> 12 & 63; + heap[outIdx++] = 128 | u >> 6 & 63; + heap[outIdx++] = 128 | u & 63 + } + } + heap[outIdx] = 0; + return outIdx - startIdx + } + + + function UTF8CharCount(t) { + for (var e = 0, r = 0; r < t.length; ++r) { + var n = t.charCodeAt(r); + n >= 55296 && n <= 57343 && (n = 65536 + ((1023 & n) << 10) | 1023 & t.charCodeAt(++r)), + n <= 127 ? ++e : e += n <= 2047 ? 2 : n <= 65535 ? 3 : 4 + } + return e + } + var E, S, O, k, W, j, R, M, I, UTF16Decoder = "undefined" != typeof TextDecoder ? new TextDecoder("utf-16le") : void 0; + + function UTF16ArrayToString(t, e) { + for (var r = t, n = r >> 1, o = n + e / 2; !(n >= o) && W[n];) + ++n; + if ((r = n << 1) - t > 32 && UTF16Decoder) + return UTF16Decoder.decode(O.subarray(t, r)); + for (var i = "", a = 0; !(a >= e / 2); ++a) { + var u = k[t + 2 * a >> 1]; + if (0 == u) + break; + i += String.fromCharCode(u) + } + return i + } + + function H(t, e, r) { + if (void 0 === r && (r = 2147483647), + r < 2) + return 0; + for (var n = e, o = (r -= 2) < 2 * t.length ? r / 2 : t.length, i = 0; i < o; ++i) { + var a = t.charCodeAt(i); + k[e >> 1] = a, + e += 2 + } + return k[e >> 1] = 0, + e - n + } + + function Y(t) { + return 2 * t.length + } + + function V(t, e) { + for (var r = 0, n = ""; !(r >= e / 4);) { + var o = j[t + 4 * r >> 2]; + if (0 == o) + break; + if (++r, + o >= 65536) { + var i = o - 65536; + n += String.fromCharCode(55296 | i >> 10, 56320 | 1023 & i) + } else + n += String.fromCharCode(o) + } + return n + } + + function z(t, e, r) { + if (void 0 === r && (r = 2147483647), + r < 4) + return 0; + for (var n = e, o = n + r - 4, i = 0; i < t.length; ++i) { + var a = t.charCodeAt(i); + if (a >= 55296 && a <= 57343) + a = 65536 + ((1023 & a) << 10) | 1023 & t.charCodeAt(++i); + if (j[e >> 2] = a, + (e += 4) + 4 > o) + break + } + return j[e >> 2] = 0, + e - n + } + + function B(t) { + for (var e = 0, r = 0; r < t.length; ++r) { + var n = t.charCodeAt(r); + n >= 55296 && n <= 57343 && ++r, + e += 4 + } + return e + } + o.INITIAL_MEMORY; + var L, G = [], + N = [], + q = []; + var J = 0, + X = null, + Z = null; + + function abort(what) { + throw o.onAbort && o.onAbort(what), + g(what = "Aborted(" + what + ")"), + C = !0, + 1, + what += ". Build with -s ASSERTIONS=1 for more info.", + new WebAssembly.RuntimeError(what) + } + o.preloadedImages = {}, + o.preloadedAudios = {}; + var Q; + + function isDataURI(t) { + return t.startsWith("data:application/octet-stream;base64,") + } + + function isFileURI(t) { + return t.startsWith("file://") + } + + function getBinary(file) { + try { + if (file == Q && w) + return new Uint8Array(w); + if (readBinary) + return readBinary(file); + throw "both async and sync fetching of the wasm failed" + } catch (t) { + abort(t) + } + } + + function callRuntimeCallbacks(cb) { + for (; cb.length > 0;) { + var func = cb.shift(); + if ("function" != typeof func) { + var r = func.func; + "number" == typeof r ? void 0 === func.arg ? it(r)() : it(r)(func.arg) : r(void 0 === func.arg ? null : func.arg) + } else + func(o) + } + } + var wasmBinaryFile = "afp.wasm"; + isDataURI(wasmBinaryFile) || (Q = function(t) { + return wasmBinaryFile + }(Q)); + var ot = []; + + function it(t) { + var e = ot[t]; + return e || (t >= ot.length && (ot.length = t + 1), + ot[t] = e = L.get(t)), + e + } + + function ExceptionInfo(excPtr) { + this.excPtr = excPtr, + this.ptr = excPtr - 16, + this.set_type = function(t) { + j[this.ptr + 4 >> 2] = t + }, + this.get_type = function() { + return j[this.ptr + 4 >> 2] + }, + this.set_destructor = function(t) { + j[this.ptr + 8 >> 2] = t + }, + this.get_destructor = function() { + return j[this.ptr + 8 >> 2] + }, + this.set_refcount = function(t) { + j[this.ptr >> 2] = t + }, + this.set_caught = function(t) { + t = t ? 1 : 0, + S[this.ptr + 12 >> 0] = t + }, + this.get_caught = function() { + return 0 != S[this.ptr + 12 >> 0] + }, + this.set_rethrown = function(t) { + t = t ? 1 : 0, + S[this.ptr + 13 >> 0] = t + }, + this.get_rethrown = function() { + return 0 != S[this.ptr + 13 >> 0] + }, + this.init = function(t, e) { + this.set_type(t), + this.set_destructor(e), + this.set_refcount(0), + this.set_caught(!1), + this.set_rethrown(!1) + }, + this.add_ref = function() { + var t = j[this.ptr >> 2]; + j[this.ptr >> 2] = t + 1 + }, + this.release_ref = function() { + var t = j[this.ptr >> 2]; + return j[this.ptr >> 2] = t - 1, + 1 === t + } + } + + function ut(t) { + switch (t) { + case 1: + return 0; + case 2: + return 1; + case 4: + return 2; + case 8: + return 3; + default: + throw new TypeError("Unknown type size: " + t) + } + } + var st = void 0; + + function ct(t) { + for (var e = "", r = t; O[r];) + e += st[O[r++]]; + return e + } + var ft = {}, + lt = {}, + pt = {}; + + function dt(t) { + if (void 0 === t) + return "_unknown"; + var e = (t = t.replace(/[^a-zA-Z0-9_]/g, "$")).charCodeAt(0); + return e >= 48 && e <= 57 ? "_" + t : t + } + + function ht(t, e) { + return t = dt(t), + new Function("body", "return function " + t + '() {\n "use strict"; return body.apply(this, arguments);\n};\n')(e) + } + + function yt(t, e) { + var r = ht(e, (function(t) { + this.name = e, + this.message = t; + var r = new Error(t).stack; + void 0 !== r && (this.stack = this.toString() + "\n" + r.replace(/^Error(:[^\n]*)?\n/, "")) + })); + return r.prototype = Object.create(t.prototype), + r.prototype.constructor = r, + r.prototype.toString = function() { + return void 0 === this.message ? this.name : this.name + ": " + this.message + }, + r + } + var mt = void 0; + + function vt(t) { + throw new mt(t) + } + var gt = void 0; + + function wt(t) { + throw new gt(t) + } + + function bt(t, e, r) { + function n(e) { + var n = r(e); + n.length !== t.length && wt("Mismatched type converter count"); + for (var o = 0; o < t.length; ++o) + _t(t[o], n[o]) + } + t.forEach((function(t) { + pt[t] = e + })); + var o = new Array(e.length), + i = [], + a = 0; + e.forEach((function(t, e) { + lt.hasOwnProperty(t) ? o[e] = lt[t] : (i.push(t), + ft.hasOwnProperty(t) || (ft[t] = []), + ft[t].push((function() { + o[e] = lt[t], + ++a === i.length && n(o) + }))) + })), + 0 === i.length && n(o) + } + + function _t(t, e, r) { + if (r = r || {}, + !("argPackAdvance" in e)) + throw new TypeError("registerType registeredInstance requires argPackAdvance"); + var n = e.name; + if (t || vt('type "' + n + '" must have a positive integer typeid pointer'), + lt.hasOwnProperty(t)) { + if (r.ignoreDuplicateRegistrations) + return; + vt("Cannot register type '" + n + "' twice") + } + if (lt[t] = e, + delete pt[t], + ft.hasOwnProperty(t)) { + var o = ft[t]; + delete ft[t], + o.forEach((function(t) { + t() + })) + } + } + + function Ct(t) { + if (!(this instanceof Rt)) + return !1; + if (!(t instanceof Rt)) + return !1; + for (var e = this.$$.ptrType.registeredClass, r = this.$$.ptr, n = t.$$.ptrType.registeredClass, o = t.$$.ptr; e.baseClass;) + r = e.upcast(r), + e = e.baseClass; + for (; n.baseClass;) + o = n.upcast(o), + n = n.baseClass; + return e === n && r === o + } + + function Tt(t) { + vt(t.$$.ptrType.registeredClass.name + " instance already deleted") + } + var $t = !1; + + function Pt(t) {} + + function At(t) { + t.count.value -= 1, + 0 === t.count.value && function(t) { + t.smartPtr ? t.smartPtrType.rawDestructor(t.smartPtr) : t.ptrType.registeredClass.rawDestructor(t.ptr) + }(t) + } + + function Dt(t) { + return "undefined" == typeof FinalizationRegistry ? (Dt = function(t) { + return t + }, + t) : ($t = new FinalizationRegistry((function(t) { + At(t.$$) + })), + Dt = function(t) { + var e = { + $$: t.$$ + }; + return $t.register(t, e, t), + t + }, + Pt = function(t) { + $t.unregister(t) + }, + Dt(t)) + } + + function Ft() { + if (this.$$.ptr || Tt(this), + this.$$.preservePointerOnDelete) + return this.$$.count.value += 1, + this; + var t, e = Dt(Object.create(Object.getPrototypeOf(this), { + $$: { + value: (t = this.$$, { + count: t.count, + deleteScheduled: t.deleteScheduled, + preservePointerOnDelete: t.preservePointerOnDelete, + ptr: t.ptr, + ptrType: t.ptrType, + smartPtr: t.smartPtr, + smartPtrType: t.smartPtrType + }) + } + })); + return e.$$.count.value += 1, + e.$$.deleteScheduled = !1, + e + } + + function Et() { + this.$$.ptr || Tt(this), + this.$$.deleteScheduled && !this.$$.preservePointerOnDelete && vt("Object already scheduled for deletion"), + Pt(this), + At(this.$$), + this.$$.preservePointerOnDelete || (this.$$.smartPtr = void 0, + this.$$.ptr = void 0) + } + + function St() { + return !this.$$.ptr + } + var Ot = void 0, + kt = []; + + function Wt() { + for (; kt.length;) { + var t = kt.pop(); + t.$$.deleteScheduled = !1, + t.delete() + } + } + + function jt() { + return this.$$.ptr || Tt(this), + this.$$.deleteScheduled && !this.$$.preservePointerOnDelete && vt("Object already scheduled for deletion"), + kt.push(this), + 1 === kt.length && Ot && Ot(Wt), + this.$$.deleteScheduled = !0, + this + } + + function Rt() {} + var Mt = {}; + + function It(t, e, r) { + if (void 0 === t[e].overloadTable) { + var n = t[e]; + t[e] = function() { + return t[e].overloadTable.hasOwnProperty(arguments.length) || vt("Function '" + r + "' called with an invalid number of arguments (" + arguments.length + ") - expects one of (" + t[e].overloadTable + ")!"), + t[e].overloadTable[arguments.length].apply(this, arguments) + }, + t[e].overloadTable = [], + t[e].overloadTable[n.argCount] = n + } + } + + function xt(t, e, r) { + o.hasOwnProperty(t) ? ((void 0 === r || void 0 !== o[t].overloadTable && void 0 !== o[t].overloadTable[r]) && vt("Cannot register public name '" + t + "' twice"), + It(o, t, t), + o.hasOwnProperty(r) && vt("Cannot register multiple overloads of a function with the same number of arguments (" + r + ")!"), + o[t].overloadTable[r] = e) : (o[t] = e, + void 0 !== r && (o[t].numArguments = r)) + } + + function Ut(t, e, r, n, o, i, a, u) { + this.name = t, + this.constructor = e, + this.instancePrototype = r, + this.rawDestructor = n, + this.baseClass = o, + this.getActualType = i, + this.upcast = a, + this.downcast = u, + this.pureVirtualFunctions = [] + } + + function Ht(t, e, r) { + for (; e !== r;) + e.upcast || vt("Expected null or instance of " + r.name + ", got an instance of " + e.name), + t = e.upcast(t), + e = e.baseClass; + return t + } + + function Yt(t, e) { + if (null === e) + return this.isReference && vt("null is not a valid " + this.name), + 0; + e.$$ || vt('Cannot pass "' + ge(e) + '" as a ' + this.name), + e.$$.ptr || vt("Cannot pass deleted object as a pointer of type " + this.name); + var r = e.$$.ptrType.registeredClass; + return Ht(e.$$.ptr, r, this.registeredClass) + } + + function Vt(t, e) { + var r; + if (null === e) + return this.isReference && vt("null is not a valid " + this.name), + this.isSmartPointer ? (r = this.rawConstructor(), + null !== t && t.push(this.rawDestructor, r), + r) : 0; + e.$$ || vt('Cannot pass "' + ge(e) + '" as a ' + this.name), + e.$$.ptr || vt("Cannot pass deleted object as a pointer of type " + this.name), + !this.isConst && e.$$.ptrType.isConst && vt("Cannot convert argument of type " + (e.$$.smartPtrType ? e.$$.smartPtrType.name : e.$$.ptrType.name) + " to parameter type " + this.name); + var n = e.$$.ptrType.registeredClass; + if (r = Ht(e.$$.ptr, n, this.registeredClass), + this.isSmartPointer) + switch (void 0 === e.$$.smartPtr && vt("Passing raw pointer to smart pointer is illegal"), + this.sharingPolicy) { + case 0: + e.$$.smartPtrType === this ? r = e.$$.smartPtr : vt("Cannot convert argument of type " + (e.$$.smartPtrType ? e.$$.smartPtrType.name : e.$$.ptrType.name) + " to parameter type " + this.name); + break; + case 1: + r = e.$$.smartPtr; + break; + case 2: + if (e.$$.smartPtrType === this) + r = e.$$.smartPtr; + else { + var o = e.clone(); + r = this.rawShare(r, ve.toHandle((function() { + o.delete() + }))), + null !== t && t.push(this.rawDestructor, r) + } + break; + default: + vt("Unsupporting sharing policy") + } + return r + } + + function zt(t, e) { + if (null === e) + return this.isReference && vt("null is not a valid " + this.name), + 0; + e.$$ || vt('Cannot pass "' + ge(e) + '" as a ' + this.name), + e.$$.ptr || vt("Cannot pass deleted object as a pointer of type " + this.name), + e.$$.ptrType.isConst && vt("Cannot convert argument of type " + e.$$.ptrType.name + " to parameter type " + this.name); + var r = e.$$.ptrType.registeredClass; + return Ht(e.$$.ptr, r, this.registeredClass) + } + + function Bt(t) { + return this.fromWireType(R[t >> 2]) + } + + function Lt(t) { + return this.rawGetPointee && (t = this.rawGetPointee(t)), + t + } + + function Gt(t) { + this.rawDestructor && this.rawDestructor(t) + } + + function Nt(t) { + null !== t && t.delete() + } + + function qt(t, e, r) { + if (e === r) + return t; + if (void 0 === r.baseClass) + return null; + var n = qt(t, e, r.baseClass); + return null === n ? null : r.downcast(n) + } + + function Jt() { + return Object.keys(Kt).length + } + + function Xt() { + var t = []; + for (var e in Kt) + Kt.hasOwnProperty(e) && t.push(Kt[e]); + return t + } + + function Zt(t) { + Ot = t, + kt.length && Ot && Ot(Wt) + } + var Kt = {}; + + function Qt(t, e) { + return e = function(t, e) { + for (void 0 === e && vt("ptr should not be undefined"); t.baseClass;) + e = t.upcast(e), + t = t.baseClass; + return e + }(t, e), + Kt[e] + } + + function te(t, e) { + return e.ptrType && e.ptr || wt("makeClassHandle requires ptr and ptrType"), + !!e.smartPtrType !== !!e.smartPtr && wt("Both smartPtrType and smartPtr must be specified"), + e.count = { + value: 1 + }, + Dt(Object.create(t, { + $$: { + value: e + } + })) + } + + function ee(t) { + var e = this.getPointee(t); + if (!e) + return this.destructor(t), + null; + var r = Qt(this.registeredClass, e); + if (void 0 !== r) { + if (0 === r.$$.count.value) + return r.$$.ptr = e, + r.$$.smartPtr = t, + r.clone(); + var n = r.clone(); + return this.destructor(t), + n + } + + function o() { + return this.isSmartPointer ? te(this.registeredClass.instancePrototype, { + ptrType: this.pointeeType, + ptr: e, + smartPtrType: this, + smartPtr: t + }) : te(this.registeredClass.instancePrototype, { + ptrType: this, + ptr: t + }) + } + var i, a = this.registeredClass.getActualType(e), + u = Mt[a]; + if (!u) + return o.call(this); + i = this.isConst ? u.constPointerType : u.pointerType; + var s = qt(e, this.registeredClass, i.registeredClass); + return null === s ? o.call(this) : this.isSmartPointer ? te(i.registeredClass.instancePrototype, { + ptrType: i, + ptr: s, + smartPtrType: this, + smartPtr: t + }) : te(i.registeredClass.instancePrototype, { + ptrType: i, + ptr: s + }) + } + + function re(t, e, r, n, o, i, a, u, s, c, f) { + this.name = t, + this.registeredClass = e, + this.isReference = r, + this.isConst = n, + this.isSmartPointer = o, + this.pointeeType = i, + this.sharingPolicy = a, + this.rawGetPointee = u, + this.rawConstructor = s, + this.rawShare = c, + this.rawDestructor = f, + o || void 0 !== e.baseClass ? this.toWireType = Vt : n ? (this.toWireType = Yt, + this.destructorFunction = null) : (this.toWireType = zt, + this.destructorFunction = null) + } + + function ne(t, e, r) { + o.hasOwnProperty(t) || wt("Replacing nonexistant public symbol"), + void 0 !== o[t].overloadTable && void 0 !== r ? o[t].overloadTable[r] = e : (o[t] = e, + o[t].argCount = r) + } + + function oe(t, e, r) { + return t.includes("j") ? function(t, e, r) { + var n = o["dynCall_" + t]; + return r && r.length ? n.apply(null, [e].concat(r)) : n.call(null, e) + }(t, e, r) : it(e).apply(null, r) + } + + function ie(t, e) { + var r, n, o, i = (t = ct(t)).includes("j") ? (r = t, + n = e, + o = [], + function() { + o.length = arguments.length; + for (var t = 0; t < arguments.length; t++) + o[t] = arguments[t]; + return oe(r, n, o) + } + ) : it(e); + return "function" != typeof i && vt("unknown function pointer with signature " + t + ": " + e), + i + } + var ae = void 0; + + function ue(t) { + var e = je(t), + r = ct(e); + return We(e), + r + } + + function se(t, e) { + var r = [], + n = {}; + throw e.forEach((function t(e) { + n[e] || lt[e] || (pt[e] ? pt[e].forEach(t) : (r.push(e), + n[e] = !0)) + })), + new ae(t + ": " + r.map(ue).join([", "])) + } + + function ce(t, e) { + for (var r = [], n = 0; n < t; n++) + r.push(j[(e >> 2) + n]); + return r + } + + function fe(t) { + for (; t.length;) { + var e = t.pop(); + t.pop()(e) + } + } + + function le(t, e, r, n, o) { + var i = e.length; + i < 2 && vt("argTypes array size mismatch! Must at least get return value and 'this' types!"); + for (var a = null !== e[1] && null !== r, u = !1, s = 1; s < e.length; ++s) + if (null !== e[s] && void 0 === e[s].destructorFunction) { + u = !0; + break + } + var c = "void" !== e[0].name, + f = "", + l = ""; + for (s = 0; s < i - 2; ++s) + f += (0 !== s ? ", " : "") + "arg" + s, + l += (0 !== s ? ", " : "") + "arg" + s + "Wired"; + var p = "return function " + dt(t) + "(" + f + ") {\nif (arguments.length !== " + (i - 2) + ") {\nthrowBindingError('function " + t + " called with ' + arguments.length + ' arguments, expected " + (i - 2) + " args!');\n}\n"; + u && (p += "var destructors = [];\n"); + var d = u ? "destructors" : "null", + h = ["throwBindingError", "invoker", "fn", "runDestructors", "retType", "classParam"], + y = [vt, n, o, fe, e[0], e[1]]; + a && (p += "var thisWired = classParam.toWireType(" + d + ", this);\n"); + for (s = 0; s < i - 2; ++s) + p += "var arg" + s + "Wired = argType" + s + ".toWireType(" + d + ", arg" + s + "); // " + e[s + 2].name + "\n", + h.push("argType" + s), + y.push(e[s + 2]); + if (a && (l = "thisWired" + (l.length > 0 ? ", " : "") + l), + p += (c ? "var rv = " : "") + "invoker(fn" + (l.length > 0 ? ", " : "") + l + ");\n", + u) + p += "runDestructors(destructors);\n"; + else + for (s = a ? 1 : 2; s < e.length; ++s) { + var m = 1 === s ? "thisWired" : "arg" + (s - 2) + "Wired"; + null !== e[s].destructorFunction && (p += m + "_dtor(" + m + "); // " + e[s].name + "\n", + h.push(m + "_dtor"), + y.push(e[s].destructorFunction)) + } + return c && (p += "var ret = retType.fromWireType(rv);\nreturn ret;\n"), + p += "}\n", + h.push(p), + function(t, e) { + if (!(t instanceof Function)) + throw new TypeError("new_ called with constructor type " + typeof t + " which is not a function"); + var r = ht(t.name || "unknownFunctionName", (function() {})); + r.prototype = t.prototype; + var n = new r, + o = t.apply(n, e); + return o instanceof Object ? o : n + }(Function, h).apply(null, y) + } + var pe = [], + de = [{}, { + value: void 0 + }, { + value: null + }, { + value: !0 + }, { + value: !1 + }]; + + function he(t) { + t > 4 && 0 == --de[t].refcount && (de[t] = void 0, + pe.push(t)) + } + + function ye() { + for (var t = 0, e = 5; e < de.length; ++e) + void 0 !== de[e] && ++t; + return t + } + + function me() { + for (var t = 5; t < de.length; ++t) + if (void 0 !== de[t]) + return de[t]; + return null + } + var ve = { + toValue: function(t) { + return t || vt("Cannot use deleted val. handle = " + t), + de[t].value + }, + toHandle: function(t) { + switch (t) { + case void 0: + return 1; + case null: + return 2; + case !0: + return 3; + case !1: + return 4; + default: + var e = pe.length ? pe.pop() : de.length; + return de[e] = { + refcount: 1, + value: t + }, + e + } + } + }; + + function ge(t) { + if (null === t) + return "null"; + var e = typeof t; + return "object" === e || "array" === e || "function" === e ? t.toString() : "" + t + } + + function we(t, e) { + switch (e) { + case 2: + return function(t) { + return this.fromWireType(M[t >> 2]) + }; + case 3: + return function(t) { + return this.fromWireType(I[t >> 3]) + }; + default: + throw new TypeError("Unknown float type: " + t) + } + } + + function be(t, e, r) { + switch (e) { + case 0: + return r ? function(t) { + return S[t] + } : + function(t) { + return O[t] + }; + case 1: + return r ? function(t) { + return k[t >> 1] + } : + function(t) { + return W[t >> 1] + }; + case 2: + return r ? function(t) { + return j[t >> 2] + } : + function(t) { + return R[t >> 2] + }; + default: + throw new TypeError("Unknown integer type: " + t) + } + } + var Te = { + mappings: {}, + buffers: [null, [], + [] + ], + printChar: function(t, e) { + var r = Te.buffers[t]; + 0 === e || 10 === e ? ((1 === t ? v : g)(UTF8ArrayToString(r, 0)), + r.length = 0) : r.push(e) + }, + varargs: void 0, + get: function() { + return Te.varargs += 4, + j[Te.varargs - 4 >> 2] + }, + getStr: function(t) { + return UTF8ToString(t) + }, + get64: function(t, e) { + return t + } + }; + + function $e(t) { + return t % 4 == 0 && (t % 100 != 0 || t % 400 == 0) + } + + function Pe(t, e) { + for (var r = 0, n = 0; n <= e; r += t[n++]) + ; + return r + } + var Ae = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], + De = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + + function Fe(t, e) { + for (var r = new Date(t.getTime()); e > 0;) { + var n = $e(r.getFullYear()), + o = r.getMonth(), + i = (n ? Ae : De)[o]; + if (!(e > i - r.getDate())) + return r.setDate(r.getDate() + e), + r; + e -= i - r.getDate() + 1, + r.setDate(1), + o < 11 ? r.setMonth(o + 1) : (r.setMonth(0), + r.setFullYear(r.getFullYear() + 1)) + } + return r + } + + for (var t = new Array(256), e = 0; e < 256; ++e) + t[e] = String.fromCharCode(e); + st = t + + mt = o.BindingError = yt(Error, "BindingError"), + gt = o.InternalError = yt(Error, "InternalError"), + Rt.prototype.isAliasOf = Ct, + Rt.prototype.clone = Ft, + Rt.prototype.delete = Et, + Rt.prototype.isDeleted = St, + Rt.prototype.deleteLater = jt, + re.prototype.getPointee = Lt, + re.prototype.destructor = Gt, + re.prototype.argPackAdvance = 8, + re.prototype.readValueFromPointer = Bt, + re.prototype.deleteObject = Nt, + re.prototype.fromWireType = ee, + o.getInheritedInstanceCount = Jt, + o.getLiveInheritedInstances = Xt, + o.flushPendingDeletes = Wt, + o.setDelayFunction = Zt, + ae = o.UnboundTypeError = yt(Error, "UnboundTypeError"), + o.count_emval_handles = ye, + o.get_first_emval = me; + var Se, import_table_impl = { + d: function(t, e, r, n) { + abort("Assertion failed: " + UTF8ToString(t) + ", at: " + [e ? UTF8ToString(e) : "unknown filename", r, n ? UTF8ToString(n) : "unknown function"]) + }, + g: function(t) { + return ke(t + 16) + 16 + }, + f: function(t, e, r) { + throw new ExceptionInfo(t).init(e, r),t,t + }, + p: function(t, e, r, n, o) {}, + y: function(t, e, r, n, o) { + var i = ut(r); + _t(t, { + name: e = ct(e), + fromWireType: function(t) { + return !!t + }, + toWireType: function(t, e) { + return e ? n : o + }, + argPackAdvance: 8, + readValueFromPointer: function(t) { + var n; + if (1 === r) + n = S; + else if (2 === r) + n = k; + else { + if (4 !== r) + throw new TypeError("Unknown boolean type size: " + e); + n = j + } + return this.fromWireType(n[t >> i]) + }, + destructorFunction: null + }) + }, + A: function(t, e, r, n, o, i, a, u, s, c, f, l, p) { + f = ct(f), + i = ie(o, i), + u && (u = ie(a, u)), + c && (c = ie(s, c)), + p = ie(l, p); + var d = dt(f); + xt(d, (function() { + se("Cannot construct " + f + " due to unbound types", [n]) + })), + bt([t, e, r], n ? [n] : [], (function(e) { + var r, o; + e = e[0], + o = n ? (r = e.registeredClass).instancePrototype : Rt.prototype; + var a = ht(d, (function() { + if (Object.getPrototypeOf(this) !== s) + throw new mt("Use 'new' to construct " + f); + if (void 0 === l.constructor_body) + throw new mt(f + " has no accessible constructor"); + var t = l.constructor_body[arguments.length]; + if (void 0 === t) + throw new mt("Tried to invoke ctor of " + f + " with invalid number of parameters (" + arguments.length + ") - expected (" + Object.keys(l.constructor_body).toString() + ") parameters instead!"); + return t.apply(this, arguments) + })), + s = Object.create(o, { + constructor: { + value: a + } + }); + a.prototype = s; + var l = new Ut(f, a, s, p, r, i, u, c), + h = new re(f, l, !0, !1, !1), + y = new re(f + "*", l, !1, !1, !1), + m = new re(f + " const*", l, !1, !0, !1); + return Mt[t] = { + pointerType: y, + constPointerType: m + }, + ne(d, a), + [h, y, m] + })) + }, + w: function(t, e, r, n, o, i) { + T(e > 0); + var a = ce(e, r); + o = ie(n, o), + bt([], [t], (function(t) { + var r = "constructor " + (t = t[0]).name; + if (void 0 === t.registeredClass.constructor_body && (t.registeredClass.constructor_body = []), + void 0 !== t.registeredClass.constructor_body[e - 1]) + throw new mt("Cannot register multiple constructors with identical number of parameters (" + (e - 1) + ") for class '" + t.name + "'! Overload resolution is currently only performed using the parameter count, not actual type info!"); + return t.registeredClass.constructor_body[e - 1] = function() { + se("Cannot construct " + t.name + " due to unbound types", a) + }, + bt([], a, (function(n) { + return n.splice(1, 0, null), + t.registeredClass.constructor_body[e - 1] = le(r, n, null, o, i), + [] + })), + [] + })) + }, + c: function(t, e, r, n, o, i, a, u) { + var s = ce(r, n); + e = ct(e), + i = ie(o, i), + bt([], [t], (function(t) { + var n = (t = t[0]).name + "." + e; + + function o() { + se("Cannot call " + n + " due to unbound types", s) + } + e.startsWith("@@") && (e = Symbol[e.substring(2)]), + u && t.registeredClass.pureVirtualFunctions.push(e); + var c = t.registeredClass.instancePrototype, + f = c[e]; + return void 0 === f || void 0 === f.overloadTable && f.className !== t.name && f.argCount === r - 2 ? (o.argCount = r - 2, + o.className = t.name, + c[e] = o) : (It(c, e, n), + c[e].overloadTable[r - 2] = o), + bt([], s, (function(o) { + var u = le(n, o, t, i, a); + return void 0 === c[e].overloadTable ? (u.argCount = r - 2, + c[e] = u) : c[e].overloadTable[r - 2] = u, + [] + })), + [] + })) + }, + x: function(t, e) { + _t(t, { + name: e = ct(e), + fromWireType: function(t) { + var e = ve.toValue(t); + return he(t), + e + }, + toWireType: function(t, e) { + return ve.toHandle(e) + }, + argPackAdvance: 8, + readValueFromPointer: Bt, + destructorFunction: null + }) + }, + j: function(t, e, r) { + var n = ut(r); + _t(t, { + name: e = ct(e), + fromWireType: function(t) { + return t + }, + toWireType: function(t, e) { + if ("number" != typeof e && "boolean" != typeof e) + throw new TypeError('Cannot convert "' + ge(e) + '" to ' + this.name); + return e + }, + argPackAdvance: 8, + readValueFromPointer: we(e, n), + destructorFunction: null + }) + }, + l: function(t, e, r, n, o, i) { + // Registering functions from constructor (;204;) + var a = ce(e, r); + t = ct(t), + o = ie(n, o), + xt(t, (function() { + se("Cannot call " + t + " due to unbound types", a) + }), e - 1), + bt([], a, (function(r) { + var n = [r[0], null].concat(r.slice(1)); + return ne(t, le(t, n, null, o, i), e - 1), + [] + })) + }, + b: function(t, e, r, n, o) { + e = ct(e), + -1 === o && (o = 4294967295); + var i = ut(r), + a = function(t) { + return t + }; + if (0 === n) { + var u = 32 - 8 * r; + a = function(t) { + return t << u >>> u + } + } + var s = e.includes("unsigned"); + _t(t, { + name: e, + fromWireType: a, + toWireType: function(t, r) { + if ("number" != typeof r && "boolean" != typeof r) + throw new TypeError('Cannot convert "' + ge(r) + '" to ' + this.name); + if (r < n || r > o) + throw new TypeError('Passing a number "' + ge(r) + '" from JS side to C/C++ side to an argument of type "' + e + '", which is outside the valid range [' + n + ", " + o + "]!"); + return s ? r >>> 0 : 0 | r + }, + argPackAdvance: 8, + readValueFromPointer: be(e, i, 0 !== n), + destructorFunction: null + }) + }, + a: function(t, e, r) { + var n = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array][e]; + + function o(t) { + var e = R, + r = e[t >>= 2], + o = e[t + 1]; + return new n(E, o, r) + } + _t(t, { + name: r = ct(r), + fromWireType: o, + argPackAdvance: 8, + readValueFromPointer: o + }, { + ignoreDuplicateRegistrations: !0 + }) + }, + k: function(t, e) { + var r = "std::string" === (e = ct(e)); + _t(t, { + name: e, + fromWireType: function(t) { + var e, n = R[t >> 2]; + if (r) + for (var o = t + 4, i = 0; i <= n; ++i) { + var a = t + 4 + i; + if (i == n || 0 == O[a]) { + var u = UTF8ToString(o, a - o); + void 0 === e ? e = u : (e += String.fromCharCode(0), + e += u), + o = a + 1 + } + } + else { + var s = new Array(n); + for (i = 0; i < n; ++i) + s[i] = String.fromCharCode(O[t + 4 + i]); + e = s.join("") + } + return We(t), + e + }, + toWireType: function(t, e) { + e instanceof ArrayBuffer && (e = new Uint8Array(e)); + var n = "string" == typeof e; + n || e instanceof Uint8Array || e instanceof Uint8ClampedArray || e instanceof Int8Array || vt("Cannot pass non-string to std::string"); + var o = (r && n ? function() { + return UTF8CharCount(e) + } : + function() { + return e.length + } + )(), + i = ke(4 + o + 1); + if (R[i >> 2] = o, + r && n) + stringToUTF8Array(e, O, i + 4, o + 1); + else if (n) + for (var a = 0; a < o; ++a) { + var u = e.charCodeAt(a); + u > 255 && (We(i), + vt("String has UTF-16 code units that do not fit in 8 bits")), + O[i + 4 + a] = u + } + else + for (a = 0; a < o; ++a) + O[i + 4 + a] = e[a]; + return null !== t && t.push(We, i), + i + }, + argPackAdvance: 8, + readValueFromPointer: Bt, + destructorFunction: function(t) { + We(t) + } + }) + }, + e: function(t, e, r) { + var n, o, i, a, u; + r = ct(r), + 2 === e ? (n = UTF16ArrayToString, + o = H, + a = Y, + i = function() { + return W + }, + u = 1) : 4 === e && (n = V, + o = z, + a = B, + i = function() { + return R + }, + u = 2), + _t(t, { + name: r, + fromWireType: function(t) { + for (var r, o = R[t >> 2], a = i(), s = t + 4, c = 0; c <= o; ++c) { + var f = t + 4 + c * e; + if (c == o || 0 == a[f >> u]) { + var l = n(s, f - s); + void 0 === r ? r = l : (r += String.fromCharCode(0), + r += l), + s = f + e + } + } + return We(t), + r + }, + toWireType: function(t, n) { + "string" != typeof n && vt("Cannot pass non-string to C++ string type " + r); + var i = a(n), + s = ke(4 + i + e); + return R[s >> 2] = i >> u, + o(n, s + 4, i + e), + null !== t && t.push(We, s), + s + }, + argPackAdvance: 8, + readValueFromPointer: Bt, + destructorFunction: function(t) { + We(t) + } + }) + }, + z: function(t, e) { + _t(t, { + isVoid: !0, + name: e = ct(e), + argPackAdvance: 0, + fromWireType: function() {}, + toWireType: function(t, e) {} + }) + }, + m: he, + n: function(t) { + t > 4 && (de[t].refcount += 1) + }, + o: function(t, e) { + var r, n, o; + n = "_emval_take_value", + void 0 === (o = lt[r = t]) && vt(n + " has unknown type " + ue(r)); + var i = (t = o).readValueFromPointer(e); + return ve.toHandle(i) + }, + h: function() { + abort("") + }, + r: function(t, e, r) { + O.copyWithin(t, e, e + r) + }, + s: function(t) { + O.length, + abort("OOM") + }, + u: function(t, e) {}, + v: function(t, e) {}, + i: function(t, e, r, n) { + for (var o = 0, i = 0; i < r; i++) { + var a = j[e >> 2], + u = j[e + 4 >> 2]; + e += 8; + for (var s = 0; s < u; s++) + Te.printChar(t, O[a + s]); + o += u + } + return j[n >> 2] = o, + 0 + }, + q: function(t) { + t + }, + t: function(t, e, r, n) { + return Ee(t, e, r, n) + } + }, + ke = (function() { + var import_table = { + a: import_table_impl + }; + + function updateGlobalBufferAndViews(t, e) { + var r, n, exports = t.exports; + o.asm = exports; + b = o.asm.B; // Mem + r = b.buffer + E = r + o.HEAP8 = S = new Int8Array(r), + o.HEAP16 = k = new Int16Array(r), + o.HEAP32 = j = new Int32Array(r), + o.HEAPU8 = O = new Uint8Array(r), + o.HEAPU16 = W = new Uint16Array(r), + o.HEAPU32 = R = new Uint32Array(r), + o.HEAPF32 = M = new Float32Array(r), + o.HEAPF64 = I = new Float64Array(r), + L = o.asm.D // Table + n = o.asm.C // ctor + N.unshift(n), + function(t) { + if (J--, + o.monitorRunDependencies && o.monitorRunDependencies(J), + 0 == J && (null !== X && (clearInterval(X), + X = null), + Z)) { + var e = Z; + Z = null, + e() + } + }() + } + + function load_wasm(t) { + updateGlobalBufferAndViews(t.instance) + } + + function getBinaryPromise(e) { + return function() { + if (!w && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) { + if ("function" == typeof fetch && !isFileURI(Q)) + return fetch(Q, { + credentials: "same-origin" + }).then((function(t) { + if (!t.ok) + throw "failed to load wasm binary file at '" + Q + "'"; + return t.arrayBuffer() + })).catch((function() { + return getBinary(Q) + })); + if (readAsync) + return new Promise((function(t, e) { + readAsync(Q, (function(e) { + t(new Uint8Array(e)) + }), e) + })) + } + return Promise.resolve().then((function() { + return getBinary(Q) + })) + }().then((function(e) { + return WebAssembly.instantiate(e, import_table) + })).then((function(t) { + return t + })).then(e, (function(t) { + g("failed to asynchronously prepare wasm: " + t), + abort(t) + })) + } + if (J++, + o.monitorRunDependencies && o.monitorRunDependencies(J), + o.instantiateWasm) + try { + return o.instantiateWasm(import_table, updateGlobalBufferAndViews) + } catch (t) { + return g("Module.instantiateWasm callback failed with error: " + t), + !1 + } + w || "function" != typeof WebAssembly.instantiate || isDataURI(Q) || isFileURI(Q) || getBinaryPromise(load_wasm) + }(), + o.___wasm_call_ctors = function() { + return (o.___wasm_call_ctors = o.asm.C).apply(null, arguments) + }, + o._malloc = function() { + return (ke = o._malloc = o.asm.E).apply(null, arguments) + } + ), + We = o._free = function() { + return (We = o._free = o.asm.F).apply(null, arguments) + }, + je = o.___getTypeName = function() { + return (je = o.___getTypeName = o.asm.G).apply(null, arguments) + }; + o.___embind_register_native_and_builtin_types = function() { + return (o.___embind_register_native_and_builtin_types = o.asm.H).apply(null, arguments) + }, + o.dynCall_jiji = function() { + return (o.dynCall_jiji = o.asm.I).apply(null, arguments) + }, + o.dynCall_iiiiij = function() { + return (o.dynCall_iiiiij = o.asm.J).apply(null, arguments) + }, + o.dynCall_iiiiijj = function() { + return (o.dynCall_iiiiijj = o.asm.K).apply(null, arguments) + }, + o.dynCall_iiiiiijj = function() { + return (o.dynCall_iiiiiijj = o.asm.L).apply(null, arguments) + }, + o.dynCall_viijii = function() { + return (o.dynCall_viijii = o.asm.M).apply(null, arguments) + }; + + function ExitStatus(t) { + this.name = "ExitStatus", + this.message = "Program terminated with exit(" + t + ")", + this.status = t + } + + function doRun(t) { + function postRun() { + Se || (Se = !0,o.calledRun = !0,C || (!0, + callRuntimeCallbacks(N), + o.onRuntimeInitialized && o.onRuntimeInitialized(), + function() { + if (o.postRun) + for ("function" == typeof o.postRun && (o.postRun = [o.postRun]); o.postRun.length;) + t = o.postRun.shift(), + q.unshift(t); + var t; + callRuntimeCallbacks(q) + }())) + } + t = t || l + J > 0 || (! function preRun() { + if (o.preRun) + for ("function" == typeof o.preRun && (o.preRun = [o.preRun]); o.preRun.length;) + t = o.preRun.shift(), + G.unshift(t); + var t; + callRuntimeCallbacks(G) + }(), + J > 0 || (o.setStatus ? (o.setStatus("Running..."), + setTimeout((function() { + setTimeout((function() { + o.setStatus("") + }), 1), + postRun() + }), 1)) : postRun())) + } + if (Z = function t() { + Se || doRun(), + Se || (Z = t) + }, + o.run = doRun, + o.preInit) + for ("function" == typeof o.preInit && (o.preInit = [o.preInit]); o.preInit.length > 0;) + o.preInit.pop()(); + doRun(); + return o; +}) +let fpRuntime; +export function InstantiateRuntime(){ + return new Promise((resolve, reject) => { + fpRuntime = AudioFingerprintRuntime() + var monitor = setInterval(() => { + // Wait for ctor + if (typeof fpRuntime.ExtractQueryFP == "function") + resolve(fpRuntime) || clearInterval(monitor) + }) + }) +} +export function GenerateFP(PCMBuffer) { + /* Generates audio fingerprint via ShazamV2 algorithm, + as implmented by afp.wasm + + input : (Float32Array) 8kHz Mono PCM audio sample + output: (string) Base64 Encoded AFP + */ + if (typeof fpRuntime.ExtractQueryFP != "function") + return console.error('InstantiateRuntime() Must be called first.') + + let fp_vector = fpRuntime.ExtractQueryFP(PCMBuffer.buffer) + let result_buf = new Uint8Array(fp_vector.size()); + for (let t = 0; t < fp_vector.size(); t++) + result_buf[t] = fp_vector.get(t); + return btoa(String.fromCharCode(...result_buf)) +} diff --git a/WebSourceCode/src/Netease/public/audio_match_demo/afp.wasm b/WebSourceCode/src/Netease/public/audio_match_demo/afp.wasm new file mode 100644 index 0000000..bb3e2ad Binary files /dev/null and b/WebSourceCode/src/Netease/public/audio_match_demo/afp.wasm differ diff --git a/WebSourceCode/src/Netease/public/audio_match_demo/index.html b/WebSourceCode/src/Netease/public/audio_match_demo/index.html new file mode 100644 index 0000000..f6ebe81 --- /dev/null +++ b/WebSourceCode/src/Netease/public/audio_match_demo/index.html @@ -0,0 +1,184 @@ + + + + + + + +

听歌识曲 Demo (Credit: https://github.com/mos9527/ncm-afp)

+

Usage:

+
  • Select your audio file through "Choose File" picker
  • +
  • Seek to a point where your music should sound the most distinct
  • +
  • Hit the "Clip" button and wait for the results!
  • +

    Sorry if your music somehow sounds 100x awful here, since everything is in telephone quality and that's what they're using :/

    + + + + + +
    + + +
    +
    
    +
    +
    diff --git a/WebSourceCode/src/Netease/public/audio_match_demo/rec.js b/WebSourceCode/src/Netease/public/audio_match_demo/rec.js
    new file mode 100644
    index 0000000..9b5b8fe
    --- /dev/null
    +++ b/WebSourceCode/src/Netease/public/audio_match_demo/rec.js
    @@ -0,0 +1,49 @@
    +/* AudioWorkletProcesser must be initialized as modules (i.e. seperate files)
    + *  Ref : https://developer.mozilla.org/en-US/docs/Web/API/AudioWorkletProcessor
    + */
    +class TimedRecorder extends AudioWorkletProcessor {
    +  constructor(options) {
    +    super()
    +    this.max_length = 0
    +    this.recbuffer = new Float32Array()
    +    this.recording = false
    +    this.buf_index = 0
    +    this.port.onmessage = (event) => {
    +      switch (event.data.message) {
    +        case 'start':
    +          this.max_length = event.data.duration * 8000
    +          this.recbuffer = new Float32Array(this.max_length)
    +          this.buf_index = 0
    +          this.recording = true
    +          this.port.postMessage({ message: '[rec.js] Recording started' })
    +          break
    +      }
    +    }
    +  }
    +  process(inputs) {
    +    // Only take care of channel 0 (Left)
    +    if (this.recording) {
    +      let channelL = inputs[0][0]
    +      this.port.postMessage({
    +        message: 'bufferhealth',
    +        health: this.buf_index / this.max_length,
    +        recording: this.recbuffer,
    +      })
    +      if (this.buf_index + channelL.length > this.max_length) {
    +        this.port.postMessage({ message: '[rec.js] Recording finished' })
    +        this.recording = false
    +        this.buf_index = 0
    +        this.port.postMessage({
    +          message: 'finished',
    +          recording: this.recbuffer,
    +        })
    +      } else {
    +        this.recbuffer.set(channelL, this.buf_index)
    +        this.buf_index += channelL.length
    +      }
    +    }
    +    return true
    +  }
    +}
    +
    +registerProcessor('timed-recorder', TimedRecorder)
    diff --git a/WebSourceCode/src/Netease/public/avatar_update.html b/WebSourceCode/src/Netease/public/avatar_update.html
    new file mode 100644
    index 0000000..dfa34bd
    --- /dev/null
    +++ b/WebSourceCode/src/Netease/public/avatar_update.html
    @@ -0,0 +1,82 @@
    +
    +
    +  
    +    
    +    
    +    更新头像
    +  
    +
    +  
    +    
    +    
    +    
    +    
    +  
    +
    diff --git a/WebSourceCode/src/Netease/public/cloud.html b/WebSourceCode/src/Netease/public/cloud.html
    new file mode 100644
    index 0000000..0a38ca1
    --- /dev/null
    +++ b/WebSourceCode/src/Netease/public/cloud.html
    @@ -0,0 +1,78 @@
    +
    +
    +
    +
    +  
    +  
    +  云盘上传
    +
    +
    +
    +  
    +
    +  
    +  
    +
    +
    +
    diff --git a/WebSourceCode/src/Netease/public/home.html b/WebSourceCode/src/Netease/public/home.html
    new file mode 100644
    index 0000000..6b21af8
    --- /dev/null
    +++ b/WebSourceCode/src/Netease/public/home.html
    @@ -0,0 +1,58 @@
    +
    +
    +
    +
    +  
    +  
    +  home
    +
    +
    +
    +  
    +  
    +
    +
    +
    diff --git a/WebSourceCode/src/Netease/public/index.html b/WebSourceCode/src/Netease/public/index.html
    new file mode 100644
    index 0000000..e8defa5
    --- /dev/null
    +++ b/WebSourceCode/src/Netease/public/index.html
    @@ -0,0 +1,60 @@
    +
    +
    +
    +
    +  
    +  
    +  
    +  网易云音乐 API
    +
    +
    +
    +  

    网易云音乐 API

    + 当你看到这个页面时,这个服务已经成功跑起来了~ + 查看文档 +

    例子:

    + + + + + diff --git a/WebSourceCode/src/Netease/public/listen_together_host.html b/WebSourceCode/src/Netease/public/listen_together_host.html new file mode 100644 index 0000000..4c40a11 --- /dev/null +++ b/WebSourceCode/src/Netease/public/listen_together_host.html @@ -0,0 +1,242 @@ + + + + + + + + 一起听 - 主机模式 + + + + + + + +

    一起听 - 主机模式

    +
    消息: {{message}}
    + +
    +
    + +
    您的当前登录账号为: {{account.nickname}}
    +
    +
    + + +
    +
    分享链接为: + https://st.music.163.com/listen-together/share/?songId=1372188635&roomId={{roomInfo.roomId}}&inviterId={{account.userId}} +
    +
    + +
    在线用户:
    +
      +
    • +
      + +
      +
      {{user.nickname}}
      +
    • +
    + +
    +
    + + + +
    + 播放列表 +
    +
    歌单ID:
    + + {{playlistInfo.playlistName}} +
    +
    +
    歌单内容:
    +
      +
    • +
      + +
      +
      {{track.name}}
      +
    • +
    +
    + + + + + diff --git a/WebSourceCode/src/Netease/public/login.html b/WebSourceCode/src/Netease/public/login.html new file mode 100644 index 0000000..63e0907 --- /dev/null +++ b/WebSourceCode/src/Netease/public/login.html @@ -0,0 +1,47 @@ + + + + + + + 登录 + + + + + + + + diff --git a/WebSourceCode/src/Netease/public/playlist_cover_update.html b/WebSourceCode/src/Netease/public/playlist_cover_update.html new file mode 100644 index 0000000..d9f348f --- /dev/null +++ b/WebSourceCode/src/Netease/public/playlist_cover_update.html @@ -0,0 +1,89 @@ + + + + + + 歌单封面上传 + + + + + + + + + diff --git a/WebSourceCode/src/Netease/public/qrlogin-nocookie.html b/WebSourceCode/src/Netease/public/qrlogin-nocookie.html new file mode 100644 index 0000000..e9a682a --- /dev/null +++ b/WebSourceCode/src/Netease/public/qrlogin-nocookie.html @@ -0,0 +1,70 @@ + + + + + + + 二维码登录 + + + + +
    + + + + + + diff --git a/WebSourceCode/src/Netease/public/qrlogin.html b/WebSourceCode/src/Netease/public/qrlogin.html new file mode 100644 index 0000000..9a24ddc --- /dev/null +++ b/WebSourceCode/src/Netease/public/qrlogin.html @@ -0,0 +1,70 @@ + + + + + + + 二维码登录 + + + + +
    + + + + + + diff --git a/WebSourceCode/src/Netease/public/test.html b/WebSourceCode/src/Netease/public/test.html new file mode 100644 index 0000000..f3a1dd1 --- /dev/null +++ b/WebSourceCode/src/Netease/public/test.html @@ -0,0 +1,63 @@ + + + + + + + + test + + + +

    请在控制台看结果

    + + + + + + diff --git a/WebSourceCode/src/Netease/public/voice_upload.html b/WebSourceCode/src/Netease/public/voice_upload.html new file mode 100644 index 0000000..be7db4f --- /dev/null +++ b/WebSourceCode/src/Netease/public/voice_upload.html @@ -0,0 +1,145 @@ + + + + + + + 播客上传声音 + + + +
    +
      +
    • + +
        +
      • + {{item2.voiceName}} +
      • +
      + {{item.voiceListName}} +
    • +
    + + + + +
    + + + + + + + + + + diff --git a/WebSourceCode/src/Netease/renovate.json b/WebSourceCode/src/Netease/renovate.json new file mode 100644 index 0000000..6ab0567 --- /dev/null +++ b/WebSourceCode/src/Netease/renovate.json @@ -0,0 +1,6 @@ +{ + "extends": [ + "config:base", + "helpers:pinGitHubActionDigests" + ] +} diff --git a/WebSourceCode/src/Netease/scf_bootstrap b/WebSourceCode/src/Netease/scf_bootstrap new file mode 100755 index 0000000..0d8f599 --- /dev/null +++ b/WebSourceCode/src/Netease/scf_bootstrap @@ -0,0 +1,3 @@ +#!/bin/bash +export PORT=9000 +/var/lang/node16/bin/node app.js diff --git a/WebSourceCode/src/Netease/server.js b/WebSourceCode/src/Netease/server.js new file mode 100644 index 0000000..befa286 --- /dev/null +++ b/WebSourceCode/src/Netease/server.js @@ -0,0 +1,322 @@ +const fs = require('fs') +const path = require('path') +const express = require('express') +const request = require('./util/request') +const packageJSON = require('./package.json') +const exec = require('child_process').exec +const cache = require('./util/apicache').middleware +const { cookieToJson } = require('./util/index') +const fileUpload = require('express-fileupload') +const decode = require('safe-decode-uri-component') + +/** + * The version check result. + * @readonly + * @enum {number} + */ +const VERSION_CHECK_RESULT = { + FAILED: -1, + NOT_LATEST: 0, + LATEST: 1, +} + +/** + * @typedef {{ + * identifier?: string, + * route: string, + * module: any + * }} ModuleDefinition + */ + +/** + * @typedef {{ + * port?: number, + * host?: string, + * checkVersion?: boolean, + * moduleDefs?: ModuleDefinition[] + * }} NcmApiOptions + */ + +/** + * @typedef {{ + * status: VERSION_CHECK_RESULT, + * ourVersion?: string, + * npmVersion?: string, + * }} VersionCheckResult + */ + +/** + * @typedef {{ + * server?: import('http').Server, + * }} ExpressExtension + */ + +/** + * Get the module definitions dynamically. + * + * @param {string} modulesPath The path to modules (JS). + * @param {Record} [specificRoute] The specific route of specific modules. + * @param {boolean} [doRequire] If true, require() the module directly. + * Otherwise, print out the module path. Default to true. + * @returns {Promise} The module definitions. + * + * @example getModuleDefinitions("./module", {"album_new.js": "/album/create"}) + */ +async function getModulesDefinitions( + modulesPath, + specificRoute, + doRequire = true, +) { + const files = await fs.promises.readdir(modulesPath) + const parseRoute = (/** @type {string} */ fileName) => + specificRoute && fileName in specificRoute + ? specificRoute[fileName] + : `/${fileName.replace(/\.js$/i, '').replace(/_/g, '/')}` + + const modules = files + .reverse() + .filter((file) => file.endsWith('.js')) + .map((file) => { + const identifier = file.split('.').shift() + const route = parseRoute(file) + const modulePath = path.join(modulesPath, file) + const module = doRequire ? require(modulePath) : modulePath + + return { identifier, route, module } + }) + + return modules +} + +/** + * Check if the version of this API is latest. + * + * @returns {Promise} If true, this API is up-to-date; + * otherwise, this API should be upgraded and you would + * need to notify users to upgrade it manually. + */ +async function checkVersion() { + return new Promise((resolve) => { + exec('npm info NeteaseCloudMusicApi version', (err, stdout) => { + if (!err) { + let version = stdout.trim() + + /** + * @param {VERSION_CHECK_RESULT} status + */ + const resolveStatus = (status) => + resolve({ + status, + ourVersion: packageJSON.version, + npmVersion: version, + }) + + resolveStatus( + packageJSON.version < version + ? VERSION_CHECK_RESULT.NOT_LATEST + : VERSION_CHECK_RESULT.LATEST, + ) + } + }) + + resolve({ + status: VERSION_CHECK_RESULT.FAILED, + }) + }) +} + +/** + * Construct the server of NCM API. + * + * @param {ModuleDefinition[]} [moduleDefs] Customized module definitions [advanced] + * @returns {Promise} The server instance. + */ +async function consturctServer(moduleDefs) { + const app = express() + const { CORS_ALLOW_ORIGIN } = process.env + app.set('trust proxy', true) + + /** + * CORS & Preflight request + */ + app.use((req, res, next) => { + if (req.path !== '/' && !req.path.includes('.')) { + res.set({ + 'Access-Control-Allow-Credentials': true, + 'Access-Control-Allow-Origin': + CORS_ALLOW_ORIGIN || req.headers.origin || '*', + 'Access-Control-Allow-Headers': 'X-Requested-With,Content-Type', + 'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS', + 'Content-Type': 'application/json; charset=utf-8', + }) + } + req.method === 'OPTIONS' ? res.status(204).end() : next() + }) + + /** + * Cookie Parser + */ + app.use((req, _, next) => { + req.cookies = {} + //;(req.headers.cookie || '').split(/\s*;\s*/).forEach((pair) => { // Polynomial regular expression // + ;(req.headers.cookie || '').split(/;\s+|(? { + let crack = pair.indexOf('=') + if (crack < 1 || crack == pair.length - 1) return + req.cookies[decode(pair.slice(0, crack)).trim()] = decode( + pair.slice(crack + 1), + ).trim() + }) + next() + }) + + /** + * Body Parser and File Upload + */ + app.use(express.json()) + app.use(express.urlencoded({ extended: false })) + + app.use(fileUpload()) + + /** + * Serving static files + */ + app.use(express.static(path.join(__dirname, 'public'))) + + /** + * Cache + */ + app.use(cache('2 minutes', (_, res) => res.statusCode === 200)) + + /** + * Special Routers + */ + const special = { + 'daily_signin.js': '/daily_signin', + 'fm_trash.js': '/fm_trash', + 'personal_fm.js': '/personal_fm', + } + + /** + * Load every modules in this directory + */ + const moduleDefinitions = + moduleDefs || + (await getModulesDefinitions(path.join(__dirname, 'module'), special)) + + for (const moduleDef of moduleDefinitions) { + // Register the route. + app.use(moduleDef.route, async (req, res) => { + ;[req.query, req.body].forEach((item) => { + if (typeof item.cookie === 'string') { + item.cookie = cookieToJson(decode(item.cookie)) + } + }) + + let query = Object.assign( + {}, + { cookie: req.cookies }, + req.query, + req.body, + req.files, + ) + + try { + const moduleResponse = await moduleDef.module(query, (...params) => { + // 参数注入客户端IP + const obj = [...params] + let ip = req.ip + + if (ip.substr(0, 7) == '::ffff:') { + ip = ip.substr(7) + } + // console.log(ip) + obj[3] = { + ...obj[3], + ip, + } + return request(...obj) + }) + console.log('[OK]', decode(req.originalUrl)) + + const cookies = moduleResponse.cookie + if (!query.noCookie) { + if (Array.isArray(cookies) && cookies.length > 0) { + if (req.protocol === 'https') { + // Try to fix CORS SameSite Problem + res.append( + 'Set-Cookie', + cookies.map((cookie) => { + return cookie + '; SameSite=None; Secure' + }), + ) + } else { + res.append('Set-Cookie', cookies) + } + } + } + res.status(moduleResponse.status).send(moduleResponse.body) + } catch (/** @type {*} */ moduleResponse) { + console.log('[ERR]', decode(req.originalUrl), { + status: moduleResponse.status, + body: moduleResponse.body, + }) + if (!moduleResponse.body) { + res.status(404).send({ + code: 404, + data: null, + msg: 'Not Found', + }) + return + } + if (moduleResponse.body.code == '301') + moduleResponse.body.msg = '需要登录' + if (!query.noCookie) { + res.append('Set-Cookie', moduleResponse.cookie) + } + + res.status(moduleResponse.status).send(moduleResponse.body) + } + }) + } + + return app +} + +/** + * Serve the NCM API. + * @param {NcmApiOptions} options + * @returns {Promise} + */ +async function serveNcmApi(options) { + const port = Number(options.port || process.env.PORT || '3000') + const host = options.host || process.env.HOST || '' + + const checkVersionSubmission = + options.checkVersion && + checkVersion().then(({ npmVersion, ourVersion, status }) => { + if (status == VERSION_CHECK_RESULT.NOT_LATEST) { + console.log( + `最新版本: ${npmVersion}, 当前版本: ${ourVersion}, 请及时更新`, + ) + } + }) + const constructServerSubmission = consturctServer(options.moduleDefs) + + const [_, app] = await Promise.all([ + checkVersionSubmission, + constructServerSubmission, + ]) + + /** @type {import('express').Express & ExpressExtension} */ + const appExt = app + appExt.server = app.listen(port, host, () => { + console.log(`server running @ http://${host ? host : 'localhost'}:${port}`) + }) + + return appExt +} + +module.exports = { + serveNcmApi, + getModulesDefinitions, +} diff --git a/WebSourceCode/src/Netease/server.test.js b/WebSourceCode/src/Netease/server.test.js new file mode 100644 index 0000000..aaf8070 --- /dev/null +++ b/WebSourceCode/src/Netease/server.test.js @@ -0,0 +1,35 @@ +const fs = require('fs') +const path = require('path') +const tmpPath = require('os').tmpdir() +/** @type {import("express").Express & serverMod.ExpressExtension} */ +let app +if (!fs.existsSync(path.resolve(tmpPath, 'anonymous_token'))) { + fs.writeFileSync(path.resolve(tmpPath, 'anonymous_token'), '', 'utf-8') +} +const serverMod = require('./server') +before(async () => { + app = await serverMod.serveNcmApi({}) + + if (app.server && app.server.address) { + const addr = app.server.address() + if (addr && typeof addr === 'object' && 'port' in addr) { + global.host = `http://localhost:${addr.port}` + return + } + } + + throw new Error('failed to set up host') +}) + +after((done) => { + if (app.server) { + app.server.close(done) + return + } + + throw new Error('failed to set up server') +}) + +fs.readdirSync(path.join(__dirname, 'test')).forEach((file) => { + require(path.join(__dirname, 'test', file)) +}) diff --git a/WebSourceCode/src/Netease/static/artist_album.png b/WebSourceCode/src/Netease/static/artist_album.png new file mode 100644 index 0000000..7188755 Binary files /dev/null and b/WebSourceCode/src/Netease/static/artist_album.png differ diff --git a/WebSourceCode/src/Netease/static/artists.png b/WebSourceCode/src/Netease/static/artists.png new file mode 100644 index 0000000..dfe4422 Binary files /dev/null and b/WebSourceCode/src/Netease/static/artists.png differ diff --git a/WebSourceCode/src/Netease/static/banner.png b/WebSourceCode/src/Netease/static/banner.png new file mode 100644 index 0000000..fac182a Binary files /dev/null and b/WebSourceCode/src/Netease/static/banner.png differ diff --git a/WebSourceCode/src/Netease/static/comment.png b/WebSourceCode/src/Netease/static/comment.png new file mode 100644 index 0000000..6631f62 Binary files /dev/null and b/WebSourceCode/src/Netease/static/comment.png differ diff --git a/WebSourceCode/src/Netease/static/docs.png b/WebSourceCode/src/Netease/static/docs.png new file mode 100644 index 0000000..1f1794a Binary files /dev/null and b/WebSourceCode/src/Netease/static/docs.png differ diff --git a/WebSourceCode/src/Netease/static/fm_trash.png b/WebSourceCode/src/Netease/static/fm_trash.png new file mode 100644 index 0000000..4c85539 Binary files /dev/null and b/WebSourceCode/src/Netease/static/fm_trash.png differ diff --git a/WebSourceCode/src/Netease/static/like.png b/WebSourceCode/src/Netease/static/like.png new file mode 100644 index 0000000..85acf19 Binary files /dev/null and b/WebSourceCode/src/Netease/static/like.png differ diff --git a/WebSourceCode/src/Netease/static/likeSuccess.png b/WebSourceCode/src/Netease/static/likeSuccess.png new file mode 100644 index 0000000..d882a6b Binary files /dev/null and b/WebSourceCode/src/Netease/static/likeSuccess.png differ diff --git a/WebSourceCode/src/Netease/static/mv.png b/WebSourceCode/src/Netease/static/mv.png new file mode 100644 index 0000000..dbb9b16 Binary files /dev/null and b/WebSourceCode/src/Netease/static/mv.png differ diff --git a/WebSourceCode/src/Netease/static/new_albums.png b/WebSourceCode/src/Netease/static/new_albums.png new file mode 100644 index 0000000..b5ceaa4 Binary files /dev/null and b/WebSourceCode/src/Netease/static/new_albums.png differ diff --git a/WebSourceCode/src/Netease/static/personal_fm.png b/WebSourceCode/src/Netease/static/personal_fm.png new file mode 100644 index 0000000..ba0d297 Binary files /dev/null and b/WebSourceCode/src/Netease/static/personal_fm.png differ diff --git a/WebSourceCode/src/Netease/static/play_mv.png b/WebSourceCode/src/Netease/static/play_mv.png new file mode 100644 index 0000000..de23951 Binary files /dev/null and b/WebSourceCode/src/Netease/static/play_mv.png differ diff --git a/WebSourceCode/src/Netease/static/screenshot1.png b/WebSourceCode/src/Netease/static/screenshot1.png new file mode 100644 index 0000000..eb20062 Binary files /dev/null and b/WebSourceCode/src/Netease/static/screenshot1.png differ diff --git a/WebSourceCode/src/Netease/static/screenshot2.png b/WebSourceCode/src/Netease/static/screenshot2.png new file mode 100644 index 0000000..1d8418d Binary files /dev/null and b/WebSourceCode/src/Netease/static/screenshot2.png differ diff --git a/WebSourceCode/src/Netease/static/signinError.png b/WebSourceCode/src/Netease/static/signinError.png new file mode 100644 index 0000000..e5815dc Binary files /dev/null and b/WebSourceCode/src/Netease/static/signinError.png differ diff --git a/WebSourceCode/src/Netease/static/signinSuccess.png b/WebSourceCode/src/Netease/static/signinSuccess.png new file mode 100644 index 0000000..7778a57 Binary files /dev/null and b/WebSourceCode/src/Netease/static/signinSuccess.png differ diff --git a/WebSourceCode/src/Netease/static/songDetail.png b/WebSourceCode/src/Netease/static/songDetail.png new file mode 100644 index 0000000..808d0b1 Binary files /dev/null and b/WebSourceCode/src/Netease/static/songDetail.png differ diff --git a/WebSourceCode/src/Netease/static/top_artists.png b/WebSourceCode/src/Netease/static/top_artists.png new file mode 100644 index 0000000..4105876 Binary files /dev/null and b/WebSourceCode/src/Netease/static/top_artists.png differ diff --git a/WebSourceCode/src/Netease/static/top_list.png b/WebSourceCode/src/Netease/static/top_list.png new file mode 100644 index 0000000..d1fbe02 Binary files /dev/null and b/WebSourceCode/src/Netease/static/top_list.png differ diff --git a/WebSourceCode/src/Netease/static/top_playlist.png b/WebSourceCode/src/Netease/static/top_playlist.png new file mode 100644 index 0000000..51715d6 Binary files /dev/null and b/WebSourceCode/src/Netease/static/top_playlist.png differ diff --git "a/WebSourceCode/src/Netease/static/\344\270\223\350\276\221.png" "b/WebSourceCode/src/Netease/static/\344\270\223\350\276\221.png" new file mode 100644 index 0000000..251f6a8 Binary files /dev/null and "b/WebSourceCode/src/Netease/static/\344\270\223\350\276\221.png" differ diff --git "a/WebSourceCode/src/Netease/static/\346\216\250\350\215\220\346\255\214\345\215\225.png" "b/WebSourceCode/src/Netease/static/\346\216\250\350\215\220\346\255\214\345\215\225.png" new file mode 100644 index 0000000..05a425a Binary files /dev/null and "b/WebSourceCode/src/Netease/static/\346\216\250\350\215\220\346\255\214\345\215\225.png" differ diff --git "a/WebSourceCode/src/Netease/static/\346\216\250\350\215\220\346\255\214\346\233\262.png" "b/WebSourceCode/src/Netease/static/\346\216\250\350\215\220\346\255\214\346\233\262.png" new file mode 100644 index 0000000..fdd8f9e Binary files /dev/null and "b/WebSourceCode/src/Netease/static/\346\216\250\350\215\220\346\255\214\346\233\262.png" differ diff --git "a/WebSourceCode/src/Netease/static/\346\220\234\347\264\242.png" "b/WebSourceCode/src/Netease/static/\346\220\234\347\264\242.png" new file mode 100644 index 0000000..c787181 Binary files /dev/null and "b/WebSourceCode/src/Netease/static/\346\220\234\347\264\242.png" differ diff --git "a/WebSourceCode/src/Netease/static/\346\255\214\345\215\225\350\257\246\346\203\205.png" "b/WebSourceCode/src/Netease/static/\346\255\214\345\215\225\350\257\246\346\203\205.png" new file mode 100644 index 0000000..9300715 Binary files /dev/null and "b/WebSourceCode/src/Netease/static/\346\255\214\345\215\225\350\257\246\346\203\205.png" differ diff --git "a/WebSourceCode/src/Netease/static/\346\255\214\350\257\215.png" "b/WebSourceCode/src/Netease/static/\346\255\214\350\257\215.png" new file mode 100644 index 0000000..e886906 Binary files /dev/null and "b/WebSourceCode/src/Netease/static/\346\255\214\350\257\215.png" differ diff --git "a/WebSourceCode/src/Netease/static/\347\224\250\346\210\267\346\255\214\345\215\225.png" "b/WebSourceCode/src/Netease/static/\347\224\250\346\210\267\346\255\214\345\215\225.png" new file mode 100644 index 0000000..5c1835f Binary files /dev/null and "b/WebSourceCode/src/Netease/static/\347\224\250\346\210\267\346\255\214\345\215\225.png" differ diff --git "a/WebSourceCode/src/Netease/static/\347\231\273\345\275\225.png" "b/WebSourceCode/src/Netease/static/\347\231\273\345\275\225.png" new file mode 100644 index 0000000..fdf6c80 Binary files /dev/null and "b/WebSourceCode/src/Netease/static/\347\231\273\345\275\225.png" differ diff --git "a/WebSourceCode/src/Netease/static/\351\237\263\344\271\220 url.png" "b/WebSourceCode/src/Netease/static/\351\237\263\344\271\220 url.png" new file mode 100644 index 0000000..14599c6 Binary files /dev/null and "b/WebSourceCode/src/Netease/static/\351\237\263\344\271\220 url.png" differ diff --git a/WebSourceCode/src/Netease/test/album.test.js b/WebSourceCode/src/Netease/test/album.test.js new file mode 100644 index 0000000..58632c4 --- /dev/null +++ b/WebSourceCode/src/Netease/test/album.test.js @@ -0,0 +1,26 @@ +const assert = require('assert') +const { default: axios } = require('axios') +const host = global.host || 'http://localhost:3000' +const config = require('../util/config.json') +describe('测试获取歌手专辑列表是否正常', () => { + it('数据的 code 应该为200', (done) => { + const qs = { + id: 32311, + realIP: '116.25.146.177', + } + + axios + .get(`${host}/album`, { + params: qs, + }) + .then(({ status, data }) => { + if (status == 200) { + assert(data.code === 200) + } + done() + }) + .catch((err) => { + done(err) + }) + }) +}) diff --git a/WebSourceCode/src/Netease/test/comment.test.js b/WebSourceCode/src/Netease/test/comment.test.js new file mode 100644 index 0000000..39ccf68 --- /dev/null +++ b/WebSourceCode/src/Netease/test/comment.test.js @@ -0,0 +1,26 @@ +const assert = require('assert') +const { default: axios } = require('axios') +const host = global.host || 'http://localhost:3000' +const config = require('../util/config.json') +describe('测试获取评论是否正常', () => { + it('数据的 code 应该为200', (done) => { + const qs = { + id: 32311, + realIP: '116.25.146.177', + } + + axios + .get(`${host}/comment/album`, { + params: qs, + }) + .then(({ status, data }) => { + if (status == 200) { + assert(data.code === 200) + } + done() + }) + .catch((err) => { + done(err) + }) + }) +}) diff --git a/WebSourceCode/src/Netease/test/lyric.test.js b/WebSourceCode/src/Netease/test/lyric.test.js new file mode 100644 index 0000000..017f2cd --- /dev/null +++ b/WebSourceCode/src/Netease/test/lyric.test.js @@ -0,0 +1,26 @@ +const assert = require('assert') +const { default: axios } = require('axios') +const host = global.host || 'http://localhost:3000' +const config = require('../util/config.json') +describe('测试获取歌词是否正常', () => { + it('数据应该有 lrc 字段', (done) => { + const qs = { + id: 347230, + realIP: '116.25.146.177', + } + + axios + .get(`${host}/lyric`, { + params: qs, + }) + .then(({ status, data }) => { + if (status == 200) { + assert(typeof data.lrc !== 'undefined') + } + done() + }) + .catch((err) => { + done(err) + }) + }) +}) diff --git a/WebSourceCode/src/Netease/test/music_url.test.js b/WebSourceCode/src/Netease/test/music_url.test.js new file mode 100644 index 0000000..5640c97 --- /dev/null +++ b/WebSourceCode/src/Netease/test/music_url.test.js @@ -0,0 +1,27 @@ +const assert = require('assert') +const { default: axios } = require('axios') +const host = global.host || 'http://localhost:3000' +const config = require('../util/config.json') +describe('测试获取歌曲是否正常', () => { + it('歌曲的 url 不应该为空', (done) => { + const qs = { + id: 464315036, + br: 999000, + realIP: '116.25.146.177', + } + + axios + .get(`${host}/song/url`, { + params: qs, + }) + .then(({ status, data }) => { + if (status == 200) { + assert(!!data.data[0].url) + } + done() + }) + .catch((err) => { + done(err) + }) + }) +}) diff --git a/WebSourceCode/src/Netease/test/search.test.js b/WebSourceCode/src/Netease/test/search.test.js new file mode 100644 index 0000000..efd90c7 --- /dev/null +++ b/WebSourceCode/src/Netease/test/search.test.js @@ -0,0 +1,26 @@ +const assert = require('assert') +const { default: axios } = require('axios') +const host = global.host || 'http://localhost:3000' +const config = require('../util/config.json') +describe('测试搜索是否正常', () => { + it('获取到的数据的 name 应该和搜索关键词一致', (done) => { + const qs = { + keywords: '海阔天空', + type: 1, + realIP: '116.25.146.177', + } + axios + .get(`${host}/search`, { + params: qs, + }) + .then(({ status, data }) => { + if (status == 200) { + assert(data.result.songs[0].name === '海阔天空') + } + done() + }) + .catch((err) => { + done(err) + }) + }) +}) diff --git a/WebSourceCode/src/Netease/tsconfig.json b/WebSourceCode/src/Netease/tsconfig.json new file mode 100644 index 0000000..9656c53 --- /dev/null +++ b/WebSourceCode/src/Netease/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "target": "ES2015", + "module": "commonjs", + "experimentalDecorators": true, + "moduleResolution": "node", + "lib": [ + "esnext", + "esnext.asynciterable", + "dom" + ], + "esModuleInterop": true, + "allowJs": true, + "sourceMap": true, + "strict": true, + "noEmit": true, + "baseUrl": ".", + "paths": { + "~/*": [ + "./*" + ], + "@/*": [ + "./*" + ] + }, + }, + "exclude": [ + "node_modules" + ] + } \ No newline at end of file diff --git a/WebSourceCode/src/Netease/util/apicache.js b/WebSourceCode/src/Netease/util/apicache.js new file mode 100644 index 0000000..57057de --- /dev/null +++ b/WebSourceCode/src/Netease/util/apicache.js @@ -0,0 +1,829 @@ +var url = require('url') +var MemoryCache = require('./memory-cache') + +var t = { + ms: 1, + second: 1000, + minute: 60000, + hour: 3600000, + day: 3600000 * 24, + week: 3600000 * 24 * 7, + month: 3600000 * 24 * 30, +} + +var instances = [] + +var matches = function (a) { + return function (b) { + return a === b + } +} + +var doesntMatch = function (a) { + return function (b) { + return !matches(a)(b) + } +} + +var logDuration = function (d, prefix) { + var str = d > 1000 ? (d / 1000).toFixed(2) + 'sec' : d + 'ms' + return '\x1b[33m- ' + (prefix ? prefix + ' ' : '') + str + '\x1b[0m' +} + +function getSafeHeaders(res) { + return res.getHeaders ? res.getHeaders() : res._headers +} + +function ApiCache() { + var memCache = new MemoryCache() + + var globalOptions = { + debug: false, + defaultDuration: 3600000, + enabled: true, + appendKey: [], + jsonp: false, + redisClient: false, + headerBlacklist: [], + statusCodes: { + include: [], + exclude: [], + }, + events: { + expire: undefined, + }, + headers: { + // 'cache-control': 'no-cache' // example of header overwrite + }, + trackPerformance: false, + } + + var middlewareOptions = [] + var instance = this + var index = null + var timers = {} + var performanceArray = [] // for tracking cache hit rate + + instances.push(this) + this.id = instances.length + + function debug(a, b, c, d) { + var arr = ['\x1b[36m[apicache]\x1b[0m', a, b, c, d].filter(function (arg) { + return arg !== undefined + }) + var debugEnv = + process.env.DEBUG && + process.env.DEBUG.split(',').indexOf('apicache') !== -1 + + return (globalOptions.debug || debugEnv) && console.log.apply(null, arr) + } + + function shouldCacheResponse(request, response, toggle) { + var opt = globalOptions + var codes = opt.statusCodes + + if (!response) return false + + if (toggle && !toggle(request, response)) { + return false + } + + if ( + codes.exclude && + codes.exclude.length && + codes.exclude.indexOf(response.statusCode) !== -1 + ) + return false + if ( + codes.include && + codes.include.length && + codes.include.indexOf(response.statusCode) === -1 + ) + return false + + return true + } + + function addIndexEntries(key, req) { + var groupName = req.apicacheGroup + + if (groupName) { + debug('group detected "' + groupName + '"') + var group = (index.groups[groupName] = index.groups[groupName] || []) + group.unshift(key) + } + + index.all.unshift(key) + } + + function filterBlacklistedHeaders(headers) { + return Object.keys(headers) + .filter(function (key) { + return globalOptions.headerBlacklist.indexOf(key) === -1 + }) + .reduce(function (acc, header) { + acc[header] = headers[header] + return acc + }, {}) + } + + function createCacheObject(status, headers, data, encoding) { + return { + status: status, + headers: filterBlacklistedHeaders(headers), + data: data, + encoding: encoding, + timestamp: new Date().getTime() / 1000, // seconds since epoch. This is used to properly decrement max-age headers in cached responses. + } + } + + function cacheResponse(key, value, duration) { + var redis = globalOptions.redisClient + var expireCallback = globalOptions.events.expire + + if (redis && redis.connected) { + try { + redis.hset(key, 'response', JSON.stringify(value)) + redis.hset(key, 'duration', duration) + redis.expire(key, duration / 1000, expireCallback || function () {}) + } catch (err) { + debug('[apicache] error in redis.hset()') + } + } else { + memCache.add(key, value, duration, expireCallback) + } + + // add automatic cache clearing from duration, includes max limit on setTimeout + timers[key] = setTimeout(function () { + instance.clear(key, true) + }, Math.min(duration, 2147483647)) + } + + function accumulateContent(res, content) { + if (content) { + if (typeof content == 'string') { + res._apicache.content = (res._apicache.content || '') + content + } else if (Buffer.isBuffer(content)) { + var oldContent = res._apicache.content + + if (typeof oldContent === 'string') { + oldContent = !Buffer.from + ? new Buffer(oldContent) + : Buffer.from(oldContent) + } + + if (!oldContent) { + oldContent = !Buffer.alloc ? new Buffer(0) : Buffer.alloc(0) + } + + res._apicache.content = Buffer.concat( + [oldContent, content], + oldContent.length + content.length, + ) + } else { + res._apicache.content = content + } + } + } + + function makeResponseCacheable( + req, + res, + next, + key, + duration, + strDuration, + toggle, + ) { + // monkeypatch res.end to create cache object + res._apicache = { + write: res.write, + writeHead: res.writeHead, + end: res.end, + cacheable: true, + content: undefined, + } + + // append header overwrites if applicable + Object.keys(globalOptions.headers).forEach(function (name) { + res.setHeader(name, globalOptions.headers[name]) + }) + + res.writeHead = function () { + // add cache control headers + if (!globalOptions.headers['cache-control']) { + if (shouldCacheResponse(req, res, toggle)) { + res.setHeader( + 'cache-control', + 'max-age=' + (duration / 1000).toFixed(0), + ) + } else { + res.setHeader('cache-control', 'no-cache, no-store, must-revalidate') + } + } + + res._apicache.headers = Object.assign({}, getSafeHeaders(res)) + return res._apicache.writeHead.apply(this, arguments) + } + + // patch res.write + res.write = function (content) { + accumulateContent(res, content) + return res._apicache.write.apply(this, arguments) + } + + // patch res.end + res.end = function (content, encoding) { + if (shouldCacheResponse(req, res, toggle)) { + accumulateContent(res, content) + + if (res._apicache.cacheable && res._apicache.content) { + addIndexEntries(key, req) + var headers = res._apicache.headers || getSafeHeaders(res) + var cacheObject = createCacheObject( + res.statusCode, + headers, + res._apicache.content, + encoding, + ) + cacheResponse(key, cacheObject, duration) + + // display log entry + var elapsed = new Date() - req.apicacheTimer + debug( + 'adding cache entry for "' + key + '" @ ' + strDuration, + logDuration(elapsed), + ) + debug('_apicache.headers: ', res._apicache.headers) + debug('res.getHeaders(): ', getSafeHeaders(res)) + debug('cacheObject: ', cacheObject) + } + } + + return res._apicache.end.apply(this, arguments) + } + + next() + } + + function sendCachedResponse( + request, + response, + cacheObject, + toggle, + next, + duration, + ) { + if (toggle && !toggle(request, response)) { + return next() + } + + var headers = getSafeHeaders(response) + + Object.assign( + headers, + filterBlacklistedHeaders(cacheObject.headers || {}), + { + // set properly-decremented max-age header. This ensures that max-age is in sync with the cache expiration. + 'cache-control': + 'max-age=' + + Math.max( + 0, + ( + duration / 1000 - + (new Date().getTime() / 1000 - cacheObject.timestamp) + ).toFixed(0), + ), + }, + ) + + // only embed apicache headers when not in production environment + + // unstringify buffers + var data = cacheObject.data + if (data && data.type === 'Buffer') { + data = + typeof data.data === 'number' + ? new Buffer.alloc(data.data) + : new Buffer.from(data.data) + } + + // test Etag against If-None-Match for 304 + var cachedEtag = cacheObject.headers.etag + var requestEtag = request.headers['if-none-match'] + + if (requestEtag && cachedEtag === requestEtag) { + response.writeHead(304, headers) + return response.end() + } + + response.writeHead(cacheObject.status || 200, headers) + + return response.end(data, cacheObject.encoding) + } + + function syncOptions() { + for (var i in middlewareOptions) { + Object.assign( + middlewareOptions[i].options, + globalOptions, + middlewareOptions[i].localOptions, + ) + } + } + + this.clear = function (target, isAutomatic) { + var group = index.groups[target] + var redis = globalOptions.redisClient + + if (group) { + debug('clearing group "' + target + '"') + + group.forEach(function (key) { + debug('clearing cached entry for "' + key + '"') + clearTimeout(timers[key]) + delete timers[key] + if (!globalOptions.redisClient) { + memCache.delete(key) + } else { + try { + redis.del(key) + } catch (err) { + console.log('[apicache] error in redis.del("' + key + '")') + } + } + index.all = index.all.filter(doesntMatch(key)) + }) + + delete index.groups[target] + } else if (target) { + debug( + 'clearing ' + + (isAutomatic ? 'expired' : 'cached') + + ' entry for "' + + target + + '"', + ) + clearTimeout(timers[target]) + delete timers[target] + // clear actual cached entry + if (!redis) { + memCache.delete(target) + } else { + try { + redis.del(target) + } catch (err) { + console.log('[apicache] error in redis.del("' + target + '")') + } + } + + // remove from global index + index.all = index.all.filter(doesntMatch(target)) + + // remove target from each group that it may exist in + Object.keys(index.groups).forEach(function (groupName) { + index.groups[groupName] = index.groups[groupName].filter( + doesntMatch(target), + ) + + // delete group if now empty + if (!index.groups[groupName].length) { + delete index.groups[groupName] + } + }) + } else { + debug('clearing entire index') + + if (!redis) { + memCache.clear() + } else { + // clear redis keys one by one from internal index to prevent clearing non-apicache entries + index.all.forEach(function (key) { + clearTimeout(timers[key]) + delete timers[key] + try { + redis.del(key) + } catch (err) { + console.log('[apicache] error in redis.del("' + key + '")') + } + }) + } + this.resetIndex() + } + + return this.getIndex() + } + + function parseDuration(duration, defaultDuration) { + if (typeof duration === 'number') return duration + + if (typeof duration === 'string') { + var split = duration.match(/^([\d\.,]+)\s?(\w+)$/) + + if (split.length === 3) { + var len = parseFloat(split[1]) + var unit = split[2].replace(/s$/i, '').toLowerCase() + if (unit === 'm') { + unit = 'ms' + } + + return (len || 1) * (t[unit] || 0) + } + } + + return defaultDuration + } + + this.getDuration = function (duration) { + return parseDuration(duration, globalOptions.defaultDuration) + } + + /** + * Return cache performance statistics (hit rate). Suitable for putting into a route: + * + * app.get('/api/cache/performance', (req, res) => { + * res.json(apicache.getPerformance()) + * }) + * + */ + this.getPerformance = function () { + return performanceArray.map(function (p) { + return p.report() + }) + } + + this.getIndex = function (group) { + if (group) { + return index.groups[group] + } else { + return index + } + } + + this.middleware = function cache( + strDuration, + middlewareToggle, + localOptions, + ) { + var duration = instance.getDuration(strDuration) + var opt = {} + + middlewareOptions.push({ + options: opt, + }) + + var options = function (localOptions) { + if (localOptions) { + middlewareOptions.find(function (middleware) { + return middleware.options === opt + }).localOptions = localOptions + } + + syncOptions() + + return opt + } + + options(localOptions) + + /** + * A Function for non tracking performance + */ + function NOOPCachePerformance() { + this.report = this.hit = this.miss = function () {} // noop; + } + + /** + * A function for tracking and reporting hit rate. These statistics are returned by the getPerformance() call above. + */ + function CachePerformance() { + /** + * Tracks the hit rate for the last 100 requests. + * If there have been fewer than 100 requests, the hit rate just considers the requests that have happened. + */ + this.hitsLast100 = new Uint8Array(100 / 4) // each hit is 2 bits + + /** + * Tracks the hit rate for the last 1000 requests. + * If there have been fewer than 1000 requests, the hit rate just considers the requests that have happened. + */ + this.hitsLast1000 = new Uint8Array(1000 / 4) // each hit is 2 bits + + /** + * Tracks the hit rate for the last 10000 requests. + * If there have been fewer than 10000 requests, the hit rate just considers the requests that have happened. + */ + this.hitsLast10000 = new Uint8Array(10000 / 4) // each hit is 2 bits + + /** + * Tracks the hit rate for the last 100000 requests. + * If there have been fewer than 100000 requests, the hit rate just considers the requests that have happened. + */ + this.hitsLast100000 = new Uint8Array(100000 / 4) // each hit is 2 bits + + /** + * The number of calls that have passed through the middleware since the server started. + */ + this.callCount = 0 + + /** + * The total number of hits since the server started + */ + this.hitCount = 0 + + /** + * The key from the last cache hit. This is useful in identifying which route these statistics apply to. + */ + this.lastCacheHit = null + + /** + * The key from the last cache miss. This is useful in identifying which route these statistics apply to. + */ + this.lastCacheMiss = null + + /** + * Return performance statistics + */ + this.report = function () { + return { + lastCacheHit: this.lastCacheHit, + lastCacheMiss: this.lastCacheMiss, + callCount: this.callCount, + hitCount: this.hitCount, + missCount: this.callCount - this.hitCount, + hitRate: this.callCount == 0 ? null : this.hitCount / this.callCount, + hitRateLast100: this.hitRate(this.hitsLast100), + hitRateLast1000: this.hitRate(this.hitsLast1000), + hitRateLast10000: this.hitRate(this.hitsLast10000), + hitRateLast100000: this.hitRate(this.hitsLast100000), + } + } + + /** + * Computes a cache hit rate from an array of hits and misses. + * @param {Uint8Array} array An array representing hits and misses. + * @returns a number between 0 and 1, or null if the array has no hits or misses + */ + this.hitRate = function (array) { + var hits = 0 + var misses = 0 + for (var i = 0; i < array.length; i++) { + var n8 = array[i] + for (j = 0; j < 4; j++) { + switch (n8 & 3) { + case 1: + hits++ + break + case 2: + misses++ + break + } + n8 >>= 2 + } + } + var total = hits + misses + if (total == 0) return null + return hits / total + } + + /** + * Record a hit or miss in the given array. It will be recorded at a position determined + * by the current value of the callCount variable. + * @param {Uint8Array} array An array representing hits and misses. + * @param {boolean} hit true for a hit, false for a miss + * Each element in the array is 8 bits, and encodes 4 hit/miss records. + * Each hit or miss is encoded as to bits as follows: + * 00 means no hit or miss has been recorded in these bits + * 01 encodes a hit + * 10 encodes a miss + */ + this.recordHitInArray = function (array, hit) { + var arrayIndex = ~~(this.callCount / 4) % array.length + var bitOffset = (this.callCount % 4) * 2 // 2 bits per record, 4 records per uint8 array element + var clearMask = ~(3 << bitOffset) + var record = (hit ? 1 : 2) << bitOffset + array[arrayIndex] = (array[arrayIndex] & clearMask) | record + } + + /** + * Records the hit or miss in the tracking arrays and increments the call count. + * @param {boolean} hit true records a hit, false records a miss + */ + this.recordHit = function (hit) { + this.recordHitInArray(this.hitsLast100, hit) + this.recordHitInArray(this.hitsLast1000, hit) + this.recordHitInArray(this.hitsLast10000, hit) + this.recordHitInArray(this.hitsLast100000, hit) + if (hit) this.hitCount++ + this.callCount++ + } + + /** + * Records a hit event, setting lastCacheMiss to the given key + * @param {string} key The key that had the cache hit + */ + this.hit = function (key) { + this.recordHit(true) + this.lastCacheHit = key + } + + /** + * Records a miss event, setting lastCacheMiss to the given key + * @param {string} key The key that had the cache miss + */ + this.miss = function (key) { + this.recordHit(false) + this.lastCacheMiss = key + } + } + + var perf = globalOptions.trackPerformance + ? new CachePerformance() + : new NOOPCachePerformance() + + performanceArray.push(perf) + + var cache = function (req, res, next) { + function bypass() { + debug('bypass detected, skipping cache.') + return next() + } + + // initial bypass chances + if (!opt.enabled) return bypass() + if ( + req.headers['x-apicache-bypass'] || + req.headers['x-apicache-force-fetch'] + ) + return bypass() + + // REMOVED IN 0.11.1 TO CORRECT MIDDLEWARE TOGGLE EXECUTE ORDER + // if (typeof middlewareToggle === 'function') { + // if (!middlewareToggle(req, res)) return bypass() + // } else if (middlewareToggle !== undefined && !middlewareToggle) { + // return bypass() + // } + + // embed timer + req.apicacheTimer = new Date() + + // In Express 4.x the url is ambigious based on where a router is mounted. originalUrl will give the full Url + var key = req.hostname + (req.originalUrl || req.url) + // Remove querystring from key if jsonp option is enabled + if (opt.jsonp) { + key = url.parse(key).pathname + } + + // add appendKey (either custom function or response path) + if (typeof opt.appendKey === 'function') { + key += '$$appendKey=' + opt.appendKey(req, res) + } else if (opt.appendKey.length > 0) { + var appendKey = req + + for (var i = 0; i < opt.appendKey.length; i++) { + appendKey = appendKey[opt.appendKey[i]] + } + key += '$$appendKey=' + appendKey + } + + // attempt cache hit + var redis = opt.redisClient + var cached = !redis ? memCache.getValue(key) : null + + // send if cache hit from memory-cache + if (cached) { + var elapsed = new Date() - req.apicacheTimer + debug( + 'sending cached (memory-cache) version of', + key, + logDuration(elapsed), + ) + + perf.hit(key) + return sendCachedResponse( + req, + res, + cached, + middlewareToggle, + next, + duration, + ) + } + + // send if cache hit from redis + if (redis && redis.connected) { + try { + redis.hgetall(key, function (err, obj) { + if (!err && obj && obj.response) { + var elapsed = new Date() - req.apicacheTimer + debug( + 'sending cached (redis) version of', + key, + logDuration(elapsed), + ) + + perf.hit(key) + return sendCachedResponse( + req, + res, + JSON.parse(obj.response), + middlewareToggle, + next, + duration, + ) + } else { + perf.miss(key) + return makeResponseCacheable( + req, + res, + next, + key, + duration, + strDuration, + middlewareToggle, + ) + } + }) + } catch (err) { + // bypass redis on error + perf.miss(key) + return makeResponseCacheable( + req, + res, + next, + key, + duration, + strDuration, + middlewareToggle, + ) + } + } else { + perf.miss(key) + return makeResponseCacheable( + req, + res, + next, + key, + duration, + strDuration, + middlewareToggle, + ) + } + } + + cache.options = options + + return cache + } + + this.options = function (options) { + if (options) { + Object.assign(globalOptions, options) + syncOptions() + + if ('defaultDuration' in options) { + // Convert the default duration to a number in milliseconds (if needed) + globalOptions.defaultDuration = parseDuration( + globalOptions.defaultDuration, + 3600000, + ) + } + + if (globalOptions.trackPerformance) { + debug( + 'WARNING: using trackPerformance flag can cause high memory usage!', + ) + } + + return this + } else { + return globalOptions + } + } + + this.resetIndex = function () { + index = { + all: [], + groups: {}, + } + } + + this.newInstance = function (config) { + var instance = new ApiCache() + + if (config) { + instance.options(config) + } + + return instance + } + + this.clone = function () { + return this.newInstance(this.options()) + } + + // initialize index + this.resetIndex() +} + +module.exports = new ApiCache() diff --git a/WebSourceCode/src/Netease/util/config.json b/WebSourceCode/src/Netease/util/config.json new file mode 100644 index 0000000..2c4a457 --- /dev/null +++ b/WebSourceCode/src/Netease/util/config.json @@ -0,0 +1,12 @@ +{ + "resourceTypeMap": { + "0": "R_SO_4_", + "1": "R_MV_5_", + "2": "A_PL_0_", + "3": "R_AL_3_", + "4": "A_DJ_1_", + "5": "R_VI_62_", + "6": "A_EV_2_", + "7": "A_DR_14_" + } +} diff --git a/WebSourceCode/src/Netease/util/crypto.js b/WebSourceCode/src/Netease/util/crypto.js new file mode 100644 index 0000000..3f99e85 --- /dev/null +++ b/WebSourceCode/src/Netease/util/crypto.js @@ -0,0 +1,67 @@ +const crypto = require('crypto') +const iv = Buffer.from('0102030405060708') +const presetKey = Buffer.from('0CoJUm6Qyw8W8jud') +const linuxapiKey = Buffer.from('rFgB&h#%2?^eDg:Q') +const base62 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' +const publicKey = + '-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgtQn2JZ34ZC28NWYpAUd98iZ37BUrX/aKzmFbt7clFSs6sXqHauqKWqdtLkF2KexO40H1YTX8z2lSgBBOAxLsvaklV8k4cBFK9snQXE9/DDaFt6Rr7iVZMldczhC0JNgTz+SHXT6CBHuX3e9SdB1Ua44oncaTWz7OBGLbCiK45wIDAQAB\n-----END PUBLIC KEY-----' +const eapiKey = 'e82ckenh8dichen8' + +const aesEncrypt = (buffer, mode, key, iv) => { + const cipher = crypto.createCipheriv('aes-128-' + mode, key, iv) + return Buffer.concat([cipher.update(buffer), cipher.final()]) +} + +const rsaEncrypt = (buffer, key) => { + buffer = Buffer.concat([Buffer.alloc(128 - buffer.length), buffer]) + return crypto.publicEncrypt( + { key: key, padding: crypto.constants.RSA_NO_PADDING }, + buffer, + ) +} + +const weapi = (object) => { + const text = JSON.stringify(object) + const secretKey = crypto + .randomBytes(16) + .map((n) => base62.charAt(n % 62).charCodeAt()) + return { + params: aesEncrypt( + Buffer.from( + aesEncrypt(Buffer.from(text), 'cbc', presetKey, iv).toString('base64'), + ), + 'cbc', + secretKey, + iv, + ).toString('base64'), + encSecKey: rsaEncrypt(secretKey.reverse(), publicKey).toString('hex'), + } +} + +const linuxapi = (object) => { + const text = JSON.stringify(object) + return { + eparams: aesEncrypt(Buffer.from(text), 'ecb', linuxapiKey, '') + .toString('hex') + .toUpperCase(), + } +} + +const eapi = (url, object) => { + const text = typeof object === 'object' ? JSON.stringify(object) : object + const message = `nobody${url}use${text}md5forencrypt` + const digest = crypto.createHash('md5').update(message).digest('hex') + const data = `${url}-36cd479b6b5-${text}-36cd479b6b5-${digest}` + return { + params: aesEncrypt(Buffer.from(data), 'ecb', eapiKey, '') + .toString('hex') + .toUpperCase(), + } +} + +const decrypt = (cipherBuffer) => { + const decipher = crypto.createDecipheriv('aes-128-ecb', eapiKey, '') + return Buffer.concat([decipher.update(cipherBuffer), decipher.final()]) +} + +module.exports = { weapi, linuxapi, eapi, decrypt } diff --git a/WebSourceCode/src/Netease/util/index.js b/WebSourceCode/src/Netease/util/index.js new file mode 100644 index 0000000..78129b4 --- /dev/null +++ b/WebSourceCode/src/Netease/util/index.js @@ -0,0 +1,24 @@ +module.exports = { + toBoolean(val) { + if (typeof val === 'boolean') return val + if (val === '') return val + return val === 'true' || val == '1' + }, + cookieToJson(cookie) { + if (!cookie) return {} + let cookieArr = cookie.split(';') + let obj = {} + cookieArr.forEach((i) => { + let arr = i.split('=') + obj[arr[0]] = arr[1] + }) + return obj + }, + getRandom(num) { + var random = Math.floor( + (Math.random() + Math.floor(Math.random() * 9 + 1)) * + Math.pow(10, num - 1), + ) + return random + }, +} diff --git a/WebSourceCode/src/Netease/util/memory-cache.js b/WebSourceCode/src/Netease/util/memory-cache.js new file mode 100644 index 0000000..6b6deaa --- /dev/null +++ b/WebSourceCode/src/Netease/util/memory-cache.js @@ -0,0 +1,63 @@ +function MemoryCache() { + this.cache = {} + this.size = 0 +} + +MemoryCache.prototype.add = function (key, value, time, timeoutCallback) { + var old = this.cache[key] + var instance = this + + var entry = { + value: value, + expire: time + Date.now(), + timeout: setTimeout(function () { + instance.delete(key) + return ( + timeoutCallback && + typeof timeoutCallback === 'function' && + timeoutCallback(value, key) + ) + }, time), + } + + this.cache[key] = entry + this.size = Object.keys(this.cache).length + + return entry +} + +MemoryCache.prototype.delete = function (key) { + var entry = this.cache[key] + + if (entry) { + clearTimeout(entry.timeout) + } + + delete this.cache[key] + + this.size = Object.keys(this.cache).length + + return null +} + +MemoryCache.prototype.get = function (key) { + var entry = this.cache[key] + + return entry +} + +MemoryCache.prototype.getValue = function (key) { + var entry = this.get(key) + + return entry && entry.value +} + +MemoryCache.prototype.clear = function () { + Object.keys(this.cache).forEach(function (key) { + this.delete(key) + }, this) + + return true +} + +module.exports = MemoryCache diff --git a/WebSourceCode/src/Netease/util/request.js b/WebSourceCode/src/Netease/util/request.js new file mode 100644 index 0000000..64940ab --- /dev/null +++ b/WebSourceCode/src/Netease/util/request.js @@ -0,0 +1,243 @@ +const encrypt = require('./crypto') +const crypto = require('crypto') +const { default: axios } = require('axios') +const { PacProxyAgent } = require('pac-proxy-agent') +const http = require('http') +const https = require('https') +const tunnel = require('tunnel') +const fs = require('fs') +const path = require('path') +const tmpPath = require('os').tmpdir() +const anonymous_token = fs.readFileSync( + path.resolve(tmpPath, './anonymous_token'), + 'utf-8', +) +const { URLSearchParams, URL } = require('url') +// request.debug = true // 开启可看到更详细信息 + +const chooseUserAgent = (ua = false) => { + const userAgentList = { + mobile: [ + // iOS 13.5.1 14.0 beta with safari + 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Mobile/15E148 Safari/604.1', + 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.', + // iOS with qq micromsg + 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/602.1.50 (KHTML like Gecko) Mobile/14A456 QQ/6.5.7.408 V1_IPH_SQ_6.5.7_1_APP_A Pixel/750 Core/UIWebView NetType/4G Mem/103', + 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/7.0.15(0x17000f27) NetType/WIFI Language/zh', + // Android -> Huawei Xiaomi + 'Mozilla/5.0 (Linux; Android 9; PCT-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 HuaweiBrowser/10.0.3.311 Mobile Safari/537.36', + 'Mozilla/5.0 (Linux; U; Android 9; zh-cn; Redmi Note 8 Build/PKQ1.190616.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/71.0.3578.141 Mobile Safari/537.36 XiaoMi/MiuiBrowser/12.5.22', + // Android + qq micromsg + 'Mozilla/5.0 (Linux; Android 10; YAL-AL00 Build/HUAWEIYAL-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.62 XWEB/2581 MMWEBSDK/200801 Mobile Safari/537.36 MMWEBID/3027 MicroMessenger/7.0.18.1740(0x27001235) Process/toolsmp WeChat/arm64 NetType/WIFI Language/zh_CN ABI/arm64', + 'Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BKK-AL10 Build/HONORBKK-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/10.6 Mobile Safari/537.36', + ], + pc: [ + // macOS 10.15.6 Firefox / Chrome / Safari + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:80.0) Gecko/20100101 Firefox/80.0', + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.30 Safari/537.36', + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15', + // Windows 10 Firefox / Chrome / Edge + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0', + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.30 Safari/537.36', + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/13.10586', + // Linux 就算了 + ], + } + let realUserAgentList = + userAgentList[ua] || userAgentList.mobile.concat(userAgentList.pc) + return ['mobile', 'pc', false].indexOf(ua) > -1 + ? realUserAgentList[Math.floor(Math.random() * realUserAgentList.length)] + : ua +} +const createRequest = (method, url, data = {}, options) => { + return new Promise((resolve, reject) => { + let headers = { 'User-Agent': chooseUserAgent(options.ua) } + options.headers = options.headers || {} + headers = { + ...headers, + ...options.headers, + } + if (method.toUpperCase() === 'POST') + headers['Content-Type'] = 'application/x-www-form-urlencoded' + if (url.includes('music.163.com')) + headers['Referer'] = 'https://music.163.com' + let ip = options.realIP || options.ip || '' + // console.log(ip) + if (ip) { + headers['X-Real-IP'] = ip + headers['X-Forwarded-For'] = ip + } + // headers['X-Real-IP'] = '118.88.88.88' + if (typeof options.cookie === 'object') { + options.cookie = { + ...options.cookie, + __remember_me: true, + // NMTID: crypto.randomBytes(16).toString('hex'), + _ntes_nuid: crypto.randomBytes(16).toString('hex'), + } + if (url.indexOf('login') === -1) { + options.cookie['NMTID'] = crypto.randomBytes(16).toString('hex') + } + if (!options.cookie.MUSIC_U) { + // 游客 + if (!options.cookie.MUSIC_A) { + options.cookie.MUSIC_A = anonymous_token + } + } + headers['Cookie'] = Object.keys(options.cookie) + .map( + (key) => + encodeURIComponent(key) + + '=' + + encodeURIComponent(options.cookie[key]), + ) + .join('; ') + } else if (options.cookie) { + headers['Cookie'] = options.cookie + } else { + headers['Cookie'] = '__remember_me=true; NMTID=xxx' + } + // console.log(options.cookie, headers['Cookie']) + if (options.crypto === 'weapi') { + headers['User-Agent'] = + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.69' + let csrfToken = (headers['Cookie'] || '').match(/_csrf=([^(;|$)]+)/) + data.csrf_token = csrfToken ? csrfToken[1] : '' + data = encrypt.weapi(data) + url = url.replace(/\w*api/, 'weapi') + } else if (options.crypto === 'linuxapi') { + data = encrypt.linuxapi({ + method: method, + url: url.replace(/\w*api/, 'api'), + params: data, + }) + headers['User-Agent'] = + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36' + url = 'https://music.163.com/api/linux/forward' + } else if (options.crypto === 'eapi') { + const cookie = options.cookie || {} + const csrfToken = cookie['__csrf'] || '' + const header = { + osver: cookie.osver, //系统版本 + deviceId: cookie.deviceId, //encrypt.base64.encode(imei + '\t02:00:00:00:00:00\t5106025eb79a5247\t70ffbaac7') + appver: cookie.appver || '8.9.70', // app版本 + versioncode: cookie.versioncode || '140', //版本号 + mobilename: cookie.mobilename, //设备model + buildver: cookie.buildver || Date.now().toString().substr(0, 10), + resolution: cookie.resolution || '1920x1080', //设备分辨率 + __csrf: csrfToken, + os: cookie.os || 'android', + channel: cookie.channel, + requestId: `${Date.now()}_${Math.floor(Math.random() * 1000) + .toString() + .padStart(4, '0')}`, + } + if (cookie.MUSIC_U) header['MUSIC_U'] = cookie.MUSIC_U + if (cookie.MUSIC_A) header['MUSIC_A'] = cookie.MUSIC_A + headers['Cookie'] = Object.keys(header) + .map( + (key) => + encodeURIComponent(key) + '=' + encodeURIComponent(header[key]), + ) + .join('; ') + data.header = header + data = encrypt.eapi(options.url, data) + url = url.replace(/\w*api/, 'eapi') + } + const answer = { status: 500, body: {}, cookie: [] } + let settings = { + method: method, + url: url, + headers: headers, + data: new URLSearchParams(data).toString(), + httpAgent: new http.Agent({ keepAlive: true }), + httpsAgent: new https.Agent({ keepAlive: true }), + } + + if (options.crypto === 'eapi') settings.encoding = null + + if (options.proxy) { + if (options.proxy.indexOf('pac') > -1) { + settings.httpAgent = new PacProxyAgent(options.proxy) + settings.httpsAgent = new PacProxyAgent(options.proxy) + } else { + const purl = new URL(options.proxy) + if (purl.hostname) { + const agent = tunnel[ + purl.protocol === 'https' ? 'httpsOverHttp' : 'httpOverHttp' + ]({ + proxy: { + host: purl.hostname, + port: purl.port || 80, + proxyAuth: + purl.username && purl.password + ? purl.username + ':' + purl.password + : '', + }, + }) + settings.httpsAgent = agent + settings.httpAgent = agent + settings.proxy = false + } else { + console.error('代理配置无效,不使用代理') + } + } + } else { + settings.proxy = false + } + if (options.crypto === 'eapi') { + settings = { + ...settings, + responseType: 'arraybuffer', + } + } + axios(settings) + .then((res) => { + const body = res.data + answer.cookie = (res.headers['set-cookie'] || []).map((x) => + x.replace(/\s*Domain=[^(;|$)]+;*/, ''), + ) + try { + if (options.crypto === 'eapi') { + answer.body = JSON.parse(encrypt.decrypt(body).toString()) + } else { + answer.body = body + } + if (answer.body.code) { + answer.body.code = Number(answer.body.code) + } + + answer.status = Number(answer.body.code || res.status) + if ( + [201, 302, 400, 502, 800, 801, 802, 803].indexOf(answer.body.code) > + -1 + ) { + // 特殊状态码 + answer.status = 200 + } + } catch (e) { + // console.log(e) + try { + answer.body = JSON.parse(body.toString()) + } catch (err) { + // console.log(err) + // can't decrypt and can't parse directly + answer.body = body + } + answer.status = res.status + } + + answer.status = + 100 < answer.status && answer.status < 600 ? answer.status : 400 + if (answer.status === 200) resolve(answer) + else reject(answer) + }) + .catch((err) => { + answer.status = 502 + answer.body = { code: 502, msg: err } + reject(answer) + }) + }) +} + +module.exports = createRequest diff --git a/WebSourceCode/src/Netease/vercel.json b/WebSourceCode/src/Netease/vercel.json new file mode 100644 index 0000000..7006eec --- /dev/null +++ b/WebSourceCode/src/Netease/vercel.json @@ -0,0 +1,15 @@ +{ + "version": 2, + "builds": [ + { + "src": "./index.js", + "use": "@vercel/node@2.5.10" + } + ], + "routes": [ + { + "src": "/(.*)", + "dest": "/" + } + ] +} diff --git a/WebSourceCode/src/Netease/yarn.lock b/WebSourceCode/src/Netease/yarn.lock new file mode 100644 index 0000000..05148fd --- /dev/null +++ b/WebSourceCode/src/Netease/yarn.lock @@ -0,0 +1,3855 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/generator@7.18.2": + version "7.18.2" + resolved "https://registry.npmmirror.com/@babel/generator/-/generator-7.18.2.tgz" + integrity sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw== + dependencies: + "@babel/types" "^7.18.2" + "@jridgewell/gen-mapping" "^0.3.0" + jsesc "^2.5.1" + +"@babel/helper-validator-identifier@^7.16.7": + version "7.19.1" + resolved "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + +"@babel/parser@7.18.4": + version "7.18.4" + resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.18.4.tgz" + integrity sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow== + +"@babel/types@7.18.4", "@babel/types@^7.18.2": + version "7.18.4" + resolved "https://registry.npmmirror.com/@babel/types/-/types-7.18.4.tgz" + integrity sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + +"@eslint/eslintrc@^1.0.5": + version "1.0.5" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz" + integrity sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.2.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@humanwhocodes/config-array@^0.9.2": + version "0.9.2" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz" + integrity sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.2" + resolved "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.17" + resolved "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@tokenizer/token@^0.1.0": + version "0.1.1" + resolved "https://registry.npmjs.org/@tokenizer/token/-/token-0.1.1.tgz" + integrity sha512-XO6INPbZCxdprl+9qa/AAbFFOMzzwqYxpjPgLICrMD6C2FCw6qfJOPcBk6JqqPLSaZ/Qx87qn4rpPmPMwaAK6w== + +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== + +"@tootallnate/quickjs-emscripten@^0.23.0": + version "0.23.0" + resolved "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz" + integrity sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA== + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/busboy@^0": + version "0.3.2" + resolved "https://registry.npmjs.org/@types/busboy/-/busboy-0.3.2.tgz" + integrity sha512-iEvdm9Z9KdSs/ozuh1Z7ZsXrOl8F4M/CLMXPZHr3QuJ4d6Bjn+HBMC5EMKpwpAo8oi8iK9GZfFoHaIMrrZgwVw== + dependencies: + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/express-fileupload@^1.2.2": + version "1.2.2" + resolved "https://registry.npmjs.org/@types/express-fileupload/-/express-fileupload-1.2.2.tgz" + integrity sha512-sWU1EVFfLsdAginKVrkwTRbRPnbn7dawxEFEBgaRDcpNFCUuksZtASaAKEhqwEIg6fSdeTyI6dIUGl3thhrypg== + dependencies: + "@types/busboy" "^0" + "@types/express" "*" + +"@types/express-serve-static-core@^4.17.18": + version "4.17.28" + resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz" + integrity sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/json-schema@^7.0.7": + version "7.0.9" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/mocha@^9.1.0": + version "9.1.0" + resolved "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz" + integrity sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg== + +"@types/node@*", "@types/node@16.11.19": + version "16.11.19" + resolved "https://registry.npmjs.org/@types/node/-/node-16.11.19.tgz" + integrity sha512-BPAcfDPoHlRQNKktbsbnpACGdypPFBuX4xQlsWDE7B8XXcfII+SpOLay3/qZmCLb39kV5S1RTYwXdkx2lwLYng== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/readable-stream@^2.3.9": + version "2.3.9" + resolved "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.9.tgz" + integrity sha512-sqsgQqFT7HmQz/V5jH1O0fvQQnXAJO46Gg9LRO/JPfjmVmGUlcx831TZZO3Y3HtWhIkzf3kTsNT0Z0kzIhIvZw== + dependencies: + "@types/node" "*" + safe-buffer "*" + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@typescript-eslint/eslint-plugin@5.0.0": + version "5.0.0" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.0.0.tgz" + integrity sha512-T6V6fCD2U0YesOedvydTnrNtsC8E+c2QzpawIpDdlaObX0OX5dLo7tLU5c64FhTZvA1Xrdim+cXDI7NPsVx8Cg== + dependencies: + "@typescript-eslint/experimental-utils" "5.0.0" + "@typescript-eslint/scope-manager" "5.0.0" + debug "^4.3.1" + functional-red-black-tree "^1.0.1" + ignore "^5.1.8" + regexpp "^3.1.0" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/experimental-utils@5.0.0": + version "5.0.0" + resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.0.0.tgz" + integrity sha512-Dnp4dFIsZcPawD6CT1p5NibNUQyGSEz80sULJZkyhyna8AEqArmfwMwJPbmKzWVo4PabqNVzHYlzmcdLQWk+pg== + dependencies: + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "5.0.0" + "@typescript-eslint/types" "5.0.0" + "@typescript-eslint/typescript-estree" "5.0.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/parser@5.0.0": + version "5.0.0" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.0.0.tgz" + integrity sha512-B6D5rmmQ14I1fdzs71eL3DAuvnPHTY/t7rQABrL9BLnx/H51Un8ox1xqYAchs0/V2trcoyxB1lMJLlrwrJCDgw== + dependencies: + "@typescript-eslint/scope-manager" "5.0.0" + "@typescript-eslint/types" "5.0.0" + "@typescript-eslint/typescript-estree" "5.0.0" + debug "^4.3.1" + +"@typescript-eslint/scope-manager@5.0.0": + version "5.0.0" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.0.0.tgz" + integrity sha512-5RFjdA/ain/MDUHYXdF173btOKncIrLuBmA9s6FJhzDrRAyVSA+70BHg0/MW6TE+UiKVyRtX91XpVS0gVNwVDQ== + dependencies: + "@typescript-eslint/types" "5.0.0" + "@typescript-eslint/visitor-keys" "5.0.0" + +"@typescript-eslint/types@5.0.0": + version "5.0.0" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.0.0.tgz" + integrity sha512-dU/pKBUpehdEqYuvkojmlv0FtHuZnLXFBn16zsDmlFF3LXkOpkAQ2vrKc3BidIIve9EMH2zfTlxqw9XM0fFN5w== + +"@typescript-eslint/typescript-estree@5.0.0": + version "5.0.0" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.0.0.tgz" + integrity sha512-V/6w+PPQMhinWKSn+fCiX5jwvd1vRBm7AX7SJQXEGQtwtBvjMPjaU3YTQ1ik2UF1u96X7tsB96HMnulG3eLi9Q== + dependencies: + "@typescript-eslint/types" "5.0.0" + "@typescript-eslint/visitor-keys" "5.0.0" + debug "^4.3.1" + globby "^11.0.3" + is-glob "^4.0.1" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/visitor-keys@5.0.0": + version "5.0.0" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.0.0.tgz" + integrity sha512-yRyd2++o/IrJdyHuYMxyFyBhU762MRHQ/bAGQeTnN3pGikfh+nEmM61XTqaDH1XDp53afZ+waXrk0ZvenoZ6xw== + dependencies: + "@typescript-eslint/types" "5.0.0" + eslint-visitor-keys "^3.0.0" + +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-es7-plugin@^1.0.10, acorn-es7-plugin@^1.0.12: + version "1.1.7" + resolved "https://registry.npm.taobao.org/acorn-es7-plugin/download/acorn-es7-plugin-1.1.7.tgz" + integrity sha1-8u4fMiipDurRJF+asZIusucdM2s= + +acorn-jsx@^5.3.1: + version "5.3.2" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^5.0.0: + version "5.7.4" + resolved "https://registry.npm.taobao.org/acorn/download/acorn-5.7.4.tgz" + integrity sha1-Po2KmUfQWZoXltECJddDL0pKz14= + +acorn@^8.7.0: + version "8.7.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + +agent-base@6: + version "6.0.2" + resolved "https://registry.npm.taobao.org/agent-base/download/agent-base-6.0.2.tgz?cache=0&sync_timestamp=1603480100923&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fagent-base%2Fdownload%2Fagent-base-6.0.2.tgz" + integrity sha1-Sf/1hXfP7j83F2/qtMIuAPhtf3c= + dependencies: + debug "4" + +agent-base@^7.0.1, agent-base@^7.0.2, agent-base@^7.1.0: + version "7.1.0" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz" + integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg== + dependencies: + debug "^4.3.4" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.npm.taobao.org/amdefine/download/amdefine-1.0.1.tgz" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.npm.taobao.org/ansi-colors/download/ansi-colors-4.1.1.tgz" + integrity sha1-y7muJWv3UK8eqzRPIpqif+lLo0g= + +ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-2.1.1.tgz" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + +ansi-regex@^4.1.0: + version "4.1.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz" + integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.0: + version "3.2.1" + resolved "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839122515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz" + integrity sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0= + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.0.0: + version "6.1.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz" + integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ== + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.npmmirror.com/aproba/-/aproba-1.2.0.tgz" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.7" + resolved "https://registry.npmmirror.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz" + integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-filter@^1.0.0: + version "1.0.0" + resolved "https://registry.npm.taobao.org/array-filter/download/array-filter-1.0.0.tgz" + integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= + +array-find@^1.0.0: + version "1.0.0" + resolved "https://registry.npm.taobao.org/array-find/download/array-find-1.0.0.tgz" + integrity sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz?cache=0&sync_timestamp=1574313384951&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-1.1.1.tgz" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +ast-types@^0.13.4: + version "0.13.4" + resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz" + integrity sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w== + dependencies: + tslib "^2.0.1" + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +axios@^1.2.2: + version "1.2.2" + resolved "https://registry.npmmirror.com/axios/-/axios-1.2.2.tgz" + integrity sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +basic-ftp@^5.0.2: + version "5.0.3" + resolved "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.3.tgz" + integrity sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz?cache=0&sync_timestamp=1601898189928&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrace-expansion%2Fdownload%2Fbrace-expansion-1.1.11.tgz" + integrity sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0= + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz" + integrity sha1-NFThpGLujVmeI23zNs2epPiv4Qc= + dependencies: + fill-range "^7.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer@^5.4.3, buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +busboy@^1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +call-matcher@^1.0.0: + version "1.1.0" + resolved "https://registry.npm.taobao.org/call-matcher/download/call-matcher-1.1.0.tgz" + integrity sha1-I7LBvHqDlMi+KGCdd929V4ZoBDI= + dependencies: + core-js "^2.0.0" + deep-equal "^1.0.0" + espurify "^1.6.0" + estraverse "^4.0.0" + +call-signature@0.0.2: + version "0.0.2" + resolved "https://registry.npm.taobao.org/call-signature/download/call-signature-0.0.2.tgz" + integrity sha1-qEq8glpV70yysCi9dOIFpluaSZY= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.npm.taobao.org/callsites/download/callsites-3.1.0.tgz" + integrity sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M= + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.0.0: + version "6.2.0" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +charenc@0.0.2: + version "0.0.2" + resolved "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz" + integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= + +chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.npmmirror.com/chownr/-/chownr-1.1.4.tgz" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + +cli-truncate@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz" + integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== + dependencies: + slice-ansi "^5.0.0" + string-width "^5.0.0" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/code-point-at/-/code-point-at-1.1.0.tgz" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz" + integrity sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg= + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz" + integrity sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM= + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz" + integrity sha1-wqCah6y95pVD3m9j+jmVyCbFNqI= + +colorette@^2.0.16: + version "2.0.16" + resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz" + integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/console-control-strings/-/console-control-strings-1.1.0.tgz" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@^1.0.4, content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz" + integrity sha1-4TjMdeBAxyexlm/l5fjJruJW/js= + +convert-source-map@^1.1.0, convert-source-map@^1.1.1: + version "1.7.0" + resolved "https://registry.npm.taobao.org/convert-source-map/download/convert-source-map-1.7.0.tgz?cache=0&sync_timestamp=1573003637425&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconvert-source-map%2Fdownload%2Fconvert-source-map-1.7.0.tgz" + integrity sha1-F6LLiC1/d9NJBYXizmxSRCSjpEI= + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +core-js@^2.0.0: + version "2.6.11" + resolved "https://registry.npm.taobao.org/core-js/download/core-js-2.6.11.tgz?cache=0&sync_timestamp=1586450269267&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-2.6.11.tgz" + integrity sha1-OIMUafmSK97Y7iHJ3EaYXgOZMIw= + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.3.tgz" + integrity sha1-9zqFudXUHQRVUcF34ogtSshXKKY= + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypt@0.0.2: + version "0.0.2" + resolved "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz" + integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.npm.taobao.org/d/download/d-1.0.1.tgz" + integrity sha1-hpgJU3LVjb7jRv/Qxwk/mfj561o= + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +data-uri-to-buffer@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-5.0.1.tgz" + integrity sha512-a9l6T1qqDogvvnw0nKlfZzqsyikEBZBClF39V3TFoKhDtGBqHu2HkuomJc02j5zft8zrUaXEuoicLeW54RkzPg== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4: + version "4.2.0" + resolved "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502894812&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz" + integrity sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E= + dependencies: + ms "2.1.2" + +debug@4.3.4, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: + version "4.3.2" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +debug@^4.3.3: + version "4.3.3" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +decompress-response@^4.2.0: + version "4.2.1" + resolved "https://registry.npmmirror.com/decompress-response/-/decompress-response-4.2.1.tgz" + integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== + dependencies: + mimic-response "^2.0.0" + +deep-equal@^1.0.0: + version "1.1.1" + resolved "https://registry.npm.taobao.org/deep-equal/download/deep-equal-1.1.1.tgz" + integrity sha1-tcmMlCzv+vfLBR4k4UNKJaLmB2o= + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.npmmirror.com/deep-extend/-/deep-extend-0.6.0.tgz" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@^0.1.3, deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.npm.taobao.org/deep-is/download/deep-is-0.1.3.tgz" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.npm.taobao.org/define-properties/download/define-properties-1.1.3.tgz" + integrity sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE= + dependencies: + object-keys "^1.0.12" + +degenerator@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/degenerator/-/degenerator-5.0.0.tgz" + integrity sha512-pdRxyYVe0unlUE/eeXBxFdB8w8J7QNNf7hFE/BKOAlTCz0bkF9h1MC82ii0r1ypqB/PTKYDbg4K9SZT9yfd9Fg== + dependencies: + ast-types "^0.13.4" + escodegen "^1.14.3" + esprima "^4.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz" + integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== + +diff-match-patch@^1.0.0: + version "1.0.5" + resolved "https://registry.npm.taobao.org/diff-match-patch/download/diff-match-patch-1.0.5.tgz" + integrity sha1-q7WE1fEM0Rlt/FWqA3AVkq4/ezc= + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +dijkstrajs@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz" + integrity sha1-082BIh4+pAdCz83lVtTpnpjdxxs= + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.1, domhandler@^5.0.2: + version "5.0.3" + resolved "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz" + integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.1" + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.npm.taobao.org/eastasianwidth/download/eastasianwidth-0.2.0.tgz" + integrity sha1-aWzi7Aqg5uqTo5f/zySqeEDIJ8s= + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +empower-assert@^1.0.0: + version "1.1.0" + resolved "https://registry.npm.taobao.org/empower-assert/download/empower-assert-1.1.0.tgz" + integrity sha1-jTJ/vmmoivkN2pjRv8mCnSok/WI= + dependencies: + estraverse "^4.2.0" + +empower-core@^1.2.0: + version "1.2.0" + resolved "https://registry.npm.taobao.org/empower-core/download/empower-core-1.2.0.tgz" + integrity sha1-zj+ySE1Rh/opwj+6g0Swsv31YBw= + dependencies: + call-signature "0.0.2" + core-js "^2.0.0" + +empower@^1.3.1: + version "1.3.1" + resolved "https://registry.npm.taobao.org/empower/download/empower-1.3.1.tgz" + integrity sha1-dol5y7s21x2PXtqrZj3qy52rkWw= + dependencies: + core-js "^2.0.0" + empower-core "^1.2.0" + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +entities@^4.2.0, entities@^4.3.0: + version "4.4.0" + resolved "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz" + integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== + +es-abstract@^1.17.0-next.1: + version "1.17.7" + resolved "https://registry.npm.taobao.org/es-abstract/download/es-abstract-1.17.7.tgz?cache=0&sync_timestamp=1601502719982&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fes-abstract%2Fdownload%2Fes-abstract-1.17.7.tgz" + integrity sha1-pN5hsvZpifx0IWdsHLl4dXOs5Uw= + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.2.2" + is-regex "^1.1.1" + object-inspect "^1.8.0" + object-keys "^1.1.1" + object.assign "^4.1.1" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" + +es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1: + version "1.18.0-next.1" + resolved "https://registry.npm.taobao.org/es-abstract/download/es-abstract-1.18.0-next.1.tgz?cache=0&sync_timestamp=1601502719982&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fes-abstract%2Fdownload%2Fes-abstract-1.18.0-next.1.tgz" + integrity sha1-bjoKS9pxflAjqzuOkL7DYQjSLGg= + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.2.2" + is-negative-zero "^2.0.0" + is-regex "^1.1.1" + object-inspect "^1.8.0" + object-keys "^1.1.1" + object.assign "^4.1.1" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.npm.taobao.org/es-to-primitive/download/es-to-primitive-1.2.1.tgz" + integrity sha1-5VzUyc3BiLzvsDs2bHNjI/xciYo= + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@~0.10.14: + version "0.10.53" + resolved "https://registry.npm.taobao.org/es5-ext/download/es5-ext-0.10.53.tgz" + integrity sha1-k8WjrP2+8nUiCtcmRK0C7hg2jeE= + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@^2.0.3, es6-iterator@~2.0.1, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.npm.taobao.org/es6-iterator/download/es6-iterator-2.0.3.tgz" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-map@^0.1.3: + version "0.1.5" + resolved "https://registry.npm.taobao.org/es6-map/download/es6-map-0.1.5.tgz" + integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.npm.taobao.org/es6-set/download/es6-set-0.1.5.tgz" + integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1: + version "3.1.1" + resolved "https://registry.npm.taobao.org/es6-symbol/download/es6-symbol-3.1.1.tgz" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-symbol@^3.1.1, es6-symbol@~3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.npm.taobao.org/es6-symbol/download/es6-symbol-3.1.3.tgz" + integrity sha1-utXTwbzawoJp9MszHkMceKxwXRg= + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.1: + version "2.0.3" + resolved "https://registry.npm.taobao.org/es6-weak-map/download/es6-weak-map-2.0.3.tgz" + integrity sha1-ttofFswswNm+Q+a9v8Xn383zHVM= + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escallmatch@^1.5.0: + version "1.5.0" + resolved "https://registry.npm.taobao.org/escallmatch/download/escallmatch-1.5.0.tgz" + integrity sha1-UAmdhugJGwkt+N37w/mm+wWgJNA= + dependencies: + call-matcher "^1.0.0" + esprima "^2.0.0" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escodegen@^1.10.0, escodegen@^1.14.3, escodegen@^1.7.0: + version "1.14.3" + resolved "https://registry.npm.taobao.org/escodegen/download/escodegen-1.14.3.tgz?cache=0&sync_timestamp=1596669832613&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fescodegen%2Fdownload%2Fescodegen-1.14.3.tgz" + integrity sha1-TnuB+6YVgdyXWC7XjKt/Do1j9QM= + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +escope@^3.3.0: + version "3.6.0" + resolved "https://registry.npm.taobao.org/escope/download/escope-3.6.0.tgz" + integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM= + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-config-prettier@8.5.0: + version "8.5.0" + resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz" + integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== + +eslint-plugin-html@7.1.0: + version "7.1.0" + resolved "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-7.1.0.tgz" + integrity sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg== + dependencies: + htmlparser2 "^8.0.1" + +eslint-plugin-prettier@4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz" + integrity sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.npm.taobao.org/eslint-scope/download/eslint-scope-5.1.1.tgz?cache=0&sync_timestamp=1599933651660&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-scope%2Fdownload%2Feslint-scope-5.1.1.tgz" + integrity sha1-54blmmbLkrP2wfsNUIqrF0hI9Iw= + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-scope@^7.1.0: + version "7.1.0" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz" + integrity sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.npm.taobao.org/eslint-visitor-keys/download/eslint-visitor-keys-2.0.0.tgz?cache=0&sync_timestamp=1597435068105&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-visitor-keys%2Fdownload%2Feslint-visitor-keys-2.0.0.tgz" + integrity sha1-If3I+82ceVzAMh8FY3AglXUVEag= + +eslint-visitor-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz" + integrity sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q== + +eslint-visitor-keys@^3.1.0, eslint-visitor-keys@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz" + integrity sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ== + +eslint@8.7.0: + version "8.7.0" + resolved "https://registry.npmjs.org/eslint/-/eslint-8.7.0.tgz" + integrity sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w== + dependencies: + "@eslint/eslintrc" "^1.0.5" + "@humanwhocodes/config-array" "^0.9.2" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.1.0" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.2.0" + espree "^9.3.0" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^6.0.1" + globals "^13.6.0" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + regexpp "^3.2.0" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espower-loader@^1.0.0: + version "1.2.2" + resolved "https://registry.npm.taobao.org/espower-loader/download/espower-loader-1.2.2.tgz" + integrity sha1-7bRsPFmga6yOpzppXIblxaC8gto= + dependencies: + convert-source-map "^1.1.0" + espower-source "^2.0.0" + minimatch "^3.0.0" + source-map-support "^0.4.0" + xtend "^4.0.0" + +espower-location-detector@^1.0.0: + version "1.0.0" + resolved "https://registry.npm.taobao.org/espower-location-detector/download/espower-location-detector-1.0.0.tgz" + integrity sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU= + dependencies: + is-url "^1.2.1" + path-is-absolute "^1.0.0" + source-map "^0.5.0" + xtend "^4.0.0" + +espower-source@^2.0.0: + version "2.3.0" + resolved "https://registry.npm.taobao.org/espower-source/download/espower-source-2.3.0.tgz" + integrity sha1-Q+k7LBivUAGL2xvqehJx9KHBJfQ= + dependencies: + acorn "^5.0.0" + acorn-es7-plugin "^1.0.10" + convert-source-map "^1.1.1" + empower-assert "^1.0.0" + escodegen "^1.10.0" + espower "^2.1.1" + estraverse "^4.0.0" + merge-estraverse-visitors "^1.0.0" + multi-stage-sourcemap "^0.2.1" + path-is-absolute "^1.0.0" + xtend "^4.0.0" + +espower@^2.1.1: + version "2.1.2" + resolved "https://registry.npm.taobao.org/espower/download/espower-2.1.2.tgz" + integrity sha1-gk+IeI+f7fTPD5KPXhG7kHzpuRg= + dependencies: + array-find "^1.0.0" + escallmatch "^1.5.0" + escodegen "^1.7.0" + escope "^3.3.0" + espower-location-detector "^1.0.0" + espurify "^1.3.0" + estraverse "^4.1.0" + source-map "^0.5.0" + type-name "^2.0.0" + +espree@^9.2.0, espree@^9.3.0: + version "9.3.0" + resolved "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz" + integrity sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ== + dependencies: + acorn "^8.7.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^3.1.0" + +esprima@^2.0.0: + version "2.7.3" + resolved "https://registry.npm.taobao.org/esprima/download/esprima-2.7.3.tgz" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + +esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.npm.taobao.org/esprima/download/esprima-4.0.1.tgz" + integrity sha1-E7BM2z5sXRnfkatph6hpVhmwqnE= + +espurify@^1.3.0, espurify@^1.6.0: + version "1.8.1" + resolved "https://registry.npm.taobao.org/espurify/download/espurify-1.8.1.tgz" + integrity sha1-V0bGwatC0wLeEL0dW/fw6MBRUFY= + dependencies: + core-js "^2.0.0" + +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.1.0, esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.npm.taobao.org/esrecurse/download/esrecurse-4.3.0.tgz?cache=0&sync_timestamp=1598898255610&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fesrecurse%2Fdownload%2Fesrecurse-4.3.0.tgz" + integrity sha1-eteWTWeauyi+5yzsY3WLHF0smSE= + dependencies: + estraverse "^5.2.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.npm.taobao.org/estraverse/download/estraverse-4.3.0.tgz?cache=0&sync_timestamp=1596642998635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festraverse%2Fdownload%2Festraverse-4.3.0.tgz" + integrity sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0= + +estraverse@^5.1.0: + version "5.2.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.npm.taobao.org/esutils/download/esutils-2.0.3.tgz" + integrity sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.npm.taobao.org/event-emitter/download/event-emitter-0.3.5.tgz" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + +execa@^5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.npmmirror.com/expand-template/-/expand-template-2.0.3.tgz" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + +express-fileupload@^1.1.9: + version "1.4.0" + resolved "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.4.0.tgz" + integrity sha512-RjzLCHxkv3umDeZKeFeMg8w7qe0V09w3B7oGZprr/oO2H/ISCgNzuqzn7gV3HRWb37GjRk429CCpSLS2KNTqMQ== + dependencies: + busboy "^1.6.0" + +express@^4.17.1: + version "4.18.2" + resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.npm.taobao.org/ext/download/ext-1.4.0.tgz" + integrity sha1-ia56BxWPedNVF4gpBDJAd+Q3kkQ= + dependencies: + type "^2.0.0" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-glob@^3.2.9: + version "3.2.12" + resolved "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.2.12.tgz" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.npm.taobao.org/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +file-type@^16.1.0: + version "16.5.4" + resolved "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz" + integrity sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw== + dependencies: + readable-web-to-node-stream "^3.0.0" + strtok3 "^6.2.4" + token-types "^4.1.1" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz" + integrity sha1-GRmmp8df44ssfHflGYU12prN2kA= + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz" + integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== + +follow-redirects@^1.15.0: + version "1.15.2" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +from2@^2.3.0: + version "2.3.0" + resolved "https://registry.npmmirror.com/from2/-/from2-2.3.0.tgz" + integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/fs-constants/-/fs-constants-1.0.0.tgz" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^9.1.0: + version "9.1.0" + resolved "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz" + integrity sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0= + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.npm.taobao.org/functional-red-black-tree/download/functional-red-black-tree-1.0.1.tgz" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.npmmirror.com/gauge/-/gauge-2.7.4.tgz" + integrity sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg== + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-caller-file@^2.0.1, get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.npm.taobao.org/get-caller-file/download/get-caller-file-2.0.5.tgz" + integrity sha1-T5RBKoLbMvNuOwuXQfipf+sDH34= + +get-intrinsic@^1.0.2: + version "1.1.3" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz" + integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-uri@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/get-uri/-/get-uri-6.0.1.tgz" + integrity sha512-7ZqONUVqaabogsYNWlYj0t3YZaL6dhuEueZXGF+/YVmf6dHmaFg8/6psJKqhx9QykIDKzpGcy2cn4oV4YC7V/Q== + dependencies: + basic-ftp "^5.0.2" + data-uri-to-buffer "^5.0.1" + debug "^4.3.4" + fs-extra "^8.1.0" + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.npmmirror.com/github-from-package/-/github-from-package-0.0.0.tgz" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@7.2.0, glob@^7.1.3: + version "7.2.0" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^13.6.0, globals@^13.9.0: + version "13.10.0" + resolved "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz" + integrity sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g== + dependencies: + type-fest "^0.20.2" + +globby@^11.0.3, globby@^11.1.0: + version "11.1.0" + resolved "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.4" + resolved "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.4.tgz" + integrity sha1-Ila94U02MpWMRl68ltxGfKB6Kfs= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz" + integrity sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s= + +has-symbols@^1.0.1, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/has-unicode/-/has-unicode-2.0.1.tgz" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.npm.taobao.org/has/download/has-1.0.3.tgz" + integrity sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y= + dependencies: + function-bind "^1.1.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +htmlparser2@^8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz" + integrity sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + domutils "^3.0.1" + entities "^4.3.0" + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz" + integrity sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ== + dependencies: + agent-base "^7.1.0" + debug "^4.3.4" + +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.npm.taobao.org/https-proxy-agent/download/https-proxy-agent-5.0.0.tgz?cache=0&sync_timestamp=1581106803611&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttps-proxy-agent%2Fdownload%2Fhttps-proxy-agent-5.0.0.tgz" + integrity sha1-4qkFQqu2inYuCghQ9sntrf2FBrI= + dependencies: + agent-base "6" + debug "4" + +https-proxy-agent@^7.0.0: + version "7.0.1" + resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz" + integrity sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ== + dependencies: + agent-base "^7.0.2" + debug "4" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +husky@7.0.4: + version "7.0.4" + resolved "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz" + integrity sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz?cache=0&sync_timestamp=1594184264130&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ficonv-lite%2Fdownload%2Ficonv-lite-0.4.24.tgz" + integrity sha1-ICK0sl+93CHS9SSXSkdKr+czkIs= + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.13, ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.8, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.2.1" + resolved "https://registry.npm.taobao.org/import-fresh/download/import-fresh-3.2.1.tgz" + integrity sha1-Yz/2GFBueTr1rJG/SLcmd+FcvmY= + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.npm.taobao.org/indexof/download/indexof-0.0.1.tgz" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +intelli-espower-loader@1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/intelli-espower-loader/-/intelli-espower-loader-1.1.0.tgz" + integrity sha512-GmnpIM5tRU5n8R4bQAcu2gJMlfRukrtklbE1auRN8qGK9KSLboGdmHSLSLLnIHKrnRmgWRBXNqy5sIOrbT2l8g== + dependencies: + espower-loader "^1.0.0" + +into-stream@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/into-stream/-/into-stream-6.0.0.tgz" + integrity sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA== + dependencies: + from2 "^2.3.0" + p-is-promise "^3.0.0" + +ip@^1.1.8: + version "1.1.8" + resolved "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz" + integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== + +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.npm.taobao.org/is-arguments/download/is-arguments-1.0.4.tgz" + integrity sha1-P6+WbHy6D/Q3+zH2JQCC/PBEjPM= + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-buffer@~1.1.6: + version "1.1.6" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.4, is-callable@^1.2.2: + version "1.2.2" + resolved "https://registry.npm.taobao.org/is-callable/download/is-callable-1.2.2.tgz?cache=0&sync_timestamp=1600719276620&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-callable%2Fdownload%2Fis-callable-1.2.2.tgz" + integrity sha1-x8ZxXNItTdtI0+GZcCI6zquwgNk= + +is-core-module@2.9.0, is-core-module@^2.9.0: + version "2.9.0" + resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.9.0.tgz" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.npm.taobao.org/is-date-object/download/is-date-object-1.0.2.tgz?cache=0&sync_timestamp=1576729165697&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-date-object%2Fdownload%2Fis-date-object-1.0.2.tgz" + integrity sha1-vac28s2P0G0yhE53Q7+nSUw7/X4= + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.npm.taobao.org/is-extglob/download/is-extglob-2.1.1.tgz" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" + integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-2.0.0.tgz" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-fullwidth-code-point@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz" + integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-negative-zero@^2.0.0: + version "2.0.0" + resolved "https://registry.npm.taobao.org/is-negative-zero/download/is-negative-zero-2.0.0.tgz" + integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz" + integrity sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss= + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-regex@^1.0.4, is-regex@^1.1.1: + version "1.1.1" + resolved "https://registry.npm.taobao.org/is-regex/download/is-regex-1.1.1.tgz?cache=0&sync_timestamp=1596555762356&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-regex%2Fdownload%2Fis-regex-1.1.1.tgz" + integrity sha1-xvmKrMVG9s7FRooHt7FTq1ZKV7k= + dependencies: + has-symbols "^1.0.1" + +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.npm.taobao.org/is-symbol/download/is-symbol-1.0.3.tgz" + integrity sha1-OOEBS55jKb4N6dJKQU/XRB7GGTc= + dependencies: + has-symbols "^1.0.1" + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-url@^1.2.1: + version "1.2.4" + resolved "https://registry.npm.taobao.org/is-url/download/is-url-1.2.4.tgz" + integrity sha1-BKTfRtKMTP89c9Af8Gq+sxihqlI= + +isarray@^2.0.1: + version "2.0.5" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +js-yaml@4.1.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.npm.taobao.org/levn/download/levn-0.3.0.tgz" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lilconfig@2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz" + integrity sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA== + +lint-staged@12.1.7: + version "12.1.7" + resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-12.1.7.tgz" + integrity sha512-bltv/ejiLWtowExpjU+s5z8j1Byjg9AlmaAjMmqNbIicY69u6sYIwXGg0dCn0TlkrrY2CphtHIXAkbZ+1VoWQQ== + dependencies: + cli-truncate "^3.1.0" + colorette "^2.0.16" + commander "^8.3.0" + debug "^4.3.3" + execa "^5.1.1" + lilconfig "2.0.4" + listr2 "^3.13.5" + micromatch "^4.0.4" + normalize-path "^3.0.0" + object-inspect "^1.11.1" + string-argv "^0.3.1" + supports-color "^9.2.1" + yaml "^1.10.2" + +listr2@^3.13.5: + version "3.14.0" + resolved "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz" + integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.16" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.5.1" + through "^2.3.8" + wrap-ansi "^7.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +md5@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz" + integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g== + dependencies: + charenc "0.0.2" + crypt "0.0.2" + is-buffer "~1.1.6" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +media-typer@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz" + integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-estraverse-visitors@^1.0.0: + version "1.0.0" + resolved "https://registry.npm.taobao.org/merge-estraverse-visitors/download/merge-estraverse-visitors-1.0.0.tgz" + integrity sha1-65aDOLXe1c7tgs7AMH3sui2OqZQ= + dependencies: + estraverse "^4.0.0" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^2.0.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/mimic-response/-/mimic-response-2.1.0.tgz" + integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^3.0.0, minimatch@^3.0.4: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.npmmirror.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +mocha@10.0.0: + version "10.0.0" + resolved "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz" + integrity sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multi-stage-sourcemap@^0.2.1: + version "0.2.1" + resolved "https://registry.npm.taobao.org/multi-stage-sourcemap/download/multi-stage-sourcemap-0.2.1.tgz" + integrity sha1-sJ/IWG6qF/gdV1xK0C4Pej9rEQU= + dependencies: + source-map "^0.1.34" + +multistream@^4.1.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/multistream/-/multistream-4.1.0.tgz" + integrity sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw== + dependencies: + once "^1.4.0" + readable-stream "^3.6.0" + +music-metadata@^7.5.3: + version "7.6.0" + resolved "https://registry.npmjs.org/music-metadata/-/music-metadata-7.6.0.tgz" + integrity sha512-XSBNmv+4JwithIharDmqwEVGLqEQ62nvrpSJAc5OQcgciSlTjjZLxmAQRic1AofiMB4t45D4MS4mwGk/5PeVeQ== + dependencies: + content-type "^1.0.4" + debug "^4.3.1" + file-type "^16.1.0" + media-typer "^1.1.0" + strtok3 "^6.0.4" + token-types "^2.0.0" + +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +netmask@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz" + integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.npm.taobao.org/next-tick/download/next-tick-1.0.0.tgz" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +node-abi@^2.21.0: + version "2.30.1" + resolved "https://registry.npmmirror.com/node-abi/-/node-abi-2.30.1.tgz" + integrity sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w== + dependencies: + semver "^5.4.1" + +node-fetch@^2.6.6: + version "2.6.9" + resolved "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.6.9.tgz" + integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== + dependencies: + whatwg-url "^5.0.0" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.npm.taobao.org/normalize-path/download/normalize-path-3.0.0.tgz" + integrity sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU= + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +npmlog@^4.0.1: + version "4.1.2" + resolved "https://registry.npmmirror.com/npmlog/-/npmlog-4.1.2.tgz" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/number-is-nan/-/number-is-nan-1.0.1.tgz" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== + +object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.11.1, object-inspect@^1.8.0, object-inspect@^1.9.0: + version "1.12.0" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz" + integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== + +object-is@^1.0.1: + version "1.1.3" + resolved "https://registry.npm.taobao.org/object-is/download/object-is-1.1.3.tgz?cache=0&sync_timestamp=1601502788762&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject-is%2Fdownload%2Fobject-is-1.1.3.tgz" + integrity sha1-LjueZVYBN0Ve471irsTZCi6hzIE= + dependencies: + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + +object-keys@^1.0.0, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.npm.taobao.org/object-keys/download/object-keys-1.1.1.tgz" + integrity sha1-HEfyct8nfzsdrwYWd9nILiMixg4= + +object.assign@^4.1.1: + version "4.1.1" + resolved "https://registry.npm.taobao.org/object.assign/download/object.assign-4.1.1.tgz?cache=0&sync_timestamp=1599844927493&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject.assign%2Fdownload%2Fobject.assign-4.1.1.tgz" + integrity sha1-MDhnpmbN1Bk27N7fsfjz4ypHjN0= + dependencies: + define-properties "^1.1.3" + es-abstract "^1.18.0-next.0" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.npm.taobao.org/optionator/download/optionator-0.8.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Foptionator%2Fdownload%2Foptionator-0.8.3.tgz" + integrity sha1-hPodA2/p08fiHZmIS2ARZ+yPtJU= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +p-is-promise@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/p-is-promise/-/p-is-promise-3.0.0.tgz" + integrity sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ== + +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pac-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.0.tgz" + integrity sha512-t4tRAMx0uphnZrio0S0Jw9zg3oDbz1zVhQ/Vy18FjLfP1XOLNUEjaVxYCYRI6NS+BsMBXKIzV6cTLOkO9AtywA== + dependencies: + "@tootallnate/quickjs-emscripten" "^0.23.0" + agent-base "^7.0.2" + debug "^4.3.4" + get-uri "^6.0.1" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.0" + pac-resolver "^7.0.0" + socks-proxy-agent "^8.0.1" + +pac-resolver@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz" + integrity sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg== + dependencies: + degenerator "^5.0.0" + ip "^1.1.8" + netmask "^2.0.2" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.npm.taobao.org/parent-module/download/parent-module-1.0.1.tgz" + integrity sha1-aR0nCeeMefrjoVZiJFLQB2LKqqI= + dependencies: + callsites "^3.0.0" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npm.taobao.org/path-key/download/path-key-3.1.1.tgz" + integrity sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U= + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-0.1.7.tgz" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.npm.taobao.org/path-type/download/path-type-4.0.0.tgz" + integrity sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs= + +peek-readable@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz" + integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +pkg-fetch@3.4.2: + version "3.4.2" + resolved "https://registry.npmmirror.com/pkg-fetch/-/pkg-fetch-3.4.2.tgz" + integrity sha512-0+uijmzYcnhC0hStDjm/cl2VYdrmVVBpe7Q8k9YBojxmR5tG8mvR9/nooQq3QSXiQqORDVOTY3XqMEqJVIzkHA== + dependencies: + chalk "^4.1.2" + fs-extra "^9.1.0" + https-proxy-agent "^5.0.0" + node-fetch "^2.6.6" + progress "^2.0.3" + semver "^7.3.5" + tar-fs "^2.1.1" + yargs "^16.2.0" + +pkg@^5.8.0: + version "5.8.0" + resolved "https://registry.npmmirror.com/pkg/-/pkg-5.8.0.tgz" + integrity sha512-8h9PUDYFi+LOMLbIyGRdP21g08mAtHidSpofSrf8LWhxUWGHymaRzcopEGiynB5EhQmZUKM6PQ9kCImV2TpdjQ== + dependencies: + "@babel/generator" "7.18.2" + "@babel/parser" "7.18.4" + "@babel/types" "7.18.4" + chalk "^4.1.2" + fs-extra "^9.1.0" + globby "^11.1.0" + into-stream "^6.0.0" + is-core-module "2.9.0" + minimist "^1.2.6" + multistream "^4.1.0" + pkg-fetch "3.4.2" + prebuild-install "6.1.4" + resolve "^1.22.0" + stream-meter "^1.0.4" + +pngjs@^3.3.0: + version "3.4.0" + resolved "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz" + integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== + +power-assert-context-formatter@^1.0.7: + version "1.2.0" + resolved "https://registry.npm.taobao.org/power-assert-context-formatter/download/power-assert-context-formatter-1.2.0.tgz" + integrity sha1-j75yaSKI7FpyA83yFci4OKYGHSo= + dependencies: + core-js "^2.0.0" + power-assert-context-traversal "^1.2.0" + +power-assert-context-reducer-ast@^1.0.7: + version "1.2.0" + resolved "https://registry.npm.taobao.org/power-assert-context-reducer-ast/download/power-assert-context-reducer-ast-1.2.0.tgz" + integrity sha1-x8ocnjmm+3F/esX+nnbhkr9SXfM= + dependencies: + acorn "^5.0.0" + acorn-es7-plugin "^1.0.12" + core-js "^2.0.0" + espurify "^1.6.0" + estraverse "^4.2.0" + +power-assert-context-traversal@^1.2.0: + version "1.2.0" + resolved "https://registry.npm.taobao.org/power-assert-context-traversal/download/power-assert-context-traversal-1.2.0.tgz" + integrity sha1-9ucUVLr2QN5cHJwnA0n1yasLLpQ= + dependencies: + core-js "^2.0.0" + estraverse "^4.1.0" + +power-assert-formatter@^1.4.1: + version "1.4.1" + resolved "https://registry.npm.taobao.org/power-assert-formatter/download/power-assert-formatter-1.4.1.tgz" + integrity sha1-XcEl7VCj37HdomwZNH879Y7CiEo= + dependencies: + core-js "^2.0.0" + power-assert-context-formatter "^1.0.7" + power-assert-context-reducer-ast "^1.0.7" + power-assert-renderer-assertion "^1.0.7" + power-assert-renderer-comparison "^1.0.7" + power-assert-renderer-diagram "^1.0.7" + power-assert-renderer-file "^1.0.7" + +power-assert-renderer-assertion@^1.0.7: + version "1.2.0" + resolved "https://registry.npm.taobao.org/power-assert-renderer-assertion/download/power-assert-renderer-assertion-1.2.0.tgz" + integrity sha1-Pbb/zaEGs3vB4GQyrQ10imgrFHo= + dependencies: + power-assert-renderer-base "^1.1.1" + power-assert-util-string-width "^1.2.0" + +power-assert-renderer-base@^1.1.1: + version "1.1.1" + resolved "https://registry.npm.taobao.org/power-assert-renderer-base/download/power-assert-renderer-base-1.1.1.tgz" + integrity sha1-lqZQxv0F7hvB9mtUrWFELIs/Y+s= + +power-assert-renderer-comparison@^1.0.7: + version "1.2.0" + resolved "https://registry.npm.taobao.org/power-assert-renderer-comparison/download/power-assert-renderer-comparison-1.2.0.tgz" + integrity sha1-5PiBEyJaab6KpYbq0FrvmUYsBJU= + dependencies: + core-js "^2.0.0" + diff-match-patch "^1.0.0" + power-assert-renderer-base "^1.1.1" + stringifier "^1.3.0" + type-name "^2.0.1" + +power-assert-renderer-diagram@^1.0.7: + version "1.2.0" + resolved "https://registry.npm.taobao.org/power-assert-renderer-diagram/download/power-assert-renderer-diagram-1.2.0.tgz" + integrity sha1-N/ZuhULlZ3xbWObXKwHA2aMOIhk= + dependencies: + core-js "^2.0.0" + power-assert-renderer-base "^1.1.1" + power-assert-util-string-width "^1.2.0" + stringifier "^1.3.0" + +power-assert-renderer-file@^1.0.7: + version "1.2.0" + resolved "https://registry.npm.taobao.org/power-assert-renderer-file/download/power-assert-renderer-file-1.2.0.tgz" + integrity sha1-P0vr2eFFXXXPKsVB57tRWofUzks= + dependencies: + power-assert-renderer-base "^1.1.1" + +power-assert-util-string-width@^1.2.0: + version "1.2.0" + resolved "https://registry.npm.taobao.org/power-assert-util-string-width/download/power-assert-util-string-width-1.2.0.tgz" + integrity sha1-bgbV41gbuHbF03fFMQn/+pW9kaA= + dependencies: + eastasianwidth "^0.2.0" + +power-assert@1.6.1: + version "1.6.1" + resolved "https://registry.npm.taobao.org/power-assert/download/power-assert-1.6.1.tgz" + integrity sha1-soy8Aq6Aiv0UMdDNUJOjmsWlsf4= + dependencies: + define-properties "^1.1.2" + empower "^1.3.1" + power-assert-formatter "^1.4.1" + universal-deep-strict-equal "^1.2.1" + xtend "^4.0.0" + +prebuild-install@6.1.4: + version "6.1.4" + resolved "https://registry.npmmirror.com/prebuild-install/-/prebuild-install-6.1.4.tgz" + integrity sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ== + dependencies: + detect-libc "^1.0.3" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^2.21.0" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^3.0.3" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.npm.taobao.org/prelude-ls/download/prelude-ls-1.1.2.tgz" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@2.7.1: + version "2.7.1" + resolved "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz" + integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +progress@^2.0.3: + version "2.0.3" + resolved "https://registry.npmmirror.com/progress/-/progress-2.0.3.tgz" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qrcode@^1.4.4: + version "1.4.4" + resolved "https://registry.npmjs.org/qrcode/-/qrcode-1.4.4.tgz" + integrity sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q== + dependencies: + buffer "^5.4.3" + buffer-alloc "^1.2.0" + buffer-from "^1.1.1" + dijkstrajs "^1.0.1" + isarray "^2.0.1" + pngjs "^3.3.0" + yargs "^13.2.4" + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.npmmirror.com/rc/-/rc-1.2.8.tgz" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +readable-stream@^2.0.0, readable-stream@^2.0.6, readable-stream@^2.1.4: + version "2.3.7" + resolved "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-web-to-node-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.0.tgz" + integrity sha512-HNmLb3n0SteGAs8HQlErYPGeO+y7cvL/mVUKtXeUkl0iCZ/2GIgKGrCFHyS7UXFnO8uc9U+0y3pYIzAPsjFfvA== + dependencies: + "@types/readable-stream" "^2.3.9" + readable-stream "^3.6.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +regexp.prototype.flags@^1.2.0: + version "1.3.0" + resolved "https://registry.npm.taobao.org/regexp.prototype.flags/download/regexp.prototype.flags-1.3.0.tgz?cache=0&sync_timestamp=1576388141321&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fregexp.prototype.flags%2Fdownload%2Fregexp.prototype.flags-1.3.0.tgz" + integrity sha1-erqJs8E6ZFCdq888qNn7ub31y3U= + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +regexpp@^3.1.0, regexpp@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.npm.taobao.org/require-directory/download/require-directory-2.1.1.tgz" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.npm.taobao.org/resolve-from/download/resolve-from-4.0.0.tgz" + integrity sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY= + +resolve@^1.22.0: + version "1.22.1" + resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rxjs@^7.5.1: + version "7.5.2" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.5.2.tgz" + integrity sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w== + dependencies: + tslib "^2.1.0" + +safe-buffer@*, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz" + integrity sha1-mR7GnSluAxN0fVm9/St0XDX4go0= + +safe-buffer@5.2.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-decode-uri-component@^1.2.1: + version "1.2.1" + resolved "https://registry.nlark.com/safe-decode-uri-component/download/safe-decode-uri-component-1.2.1.tgz" + integrity sha1-3dMMV+Z5ejsGcYiDk6SYS0VOISk= + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz" + integrity sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo= + +sax@>=0.6.0: + version "1.2.4" + resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +semver@^5.4.1: + version "5.7.1" + resolved "https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^7.3.5: + version "7.3.5" + resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npm.taobao.org/shebang-command/download/shebang-command-2.0.0.tgz" + integrity sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo= + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-3.0.0.tgz" + integrity sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI= + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/simple-concat/-/simple-concat-1.0.1.tgz" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^3.0.3: + version "3.1.1" + resolved "https://registry.npmmirror.com/simple-get/-/simple-get-3.1.1.tgz" + integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA== + dependencies: + decompress-response "^4.2.0" + once "^1.3.1" + simple-concat "^1.0.0" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz" + integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== + dependencies: + ansi-styles "^6.0.0" + is-fullwidth-code-point "^4.0.0" + +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +socks-proxy-agent@^8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.1.tgz" + integrity sha512-59EjPbbgg8U3x62hhKOFVAmySQUcfRQ4C7Q/D5sEHnZTQRrQlNKINks44DMR1gwXp0p4LaVIeccX2KHTTcHVqQ== + dependencies: + agent-base "^7.0.1" + debug "^4.3.4" + socks "^2.7.1" + +socks@^2.7.1: + version "2.7.1" + resolved "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + dependencies: + ip "^2.0.0" + smart-buffer "^4.2.0" + +source-map-support@^0.4.0: + version "0.4.18" + resolved "https://registry.npm.taobao.org/source-map-support/download/source-map-support-0.4.18.tgz?cache=0&sync_timestamp=1587719289626&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map-support%2Fdownload%2Fsource-map-support-0.4.18.tgz" + integrity sha1-Aoam3ovkJkEzhZTpfM6nXwosWF8= + dependencies: + source-map "^0.5.6" + +source-map@^0.1.34: + version "0.1.43" + resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.1.43.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.1.43.tgz" + integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y= + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.5.7.tgz" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz?cache=0&sync_timestamp=1571657176668&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map%2Fdownload%2Fsource-map-0.6.1.tgz" + integrity sha1-dHIq8y6WFOnCh6jQu95IteLxomM= + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +stream-meter@^1.0.4: + version "1.0.4" + resolved "https://registry.npmmirror.com/stream-meter/-/stream-meter-1.0.4.tgz" + integrity sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ== + dependencies: + readable-stream "^2.1.4" + +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + +string-argv@^0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" + integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.npmmirror.com/string-width/-/string-width-1.0.2.tgz" + integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0: + version "4.2.2" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^5.0.0: + version "5.1.0" + resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.0.tgz" + integrity sha512-7x54QnN21P+XL/v8SuNKvfgsUre6PXpN7mc77N3HlZv+f1SBRGmjxtOud2Z6FZ8DmdkD/IdjCaf9XXbnqmTZGQ== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string.prototype.trimend@^1.0.1: + version "1.0.2" + resolved "https://registry.npm.taobao.org/string.prototype.trimend/download/string.prototype.trimend-1.0.2.tgz?cache=0&sync_timestamp=1603219618123&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.trimend%2Fdownload%2Fstring.prototype.trimend-1.0.2.tgz" + integrity sha1-bd2ah5a8cUtImjriIkaiCPN7+kY= + dependencies: + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + +string.prototype.trimstart@^1.0.1: + version "1.0.2" + resolved "https://registry.npm.taobao.org/string.prototype.trimstart/download/string.prototype.trimstart-1.0.2.tgz?cache=0&sync_timestamp=1603219618047&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstring.prototype.trimstart%2Fdownload%2Fstring.prototype.trimstart-1.0.2.tgz" + integrity sha1-ItRdqBAVMJzQzdeXh+iRn8XGE+c= + dependencies: + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +stringifier@^1.3.0: + version "1.4.0" + resolved "https://registry.npm.taobao.org/stringifier/download/stringifier-1.4.0.tgz" + integrity sha1-1wRYFWf0UmJl0A7Y7LNUoCw/7Cg= + dependencies: + core-js "^2.0.0" + traverse "^0.6.6" + type-name "^2.0.1" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-3.0.1.tgz" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz" + integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + dependencies: + ansi-regex "^6.0.1" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.npm.taobao.org/strip-json-comments/download/strip-json-comments-3.1.1.tgz?cache=0&sync_timestamp=1594567532500&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-json-comments%2Fdownload%2Fstrip-json-comments-3.1.1.tgz" + integrity sha1-MfEoGzgyYwQ0gxwxDAHMzajL4AY= + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + +strtok3@^6.0.4, strtok3@^6.2.4: + version "6.3.0" + resolved "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz" + integrity sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^4.1.0" + +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611709087&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz" + integrity sha1-G33NyzK4E4gBs+R4umpRyqiWSNo= + dependencies: + has-flag "^4.0.0" + +supports-color@^9.2.1: + version "9.2.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-9.2.1.tgz" + integrity sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ== + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tar-fs@^2.0.0, tar-fs@^2.1.1: + version "2.1.1" + resolved "https://registry.npmmirror.com/tar-fs/-/tar-fs-2.1.1.tgz" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.npmmirror.com/tar-stream/-/tar-stream-2.2.0.tgz" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz" + integrity sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ= + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +token-types@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/token-types/-/token-types-2.0.0.tgz" + integrity sha512-WWvu8sGK8/ZmGusekZJJ5NM6rRVTTDO7/bahz4NGiSDb/XsmdYBn6a1N/bymUHuWYTWeuLUg98wUzvE4jPdCZw== + dependencies: + "@tokenizer/token" "^0.1.0" + ieee754 "^1.1.13" + +token-types@^4.1.1: + version "4.2.0" + resolved "https://registry.npmjs.org/token-types/-/token-types-4.2.0.tgz" + integrity sha512-P0rrp4wUpefLncNamWIef62J0v0kQR/GfDVji9WKY7GDCWy5YbVSrKUTam07iWPZQGy0zWNOfstYTykMmPNR7w== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +traverse@^0.6.6: + version "0.6.6" + resolved "https://registry.npm.taobao.org/traverse/download/traverse-0.6.6.tgz" + integrity sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc= + +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.1, tslib@^2.1.0: + version "2.3.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tunnel@^0.0.6: + version "0.0.6" + resolved "https://registry.npm.taobao.org/tunnel/download/tunnel-0.0.6.tgz" + integrity sha1-cvExSzSlsZLbASMk3yzFh8pH+Sw= + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.npm.taobao.org/type-check/download/type-check-0.3.2.tgz" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type-name@^2.0.0, type-name@^2.0.1: + version "2.0.2" + resolved "https://registry.npm.taobao.org/type-name/download/type-name-2.0.2.tgz" + integrity sha1-7+fUEj2KxSr/9/QMfk3sUmYAj7Q= + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.npm.taobao.org/type/download/type-1.2.0.tgz?cache=0&sync_timestamp=1598016585110&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftype%2Fdownload%2Ftype-1.2.0.tgz" + integrity sha1-hI3XaY2vo+VKbEeedZxLw/GIR6A= + +type@^2.0.0: + version "2.1.0" + resolved "https://registry.npm.taobao.org/type/download/type-2.1.0.tgz?cache=0&sync_timestamp=1598016585110&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftype%2Fdownload%2Ftype-2.1.0.tgz" + integrity sha1-m9wixkjPjPht0j0yM2pBz7ZHXj8= + +typescript@4.5.2: + version "4.5.2" + resolved "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz" + integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw== + +universal-deep-strict-equal@^1.2.1: + version "1.2.2" + resolved "https://registry.npm.taobao.org/universal-deep-strict-equal/download/universal-deep-strict-equal-1.2.2.tgz" + integrity sha1-DaSsL3PP95JMgfpN4BjKViyisKc= + dependencies: + array-filter "^1.0.0" + indexof "0.0.1" + object-keys "^1.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.npm.taobao.org/unpipe/download/unpipe-1.0.0.tgz" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.npm.taobao.org/utils-merge/download/utils-merge-1.0.1.tgz" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +v8-compile-cache@^2.0.3: + version "2.3.0" + resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npm.taobao.org/which/download/which-2.0.2.tgz?cache=0&sync_timestamp=1574116720213&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-2.0.2.tgz" + integrity sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE= + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.5" + resolved "https://registry.npmmirror.com/wide-align/-/wide-align-1.1.5.tgz" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + +word-wrap@^1.2.3, word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.npm.taobao.org/word-wrap/download/word-wrap-1.2.3.tgz" + integrity sha1-YQY29rH3A4kb00dxzLF/uTtHB5w= + +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npm.taobao.org/wrappy/download/wrappy-1.0.2.tgz" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +xml2js@^0.6.2: + version "0.6.2" + resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499" + integrity sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.npm.taobao.org/xtend/download/xtend-4.0.2.tgz" + integrity sha1-u3J3n1+kZRhrH0OPZ0+jR/2121Q= + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.2: + version "1.10.2" + resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0, yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^13.2.4: + version "13.3.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + +yargs@^17.1.1: + version "17.1.1" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.1.1.tgz" + integrity sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/WebSourceCode/src/assets/vue.svg b/WebSourceCode/src/assets/vue.svg deleted file mode 100644 index 770e9d3..0000000 --- a/WebSourceCode/src/assets/vue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/WebSourceCode/src/assets/web.svg b/WebSourceCode/src/assets/web.svg new file mode 100644 index 0000000..efd50b6 --- /dev/null +++ b/WebSourceCode/src/assets/web.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WebSourceCode/src/components/Home.vue b/WebSourceCode/src/components/Home.vue index 80ca917..4fddc3a 100644 --- a/WebSourceCode/src/components/Home.vue +++ b/WebSourceCode/src/components/Home.vue @@ -14,8 +14,6 @@ import { SystemStore } from "@/store/SystemStore.js"; import { Api } from "@/utils/Http"; import { platformListv2, MetaInfomationSupport, MetaInfomationSupportOptions, MetaInfomationSupportTypes } from "@/utils/Utils"; import { ElDivider, ElMessage } from 'element-plus'; -import { fa } from "element-plus/es/locale"; -import { ExecException } from "child_process"; const { basicStore } = SystemStore(); @@ -148,7 +146,11 @@ const loadLocalConfigurature = () => { @@ -329,6 +341,11 @@ const loadLocalConfigurature = () => { justify-content: center; border-bottom: solid 1px rgba(white, 0.1); z-index: 1; + + .logo { + height: 40px; + will-change: filter; + } } .safe-area { diff --git a/WebSourceCode/src/components/Index.vue b/WebSourceCode/src/components/Index.vue index c4f6469..d1fcc51 100644 --- a/WebSourceCode/src/components/Index.vue +++ b/WebSourceCode/src/components/Index.vue @@ -10,7 +10,9 @@