diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 49fef9e88d..8ea052dc7f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -10,9 +10,7 @@ body: value: |- ## 请注意 - Caution This form only used for bug report, for any other cases, please [click here](https://github.com/PBH-BTN/PeerBanHelper/issues/new) - 此表单**仅用于反馈错误**,如果是其它类型的反馈,请[点击这里](https://github.com/PBH-BTN/PeerBanHelper/issues/new)。 - If you think the error is related PBH WebUI, please [report to here](https://github.com/PBH-BTN/pbh-fe) - 如果你认为此错误是一个 PBH WebUI,请[在此反馈](https://github.com/PBH-BTN/pbh-fe)。 + 此表单**仅用于反馈错误**,如果是其它类型的反馈,请[点击这里](https://github.com/PBH-BTN/PeerBanHelper/issues/new)。 请尽可能完整且详细地填写所有表单项,以便我们以最高效率并准确的排查故障和诊断问题 - type: 'textarea' attributes: @@ -34,29 +32,40 @@ body: placeholder: '操作系统平台名称……' validations: required: true - - type: 'textarea' + - type: checkboxes + id: deploy-methods attributes: - label: '部署方式 - Deploy method' + label: '部署方式 - Deploy methods' description: |- - Enter the deploy method that you're using: - 输入您部署 PeerBanHelper 方式,官方支持的有如下几种方式: - * Windows 安装程序(通过 .exe 安装) (Windows .EXE Installer) - * Windows 绿色懒人包(解压即用的 .zip 文件) (Windows .ZIP Portable) - * Docker 镜像 (Docker Container) - placeholder: '部署方式……' + Check and tick checkboxes that deploy methods that you're using + 请检查并勾选你正在使用的 PeerBanHelper 部署方式 + options: + - label: "Windows .exe 安装程序 (Windows .exe Installer)" + required: false + - label: "Windows .zip 绿色部署包 (Windows .zip Portable)" + required: false + - label: "Docker" + required: false + - label: "JAR 包直接启动 (Start via .JAR directly)" + required: false validations: required: true - - type: 'textarea' + - type: checkboxes + id: downloaders attributes: - label: '关联的下载器类型 - Downloader Type' + label: '添加的下载器 - Added Downloaders' description: |- - Enter the downloader type that you trying to connecting/connected to PBH (E.g): - 输入您的 PBH 关联的下载器类型,例如: - * qBittorrent - * Transmission - * Deluge - * ... 等 - placeholder: '我添加的下载器有……' + Check and tick checkboxes if you added those downloader(s) into your PeerBanHelper installation + 请勾选被你添加到 PeerBanHelper 中的下载器类型 + options: + - label: "qBittorrent" + required: false + - label: "BiglyBT/Azureus/Vuze" + required: false + - label: "Deluge" + required: false + - label: "Transmission" + required: false validations: required: true - type: 'textarea' @@ -101,16 +110,15 @@ body: label: 检查清单 - Check list description: |- Check and tick checkboxes that listed below + 检查并勾选所有需要勾选的框框 options: - - label: "我确定正在运行 Github Releases 中的最新的正式版本 PeerBanHelper (I'm running the latest version of PBH that can be found in Github Relases)" - required: false - - label: "我确定我所添加的下载器已满足 README 中的前置要求(如版本号和插件)(The downloaders that I've added already satisfied the requirements (E.g install plugins/adapters))" + - label: "PeerBanHelper 已更新到最新版本 (I'm running the latest version of PBH that can be found in Github Relases)" required: false - - label: "我确定我所提到的问题,均未在 README 和 WIKI 中有所解答 (This not a question/or the question that not listed in README's FAQ or WIKI)" + - label: "所添加的下载器已满足 README 中的前置要求(如版本号和插件)(The downloaders that I've added already satisfied the requirements (E.g install plugins/adapters))" required: false - - label: "我确定我没有检查这个检查清单,只是闭眼选中了所有的复选框 (I have not read these checkboxes and therefore I just ticked them all)" + - label: "我已检查过 [PBH 文档](https://pbh-btn.github.io/pbh-docs/)(特别是常见问题),且即使使用了搜索也没有找到与此有关的内容 (This not a question/or the question that not listed in README's FAQ or [PBH WIKI](https://pbh-btn.github.io/pbh-docs/))" required: false - - label: "我确定这不是一个与安全有关的安全漏洞,它可以被安全的公开报告 (This not a security related issue, can be safe report in public)" + - label: "我没有检查这个检查清单,只是闭眼选中了所有的复选框,请关闭这个 Issue (I have not read these checkboxes and therefore I just ticked them all, Please close this issue)" required: false - - label: "我确定我已知悉,如果我没有正确地填写问题报告表单,则 Issue 可能会被关闭 (I know this issue may closed without any warnings if I didn't fill the form correctly)" + - label: "这不是一个安全漏洞,它可以被安全的公开报告。若需要报告安全漏洞,请[在此报告](https://github.com/PBH-BTN/PeerBanHelper/security/advisories/new) (This not a security related issue, can be safe report in public. If you want report a security exploit, please report it [here](https://github.com/PBH-BTN/PeerBanHelper/security/advisories/new))" required: false diff --git a/.github/workflows/jvm-ci-pr.yml b/.github/workflows/jvm-ci-pr.yml index da8126d077..7833480e8d 100644 --- a/.github/workflows/jvm-ci-pr.yml +++ b/.github/workflows/jvm-ci-pr.yml @@ -5,7 +5,7 @@ name: Java CI on: pull_request: - branches: [ "master", "release", "v6", "api-std" ] + branches: [ "master", "release" ] workflow_dispatch: jobs: WebUI: @@ -66,3 +66,5 @@ jobs: linux/arm64/v8 tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }}-jvm-universal + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/jvm-ci.yml b/.github/workflows/jvm-ci.yml index bfc660435d..e9eda14f24 100644 --- a/.github/workflows/jvm-ci.yml +++ b/.github/workflows/jvm-ci.yml @@ -10,7 +10,6 @@ name: Java CI on: push: - branches: [ "master", "release", "v6", "api-std" ] workflow_dispatch: jobs: WebUI: @@ -82,3 +81,5 @@ jobs: linux/arm64/v8 tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }}-jvm-universal + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/jvm-release.yml b/.github/workflows/jvm-release.yml index 3c1a38d6e8..061ebb8f1e 100644 --- a/.github/workflows/jvm-release.yml +++ b/.github/workflows/jvm-release.yml @@ -101,6 +101,10 @@ jobs: linux/arm64/v8 tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }}-jvm-universal + cache-from: type=gha + cache-to: type=gha,mode=max + build-args: | + GIT_HASH=${{ github.sha }} # ---------------- ALIYUN ACR -------------------- - name: Log in to Aliyun ACR uses: docker/login-action@v3 @@ -133,3 +137,5 @@ jobs: linux/arm64/v8 tags: ${{ steps.meta-acr.outputs.tags }} labels: ${{ steps.meta-acr.outputs.labels }}-jvm-universal + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/webui.yml b/.github/workflows/webui.yml index 27d2311b0d..247a2d67a2 100644 --- a/.github/workflows/webui.yml +++ b/.github/workflows/webui.yml @@ -4,22 +4,21 @@ on: push: branches: ["master"] paths: - - 'webui/**' + - "webui/**" pull_request: branches: ["master"] paths: - - 'webui/**' - + - "webui/**" defaults: run: - working-directory: 'webui' + working-directory: "webui" jobs: Build: uses: ./.github/workflows/build_fe.yml Lint: - needs: Build + needs: Build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/Dockerfile b/Dockerfile index 5ddfd14fad..73f668960b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,33 @@ -FROM --platform=$BUILDPLATFORM docker.io/maven:3.9.9-eclipse-temurin-21-alpine AS build +# 构建前端 +FROM --platform=$BUILDPLATFORM docker.io/node:alpine AS frontend-build +COPY ./webui /build/webui +WORKDIR /build/webui +RUN corepack enable pnpm && \ + pnpm i && \ + pnpm run build + +# 下载依赖 +FROM maven:3-eclipse-temurin-21-alpine as backend-build +COPY pom.xml /build/pom.xml +WORKDIR /build +# fetch all dependencies +RUN mvn dependency:go-offline -B -T 1.5C -Daether.dependencyCollector.impl=bf -Dmaven.artifact.threads=32 +# 构建后端 COPY . /build WORKDIR /build -RUN apk add --update npm curl && \ - curl -L https://unpkg.com/@pnpm/self-installer | node && \ - cd webui && \ - pnpm i && \ - npm run build && \ - cd .. && \ - mv webui/dist src/main/resources/static && \ - mvn -B clean package --file pom.xml -T 1.5C +# 把前端打包好的文件拉来 +COPY --from=frontend-build /build/webui/dist src/main/resources/static +RUN apk add --update curl git && \ + mvn -B clean package --file pom.xml -T 1.5C -Daether.dependencyCollector.impl=bf -Dmaven.artifact.threads=32 +# 最终阶段,只要成品 FROM docker.io/azul/zulu-openjdk-alpine:21.0.4-21.36-jre LABEL maintainer="https://github.com/PBH-BTN/PeerBanHelper" USER 0 ENV TZ=UTC WORKDIR /app VOLUME /tmp -COPY --from=build build/target/PeerBanHelper.jar /app/PeerBanHelper.jar +COPY --from=backend-build build/target/PeerBanHelper.jar /app/PeerBanHelper.jar ENV PATH="${JAVA_HOME}/bin:${PATH}" ENTRYPOINT ["java","-Xmx386M","-XX:+UseG1GC", "-XX:+UseStringDeduplication","-XX:+ShrinkHeapInSteps","-jar","PeerBanHelper.jar"] diff --git a/README.md b/README.md index bb2640adac..4a52cc89ed 100644 --- a/README.md +++ b/README.md @@ -18,19 +18,15 @@ ## 安装 PeerBanHelper -请选择您心仪的安装方式: - -| Docker/Docker Compose | Windows | Linux | 群晖DSM(Container Manager) | -| --- | ---- | ---- | ---- | -| [查看](https://github.com/PBH-BTN/PeerBanHelper/wiki/Docker-%E9%83%A8%E7%BD%B2) | [查看](https://github.com/PBH-BTN/PeerBanHelper/wiki/Windows-%E6%89%8B%E5%8A%A8%E9%83%A8%E7%BD%B2) | [查看](https://github.com/PBH-BTN/PeerBanHelper/wiki/Linux-%E6%89%8B%E5%8A%A8%E9%83%A8%E7%BD%B2) | [查看](https://github.com/PBH-BTN/PeerBanHelper/wiki/%E7%BE%A4%E6%99%96%EF%BC%88Synology%EF%BC%89%E9%83%A8%E7%BD%B2) | +查看 [PeerBanHelper 文档](https://pbh-btn.github.io/pbh-docs/docs/category/%E5%AE%89%E8%A3%85%E9%83%A8%E7%BD%B2) ## 支持的客户端 * qBittorrent -* Transmission **(3.00-20 或更高版本)** * BiglyBT(需要安装[插件](https://github.com/PBH-BTN/PBH-Adapter-BiglyBT)) * Deluge(需要安装[插件](https://github.com/PBH-BTN/PBH-Adapter-Deluge)) * Azureus(Vuze)(需要安装[插件](https://github.com/PBH-BTN/PBH-Adapter-Azureus)) +* Transmission **(3.00-20 或更高版本,不建议使用)** ## 注意事项 @@ -40,345 +36,26 @@ PeerBanHelper 主要由以下几个功能模块组成: -* PeerID 黑名单(Transmission 不支持) -* Client Name 黑名单 -* IP 黑名单 -* 虚假进度检查器(提供启发式客户端检测功能)(Transmission不支持过量下载检测) -* 自动 IP 段封禁 -* 多拨追猎 -* Peer ID/Client Name 伪装检查 +* [PeerID 黑名单](https://pbh-btn.github.io/pbh-docs/docs/module/peer-id) +* [Client Name 黑名单](https://pbh-btn.github.io/pbh-docs/docs/module/client-name) +* [IP/GeoIP/IP类型 黑名单](https://pbh-btn.github.io/pbh-docs/docs/module/ip-address-blocker) +* [虚假进度检查器(提供启发式客户端检测功能)](https://pbh-btn.github.io/pbh-docs/docs/module/progress-cheat-blocker) +* [自动连锁封禁](https://pbh-btn.github.io/pbh-docs/docs/module/auto-range-ban) +* [多拨追猎](https://pbh-btn.github.io/pbh-docs/docs/module/multi-dial) +* Peer ID/Client Name 伪装检查;通过 [AviatorScript 引擎](https://pbh-btn.github.io/pbh-docs/docs/module/expression-engine) 实现 +* [主动监测(提供本地数据分析功能)](https://pbh-btn.github.io/pbh-docs/docs/module/active-monitoring) +* [网络 IP 集规则订阅](https://pbh-btn.github.io/pbh-docs/docs/module/ip-address-blocker-rules) * WebUI (目前支持:活跃封禁名单查看,历史封禁查询,封禁最频繁的 Top 50 IP,规则订阅管理,图表查看,Peer 列表查看) -如果配置了 Maxmind IP 库,则还支持以下内容: - -* 在封禁列表中查看 IP 归属地 - -### PeerID 黑名单 - -顾名思义,它根据客户端交换的 Peer ID 来封禁客户端。 -通过在列表中添加不受欢迎的客户端的 Peer ID,即可封禁对应客户端。 - -> [!WARNING] -> Transmission 由于 API 限制,无法使用此功能,请换用 Client Name 黑名单作为替代 - -
- -查看示例配置文件 - -```yaml - # PeerId 封禁 - # 此模块对 Transmission 不起效 - peer-id-blacklist: - enabled: true - # 字符串匹配规则: - # <匹配方式>@<规则内容> 不区分大小写 - # startsWith - 匹配开头 - # endsWith - 匹配结尾 - # contains - 包含子串 - # equals - 完全匹配 - # regex - 正则匹配 - # length - 长度匹配,规则内容填写整数形式的长度 - banned-peer-id: - - '{"method":"CONTAINS","content":"-xl0019","hit":"FALSE"}' # 排除迅雷 0019 - - '{"method":"STARTS_WITH","content":"-xl"}' - - '{"method":"STARTS_WITH","content":"-sd"}' - - '{"method":"STARTS_WITH","content":"-xf"}' - - '{"method":"STARTS_WITH","content":"-qd"}' - - '{"method":"STARTS_WITH","content":"-bn"}' - - '{"method":"STARTS_WITH","content":"-dl"}' - - '{"method":"STARTS_WITH","content":"-ts"}' - - '{"method":"STARTS_WITH","content":"-fg"}' - - '{"method":"STARTS_WITH","content":"-tt"}' - - '{"method":"STARTS_WITH","content":"-nx"}' - - '{"method":"STARTS_WITH","content":"-sp"}' - - '{"method":"STARTS_WITH","content":"-gt0002"}' - - '{"method":"STARTS_WITH","content":"-gt0003"}' - - '{"method":"STARTS_WITH","content":"-dt"}' - - '{"method":"STARTS_WITH","content":"-tt"}' - - '{"method":"STARTS_WITH","content":"-tt"}' - - '{"method":"CONTAINS","content":"cacao"}' - - '{"method":"STARTS_WITH","content":"-hp"}' -``` -
- - -### Client Name 黑名单 - -部分客户端(如 Aria 2)会使用其它 BT 客户端(如:Transmission)的 Peer ID 伪装自己,但客户端名称仍然是自己的真实名称,这种情况可通过 Client Name 黑名单进行封禁。 - -
- -查看示例配置文件 - -```yaml - # 客户端名称封禁 - client-name-blacklist: - enabled: true - banned-client-name: - - '{"method":"STARTS_WITH","content":"-xl00"}' - - '{"method":"CONTAINS","content":"xunlei"}' - - '{"method":"STARTS_WITH","content":"taipei-torrent"}' - - '{"method":"STARTS_WITH","content":"xfplay"}' - - '{"method":"STARTS_WITH","content":"bitspirit"}' - - '{"method":"CONTAINS","content":"flashget"}' - - '{"method":"CONTAINS","content":"tudou"}' - - '{"method":"CONTAINS","content":"torrentstorm"}' - - '{"method":"CONTAINS","content":"qqdownload"}' - - '{"method":"CONTAINS","content":"github.com/anacrolix/torrent"}' - - '{"method":"STARTS_WITH","content":"qbittorrent/3.3.15"}' - - '{"method":"STARTS_WITH","content":"dt/torrent"}' - - '{"method":"STARTS_WITH","content":"dt"}' - - '{"method":"STARTS_WITH","content":"go.torrent.dev"}' - - '{"method":"STARTS_WITH","content":"github.com/thank423/trafficconsume"}' - - '{"method":"STARTS_WITH","content":"taipei-torrent"}' - - '{"method":"STARTS_WITH","content":"hp/torrent"}' - - '{"method":"STARTS_WITH","content":"hp"}' -``` - -
- -### IP 黑名单 - -有的客户端(如迅雷离线下载服务器)会使用匿名模式连接,使用通用客户端名称(libtorrent)和通用 Peer ID(-LTXXXX-)来连接您,但封禁通用名称/Peer ID 会误伤不少正常客户端。 -对于这种情况,您可以直接封禁这些离线下载服务器的 IP 地址或 IP 段,或者使用的端口。 - -与 qBittorrent 等客户端内置的 IP 黑名单不同,PeerBanHelper 的 IP 黑名单允许您使用 CIDR 来表示一组 IP 地址,同时支持 IPV4 和 IPV6 的 CIDR 表示法,有效提升了 IP 封禁效率。 - -
- -查看示例配置文件 - -```yaml - # IP 地址/端口 封禁 - ip-address-blocker: - enabled: true - # IP,支持 CIDR,其语法大致如下: - # ::/64 - # a:b:c:d::a:b/64 - # a:b:c:d:e:f:1.2.3.4/112 - # 1.2.3.4/16 - # 1.2.255.4/255.255.0.0 - ips: - #- 8.8.8.8 - #- 9.9.9.9 - # 端口 - ports: - #- 2003 -``` - -
- - -### 虚假进度检查器 - -此模块可谓是 PeerBanHelper 的灵魂,有助于您在不更新规则的情况下,发现那些伪装过的异常客户端。 -其大体原理如下: - -* 大部分吸血客户端都不会正常上报下载进度(如:进度一直是0%,或者每次连接进度都不同) -* 虚假进度检查器通过我们上传给此对等体的数据量,计算此对等体的最低真实进度 -* 如果对等体汇报的进度比最低真实进度差别过大,或者给此对等体的总上传量超过了种子本身的体积很多 -* 判定为异常客户端 - -> [!WARNING] -> Transmission 由于 API 限制,超量下载检测不起作用,暂时没有解决方案 - -
- -查看示例配置文件 - -```yaml - # 假进度检查 - progress-cheat-blocker: - enabled: true - # Torrent 小于此值不进行检查(单位:字节),对等体可能来不及同步正确的下载进度 - minimum-size: 50000000 - # 最大差值,单位百分比(1.0 = 100% 0.5=50%) - # PeerBanHelper 根据 BT 客户端记录的向此对等体实际上传的字节数,计算该对等体的最小下载进度 - # 并与对等体汇报给 BT 客户端下载进度进行比较 - # 如果对等体汇报的总体下载进度远远低于我们上传给此对等体的数据量的比例,我们应考虑客户端正在汇报假进度 - # 默认值为:10% - # 即:假设我们上传了 50% 的数据量给对方,对方汇报自己的下载进度只有 39%,差值大于 10%,进行封禁 - # 对于自动识别迅雷、QQ旋风的变种非常有效,能够在不更新规则的情况下自动封禁报假进度的吸血客户端 - maximum-difference: 0.1 - # 进度倒退检测 - # 默认:最多允许倒退 7% 的进度 - # (考虑到有时文件片段在传输时可能因损坏而未通过校验被丢弃,我们允许客户端出现合理的进度倒退) - # 设置为 -1 以禁用此检测 - rewind-maximum-difference: 0.07 - # 禁止那些在同一个种子的累计下载量超过种子本身大小的客户端 - # 过量下载检测不支持 Transmission - block-excessive-clients: true - # 过量下载计算阈值 - # 计算方式是: 是否过量下载 = 上传总大小 > (种子总大小 * excessive-threshold) - excessive-threshold: 1.5 -``` - -
- -### 自动 IP 段封禁 - -批量部署的恶意客户端通常在同一个 IP 段下,PBH 现在允许用户分别为 IPv4 和 IPv6 设置一个前缀长度。在封禁发现的吸血客户端时,会将其所处 IP 地址的指定范围的其余 IP 地址均加入屏蔽列表,实现链式封禁。 - -
- -查看示例配置文件 +此外,PeerBanHelper 会在启动时下载 GeoIP 库,成功加载后支持以下功能: -```yaml - # 范围 IP 段封禁 - # 在封禁 Peer 后,被封禁的 Peer 所在 IP 地址的指定前缀长度内的其它 IP 地址都将一同封禁 - auto-range-ban: - # 是否启用 - enabled: true - # IPV4 前缀长度 - ipv4: 30 # /32 = 单个 IP,/24 = 整个 ?.?.?.x 段 - # IPV6 前缀长度 - ipv6: 64 # /64 = ISP 通常分配给家宽用户的前缀长度 -``` - -
- -### 多拨侦测 - -专业PCDN用户会在一台PCDN服务器上接入多条宽带,以此提升上传带宽,称为多拨。 -这类用户的刷下载工具一般也较为复杂,会利用多条宽带不同的出口IP分散流量,对抗基于下载进度的吸血检测。 -此模块对多拨下载现象进行侦测,发现同一网段集中下载同一种子,即予以全部封禁。 -目前已知可能误伤的情况:小ISP的骨干网出口在同一网段,造成多拨假象。如果种子涉及的BT网络主体在大陆以外,请谨慎使用。 - -
- -查看示例配置文件 - -```yaml - multi-dialing-blocker: - enabled: false - # 子网掩码长度 - # IP地址前多少位相同的视为同一个子网,位数越少范围越大,一般不需要修改 - subnet-mask-length: 24 - # 对于同小区IPv6地址应该取多少位掩码没有调查过,64位是不会误杀的保险值 - subnet-mask-v6-length: 64 - # 容许同一网段下载同一种子的IP数量,正整数 - # 防止DHCP重新分配IP、碰巧有同一小区的用户下载同一种子等导致的误判 - tolerate-num: 3 - # 缓存持续时间(秒) - # 所有连接过的peer会记入缓存,DHCP服务会定期重新分配IP,缓存时间过长会导致误杀 - cache-lifespan: 86400 - # 是否追猎 - # 如果某IP已判定为多拨,无视缓存时间限制继续搜寻其同伙 - keep-hunting: true - # 追猎持续时间(秒) - # 和cache-lifspan作用相似,对被猎杀IP的缓存持续时间,keep-hunting为true时有效 - keep-hunting-time: 2592000 -``` - -
- -## AviatorScript 脚本引擎 - -AviatorScript 脚本引擎提供了完整编程能力,您可以编写自己的脚本控制是否封禁,参见 [AviatorScript 脚本引擎 WIKI](https://github.com/PBH-BTN/PeerBanHelper/wiki/AviatorScript-%E8%84%9A%E6%9C%AC%E5%BC%95%E6%93%8E) - -## 添加下载器 - -PeerBanHelper 能够连接多个支持的下载器,并共享 IP 黑名单。但每个下载器只能被一个 PeerBanHelper 添加,多个 PBH 会导致操作 IP 黑名单时出现冲突。 - -
- -查看示例配置文件 - -```yaml -# 客户端设置 -client: - # 名字,可以自己起,会在日志中显示,只能由字母数字横线组成,数字不能打头 - qbittorrent-001: - # 客户端类型 - # 支持的客户端列表: - # qBittorrent - # Transmission - # 其它也许以后会加 - type: qBittorrent - # 客户端地址 - endpoint: "http://ip:8085" - # 登录信息(暂不支持 Basic Auth) - # 用户名 - username: "username" - # 密码 - password: "password" - # Basic Auth - 不知道这是什么的话,请保持默认 - basic-auth: - user: "" - pass: "" - transmission-002: - type: Transmission - endpoint: "http://127.0.0.1:9091" - username: "admin" - password: "admin" -``` - -
+* 在封禁列表中查看 IP 归属地,AS 信息(ASN、ISP、AS名称等),网络类型信息(宽带、基站、物联网、数据中心等) +* 基于 GeoIP 信息按国家/地区、城市、网络类型、ASN 等封禁 IP 地址 +* 查看 GeoIP 统计数据 ## 常见问题 -### 打开 WebUI 时白屏/黑屏 - -清除浏览器缓存。 - -### 无法下载 GeoIP 库 / 代理无效 - -打开 `data/config.yml` 文件,配置代理服务器: - -```yaml -proxy: - # 代理服务器设置 Proxy server setting - # 注意:不支持需要密码验证的代理服务器 NOTE: Authentication required proxy servers are not supported - # 0 = 不使用代理 - No proxy - # 1 = 使用系统代理 - Use system proxy - # 2 = 使用 HTTP(s) 代理 - Use HTTP(s) proxy - # 3 = 使用 socks5 代理(可能无法使用) - Use socks5 proxy (may not work well) - setting: 0 -``` - -### PeerBanHelper 运行在 Docker 里时,下载器 IP 地址怎么填,127.0.0.1 不管用 - -如果您的 Docker 容器和下载器运行在同一台服务器上,且使用 桥接 网络模式(默认就是桥接),那么您不能使用 127.0.0.1。 - -前往 Container Manager,找到网络选项卡,查看 `bridge` 中的网关地址,使用网关地址作为下载器 IP。 - -![image](https://github.com/Ghost-chu/PeerBanHelper/assets/30802565/20d49093-bf99-41f6-971f-c0c574d493af) - -### 管理 Token 在哪里? - -您可以从 GUI 界面的 WebUI->复制Token 获得 Token。通过 GUI 唤起浏览器打开的 WebUI 将自动填写 Token。如果是首次使用,也会在日志中显示您的 Token。 -除此之外,您还可以从 config.yml 中找到 Token ↓ - -```yaml -# Http 服务器设置 -server: - http: 9898 - ...<省略>... - token: "*************************" # <-- 你的管理 Token -``` - -### Transmission 的有限支持 - -由于 Transmission 有以下局限性,因此部分功能不可用 - -* API 无法获取 PeerID,因此 PeerID 黑名单模块不起作用 -* API 无法获取客户端累计上传下载量,因此 ProgressCheatBlocker 的过量下载检测不起作用 -* API 设置黑名单只能让 Transmission 请求 URL 更新,因此 PBH 需要打开一个 API 端点,且您需要保证 Transmission 能够访问到它(可在 config.yml 中配置细节) -* API 设置黑名单时不会实时生效,必须使用某种手段使种子上已连接的对等体断开。PBH 会短暂的暂停您的 Torrent 然后恢复它。 - -### 为什么有些应该封禁的 Peers 没有封禁 - -部分规则模块只会在对方和你有速度的时候才会封禁。如果速度为 0,PBH 可能会跳过一些检查以避免误判。 -~~如果是 XunLei 0.0.1.9,新版迅雷下载过程中现在会正常上传,所以在配置文件中默认排除了。~~ 自 5.0.1 开始,PBH 将重新封禁所有 XL0019 客户端:[[社区通报] 重新封禁 -XL0019- (Xunlei 0.0.1.9) 客户端](https://github.com/PBH-BTN/PeerBanHelper/issues/254) - -### 反吸血进度检查器为什么显示进度超过 100% (例如:102%),是不是出错了?怎么还能超过 100% 的? - -不是的,进度检查器会累加此 IP 地址在特定种子上的下载进度。如果对方出现进度回退、断开更换端口重连、更换 PeerID、更换 Client name 重新下载时,下载器会认为这是一个新客户端,并从头开始计算下载数据(吸血者也使用此手段绕过吸血检查)。但对于 PBH 来说,只要对方 IP 地址未改变(或者处于特定区间内),并且下载的种子未更换的情况下,下载进度会持续增量累积,避免对方欺骗反吸血检查。例如一个文件大小是 1000MB,对方下载 102% 代表对方在这个 1000MB 大小的种子上,实际下载了 1020MB 的数据。 - -### PBH 提示我的下载器 “连续多次登录失败” ,并暂停了该怎么办? - -您可以点击下载器的编辑按钮,然后直接点击确定保存。PBH 将会解除暂停状态并重新尝试登陆,此时会显示登陆失败的原因。请根据原因进行故障排查(例如:网络连接问题、WebUI -是否启用、用户名密码是否正确等) +在报告问题前,请先检查 [常见问题列表](https://pbh-btn.github.io/pbh-docs/docs/faq) ## Install4j diff --git a/pom.xml b/pom.xml index bc692a39a6..be79a0bb13 100644 --- a/pom.xml +++ b/pom.xml @@ -142,7 +142,7 @@ io.takari.maven.plugins takari-lifecycle-plugin - 2.1.6 + 2.1.7 true proc @@ -552,6 +552,16 @@ com.maxmind.geoip2 geoip2 4.2.0 + + + jackson-databind + com.fasterxml.jackson.core + + + jackson-core + com.fasterxml.jackson.core + + io.javalin diff --git a/src/main/java/com/ghostchu/peerbanhelper/Main.java b/src/main/java/com/ghostchu/peerbanhelper/Main.java index 3b8e4a5869..aeb85836b2 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/Main.java +++ b/src/main/java/com/ghostchu/peerbanhelper/Main.java @@ -17,7 +17,15 @@ import com.google.common.io.ByteStreams; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender; +import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy; +import org.apache.logging.log4j.core.appender.rolling.TimeBasedTriggeringPolicy; +import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.core.config.LoggerConfig; import org.apache.logging.log4j.core.config.plugins.util.PluginManager; +import org.apache.logging.log4j.core.config.xml.XmlConfiguration; import org.bspfsystems.yamlconfiguration.configuration.InvalidConfigurationException; import org.bspfsystems.yamlconfiguration.file.YamlConfiguration; import org.jetbrains.annotations.Nullable; @@ -166,6 +174,7 @@ private static void setupConfDirectory(String[] args) { if (System.getProperty("pbh.datadir") != null) { root = System.getProperty("pbh.datadir"); } + dataDirectory = new File(root); logsDirectory = new File(dataDirectory, "logs"); configDirectory = new File(dataDirectory, "config"); @@ -331,7 +340,7 @@ public static String decapitalize(String name) { return name; } if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) && - Character.isUpperCase(name.charAt(0))) { + Character.isUpperCase(name.charAt(0))) { return name; } char chars[] = name.toCharArray(); diff --git a/src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java b/src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java index 44f81d8ab6..e763333862 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java +++ b/src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java @@ -9,6 +9,7 @@ import com.ghostchu.peerbanhelper.downloader.impl.biglybt.BiglyBT; import com.ghostchu.peerbanhelper.downloader.impl.deluge.Deluge; import com.ghostchu.peerbanhelper.downloader.impl.qbittorrent.QBittorrent; +import com.ghostchu.peerbanhelper.downloader.impl.qbittorrent.QBittorrentEE; import com.ghostchu.peerbanhelper.downloader.impl.transmission.Transmission; import com.ghostchu.peerbanhelper.event.LivePeersUpdatedEvent; import com.ghostchu.peerbanhelper.event.PBHServerStartedEvent; @@ -200,6 +201,7 @@ public Downloader createDownloader(String client, ConfigurationSection downloade Downloader downloader = null; switch (downloaderSection.getString("type").toLowerCase(Locale.ROOT)) { case "qbittorrent" -> downloader = QBittorrent.loadFromConfig(client, downloaderSection); + case "qbittorrentee" -> downloader = QBittorrentEE.loadFromConfig(client, downloaderSection); case "transmission" -> downloader = Transmission.loadFromConfig(client, pbhServerAddress, downloaderSection); case "biglybt" -> downloader = BiglyBT.loadFromConfig(client, downloaderSection); @@ -217,6 +219,7 @@ public Downloader createDownloader(String client, JsonObject downloaderSection) Downloader downloader = null; switch (downloaderSection.get("type").getAsString().toLowerCase(Locale.ROOT)) { case "qbittorrent" -> downloader = QBittorrent.loadFromConfig(client, downloaderSection); + case "qbittorrentee" -> downloader = QBittorrentEE.loadFromConfig(client, downloaderSection); case "transmission" -> downloader = Transmission.loadFromConfig(client, pbhServerAddress, downloaderSection); case "biglybt" -> downloader = BiglyBT.loadFromConfig(client, downloaderSection); diff --git a/src/main/java/com/ghostchu/peerbanhelper/config/ProfileUpdateScript.java b/src/main/java/com/ghostchu/peerbanhelper/config/ProfileUpdateScript.java index a3c725484a..1416d278a8 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/config/ProfileUpdateScript.java +++ b/src/main/java/com/ghostchu/peerbanhelper/config/ProfileUpdateScript.java @@ -25,6 +25,11 @@ public ProfileUpdateScript(YamlConfiguration conf) { this.conf = conf; } + @UpdateScript(version = 18) + public void banDelayWait() { + conf.set("module.progress-cheat-blocker.max-wait-duration", 30000); + } + @UpdateScript(version = 17) public void updateProfiles() { List bannedPeerIds = conf.getStringList("module.peer-id-blacklist.banned-peer-id"); diff --git a/src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java b/src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java index d74073530d..16404b4b4d 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java +++ b/src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java @@ -44,7 +44,7 @@ private void createTables() throws SQLException { private void performUpgrade() throws SQLException { Dao metadata = DaoManager.createDao(getDataSource(), MetadataEntity.class); - MetadataEntity version = metadata.createIfNotExists(new MetadataEntity("version", "4")); + MetadataEntity version = metadata.createIfNotExists(new MetadataEntity("version", "5")); int v = Integer.parseInt(version.getValue()); if (v < 3) { try { @@ -61,6 +61,11 @@ private void performUpgrade() throws SQLException { TableUtils.createTableIfNotExists(database.getDataSource(), ProgressCheatBlockerPersistEntity.class); v = 4; } + if (v == 4) { + TableUtils.dropTable(getDataSource(), ProgressCheatBlockerPersistEntity.class, true); + TableUtils.createTableIfNotExists(database.getDataSource(), ProgressCheatBlockerPersistEntity.class); + v = 5; + } version.setValue(String.valueOf(v)); metadata.update(version); } diff --git a/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/ProgressCheatBlockerPersistDao.java b/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/ProgressCheatBlockerPersistDao.java index c3b28d05d2..351d4882d6 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/ProgressCheatBlockerPersistDao.java +++ b/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/ProgressCheatBlockerPersistDao.java @@ -12,6 +12,7 @@ import java.sql.SQLException; import java.sql.Timestamp; +import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Collectors; @@ -25,6 +26,7 @@ public ProgressCheatBlockerPersistDao(@Autowired Database database) throws SQLEx public List fetchFromDatabase(ProgressCheatBlocker.Client client, Timestamp after) throws SQLException { IPAddress address = IPAddressUtil.getIPAddress(client.getPeerPrefix()); + if(address == null) return Collections.emptyList(); List entities = queryBuilder() .where() .eq("torrentId", client.getTorrentId()) @@ -43,7 +45,8 @@ public List fetchFromDatabase(ProgressCheatBloc entity.getProgressDifferenceCounter(), entity.getFirstTimeSeen().getTime(), entity.getLastTimeSeen().getTime(), - entity.getDownloader() + entity.getDownloader(), + entity.getBanDelayWindowEndAt().getTime() ) ).collect(Collectors.toCollection(CopyOnWriteArrayList::new)); // 可变 List,需要并发安全 } @@ -66,7 +69,8 @@ public void flushDatabase(List records) t task.getProgressDifferenceCounter(), new Timestamp(System.currentTimeMillis()), new Timestamp(System.currentTimeMillis()), - task.getDownloader() + task.getDownloader(), + new Timestamp(task.getBanDelayWindowEndAt()) ); create(entity); } else { diff --git a/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TorrentDao.java b/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TorrentDao.java index 2abd4a65a9..6c08254928 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TorrentDao.java +++ b/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TorrentDao.java @@ -29,13 +29,11 @@ public Optional queryByInfoHash(String infoHash) throws SQLExcept @Override public synchronized TorrentEntity createIfNotExists(TorrentEntity data) throws SQLException { - List list = queryForEq("infoHash", data.getInfoHash()); - if (list.isEmpty()) { - long id = create(data); - data.setId(id); + var entity = queryBuilder().where().eq("infoHash", data.getInfoHash()).queryForFirst(); + if (entity == null) { + create(data); return data; } - TorrentEntity entity = list.getFirst(); boolean anyUpdated = false; if (!entity.getName().equals(data.getName())) { entity.setName(data.getName()); diff --git a/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TrafficJournalDao.java b/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TrafficJournalDao.java index 99fdf5bb6f..4f52b7b055 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TrafficJournalDao.java +++ b/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TrafficJournalDao.java @@ -4,10 +4,15 @@ import com.ghostchu.peerbanhelper.database.dao.AbstractPBHDao; import com.ghostchu.peerbanhelper.database.table.TrafficJournalEntity; import com.ghostchu.peerbanhelper.util.MiscUtil; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.List; @Component public class TrafficJournalDao extends AbstractPBHDao { @@ -15,8 +20,62 @@ public TrafficJournalDao(@Autowired Database database) throws SQLException { super(database.getDataSource(), TrafficJournalEntity.class); } - public TrafficJournalEntity getTodayJournal() throws SQLException { - return createIfNotExists(new TrafficJournalEntity(MiscUtil.getStartOfToday(System.currentTimeMillis()), 0, 0)); + public TrafficJournalEntity getTodayJournal(String downloader) throws SQLException { + return createIfNotExists(new TrafficJournalEntity(null, MiscUtil.getStartOfToday(System.currentTimeMillis()), downloader, 0, 0, 0, 0)); + } + + public List getAllDownloadersOverallData(Timestamp start, Timestamp end) throws Exception { + try (var results = queryBuilder().selectRaw("timestamp", "SUM(dataOverallUploaded) AS totalUploaded", "SUM(dataOverallDownloaded) AS totalDownloaded") + .where() + .ge("timestamp", start.getTime()) + .and() + .le("timestamp", end.getTime()) + .queryBuilder() + .groupBy("timestamp") + .queryRaw()) { + return results.getResults().stream().map(args -> new TrafficData(new Timestamp(Long.parseLong(args[0])), Long.parseLong(args[1]), Long.parseLong(args[2]))).toList(); + } + } + + public List getSpecificDownloaderOverallData(String downloadName, Timestamp start, Timestamp end) throws Exception { + try (var results = queryBuilder().selectRaw("timestamp", "SUM(dataOverallUploaded) AS totalUploaded", "SUM(dataOverallDownloaded) AS totalDownloaded") + .where() + .ge("timestamp", start.getTime()) + .and() + .le("timestamp", end.getTime()) + .and() + .eq("downloader", downloadName) + .queryBuilder() + .groupBy("timestamp") + .queryRaw()) { + return results.getResults().stream().map(args -> new TrafficData(new Timestamp(Long.parseLong(args[0])), Long.parseLong(args[1]), Long.parseLong(args[2]))).toList(); + } + } + + @Override + public synchronized TrafficJournalEntity createIfNotExists(TrafficJournalEntity data) throws SQLException { + if (data == null) { + return null; + } + TrafficJournalEntity existing = queryBuilder().where() + .eq("timestamp", data.getTimestamp()) + .and() + .eq("downloader", data.getDownloader()).queryBuilder().queryForFirst(); + if (existing == null) { + create(data); + return data; + } else { + return existing; + } + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class TrafficData { + private Timestamp timestamp; + private long dataOverallUploaded; + private long dataOverallDownloaded; } } diff --git a/src/main/java/com/ghostchu/peerbanhelper/database/table/ProgressCheatBlockerPersistEntity.java b/src/main/java/com/ghostchu/peerbanhelper/database/table/ProgressCheatBlockerPersistEntity.java index d51790949c..0a1aa385b1 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/database/table/ProgressCheatBlockerPersistEntity.java +++ b/src/main/java/com/ghostchu/peerbanhelper/database/table/ProgressCheatBlockerPersistEntity.java @@ -35,4 +35,6 @@ public final class ProgressCheatBlockerPersistEntity { private Timestamp lastTimeSeen; @DatabaseField(canBeNull = false) private String downloader; + @DatabaseField(canBeNull = false) + private Timestamp banDelayWindowEndAt; } diff --git a/src/main/java/com/ghostchu/peerbanhelper/database/table/TrafficJournalEntity.java b/src/main/java/com/ghostchu/peerbanhelper/database/table/TrafficJournalEntity.java index 166e7eae80..a35763ecdb 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/database/table/TrafficJournalEntity.java +++ b/src/main/java/com/ghostchu/peerbanhelper/database/table/TrafficJournalEntity.java @@ -9,12 +9,20 @@ @AllArgsConstructor @NoArgsConstructor @Data -@DatabaseTable(tableName = "traffic_journal") +@DatabaseTable(tableName = "traffic_journal_v2") public final class TrafficJournalEntity { - @DatabaseField(id = true, unique = true, index = true) + @DatabaseField(generatedId = true, index = true) + private Long id; + @DatabaseField(index = true, uniqueCombo = true) private Long timestamp; + @DatabaseField(index = true, uniqueCombo = true) + private String downloader; @DatabaseField - private long uploaded; + private long dataOverallUploaded; @DatabaseField - private long downloaded; + private long dataOverallDownloaded; + @DatabaseField + private long protocolOverallUploaded; + @DatabaseField + private long protocolOverallDownloaded; } diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/AbstractDownloader.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/AbstractDownloader.java index e84b8f7540..f195315afd 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/downloader/AbstractDownloader.java +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/AbstractDownloader.java @@ -2,8 +2,11 @@ import com.ghostchu.peerbanhelper.text.Lang; import com.ghostchu.peerbanhelper.text.TranslationComponent; +import com.ghostchu.peerbanhelper.torrent.Torrent; import com.ghostchu.peerbanhelper.util.MsgUtil; +import com.ghostchu.peerbanhelper.wrapper.TorrentWrapper; +import java.util.Collection; import java.util.Date; public abstract class AbstractDownloader implements Downloader { @@ -31,7 +34,9 @@ public DownloaderLoginResult login() { failedLoginAttempts = 0; return result; } - failedLoginAttempts++; + if (result.getStatus() == DownloaderLoginResult.Status.INCORRECT_CREDENTIAL + || result.getStatus() == DownloaderLoginResult.Status.MISSING_COMPONENTS) + failedLoginAttempts++; return result; } catch (Throwable e) { failedLoginAttempts++; @@ -44,6 +49,16 @@ public DownloaderLoginResult login() { } } + @Override + public void relaunchTorrentIfNeeded(Collection torrents) { + + } + + @Override + public void relaunchTorrentIfNeededByTorrentWrapper(Collection torrents) { + + } + public abstract DownloaderLoginResult login0(); @Override @@ -66,4 +81,9 @@ public TranslationComponent getLastStatusMessage() { public String getName() { return name; } + + @Override + public DownloaderStatistics getStatistics() { + return new DownloaderStatistics(0, 0); + } } diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/Downloader.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/Downloader.java index 76ca023e65..186ccdf11e 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/downloader/Downloader.java +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/Downloader.java @@ -120,4 +120,11 @@ default void runScheduleTasks() { * @return 状态描述说明 */ TranslationComponent getLastStatusMessage(); + + /** + * 获取下载器的统计数据 + * + * @return 统计数据 + */ + DownloaderStatistics getStatistics(); } diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/DownloaderStatistics.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/DownloaderStatistics.java new file mode 100644 index 0000000000..dee34eb316 --- /dev/null +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/DownloaderStatistics.java @@ -0,0 +1,4 @@ +package com.ghostchu.peerbanhelper.downloader; + +public record DownloaderStatistics(long totalUploaded, long totalDownloaded) { +} diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/BiglyBT.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/BiglyBT.java index e2cd38270c..ca3bb81a41 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/BiglyBT.java +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/BiglyBT.java @@ -2,11 +2,13 @@ import com.ghostchu.peerbanhelper.downloader.AbstractDownloader; import com.ghostchu.peerbanhelper.downloader.DownloaderLoginResult; +import com.ghostchu.peerbanhelper.downloader.DownloaderStatistics; import com.ghostchu.peerbanhelper.downloader.impl.biglybt.network.bean.clientbound.BanBean; import com.ghostchu.peerbanhelper.downloader.impl.biglybt.network.bean.clientbound.BanListReplacementBean; import com.ghostchu.peerbanhelper.downloader.impl.biglybt.network.wrapper.DownloadRecord; import com.ghostchu.peerbanhelper.downloader.impl.biglybt.network.wrapper.PeerManagerRecord; import com.ghostchu.peerbanhelper.downloader.impl.biglybt.network.wrapper.PeerRecord; +import com.ghostchu.peerbanhelper.downloader.impl.biglybt.network.wrapper.StatisticsRecord; import com.ghostchu.peerbanhelper.peer.Peer; import com.ghostchu.peerbanhelper.peer.PeerImpl; import com.ghostchu.peerbanhelper.text.Lang; @@ -18,7 +20,6 @@ import com.ghostchu.peerbanhelper.util.json.JsonUtil; import com.ghostchu.peerbanhelper.wrapper.BanMetadata; import com.ghostchu.peerbanhelper.wrapper.PeerAddress; -import com.ghostchu.peerbanhelper.wrapper.TorrentWrapper; import com.github.mizosoft.methanol.Methanol; import com.github.mizosoft.methanol.MutableRequest; import com.google.gson.JsonObject; @@ -151,6 +152,9 @@ public List getTorrents() { }.getType()); List torrents = new ArrayList<>(); for (DownloadRecord detail : torrentDetail) { + if (config.isIgnorePrivate() && detail.getTorrent().isPrivateTorrent()) { + continue; + } torrents.add(new TorrentImpl( detail.getTorrent().getInfoHash(), detail.getName(), @@ -158,19 +162,27 @@ public List getTorrents() { detail.getTorrent().getSize(), detail.getStats().getCompletedInThousandNotation() / 1000d, detail.getStats().getRtUploadSpeed(), - detail.getStats().getRtDownloadSpeed())); + detail.getStats().getRtDownloadSpeed(), + detail.getTorrent().isPrivateTorrent())); } return torrents; } - @Override - public void relaunchTorrentIfNeeded(Collection torrents) { - - } @Override - public void relaunchTorrentIfNeededByTorrentWrapper(Collection torrents) { - + public DownloaderStatistics getStatistics() { + HttpResponse resp; + try { + resp = httpClient.send(MutableRequest.GET(apiEndpoint + "/statistics"), + HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); + } catch (Exception e) { + throw new IllegalStateException(e); + } + if (resp.statusCode() != 200) { + throw new IllegalStateException(tlUI(Lang.DOWNLOADER_FAILED_REQUEST_STATISTICS, resp.statusCode(), resp.body())); + } + StatisticsRecord statisticsRecord = JsonUtil.getGson().fromJson(resp.body(), StatisticsRecord.class); + return new DownloaderStatistics(statisticsRecord.getOverallDataBytesSent(), statisticsRecord.getOverallDataBytesReceived()); } @Override @@ -257,6 +269,7 @@ public static class Config { private String httpVersion; private boolean incrementBan; private boolean verifySsl; + private boolean ignorePrivate; public static Config readFromYaml(ConfigurationSection section) { Config config = new Config(); @@ -269,6 +282,7 @@ public static Config readFromYaml(ConfigurationSection section) { config.setIncrementBan(section.getBoolean("increment-ban", true)); config.setHttpVersion(section.getString("http-version", "HTTP_1_1")); config.setVerifySsl(section.getBoolean("verify-ssl", true)); + config.setIgnorePrivate(section.getBoolean("ignore-private", false)); return config; } @@ -279,6 +293,7 @@ public YamlConfiguration saveToYaml() { section.set("token", token); section.set("http-version", httpVersion); section.set("increment-ban", incrementBan); + section.set("ignore-private", ignorePrivate); section.set("verify-ssl", verifySsl); return section; } diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/network/wrapper/StatisticsRecord.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/network/wrapper/StatisticsRecord.java new file mode 100644 index 0000000000..1ea98c0679 --- /dev/null +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/network/wrapper/StatisticsRecord.java @@ -0,0 +1,26 @@ +package com.ghostchu.peerbanhelper.downloader.impl.biglybt.network.wrapper; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@Data +@NoArgsConstructor +public class StatisticsRecord { + private Long overallDataBytesReceived; + private Long overallDataBytesSent; + private Long sessionUptimeSeconds; + private Integer dataReceiveRate; + private Integer protocolReceiveRate; + private Integer dataAndProtocolReceiveRate; + private Integer dataSendRate; + private Integer protocolSendRate; + private Integer dataAndProtocolSendRate; + private Long dataBytesReceived; + private Long protocolBytesReceived; + private Long dataBytesSent; + private Long protocolBytesSent; + private Long smoothedReceiveRate; + private Long smoothedSendRate; +} diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/deluge/Deluge.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/deluge/Deluge.java index bf18d1e04e..784bc8f419 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/deluge/Deluge.java +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/deluge/Deluge.java @@ -2,6 +2,7 @@ import com.ghostchu.peerbanhelper.downloader.AbstractDownloader; import com.ghostchu.peerbanhelper.downloader.DownloaderLoginResult; +import com.ghostchu.peerbanhelper.downloader.DownloaderStatistics; import com.ghostchu.peerbanhelper.peer.Peer; import com.ghostchu.peerbanhelper.peer.PeerFlag; import com.ghostchu.peerbanhelper.text.Lang; @@ -25,6 +26,7 @@ import raccoonfink.deluge.DelugeServer; import raccoonfink.deluge.responses.DelugeListMethodsResponse; import raccoonfink.deluge.responses.PBHActiveTorrentsResponse; +import raccoonfink.deluge.responses.PBHStatisticsResponse; import java.net.http.HttpClient; import java.util.ArrayList; @@ -130,7 +132,8 @@ public List getTorrents() { activeTorrent.getSize(), activeTorrent.getUploadPayloadRate(), activeTorrent.getDownloadPayloadRate(), - peers + peers, + activeTorrent.getPriv() != null && activeTorrent.getPriv() ); torrents.add(torrent); } @@ -175,13 +178,15 @@ private void setBanListIncrement(Collection added) { } @Override - public void relaunchTorrentIfNeeded(Collection torrents) { - - } - - @Override - public void relaunchTorrentIfNeededByTorrentWrapper(Collection torrents) { - + public DownloaderStatistics getStatistics() { + try { + PBHStatisticsResponse resp = this.client.queryStatistics(); + var dto = resp.getStatistics(); + return new DownloaderStatistics(dto.getTotalPayloadUpload(), dto.getTotalPayloadDownload()); + } catch (DelugeException e) { + log.error(tlUI(Lang.DOWNLOADER_DELUGE_API_ERROR), e); + } + return new DownloaderStatistics(0,0); } @Override @@ -224,92 +229,6 @@ private PeerFlag parsePeerFlag(int peerFlag, int sourceFlag) { rc4Encrypted, plainTextEncrypted, tracker, dht, pex, lsd, resumeData, incoming); } -// private String parseFlag(int peerFlag, int sourceFlag) { -// boolean interesting = (peerFlag & (1 << 0)) != 0; -// boolean choked = (peerFlag & (1 << 1)) != 0; -// boolean remoteInterested = (peerFlag & (1 << 2)) != 0; -// boolean remoteChoked = (peerFlag & (1 << 3)) != 0; -// boolean supportsExtensions = (peerFlag & (1 << 4)) != 0; -// boolean outgoingConnection = (peerFlag & (1 << 5)) != 0; -// boolean localConnection = (peerFlag & (1 << 6)) != 0; -// boolean handshake = (peerFlag & (1 << 7)) != 0; -// boolean connecting = (peerFlag & (1 << 8)) != 0; -// boolean onParole = (peerFlag & (1 << 9)) != 0; -// boolean seed = (peerFlag & (1 << 10)) != 0; -// boolean optimisticUnchoke = (peerFlag & (1 << 11)) != 0; -// boolean snubbed = (peerFlag & (1 << 12)) != 0; -// boolean uploadOnly = (peerFlag & (1 << 13)) != 0; -// boolean endGameMode = (peerFlag & (1 << 14)) != 0; -// boolean holePunched = (peerFlag & (1 << 15)) != 0; -// boolean i2pSocket = (peerFlag & (1 << 16)) != 0; -// boolean utpSocket = (peerFlag & (1 << 17)) != 0; -// boolean sslSocket = (peerFlag & (1 << 18)) != 0; -// boolean rc4Encrypted = (peerFlag & (1 << 19)) != 0; -// boolean plainTextEncrypted = (peerFlag & (1 << 20)) != 0; -// -// boolean tracker = (sourceFlag & (1 << 0)) != 0; -// boolean dht = (sourceFlag & (1 << 1)) != 0; -// boolean pex = (sourceFlag & (1 << 2)) != 0; -// boolean lsd = (sourceFlag & (1 << 3)) != 0; -// boolean resumeData = (sourceFlag & (1 << 4)) != 0; -// boolean incoming = (sourceFlag & (1 << 5)) != 0; -// -// StringJoiner joiner = new StringJoiner(" "); -// -// if (interesting) { -// if (remoteChoked) { -// joiner.add("d"); -// } else { -// joiner.add("D"); -// } -// } -// if (remoteInterested) { -// if (choked) { -// joiner.add("u"); -// } else { -// joiner.add("U"); -// } -// } -// if (!remoteChoked && !interesting) -// joiner.add("K"); -// if (!choked && !remoteInterested) -// joiner.add("?"); -// if (optimisticUnchoke) -// joiner.add("O"); -// if (snubbed) -// joiner.add("S"); -// if (!localConnection) -// joiner.add("I"); -// if (dht) -// joiner.add("H"); -// if (pex) -// joiner.add("X"); -// if (lsd) -// joiner.add("L"); -// if (rc4Encrypted) -// joiner.add("E"); -// if (plainTextEncrypted) -// joiner.add("e"); -// if (utpSocket) -// joiner.add("P"); -// -// return joiner.toString(); -// } -// -// -// private boolean c2b(char c) { -// return c == '1'; -// } -// -// private String readBits(int i, int bitLength) { -// StringBuilder builder = new StringBuilder(); -// builder.append(Integer.toBinaryString(i)); -// while (builder.length() < bitLength) { -// builder.append("0"); -// } -// return builder.toString(); -// } - @NoArgsConstructor @Data public static class Config { @@ -321,6 +240,7 @@ public static class Config { private boolean verifySsl; private String rpcUrl; private boolean incrementBan; + private boolean ignorePrivate; public static Config readFromYaml(ConfigurationSection section) { Config config = new Config(); @@ -334,6 +254,7 @@ public static Config readFromYaml(ConfigurationSection section) { config.setHttpVersion(section.getString("http-version", "HTTP_1_1")); config.setVerifySsl(section.getBoolean("verify-ssl", true)); config.setIncrementBan(section.getBoolean("increment-ban", true)); + config.setIgnorePrivate(section.getBoolean("ignore-private", false)); return config; } @@ -346,6 +267,7 @@ public YamlConfiguration saveToYaml() { section.set("http-version", httpVersion); section.set("increment-ban", incrementBan); section.set("verify-ssl", verifySsl); + section.set("ignore-private", ignorePrivate); return section; } } diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/deluge/DelugeTorrent.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/deluge/DelugeTorrent.java index cbacc71d11..00d15b05ab 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/deluge/DelugeTorrent.java +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/deluge/DelugeTorrent.java @@ -18,4 +18,10 @@ public final class DelugeTorrent implements Torrent { private long rtUploadSpeed; private long rtDownloadSpeed; private List peers; + private boolean privateTorrent; + + @Override + public boolean isPrivate() { + return privateTorrent; + } } diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBEEPeer.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBEEPeer.java new file mode 100644 index 0000000000..6f08726c3c --- /dev/null +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBEEPeer.java @@ -0,0 +1,135 @@ +package com.ghostchu.peerbanhelper.downloader.impl.qbittorrent; + + +import com.ghostchu.peerbanhelper.peer.Peer; +import com.ghostchu.peerbanhelper.peer.PeerFlag; +import com.ghostchu.peerbanhelper.wrapper.PeerAddress; +import com.google.gson.annotations.SerializedName; +import lombok.Getter; +import lombok.Setter; +import org.jetbrains.annotations.Nullable; + +@Setter +public final class QBEEPeer implements Peer { + @SerializedName("client") + private String client; + @SerializedName("connection") + private String connection; + @SerializedName("country") + private String country; + @SerializedName("country_code") + private String countryCode; + @SerializedName("dl_speed") + private Long dlSpeed; + @SerializedName("downloaded") + private Long downloaded; + @SerializedName("files") + private String files; + @SerializedName("flags") + private String flags; + @SerializedName("flags_desc") + private String flagsDesc; + @SerializedName("ip") + private String ip; + @SerializedName("peer_id_client") + private String peerIdClient; + @SerializedName("port") + private Integer port; + @SerializedName("progress") + private Double progress; + @SerializedName("relevance") + private Double relevance; + @SerializedName("up_speed") + private Long upSpeed; + @SerializedName("uploaded") + private Long uploaded; + @Getter + @SerializedName("shadowbanned") + private Boolean shadowBanned; + private transient PeerAddress peerAddress; + private String rawIp; + + public QBEEPeer() { + } + + @Override + public PeerAddress getPeerAddress() { + if (this.peerAddress == null) { + this.peerAddress = new PeerAddress(ip, port); + } + return this.peerAddress; + } + + @Override + @Nullable + public String getPeerId() { + return peerIdClient; + } + + @Override + @Nullable + public String getClientName() { + return client; + } + + @Override + public long getDownloadSpeed() { + return dlSpeed; + } + + @Override + public long getDownloaded() { + return downloaded; + } + + @Override + public long getUploadSpeed() { + return upSpeed; + } + + @Override + public long getUploaded() { + return uploaded; + } + + @Override + public double getProgress() { + return progress; + } + + @Override + public PeerFlag getFlags() { + return new PeerFlag(flags); + } + + @Override + public String getRawIp() { + return rawIp == null ? ip : rawIp; + } + + + @Override + public String toString() { + return "QBEEPeer{" + + "client='" + client + '\'' + + ", connection='" + connection + '\'' + + ", country='" + country + '\'' + + ", countryCode='" + countryCode + '\'' + + ", dlSpeed=" + dlSpeed + + ", downloaded=" + downloaded + + ", files='" + files + '\'' + + ", flags='" + flags + '\'' + + ", flagsDesc='" + flagsDesc + '\'' + + ", ip='" + ip + '\'' + + ", peerIdClient='" + peerIdClient + '\'' + + ", port=" + port + + ", progress=" + progress + + ", relevance=" + relevance + + ", upSpeed=" + upSpeed + + ", uploaded=" + uploaded + + ", shadowBanned=" + shadowBanned + + ", peerAddress=" + peerAddress + + ", rawIp='" + rawIp + '\'' + + '}'; + } +} diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBMainData.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBMainData.java new file mode 100644 index 0000000000..62ce6cf1d5 --- /dev/null +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBMainData.java @@ -0,0 +1,69 @@ +package com.ghostchu.peerbanhelper.downloader.impl.qbittorrent; + + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Data +public class QBMainData { + + @SerializedName("server_state") + private ServerStateDTO serverState; + + @NoArgsConstructor + @Data + public static class ServerStateDTO { + @SerializedName("alltime_dl") + private Long alltimeDl; + @SerializedName("alltime_ul") + private Long alltimeUl; + @SerializedName("average_time_queue") + private Long averageTimeQueue; + @SerializedName("connection_status") + private String connectionStatus; + @SerializedName("dht_nodes") + private Long dhtNodes; + @SerializedName("dl_info_data") + private Long dlInfoData; + @SerializedName("dl_info_speed") + private Long dlInfoSpeed; + @SerializedName("dl_rate_limit") + private Long dlRateLimit; + @SerializedName("free_space_on_disk") + private Long freeSpaceOnDisk; + @SerializedName("global_ratio") + private String globalRatio; + @SerializedName("queued_io_jobs") + private Long queuedIoJobs; + @SerializedName("queueing") + private Boolean queueing; + @SerializedName("read_cache_hits") + private String readCacheHits; + @SerializedName("read_cache_overload") + private String readCacheOverload; + @SerializedName("refresh_interval") + private Long refreshInterval; + @SerializedName("total_buffers_size") + private Long totalBuffersSize; + @SerializedName("total_peer_connections") + private Long totalPeerConnections; + @SerializedName("total_queued_size") + private Long totalQueuedSize; + @SerializedName("total_wasted_session") + private Long totalWastedSession; + @SerializedName("up_info_data") + private Long upInfoData; + @SerializedName("up_info_speed") + private Long upInfoSpeed; + @SerializedName("up_rate_limit") + private Long upRateLimit; + @SerializedName("use_alt_speed_limits") + private Boolean useAltSpeedLimits; + @SerializedName("use_subcategories") + private Boolean useSubcategories; + @SerializedName("write_cache_overload") + private String writeCacheOverload; + } +} diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBTorrent.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBTorrent.java index ef492fded7..157e911e78 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBTorrent.java +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBTorrent.java @@ -161,4 +161,8 @@ public final class QBTorrent { @SerializedName("upspeed") private Long upspeed; + + @SerializedName("is_private") + private Boolean privateTorrent; + } diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBittorrent.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBittorrent.java index 65f332abdf..2c319e621b 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBittorrent.java +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBittorrent.java @@ -2,6 +2,7 @@ import com.ghostchu.peerbanhelper.downloader.AbstractDownloader; import com.ghostchu.peerbanhelper.downloader.DownloaderLoginResult; +import com.ghostchu.peerbanhelper.downloader.DownloaderStatistics; import com.ghostchu.peerbanhelper.peer.Peer; import com.ghostchu.peerbanhelper.text.Lang; import com.ghostchu.peerbanhelper.text.TranslationComponent; @@ -11,7 +12,6 @@ import com.ghostchu.peerbanhelper.util.json.JsonUtil; import com.ghostchu.peerbanhelper.wrapper.BanMetadata; import com.ghostchu.peerbanhelper.wrapper.PeerAddress; -import com.ghostchu.peerbanhelper.wrapper.TorrentWrapper; import com.github.mizosoft.methanol.FormBodyPublisher; import com.github.mizosoft.methanol.Methanol; import com.github.mizosoft.methanol.MutableRequest; @@ -160,19 +160,30 @@ public List getTorrents() { }.getType()); List torrents = new ArrayList<>(); for (QBTorrent detail : qbTorrent) { - torrents.add(new TorrentImpl(detail.getHash(), detail.getName(), detail.getHash(), detail.getTotalSize(), detail.getProgress(), detail.getUpspeed(), detail.getDlspeed())); + if (config.isIgnorePrivate() && detail.getPrivateTorrent() != null && detail.getPrivateTorrent()) { + continue; + } + torrents.add(new TorrentImpl(detail.getHash(), detail.getName(), detail.getHash(), detail.getTotalSize(), + detail.getProgress(), detail.getUpspeed(), detail.getDlspeed(), + detail.getPrivateTorrent() != null && detail.getPrivateTorrent())); } return torrents; } - @Override - public void relaunchTorrentIfNeeded(Collection torrents) { - // QB 很棒,什么都不需要做 - } @Override - public void relaunchTorrentIfNeededByTorrentWrapper(Collection torrents) { - // QB 很棒,什么都不需要做 + public DownloaderStatistics getStatistics() { + HttpResponse request; + try { + request = httpClient.send(MutableRequest.GET(apiEndpoint + "/sync/maindata"), HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); + } catch (Exception e) { + throw new IllegalStateException(e); + } + if (request.statusCode() != 200) { + throw new IllegalStateException(tlUI(Lang.DOWNLOADER_FAILED_REQUEST_STATISTICS, request.statusCode(), request.body())); + } + QBMainData mainData = JsonUtil.getGson().fromJson(request.body(), QBMainData.class); + return new DownloaderStatistics(mainData.getServerState().getAlltimeUl(), mainData.getServerState().getAlltimeDl()); } @Override @@ -234,31 +245,6 @@ private void setBanListIncrement(Collection added) { throw new IllegalStateException(e); } }); -// -// Map banTasks = new HashMap<>(); -// added.forEach(p -> { -// StringJoiner joiner = banTasks.getOrDefault(p.getTorrent().getHash(), new StringJoiner("|")); -// IPAddress ipAddress = IPAddressUtil.getIPAddress(p.getPeer().getAddress().getIp()); -// -// banTasks.put(p.getTorrent().getHash(), joiner); -// }); -// banTasks.forEach((hash, peers) -> { -// try { -// HttpResponse request = httpClient.send(MutableRequest -// .POST(apiEndpoint + "/transfer/banPeers", FormBodyPublisher.newBuilder() -// .query("hash", hash) -// .query("peers", peers.toString()).build()) -// .header("Content-Type", "application/x-www-form-urlencoded") -// , HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); -// if (request.statusCode() != 200) { -// log.error(tlUI(Lang.DOWNLOADER_QB_INCREAMENT_BAN_FAILED, name, apiEndpoint, request.statusCode(), "HTTP ERROR", request.body())); -// throw new IllegalStateException("Save qBittorrent banlist error: statusCode=" + request.statusCode()); -// } -// } catch (Exception e) { -// log.error(tlUI(Lang.DOWNLOADER_QB_INCREAMENT_BAN_FAILED, name, apiEndpoint, "N/A", e.getClass().getName(), e.getMessage()), e); -// throw new IllegalStateException(e); -// } -// }); } private void setBanListFull(Collection peerAddresses) { @@ -297,7 +283,9 @@ public static class Config { private BasicauthDTO basicAuth; private String httpVersion; private boolean incrementBan; + private boolean useShadowBan; private boolean verifySsl; + private boolean ignorePrivate; public static Config readFromYaml(ConfigurationSection section) { Config config = new Config(); @@ -314,7 +302,9 @@ public static Config readFromYaml(ConfigurationSection section) { config.setBasicAuth(basicauthDTO); config.setHttpVersion(section.getString("http-version", "HTTP_1_1")); config.setIncrementBan(section.getBoolean("increment-ban", false)); + config.setUseShadowBan(section.getBoolean("use-shadow-ban", false)); config.setVerifySsl(section.getBoolean("verify-ssl", true)); + config.setIgnorePrivate(section.getBoolean("ignore-private", false)); return config; } @@ -328,7 +318,9 @@ public YamlConfiguration saveToYaml() { section.set("basic-auth.pass", Objects.requireNonNullElse(basicAuth.pass, "")); section.set("http-version", httpVersion); section.set("increment-ban", incrementBan); + section.set("use-shadow-ban", useShadowBan); section.set("verify-ssl", verifySsl); + section.set("ignore-private", ignorePrivate); return section; } diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBittorrentEE.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBittorrentEE.java new file mode 100644 index 0000000000..46f0b77f77 --- /dev/null +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/QBittorrentEE.java @@ -0,0 +1,451 @@ +package com.ghostchu.peerbanhelper.downloader.impl.qbittorrent; + +import com.ghostchu.peerbanhelper.downloader.AbstractDownloader; +import com.ghostchu.peerbanhelper.downloader.DownloaderLoginResult; +import com.ghostchu.peerbanhelper.downloader.DownloaderStatistics; +import com.ghostchu.peerbanhelper.peer.Peer; +import com.ghostchu.peerbanhelper.text.Lang; +import com.ghostchu.peerbanhelper.text.TranslationComponent; +import com.ghostchu.peerbanhelper.torrent.Torrent; +import com.ghostchu.peerbanhelper.torrent.TorrentImpl; +import com.ghostchu.peerbanhelper.util.HTTPUtil; +import com.ghostchu.peerbanhelper.util.json.JsonUtil; +import com.ghostchu.peerbanhelper.wrapper.BanMetadata; +import com.ghostchu.peerbanhelper.wrapper.PeerAddress; +import com.github.mizosoft.methanol.FormBodyPublisher; +import com.github.mizosoft.methanol.Methanol; +import com.github.mizosoft.methanol.MutableRequest; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.bspfsystems.yamlconfiguration.configuration.ConfigurationSection; +import org.bspfsystems.yamlconfiguration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.net.*; +import java.net.http.HttpClient; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.*; + +import static com.ghostchu.peerbanhelper.text.TextManager.tlUI; + +@Slf4j +public class QBittorrentEE extends AbstractDownloader { + private final String apiEndpoint; + private final HttpClient httpClient; + private final Config config; + private final BanHandler banHandler; + + public QBittorrentEE(String name, Config config) { + super(name); + this.config = config; + this.apiEndpoint = config.getEndpoint() + "/api/v2"; + CookieManager cm = new CookieManager(); + cm.setCookiePolicy(CookiePolicy.ACCEPT_ALL); + Methanol.Builder builder = Methanol + .newBuilder() + .version(HttpClient.Version.valueOf(config.getHttpVersion())) + .defaultHeader("Accept-Encoding", "gzip,deflate") + .followRedirects(HttpClient.Redirect.ALWAYS) + .connectTimeout(Duration.of(10, ChronoUnit.SECONDS)) + .headersTimeout(Duration.of(10, ChronoUnit.SECONDS)) + .readTimeout(Duration.of(30, ChronoUnit.SECONDS)) + .requestTimeout(Duration.of(30, ChronoUnit.SECONDS)) + .authenticator(new Authenticator() { + @Override + public PasswordAuthentication requestPasswordAuthenticationInstance(String host, InetAddress addr, int port, String protocol, String prompt, String scheme, URL url, RequestorType reqType) { + return new PasswordAuthentication(config.getBasicAuth().getUser(), config.getBasicAuth().getPass().toCharArray()); + } + }) + .cookieHandler(cm); + if (!config.isVerifySsl() && HTTPUtil.getIgnoreSslContext() != null) { + builder.sslContext(HTTPUtil.getIgnoreSslContext()); + } + this.httpClient = builder.build(); + if (config.isUseShadowBan()) { + this.banHandler = new BanHandlerShadowBan(httpClient, name, apiEndpoint); + } else { + this.banHandler = new BanHandlerNormal(httpClient, name, apiEndpoint); + } + } + + public static QBittorrentEE loadFromConfig(String name, JsonObject section) { + Config config = JsonUtil.getGson().fromJson(section.toString(), Config.class); + return new QBittorrentEE(name, config); + } + + public static QBittorrentEE loadFromConfig(String name, ConfigurationSection section) { + Config config = Config.readFromYaml(section); + return new QBittorrentEE(name, config); + } + + @Override + public JsonObject saveDownloaderJson() { + return JsonUtil.getGson().toJsonTree(config).getAsJsonObject(); + } + + @Override + public YamlConfiguration saveDownloader() { + return config.saveToYaml(); + } + + public DownloaderLoginResult login0() { + // 这个接口没登陆也会 400 + try { + if (config.isUseShadowBan() && !banHandler.test()) { + return new DownloaderLoginResult(DownloaderLoginResult.Status.REQUIRE_TAKE_ACTIONS, new TranslationComponent(Lang.DOWNLOADER_QBITTORRENTEE_SHADOWBANAPI_TEST_FAILURE)); + } + } catch (Exception e) { + return new DownloaderLoginResult(DownloaderLoginResult.Status.EXCEPTION, new TranslationComponent(Lang.DOWNLOADER_LOGIN_IO_EXCEPTION, e.getClass().getName() + ": " + e.getMessage())); + } + if (isLoggedIn()) + return new DownloaderLoginResult(DownloaderLoginResult.Status.SUCCESS, new TranslationComponent(Lang.STATUS_TEXT_OK)); // 重用 Session 会话 + try { + + HttpResponse request = httpClient + .send(MutableRequest.POST(apiEndpoint + "/auth/login", + FormBodyPublisher.newBuilder() + .query("username", config.getUsername()) + .query("password", config.getPassword()).build()) + .header("Content-Type", "application/x-www-form-urlencoded") + , HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); + if (request.statusCode() == 200) { + return new DownloaderLoginResult(DownloaderLoginResult.Status.SUCCESS, new TranslationComponent(Lang.STATUS_TEXT_OK)); + } + if (request.statusCode() == 403) { + return new DownloaderLoginResult(DownloaderLoginResult.Status.INCORRECT_CREDENTIAL, new TranslationComponent(Lang.DOWNLOADER_LOGIN_EXCEPTION, request.body())); + } + return new DownloaderLoginResult(DownloaderLoginResult.Status.EXCEPTION, new TranslationComponent(Lang.DOWNLOADER_LOGIN_INCORRECT_CRED)); + // return request.statusCode() == 200; + } catch (Exception e) { + return new DownloaderLoginResult(DownloaderLoginResult.Status.EXCEPTION, new TranslationComponent(Lang.DOWNLOADER_LOGIN_IO_EXCEPTION, e.getClass().getName() + ": " + e.getMessage())); + } + } + + @Override + public String getEndpoint() { + return apiEndpoint; + } + + + @Override + public String getType() { + return "qBittorrentEE"; + } + + public boolean isLoggedIn() { + HttpResponse resp; + try { + resp = httpClient.send(MutableRequest.GET(apiEndpoint + "/app/version"), HttpResponse.BodyHandlers.discarding()); + } catch (Exception e) { + return false; + } + return resp.statusCode() == 200; + } + + @Override + public void setBanList(@NotNull Collection fullList, @Nullable Collection added, @Nullable Collection removed, boolean applyFullList) { + if (removed != null && removed.isEmpty() && added != null && config.isIncrementBan() && !applyFullList) { + banHandler.setBanListIncrement(added); + } else { + banHandler.setBanListFull(fullList); + } + } + + @Override + public List getTorrents() { + HttpResponse request; + try { + request = httpClient.send(MutableRequest.GET(apiEndpoint + "/torrents/info?filter=active"), HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); + } catch (Exception e) { + throw new IllegalStateException(e); + } + if (request.statusCode() != 200) { + throw new IllegalStateException(tlUI(Lang.DOWNLOADER_QB_FAILED_REQUEST_TORRENT_LIST, request.statusCode(), request.body())); + } + List qbTorrent = JsonUtil.getGson().fromJson(request.body(), new TypeToken>() { + }.getType()); + List torrents = new ArrayList<>(); + for (QBTorrent detail : qbTorrent) { + torrents.add(new TorrentImpl(detail.getHash(), detail.getName(), detail.getHash(), + detail.getTotalSize(), detail.getProgress(), detail.getUpspeed(), + detail.getDlspeed(), + detail.getPrivateTorrent() != null && detail.getPrivateTorrent())); + } + return torrents; + } + + @Override + public DownloaderStatistics getStatistics() { + HttpResponse request; + try { + request = httpClient.send(MutableRequest.GET(apiEndpoint + "/sync/maindata"), HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); + } catch (Exception e) { + throw new IllegalStateException(e); + } + if (request.statusCode() != 200) { + throw new IllegalStateException(tlUI(Lang.DOWNLOADER_FAILED_REQUEST_STATISTICS, request.statusCode(), request.body())); + } + QBMainData mainData = JsonUtil.getGson().fromJson(request.body(), QBMainData.class); + return new DownloaderStatistics(mainData.getServerState().getAlltimeUl(), mainData.getServerState().getAlltimeDl()); + } + + @Override + public List getPeers(Torrent torrent) { + HttpResponse resp; + try { + resp = httpClient.send(MutableRequest.GET(apiEndpoint + "/sync/torrentPeers?hash=" + torrent.getId()), + HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); + } catch (Exception e) { + throw new IllegalStateException(e); + } + if (resp.statusCode() != 200) { + throw new IllegalStateException(tlUI(Lang.DOWNLOADER_QB_FAILED_REQUEST_PEERS_LIST_IN_TORRENT, resp.statusCode(), resp.body())); + } + + JsonObject object = JsonParser.parseString(resp.body()).getAsJsonObject(); + JsonObject peers = object.getAsJsonObject("peers"); + List peersList = new ArrayList<>(); + for (String s : peers.keySet()) { + JsonObject singlePeerObject = peers.getAsJsonObject(s); + QBEEPeer qbPeer = JsonUtil.getGson().fromJson(singlePeerObject.toString(), QBEEPeer.class); + if (qbPeer.getShadowBanned()) { + continue; // 当做不存在处理 + } + // 一个 QB 本地化问题的 Workaround + if (qbPeer.getPeerId() == null || qbPeer.getPeerId().equals("Unknown") || qbPeer.getPeerId().equals("未知")) { + qbPeer.setPeerIdClient(""); + } + if (qbPeer.getClientName() != null) { + if (qbPeer.getClientName().startsWith("Unknown [") && qbPeer.getClientName().endsWith("]")) { + String mid = qbPeer.getClientName().substring("Unknown [".length(), qbPeer.getClientName().length() - 1); + qbPeer.setClient(mid); + } + } + qbPeer.setRawIp(s); + peersList.add(qbPeer); + } + return peersList; + } + + + @Override + public void close() throws Exception { + + } + + interface BanHandler { + boolean test(); + + void setBanListIncrement(Collection added); + + void setBanListFull(Collection peerAddresses); + } + + public static class BanHandlerNormal implements BanHandler { + + private final HttpClient httpClient; + private final String name; + private final String apiEndpoint; + + public BanHandlerNormal(HttpClient httpClient, String name, String apiEndpoint) { + this.httpClient = httpClient; + this.name = name; + this.apiEndpoint = apiEndpoint; + } + + @Override + public boolean test() { + return true; + } + + @Override + public void setBanListIncrement(Collection added) { + Map banTasks = new HashMap<>(); + added.forEach(p -> { + StringJoiner joiner = banTasks.getOrDefault(p.getTorrent().getHash(), new StringJoiner("|")); + joiner.add(p.getPeer().getRawIp()); + banTasks.put(p.getTorrent().getHash(), joiner); + }); + banTasks.forEach((hash, peers) -> { + try { + HttpResponse request = httpClient.send(MutableRequest + .POST(apiEndpoint + "/transfer/banPeers", FormBodyPublisher.newBuilder() + .query("hash", hash) + .query("peers", peers.toString()).build()) + .header("Content-Type", "application/x-www-form-urlencoded") + , HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); + if (request.statusCode() != 200) { + log.error(tlUI(Lang.DOWNLOADER_QB_INCREAMENT_BAN_FAILED, name, apiEndpoint, request.statusCode(), "HTTP ERROR", request.body())); + throw new IllegalStateException("Save qBittorrent banlist error: statusCode=" + request.statusCode()); + } + } catch (Exception e) { + log.error(tlUI(Lang.DOWNLOADER_QB_INCREAMENT_BAN_FAILED, name, apiEndpoint, "N/A", e.getClass().getName(), e.getMessage()), e); + throw new IllegalStateException(e); + } + }); + } + + @Override + public void setBanListFull(Collection peerAddresses) { + StringJoiner joiner = new StringJoiner("\n"); + peerAddresses.forEach(p -> joiner.add(p.getIp())); + try { + HttpResponse request = httpClient.send(MutableRequest + .POST(apiEndpoint + "/app/setPreferences", FormBodyPublisher.newBuilder() + .query("json", JsonUtil.getGson().toJson(Map.of("banned_IPs", joiner.toString()))).build()) + .header("Content-Type", "application/x-www-form-urlencoded") + , HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); + if (request.statusCode() != 200) { + log.error(tlUI(Lang.DOWNLOADER_QB_FAILED_SAVE_BANLIST, name, apiEndpoint, request.statusCode(), "HTTP ERROR", request.body())); + throw new IllegalStateException("Save qBittorrent banlist error: statusCode=" + request.statusCode()); + } + } catch (Exception e) { + log.error(tlUI(Lang.DOWNLOADER_QB_FAILED_SAVE_BANLIST, name, apiEndpoint, "N/A", e.getClass().getName(), e.getMessage()), e); + throw new IllegalStateException(e); + } + } + } + + public static class BanHandlerShadowBan implements BanHandler { + + private final HttpClient httpClient; + private final String name; + private final String apiEndpoint; + + public BanHandlerShadowBan(HttpClient httpClient, String name, String apiEndpoint) { + this.httpClient = httpClient; + this.name = name; + this.apiEndpoint = apiEndpoint; + } + + @Override + public boolean test() { + try { + HttpResponse request = httpClient.send(MutableRequest + .GET(apiEndpoint + "/transfer/shadowbanPeers") + .header("Content-Type", "application/x-www-form-urlencoded") + , HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); + return request.statusCode() == 400; + } catch (IOException | InterruptedException e) { + throw new IllegalStateException(e); + } + } + + @Override + public void setBanListIncrement(Collection added) { + Map banTasks = new HashMap<>(); + added.forEach(p -> { + StringJoiner joiner = banTasks.getOrDefault(p.getTorrent().getHash(), new StringJoiner("|")); + joiner.add(p.getPeer().getRawIp()); + banTasks.put(p.getTorrent().getHash(), joiner); + }); + banTasks.forEach((hash, peers) -> { + try { + HttpResponse request = httpClient.send(MutableRequest + .POST(apiEndpoint + "/transfer/shadowbanPeers", FormBodyPublisher.newBuilder() + .query("hash", hash) + .query("peers", peers.toString()).build()) + .header("Content-Type", "application/x-www-form-urlencoded") + , HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); + if (request.statusCode() != 200) { + log.error(tlUI(Lang.DOWNLOADER_QB_INCREAMENT_BAN_FAILED, name, apiEndpoint, request.statusCode(), "HTTP ERROR", request.body())); + throw new IllegalStateException("Save qBittorrent shadow banlist error: statusCode=" + request.statusCode()); + } + } catch (Exception e) { + log.error(tlUI(Lang.DOWNLOADER_QB_INCREAMENT_BAN_FAILED, name, apiEndpoint, "N/A", e.getClass().getName(), e.getMessage()), e); + throw new IllegalStateException(e); + } + }); + } + + @Override + public void setBanListFull(Collection peerAddresses) { + StringJoiner joiner = new StringJoiner("\n"); + peerAddresses.forEach(p -> joiner.add(p.getIp())); + try { + HttpResponse request = httpClient.send(MutableRequest + .POST(apiEndpoint + "/app/setPreferences", FormBodyPublisher.newBuilder() + .query("json", JsonUtil.getGson().toJson(Map.of("shadow_banned_IPs", joiner.toString()))).build()) + .header("Content-Type", "application/x-www-form-urlencoded") + , HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); + if (request.statusCode() != 200) { + log.error(tlUI(Lang.DOWNLOADER_QB_FAILED_SAVE_BANLIST, name, apiEndpoint, request.statusCode(), "HTTP ERROR", request.body())); + throw new IllegalStateException("Save qBittorrent shadow banlist error: statusCode=" + request.statusCode()); + } + } catch (Exception e) { + log.error(tlUI(Lang.DOWNLOADER_QB_FAILED_SAVE_BANLIST, name, apiEndpoint, "N/A", e.getClass().getName(), e.getMessage()), e); + throw new IllegalStateException(e); + } + } + } + + + @NoArgsConstructor + @Data + public static class Config { + + private String type; + private String endpoint; + private String username; + private String password; + private BasicauthDTO basicAuth; + private String httpVersion; + private boolean incrementBan; + private boolean verifySsl; + private boolean useShadowBan; + + public static Config readFromYaml(ConfigurationSection section) { + Config config = new Config(); + config.setType("qbittorrentee"); + config.setEndpoint(section.getString("endpoint")); + if (config.getEndpoint().endsWith("/")) { // 浏览器复制党 workaround 一下, 避免连不上的情况 + config.setEndpoint(config.getEndpoint().substring(0, config.getEndpoint().length() - 1)); + } + config.setUsername(section.getString("username", "")); + config.setPassword(section.getString("password", "")); + BasicauthDTO basicauthDTO = new BasicauthDTO(); + basicauthDTO.setUser(section.getString("basic-auth.user")); + basicauthDTO.setPass(section.getString("basic-auth.pass")); + config.setBasicAuth(basicauthDTO); + config.setHttpVersion(section.getString("http-version", "HTTP_1_1")); + config.setIncrementBan(section.getBoolean("increment-ban", false)); + config.setUseShadowBan(section.getBoolean("use-shadow-ban", false)); + config.setVerifySsl(section.getBoolean("verify-ssl", true)); + return config; + } + + public YamlConfiguration saveToYaml() { + YamlConfiguration section = new YamlConfiguration(); + section.set("type", "qbittorrentee"); + section.set("endpoint", endpoint); + section.set("username", username); + section.set("password", password); + section.set("basic-auth.user", Objects.requireNonNullElse(basicAuth.user, "")); + section.set("basic-auth.pass", Objects.requireNonNullElse(basicAuth.pass, "")); + section.set("http-version", httpVersion); + section.set("increment-ban", incrementBan); + section.set("use-shadow-ban", useShadowBan); + section.set("verify-ssl", verifySsl); + return section; + } + + @NoArgsConstructor + @Data + public static class BasicauthDTO { + @SerializedName("user") + private String user; + @SerializedName("pass") + private String pass; + } + } +} diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/TRTorrent.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/TRTorrent.java index 8a8917c3bd..5e19a3815e 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/TRTorrent.java +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/TRTorrent.java @@ -50,6 +50,11 @@ public long getRtDownloadSpeed() { return backend.getRateDownload(); } + @Override + public boolean isPrivate() { + return backend.getIsPrivate(); + } + @NotNull public List getPeers() { return backend.getPeers().stream().map(TRPeer::new).collect(Collectors.toList()); diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/Transmission.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/Transmission.java index 9382367902..18f7f0d9a5 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/Transmission.java +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/Transmission.java @@ -2,6 +2,7 @@ import com.ghostchu.peerbanhelper.downloader.AbstractDownloader; import com.ghostchu.peerbanhelper.downloader.DownloaderLoginResult; +import com.ghostchu.peerbanhelper.downloader.DownloaderStatistics; import com.ghostchu.peerbanhelper.peer.Peer; import com.ghostchu.peerbanhelper.text.Lang; import com.ghostchu.peerbanhelper.text.TranslationComponent; @@ -127,6 +128,7 @@ public List getTorrents() { TypedResponse rsp = client.execute(torrent); return rsp.getArgs().getTorrents().stream() .filter(t -> t.getStatus() == Status.DOWNLOADING || t.getStatus() == Status.SEEDING) + .filter(t -> !(config.isIgnorePrivate() && t.getIsPrivate())) .map(TRTorrent::new).collect(Collectors.toList()); } @@ -149,6 +151,13 @@ public void setBanList(Collection fullList, @Nullable Collection sessionStatsResp = client.execute(sessionStats); + var stats = sessionStatsResp.getArgs(); + return new DownloaderStatistics(stats.getCumulativeStats().getUploadedBytes(), stats.getCumulativeStats().getDownloadedBytes()); + } @Override public void relaunchTorrentIfNeeded(Collection torrents) { @@ -168,7 +177,7 @@ private void relaunchTorrents(Collection ids) { RqTorrentGet torrentList = new RqTorrentGet(Fields.ID, Fields.HASH_STRING, Fields.NAME, Fields.PEERS_CONNECTED, Fields.STATUS, Fields.TOTAL_SIZE, Fields.PEERS, Fields.RATE_DOWNLOAD, - Fields.RATE_UPLOAD, Fields.PEER_LIMIT, Fields.PERCENT_DONE); + Fields.RATE_UPLOAD, Fields.PEER_LIMIT, Fields.PERCENT_DONE, Fields.IS_PRIVATE); TypedResponse rsp = client.execute(torrentList); List torrents = rsp.getArgs().getTorrents().stream() .filter(t -> t.getStatus() != Status.STOPPED) @@ -266,6 +275,7 @@ public static class Config { private String httpVersion; private boolean verifySsl; private String rpcUrl; + private boolean ignorePrivate; public static Transmission.Config readFromYaml(ConfigurationSection section) { Transmission.Config config = new Transmission.Config(); @@ -279,6 +289,7 @@ public static Transmission.Config readFromYaml(ConfigurationSection section) { config.setRpcUrl(section.getString("rpc-url", "/transmission/rpc")); config.setHttpVersion(section.getString("http-version", "HTTP_1_1")); config.setVerifySsl(section.getBoolean("verify-ssl", true)); + config.setIgnorePrivate(section.getBoolean("ignore-private", false)); return config; } @@ -291,6 +302,7 @@ public YamlConfiguration saveToYaml() { section.set("rpc-url", rpcUrl); section.set("http-version", httpVersion); section.set("verify-ssl", verifySsl); + section.set("ignore-private", ignorePrivate); return section; } } diff --git a/src/main/java/com/ghostchu/peerbanhelper/module/AbstractFeatureModule.java b/src/main/java/com/ghostchu/peerbanhelper/module/AbstractFeatureModule.java index d15f879bcd..f647023434 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/module/AbstractFeatureModule.java +++ b/src/main/java/com/ghostchu/peerbanhelper/module/AbstractFeatureModule.java @@ -15,6 +15,7 @@ import java.io.File; import java.io.IOException; import java.util.Objects; +import java.util.TimeZone; import java.util.concurrent.locks.ReentrantLock; import static com.ghostchu.peerbanhelper.text.TextManager.tlUI; @@ -98,4 +99,11 @@ public String locale(Context ctx) { return javalinWebContainer.reqLocale(ctx); } + public TimeZone timezone(Context ctx) { + var tz = TimeZone.getDefault(); + if (ctx.header("X-Timezone") != null) { + tz = TimeZone.getTimeZone(ctx.header("X-Timezone")); + } + return tz; + } } diff --git a/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/ActiveMonitoringModule.java b/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/ActiveMonitoringModule.java index 45b9a029b3..ef273770dd 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/ActiveMonitoringModule.java +++ b/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/ActiveMonitoringModule.java @@ -3,6 +3,7 @@ import com.ghostchu.peerbanhelper.Main; import com.ghostchu.peerbanhelper.database.dao.impl.PeerRecordDao; import com.ghostchu.peerbanhelper.database.dao.impl.TrafficJournalDao; +import com.ghostchu.peerbanhelper.downloader.Downloader; import com.ghostchu.peerbanhelper.event.LivePeersUpdatedEvent; import com.ghostchu.peerbanhelper.module.AbstractFeatureModule; import com.ghostchu.peerbanhelper.text.Lang; @@ -119,26 +120,16 @@ private void reloadConfig() { } private void writeJournal() { - try { - var entity = trafficJournalDao.getTodayJournal(); - String[] data = peerRecordDao.queryBuilder() - .selectRaw("SUM(uploaded) as total_uploaded", "SUM(downloaded) as total_downloaded") - .queryRawFirst(); - long uploaded = 0; - long downloaded = 0; - if (data != null) { - if (data[0] != null && !data[0].isBlank()) { - uploaded = Long.parseLong(data[0]); - } - if (data[1] != null && !data[1].isBlank()) { - downloaded = Long.parseLong(data[1]); - } + for (Downloader downloader : getServer().getDownloaders()) { + try { + var entity = trafficJournalDao.getTodayJournal(downloader.getName()); + var stats = downloader.getStatistics(); + entity.setDataOverallUploaded(stats.totalUploaded()); + entity.setDataOverallDownloaded(stats.totalDownloaded()); + trafficJournalDao.update(entity); + } catch (Throwable e) { + log.error("Unable to write hourly traffic journal to database", e); } - entity.setUploaded(uploaded); - entity.setDownloaded(downloaded); - trafficJournalDao.update(entity); - } catch (Throwable e) { - log.error("Unable to write hourly traffic journal to database", e); } } diff --git a/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/ProgressCheatBlocker.java b/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/ProgressCheatBlocker.java index fd3a959710..5035cbe23c 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/ProgressCheatBlocker.java +++ b/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/ProgressCheatBlocker.java @@ -74,6 +74,7 @@ public class ProgressCheatBlocker extends AbstractRuleFeatureModule implements R private ProgressCheatBlockerPersistDao progressCheatBlockerPersistDao; private boolean enablePersist; private long persistDuration; + private long maxWaitDuration; @Override public @NotNull String getName() { @@ -177,6 +178,7 @@ private void reloadConfig() { this.ipv6PrefixLength = getConfig().getInt("ipv6-prefix-length"); this.enablePersist = getConfig().getBoolean("enable-persist"); this.persistDuration = getConfig().getLong("persist-duration"); + this.maxWaitDuration = getConfig().getLong("max-wait-duration"); } @@ -206,7 +208,7 @@ private void reloadConfig() { if (lastRecordedProgress == null) lastRecordedProgress = new CopyOnWriteArrayList<>(); ClientTask clientTask = lastRecordedProgress.stream().filter(task -> task.getPeerIp().equals(peerIpString)).findFirst().orElse(null); if (clientTask == null) { - clientTask = new ClientTask(peerIpString, 0d, 0L, 0L, 0, 0, System.currentTimeMillis(), System.currentTimeMillis(), downloader.getName()); + clientTask = new ClientTask(peerIpString, 0d, 0L, 0L, 0, 0, System.currentTimeMillis(), System.currentTimeMillis(), downloader.getName(), 0L); lastRecordedProgress.add(clientTask); } long uploadedIncremental; // 上传增量 @@ -238,6 +240,8 @@ private void reloadConfig() { // 下载过量,检查 long maxAllowedExcessiveThreshold = (long) (torrentSize * excessiveThreshold); if (actualUploaded > maxAllowedExcessiveThreshold) { + clientTask.setBanDelayWindowEndAt(0L); + progressRecorder.invalidate(client); // 封禁时,移除缓存 return new CheckResult(getClass(), PeerAction.BAN, banDuration, new TranslationComponent(Lang.PCB_RULE_REACHED_MAX_ALLOWED_EXCESSIVE_THRESHOLD), new TranslationComponent(Lang.MODULE_PCB_EXCESSIVE_DOWNLOAD, torrentSize, @@ -252,12 +256,17 @@ private void reloadConfig() { // 计算进度差异 double difference = Math.abs(actualProgress - clientProgress); if (difference > maximumDifference) { - clientTask.setProgressDifferenceCounter(clientTask.getProgressDifferenceCounter() + 1); - return new CheckResult(getClass(), PeerAction.BAN, banDuration, new TranslationComponent(Lang.PCB_RULE_REACHED_MAX_DIFFERENCE), - new TranslationComponent(Lang.MODULE_PCB_PEER_BAN_INCORRECT_PROGRESS, - percent(clientProgress), - percent(actualProgress), - percent(difference))); + if (banPeerIfConditionReached(clientTask)) { + clientTask.setProgressDifferenceCounter(clientTask.getProgressDifferenceCounter() + 1); + clientTask.setBanDelayWindowEndAt(0L); + progressRecorder.invalidate(client); // 封禁时,移除缓存 + return new CheckResult(getClass(), PeerAction.BAN, banDuration, new TranslationComponent(Lang.PCB_RULE_REACHED_MAX_DIFFERENCE), + new TranslationComponent(Lang.MODULE_PCB_PEER_BAN_INCORRECT_PROGRESS, + percent(clientProgress), + percent(actualProgress), + percent(difference))); + } + } if (rewindMaximumDifference > 0) { double lastRecord = clientTask.getLastReportProgress(); @@ -265,6 +274,7 @@ private void reloadConfig() { boolean ban = rewind > rewindMaximumDifference; if (ban) { clientTask.setRewindCounter(clientTask.getRewindCounter() + 1); + clientTask.setBanDelayWindowEndAt(0L); progressRecorder.invalidate(client); // 封禁时,移除缓存 } @@ -286,6 +296,14 @@ private void reloadConfig() { } } + private boolean banPeerIfConditionReached(ClientTask clientTask) { + if (clientTask.getBanDelayWindowEndAt() == 0L) { + clientTask.setBanDelayWindowEndAt(System.currentTimeMillis() + this.maxWaitDuration); + return false; + } + return System.currentTimeMillis() >= clientTask.getBanDelayWindowEndAt(); + } + private List loadClientTasks(Client client) { try { if (enablePersist) { @@ -306,7 +324,7 @@ private int calcClientTaskSize(ClientTask clientTask) { // double = 8 // int = 4 // 对象头 = 12 - return calcStringSize(clientTask.peerIp) + (4 * 8) + 8 + (2 * 4) + 12; + return calcStringSize(clientTask.peerIp) + (5 * 8) + 8 + (2 * 4) + 12; } private int calcClientSize(Client client) { @@ -332,6 +350,7 @@ public static class ClientTask { private long firstTimeSeen; private long lastTimeSeen; private String downloader; + private long banDelayWindowEndAt; } @AllArgsConstructor diff --git a/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHChartController.java b/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHChartController.java index 94e8fb423b..5683f383de 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHChartController.java +++ b/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHChartController.java @@ -3,7 +3,6 @@ import com.ghostchu.peerbanhelper.database.dao.impl.HistoryDao; import com.ghostchu.peerbanhelper.database.dao.impl.PeerRecordDao; import com.ghostchu.peerbanhelper.database.dao.impl.TrafficJournalDao; -import com.ghostchu.peerbanhelper.database.table.TrafficJournalEntity; import com.ghostchu.peerbanhelper.ipdb.IPDB; import com.ghostchu.peerbanhelper.ipdb.IPGeoData; import com.ghostchu.peerbanhelper.module.AbstractFeatureModule; @@ -24,6 +23,9 @@ import java.net.InetAddress; import java.net.UnknownHostException; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -69,7 +71,7 @@ public void onEnable() { webContainer.javalin() .get("/api/chart/geoIpInfo", this::handleGeoIP, Role.USER_READ) .get("/api/chart/trend", this::handlePeerTrends, Role.USER_READ) - .get("/api/chart/traffic", this::handleTraffic, Role.USER_READ) + .get("/api/chart/traffic", this::handleTrafficClassic, Role.USER_READ) ; } @@ -78,46 +80,66 @@ private void handleTraffic(Context ctx) throws Exception { throw new RequirePBHPlusLicenseException(tl(locale(ctx), Lang.PBHPLUS_LICENSE_FAILED)); } var timeQueryModel = WebUtil.parseTimeQueryModel(ctx); - String[] data = peerRecordDao.queryBuilder() - .selectRaw("SUM(uploaded) as total_uploaded", "SUM(downloaded) as total_downloaded") - .queryRawFirst(); - long totalUploaded = Long.parseLong(data[0]); - long totalDownloaded = Long.parseLong(data[1]); - List records = new ArrayList<>(); + String downloader = ctx.queryParam("downloader"); + if (downloader == null || downloader.isBlank()) { + ctx.json(new StdResp(true, null, trafficJournalDao.getAllDownloadersOverallData(timeQueryModel.startAt(), timeQueryModel.endAt()).stream().peek(data -> fixTimezone(ctx, data)).toList())); + } else { + ctx.json(new StdResp(true, null, trafficJournalDao.getSpecificDownloaderOverallData(downloader, timeQueryModel.startAt(), timeQueryModel.endAt()).stream().peek(data -> fixTimezone(ctx, data)).toList())); + } + } + + private void handleTrafficClassic(Context ctx) throws Exception { + if (!activationManager.isActivated()) { + throw new RequirePBHPlusLicenseException(tl(locale(ctx), Lang.PBHPLUS_LICENSE_FAILED)); + } + var timeQueryModel = WebUtil.parseTimeQueryModel(ctx); + List results = null; + + String downloader = ctx.queryParam("downloader"); + if (downloader == null || downloader.isBlank()) { + results = trafficJournalDao.getAllDownloadersOverallData(timeQueryModel.startAt(), timeQueryModel.endAt()).stream().peek(data -> fixTimezone(ctx, data)).toList(); + } else { + results = trafficJournalDao.getSpecificDownloaderOverallData(downloader, timeQueryModel.startAt(), timeQueryModel.endAt()).stream().peek(data -> fixTimezone(ctx, data)).toList(); + } + + List records = new ArrayList<>(); + var it = results.iterator(); // ----- - try (var it = trafficJournalDao.queryBuilder() - .orderBy("timestamp", true) - .where() - .ge("timestamp", MiscUtil.getStartOfToday(timeQueryModel.startAt().getTime())) - .and() - .le("timestamp", MiscUtil.getStartOfToday(timeQueryModel.endAt().getTime())) - .iterator()) { - TrafficJournalEntity base = null; - while (it.hasNext()) { - if (base == null) { - base = it.next(); - // 多插一个进去 - records.add(new TrafficJournalRecord(base.getTimestamp(), base.getUploaded(), base.getDownloaded())); - continue; - } - var target = it.next(); - long uploadedOffset = target.getUploaded() - base.getUploaded(); - long downloadedOffset = target.getDownloaded() - base.getDownloaded(); - if (uploadedOffset < 0) uploadedOffset = 0; - if (downloadedOffset < 0) downloadedOffset = 0; + TrafficJournalDao.TrafficData base = null; + while (it.hasNext()) { + var target = it.next(); + + if (base == null) { base = target; - records.add(new TrafficJournalRecord(base.getTimestamp(), uploadedOffset, downloadedOffset)); + continue; // 跳过插入当天的总数据,直接计算增量 } + + long uploadedOffset = target.getDataOverallUploaded() - base.getDataOverallUploaded(); + long downloadedOffset = target.getDataOverallDownloaded() - base.getDataOverallDownloaded(); + if (uploadedOffset < 0) uploadedOffset = 0; + if (downloadedOffset < 0) downloadedOffset = 0; + + // 插入增量数据 + records.add(new TrafficJournalDao.TrafficData(target.getTimestamp(), uploadedOffset, downloadedOffset)); + base = target; } - if (records.size() > 1) { - // 多插的那个移除 - records.removeFirst(); - } - ctx.json(new StdResp(true, null, new TrafficChart(totalUploaded, totalDownloaded, records))); + +// if (records.size() > 1) { +// // 多插的那个移除 +// records.removeFirst(); +// } + ctx.json(new StdResp(true, null, records)); } + private void fixTimezone(Context ctx, TrafficJournalDao.TrafficData data) { + Timestamp ts = data.getTimestamp(); + var epochSecond = ts.toLocalDateTime().atZone(timezone(ctx).toZoneId().getRules().getOffset(Instant.now())) + .truncatedTo(ChronoUnit.DAYS).toEpochSecond(); + data.setTimestamp(new Timestamp(epochSecond * 1000)); + } + private void handlePeerTrends(Context ctx) throws Exception { if (!activationManager.isActivated()) { throw new RequirePBHPlusLicenseException(tl(locale(ctx), Lang.PBHPLUS_LICENSE_FAILED)); @@ -345,13 +367,6 @@ record SimpleLongLongKV(long key, long value) { } - record TrafficChart( - long allTimeUploaded, - long allTimeDownloaded, - List journal - ) { - } - record TrafficJournalRecord( long timestamp, long uploaded, @@ -360,7 +375,6 @@ record TrafficJournalRecord( } - // public record GeoIPQuery(GeoIPPie data, long count) { // // } diff --git a/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHDownloaderController.java b/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHDownloaderController.java index ca8b99bad3..af9c9cea9c 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHDownloaderController.java +++ b/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHDownloaderController.java @@ -264,7 +264,9 @@ private void handleDownloaderStatus(@NotNull Context ctx, String downloaderName) } private void handleDownloaderList(@NotNull Context ctx) { - List downloaders = getServer().getDownloaders().stream().map(d -> new DownloaderWrapper(d.getName(), d.getEndpoint(), d.getType().toLowerCase())).toList(); + List downloaders = getServer().getDownloaders() + .stream().map(d -> new DownloaderWrapper(d.getName(), d.getEndpoint(), d.getType().toLowerCase())) + .toList(); ctx.json(new StdResp(true, null, downloaders)); } diff --git a/src/main/java/com/ghostchu/peerbanhelper/text/Lang.java b/src/main/java/com/ghostchu/peerbanhelper/text/Lang.java index 843683fb16..c20fbf543d 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/text/Lang.java +++ b/src/main/java/com/ghostchu/peerbanhelper/text/Lang.java @@ -326,7 +326,7 @@ public enum Lang { RELOAD_COMPLETED_TITLE, RELOAD_COMPLETED_DESCRIPTION, HEAPDUMP_COMPLETED_TITLE, HEAPDUMP_COMPLETED_DESCRIPTION, HEAPDUMP_FAILED_DESCRIPTION, HEAPDUMP_FAILED_TITLE, RELOADING_MODULE, GUI_MENU_DEBUG, TORRENT_NOT_FOUND, PEER_NOT_FOUND, - PBH_PLUS_LICENSE_INVALID, PBH_PLUS_LICENSE_EXPIRED, IN_ECOMODE_DESCRIPTION, IN_ECOMODE_SHORT, DOWNLOADER_TRANSMISSION_DISCOURAGE; + PBH_PLUS_LICENSE_INVALID, PBH_PLUS_LICENSE_EXPIRED, IN_ECOMODE_DESCRIPTION, IN_ECOMODE_SHORT, DOWNLOADER_TRANSMISSION_DISCOURAGE, DOWNLOADER_FAILED_REQUEST_STATISTICS, DOWNLOADER_QBITTORRENTEE_SHADOWBANAPI_TEST_FAILURE; public String getKey() { return name(); diff --git a/src/main/java/com/ghostchu/peerbanhelper/torrent/Torrent.java b/src/main/java/com/ghostchu/peerbanhelper/torrent/Torrent.java index c5a23005be..8a9af82be5 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/torrent/Torrent.java +++ b/src/main/java/com/ghostchu/peerbanhelper/torrent/Torrent.java @@ -52,6 +52,13 @@ public interface Torrent { */ long getRtDownloadSpeed(); + /** + * 是否是私有种子 + * + * @return 私有种子 + */ + boolean isPrivate(); + /** * 获取种子不可逆匿名识别符 * diff --git a/src/main/java/com/ghostchu/peerbanhelper/torrent/TorrentImpl.java b/src/main/java/com/ghostchu/peerbanhelper/torrent/TorrentImpl.java index d097461430..b458b96642 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/torrent/TorrentImpl.java +++ b/src/main/java/com/ghostchu/peerbanhelper/torrent/TorrentImpl.java @@ -4,6 +4,7 @@ @Setter public class TorrentImpl implements Torrent { + private boolean privateTorrent; private double progress; private long rtUploadSpeed; private long rtDownloadSpeed; @@ -12,7 +13,7 @@ public class TorrentImpl implements Torrent { private String name; private long size; - public TorrentImpl(String id, String name, String hash, long size, double progress, long rtUploadSpeed, long rtDownloadSpeed) { + public TorrentImpl(String id, String name, String hash, long size, double progress, long rtUploadSpeed, long rtDownloadSpeed, boolean privateTorrent) { this.id = id; this.name = name; this.hash = hash; @@ -20,6 +21,7 @@ public TorrentImpl(String id, String name, String hash, long size, double progre this.progress = progress; this.rtUploadSpeed = rtUploadSpeed; this.rtDownloadSpeed = rtDownloadSpeed; + this.privateTorrent = privateTorrent; } @Override @@ -56,4 +58,9 @@ public long getRtUploadSpeed() { public long getRtDownloadSpeed() { return rtDownloadSpeed; } + + @Override + public boolean isPrivate() { + return privateTorrent; + } } diff --git a/src/main/java/raccoonfink/deluge/DelugeServer.java b/src/main/java/raccoonfink/deluge/DelugeServer.java index db5cb263c7..3f46562aa9 100644 --- a/src/main/java/raccoonfink/deluge/DelugeServer.java +++ b/src/main/java/raccoonfink/deluge/DelugeServer.java @@ -283,6 +283,11 @@ public boolean replaceBannedPeers(List ips) throws DelugeException { return !determineResponseError(response); } + public PBHStatisticsResponse queryStatistics() throws DelugeException { + final DelugeResponse response = makeRequest(new DelugeRequest("peerbanhelperadapter.get_session_totals")); + return new PBHStatisticsResponse(response.getResponseCode(), response.getResponseData()); + } + private boolean determineResponseError(DelugeResponse response) { if (response.getResponseData().isNull("error")) { return false; diff --git a/src/main/java/raccoonfink/deluge/responses/PBHActiveTorrentsResponse.java b/src/main/java/raccoonfink/deluge/responses/PBHActiveTorrentsResponse.java index 9a27d17f09..bd923af87d 100644 --- a/src/main/java/raccoonfink/deluge/responses/PBHActiveTorrentsResponse.java +++ b/src/main/java/raccoonfink/deluge/responses/PBHActiveTorrentsResponse.java @@ -45,6 +45,8 @@ public static class ActiveTorrentsResponseDTO { private Integer uploadPayloadRate; @SerializedName("download_payload_rate") private Integer downloadPayloadRate; + @SerializedName("priv") + private Boolean priv; @SerializedName("peers") private List peers; diff --git a/src/main/java/raccoonfink/deluge/responses/PBHStatisticsResponse.java b/src/main/java/raccoonfink/deluge/responses/PBHStatisticsResponse.java new file mode 100644 index 0000000000..704ea10ed0 --- /dev/null +++ b/src/main/java/raccoonfink/deluge/responses/PBHStatisticsResponse.java @@ -0,0 +1,86 @@ +package raccoonfink.deluge.responses; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ghostchu.peerbanhelper.util.json.JsonUtil; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.json.JSONArray; +import org.json.JSONObject; +import raccoonfink.deluge.DelugeException; + +import java.util.List; + +@Getter +public class PBHStatisticsResponse extends DelugeResponse { + private StatisticsResponseDTO statistics; + + public PBHStatisticsResponse(final Integer httpResponseCode, final JSONObject response) throws DelugeException { + super(httpResponseCode, response); + if (response.isNull("result")) { + return; + } + JSONObject jsonArray = response.getJSONObject("result"); + String resultJson = jsonArray.toString(); + this.statistics = JsonUtil.getGson().fromJson(resultJson, StatisticsResponseDTO.class); + } + + @NoArgsConstructor + @Data + public static class StatisticsResponseDTO{ + @SerializedName("stats_last_timestamp") + private Long statsLastTimestamp; + @SerializedName("total_payload_download") + private Long totalPayloadDownload; + @SerializedName("total_payload_upload") + private Long totalPayloadUpload; + @SerializedName("ip_overhead_download") + private Long ipOverheadDownload; + @SerializedName("ip_overhead_upload") + private Long ipOverheadUpload; + @SerializedName("tracker_download") + private Long trackerDownload; + @SerializedName("tracker_upload") + private Long trackerUpload; + @SerializedName("dht_download") + private Long dhtDownload; + @SerializedName("dht_upload") + private Long dhtUpload; + @SerializedName("total_wasted") + private Long totalWasted; + @SerializedName("total_download") + private Long totalDownload; + @SerializedName("total_upload") + private Long totalUpload; + @SerializedName("payload_download_rate") + private Double payloadDownloadRate; + @SerializedName("payload_upload_rate") + private Double payloadUploadRate; + @SerializedName("download_rate") + private Double downloadRate; + @SerializedName("upload_rate") + private Double uploadRate; + @SerializedName("ip_overhead_download_rate") + private Double ipOverheadDownloadRate; + @SerializedName("ip_overhead_upload_rate") + private Double ipOverheadUploadRate; + @SerializedName("dht_download_rate") + private Double dhtDownloadRate; + @SerializedName("dht_upload_rate") + private Double dhtUploadRate; + @SerializedName("tracker_download_rate") + private Double trackerDownloadRate; + @SerializedName("tracker_upload_rate") + private Double trackerUploadRate; + @SerializedName("dht_nodes") + private Long dhtNodes; + @SerializedName("disk_read_queue") + private Long diskReadQueue; + @SerializedName("disk_write_queue") + private Long diskWriteQueue; + @SerializedName("peers_count") + private Long peersCount; + } +} diff --git a/src/main/resources/lang/en_us/messages.yml b/src/main/resources/lang/en_us/messages.yml index 881c20dd03..15aea2776e 100644 --- a/src/main/resources/lang/en_us/messages.yml +++ b/src/main/resources/lang/en_us/messages.yml @@ -364,4 +364,7 @@ PEER_NOT_FOUND: "No records found by given Peer" IN_ECOMODE_SHORT: "🍃EcoQoS" IN_ECOMODE_DESCRIPTION: "EcoQoS API load successfully,Windows Efficiency Mode now applied to PeerBanHelper for saving power usage." -DOWNLOADER_TRANSMISSION_DISCOURAGE: "Warning: Use Transmission Adapter is discourage. Frequent starting and stopping of torrents on seeds that are often subject to bans can result in frequent updates to the tracker server, indirectly triggering DoS attacks. This increases the load on the tracker server and may lead to your IP address being banned by the tracker. We encourage you to migrate to other downloaders whenever possible. https://github.com/PBH-BTN/PeerBanHelper/issues/382" \ No newline at end of file +DOWNLOADER_TRANSMISSION_DISCOURAGE: "Warning: Use Transmission Adapter is discourage. Frequent starting and stopping of torrents on seeds that are often subject to bans can result in frequent updates to the tracker server, indirectly triggering DoS attacks. This increases the load on the tracker server and may lead to your IP address being banned by the tracker. We encourage you to migrate to other downloaders whenever possible. https://github.com/PBH-BTN/PeerBanHelper/issues/382" +DOWNLOADER_QBITTORRENTEE_SHADOWBANAPI_TEST_FAILURE: "You are using an official qBittorrent build or a version of qBittorrentEE that does not support ShadowBan. Please turn off the ShadowBan switch." + +DOWNLOADER_FAILED_REQUEST_STATISTICS: "Getting stats data from downloader {} failed: {}" \ No newline at end of file diff --git a/src/main/resources/lang/messages_fallback.yml b/src/main/resources/lang/messages_fallback.yml index b923714cec..a409e552ca 100644 --- a/src/main/resources/lang/messages_fallback.yml +++ b/src/main/resources/lang/messages_fallback.yml @@ -364,4 +364,7 @@ PEER_NOT_FOUND: "指定的 Peer 记录不存在" IN_ECOMODE_SHORT: "🍃EcoQoS" IN_ECOMODE_DESCRIPTION: "EcoQoS API 加载成功,Windows 效率模式已应用至 PeerBanHelper 以降低系统能耗" -DOWNLOADER_TRANSMISSION_DISCOURAGE: "警告:Transmission 适配器已被废弃,不再推荐使用。在频繁发生封禁事件的种子上,频繁启停 Torrent 将导致对 Tracker 服务器的频繁更新,并间接引发 DoS 攻击,这会增加 Tracker 服务器压力并可能导致您的 IP 地址被 Tracker 服务器封禁。我们鼓励您尽可能迁移到其它下载器上。https://github.com/PBH-BTN/PeerBanHelper/issues/382" \ No newline at end of file +DOWNLOADER_TRANSMISSION_DISCOURAGE: "警告:Transmission 适配器已被废弃,不再推荐使用。在频繁发生封禁事件的种子上,频繁启停 Torrent 将导致对 Tracker 服务器的频繁更新,并间接引发 DoS 攻击,这会增加 Tracker 服务器压力并可能导致您的 IP 地址被 Tracker 服务器封禁。我们鼓励您尽可能迁移到其它下载器上。https://github.com/PBH-BTN/PeerBanHelper/issues/382" +DOWNLOADER_QBITTORRENTEE_SHADOWBANAPI_TEST_FAILURE: "您正在使用普通版本 qBittorrent 或当前版本 qBittorrentEE 不支持 ShadowBan,请关闭 ShadowBan 开关。" + +DOWNLOADER_FAILED_REQUEST_STATISTICS: "获取下载器 {} 的统计数据信息失败: {}" \ No newline at end of file diff --git a/src/main/resources/lang/zh_cn/messages.yml b/src/main/resources/lang/zh_cn/messages.yml index 045b71254c..54367d8c00 100644 --- a/src/main/resources/lang/zh_cn/messages.yml +++ b/src/main/resources/lang/zh_cn/messages.yml @@ -363,4 +363,7 @@ PEER_NOT_FOUND: "指定的 Peer 记录不存在" IN_ECOMODE_SHORT: "🍃EcoQoS" IN_ECOMODE_DESCRIPTION: "EcoQoS API 加载成功,Windows 效率模式已应用至 PeerBanHelper 以降低系统能耗" -DOWNLOADER_TRANSMISSION_DISCOURAGE: "警告:Transmission 适配器已被废弃,不再推荐使用。在频繁发生封禁事件的种子上,频繁启停 Torrent 将导致对 Tracker 服务器的频繁更新,并间接引发 DoS 攻击,这会增加 Tracker 服务器压力并可能导致您的 IP 地址被 Tracker 服务器封禁。我们鼓励您尽可能迁移到其它下载器上。https://github.com/PBH-BTN/PeerBanHelper/issues/382" \ No newline at end of file +DOWNLOADER_TRANSMISSION_DISCOURAGE: "警告:Transmission 适配器已被废弃,不再推荐使用。在频繁发生封禁事件的种子上,频繁启停 Torrent 将导致对 Tracker 服务器的频繁更新,并间接引发 DoS 攻击,这会增加 Tracker 服务器压力并可能导致您的 IP 地址被 Tracker 服务器封禁。我们鼓励您尽可能迁移到其它下载器上。https://github.com/PBH-BTN/PeerBanHelper/issues/382" +DOWNLOADER_QBITTORRENTEE_SHADOWBANAPI_TEST_FAILURE: "您正在使用普通版本 qBittorrent 或当前版本 qBittorrentEE 不支持 ShadowBan,请关闭 ShadowBan 开关。" + +DOWNLOADER_FAILED_REQUEST_STATISTICS: "获取下载器 {} 的统计数据信息失败: {}" \ No newline at end of file diff --git a/src/main/resources/profile.yml b/src/main/resources/profile.yml index 037fe0ddb5..832dd1c8cf 100644 --- a/src/main/resources/profile.yml +++ b/src/main/resources/profile.yml @@ -1,4 +1,4 @@ -config-version: 17 +config-version: 18 # Check interval (Timeunit: ms) # 检查频率(单位:毫秒) check-interval: 5000 @@ -163,6 +163,15 @@ module: # 单位:ms 默认值:1209600000 (14 天) # Time unit: ms, default: 1209600000 (14 days) persist-duration: 1209600000 + # 封禁前最长等待时间 + # Max duration before ban + # 有时由于下载器网络原因,Peer 可能无法及时同步其进度信息 + # Sometimes due the network issue, the peer may cannot sync the progress information on time + # 当 Peer 达到封禁阈值后开始计时,如果 Peer 未在给定时间内更新自己的进度到正常水平,则将被封禁 + # When a Peer reached ban condition, the timer will start and Peer will be banned after timer timed out if Peer's progress not update to excepted value on time + # 注意:这不适用于进度回退和过量下载 + # Note: This not suitable for progress rewind or over-download + max-wait-duration: 30000 # IP 地址/端口 封禁 # IP address/port blacklist ip-address-blocker: @@ -189,7 +198,7 @@ module: # Banning ASN (Require config GeoIP-ASN database) asns: - "0" - # - 0 # 网络 ASN 好 + # - 0 # 网络 ASN 号 # 按国家或地区封禁(需要配置 GeoIP-City 数据库才能工作!) # Banning as Country/Region code regions: @@ -376,4 +385,4 @@ module: # 建议不要设置的太频繁,SQLite 是单线程数据库,无法同时执行多个 SQL 查询,慢查询可能导致 PBH 数据写入延迟/耗尽运行 RAM # Do not set it run too frequently # 时间单位:ms;默认值:604800000 (7 天); default: (7 days) - data-cleanup-interval: 604800000 \ No newline at end of file + data-cleanup-interval: 604800000 diff --git a/webui/.eslintrc.cjs b/webui/.eslintrc.cjs deleted file mode 100644 index 35a17d7464..0000000000 --- a/webui/.eslintrc.cjs +++ /dev/null @@ -1,18 +0,0 @@ -/* eslint-env node */ -require('@rushstack/eslint-patch/modern-module-resolution') - -module.exports = { - root: true, - 'extends': [ - 'plugin:vue/vue3-essential', - 'eslint:recommended', - '@vue/eslint-config-typescript', - '@vue/eslint-config-prettier/skip-formatting' - ], - parserOptions: { - ecmaVersion: 'latest' - }, - rules:{ - 'vue/multi-word-component-names': 0 - } -} diff --git a/webui/eslint.config.js b/webui/eslint.config.js new file mode 100644 index 0000000000..78a24d1d54 --- /dev/null +++ b/webui/eslint.config.js @@ -0,0 +1,35 @@ +import tsParser from '@typescript-eslint/parser' +import eslintConfigPrettier from 'eslint-config-prettier' +import pluginVue from 'eslint-plugin-vue' +import ts from 'typescript-eslint' + +export default [ + ...ts.configs.recommended, + ...pluginVue.configs['flat/recommended'], + eslintConfigPrettier, + { + files: ['**/*.ts', '**/*.js', '**/*.vue'], + languageOptions: { + parserOptions: { + parser: tsParser + } + }, + ignores: ['dist/*', 'node_modules/*'], + rules: { + 'vue/multi-word-component-names': 0, + 'vue/no-unused-vars': ['error', { ignorePattern: '^_' }], + '@typescript-eslint/no-unused-vars': [ + 'error', + { + args: 'all', + argsIgnorePattern: '^_', + caughtErrors: 'all', + caughtErrorsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + varsIgnorePattern: '^_', + ignoreRestSiblings: true + } + ] + } + } +] diff --git a/webui/package.json b/webui/package.json index 181706b412..4d207ed487 100644 --- a/webui/package.json +++ b/webui/package.json @@ -10,15 +10,15 @@ "build-only": "vite build", "analyze": "ANALYZE=true vite build", "type-check": "vue-tsc --build --force", - "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", + "lint": "prettier -c src/ && eslint . --ignore-pattern 'dist/*'", "format": "prettier --write src/" }, "dependencies": { - "@arco-design/web-vue": "^2.56.0", + "@arco-design/web-vue": "^2.56.1", "@dzangolab/flag-icon-css": "^3.4.5", "@octokit/core": "^6.1.2", "@octokit/request-error": "^6.1.4", - "@vueuse/core": "^11.0.1", + "@vueuse/core": "^11.0.3", "compare-versions": "^6.1.1", "copy-to-clipboard": "^3.3.3", "dayjs": "^1.11.13", @@ -29,7 +29,7 @@ "pinia": "^2.2.2", "url-join": "^5.0.0", "uuid": "^10.0.0", - "vue": "^3.4.38", + "vue": "^3.5.3", "vue-2048": "^3.0.5", "vue-echarts": "^7.0.3", "vue-i18n": "^9.14.0", @@ -38,28 +38,32 @@ }, "devDependencies": { "@arco-plugins/vite-vue": "^1.4.5", + "@eslint/js": "^9.9.1", "@rushstack/eslint-patch": "^1.10.4", "@tsconfig/node20": "^20.1.4", + "@types/eslint__js": "^8.42.3", "@types/lodash": "^4.17.7", "@types/mockjs": "^1.0.10", - "@types/node": "^22.4.2", + "@types/node": "^22.5.4", "@types/uuid": "^10.0.0", - "@vitejs/plugin-vue": "^5.1.2", - "@vue/eslint-config-prettier": "^9.0.0", - "@vue/eslint-config-typescript": "^13.0.0", + "@typescript-eslint/parser": "^8.4.0", + "@vitejs/plugin-vue": "^5.1.3", "@vue/tsconfig": "^0.5.1", - "eslint": "^8.57.0", - "eslint-plugin-vue": "^9.27.0", + "eslint": "^9.9.1", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-vue": "^9.28.0", "less": "^4.2.0", "mockjs": "^1.1.0", "npm-run-all2": "^6.2.2", "prettier": "^3.3.3", "typescript": "~5.5.4", - "vite": "^5.4.2", - "vite-bundle-analyzer": "^0.10.5", + "typescript-eslint": "^8.4.0", + "vite": "^5.4.3", + "vite-bundle-analyzer": "^0.10.6", "vite-plugin-node-polyfills": "^0.22.0", - "vite-plugin-vue-devtools": "^7.3.8", - "vue-tsc": "^2.0.29" + "vite-plugin-vue-devtools": "^7.4.4", + "vue-eslint-parser": "^9.4.3", + "vue-tsc": "^2.1.6" }, "engines": { "node": ">=20.0.0", diff --git a/webui/pnpm-lock.yaml b/webui/pnpm-lock.yaml index f8d34b6ee0..18ff3972ca 100644 --- a/webui/pnpm-lock.yaml +++ b/webui/pnpm-lock.yaml @@ -14,8 +14,8 @@ importers: .: dependencies: '@arco-design/web-vue': - specifier: ^2.56.0 - version: 2.56.1(vue@3.4.38(typescript@5.5.4)) + specifier: ^2.56.1 + version: 2.56.1(vue@3.5.3(typescript@5.5.4)) '@dzangolab/flag-icon-css': specifier: ^3.4.5 version: 3.4.5 @@ -26,8 +26,8 @@ importers: specifier: ^6.1.4 version: 6.1.4 '@vueuse/core': - specifier: ^11.0.1 - version: 11.0.1(vue@3.4.38(typescript@5.5.4)) + specifier: ^11.0.3 + version: 11.0.3(vue@3.5.3(typescript@5.5.4)) compare-versions: specifier: ^6.1.1 version: 6.1.1 @@ -51,7 +51,7 @@ importers: version: 8.0.1 pinia: specifier: ^2.2.2 - version: 2.2.2(typescript@5.5.4)(vue@3.4.38(typescript@5.5.4)) + version: 2.2.2(typescript@5.5.4)(vue@3.5.3(typescript@5.5.4)) url-join: specifier: ^5.0.0 version: 5.0.0 @@ -59,33 +59,39 @@ importers: specifier: ^10.0.0 version: 10.0.0 vue: - specifier: ^3.4.38 - version: 3.4.38(typescript@5.5.4) + specifier: ^3.5.3 + version: 3.5.3(typescript@5.5.4) vue-2048: specifier: ^3.0.5 - version: 3.0.5(typescript@5.5.4)(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8)) + version: 3.0.5(typescript@5.5.4)(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8)) vue-echarts: specifier: ^7.0.3 - version: 7.0.3(@vue/runtime-core@3.4.38)(echarts@5.5.1)(vue@3.4.38(typescript@5.5.4)) + version: 7.0.3(@vue/runtime-core@3.4.38)(echarts@5.5.1)(vue@3.5.3(typescript@5.5.4)) vue-i18n: specifier: ^9.14.0 - version: 9.14.0(vue@3.4.38(typescript@5.5.4)) + version: 9.14.0(vue@3.5.3(typescript@5.5.4)) vue-request: specifier: ^2.0.4 - version: 2.0.4(patch_hash=imva7qnbqmkxs76or73cwn5jom)(vue@3.4.38(typescript@5.5.4)) + version: 2.0.4(patch_hash=imva7qnbqmkxs76or73cwn5jom)(vue@3.5.3(typescript@5.5.4)) vue-router: specifier: ^4.4.3 - version: 4.4.3(vue@3.4.38(typescript@5.5.4)) + version: 4.4.3(vue@3.5.3(typescript@5.5.4)) devDependencies: '@arco-plugins/vite-vue': specifier: ^1.4.5 version: 1.4.5 + '@eslint/js': + specifier: ^9.9.1 + version: 9.9.1 '@rushstack/eslint-patch': specifier: ^1.10.4 version: 1.10.4 '@tsconfig/node20': specifier: ^20.1.4 version: 20.1.4 + '@types/eslint__js': + specifier: ^8.42.3 + version: 8.42.3 '@types/lodash': specifier: ^4.17.7 version: 4.17.7 @@ -93,29 +99,29 @@ importers: specifier: ^1.0.10 version: 1.0.10 '@types/node': - specifier: ^22.4.2 - version: 22.4.2 + specifier: ^22.5.4 + version: 22.5.4 '@types/uuid': specifier: ^10.0.0 version: 10.0.0 + '@typescript-eslint/parser': + specifier: ^8.4.0 + version: 8.4.0(eslint@9.9.1)(typescript@5.5.4) '@vitejs/plugin-vue': - specifier: ^5.1.2 - version: 5.1.2(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)) - '@vue/eslint-config-prettier': - specifier: ^9.0.0 - version: 9.0.0(eslint@8.57.0)(prettier@3.3.3) - '@vue/eslint-config-typescript': - specifier: ^13.0.0 - version: 13.0.0(eslint-plugin-vue@9.27.0(eslint@8.57.0))(eslint@8.57.0)(typescript@5.5.4) + specifier: ^5.1.3 + version: 5.1.3(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8))(vue@3.5.3(typescript@5.5.4)) '@vue/tsconfig': specifier: ^0.5.1 version: 0.5.1 eslint: - specifier: ^8.57.0 - version: 8.57.0 + specifier: ^9.9.1 + version: 9.9.1 + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@9.9.1) eslint-plugin-vue: - specifier: ^9.27.0 - version: 9.27.0(eslint@8.57.0) + specifier: ^9.28.0 + version: 9.28.0(eslint@9.9.1) less: specifier: ^4.2.0 version: 4.2.0 @@ -131,40 +137,46 @@ importers: typescript: specifier: ~5.5.4 version: 5.5.4 + typescript-eslint: + specifier: ^8.4.0 + version: 8.4.0(eslint@9.9.1)(typescript@5.5.4) vite: - specifier: ^5.4.2 - version: 5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8) + specifier: ^5.4.3 + version: 5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8) vite-bundle-analyzer: - specifier: ^0.10.5 + specifier: ^0.10.6 version: 0.10.6 vite-plugin-node-polyfills: specifier: ^0.22.0 - version: 0.22.0(rollup@4.21.0)(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8)) + version: 0.22.0(rollup@4.21.0)(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8)) vite-plugin-vue-devtools: - specifier: ^7.3.8 - version: 7.3.9(rollup@4.21.0)(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)) + specifier: ^7.4.4 + version: 7.4.4(rollup@4.21.0)(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8))(vue@3.5.3(typescript@5.5.4)) + vue-eslint-parser: + specifier: ^9.4.3 + version: 9.4.3(eslint@9.9.1) vue-tsc: - specifier: ^2.0.29 - version: 2.0.29(typescript@5.5.4) + specifier: ^2.1.6 + version: 2.1.6(typescript@5.5.4) packages: '@aashutoshrathi/word-wrap@1.2.6': - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==, tarball: https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz} engines: {node: '>=0.10.0'} '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==, tarball: https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz} engines: {node: '>=6.0.0'} '@antfu/utils@0.7.10': - resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==, tarball: https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz} '@arco-design/color@0.4.0': - resolution: {integrity: sha512-s7p9MSwJgHeL8DwcATaXvWT3m2SigKpxx4JA1BGPHL4gfvaQsmQfrLBDpjOJFJuJ2jG2dMt3R3P8Pm9E65q18g==} + resolution: {integrity: sha512-s7p9MSwJgHeL8DwcATaXvWT3m2SigKpxx4JA1BGPHL4gfvaQsmQfrLBDpjOJFJuJ2jG2dMt3R3P8Pm9E65q18g==, tarball: https://registry.npmjs.org/@arco-design/color/-/color-0.4.0.tgz} '@arco-design/web-vue@2.56.1': - resolution: {integrity: sha512-RHIG7DXpCJrpxCKXdxZMzsGvMPCUott57soXW3aHJfxOcf+I2rdX8/UTAt2ka5MyRLUZ4B90B1LKyUgLChGklg==} + resolution: {integrity: sha512-RHIG7DXpCJrpxCKXdxZMzsGvMPCUott57soXW3aHJfxOcf+I2rdX8/UTAt2ka5MyRLUZ4B90B1LKyUgLChGklg==, tarball: https://registry.npmjs.org/@arco-design/web-vue/-/web-vue-2.56.1.tgz} peerDependencies: vue: ^3.1.0 @@ -176,15 +188,15 @@ packages: engines: {node: '>=6.9.0'} '@babel/code-frame@7.24.7': - resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==, tarball: https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz} engines: {node: '>=6.9.0'} '@babel/compat-data@7.25.4': - resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==} + resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==, tarball: https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz} engines: {node: '>=6.9.0'} '@babel/core@7.25.2': - resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} + resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==, tarball: https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz} engines: {node: '>=6.9.0'} '@babel/generator@7.24.4': @@ -192,19 +204,19 @@ packages: engines: {node: '>=6.9.0'} '@babel/generator@7.25.5': - resolution: {integrity: sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==} + resolution: {integrity: sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==, tarball: https://registry.npmjs.org/@babel/generator/-/generator-7.25.5.tgz} engines: {node: '>=6.9.0'} '@babel/helper-annotate-as-pure@7.24.7': - resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} + resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==, tarball: https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz} engines: {node: '>=6.9.0'} '@babel/helper-compilation-targets@7.25.2': - resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} + resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==, tarball: https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz} engines: {node: '>=6.9.0'} '@babel/helper-create-class-features-plugin@7.25.4': - resolution: {integrity: sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==} + resolution: {integrity: sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==, tarball: https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -222,11 +234,11 @@ packages: engines: {node: '>=6.9.0'} '@babel/helper-member-expression-to-functions@7.24.8': - resolution: {integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==} + resolution: {integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==, tarball: https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz} engines: {node: '>=6.9.0'} '@babel/helper-module-imports@7.22.15': - resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==, tarball: https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz} engines: {node: '>=6.9.0'} '@babel/helper-module-imports@7.24.3': @@ -234,35 +246,35 @@ packages: engines: {node: '>=6.9.0'} '@babel/helper-module-imports@7.24.7': - resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==, tarball: https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz} engines: {node: '>=6.9.0'} '@babel/helper-module-transforms@7.25.2': - resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} + resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==, tarball: https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/helper-optimise-call-expression@7.24.7': - resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} + resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==, tarball: https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz} engines: {node: '>=6.9.0'} '@babel/helper-plugin-utils@7.24.8': - resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} + resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==, tarball: https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz} engines: {node: '>=6.9.0'} '@babel/helper-replace-supers@7.25.0': - resolution: {integrity: sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==} + resolution: {integrity: sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==, tarball: https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 '@babel/helper-simple-access@7.24.7': - resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==, tarball: https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz} engines: {node: '>=6.9.0'} '@babel/helper-skip-transparent-expression-wrappers@7.24.7': - resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} + resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==, tarball: https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz} engines: {node: '>=6.9.0'} '@babel/helper-split-export-declaration@7.22.6': @@ -274,7 +286,7 @@ packages: engines: {node: '>=6.9.0'} '@babel/helper-string-parser@7.24.8': - resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==, tarball: https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz} engines: {node: '>=6.9.0'} '@babel/helper-validator-identifier@7.22.20': @@ -282,15 +294,15 @@ packages: engines: {node: '>=6.9.0'} '@babel/helper-validator-identifier@7.24.7': - resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==, tarball: https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz} engines: {node: '>=6.9.0'} '@babel/helper-validator-option@7.24.8': - resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} + resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==, tarball: https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz} engines: {node: '>=6.9.0'} '@babel/helpers@7.25.0': - resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} + resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==, tarball: https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz} engines: {node: '>=6.9.0'} '@babel/highlight@7.24.2': @@ -298,7 +310,7 @@ packages: engines: {node: '>=6.9.0'} '@babel/highlight@7.24.7': - resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==, tarball: https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz} engines: {node: '>=6.9.0'} '@babel/parser@7.24.4': @@ -306,53 +318,48 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.24.7': - resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/parser@7.25.4': - resolution: {integrity: sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==} + resolution: {integrity: sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==, tarball: https://registry.npmjs.org/@babel/parser/-/parser-7.25.4.tgz} engines: {node: '>=6.0.0'} hasBin: true '@babel/plugin-proposal-decorators@7.24.7': - resolution: {integrity: sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==} + resolution: {integrity: sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==, tarball: https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.7.tgz} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-decorators@7.24.7': - resolution: {integrity: sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==} + resolution: {integrity: sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==, tarball: https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.7.tgz} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-import-attributes@7.24.7': - resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} + resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==, tarball: https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==, tarball: https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-jsx@7.24.7': - resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} + resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==, tarball: https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-syntax-typescript@7.25.4': - resolution: {integrity: sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==} + resolution: {integrity: sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==, tarball: https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 '@babel/plugin-transform-typescript@7.25.2': - resolution: {integrity: sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==} + resolution: {integrity: sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==, tarball: https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -362,7 +369,7 @@ packages: engines: {node: '>=6.9.0'} '@babel/template@7.25.0': - resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} + resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==, tarball: https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz} engines: {node: '>=6.9.0'} '@babel/traverse@7.24.1': @@ -370,7 +377,7 @@ packages: engines: {node: '>=6.9.0'} '@babel/traverse@7.25.4': - resolution: {integrity: sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==} + resolution: {integrity: sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==, tarball: https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.4.tgz} engines: {node: '>=6.9.0'} '@babel/types@7.24.0': @@ -378,146 +385,146 @@ packages: engines: {node: '>=6.9.0'} '@babel/types@7.25.4': - resolution: {integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==} + resolution: {integrity: sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==, tarball: https://registry.npmjs.org/@babel/types/-/types-7.25.4.tgz} engines: {node: '>=6.9.0'} '@dzangolab/flag-icon-css@3.4.5': resolution: {integrity: sha512-XqVAi0O/KITtznpMK5TP4D+rWfwst5lrsbPbes5c5SPMGjwK7fuvlTdEmG2XUrxzYqDTIPshywyzdVYKooGdGA==} '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==, tarball: https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz} engines: {node: '>=12'} cpu: [ppc64] os: [aix] '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==, tarball: https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [android] '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==, tarball: https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm] os: [android] '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==, tarball: https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [android] '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==, tarball: https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==, tarball: https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [darwin] '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==, tarball: https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==, tarball: https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [freebsd] '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==, tarball: https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==, tarball: https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==, tarball: https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz} engines: {node: '>=12'} cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==, tarball: https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz} engines: {node: '>=12'} cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==, tarball: https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz} engines: {node: '>=12'} cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==, tarball: https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz} engines: {node: '>=12'} cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==, tarball: https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz} engines: {node: '>=12'} cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==, tarball: https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz} engines: {node: '>=12'} cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==, tarball: https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [linux] '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==, tarball: https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [netbsd] '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==, tarball: https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [openbsd] '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==, tarball: https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [sunos] '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==, tarball: https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==, tarball: https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz} engines: {node: '>=12'} cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==, tarball: https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -528,30 +535,33 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.10.0': - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + '@eslint-community/regexpp@4.11.0': + resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==, tarball: https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/eslintrc@2.1.4': - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/config-array@0.18.0': + resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==, tarball: https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@8.57.0': - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==, tarball: https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.9.1': + resolution: {integrity: sha512-xIDQRsfg5hNBqHz04H1R3scSVwmI+KUbqjsQKHKQ1DAUSaUjYPReZZmS/5PNiKu1fUvzDd6H7DEDKACSEhu+TQ==, tarball: https://registry.npmjs.org/@eslint/js/-/js-9.9.1.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@humanwhocodes/config-array@0.11.14': - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} - engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==, tarball: https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==, tarball: https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz} engines: {node: '>=12.22'} - '@humanwhocodes/object-schema@2.0.3': - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - deprecated: Use @eslint/object-schema instead + '@humanwhocodes/retry@0.3.0': + resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==, tarball: https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz} + engines: {node: '>=18.18'} '@intlify/core-base@9.14.0': resolution: {integrity: sha512-zJn0imh9HIsZZUtt9v8T16PeVstPv6bP2YzlrYJwoF8F30gs4brZBwW2KK6EI5WYKFi3NeqX6+UU4gniz5TkGg==} @@ -581,7 +591,7 @@ packages: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==, tarball: https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz} '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} @@ -628,12 +638,8 @@ packages: '@octokit/types@13.5.0': resolution: {integrity: sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==} - '@pkgr/core@0.1.1': - resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@polka/url@1.0.0-next.25': - resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} + resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==, tarball: https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz} '@rollup/plugin-inject@5.0.5': resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} @@ -654,82 +660,82 @@ packages: optional: true '@rollup/rollup-android-arm-eabi@4.21.0': - resolution: {integrity: sha512-WTWD8PfoSAJ+qL87lE7votj3syLavxunWhzCnx3XFxFiI/BA/r3X7MUM8dVrH8rb2r4AiO8jJsr3ZjdaftmnfA==} + resolution: {integrity: sha512-WTWD8PfoSAJ+qL87lE7votj3syLavxunWhzCnx3XFxFiI/BA/r3X7MUM8dVrH8rb2r4AiO8jJsr3ZjdaftmnfA==, tarball: https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.0.tgz} cpu: [arm] os: [android] '@rollup/rollup-android-arm64@4.21.0': - resolution: {integrity: sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA==} + resolution: {integrity: sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA==, tarball: https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.0.tgz} cpu: [arm64] os: [android] '@rollup/rollup-darwin-arm64@4.21.0': - resolution: {integrity: sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA==} + resolution: {integrity: sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA==, tarball: https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.0.tgz} cpu: [arm64] os: [darwin] '@rollup/rollup-darwin-x64@4.21.0': - resolution: {integrity: sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg==} + resolution: {integrity: sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg==, tarball: https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.0.tgz} cpu: [x64] os: [darwin] '@rollup/rollup-linux-arm-gnueabihf@4.21.0': - resolution: {integrity: sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA==} + resolution: {integrity: sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.0.tgz} cpu: [arm] os: [linux] '@rollup/rollup-linux-arm-musleabihf@4.21.0': - resolution: {integrity: sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w==} + resolution: {integrity: sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.0.tgz} cpu: [arm] os: [linux] '@rollup/rollup-linux-arm64-gnu@4.21.0': - resolution: {integrity: sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w==} + resolution: {integrity: sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.0.tgz} cpu: [arm64] os: [linux] '@rollup/rollup-linux-arm64-musl@4.21.0': - resolution: {integrity: sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw==} + resolution: {integrity: sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.0.tgz} cpu: [arm64] os: [linux] '@rollup/rollup-linux-powerpc64le-gnu@4.21.0': - resolution: {integrity: sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg==} + resolution: {integrity: sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.0.tgz} cpu: [ppc64] os: [linux] '@rollup/rollup-linux-riscv64-gnu@4.21.0': - resolution: {integrity: sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg==} + resolution: {integrity: sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.0.tgz} cpu: [riscv64] os: [linux] '@rollup/rollup-linux-s390x-gnu@4.21.0': - resolution: {integrity: sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw==} + resolution: {integrity: sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.0.tgz} cpu: [s390x] os: [linux] '@rollup/rollup-linux-x64-gnu@4.21.0': - resolution: {integrity: sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg==} + resolution: {integrity: sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.0.tgz} cpu: [x64] os: [linux] '@rollup/rollup-linux-x64-musl@4.21.0': - resolution: {integrity: sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ==} + resolution: {integrity: sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.0.tgz} cpu: [x64] os: [linux] '@rollup/rollup-win32-arm64-msvc@4.21.0': - resolution: {integrity: sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ==} + resolution: {integrity: sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.0.tgz} cpu: [arm64] os: [win32] '@rollup/rollup-win32-ia32-msvc@4.21.0': - resolution: {integrity: sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg==} + resolution: {integrity: sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.0.tgz} cpu: [ia32] os: [win32] '@rollup/rollup-win32-x64-msvc@4.21.0': - resolution: {integrity: sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ==} + resolution: {integrity: sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.0.tgz} cpu: [x64] os: [win32] @@ -739,11 +745,17 @@ packages: '@tsconfig/node20@20.1.4': resolution: {integrity: sha512-sqgsT69YFeLWf5NtJ4Xq/xAF8p4ZQHlmGW74Nu2tD4+g5fAsposc4ZfaaPixVu4y01BEiDCWLRDCvDM5JOsRxg==} + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==, tarball: https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz} + + '@types/eslint__js@8.42.3': + resolution: {integrity: sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==, tarball: https://registry.npmjs.org/@types/eslint__js/-/eslint__js-8.42.3.tgz} + '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==, tarball: https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz} '@types/lodash@4.17.7': resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==} @@ -752,102 +764,95 @@ packages: resolution: {integrity: sha512-SXgrhajHG7boLv6oU93CcmdDm0HYRiceuz6b+7z+/2lCJPTWDv0V5YiwFHT2ejE4bQqgSXQiVPQYPWv7LGsK1g==} '@types/node@16.18.101': - resolution: {integrity: sha512-AAsx9Rgz2IzG8KJ6tXd6ndNkVcu+GYB6U/SnFAaokSPNx2N7dcIIfnighYUNumvj6YS2q39Dejz5tT0NCV7CWA==} - - '@types/node@22.4.2': - resolution: {integrity: sha512-nAvM3Ey230/XzxtyDcJ+VjvlzpzoHwLsF7JaDRfoI0ytO0mVheerNmM45CtA0yOILXwXXxOrcUWH3wltX+7PSw==} + resolution: {integrity: sha512-AAsx9Rgz2IzG8KJ6tXd6ndNkVcu+GYB6U/SnFAaokSPNx2N7dcIIfnighYUNumvj6YS2q39Dejz5tT0NCV7CWA==, tarball: https://registry.npmjs.org/@types/node/-/node-16.18.101.tgz} - '@types/semver@7.5.8': - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + '@types/node@22.5.4': + resolution: {integrity: sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==, tarball: https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz} '@types/uuid@10.0.0': resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} '@types/web-bluetooth@0.0.20': - resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==, tarball: https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz} - '@typescript-eslint/eslint-plugin@7.7.0': - resolution: {integrity: sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/eslint-plugin@8.4.0': + resolution: {integrity: sha512-rg8LGdv7ri3oAlenMACk9e+AR4wUV0yrrG+XKsGKOK0EVgeEDqurkXMPILG2836fW4ibokTB5v4b6Z9+GYQDEw==, tarball: https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.4.0.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/parser@7.7.0': - resolution: {integrity: sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/parser@8.4.0': + resolution: {integrity: sha512-NHgWmKSgJk5K9N16GIhQ4jSobBoJwrmURaLErad0qlLjrpP5bECYg+wxVTGlGZmJbU03jj/dfnb6V9bw+5icsA==, tarball: https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.4.0.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/scope-manager@7.7.0': - resolution: {integrity: sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/scope-manager@8.4.0': + resolution: {integrity: sha512-n2jFxLeY0JmKfUqy3P70rs6vdoPjHK8P/w+zJcV3fk0b0BwRXC/zxRTEnAsgYT7MwdQDt/ZEbtdzdVC+hcpF0A==, tarball: https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.4.0.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@7.7.0': - resolution: {integrity: sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/type-utils@8.4.0': + resolution: {integrity: sha512-pu2PAmNrl9KX6TtirVOrbLPLwDmASpZhK/XU7WvoKoCUkdtq9zF7qQ7gna0GBZFN0hci0vHaSusiL2WpsQk37A==, tarball: https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.4.0.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/types@7.7.0': - resolution: {integrity: sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/types@8.4.0': + resolution: {integrity: sha512-T1RB3KQdskh9t3v/qv7niK6P8yvn7ja1mS7QK7XfRVL6wtZ8/mFs/FHf4fKvTA0rKnqnYxl/uHFNbnEt0phgbw==, tarball: https://registry.npmjs.org/@typescript-eslint/types/-/types-8.4.0.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@7.7.0': - resolution: {integrity: sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/typescript-estree@8.4.0': + resolution: {integrity: sha512-kJ2OIP4dQw5gdI4uXsaxUZHRwWAGpREJ9Zq6D5L0BweyOrWsL6Sz0YcAZGWhvKnH7fm1J5YFE1JrQL0c9dd53A==, tarball: https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.4.0.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/utils@7.7.0': - resolution: {integrity: sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/utils@8.4.0': + resolution: {integrity: sha512-swULW8n1IKLjRAgciCkTCafyTHHfwVQFt8DovmaF69sKbOxTSFMmIZaSHjqO9i/RV0wIblaawhzvtva8Nmm7lQ==, tarball: https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.4.0.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 - '@typescript-eslint/visitor-keys@7.7.0': - resolution: {integrity: sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/visitor-keys@8.4.0': + resolution: {integrity: sha512-zTQD6WLNTre1hj5wp09nBIDiOc2U5r/qmzo7wxPn4ZgAjHql09EofqhF9WF+fZHzL5aCyaIpPcT2hyxl73kr9A==, tarball: https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.4.0.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@ungap/structured-clone@1.2.0': - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - - '@vitejs/plugin-vue@5.1.2': - resolution: {integrity: sha512-nY9IwH12qeiJqumTCLJLE7IiNx7HZ39cbHaysEUd+Myvbz9KAqd2yq+U01Kab1R/H1BmiyM2ShTYlNH32Fzo3A==} + '@vitejs/plugin-vue@5.1.3': + resolution: {integrity: sha512-3xbWsKEKXYlmX82aOHufFQVnkbMC/v8fLpWwh6hWOUrK5fbbtBh9Q/WWse27BFgSy2/e2c0fz5Scgya9h2GLhw==, tarball: https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.3.tgz} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: vite: ^5.0.0 vue: ^3.2.25 - '@volar/language-core@2.4.0-alpha.18': - resolution: {integrity: sha512-JAYeJvYQQROmVRtSBIczaPjP3DX4QW1fOqW1Ebs0d3Y3EwSNRglz03dSv0Dm61dzd0Yx3WgTW3hndDnTQqgmyg==} + '@volar/language-core@2.4.2': + resolution: {integrity: sha512-sONt5RLvLL1SlBdhyUSthZzuKePbJ7DwFFB9zT0eyWpDl+v7GXGh/RkPxxWaR22bIhYtTzp4Ka1MWatl/53Riw==, tarball: https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.2.tgz} - '@volar/source-map@2.4.0-alpha.18': - resolution: {integrity: sha512-MTeCV9MUwwsH0sNFiZwKtFrrVZUK6p8ioZs3xFzHc2cvDXHWlYN3bChdQtwKX+FY2HG6H3CfAu1pKijolzIQ8g==} + '@volar/source-map@2.4.2': + resolution: {integrity: sha512-qiGfGgeZ5DEarPX3S+HcFktFCjfDrFPCXKeXNbrlB7v8cvtPRm8YVwoXOdGG1NhaL5rMlv5BZPVQyu4EdWWIvA==, tarball: https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.2.tgz} - '@volar/typescript@2.4.0-alpha.18': - resolution: {integrity: sha512-sXh5Y8sqGUkgxpMWUGvRXggxYHAVxg0Pa1C42lQZuPDrW6vHJPR0VCK8Sr7WJsAW530HuNQT/ZIskmXtxjybMQ==} + '@volar/typescript@2.4.2': + resolution: {integrity: sha512-m2uZduhaHO1SZuagi30OsjI/X1gwkaEAC+9wT/nCNAtJ5FqXEkKvUncHmffG7ESDZPlFFUBK4vJ0D9Hfr+f2EA==, tarball: https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.2.tgz} '@vue/babel-helper-vue-transform-on@1.2.2': - resolution: {integrity: sha512-nOttamHUR3YzdEqdM/XXDyCSdxMA9VizUKoroLX6yTyRtggzQMHXcmwh8a7ZErcJttIBIc9s68a1B8GZ+Dmvsw==} + resolution: {integrity: sha512-nOttamHUR3YzdEqdM/XXDyCSdxMA9VizUKoroLX6yTyRtggzQMHXcmwh8a7ZErcJttIBIc9s68a1B8GZ+Dmvsw==, tarball: https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.2.2.tgz} '@vue/babel-plugin-jsx@1.2.2': - resolution: {integrity: sha512-nYTkZUVTu4nhP199UoORePsql0l+wj7v/oyQjtThUVhJl1U+6qHuoVhIvR3bf7eVKjbCK+Cs2AWd7mi9Mpz9rA==} + resolution: {integrity: sha512-nYTkZUVTu4nhP199UoORePsql0l+wj7v/oyQjtThUVhJl1U+6qHuoVhIvR3bf7eVKjbCK+Cs2AWd7mi9Mpz9rA==, tarball: https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.2.2.tgz} peerDependencies: '@babel/core': ^7.0.0-0 peerDependenciesMeta: @@ -855,58 +860,53 @@ packages: optional: true '@vue/babel-plugin-resolve-type@1.2.2': - resolution: {integrity: sha512-EntyroPwNg5IPVdUJupqs0CFzuf6lUrVvCspmv2J1FITLeGnUCuoGNNk78dgCusxEiYj6RMkTJflGSxk5aIC4A==} + resolution: {integrity: sha512-EntyroPwNg5IPVdUJupqs0CFzuf6lUrVvCspmv2J1FITLeGnUCuoGNNk78dgCusxEiYj6RMkTJflGSxk5aIC4A==, tarball: https://registry.npmjs.org/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.2.2.tgz} peerDependencies: '@babel/core': ^7.0.0-0 '@vue/compiler-core@3.4.38': - resolution: {integrity: sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==} + resolution: {integrity: sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==, tarball: https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.38.tgz} + + '@vue/compiler-core@3.5.3': + resolution: {integrity: sha512-adAfy9boPkP233NTyvLbGEqVuIfK/R0ZsBsIOW4BZNfb4BRpRW41Do1u+ozJpsb+mdoy80O20IzAsHaihRb5qA==, tarball: https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.3.tgz} '@vue/compiler-dom@3.4.38': - resolution: {integrity: sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==} + resolution: {integrity: sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==, tarball: https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.38.tgz} + + '@vue/compiler-dom@3.5.3': + resolution: {integrity: sha512-wnzFArg9zpvk/811CDOZOadJRugf1Bgl/TQ3RfV4nKfSPok4hi0w10ziYUQR6LnnBAUlEXYLUfZ71Oj9ds/+QA==, tarball: https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.3.tgz} '@vue/compiler-sfc@3.4.38': - resolution: {integrity: sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==} + resolution: {integrity: sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==, tarball: https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.38.tgz} + + '@vue/compiler-sfc@3.5.3': + resolution: {integrity: sha512-P3uATLny2tfyvMB04OQFe7Sczteno7SLFxwrOA/dw01pBWQHB5HL15a8PosoNX2aG/EAMGqnXTu+1LnmzFhpTQ==, tarball: https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.3.tgz} '@vue/compiler-ssr@3.4.38': - resolution: {integrity: sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==} + resolution: {integrity: sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==, tarball: https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.38.tgz} + + '@vue/compiler-ssr@3.5.3': + resolution: {integrity: sha512-F/5f+r2WzL/2YAPl7UlKcJWHrvoZN8XwEBLnT7S4BXwncH25iDOabhO2M2DWioyTguJAGavDOawejkFXj8EM1w==, tarball: https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.3.tgz} '@vue/compiler-vue2@2.7.16': - resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==, tarball: https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz} '@vue/devtools-api@6.6.3': resolution: {integrity: sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw==} - '@vue/devtools-core@7.3.9': - resolution: {integrity: sha512-B5zAl9ulNjI6nknSnGNRzmP/ldR9ADUwwT8HkI8Hejo1W00uK9ABUahbfrXzME296rBfmwhQuCFwJ6t9KFdbXQ==} + '@vue/devtools-core@7.4.4': + resolution: {integrity: sha512-DLxgA3DfeADkRzhAfm3G2Rw/cWxub64SdP5b+s5dwL30+whOGj+QNhmyFpwZ8ZTrHDFRIPj0RqNzJ8IRR1pz7w==, tarball: https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.4.4.tgz} peerDependencies: vue: ^3.0.0 - '@vue/devtools-kit@7.3.9': - resolution: {integrity: sha512-Gr17nA+DaQzqyhNx1DUJr1CJRzTRfbIuuC80ZgU8MD/qNO302tv9la+ROi+Uaw+ULVwU9T71GnwLy4n8m9Lspg==} - - '@vue/devtools-shared@7.3.9': - resolution: {integrity: sha512-CdfMRZKXyI8vw+hqOcQIiLihB6Hbbi7WNZGp7LsuH1Qe4aYAFmTaKjSciRZ301oTnwmU/knC/s5OGuV6UNiNoA==} + '@vue/devtools-kit@7.4.4': + resolution: {integrity: sha512-awK/4NfsUG0nQ7qnTM37m7ZkEUMREyPh8taFCX+uQYps/MTFEum0AD05VeGDRMXwWvMmGIcWX9xp8ZiBddY0jw==, tarball: https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.4.4.tgz} - '@vue/eslint-config-prettier@9.0.0': - resolution: {integrity: sha512-z1ZIAAUS9pKzo/ANEfd2sO+v2IUalz7cM/cTLOZ7vRFOPk5/xuRKQteOu1DErFLAh/lYGXMVZ0IfYKlyInuDVg==} - peerDependencies: - eslint: '>= 8.0.0' - prettier: '>= 3.0.0' + '@vue/devtools-shared@7.4.4': + resolution: {integrity: sha512-yeJULXFHOKIm8yL2JFO050a9ztTVqOCKTqN9JHFxGTJN0b+gjtfn6zC+FfyHUgjwCwf6E3hfKrlohtthcqoYqw==, tarball: https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.4.4.tgz} - '@vue/eslint-config-typescript@13.0.0': - resolution: {integrity: sha512-MHh9SncG/sfqjVqjcuFLOLD6Ed4dRAis4HNt0dXASeAuLqIAx4YMB1/m2o4pUKK1vCt8fUvYG8KKX2Ot3BVZTg==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - eslint-plugin-vue: ^9.0.0 - typescript: '>=4.7.4' - peerDependenciesMeta: - typescript: - optional: true - - '@vue/language-core@2.0.29': - resolution: {integrity: sha512-o2qz9JPjhdoVj8D2+9bDXbaI4q2uZTHQA/dbyZT4Bj1FR9viZxDJnLcKVHfxdn6wsOzRgpqIzJEEmSSvgMvDTQ==} + '@vue/language-core@2.1.6': + resolution: {integrity: sha512-MW569cSky9R/ooKMh6xa2g1D0AtRKbL56k83dzus/bx//RDJk24RHWkMzbAlXjMdDNyxAaagKPRquBIxkxlCkg==, tarball: https://registry.npmjs.org/@vue/language-core/-/language-core-2.1.6.tgz} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -914,49 +914,58 @@ packages: optional: true '@vue/reactivity@3.4.38': - resolution: {integrity: sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==} + resolution: {integrity: sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==, tarball: https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.38.tgz} + + '@vue/reactivity@3.5.3': + resolution: {integrity: sha512-2w61UnRWTP7+rj1H/j6FH706gRBHdFVpIqEkSDAyIpafBXYH8xt4gttstbbCWdU3OlcSWO8/3mbKl/93/HSMpw==, tarball: https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.3.tgz} '@vue/runtime-core@3.4.38': - resolution: {integrity: sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==} + resolution: {integrity: sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==, tarball: https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.38.tgz} - '@vue/runtime-dom@3.4.38': - resolution: {integrity: sha512-afZzmUreU7vKwKsV17H1NDThEEmdYI+GCAK/KY1U957Ig2NATPVjCROv61R19fjZNzMmiU03n79OMnXyJVN0UA==} + '@vue/runtime-core@3.5.3': + resolution: {integrity: sha512-5b2AQw5OZlmCzSsSBWYoZOsy75N4UdMWenTfDdI5bAzXnuVR7iR8Q4AOzQm2OGoA41xjk53VQKrqQhOz2ktWaw==, tarball: https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.3.tgz} - '@vue/server-renderer@3.4.38': - resolution: {integrity: sha512-NggOTr82FbPEkkUvBm4fTGcwUY8UuTsnWC/L2YZBmvaQ4C4Jl/Ao4HHTB+l7WnFCt5M/dN3l0XLuyjzswGYVCA==} + '@vue/runtime-dom@3.5.3': + resolution: {integrity: sha512-wPR1DEGc3XnQ7yHbmkTt3GoY0cEnVGQnARRdAkDzZ8MbUKEs26gogCQo6AOvvgahfjIcnvWJzkZArQ1fmWjcSg==, tarball: https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.3.tgz} + + '@vue/server-renderer@3.5.3': + resolution: {integrity: sha512-28volmaZVG2PGO3V3+gBPKoSHvLlE8FGfG/GKXKkjjfxLuj/50B/0OQGakM/g6ehQeqCrZYM4eHC4Ks48eig1Q==, tarball: https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.3.tgz} peerDependencies: - vue: 3.4.38 + vue: 3.5.3 '@vue/shared@3.4.38': - resolution: {integrity: sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==} + resolution: {integrity: sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==, tarball: https://registry.npmjs.org/@vue/shared/-/shared-3.4.38.tgz} + + '@vue/shared@3.5.3': + resolution: {integrity: sha512-Jp2v8nylKBT+PlOUjun2Wp/f++TfJVFjshLzNtJDdmFJabJa7noGMncqXRM1vXGX+Yo2V7WykQFNxusSim8SCA==, tarball: https://registry.npmjs.org/@vue/shared/-/shared-3.5.3.tgz} '@vue/tsconfig@0.5.1': resolution: {integrity: sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==} - '@vueuse/core@11.0.1': - resolution: {integrity: sha512-YTrekI18WwEyP3h168Fir94G/HNC27wvXJI21Alm0sPOwvhihfkrvHIe+5PNJq+MpgWdRcsjvE/38JaoKrgZhQ==} + '@vueuse/core@11.0.3': + resolution: {integrity: sha512-RENlh64+SYA9XMExmmH1a3TPqeIuJBNNB/63GT35MZI+zpru3oMRUA6cEFr9HmGqEgUisurwGwnIieF6qu3aXw==, tarball: https://registry.npmjs.org/@vueuse/core/-/core-11.0.3.tgz} - '@vueuse/metadata@11.0.1': - resolution: {integrity: sha512-dTFvuHFAjLYOiSd+t9Sk7xUiuL6jbfay/eX+g+jaipXXlwKur2VCqBCZX+jfu+2vROUGcUsdn3fJR9KkpadIOg==} + '@vueuse/metadata@11.0.3': + resolution: {integrity: sha512-+FtbO4SD5WpsOcQTcC0hAhNlOid6QNLzqedtquTtQ+CRNBoAt9GuV07c6KNHK1wCmlq8DFPwgiLF2rXwgSHX5Q==, tarball: https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.0.3.tgz} - '@vueuse/shared@11.0.1': - resolution: {integrity: sha512-eAPf5CQB3HR0S76HqrhjBqFYstZfiHWZq8xF9EQmobGBkrhPfErJEhr8aMNQMqd6MkENIx2pblIEfJGlHpClug==} + '@vueuse/shared@11.0.3': + resolution: {integrity: sha512-0rY2m6HS5t27n/Vp5cTDsKTlNnimCqsbh/fmT2LgE+aaU42EMfXo8+bNX91W9I7DDmxfuACXMmrd7d79JxkqWA==, tarball: https://registry.npmjs.org/@vueuse/shared/-/shared-11.0.3.tgz} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==, tarball: https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz} engines: {node: '>=0.4.0'} hasBin: true ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==, tarball: https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz} ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, tarball: https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz} engines: {node: '>=8'} ansi-styles@3.2.1: @@ -964,7 +973,7 @@ packages: engines: {node: '>=4'} ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, tarball: https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz} engines: {node: '>=8'} ansi-styles@6.2.1: @@ -972,15 +981,11 @@ packages: engines: {node: '>=12'} anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, tarball: https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz} engines: {node: '>= 8'} argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, tarball: https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz} asn1.js@4.10.1: resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} @@ -993,10 +998,10 @@ packages: engines: {node: '>= 0.4'} b-tween@0.3.3: - resolution: {integrity: sha512-oEHegcRpA7fAuc9KC4nktucuZn2aS8htymCPcP3qkEGPqiBH+GfqtqoG2l7LxHngg6O0HFM7hOeOYExl1Oz4ZA==} + resolution: {integrity: sha512-oEHegcRpA7fAuc9KC4nktucuZn2aS8htymCPcP3qkEGPqiBH+GfqtqoG2l7LxHngg6O0HFM7hOeOYExl1Oz4ZA==, tarball: https://registry.npmjs.org/b-tween/-/b-tween-0.3.3.tgz} b-validate@1.5.3: - resolution: {integrity: sha512-iCvCkGFskbaYtfQ0a3GmcQCHl/Sv1GufXFGuUQ+FE+WJa7A/espLOuFIn09B944V8/ImPj71T4+rTASxO2PAuA==} + resolution: {integrity: sha512-iCvCkGFskbaYtfQ0a3GmcQCHl/Sv1GufXFGuUQ+FE+WJa7A/espLOuFIn09B944V8/ImPj71T4+rTASxO2PAuA==, tarball: https://registry.npmjs.org/b-validate/-/b-validate-1.5.3.tgz} balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1008,11 +1013,11 @@ packages: resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==, tarball: https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz} engines: {node: '>=8'} birpc@0.2.17: - resolution: {integrity: sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg==} + resolution: {integrity: sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg==, tarball: https://registry.npmjs.org/birpc/-/birpc-0.2.17.tgz} bn.js@4.12.0: resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} @@ -1021,20 +1026,16 @@ packages: resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==, tarball: https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz} brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, tarball: https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz} brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, tarball: https://registry.npmjs.org/braces/-/braces-3.0.3.tgz} engines: {node: '>=8'} brorand@1.1.0: @@ -1063,7 +1064,7 @@ packages: resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} browserslist@4.23.3: - resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==, tarball: https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1077,7 +1078,7 @@ packages: resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} bundle-name@4.1.0: - resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==, tarball: https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz} engines: {node: '>=18'} call-bind@1.0.7: @@ -1085,26 +1086,26 @@ packages: engines: {node: '>= 0.4'} callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, tarball: https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz} engines: {node: '>=6'} camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==, tarball: https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz} engines: {node: '>=10'} caniuse-lite@1.0.30001653: - resolution: {integrity: sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==} + resolution: {integrity: sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==, tarball: https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz} chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, tarball: https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz} engines: {node: '>=10'} chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==, tarball: https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz} engines: {node: '>= 8.10.0'} cipher-base@1.0.4: @@ -1114,7 +1115,7 @@ packages: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, tarball: https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz} engines: {node: '>=7.0.0'} color-name@1.1.3: @@ -1124,10 +1125,10 @@ packages: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==, tarball: https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz} color@3.2.1: - resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==, tarball: https://registry.npmjs.org/color/-/color-3.2.1.tgz} commander@12.0.0: resolution: {integrity: sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==} @@ -1137,13 +1138,13 @@ packages: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} compute-scroll-into-view@1.0.20: - resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==} + resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==, tarball: https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz} computeds@0.0.1: - resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} + resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==, tarball: https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz} concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, tarball: https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz} console-browserify@1.2.0: resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} @@ -1152,13 +1153,13 @@ packages: resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, tarball: https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz} copy-anything@2.0.6: resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} copy-anything@3.0.5: - resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==, tarball: https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz} engines: {node: '>=12.13'} copy-to-clipboard@3.3.3: @@ -1187,18 +1188,18 @@ packages: resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==, tarball: https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz} engines: {node: '>=4'} hasBin: true csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==, tarball: https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz} dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} de-indent@1.0.2: - resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==, tarball: https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz} debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} @@ -1209,17 +1210,8 @@ packages: supports-color: optional: true - debug@4.3.5: - resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.3.6: - resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==, tarball: https://registry.npmjs.org/debug/-/debug-4.3.6.tgz} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1228,14 +1220,14 @@ packages: optional: true deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, tarball: https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz} default-browser-id@5.0.0: - resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==, tarball: https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz} engines: {node: '>=18'} default-browser@5.2.1: - resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==, tarball: https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz} engines: {node: '>=18'} define-data-property@1.1.4: @@ -1243,7 +1235,7 @@ packages: engines: {node: '>= 0.4'} define-lazy-prop@3.0.0: - resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==, tarball: https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz} engines: {node: '>=12'} define-properties@1.2.1: @@ -1256,14 +1248,6 @@ packages: diffie-hellman@5.0.3: resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - - doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - domain-browser@4.23.0: resolution: {integrity: sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==} engines: {node: '>=10'} @@ -1272,21 +1256,21 @@ packages: resolution: {integrity: sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==} electron-to-chromium@1.5.13: - resolution: {integrity: sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==} + resolution: {integrity: sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==, tarball: https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz} elliptic@6.5.5: resolution: {integrity: sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==} entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==, tarball: https://registry.npmjs.org/entities/-/entities-4.5.0.tgz} engines: {node: '>=0.12'} errno@0.1.8: - resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} + resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==, tarball: https://registry.npmjs.org/errno/-/errno-0.1.8.tgz} hasBin: true error-stack-parser-es@0.1.5: - resolution: {integrity: sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==} + resolution: {integrity: sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==, tarball: https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-0.1.5.tgz} es-define-property@1.0.0: resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} @@ -1297,12 +1281,12 @@ packages: engines: {node: '>= 0.4'} esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==, tarball: https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz} engines: {node: '>=12'} hasBin: true escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==, tarball: https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz} engines: {node: '>=6'} escape-string-regexp@1.0.5: @@ -1310,56 +1294,55 @@ packages: engines: {node: '>=0.8.0'} escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, tarball: https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz} engines: {node: '>=10'} eslint-config-prettier@9.1.0: - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==, tarball: https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz} hasBin: true peerDependencies: eslint: '>=7.0.0' - eslint-plugin-prettier@5.1.3: - resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '*' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true - - eslint-plugin-vue@9.27.0: - resolution: {integrity: sha512-5Dw3yxEyuBSXTzT5/Ge1X5kIkRTQ3nvBn/VwPwInNiZBSJOO/timWMUaflONnFBzU6NhB68lxnCda7ULV5N7LA==} + eslint-plugin-vue@9.28.0: + resolution: {integrity: sha512-ShrihdjIhOTxs+MfWun6oJWuk+g/LAhN+CiuOl/jjkG3l0F2AuK5NMTaWqyvBgkFtpYmyks6P4603mLmhNJW8g==, tarball: https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.28.0.tgz} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==, tarball: https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-scope@8.0.2: + resolution: {integrity: sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==, tarball: https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint@8.57.0: - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-visitor-keys@4.0.0: + resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==, tarball: https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.9.1: + resolution: {integrity: sha512-dHvhrbfr4xFQ9/dq+jcVneZMyRYLjggWjk6RVsIiHsP8Rz6yZ8LvZ//iU4TrZF+SXWG+JkNF2OyiZRvzgRDqMg==, tarball: https://registry.npmjs.org/eslint/-/eslint-9.9.1.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.1.0: + resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==, tarball: https://registry.npmjs.org/espree/-/espree-10.1.0.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==, tarball: https://registry.npmjs.org/espree/-/espree-9.6.1.tgz} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} - esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} @@ -1376,7 +1359,7 @@ packages: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, tarball: https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz} engines: {node: '>=0.10.0'} events@3.3.0: @@ -1387,63 +1370,53 @@ packages: resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==, tarball: https://registry.npmjs.org/execa/-/execa-8.0.1.tgz} engines: {node: '>=16.17'} fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, tarball: https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz} fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==, tarball: https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz} engines: {node: '>=8.6.0'} fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, tarball: https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz} fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==, tarball: https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz} fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - - fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==, tarball: https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz} + engines: {node: '>=16.0.0'} fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, tarball: https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz} engines: {node: '>=8'} find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==, tarball: https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz} + engines: {node: '>=16'} flatted@3.3.1: - resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==, tarball: https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz} for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==, tarball: https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz} engines: {node: '>=14.14'} - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] @@ -1451,7 +1424,7 @@ packages: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, tarball: https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz} engines: {node: '>=6.9.0'} get-intrinsic@1.2.4: @@ -1459,48 +1432,44 @@ packages: engines: {node: '>= 0.4'} get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==, tarball: https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz} engines: {node: '>=16'} glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, tarball: https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz} engines: {node: '>= 6'} glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==, tarball: https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz} engines: {node: '>=10.13.0'} - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported - globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==, tarball: https://registry.npmjs.org/globals/-/globals-13.24.0.tgz} engines: {node: '>=8'} - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==, tarball: https://registry.npmjs.org/globals/-/globals-14.0.0.tgz} + engines: {node: '>=18'} gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, tarball: https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz} graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==, tarball: https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz} has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, tarball: https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz} engines: {node: '>=8'} has-property-descriptors@1.0.2: @@ -1534,24 +1503,24 @@ packages: engines: {node: '>= 0.4'} he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==, tarball: https://registry.npmjs.org/he/-/he-1.2.0.tgz} hasBin: true hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} hookable@5.5.3: - resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==, tarball: https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz} html-tags@3.3.1: - resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==, tarball: https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz} engines: {node: '>=8'} https-browserify@1.0.0: resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==} human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==, tarball: https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz} engines: {node: '>=16.17.0'} iconv-lite@0.6.3: @@ -1566,25 +1535,21 @@ packages: engines: {node: '>= 4'} image-size@0.5.5: - resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} + resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==, tarball: https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz} engines: {node: '>=0.10.0'} hasBin: true immutable@4.3.7: - resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} + resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==, tarball: https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz} import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==, tarball: https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz} engines: {node: '>=6'} imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, tarball: https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz} engines: {node: '>=0.8.19'} - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -1593,10 +1558,10 @@ packages: engines: {node: '>= 0.4'} is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==, tarball: https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz} is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, tarball: https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz} engines: {node: '>=8'} is-callable@1.2.7: @@ -1607,7 +1572,7 @@ packages: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==, tarball: https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} hasBin: true @@ -1624,7 +1589,7 @@ packages: engines: {node: '>=0.10.0'} is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==, tarball: https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz} engines: {node: '>=14.16'} hasBin: true @@ -1633,15 +1598,15 @@ packages: engines: {node: '>= 0.4'} is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, tarball: https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz} engines: {node: '>=0.12.0'} is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==, tarball: https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz} engines: {node: '>=8'} is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==, tarball: https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} is-typed-array@1.1.13: @@ -1652,11 +1617,11 @@ packages: resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} is-what@4.1.16: - resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==, tarball: https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz} engines: {node: '>=12.13'} is-wsl@3.1.0: - resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==, tarball: https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz} engines: {node: '>=16'} isarray@1.0.0: @@ -1673,7 +1638,7 @@ packages: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==, tarball: https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz} hasBin: true jsesc@2.5.2: @@ -1682,31 +1647,31 @@ packages: hasBin: true json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==, tarball: https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz} json-parse-even-better-errors@3.0.2: resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==, tarball: https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz} json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==, tarball: https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz} json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, tarball: https://registry.npmjs.org/json5/-/json5-2.2.3.tgz} engines: {node: '>=6'} hasBin: true jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==, tarball: https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz} keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==, tarball: https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz} kolorist@1.8.0: - resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==, tarball: https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz} less@4.2.0: resolution: {integrity: sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==} @@ -1714,7 +1679,7 @@ packages: hasBin: true levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==, tarball: https://registry.npmjs.org/levn/-/levn-0.4.1.tgz} engines: {node: '>= 0.8.0'} locate-path@6.0.0: @@ -1722,26 +1687,23 @@ packages: engines: {node: '>=10'} lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, tarball: https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz} lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - - magic-string@0.30.10: - resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, tarball: https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz} magic-string@0.30.11: - resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==, tarball: https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz} magic-string@0.30.9: resolution: {integrity: sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==} engines: {node: '>=12'} make-dir@2.1.0: - resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==, tarball: https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz} engines: {node: '>=6'} md5.js@1.3.5: @@ -1752,14 +1714,14 @@ packages: engines: {node: '>= 0.10.0'} merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, tarball: https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz} merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, tarball: https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz} engines: {node: '>= 8'} micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==, tarball: https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz} engines: {node: '>=8.6'} miller-rabin@4.0.1: @@ -1767,12 +1729,12 @@ packages: hasBin: true mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==, tarball: https://registry.npmjs.org/mime/-/mime-1.6.0.tgz} engines: {node: '>=4'} hasBin: true mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==, tarball: https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz} engines: {node: '>=12'} minimalistic-assert@1.0.1: @@ -1782,7 +1744,7 @@ packages: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, tarball: https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz} minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} @@ -1796,17 +1758,17 @@ packages: hasBin: true mrmime@2.0.0: - resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==, tarball: https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz} engines: {node: '>=10'} ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} muggle-string@0.4.1: - resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==, tarball: https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz} nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==, tarball: https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -1814,19 +1776,19 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} needle@3.3.1: - resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==} + resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==, tarball: https://registry.npmjs.org/needle/-/needle-3.3.1.tgz} engines: {node: '>= 4.4.x'} hasBin: true node-releases@2.0.18: - resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==, tarball: https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz} node-stdlib-browser@1.2.0: resolution: {integrity: sha512-VSjFxUhRhkyed8AtLwSCkMrJRfQ3e2lGtG3sP6FEgaLKBBbxM/dLfjRe1+iLhjvyLFW3tBQ8+c0pcOtXGbAZJg==} engines: {node: '>=10'} normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, tarball: https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz} engines: {node: '>=0.10.0'} normalize.css@8.0.1: @@ -1842,14 +1804,14 @@ packages: hasBin: true npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==, tarball: https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==, tarball: https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz} number-precision@1.6.0: - resolution: {integrity: sha512-05OLPgbgmnixJw+VvEh18yNPUo3iyp4BEWJcrLu4X9W05KmMifN7Mu5exYvQXqxxeNWhvIF+j3Rij+HmddM/hQ==} + resolution: {integrity: sha512-05OLPgbgmnixJw+VvEh18yNPUo3iyp4BEWJcrLu4X9W05KmMifN7Mu5exYvQXqxxeNWhvIF+j3Rij+HmddM/hQ==, tarball: https://registry.npmjs.org/number-precision/-/number-precision-1.6.0.tgz} object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} @@ -1866,19 +1828,16 @@ packages: resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==, tarball: https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz} engines: {node: '>=12'} open@10.1.0: - resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==} + resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==, tarball: https://registry.npmjs.org/open/-/open-10.1.0.tgz} engines: {node: '>=18'} optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==, tarball: https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz} engines: {node: '>= 0.8.0'} os-browserify@0.3.0: @@ -1896,7 +1855,7 @@ packages: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, tarball: https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz} engines: {node: '>=6'} parse-asn1@5.1.7: @@ -1914,40 +1873,32 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==, tarball: https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz} engines: {node: '>=12'} path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==, tarball: https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz} pbkdf2@3.1.2: resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} engines: {node: '>=0.12'} perfect-debounce@1.0.0: - resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==, tarball: https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz} picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} picocolors@1.0.1: - resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==, tarball: https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -1983,25 +1934,21 @@ packages: engines: {node: '>= 0.4'} postcss-selector-parser@6.1.0: - resolution: {integrity: sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==} + resolution: {integrity: sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==, tarball: https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz} engines: {node: '>=4'} - postcss@8.4.40: - resolution: {integrity: sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==} + postcss@8.4.41: + resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==, tarball: https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz} engines: {node: ^10 || ^12 || >=14} - postcss@8.4.41: - resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} + postcss@8.4.45: + resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==, tarball: https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==, tarball: https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz} engines: {node: '>= 0.8.0'} - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - prettier@3.3.3: resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} engines: {node: '>=14'} @@ -2024,7 +1971,7 @@ packages: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, tarball: https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz} engines: {node: '>=6'} qs@6.12.1: @@ -2056,14 +2003,14 @@ packages: engines: {node: '>= 6'} readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, tarball: https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz} engines: {node: '>=8.10.0'} resize-observer-polyfill@1.5.1: - resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==, tarball: https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz} resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, tarball: https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz} engines: {node: '>=4'} resolve@1.22.8: @@ -2075,23 +2022,18 @@ packages: engines: {iojs: '>=1.0.0', node: '>=0.10.0'} rfdc@1.4.1: - resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - - rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==, tarball: https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz} ripemd160@2.0.2: resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} rollup@4.21.0: - resolution: {integrity: sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ==} + resolution: {integrity: sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ==, tarball: https://registry.npmjs.org/rollup/-/rollup-4.21.0.tgz} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true run-applescript@7.0.0: - resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==, tarball: https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz} engines: {node: '>=18'} run-parallel@1.2.0: @@ -2107,7 +2049,7 @@ packages: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} sass@1.77.8: - resolution: {integrity: sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==} + resolution: {integrity: sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==, tarball: https://registry.npmjs.org/sass/-/sass-1.77.8.tgz} engines: {node: '>=14.0.0'} hasBin: true @@ -2115,14 +2057,14 @@ packages: resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==} scroll-into-view-if-needed@2.2.31: - resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==} + resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==, tarball: https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz} semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, tarball: https://registry.npmjs.org/semver/-/semver-6.3.1.tgz} hasBin: true semver@7.6.2: @@ -2130,6 +2072,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==, tarball: https://registry.npmjs.org/semver/-/semver-7.6.3.tgz} + engines: {node: '>=10'} + hasBin: true + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -2157,30 +2104,26 @@ packages: engines: {node: '>= 0.4'} signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, tarball: https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz} engines: {node: '>=14'} simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==, tarball: https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz} sirv@2.0.4: - resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==, tarball: https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz} engines: {node: '>= 10'} - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - source-map-js@1.2.0: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, tarball: https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz} engines: {node: '>=0.10.0'} speakingurl@14.0.1: - resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==, tarball: https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz} engines: {node: '>=0.10.0'} stream-browserify@3.0.0: @@ -2196,19 +2139,19 @@ packages: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, tarball: https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz} engines: {node: '>=8'} strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==, tarball: https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz} engines: {node: '>=12'} strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, tarball: https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz} engines: {node: '>=8'} superjson@2.2.1: - resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==} + resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==, tarball: https://registry.npmjs.org/superjson/-/superjson-2.2.1.tgz} engines: {node: '>=16'} supports-color@5.5.0: @@ -2216,7 +2159,7 @@ packages: engines: {node: '>=4'} supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, tarball: https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz} engines: {node: '>=8'} supports-preserve-symlinks-flag@1.0.0: @@ -2224,14 +2167,10 @@ packages: engines: {node: '>= 0.4'} svg-tags@1.0.0: - resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} - - synckit@0.8.8: - resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} - engines: {node: ^14.18.0 || >=16.0.0} + resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==, tarball: https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz} text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==, tarball: https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz} timers-browserify@2.0.12: resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} @@ -2242,18 +2181,18 @@ packages: engines: {node: '>=4'} to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, tarball: https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz} engines: {node: '>=8.0'} toggle-selection@1.0.6: resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} totalist@3.0.1: - resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==, tarball: https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz} engines: {node: '>=6'} ts-api-utils@1.3.0: - resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==, tarball: https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' @@ -2268,36 +2207,45 @@ packages: resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==} type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==, tarball: https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz} engines: {node: '>= 0.8.0'} type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==, tarball: https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz} engines: {node: '>=10'} + typescript-eslint@8.4.0: + resolution: {integrity: sha512-67qoc3zQZe3CAkO0ua17+7aCLI0dU+sSQd1eKPGq06QE4rfQjstVXR6woHO5qQvGUa550NfGckT4tzh3b3c8Pw==, tarball: https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.4.0.tgz} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + typescript@5.5.4: resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} engines: {node: '>=14.17'} hasBin: true undici-types@6.19.6: - resolution: {integrity: sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==} + resolution: {integrity: sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==, tarball: https://registry.npmjs.org/undici-types/-/undici-types-6.19.6.tgz} universal-user-agent@7.0.2: resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==} universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==, tarball: https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz} engines: {node: '>= 10.0.0'} update-browserslist-db@1.1.0: - resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} + resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==, tarball: https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz} hasBin: true peerDependencies: browserslist: '>= 4.21.0' uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, tarball: https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz} url-join@5.0.0: resolution: {integrity: sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==} @@ -2317,15 +2265,15 @@ packages: hasBin: true vite-bundle-analyzer@0.10.6: - resolution: {integrity: sha512-w/5wvRZeZo2lKdJzRGCTn4YW/mT++fKeii2PQPK3odblfFqsODYHF72V+QTg1Xznbxy543N0WfT5vPiSosVWxA==} + resolution: {integrity: sha512-w/5wvRZeZo2lKdJzRGCTn4YW/mT++fKeii2PQPK3odblfFqsODYHF72V+QTg1Xznbxy543N0WfT5vPiSosVWxA==, tarball: https://registry.npmjs.org/vite-bundle-analyzer/-/vite-bundle-analyzer-0.10.6.tgz} vite-hot-client@0.2.3: - resolution: {integrity: sha512-rOGAV7rUlUHX89fP2p2v0A2WWvV3QMX2UYq0fRqsWSvFvev4atHWqjwGoKaZT1VTKyLGk533ecu3eyd0o59CAg==} + resolution: {integrity: sha512-rOGAV7rUlUHX89fP2p2v0A2WWvV3QMX2UYq0fRqsWSvFvev4atHWqjwGoKaZT1VTKyLGk533ecu3eyd0o59CAg==, tarball: https://registry.npmjs.org/vite-hot-client/-/vite-hot-client-0.2.3.tgz} peerDependencies: vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 vite-plugin-inspect@0.8.7: - resolution: {integrity: sha512-/XXou3MVc13A5O9/2Nd6xczjrUwt7ZyI9h8pTnUMkr5SshLcb0PJUOVq2V+XVkdeU4njsqAtmK87THZuO2coGA==} + resolution: {integrity: sha512-/XXou3MVc13A5O9/2Nd6xczjrUwt7ZyI9h8pTnUMkr5SshLcb0PJUOVq2V+XVkdeU4njsqAtmK87THZuO2coGA==, tarball: https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-0.8.7.tgz} engines: {node: '>=14'} peerDependencies: '@nuxt/kit': '*' @@ -2339,19 +2287,19 @@ packages: peerDependencies: vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 - vite-plugin-vue-devtools@7.3.9: - resolution: {integrity: sha512-ybDV2kepW0NpusvtfbRKHs0pvyrReNcFtL572gyZ6Alox6u5uebYefd2eAG/7mJSU3NPI5UxUH1e/Mof5exdlw==} + vite-plugin-vue-devtools@7.4.4: + resolution: {integrity: sha512-lJ7Vr6gznv1nf2S75XJTpXl4XcwnHfyvqJQ7szOvTUfumQALDGo772TEH69wx8gkY/ZWZQea4DZR5IQZMOZKUA==, tarball: https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.4.4.tgz} engines: {node: '>=v14.21.3'} peerDependencies: vite: ^3.1.0 || ^4.0.0-0 || ^5.0.0-0 - vite-plugin-vue-inspector@5.1.3: - resolution: {integrity: sha512-pMrseXIDP1Gb38mOevY+BvtNGNqiqmqa2pKB99lnLsADQww9w9xMbAfT4GB6RUoaOkSPrtlXqpq2Fq+Dj2AgFg==} + vite-plugin-vue-inspector@5.2.0: + resolution: {integrity: sha512-wWxyb9XAtaIvV/Lr7cqB1HIzmHZFVUJsTNm3yAxkS87dgh/Ky4qr2wDEWNxF23fdhVa3jQ8MZREpr4XyiuaRqA==, tarball: https://registry.npmjs.org/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-5.2.0.tgz} peerDependencies: vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 - vite@5.4.2: - resolution: {integrity: sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==} + vite@5.4.3: + resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==, tarball: https://registry.npmjs.org/vite/-/vite-5.4.3.tgz} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -2385,7 +2333,7 @@ packages: resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} vscode-uri@3.0.8: - resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==, tarball: https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz} vue-2048@3.0.5: resolution: {integrity: sha512-l1XcKQ+cxr8roZxebXespk3b5Xq2Sxv/hs8IqzxQ4+Gey6FhboGabJY7kOHSFEqlhjBR4RWkDpNXtZtm46/1CQ==} @@ -2422,14 +2370,8 @@ packages: '@vue/runtime-core': optional: true - vue-eslint-parser@9.4.2: - resolution: {integrity: sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==} - engines: {node: ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '>=6.0.0' - vue-eslint-parser@9.4.3: - resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==, tarball: https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' @@ -2455,14 +2397,14 @@ packages: peerDependencies: vue: ^3.2.0 - vue-tsc@2.0.29: - resolution: {integrity: sha512-MHhsfyxO3mYShZCGYNziSbc63x7cQ5g9kvijV7dRe1TTXBRLxXyL0FnXWpUF1xII2mJ86mwYpYsUmMwkmerq7Q==} + vue-tsc@2.1.6: + resolution: {integrity: sha512-f98dyZp5FOukcYmbFpuSCJ4Z0vHSOSmxGttZJCsFeX0M4w/Rsq0s4uKXjcSRsZqsRgQa6z7SfuO+y0HVICE57Q==, tarball: https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.1.6.tgz} hasBin: true peerDependencies: typescript: '>=5.0.0' - vue@3.4.38: - resolution: {integrity: sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==} + vue@3.5.3: + resolution: {integrity: sha512-xvRbd0HpuLovYbOHXRHlSBsSvmUJbo0pzbkKTApWnQGf3/cu5Z39mQeA5cZdLRVIoNf3zI6MSoOgHUT5i2jO+Q==, tarball: https://registry.npmjs.org/vue/-/vue-3.5.3.tgz} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -2478,11 +2420,8 @@ packages: engines: {node: '>= 8'} hasBin: true - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - xml-name-validator@4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==, tarball: https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz} engines: {node: '>=12'} xtend@4.0.2: @@ -2490,7 +2429,7 @@ packages: engines: {node: '>=0.4'} yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, tarball: https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz} yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} @@ -2514,7 +2453,7 @@ snapshots: dependencies: color: 3.2.1 - '@arco-design/web-vue@2.56.1(vue@3.4.38(typescript@5.5.4))': + '@arco-design/web-vue@2.56.1(vue@3.5.3(typescript@5.5.4))': dependencies: '@arco-design/color': 0.4.0 b-tween: 0.3.3 @@ -2524,7 +2463,7 @@ snapshots: number-precision: 1.6.0 resize-observer-polyfill: 1.5.1 scroll-into-view-if-needed: 2.2.31 - vue: 3.4.38(typescript@5.5.4) + vue: 3.5.3(typescript@5.5.4) '@arco-plugins/vite-vue@1.4.5': dependencies: @@ -2717,10 +2656,6 @@ snapshots: dependencies: '@babel/types': 7.24.0 - '@babel/parser@7.24.7': - dependencies: - '@babel/types': 7.24.0 - '@babel/parser@7.25.4': dependencies: '@babel/types': 7.25.4 @@ -2892,19 +2827,27 @@ snapshots: '@esbuild/win32-x64@0.21.5': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': + '@eslint-community/eslint-utils@4.4.0(eslint@9.9.1)': dependencies: - eslint: 8.57.0 + eslint: 9.9.1 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.10.0': {} + '@eslint-community/regexpp@4.11.0': {} + + '@eslint/config-array@0.18.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.6 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color - '@eslint/eslintrc@2.1.4': + '@eslint/eslintrc@3.1.0': dependencies: ajv: 6.12.6 - debug: 4.3.4 - espree: 9.6.1 - globals: 13.24.0 + debug: 4.3.6 + espree: 10.1.0 + globals: 14.0.0 ignore: 5.3.1 import-fresh: 3.3.0 js-yaml: 4.1.0 @@ -2913,19 +2856,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@8.57.0': {} + '@eslint/js@9.9.1': {} - '@humanwhocodes/config-array@0.11.14': - dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color + '@eslint/object-schema@2.1.4': {} '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/object-schema@2.0.3': {} + '@humanwhocodes/retry@0.3.0': {} '@intlify/core-base@9.14.0': dependencies: @@ -3010,8 +2947,6 @@ snapshots: dependencies: '@octokit/openapi-types': 22.2.0 - '@pkgr/core@0.1.1': {} - '@polka/url@1.0.0-next.25': {} '@rollup/plugin-inject@5.0.5(rollup@4.21.0)': @@ -3082,6 +3017,15 @@ snapshots: '@tsconfig/node20@20.1.4': {} + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.5 + '@types/json-schema': 7.0.15 + + '@types/eslint__js@8.42.3': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree@1.0.5': {} '@types/json-schema@7.0.15': {} @@ -3092,74 +3036,70 @@ snapshots: '@types/node@16.18.101': {} - '@types/node@22.4.2': + '@types/node@22.5.4': dependencies: undici-types: 6.19.6 - '@types/semver@7.5.8': {} - '@types/uuid@10.0.0': {} '@types/web-bluetooth@0.0.20': {} - '@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/eslint-plugin@8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1)(typescript@5.5.4))(eslint@9.9.1)(typescript@5.5.4)': dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.5.4) - '@typescript-eslint/scope-manager': 7.7.0 - '@typescript-eslint/type-utils': 7.7.0(eslint@8.57.0)(typescript@5.5.4) - '@typescript-eslint/utils': 7.7.0(eslint@8.57.0)(typescript@5.5.4) - '@typescript-eslint/visitor-keys': 7.7.0 - debug: 4.3.4 - eslint: 8.57.0 + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 8.4.0(eslint@9.9.1)(typescript@5.5.4) + '@typescript-eslint/scope-manager': 8.4.0 + '@typescript-eslint/type-utils': 8.4.0(eslint@9.9.1)(typescript@5.5.4) + '@typescript-eslint/utils': 8.4.0(eslint@9.9.1)(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 8.4.0 + eslint: 9.9.1 graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 - semver: 7.6.2 ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/parser@8.4.0(eslint@9.9.1)(typescript@5.5.4)': dependencies: - '@typescript-eslint/scope-manager': 7.7.0 - '@typescript-eslint/types': 7.7.0 - '@typescript-eslint/typescript-estree': 7.7.0(typescript@5.5.4) - '@typescript-eslint/visitor-keys': 7.7.0 - debug: 4.3.4 - eslint: 8.57.0 + '@typescript-eslint/scope-manager': 8.4.0 + '@typescript-eslint/types': 8.4.0 + '@typescript-eslint/typescript-estree': 8.4.0(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 8.4.0 + debug: 4.3.6 + eslint: 9.9.1 optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@7.7.0': + '@typescript-eslint/scope-manager@8.4.0': dependencies: - '@typescript-eslint/types': 7.7.0 - '@typescript-eslint/visitor-keys': 7.7.0 + '@typescript-eslint/types': 8.4.0 + '@typescript-eslint/visitor-keys': 8.4.0 - '@typescript-eslint/type-utils@7.7.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/type-utils@8.4.0(eslint@9.9.1)(typescript@5.5.4)': dependencies: - '@typescript-eslint/typescript-estree': 7.7.0(typescript@5.5.4) - '@typescript-eslint/utils': 7.7.0(eslint@8.57.0)(typescript@5.5.4) - debug: 4.3.4 - eslint: 8.57.0 + '@typescript-eslint/typescript-estree': 8.4.0(typescript@5.5.4) + '@typescript-eslint/utils': 8.4.0(eslint@9.9.1)(typescript@5.5.4) + debug: 4.3.6 ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: + - eslint - supports-color - '@typescript-eslint/types@7.7.0': {} + '@typescript-eslint/types@8.4.0': {} - '@typescript-eslint/typescript-estree@7.7.0(typescript@5.5.4)': + '@typescript-eslint/typescript-estree@8.4.0(typescript@5.5.4)': dependencies: - '@typescript-eslint/types': 7.7.0 - '@typescript-eslint/visitor-keys': 7.7.0 - debug: 4.3.4 - globby: 11.1.0 + '@typescript-eslint/types': 8.4.0 + '@typescript-eslint/visitor-keys': 8.4.0 + debug: 4.3.6 + fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.2 @@ -3169,41 +3109,36 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.7.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/utils@8.4.0(eslint@9.9.1)(typescript@5.5.4)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 7.7.0 - '@typescript-eslint/types': 7.7.0 - '@typescript-eslint/typescript-estree': 7.7.0(typescript@5.5.4) - eslint: 8.57.0 - semver: 7.6.2 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1) + '@typescript-eslint/scope-manager': 8.4.0 + '@typescript-eslint/types': 8.4.0 + '@typescript-eslint/typescript-estree': 8.4.0(typescript@5.5.4) + eslint: 9.9.1 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@7.7.0': + '@typescript-eslint/visitor-keys@8.4.0': dependencies: - '@typescript-eslint/types': 7.7.0 + '@typescript-eslint/types': 8.4.0 eslint-visitor-keys: 3.4.3 - '@ungap/structured-clone@1.2.0': {} - - '@vitejs/plugin-vue@5.1.2(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4))': + '@vitejs/plugin-vue@5.1.3(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8))(vue@3.5.3(typescript@5.5.4))': dependencies: - vite: 5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8) - vue: 3.4.38(typescript@5.5.4) + vite: 5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8) + vue: 3.5.3(typescript@5.5.4) - '@volar/language-core@2.4.0-alpha.18': + '@volar/language-core@2.4.2': dependencies: - '@volar/source-map': 2.4.0-alpha.18 + '@volar/source-map': 2.4.2 - '@volar/source-map@2.4.0-alpha.18': {} + '@volar/source-map@2.4.2': {} - '@volar/typescript@2.4.0-alpha.18': + '@volar/typescript@2.4.2': dependencies: - '@volar/language-core': 2.4.0-alpha.18 + '@volar/language-core': 2.4.2 path-browserify: 1.0.1 vscode-uri: 3.0.8 @@ -3238,27 +3173,52 @@ snapshots: '@vue/compiler-core@3.4.38': dependencies: - '@babel/parser': 7.24.7 + '@babel/parser': 7.25.4 '@vue/shared': 3.4.38 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.2.0 + '@vue/compiler-core@3.5.3': + dependencies: + '@babel/parser': 7.25.4 + '@vue/shared': 3.5.3 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + '@vue/compiler-dom@3.4.38': dependencies: '@vue/compiler-core': 3.4.38 '@vue/shared': 3.4.38 + '@vue/compiler-dom@3.5.3': + dependencies: + '@vue/compiler-core': 3.5.3 + '@vue/shared': 3.5.3 + '@vue/compiler-sfc@3.4.38': dependencies: - '@babel/parser': 7.24.7 + '@babel/parser': 7.25.4 '@vue/compiler-core': 3.4.38 '@vue/compiler-dom': 3.4.38 '@vue/compiler-ssr': 3.4.38 '@vue/shared': 3.4.38 estree-walker: 2.0.2 - magic-string: 0.30.10 - postcss: 8.4.40 + magic-string: 0.30.11 + postcss: 8.4.41 + source-map-js: 1.2.0 + + '@vue/compiler-sfc@3.5.3': + dependencies: + '@babel/parser': 7.25.4 + '@vue/compiler-core': 3.5.3 + '@vue/compiler-dom': 3.5.3 + '@vue/compiler-ssr': 3.5.3 + '@vue/shared': 3.5.3 + estree-walker: 2.0.2 + magic-string: 0.30.11 + postcss: 8.4.45 source-map-js: 1.2.0 '@vue/compiler-ssr@3.4.38': @@ -3266,6 +3226,11 @@ snapshots: '@vue/compiler-dom': 3.4.38 '@vue/shared': 3.4.38 + '@vue/compiler-ssr@3.5.3': + dependencies: + '@vue/compiler-dom': 3.5.3 + '@vue/shared': 3.5.3 + '@vue/compiler-vue2@2.7.16': dependencies: de-indent: 1.0.2 @@ -3273,21 +3238,21 @@ snapshots: '@vue/devtools-api@6.6.3': {} - '@vue/devtools-core@7.3.9(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4))': + '@vue/devtools-core@7.4.4(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8))(vue@3.5.3(typescript@5.5.4))': dependencies: - '@vue/devtools-kit': 7.3.9 - '@vue/devtools-shared': 7.3.9 + '@vue/devtools-kit': 7.4.4 + '@vue/devtools-shared': 7.4.4 mitt: 3.0.1 nanoid: 3.3.7 pathe: 1.1.2 - vite-hot-client: 0.2.3(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8)) - vue: 3.4.38(typescript@5.5.4) + vite-hot-client: 0.2.3(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8)) + vue: 3.5.3(typescript@5.5.4) transitivePeerDependencies: - vite - '@vue/devtools-kit@7.3.9': + '@vue/devtools-kit@7.4.4': dependencies: - '@vue/devtools-shared': 7.3.9 + '@vue/devtools-shared': 7.4.4 birpc: 0.2.17 hookable: 5.5.3 mitt: 3.0.1 @@ -3295,34 +3260,13 @@ snapshots: speakingurl: 14.0.1 superjson: 2.2.1 - '@vue/devtools-shared@7.3.9': + '@vue/devtools-shared@7.4.4': dependencies: rfdc: 1.4.1 - '@vue/eslint-config-prettier@9.0.0(eslint@8.57.0)(prettier@3.3.3)': - dependencies: - eslint: 8.57.0 - eslint-config-prettier: 9.1.0(eslint@8.57.0) - eslint-plugin-prettier: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.3) - prettier: 3.3.3 - transitivePeerDependencies: - - '@types/eslint' - - '@vue/eslint-config-typescript@13.0.0(eslint-plugin-vue@9.27.0(eslint@8.57.0))(eslint@8.57.0)(typescript@5.5.4)': - dependencies: - '@typescript-eslint/eslint-plugin': 7.7.0(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) - '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 - eslint-plugin-vue: 9.27.0(eslint@8.57.0) - vue-eslint-parser: 9.4.2(eslint@8.57.0) - optionalDependencies: - typescript: 5.5.4 - transitivePeerDependencies: - - supports-color - - '@vue/language-core@2.0.29(typescript@5.5.4)': + '@vue/language-core@2.1.6(typescript@5.5.4)': dependencies: - '@volar/language-core': 2.4.0-alpha.18 + '@volar/language-core': 2.4.2 '@vue/compiler-dom': 3.4.38 '@vue/compiler-vue2': 2.7.16 '@vue/shared': 3.4.38 @@ -3336,53 +3280,66 @@ snapshots: '@vue/reactivity@3.4.38': dependencies: '@vue/shared': 3.4.38 + optional: true + + '@vue/reactivity@3.5.3': + dependencies: + '@vue/shared': 3.5.3 '@vue/runtime-core@3.4.38': dependencies: '@vue/reactivity': 3.4.38 '@vue/shared': 3.4.38 + optional: true - '@vue/runtime-dom@3.4.38': + '@vue/runtime-core@3.5.3': dependencies: - '@vue/reactivity': 3.4.38 - '@vue/runtime-core': 3.4.38 - '@vue/shared': 3.4.38 + '@vue/reactivity': 3.5.3 + '@vue/shared': 3.5.3 + + '@vue/runtime-dom@3.5.3': + dependencies: + '@vue/reactivity': 3.5.3 + '@vue/runtime-core': 3.5.3 + '@vue/shared': 3.5.3 csstype: 3.1.3 - '@vue/server-renderer@3.4.38(vue@3.4.38(typescript@5.5.4))': + '@vue/server-renderer@3.5.3(vue@3.5.3(typescript@5.5.4))': dependencies: - '@vue/compiler-ssr': 3.4.38 - '@vue/shared': 3.4.38 - vue: 3.4.38(typescript@5.5.4) + '@vue/compiler-ssr': 3.5.3 + '@vue/shared': 3.5.3 + vue: 3.5.3(typescript@5.5.4) '@vue/shared@3.4.38': {} + '@vue/shared@3.5.3': {} + '@vue/tsconfig@0.5.1': {} - '@vueuse/core@11.0.1(vue@3.4.38(typescript@5.5.4))': + '@vueuse/core@11.0.3(vue@3.5.3(typescript@5.5.4))': dependencies: '@types/web-bluetooth': 0.0.20 - '@vueuse/metadata': 11.0.1 - '@vueuse/shared': 11.0.1(vue@3.4.38(typescript@5.5.4)) - vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) + '@vueuse/metadata': 11.0.3 + '@vueuse/shared': 11.0.3(vue@3.5.3(typescript@5.5.4)) + vue-demi: 0.14.10(vue@3.5.3(typescript@5.5.4)) transitivePeerDependencies: - '@vue/composition-api' - vue - '@vueuse/metadata@11.0.1': {} + '@vueuse/metadata@11.0.3': {} - '@vueuse/shared@11.0.1(vue@3.4.38(typescript@5.5.4))': + '@vueuse/shared@11.0.3(vue@3.5.3(typescript@5.5.4))': dependencies: - vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) + vue-demi: 0.14.10(vue@3.5.3(typescript@5.5.4)) transitivePeerDependencies: - '@vue/composition-api' - vue - acorn-jsx@5.3.2(acorn@8.11.3): + acorn-jsx@5.3.2(acorn@8.12.1): dependencies: - acorn: 8.11.3 + acorn: 8.12.1 - acorn@8.11.3: {} + acorn@8.12.1: {} ajv@6.12.6: dependencies: @@ -3411,8 +3368,6 @@ snapshots: argparse@2.0.1: {} - array-union@2.1.0: {} - asn1.js@4.10.1: dependencies: bn.js: 4.12.0 @@ -3461,14 +3416,9 @@ snapshots: dependencies: balanced-match: 1.0.2 - braces@3.0.2: - dependencies: - fill-range: 7.0.1 - braces@3.0.3: dependencies: fill-range: 7.1.1 - optional: true brorand@1.1.0: {} @@ -3691,10 +3641,6 @@ snapshots: dependencies: ms: 2.1.2 - debug@4.3.5: - dependencies: - ms: 2.1.2 - debug@4.3.6: dependencies: ms: 2.1.2 @@ -3733,14 +3679,6 @@ snapshots: miller-rabin: 4.0.1 randombytes: 2.1.0 - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - domain-browser@4.23.0: {} echarts@5.5.1: @@ -3807,29 +3745,20 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@9.1.0(eslint@8.57.0): - dependencies: - eslint: 8.57.0 - - eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.3): + eslint-config-prettier@9.1.0(eslint@9.9.1): dependencies: - eslint: 8.57.0 - prettier: 3.3.3 - prettier-linter-helpers: 1.0.0 - synckit: 0.8.8 - optionalDependencies: - eslint-config-prettier: 9.1.0(eslint@8.57.0) + eslint: 9.9.1 - eslint-plugin-vue@9.27.0(eslint@8.57.0): + eslint-plugin-vue@9.28.0(eslint@9.9.1): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - eslint: 8.57.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1) + eslint: 9.9.1 globals: 13.24.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.0 - semver: 7.6.2 - vue-eslint-parser: 9.4.3(eslint@8.57.0) + semver: 7.6.3 + vue-eslint-parser: 9.4.3(eslint@9.9.1) xml-name-validator: 4.0.0 transitivePeerDependencies: - supports-color @@ -3839,40 +3768,43 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 + eslint-scope@8.0.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-visitor-keys@3.4.3: {} - eslint@8.57.0: + eslint-visitor-keys@4.0.0: {} + + eslint@9.9.1: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@eslint-community/regexpp': 4.10.0 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.0 - '@humanwhocodes/config-array': 0.11.14 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1) + '@eslint-community/regexpp': 4.11.0 + '@eslint/config-array': 0.18.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.9.1 '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.3.0 '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 + debug: 4.3.6 escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.5.0 + eslint-scope: 8.0.2 + eslint-visitor-keys: 4.0.0 + espree: 10.1.0 + esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 + file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 ignore: 5.3.1 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 - js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash.merge: 4.6.2 @@ -3884,15 +3816,17 @@ snapshots: transitivePeerDependencies: - supports-color - espree@9.6.1: + espree@10.1.0: dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) - eslint-visitor-keys: 3.4.3 + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) + eslint-visitor-keys: 4.0.0 - esquery@1.5.0: + espree@9.6.1: dependencies: - estraverse: 5.3.0 + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) + eslint-visitor-keys: 3.4.3 esquery@1.6.0: dependencies: @@ -3929,8 +3863,6 @@ snapshots: fast-deep-equal@3.1.3: {} - fast-diff@1.3.0: {} - fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3947,29 +3879,23 @@ snapshots: dependencies: reusify: 1.0.4 - file-entry-cache@6.0.1: - dependencies: - flat-cache: 3.2.0 - - fill-range@7.0.1: + file-entry-cache@8.0.0: dependencies: - to-regex-range: 5.0.1 + flat-cache: 4.0.1 fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 - optional: true find-up@5.0.0: dependencies: locate-path: 6.0.0 path-exists: 4.0.0 - flat-cache@3.2.0: + flat-cache@4.0.1: dependencies: flatted: 3.3.1 keyv: 4.5.4 - rimraf: 3.0.2 flatted@3.3.1: {} @@ -3983,8 +3909,6 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 - fs.realpath@1.0.0: {} - fsevents@2.3.3: optional: true @@ -4010,29 +3934,13 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - globals@11.12.0: {} globals@13.24.0: dependencies: type-fest: 0.20.2 - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.1 - merge2: 1.4.1 - slash: 3.0.0 + globals@14.0.0: {} gopd@1.0.1: dependencies: @@ -4116,11 +4024,6 @@ snapshots: imurmurhash@0.1.4: {} - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - inherits@2.0.4: {} is-arguments@1.1.1: @@ -4247,10 +4150,6 @@ snapshots: dependencies: yallist: 3.1.1 - magic-string@0.30.10: - dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 - magic-string@0.30.11: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -4279,7 +4178,7 @@ snapshots: micromatch@4.0.5: dependencies: - braces: 3.0.2 + braces: 3.0.3 picomatch: 2.3.1 miller-rabin@4.0.1: @@ -4401,10 +4300,6 @@ snapshots: has-symbols: 1.0.3 object-keys: 1.1.1 - once@1.4.0: - dependencies: - wrappy: 1.0.2 - onetime@6.0.0: dependencies: mimic-fn: 4.0.0 @@ -4456,16 +4351,12 @@ snapshots: path-exists@4.0.0: {} - path-is-absolute@1.0.1: {} - path-key@3.1.1: {} path-key@4.0.0: {} path-parse@1.0.7: {} - path-type@4.0.0: {} - pathe@1.1.2: {} pbkdf2@3.1.2: @@ -4489,11 +4380,11 @@ snapshots: pify@4.0.1: optional: true - pinia@2.2.2(typescript@5.5.4)(vue@3.4.38(typescript@5.5.4)): + pinia@2.2.2(typescript@5.5.4)(vue@3.5.3(typescript@5.5.4)): dependencies: '@vue/devtools-api': 6.6.3 - vue: 3.4.38(typescript@5.5.4) - vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) + vue: 3.5.3(typescript@5.5.4) + vue-demi: 0.14.10(vue@3.5.3(typescript@5.5.4)) optionalDependencies: typescript: 5.5.4 @@ -4508,13 +4399,13 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss@8.4.40: + postcss@8.4.41: dependencies: nanoid: 3.3.7 picocolors: 1.0.1 source-map-js: 1.2.0 - postcss@8.4.41: + postcss@8.4.45: dependencies: nanoid: 3.3.7 picocolors: 1.0.1 @@ -4522,10 +4413,6 @@ snapshots: prelude-ls@1.2.1: {} - prettier-linter-helpers@1.0.0: - dependencies: - fast-diff: 1.3.0 - prettier@3.3.3: {} process-nextick-args@2.0.1: {} @@ -4605,10 +4492,6 @@ snapshots: rfdc@1.4.1: {} - rimraf@3.0.2: - dependencies: - glob: 7.2.3 - ripemd160@2.0.2: dependencies: hash-base: 3.1.0 @@ -4670,6 +4553,8 @@ snapshots: semver@7.6.2: {} + semver@7.6.3: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -4713,8 +4598,6 @@ snapshots: mrmime: 2.0.0 totalist: 3.0.1 - slash@3.0.0: {} - source-map-js@1.2.0: {} source-map@0.6.1: @@ -4766,11 +4649,6 @@ snapshots: svg-tags@1.0.0: {} - synckit@0.8.8: - dependencies: - '@pkgr/core': 0.1.1 - tslib: 2.6.2 - text-table@0.2.0: {} timers-browserify@2.0.12: @@ -4803,6 +4681,17 @@ snapshots: type-fest@0.20.2: {} + typescript-eslint@8.4.0(eslint@9.9.1)(typescript@5.5.4): + dependencies: + '@typescript-eslint/eslint-plugin': 8.4.0(@typescript-eslint/parser@8.4.0(eslint@9.9.1)(typescript@5.5.4))(eslint@9.9.1)(typescript@5.5.4) + '@typescript-eslint/parser': 8.4.0(eslint@9.9.1)(typescript@5.5.4) + '@typescript-eslint/utils': 8.4.0(eslint@9.9.1)(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - eslint + - supports-color + typescript@5.5.4: {} undici-types@6.19.6: {} @@ -4842,11 +4731,11 @@ snapshots: vite-bundle-analyzer@0.10.6: {} - vite-hot-client@0.2.3(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8)): + vite-hot-client@0.2.3(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8)): dependencies: - vite: 5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8) + vite: 5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8) - vite-plugin-inspect@0.8.7(rollup@4.21.0)(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8)): + vite-plugin-inspect@0.8.7(rollup@4.21.0)(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8)): dependencies: '@antfu/utils': 0.7.10 '@rollup/pluginutils': 5.1.0(rollup@4.21.0) @@ -4857,36 +4746,36 @@ snapshots: perfect-debounce: 1.0.0 picocolors: 1.0.1 sirv: 2.0.4 - vite: 5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8) + vite: 5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8) transitivePeerDependencies: - rollup - supports-color - vite-plugin-node-polyfills@0.22.0(rollup@4.21.0)(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8)): + vite-plugin-node-polyfills@0.22.0(rollup@4.21.0)(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8)): dependencies: '@rollup/plugin-inject': 5.0.5(rollup@4.21.0) node-stdlib-browser: 1.2.0 - vite: 5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8) + vite: 5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8) transitivePeerDependencies: - rollup - vite-plugin-vue-devtools@7.3.9(rollup@4.21.0)(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)): + vite-plugin-vue-devtools@7.4.4(rollup@4.21.0)(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8))(vue@3.5.3(typescript@5.5.4)): dependencies: - '@vue/devtools-core': 7.3.9(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)) - '@vue/devtools-kit': 7.3.9 - '@vue/devtools-shared': 7.3.9 + '@vue/devtools-core': 7.4.4(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8))(vue@3.5.3(typescript@5.5.4)) + '@vue/devtools-kit': 7.4.4 + '@vue/devtools-shared': 7.4.4 execa: 8.0.1 sirv: 2.0.4 - vite: 5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8) - vite-plugin-inspect: 0.8.7(rollup@4.21.0)(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8)) - vite-plugin-vue-inspector: 5.1.3(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8)) + vite: 5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8) + vite-plugin-inspect: 0.8.7(rollup@4.21.0)(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8)) + vite-plugin-vue-inspector: 5.2.0(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8)) transitivePeerDependencies: - '@nuxt/kit' - rollup - supports-color - vue - vite-plugin-vue-inspector@5.1.3(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8)): + vite-plugin-vue-inspector@5.2.0(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8)): dependencies: '@babel/core': 7.25.2 '@babel/plugin-proposal-decorators': 7.24.7(@babel/core@7.25.2) @@ -4897,17 +4786,17 @@ snapshots: '@vue/compiler-dom': 3.4.38 kolorist: 1.8.0 magic-string: 0.30.11 - vite: 5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8) + vite: 5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8) transitivePeerDependencies: - supports-color - vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8): + vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8): dependencies: esbuild: 0.21.5 - postcss: 8.4.41 + postcss: 8.4.45 rollup: 4.21.0 optionalDependencies: - '@types/node': 22.4.2 + '@types/node': 22.5.4 fsevents: 2.3.3 less: 4.2.0 sass: 1.77.8 @@ -4916,49 +4805,36 @@ snapshots: vscode-uri@3.0.8: {} - vue-2048@3.0.5(typescript@5.5.4)(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8)): + vue-2048@3.0.5(typescript@5.5.4)(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8)): dependencies: - '@vitejs/plugin-vue': 5.1.2(vite@5.4.2(@types/node@22.4.2)(less@4.2.0)(sass@1.77.8))(vue@3.4.38(typescript@5.5.4)) - vue: 3.4.38(typescript@5.5.4) + '@vitejs/plugin-vue': 5.1.3(vite@5.4.3(@types/node@22.5.4)(less@4.2.0)(sass@1.77.8))(vue@3.5.3(typescript@5.5.4)) + vue: 3.5.3(typescript@5.5.4) transitivePeerDependencies: - typescript - vite - vue-demi@0.13.11(vue@3.4.38(typescript@5.5.4)): + vue-demi@0.13.11(vue@3.5.3(typescript@5.5.4)): dependencies: - vue: 3.4.38(typescript@5.5.4) + vue: 3.5.3(typescript@5.5.4) - vue-demi@0.14.10(vue@3.4.38(typescript@5.5.4)): + vue-demi@0.14.10(vue@3.5.3(typescript@5.5.4)): dependencies: - vue: 3.4.38(typescript@5.5.4) + vue: 3.5.3(typescript@5.5.4) - vue-echarts@7.0.3(@vue/runtime-core@3.4.38)(echarts@5.5.1)(vue@3.4.38(typescript@5.5.4)): + vue-echarts@7.0.3(@vue/runtime-core@3.4.38)(echarts@5.5.1)(vue@3.5.3(typescript@5.5.4)): dependencies: echarts: 5.5.1 - vue: 3.4.38(typescript@5.5.4) - vue-demi: 0.13.11(vue@3.4.38(typescript@5.5.4)) + vue: 3.5.3(typescript@5.5.4) + vue-demi: 0.13.11(vue@3.5.3(typescript@5.5.4)) optionalDependencies: '@vue/runtime-core': 3.4.38 transitivePeerDependencies: - '@vue/composition-api' - vue-eslint-parser@9.4.2(eslint@8.57.0): - dependencies: - debug: 4.3.4 - eslint: 8.57.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.5.0 - lodash: 4.17.21 - semver: 7.6.2 - transitivePeerDependencies: - - supports-color - - vue-eslint-parser@9.4.3(eslint@8.57.0): + vue-eslint-parser@9.4.3(eslint@9.9.1): dependencies: - debug: 4.3.5 - eslint: 8.57.0 + debug: 4.3.6 + eslint: 9.9.1 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 @@ -4968,37 +4844,37 @@ snapshots: transitivePeerDependencies: - supports-color - vue-i18n@9.14.0(vue@3.4.38(typescript@5.5.4)): + vue-i18n@9.14.0(vue@3.5.3(typescript@5.5.4)): dependencies: '@intlify/core-base': 9.14.0 '@intlify/shared': 9.14.0 '@vue/devtools-api': 6.6.3 - vue: 3.4.38(typescript@5.5.4) + vue: 3.5.3(typescript@5.5.4) - vue-request@2.0.4(patch_hash=imva7qnbqmkxs76or73cwn5jom)(vue@3.4.38(typescript@5.5.4)): + vue-request@2.0.4(patch_hash=imva7qnbqmkxs76or73cwn5jom)(vue@3.5.3(typescript@5.5.4)): dependencies: - vue: 3.4.38(typescript@5.5.4) - vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) + vue: 3.5.3(typescript@5.5.4) + vue-demi: 0.14.10(vue@3.5.3(typescript@5.5.4)) - vue-router@4.4.3(vue@3.4.38(typescript@5.5.4)): + vue-router@4.4.3(vue@3.5.3(typescript@5.5.4)): dependencies: '@vue/devtools-api': 6.6.3 - vue: 3.4.38(typescript@5.5.4) + vue: 3.5.3(typescript@5.5.4) - vue-tsc@2.0.29(typescript@5.5.4): + vue-tsc@2.1.6(typescript@5.5.4): dependencies: - '@volar/typescript': 2.4.0-alpha.18 - '@vue/language-core': 2.0.29(typescript@5.5.4) + '@volar/typescript': 2.4.2 + '@vue/language-core': 2.1.6(typescript@5.5.4) semver: 7.6.2 typescript: 5.5.4 - vue@3.4.38(typescript@5.5.4): + vue@3.5.3(typescript@5.5.4): dependencies: - '@vue/compiler-dom': 3.4.38 - '@vue/compiler-sfc': 3.4.38 - '@vue/runtime-dom': 3.4.38 - '@vue/server-renderer': 3.4.38(vue@3.4.38(typescript@5.5.4)) - '@vue/shared': 3.4.38 + '@vue/compiler-dom': 3.5.3 + '@vue/compiler-sfc': 3.5.3 + '@vue/runtime-dom': 3.5.3 + '@vue/server-renderer': 3.5.3(vue@3.5.3(typescript@5.5.4)) + '@vue/shared': 3.5.3 optionalDependencies: typescript: 5.5.4 @@ -5014,8 +4890,6 @@ snapshots: dependencies: isexe: 2.0.0 - wrappy@1.0.2: {} - xml-name-validator@4.0.0: {} xtend@4.0.2: {} diff --git a/webui/src/App.vue b/webui/src/App.vue index 7bcf031ca0..a08cd01344 100644 --- a/webui/src/App.vue +++ b/webui/src/App.vue @@ -19,12 +19,12 @@ @after-enter="onAfterEnter" > - + diff --git a/webui/src/api/model/downloader.ts b/webui/src/api/model/downloader.ts index d59b5dbef4..0914c8e1a4 100644 --- a/webui/src/api/model/downloader.ts +++ b/webui/src/api/model/downloader.ts @@ -15,6 +15,7 @@ export enum ClientStatusEnum { export enum ClientTypeEnum { qBittorrent = 'qbittorrent', + qBittorrentEE = 'qbittorrentee', Transmission = 'transmission', BiglyBT = 'biglybt', Deluge = 'deluge', @@ -214,7 +215,12 @@ interface TorrentWrapper { size?: number } -export type downloaderConfig = qBittorrentConfig | transmissionConfig | biglybtConfig | delugeConfig +export type downloaderConfig = + | qBittorrentConfig + | qBittorrentEEConfig + | transmissionConfig + | biglybtConfig + | delugeConfig export interface qBittorrentConfig { type: ClientTypeEnum.qBittorrent @@ -225,6 +231,20 @@ export interface qBittorrentConfig { httpVersion: string incrementBan: boolean verifySsl: boolean + ignorePrivate: boolean +} + +export interface qBittorrentEEConfig { + type: ClientTypeEnum.qBittorrentEE + endpoint: string + username: string + password: string + basicAuth: BasicAuth + httpVersion: string + incrementBan: boolean + useShadowBan: boolean + verifySsl: boolean + ignorePrivate: boolean } interface BasicAuth { @@ -239,6 +259,7 @@ export interface transmissionConfig { password: string httpVersion: string verifySsl: boolean + ignorePrivate: boolean rpcUrl: string } @@ -248,6 +269,7 @@ export interface biglybtConfig { token: string httpVersion: string verifySsl: boolean + ignorePrivate: boolean } export interface delugeConfig { @@ -257,6 +279,7 @@ export interface delugeConfig { httpVersion: string incrementBan: boolean verifySsl: boolean + ignorePrivate: boolean rpcUrl: string } diff --git a/webui/src/api/model/statistic.ts b/webui/src/api/model/statistic.ts index 8e7c20f2c2..0057f3e537 100644 --- a/webui/src/api/model/statistic.ts +++ b/webui/src/api/model/statistic.ts @@ -26,13 +26,9 @@ export interface Trends { } export interface Traffic { - allTimeUploaded: number - allTimeDownloaded: number - journal: { - timestamp: number - uploaded: number - downloaded: number - }[] + timestamp: number + dataOverallUploaded: number + dataOverallDownloaded: number } export interface GeoIP { diff --git a/webui/src/components/asyncMethod.vue b/webui/src/components/asyncMethod.vue index c64ca0d688..ad4ca8a046 100644 --- a/webui/src/components/asyncMethod.vue +++ b/webui/src/components/asyncMethod.vue @@ -9,14 +9,17 @@ const loading = ref(false) const error = ref() defineSlots<{ + // eslint-disable-next-line @typescript-eslint/no-explicit-any default(props: { run: (...arg: any) => Promise; loading: boolean; error?: Error }): any }>() const props = defineProps<{ once?: boolean + // eslint-disable-next-line @typescript-eslint/no-explicit-any asyncFn: (...arg: any) => Promise }>() +// eslint-disable-next-line @typescript-eslint/no-explicit-any const run = async (...arg: any) => { if (loading.value && props.once) return loading.value = true diff --git a/webui/src/components/autoUpdateBtn.vue b/webui/src/components/autoUpdateBtn.vue index b351c2276f..30855948a1 100644 --- a/webui/src/components/autoUpdateBtn.vue +++ b/webui/src/components/autoUpdateBtn.vue @@ -1,6 +1,7 @@ diff --git a/webui/src/views/charts/components/banLine.vue b/webui/src/views/charts/components/banLine.vue index a4b30150c1..2536e50a95 100644 --- a/webui/src/views/charts/components/banLine.vue +++ b/webui/src/views/charts/components/banLine.vue @@ -24,8 +24,8 @@ label-col-flex="100px" > @@ -55,7 +55,7 @@ {{ t('page.charts.options.thresold') }} - + {{ t('page.charts.options.mergeSame') }} @@ -157,7 +157,7 @@ const { loading, run, refresh } = useRequest(getAnalysisDataByField, { const match = key.match(/^([-]?[a-zA-z]+)[0-9]+.*/) if (match && match?.length >= 2) key = match[1] + '*' if (map.has(key)) { - map.set(key, map.get(key)!! + it.count) + map.set(key, map.get(key)! + it.count) } else { map.set(key, it.count) } diff --git a/webui/src/views/charts/components/ispPie.vue b/webui/src/views/charts/components/ispPie.vue index c123af041f..4b25262898 100644 --- a/webui/src/views/charts/components/ispPie.vue +++ b/webui/src/views/charts/components/ispPie.vue @@ -5,13 +5,24 @@ t('page.charts.title.geoip') + (option.bannedOnly ? t('page.charts.subtitle.bannedOnly') : '') " > - + @@ -46,14 +57,10 @@ - + -import { use } from 'echarts/core' +import { getGeoIPData } from '@/service/charts' +import { useDarkStore } from '@/stores/dark' +import dayjs from 'dayjs' import { PieChart } from 'echarts/charts' import { LegendComponent, TooltipComponent } from 'echarts/components' +import { use } from 'echarts/core' import { SVGRenderer } from 'echarts/renderers' import { computed, reactive, ref, watch } from 'vue' -import { getGeoIPData } from '@/service/charts' -import { useRequest } from 'vue-request' import VChart from 'vue-echarts' -import { useDarkStore } from '@/stores/dark' import { useI18n } from 'vue-i18n' -import dayjs from 'dayjs' +import { useRequest } from 'vue-request' const { t } = useI18n() @@ -168,7 +175,7 @@ watch(option, (v) => { run(v.range[0], v.range[1], option.bannedOnly) }) -const { loading, run,refresh } = useRequest(getGeoIPData, { +const { loading, run, refresh } = useRequest(getGeoIPData, { defaultParams: [dayjs().startOf('day').add(-7, 'day').toDate(), new Date(), option.bannedOnly], onSuccess: (data) => { if (data.data) { diff --git a/webui/src/views/charts/components/traffic.vue b/webui/src/views/charts/components/traffic.vue index ee9adc3221..6c0348098e 100644 --- a/webui/src/views/charts/components/traffic.vue +++ b/webui/src/views/charts/components/traffic.vue @@ -11,8 +11,8 @@ label-col-flex="100px" > @@ -50,7 +51,7 @@ const { t } = useI18n() .chart { height: 440px; } -.chart-error{ +.chart-error { display: flex; flex-direction: column; align-items: center; diff --git a/webui/src/views/dashboard/components/clientStatus.vue b/webui/src/views/dashboard/components/clientStatus.vue index 9d68c54384..2da1344536 100644 --- a/webui/src/views/dashboard/components/clientStatus.vue +++ b/webui/src/views/dashboard/components/clientStatus.vue @@ -46,7 +46,7 @@ - + {{ t('page.dashboard.torrentList.title') }} - + diff --git a/webui/src/views/dashboard/components/clientStatusCard.vue b/webui/src/views/dashboard/components/clientStatusCard.vue index 2a5c30423c..d38dd69954 100644 --- a/webui/src/views/dashboard/components/clientStatusCard.vue +++ b/webui/src/views/dashboard/components/clientStatusCard.vue @@ -113,19 +113,19 @@