diff --git a/.github/workflows/lint-and-fmt.yml b/.github/workflows/lint-and-fmt.yml
index 421b95359..fc10a93b9 100644
--- a/.github/workflows/lint-and-fmt.yml
+++ b/.github/workflows/lint-and-fmt.yml
@@ -74,3 +74,31 @@ jobs:
working-directory: packages/biliass/rust
run: |
cargo clippy --all-targets --all-features -- -D warnings
+
+ lint-and-fmt-docs:
+ name: Lint and Format (Docs)
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v2
+ with:
+ package_json_file: "docs/package.json"
+ version: "latest"
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: "22"
+ cache: "pnpm"
+ cache-dependency-path: "docs/pnpm-lock.yaml"
+
+ - name: Install dependencies
+ working-directory: ./docs
+ run: pnpm i --frozen-lockfile
+
+ - name: Format check
+ working-directory: ./docs
+ run: pnpm fmt:check
diff --git a/.github/workflows/vitepress-deploy.yml b/.github/workflows/vitepress-deploy.yml
new file mode 100644
index 000000000..2214032b9
--- /dev/null
+++ b/.github/workflows/vitepress-deploy.yml
@@ -0,0 +1,53 @@
+name: VitePress Deploy
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ merge_group:
+ workflow_dispatch:
+
+jobs:
+ build-and-deploy:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ submodules: true
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v2
+ with:
+ package_json_file: "docs/package.json"
+ version: "latest"
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: "22"
+ cache: "pnpm"
+ cache-dependency-path: "docs/pnpm-lock.yaml"
+
+ - name: Install dependencies
+ working-directory: ./docs
+ run: pnpm i --frozen-lockfile
+
+ - name: Build VitePress site
+ working-directory: ./docs
+ run: pnpm build
+
+ - name: Deploy
+ uses: peaceiris/actions-gh-pages@v3
+ if: github.ref == 'refs/heads/main'
+ with:
+ personal_token: ${{ secrets.PERSONAL_TOKEN }}
+ publish_dir: docs/.vitepress/dist
+ external_repository: SigureMo/docs
+ publish_branch: yutto
+ force_orphan: true
+ commit_message: ":rocket: deploy: "
+ user_name: "github-actions[bot]"
+ user_email: "github-actions[bot]@users.noreply.github.com"
diff --git a/README.md b/README.md
index 40b22dd26..1f4f3df3c 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-# yutto2.0.0
+# yutto
-
+
@@ -16,15 +16,48 @@
-🧊 yutto,一个可爱且任性的 B 站下载器(CLI)
+🧊 yutto,一个可爱且任性的 B 站视频下载器(CLI)
+
+**完整静态文档在这里喔 → [yutto](https://yutto.nyakku.moe/)**
> [!TIP]
>
> 如果在使用过程中遇到问题,请通过 [Issues](https://github.com/yutto-dev/yutto/issues) 反馈功能正确性问题和功能请求,其他问题请通过 [Discussions](https://github.com/yutto-dev/yutto/discussions) 反馈~
-## 版本号为什么是 2.0
-
-因为 yutto 是 [bilili](https://github.com/yutto-dev/bilili) 的後輩呀~
+## 什么是 yutto?
+
+yutto 是一个 B 站视频下载器,它可以帮助你下载 B 站上的投稿视频、番剧、课程等资源,支持单个视频下载、批量下载等功能,就像这样:
+
+```bash
+❯ yutto https://www.bilibili.com/video/BV1ZEf9YiE2h/
+ INFO 发现配置文件 yutto.toml,加载中……
+ 大会员 成功以大会员身份登录~
+ 投稿视频 植物大战僵尸融合版2.2正式版宣传片
+ INFO 开始处理视频 植物大战僵尸融合版2.2正式版宣传片
+ INFO 共包含以下 15 个视频流:
+ INFO * 0 [AVC ] [1920x1080] <1080P 60帧> #3
+ INFO 1 [HEVC] [1920x1080] <1080P 60帧> #3
+ INFO 2 [AV1 ] [1920x1080] <1080P 60帧> #3
+ INFO 3 [AVC ] [1920x1080] <1080P 高清> #3
+ INFO 4 [HEVC] [1920x1080] <1080P 高清> #3
+ INFO 5 [AV1 ] [1920x1080] <1080P 高清> #3
+ INFO 6 [AVC ] [1280x720 ] <720P 高清 > #3
+ INFO 7 [HEVC] [1280x720 ] <720P 高清 > #3
+ INFO 8 [AV1 ] [1280x720 ] <720P 高清 > #3
+ INFO 9 [AVC ] [ 852x480 ] <480P 清晰 > #3
+ INFO 10 [HEVC] [ 852x480 ] <480P 清晰 > #3
+ INFO 11 [AV1 ] [ 852x480 ] <480P 清晰 > #3
+ INFO 12 [AVC ] [ 640x360 ] <360P 流畅 > #3
+ INFO 13 [HEVC] [ 640x360 ] <360P 流畅 > #3
+ INFO 14 [AV1 ] [ 640x360 ] <360P 流畅 > #3
+ INFO 共包含以下 3 个音频流:
+ INFO * 0 [MP4A] <320kbps >
+ INFO 1 [MP4A] < 64kbps >
+ INFO 2 [MP4A] <128kbps >
+ 弹幕 ASS 弹幕已生成
+ INFO 开始下载……
+━━━━━━━━━━━━━━━━━━━━━━━━━━━╸━━━━━━━━━━━━━━━━━━━━━━ 39.05 MiB/ 72.13 MiB 32.22 MiB/⚡
+```
## 从安装开始~
@@ -90,28 +123,6 @@ uv tool install git+https://github.com/yutto-dev/yutto.git@main # 通过
## 主要功能
-### 已支持的下载类型
-
-
-| 类型 | 是否支持选集 | 示例链接 | 默认路径模板 |
-| - | - | - | - |
-| 投稿视频 | - | `https://www.bilibili.com/video/BV1vZ4y1M7mQ`
`https://www.bilibili.com/video/av371660125`
`https://www.bilibili.com/video/BV1vZ4y1M7mQ?p=1`
`av371660125`
`BV1vZ4y1M7mQ` | `{title}` |
-| 投稿视频 批量 | :white_check_mark: | `https://www.bilibili.com/video/BV1vZ4y1M7mQ`
`https://www.bilibili.com/video/av371660125`
`av371660125`
`BV1vZ4y1M7mQ` | `{title}/{name}` |
-| 番剧 | - | `https://www.bilibili.com/bangumi/play/ep395211`
`ep395211` | `{name}` |
-| 番剧 批量 | :white_check_mark: | `https://www.bilibili.com/bangumi/play/ep395211`
`https://www.bilibili.com/bangumi/play/ss38221`
`https://www.bilibili.com/bangumi/media/md28233903`
`ep395211`
`ss38221`
`md28233903` | `{title}/{name}` |
-| 课程 | - | `https://www.bilibili.com/cheese/play/ep6902` | `{name}` |
-| 课程 批量 | :white_check_mark: | `https://www.bilibili.com/cheese/play/ep6902`
`https://www.bilibili.com/cheese/play/ss298` | `{title}/{name}` |
-| 用户指定收藏夹 批量 | :x: | `https://space.bilibili.com/100969474/favlist?fid=1306978874&ftype=create` | `{username}的收藏夹/{series_title}/{title}/{name}` |
-| 当前用户稍后再看 批量 | :x: | `https://www.bilibili.com/watchlater` | `稍后再看/{title}/{name}` |
-| 用户全部收藏夹 批量 | :x: | `https://space.bilibili.com/100969474/favlist` | `{username}的收藏夹/{series_title}/{title}/{name}` |
-| UP 主个人空间 批量 | :x: | `https://space.bilibili.com/100969474/video` | `{username}的全部投稿视频/{title}/{name}` |
-| 合集 批量 | :white_check_mark: | `https://space.bilibili.com/3546619314178489/lists?sid=3221717?type=season`
`https://space.bilibili.com/3546619314178489/channel/collectiondetail?sid=3221717`旧版页面
`https://space.bilibili.com/100969474/favlist?fid=3221717&ftype=collect&ctype=21` | `{series_title}/{title}` |
-| 视频列表 批量 | :x: | `https://space.bilibili.com/100969474/lists/1947439?type=series`
`https://space.bilibili.com/100969474/channel/seriesdetail?sid=1947439`旧版页面
`https://www.bilibili.com/list/100969474?sid=1947439` | `{series_title}/{title}/{name}` |
-
-> [!NOTE]
->
-> 标记「批量」的视频都必须通过 `-b/--batch` 参数来下载,否则会按照单个视频来解析下载
-
### 基本命令
yutto 的基本命令如下:
@@ -144,764 +155,9 @@ yutto ep395211
yutto --batch https://www.bilibili.com/bangumi/play/ep395211
```
-### 基础参数
-
-yutto 支持一些基础参数,无论是批量下载还是单视频下载都适用。
-
-
-点击展开详细参数
-
-#### 最大并行 worker 数量
-
-- 参数 `-n` 或 `--num-workers`
-- 默认值 `8`
-
-与 bilili 不同的是,yutto 并不是使用多线程实现并行下载,而是使用协程实现的,本参数限制的是最大的并行 Worker 数量。
-
-#### 指定视频清晰度等级
-
-- 参数 `-q` 或 `--video-quality`
-- 可选值 `127 | 126 | 125 | 120 | 116 | 112 | 100 | 80 | 74 | 64 | 32 | 16`
-- 默认值 `127`
-
-清晰度对应关系如下
-
-
-| code | 清晰度 |
-| :-: | :-: |
-| 127 | 8K 超高清 |
-| 126 | 杜比视界 |
-| 125 | HDR 真彩 |
-| 120 | 4K 超清 |
-| 116 | 1080P 60帧 |
-| 112 | 1080P 高码率 |
-| 100 | 智能修复 |
-| 80 | 1080P 高清 |
-| 74 | 720P 60帧 |
-| 64 | 720P 高清 |
-| 32 | 480P 清晰 |
-| 16 | 360P 流畅 |
-
-并不是说指定某个清晰度就一定会下载该清晰度的视频,yutto 只会尽可能满足你的要求,如果不存在指定的清晰度,yutto 就会按照默认的清晰度搜索机制进行调节,比如指定清晰度为 `80`,**首先会依次降清晰度搜索** `74`、`64`、`32`、`16`,如果依然找不到合适的则**继续升清晰度搜索** `100`、`112`、`116`、`120`、`125`、`126`、`127`。
-
-值得注意的是,目前杜比视界视频只能简单下载音视频流并合并,合并后并不能达到在线观看的效果。
-
-#### 指定音频码率等级
-
-- 参数 `-aq` 或 `--audio-quality`
-- 可选值 `30251 | 30255 | 30250 | 30280 | 30232 | 30216`
-- 默认值 `30251`
-
-码率对应关系如下
-
-
-| code | 码率 |
-| :-: | :-: |
-| 30251 | - (Hi-Res) |
-| 30255 | - (杜比音效) |
-| 30250 | - (杜比全景声) |
-| 30280 | 320kbps |
-| 30232 | 128kbps |
-| 30216 | 64kbps |
-
-码率自动调节机制与视频清晰度一致,也采用先降后升的匹配机制。
-
-#### 指定视频编码
-
-- 参数 `--vcodec`
-- 下载编码可选值 `"av1" | "hevc" | "avc"`
-- 保存编码可选值 FFmpeg 所有可用的视频编码器
-- 默认值 `"avc:copy"`
-
-该参数略微复杂,前半部分表示在下载时**优先**选择哪一种编码的视频流,后半部分则表示在合并时如何编码视频流,两者使用 `:` 分隔。
-
-值得注意的是,前半的下载编码只是优先下载的编码而已,如果不存在该编码,则会根据 `--download-vcodec-priority` 自动选择其余编码,如未设置 `--download-vcodec-priority`,则会类似视频清晰度调节机制先降序后升序的方式来选择。
-
-而后半部分的参数如果设置成非 `copy` 的值则可以确保在下载完成后对其进行重新编码,而且不止支持 `av1`、`hevc` 与 `avc`,只要你的 FFmpeg 支持的视频编码器,它都可以完成。
-
-#### 指定音频编码
-
-- 参数 `--acodec`
-- 下载编码可选值 `"mp4a"`
-- 保存编码可选值 FFmpeg 所有可用的音频编码器
-- 默认值 `"mp4a:copy"`
-
-详情同视频编码。
-
-#### 指定视频下载编码优先级
-
-- 参数 `--download-vcodec-priority`
-- 默认值 `"auto"`
-- 可选值 `"auto"` 或者使用 `,` 分隔的下载编码列表,如 `"hevc,avc,av1"`
-
-当使用默认值 `"auto"` 时,yutto 会类似视频清晰度调节机制先降序后升序的方式来选择。
-
-当使用自定义下载编码列表时,yutto 会严格按照列表中的顺序进行选择,如果不存在则会认为该视频无视频流。
-
-
-
-> **Warning**
->
-> 如若设置本参数,请总是将 `--download-vcode-priority` 首选编码作为 `--vcodec` 的前半部分,否则可能会导致下载失败。
-
-#### 指定输出格式
-
-- 参数 `--output-format`
-- 可选值 `"infer" | "mp4" | "mkv" | "mov"`
-- 默认值 `"infer"`
-
-在至少包含视频流时所使用的输出格式,默认选值 `"infer"` 表示自动根据情况进行推导以保证输出的可用,推导规则如下:
-
-- 如果输出包含音频流且音频流编码为 `"fLaC"`,则输出格式为 `"mkv"`,因为 `"mp4"` 尚不支持 `"fLaC"` 编码
-- 否则为 `"mp4"`
-
-#### 指定在仅包含音频流时的输出格式
-
-- 参数 `--output-format-audio-only`
-- 可选值 `"infer" | "m4a" | "aac" | "mp3" | "flac" | "mp4" | "mkv" | "mov"`
-- 默认值 `"infer"`
-
-在仅包含音频流时所使用的输出格式,默认选值 `"infer"` 表示自动根据情况进行推导以保证输出的可用,推导规则如下:
-
-- 如果音频流编码为 `"fLaC"`,则输出格式为 `"flac"`
-- 否则为 `"m4a"`
-
-> **Note**
->
-> 并不是仅仅在指定 `--audio-only` 时才会仅仅包含视频流,有些视频是仅包含音频流的,此时即便不指定 `--audio-only` 选项也会按照本选项的格式进行输出。
-
-#### 弹幕格式选择
-
-- 参数 `-df` 或 `--danmaku-format`
-- 可选值 `"ass" | "xml" | "protobuf"`
-- 默认值 `"ass"`
-
-B 站提供了 `xml` 与 `protobuf` 两种弹幕数据接口,`xml` 接口为旧接口,弹幕数上限较低,`protobuf` 接口相对较高,但不登录情况下只能获取很少的弹幕
-
-为了确保无论是否登录都能获取最多的弹幕,yutto 在登录时会下载 `protobuf` 源数据,在未登录时会下载 `xml` 源数据,并将其转换为主流播放器支持的 `ass` 格式
-
-如果你不喜欢 yutto 自动转换的效果,可以选择输出格式为 `xml` 或 `protobuf`,手动通过一些工具进行转换,比如 yutto 和 bilili 所使用的 [biliass](https://github.com/yutto-dev/yutto/tree/main/packages/biliass),或者使用 [us-danmaku](https://tiansh.github.io/us-danmaku/bilibili/) 进行在线转换。
-
-如果你不想下载弹幕,只需要使用参数 `--no-danmaku` 即可。
-
-#### 下载块大小
-
-- 参数 `-bs` 或 `--block-size`
-- 默认值 `0.5`
-
-以 MiB 为单位,为分块下载时各块大小,不建议更改。
-
-#### 强制覆盖已下载文件
-
-- 参数 `-w` 或 `--overwrite`
-- 默认值 `False`
-
-#### 代理设置
-
-- 参数 `-x` 或 `--proxy`
-- 可选值 `"auto" | "no" | `
-- 默认值 `"auto"`
-
-设置代理服务器,默认是从环境变量读取,`no` 则为不设置代理,设置其它 http/https url 则将其作为代理服务器。
-
-#### 存放根目录
-
-- 参数 `-d` 或 `--dir`
-- 默认值 `"./"`
-
-#### 临时文件目录
-
-- 参数 `--tmp-dir`
-- 默认值是“存放根目录”即 `-d, --dir` 的值
-
-#### Cookies 设置
-
-- 参数 `-c` 或 `--sessdata`
-- 默认值 `""`
-
-设置 Cookies 后你才可以下载更高清晰度以及更多的剧集,当你传入你的大会员 `SESSDATA` 时(当然前提是你是大会员),你就可以下载大会员可访问的资源咯。
-
- SESSDATA 获取方式
-
-这里用 Chrome 作为示例,其它浏览器请尝试类似方法。
-
-首先,用你的帐号登录 B 站,然后随便打开一个 B 站网页,比如[首页](https://www.bilibili.com/)。
-
-按 F12 打开开发者工具,切换到 Network 栏,刷新页面,此时第一个加载的资源应该就是当前页面的 html,选中该资源,在右侧 「Request Headers」 中找到 「cookie」,在其中找到类似于 `SESSDATA=d8bc7493%2C2843925707%2C08c3e*81;` 的一串字符串,复制这里的 `d8bc7493%2C2843925707%2C08c3e*81`,这就是你需要的 `SESSDATA`。
-
-
-
-另外,由于 SESSDATA 中可能有特殊符号,所以传入时你可能需要使用双引号来包裹
-
-```bash
-yutto -c "d8bc7493%2C2843925707%2C08c3e*81"
-```
-
-当然,示例里的 SESSDATA 是无效的,请使用自己的 SESSDATA。
-
-#### 存放子路径模板
-
-- 参数 `-tp` 或 `--subpath-template`
-- 可选参数变量 `title | id | name | username | series_title | pubdate | download_date | owner_uid` (以后可能会有更多)
-- 默认值 `"{auto}"`
-
-通过配置子路径模板可以灵活地控制视频存放位置。
-
-默认情况是由 yutto 自动控制存放位置的。比如下载单个视频时默认就是直接存放在设定的根目录,不会创建一层容器目录,此时自动选择了 `{name}` 作为模板;而批量下载时则会根据视频层级生成多级目录,比如番剧会是 `{title}/{name}`,首先会在设定根目录里生成一个番剧名的目录,其内才会存放各个番剧剧集视频,这样方便了多个不同番剧的管理。当然,如果你仍希望将番剧直接存放在设定根目录下的话,可以修改该参数值为 `{name}`即可。
-
-另外,该功能语法由 Python format 函数模板语法提供,所以也支持一些高级的用法,比如 `{id:0>3}{name}`,此外还专门为时间变量 🕛 增加了自定义时间模板的语法 `{pubdate@%Y-%m-%d %H:%M:%S}`,默认时间模板为 `%Y-%m-%d`。
-
-值得注意的是,并不是所有变量在各种场合下都会提供,比如 `username`, `owner_uid` 变量当前仅在 UP 主全部投稿视频/收藏夹/稍后再看才提供,在其它情况下不应使用它。各变量详细作用域描述见下表:
-
-
-| Variable | Description | Scope |
-| - | - | - |
-| title | 系列视频总标题(番剧名/投稿视频标题) | 全部 |
-| id | 系列视频单 p 顺序标号 | 全部 |
-| aid | 视频 AV 号,早期使用的视频 ID,不建议使用,详见 [AV 号全面升级公告](https://www.bilibili.com/blackboard/activity-BV-PC.html) | 全部 |
-| bvid | 视频 BV 号,即视频 ID | 全部 |
-| name | 系列视频单 p 标题 | 全部 |
-| username | UP 主用户名 | 个人空间、收藏夹、稍后再看、合集、视频列表下载 |
-| series_title | 合集标题 | 收藏夹、视频合集、视频列表下载 |
-| pubdate🕛 | 投稿日期 | 仅投稿视频 |
-| download_date🕛 | 下载日期 | 全部 |
-| owner_uid | UP 主 UID | 个人空间、收藏夹、稍后再看、合集、视频列表下载 |
-
-> **Note**
->
-> 未来可能会对路径变量及默认路径模板进行调整
-
-#### url 别名文件路径
-
-- 参数 `-af` 或 `--alias-file`
-- 默认值 `None`
-
-指定别名文件路径,别名文件中存放一个别名与其对应的 url,使用空格或者 `=` 分隔,示例如下:
-
-```
-tensura1=https://www.bilibili.com/bangumi/play/ss25739/
-tensura2=https://www.bilibili.com/bangumi/play/ss36170/
-tensura-nikki=https://www.bilibili.com/bangumi/play/ss38221/
-```
-
-比如将上述内容存储到 `~/.yutto_alias`,则通过以下命令即可解析该文件:
-
-```bash
-yutto tensura1 --batch --alias-file='~/.yutto_alias'
-```
-
-当参数值为 `-` 时,会从标准输入中读取:
-
-```bash
-cat ~/.yutto_alias | yutto tensura-nikki --batch --alias-file -
-```
-
-#### 指定媒体元数据值的格式
-
-当前仅支持 `premiered`
-
-- 参数 `--metadata-format-premiered`
-- 默认值 `"%Y-%m-%d"`
-- 常用值 `"%Y-%m-%d %H:%M:%S"`
-
-#### 严格校验大会员状态有效
-
-- 参数 `--vip-strict`
-- 默认值 `False`
-
-#### 严格校验登录状态有效
-
-- 参数 `--login-strict`
-- 默认值 `False`
-
-#### 设置下载间隔
-
-- 参数 `--download-interval`
-- 默认值 `0`
-
-设置两话之间的下载间隔(单位为秒),避免短时间內下载大量视频导致账号被封禁
-
-#### 禁用下载镜像
-
-- 参数 `--banned-mirrors-pattern`
-- 默认值 `None`
-
-使用正则禁用特定镜像,比如 `--banned-mirrors-pattern "mirrorali"` 将禁用 url 中包含 `mirrorali` 的镜像
-
-#### 不显示颜色
-
-- 参数 `--no-color`
-- 默认值 `False`
-
-#### 不显示进度条
-
-- 参数 `--no-progress`
-- 默认值 `False`
-
-#### 启用 Debug 模式
-
-- 参数 `--debug`
-- 默认值 `False`
-
-
-
-### 资源选择参数
-
-此外有一些参数专用于资源选择,比如选择是否下载弹幕、音频、视频等等。
-
-
-点击展开详细参数
-
-#### 仅下载视频流
-
-- 参数 `--video-only`
-- 默认值 `False`
-
-> **Note**
->
-> 这里「仅下载视频流」是指视频中音视频流仅选择视频流,而不是仅仅下载视频而不下载弹幕字幕等资源,如果需要取消字幕等资源下载,请额外使用 `--no-danmaku` 等参数。
->
-> 「仅下载音频流」也是同样的。
-
-#### 仅下载音频流
-
-- 参数 `--audio-only`
-- 默认值 `False`
-
-仅下载其中的音频流,保存为 `.m4a` 文件。
-
-#### 不生成弹幕文件
-
-- 参数 `--no-danmaku`
-- 默认值 `False`
-
-#### 仅生成弹幕文件
-
-- 参数 `--danmaku-only`
-- 默认值 `False`
-
-#### 不生成字幕文件
-
-- 参数 `--no-subtitle`
-- 默认值 `False`
-
-#### 仅生成字幕文件
-
-- 参数 `--subtitle-only`
-- 默认值 `False`
-
-#### 生成媒体元数据文件
-
-- 参数 `--with-metadata`
-- 默认值 `False`
-
-目前媒体元数据生成尚在试验阶段,可能提取出的信息并不完整。
-
-#### 仅生成媒体元数据文件
-
-- 参数 `--metadata-only`
-- 默认值 `False`
-
-#### 不生成视频封面
-
-- 参数 `--no-cover`
-- 默认值 `False`
-
-> [!NOTE]
->
-> 当前仅支持为包含视频流的视频生成封面。
-
-#### 生成视频流封面时单独保存封面
-
-- 参数 `--save-cover`
-- 默认值 `False`
-
-#### 仅生成视频封面
-
-- 参数 `--cover-only`
-- 默认值 `False`
-
-#### 不生成章节信息
-
-- 参数 `--no-chapter-info`
-- 默认值 `False`
-
-不生成章节信息,包含 MetaData 和嵌入视频流的章节信息。
-
-
-
-### 弹幕设置参数Experimental
-
-yutto 通过与 biliass 的集成,提供了一些 ASS 弹幕选项,包括字号、字体、速度等~
-
-
-点击展开详细参数
-
-#### 弹幕字体大小
-
-- 参数 `--danmaku-font-size`
-- 默认值 `video_width / 40`
-
-#### 弹幕字体
-
-- 参数 `--danmaku-font`
-- 默认值 `"SimHei"`
-
-#### 弹幕不透明度
-
-- 参数 `--danmaku-opacity`
-- 默认值 `0.8`
-
-#### 弹幕显示区域与视频高度的比例
-
-- 参数 `--danmaku-display-region-ratio`
-- 默认值 `1.0`
-
-#### 弹幕速度
-
-- 参数 `--danmaku-speed`
-- 默认值 `1.0`
-
-#### 屏蔽顶部弹幕
-
-- 参数 `--danmaku-block-top`
-- 默认值 `False`
-
-#### 屏蔽底部弹幕
-
-- 参数 `--danmaku-block-bottom`
-- 默认值 `False`
-
-#### 屏蔽滚动弹幕
-
-- 参数 `--danmaku-block-scroll`
-- 默认值 `False`
-
-#### 屏蔽逆向弹幕
-
-- 参数 `--danmaku-block-reverse`
-- 默认值 `False`
-
-#### 屏蔽固定弹幕(顶部、底部)
-
-- 参数 `--danmaku-block-fixed`
-- 默认值 `False`
-
-#### 屏蔽高级弹幕
-
-- 参数 `--danmaku-block-special`
-- 默认值 `False`
-
-#### 屏蔽彩色弹幕
-
-- 参数 `--danmaku-block-colorful`
-- 默认值 `False`
-
-#### 屏蔽关键词
-
-- 参数 `--danmaku-block-keyword-patterns`
-- 默认值 `None`
-
-按关键词屏蔽,支持正则,使用 `,` 分隔
-
-
-
-### 批量参数
-
-有些参数是只有批量下载时才可以使用的
-
-
-点击展开详细参数
-
-#### 启用批量下载
-
-- 参数 `-b` 或 `--batch`
-- 默认值 `False`
-
-只需要 `yutto --batch ` 即可启用批量下载功能。
-
-#### 选集
-
-- 参数 `-p` 或 `--episodes`
-- 默认值 `1~-1`(也即全选)
-
-也就是选集咯,其语法是这样的
-
-- `` 单独下某一剧集
- - 支持负数来选择倒数第几话
- - 此外还可以使用 `$` 来代表 `-1`
-- `~` 使用 `~` 可以连续选取(如果起始为 1,或者终止为 -1 则可以省略)
-- `,,,...,` 使用 `,` 可以不连续选取
-
-emmm,直接看的话大概并不能知道我在说什么,所以我们通过几个小例子来了解其语法
-
-```bash
-# 假设要下载一个具有 24 话的番剧
-# 如果我们只想下载第 3 话,只需要这样
-yutto -b -p 3
-# 那如果我想下载第 5 话到第 7 话呢,使用 `~` 可以连续选中
-yutto -b -p 5~7
-# 那我想下载第 12 话和第 17 话又要怎么办?此时只需要 `,` 就可以将多个不连续的选集一起选中
-yutto -b -p 12,17
-# 那我突然又想将刚才那些都选中了呢?还是使用 `,` 呀,将它们连在一起即可
-yutto -b -p 3,5~7,12,17
-# 嗯,你已经把基本用法都了解过了,很简单吧~
-# 下面是一些语法糖,不了解也完全不会影响任何功能哒~
-# 那如果我只知道我想下载倒数第 3 话,而不想算倒数第三话是第几话应该怎么办?
-# 此时可以用负数哒~不过要注意的是,这种参数以 `-` 开头参数需要使用 `=` 来连接选项和参数
-yutto -b -p=-3
-# 那么如果想下载最后一话你可能会想到 `-p=-1` 对吧?不过我内置了符号 $ 用于代表最后一话
-# 像下面这样就可以直接下载最后一话啦~
-yutto -b -p $
-# 为了进一步方便表示一个范围选取,在从第一话开始选取或者以最后一话为终止时可以省略它们
-# 这样就是前三话啦(这里与以 `-` 开头类似,以 `~` 开头可能被识别为 $HOME,因此最好也用等号,或者使用引号包裹)
-yutto -b -p=~3
-# 这样就是后四话啦
-yutto -b -p=-4~
-# 所有语法都了解完啦,我们看一个稍微复杂的例子
-yutto -b -p "~3,10,12~14,16,-4~"
-# 很明显,上面的例子就是下载前 3 话、第 10 话、第 12 到 14 话、第 16 话以及后 4 话
-```
-
-下面是一些要注意的问题
-
-1. 这里使用的序号是视频的顺序序号,而不是番剧所标注的`第 n 话`,因为有可能会出现 `第 x.5 话` 等等的特殊情况,此时一定要按照顺序自行计数。
-2. 参数值里一定不要加空格
-3. 参数值开头为特殊符号时最好使用 `=` 来连接选项和参数,或者尝试使用引号包裹参数
-4. 个人空间、视频列表、收藏夹等批量下载暂不支持选集操作
-
-#### 同时下载附加剧集
-
-- 参数 `-s` 或 `--with-section`
-- 默认值 `False`
-
-#### 指定稿件发布时间范围
-
-- 参数 `--batch-filter-start-time` 和 `--batch-filter-end-time` 分别表示`开始`和`结束`时间,该区间**左闭右开**
-- 默认 `不限制`
-- 支持的格式
-
- - `%Y-%m-%d`
- - `%Y-%m-%d %H:%M:%S`
-
- 例如仅下载 2020 年投稿的视频,可以这样:
-
- `--batch-filter-start-time=2020-01-01 --batch-filter-end-time=2021-01-01`
-
-
-
-### 配置文件Experimental
-
-yutto 自 `2.0.0-rc.3` 起增加了实验性的配置文件功能,你可以通过 `--config` 选项来指定配置文件路径,比如
-
-```bash
-yutto --config /path/to/config.toml
-```
-
-如果不指定配置文件路径,yutto 也支持配置自动发现,根据优先级,搜索路径如下:
-
-- 当前目录下的 `yutto.toml`
-- 搜索 [`XDG_CONFIG_HOME`](https://specifications.freedesktop.org/basedir-spec/latest/) 下的 `yutto/yutto.toml` 文件
-- 非 Windows 系统下的 `~/.config/yutto/yutto.toml`,Windows 系统下的 `~/AppData/Roaming/yutto/yutto.toml`
-
-你可以通过配置文件来设置一些默认参数,整体上与命令行参数基本一致,下面以一些示例来展示配置文件的写法:
-
-```toml
-# yutto.toml
-#:schema https://raw.githubusercontent.com/yutto-dev/yutto/refs/heads/main/schemas/config.json
-[basic]
-# 设置下载目录
-dir = "/path/to/download"
-# 设置临时文件目录
-tmp_dir = "/path/to/tmp"
-# 设置 SESSDATA
-sessdata = "***************"
-# 设置大会员严格校验
-vip_strict = true
-# 设置登录严格校验
-login_strict = true
-
-[resource]
-# 不下载字幕
-require_subtitle = false
-
-[danmaku]
-# 设置弹幕速度
-speed = 2.0
-# 设置弹幕屏蔽关键词
-block_keyword_patterns = [
- ".*keyword1.*",
- ".*keyword2.*",
-]
-
-[batch]
-# 下载额外剧集
-with_section = true
-```
-
-如果你使用 VS Code 对配置文件编辑,强烈建议使用 [Even Better TOML](https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml) 扩展,配合 yutto 提供的 schema,可以获得最佳的提示体验。
+### 更多功能
-## 从 bilili1.x 迁移
-
-### 取消的功能
-
-- `- bilibili` 目录的生成
-- 播放列表生成
-- 源格式修改功能(不再支持 flv 源视频下载,如果仍有视频不支持 dash 源,请继续使用 bilili)
-- 对 Python3.8 的支持,最低支持 Python3.9
-- 下载前询问
-- 弃用选集语法糖开始符号 `^`,直接使用明确的剧集号 `1` 即可
-
-### 默认行为的修改
-
-- 使用协程而非多线程进行下载
-- 默认生成弹幕为 ASS
-- 默认启用从多镜像源下载的特性
-- 不仅可以控制是否使用系统代理,还能配置特定的代理服务器
-
-### 新增的特性
-
-- 单视频下载与批量下载命令分离(`bilili` 命令与 `yutto --batch` 相类似)
-- 音频/视频编码选择
-- 可选仅下载音频/视频
-- 存放子路径的自由定制
-- 支持 url 别名
-- 支持文件列表
-- 更多的批下载支持(现已支持 UP 主全部投稿视频、视频合集、收藏夹等)
-- 更加完善的 warning 与 error 提示
-- 支持仅输入 id 即可下载(aid、bvid、episode_id 等)
-- 支持描述文件生成
-- 将链接解析延迟到下载前一刻,避免短时间大量请求导致 IP 被封的问题
-
-## 小技巧
-
-### 作为 log 输出到文件
-
-虽说 yutto 不像 bilili 那样会全屏刷新,但进度条还是会一直刷新占据多行,可能影响 log 的阅读,另外颜色码也是难以阅读的,因此我们可以通过选项禁用他们:
-
-```bash
-yutto --no-color --no-progress > log
-```
-
-### 使用配置自定义默认参数
-
-如果你希望修改 yutto 的部分参数,那么可能每次运行都需要在后面加上长长一串选项,为了避免这个问题,你可以尝试使用配置文件
-
-```toml
-# ~/.config/yutto/yutto.toml
-#:schema https://raw.githubusercontent.com/yutto-dev/yutto/refs/heads/main/schemas/config.json
-[basic]
-dir = "~/Movies/yutto"
-sessdata = "***************"
-num_workers = 16
-vcodec = "av1:copy"
-```
-
-当然,请手动修改 `sessdata` 内容为自己的 `SESSDATA` 哦~
-
-> [!TIP]
->
-> 本方案可替代原有的「自定义命令别名」方式~
->
->
-> 原「自定义命令别名」方案
->
-> 在 `~/.zshrc` / `~/.bashrc` 中自定义一条 alias,像这样
->
-> ```bash
-> alias ytt='yutto -d ~/Movies/yutto/ -c `cat ~/.sessdata` -n 16 --vcodec="av1:copy"'
-> ```
->
-> 这样我每次只需要 `ytt ` 就可以直接使用这些参数进行下载啦~
->
-> 由于我提前在 `~/.sessdata` 存储了我的 `SESSDATA`,所以避免每次都要手动输入 cookie 的问题。
->
->
-
-### 使用 url alias
-
-yutto 新增的 url alias 可以让你下载正在追的番剧时不必每次都打开浏览器复制 url,只需要将追番列表存储在一个文件中,并为这些 url 起一个别名即可
-
-```
-tensura-nikki=https://www.bilibili.com/bangumi/play/ss38221/
-```
-
-之后下载最新话只需要
-
-```
-yutto --batch tensura-nikki --alias-file=/path/to/alias-file
-```
-
-你同样可以通过配置文件来实现这一点(推荐)
-
-```toml
-# ~/.config/yutto/yutto.toml
-#:schema https://raw.githubusercontent.com/yutto-dev/yutto/refs/heads/main/schemas/config.json
-[basic.aliases]
-tensura-nikki = "https://www.bilibili.com/bangumi/play/ss38221/"
-```
-
-### 使用任务列表
-
-现在 url 不仅支持 http/https 链接与裸 id,还支持使用文件路径与 file scheme 来用于表示文件列表,文件列表以行分隔,每行写一次命令的参数,该参数会覆盖掉主程序中所使用的参数,示例如下:
-
-首先将下面的文件存储到一个地方
-
-```
-https://www.bilibili.com/bangumi/play/ss38221/ --batch -p $
-https://www.bilibili.com/bangumi/play/ss38260/ --batch -p $
-```
-
-然后运行
-
-```
-yutto file:///path/to/list
-```
-
-即可分别下载这两个番剧的最新一话
-
-或者直接使用相对或者绝对路径也是可以的
-
-```
-yutto ./path/to/list
-```
-
-值得注意的是,在文件列表各项里的参数优先级是高于命令里的优先级的,比如文件中使用:
-
-```
-tensura1 --batch -p $ --no-danmaku --vcodec="hevc:copy"
-tensura2 --batch -p $
-```
-
-而命令中则使用
-
-```
-yutto file:///path/to/list --vcodec="avc:copy"
-```
-
-最终下载的 tensura1 会是 "hevc:copy",而 tensura2 则会是 "avc:copy"
-
-另外,文件列表也是支持 alias 的,你完全可以为该列表起一个别名,一个比较特别的用例是将你所有追番的内容放在一个文件里,然后为该文件起一个别名(比如 `subscription`),这样只需要 `yutto subscription --alias-file path/to/alias/file` 就可以达到追番效果啦~
-
-最后,列表也是支持嵌套的哦(虽然没什么用 2333)
-
-## FAQ
-
-### 名字的由来
-
-[《転スラ日記》第一话 00:24](https://www.bilibili.com/bangumi/play/ep395211?t=24)
-
-### 何谓「任性」?
-
-yutto 添加任何特性都需要以保证可维护性为前提,因此 yutto 不会添加过于复杂的特性,只需要满足够用即可。
-
-### yutto 会替代 bilili 吗
-
-yutto 自诞生以来已经过去三年多了,功能上基本可以替代 bilili 了,由于 B 站接口的不断变化,bilili 也不再适用于现在的环境,因此请 bilili 用户尽快迁移到 yutto ~
+yutto 还支持很多功能,限于篇幅不在 `README` 中展示,你可以前往 [yutto 文档](https://yutto.nyakku.moe/) 查看更多详细内容~
## 其他应用
@@ -921,7 +177,7 @@ yutto 自诞生以来已经过去三年多了,功能上基本可以替代 bili
### future
-- [ ] docs: 可爱的静态文档(WIP in [#86](https://github.com/yutto-dev/yutto/pull/86))
+- [x] docs: 可爱的静态文档(WIP in [#86](https://github.com/yutto-dev/yutto/pull/86))
- [ ] feat: 新的基于 toml 的任务列表
- [ ] refactor: 配置参数复用 pydantic 验证
- [ ] refactor: 针对视频合集优化路径变量
@@ -930,13 +186,6 @@ yutto 自诞生以来已经过去三年多了,功能上基本可以替代 bili
- [ ] feat: 更多批下载支持
- [ ] feat: 以及更加可爱~
-## 参考
-
-- 基本结构:
-- 协程下载:
-- 弹幕转换:
-- 样式设计:
-
## 参与贡献
请阅读 [CONTRIBUTING.md](CONTRIBUTING.md)
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 000000000..99e395a90
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,8 @@
+node_modules
+.temp
+.cache
+dist/
+lib/
+*.tsbuildinfo
+.DS_Store
+.vitepress/cache
diff --git a/docs/.prettierignore b/docs/.prettierignore
new file mode 100644
index 000000000..6bc17221f
--- /dev/null
+++ b/docs/.prettierignore
@@ -0,0 +1,6 @@
+*.html
+dist/
+node_modules/
+*.min.js
+lib/*
+pnpm-lock.yaml
diff --git a/docs/.prettierrc b/docs/.prettierrc
new file mode 100644
index 000000000..80a3b854b
--- /dev/null
+++ b/docs/.prettierrc
@@ -0,0 +1,22 @@
+{
+ "printWidth": 100,
+ "tabWidth": 2,
+ "singleQuote": true,
+ "trailingComma": "es5",
+ "semi": false,
+ "arrowParens": "always",
+ "overrides": [
+ {
+ "files": "*.md",
+ "options": {
+ "tabWidth": 3
+ }
+ },
+ {
+ "files": "*.json5",
+ "options": {
+ "singleQuote": false
+ }
+ }
+ ]
+}
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts
new file mode 100644
index 000000000..83eceb9f2
--- /dev/null
+++ b/docs/.vitepress/config.mts
@@ -0,0 +1,133 @@
+import { defineConfig } from 'vitepress'
+import {
+ groupIconMdPlugin,
+ groupIconVitePlugin,
+ localIconLoader,
+} from 'vitepress-plugin-group-icons'
+
+export default defineConfig({
+ lang: 'zh-CN',
+ title: 'yutto',
+ description: '🧊 yutto,一个可爱且任性的 B 站视频下载器(CLI)',
+ cleanUrls: true,
+ head: [['link', { rel: 'icon', type: 'image/svg+xml', href: '/logo-mini.svg' }]],
+ themeConfig: {
+ logo: '/logo-mini.svg',
+ nav: [
+ { text: '首页', link: '/' },
+ { text: '指南', link: '/guide/quick-start' },
+ { text: '迁移', link: '/migration/' },
+ {
+ text: '支持我',
+ items: [
+ { text: '赞助', link: '/sponsor' },
+ {
+ text: '参与贡献',
+ link: 'https://github.com/yutto-dev/yutto/blob/main/CONTRIBUTING.md',
+ },
+ ],
+ },
+ ],
+
+ sidebar: {
+ '/guide': [
+ {
+ text: '开始',
+ items: [
+ {
+ text: '快速开始',
+ link: '/guide/quick-start',
+ },
+ {
+ text: '支持的链接',
+ link: '/guide/supported-links',
+ },
+ {
+ text: '命令行参数',
+ collapsed: false,
+ items: [
+ {
+ text: '介绍',
+ link: '/guide/cli/introduction',
+ },
+ {
+ text: '基础参数',
+ link: '/guide/cli/basic',
+ },
+ {
+ text: '资源选择参数',
+ link: '/guide/cli/resource',
+ },
+ {
+ text: '弹幕设置参数',
+ link: '/guide/cli/danmaku',
+ },
+ {
+ text: '批量下载参数',
+ link: '/guide/cli/batch',
+ },
+ ],
+ },
+ ],
+ },
+ {
+ text: '小技巧',
+ link: '/guide/tips',
+ },
+ {
+ text: 'FAQ',
+ link: '/guide/faq',
+ },
+ {
+ text: '交流和反馈',
+ link: '/guide/feedback',
+ },
+ {
+ text: '注意事项',
+ link: '/guide/notice',
+ },
+ {
+ text: '特别感谢',
+ link: '/guide/thanks',
+ },
+ ],
+ },
+
+ footer: {
+ message: 'Released under the GPL3.0 License.',
+ copyright: 'Copyright © 2025-present Nyakku Shigure',
+ },
+
+ editLink: {
+ pattern: 'https://github.com/yutto-dev/yutto/edit/main/docs/:path',
+ text: '欸?我刚刚哪里说错了?你可以帮我改正一下哦~',
+ },
+
+ socialLinks: [
+ { icon: 'github', link: 'https://github.com/yutto-dev/yutto' },
+ { icon: 'discord', link: 'https://discord.gg/5cQGyFwsqC' },
+ ],
+
+ search: {
+ provider: 'local',
+ },
+ },
+
+ markdown: {
+ image: {
+ lazyLoading: true,
+ },
+ config(md) {
+ md.use(groupIconMdPlugin)
+ },
+ },
+ vite: {
+ plugins: [
+ groupIconVitePlugin({
+ customIcon: {
+ yutto: localIconLoader(import.meta.url, '../public/logo-mini.svg'),
+ },
+ }) as any,
+ ],
+ },
+})
diff --git a/docs/.vitepress/env.d.ts b/docs/.vitepress/env.d.ts
new file mode 100644
index 000000000..2f7d41bcf
--- /dev/null
+++ b/docs/.vitepress/env.d.ts
@@ -0,0 +1,6 @@
+declare module '*.vue' {
+ import type { DefineComponent } from 'vue'
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
+ const component: DefineComponent<{}, {}, any>
+ export default component
+}
diff --git a/docs/.vitepress/theme/Layout.vue b/docs/.vitepress/theme/Layout.vue
new file mode 100644
index 000000000..617d4277a
--- /dev/null
+++ b/docs/.vitepress/theme/Layout.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/components/Contributors.vue b/docs/.vitepress/theme/components/Contributors.vue
new file mode 100644
index 000000000..699a502f2
--- /dev/null
+++ b/docs/.vitepress/theme/components/Contributors.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/components/GitHubUser.vue b/docs/.vitepress/theme/components/GitHubUser.vue
new file mode 100644
index 000000000..85f3bf204
--- /dev/null
+++ b/docs/.vitepress/theme/components/GitHubUser.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/theme/components/Sparkler.vue b/docs/.vitepress/theme/components/Sparkler.vue
new file mode 100644
index 000000000..540b2ad3d
--- /dev/null
+++ b/docs/.vitepress/theme/components/Sparkler.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
diff --git a/docs/.vitepress/theme/index.css b/docs/.vitepress/theme/index.css
new file mode 100644
index 000000000..41e0cd0b9
--- /dev/null
+++ b/docs/.vitepress/theme/index.css
@@ -0,0 +1,30 @@
+/**
+ * Colors
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-c-brand-1: #379c9c;
+ --vp-c-brand-2: #46bcc0;
+ --vp-c-brand-3: #67e8e2;
+ --vp-c-brand-soft: #29c9cf33;
+}
+
+.dark {
+ --vp-c-brand-1: #32cbcb;
+ --vp-c-brand-2: #3dd6db;
+ --vp-c-brand-3: #67e8e2;
+ --vp-c-brand-soft: #29c9cf33;
+}
+
+/**
+ * Component: Button
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-button-brand-text: var(--vp-c-bg-soft);
+ --vp-button-brand-bg: var(--vp-c-brand-2);
+ --vp-button-brand-hover-text: var(--vp-c-bg-soft);
+ --vp-button-brand-hover-bg: var(--vp-c-brand-3);
+ --vp-button-brand-active-text: var(--vp-c-bg-soft);
+ --vp-button-brand-active-bg: var(--vp-c-brand-2);
+}
diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts
new file mode 100644
index 000000000..ee420afe0
--- /dev/null
+++ b/docs/.vitepress/theme/index.ts
@@ -0,0 +1,14 @@
+import { EnhanceAppContext } from 'vitepress'
+import DefaultTheme from 'vitepress/theme'
+import Layout from './Layout.vue'
+import 'virtual:group-icons.css'
+import './index.css'
+
+export default {
+ ...DefaultTheme,
+ Layout,
+ enhanceApp(ctx: EnhanceAppContext) {
+ // extend default theme custom behaviour.
+ DefaultTheme.enhanceApp(ctx)
+ },
+}
diff --git a/docs/LICENSE b/docs/LICENSE
new file mode 100644
index 000000000..0e259d42c
--- /dev/null
+++ b/docs/LICENSE
@@ -0,0 +1,121 @@
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+ HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+ i. the right to reproduce, adapt, distribute, perform, display,
+ communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+ likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+ v. rights protecting the extraction, dissemination, use and reuse of data
+ in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation
+ thereof, including any amended or successor version of such
+ directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+ world based on applicable law or treaty, and any national
+ implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+ warranties of any kind concerning the Work, express, implied,
+ statutory or otherwise, including without limitation warranties of
+ title, merchantability, fitness for a particular purpose, non
+ infringement, or the absence of latent or other defects, accuracy, or
+ the present or absence of errors, whether or not discoverable, all to
+ the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without
+ limitation any person's Copyright and Related Rights in the Work.
+ Further, Affirmer disclaims responsibility for obtaining any necessary
+ consents, permissions or other rights required for any use of the
+ Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to
+ this CC0 or use of the Work.
diff --git a/docs/env.d.ts b/docs/env.d.ts
new file mode 100644
index 000000000..2f7d41bcf
--- /dev/null
+++ b/docs/env.d.ts
@@ -0,0 +1,6 @@
+declare module '*.vue' {
+ import type { DefineComponent } from 'vue'
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
+ const component: DefineComponent<{}, {}, any>
+ export default component
+}
diff --git a/docs/guide/cli/basic.md b/docs/guide/cli/basic.md
new file mode 100644
index 000000000..1060a3f7f
--- /dev/null
+++ b/docs/guide/cli/basic.md
@@ -0,0 +1,346 @@
+---
+aside: true
+---
+
+# 基础参数
+
+我支持一些基础参数,无论是批量下载还是单视频下载都适用。
+
+## 最大并行 worker 数量
+
+- 参数 `-n` 或 `--num-workers`
+- 配置项 `basic.num_workers`
+- 默认值 `8`
+
+与 bilili 不同的是,我并不是使用多线程实现并行下载,而是使用协程实现的,本参数限制的是最大的并行 Worker 数量。
+
+## 指定视频清晰度等级
+
+- 参数 `-q` 或 `--video-quality`
+- 配置项 `basic.video_quality`
+- 可选值 `127 | 126 | 125 | 120 | 116 | 112 | 100 | 80 | 74 | 64 | 32 | 16`
+- 默认值 `127`
+
+清晰度对应关系如下
+
+
+| code | 清晰度 |
+| :-: | :-: |
+| 127 | 8K 超高清 |
+| 126 | 杜比视界 |
+| 125 | HDR 真彩 |
+| 120 | 4K 超清 |
+| 116 | 1080P 60帧 |
+| 112 | 1080P 高码率 |
+| 100 | 智能修复 |
+| 80 | 1080P 高清 |
+| 74 | 720P 60帧 |
+| 64 | 720P 高清 |
+| 32 | 480P 清晰 |
+| 16 | 360P 流畅 |
+
+并不是说指定某个清晰度就一定会下载该清晰度的视频,我只会尽可能满足你的要求,如果不存在指定的清晰度,我就会按照默认的清晰度搜索机制进行调节,比如指定清晰度为 `80`,**首先会依次降清晰度搜索** `74`、`64`、`32`、`16`,如果依然找不到合适的则**继续升清晰度搜索** `100`、`112`、`116`、`120`、`125`、`126`、`127`。
+
+## 指定音频码率等级
+
+- 参数 `-aq` 或 `--audio-quality`
+- 配置项 `basic.audio_quality`
+- 可选值 `30251 | 30255 | 30250 | 30280 | 30232 | 30216`
+- 默认值 `30251`
+
+码率对应关系如下
+
+
+| code | 码率 |
+| :-: | :-: |
+| 30251 | - (Hi-Res) |
+| 30255 | - (杜比音效) |
+| 30250 | - (杜比全景声) |
+| 30280 | 320kbps |
+| 30232 | 128kbps |
+| 30216 | 64kbps |
+
+码率自动调节机制与视频清晰度一致,也采用先降后升的匹配机制。
+
+## 指定视频编码
+
+- 参数 `--vcodec`
+- 配置项 `basic.vcodec`
+- 下载编码可选值 `"av1" | "hevc" | "avc"`
+- 保存编码可选值 FFmpeg 所有可用的视频编码器
+- 默认值 `"avc:copy"`
+
+该参数略微复杂,前半部分表示在下载时**优先**选择哪一种编码的视频流,后半部分则表示在合并时如何编码视频流,两者使用 `:` 分隔。
+
+值得注意的是,前半的下载编码只是优先下载的编码而已,如果不存在该编码,则会根据 `--download-vcodec-priority` 自动选择其余编码,如未设置 `--download-vcodec-priority`,则会类似视频清晰度调节机制先降序后升序的方式来选择。
+
+而后半部分的参数如果设置成非 `copy` 的值则可以确保在下载完成后对其进行重新编码,而且不止支持 `av1`、`hevc` 与 `avc`,只要你的 FFmpeg 支持的视频编码器,它都可以完成。
+
+## 指定音频编码
+
+- 参数 `--acodec`
+- 配置项 `basic.acodec`
+- 下载编码可选值 `"mp4a"`
+- 保存编码可选值 FFmpeg 所有可用的音频编码器
+- 默认值 `"mp4a:copy"`
+
+详情同视频编码。
+
+## 指定视频下载编码优先级
+
+- 参数 `--download-vcodec-priority`
+- 配置项 `basic.download_vcodec_priority`
+- 默认值 `"auto"`
+- 可选值 `"auto"` 或者使用 `,` 分隔的下载编码列表,如 `"hevc,avc,av1"`
+
+当使用默认值 `"auto"` 时,我会类似视频清晰度调节机制先降序后升序的方式来选择。
+
+当使用自定义下载编码列表时,我会严格按照列表中的顺序进行选择,如果不存在则会认为该视频无视频流。
+
+::: warning
+
+如若设置本参数,请总是将 `--download-vcode-priority` 首选编码作为 `--vcodec` 的前半部分,否则可能会导致下载失败。
+
+另外需要注意的是,作为配置项时,请直接使用列表形式,比如:
+
+```toml [yutto.toml]
+[basic]
+download_vcodec_priority = ["hevc", "avc", "av1"]
+```
+
+:::
+
+## 指定输出格式
+
+- 参数 `--output-format`
+- 配置项 `basic.output_format`
+- 可选值 `"infer" | "mp4" | "mkv" | "mov"`
+- 默认值 `"infer"`
+
+在至少包含视频流时所使用的输出格式,默认选值 `"infer"` 表示自动根据情况进行推导以保证输出的可用,推导规则如下:
+
+- 如果输出包含音频流且音频流编码为 `"fLaC"`,则输出格式为 `"mkv"`,因为 `"mp4"` 尚不支持 `"fLaC"` 编码
+- 否则为 `"mp4"`
+
+## 指定在仅包含音频流时的输出格式
+
+- 参数 `--output-format-audio-only`
+- 配置项 `basic.output_format_audio_only`
+- 可选值 `"infer" | "m4a" | "aac" | "mp3" | "flac" | "mp4" | "mkv" | "mov"`
+- 默认值 `"infer"`
+
+在仅包含音频流时所使用的输出格式,默认选值 `"infer"` 表示自动根据情况进行推导以保证输出的可用,推导规则如下:
+
+- 如果音频流编码为 `"fLaC"`,则输出格式为 `"flac"`
+- 否则为 `"m4a"`
+
+::: tip
+
+并不是仅仅在指定 `--audio-only` 时才会仅仅包含视频流,有些视频是仅包含音频流的,此时即便不指定 `--audio-only` 选项也会按照本选项的格式进行输出。
+
+:::
+
+## 弹幕格式选择
+
+- 参数 `-df` 或 `--danmaku-format`
+- 配置项 `basic.danmaku_format`
+- 可选值 `"ass" | "xml" | "protobuf"`
+- 默认值 `"ass"`
+
+B 站提供了 `xml` 与 `protobuf` 两种弹幕数据接口,`xml` 接口为旧接口,弹幕数上限较低,`protobuf` 接口相对较高,但不登录情况下只能获取很少的弹幕
+
+为了确保无论是否登录都能获取最多的弹幕,我在登录时会下载 `protobuf` 源数据,在未登录时会下载 `xml` 源数据,并将其转换为主流播放器支持的 `ass` 格式
+
+如果你不喜欢我自动转换的效果,可以选择输出格式为 `xml` 或 `protobuf`,手动通过一些工具进行转换,比如我和 bilili 所使用的 [biliass](https://github.com/yutto-dev/yutto/tree/main/packages/biliass),或者使用 [us-danmaku](https://tiansh.github.io/us-danmaku/bilibili/) 进行在线转换。
+
+如果你不想下载弹幕,只需要使用参数 `--no-danmaku` 即可。
+
+## 下载块大小
+
+- 参数 `-bs` 或 `--block-size`
+- 配置项 `basic.block_size`
+- 默认值 `0.5`
+
+以 MiB 为单位,为分块下载时各块大小,不建议更改。
+
+## 强制覆盖已下载文件
+
+- 参数 `-w` 或 `--overwrite`
+- 配置项 `basic.overwrite`
+- 默认值 `False`
+
+## 代理设置
+
+- 参数 `-x` 或 `--proxy`
+- 配置项 `basic.proxy`
+- 可选值 `"auto" | "no" | `
+- 默认值 `"auto"`
+
+设置代理服务器,默认是从环境变量读取,`no` 则为不设置代理,设置其它 http/https url 则将其作为代理服务器。
+
+## 存放根目录
+
+- 参数 `-d` 或 `--dir`
+- 配置项 `basic.dir`
+- 默认值 `"./"`
+
+## 临时文件目录
+
+- 参数 `--tmp-dir`
+- 配置项 `basic.tmp_dir`
+- 默认值是“存放根目录”即 `-d, --dir` 的值
+
+## Cookies 设置
+
+- 参数 `-c` 或 `--sessdata`
+- 配置项 `basic.sessdata`
+- 默认值 `""`
+
+设置 Cookies 后你才可以下载更高清晰度以及更多的剧集,当你传入你的大会员 `SESSDATA` 时(当然前提是你是大会员),你就可以下载大会员可访问的资源咯。
+
+::: details `SESSDATA` 获取方式
+
+这里用 Chrome 作为示例,其它浏览器请尝试类似方法。
+
+首先,用你的帐号登录 B 站,然后随便打开一个 B 站网页,比如[首页](https://www.bilibili.com/)。
+
+按 F12 打开开发者工具,切换到 Network 栏,刷新页面,此时第一个加载的资源应该就是当前页面的 html,选中该资源,在右侧 「Request Headers」 中找到 「cookie」,在其中找到类似于 `SESSDATA=d8bc7493%2C2843925707%2C08c3e*81;` 的一串字符串,复制这里的 `d8bc7493%2C2843925707%2C08c3e*81`,这就是你需要的 `SESSDATA`。
+
+:::
+
+另外,由于 `SESSDATA` 中可能有特殊符号,所以传入时你可能需要使用双引号来包裹
+
+```bash
+yutto -c "d8bc7493%2C2843925707%2C08c3e*81"
+```
+
+当然,示例里的 `SESSDATA` 是无效的,请使用自己的 `SESSDATA`。
+
+## 存放子路径模板
+
+- 参数 `-tp` 或 `--subpath-template`
+- 配置项 `basic.subpath_template`
+- 可选参数变量 `title | id | name | username | series_title | pubdate | download_date | owner_uid` (以后可能会有更多)
+- 默认值 `"{auto}"`
+
+通过配置子路径模板可以灵活地控制视频存放位置。
+
+默认情况是由我自动控制存放位置的。比如下载单个视频时默认就是直接存放在设定的根目录,不会创建一层容器目录,此时自动选择了 `{name}` 作为模板;而批量下载时则会根据视频层级生成多级目录,比如番剧会是 `{title}/{name}`,首先会在设定根目录里生成一个番剧名的目录,其内才会存放各个番剧剧集视频,这样方便了多个不同番剧的管理。当然,如果你仍希望将番剧直接存放在设定根目录下的话,可以修改该参数值为 `{name}`即可。
+
+另外,该功能语法由 Python format 函数模板语法提供,所以也支持一些高级的用法,比如 `{id:0>3}{name}`,此外还专门为时间变量 🕛 增加了自定义时间模板的语法 `{pubdate@%Y-%m-%d %H:%M:%S}`,默认时间模板为 `%Y-%m-%d`。
+
+值得注意的是,并不是所有变量在各种场合下都会提供,比如 `username`, `owner_uid` 变量当前仅在 UP 主全部投稿视频/收藏夹/稍后再看才提供,在其它情况下不应使用它。各变量详细作用域描述见下表:
+
+
+| Variable | Description | Scope |
+| - | - | - |
+| title | 系列视频总标题(番剧名/投稿视频标题) | 全部 |
+| id | 系列视频单 p 顺序标号 | 全部 |
+| aid | 视频 AV 号,早期使用的视频 ID,不建议使用,详见 [AV 号全面升级公告](https://www.bilibili.com/blackboard/activity-BV-PC.html) | 全部 |
+| bvid | 视频 BV 号,即视频 ID | 全部 |
+| name | 系列视频单 p 标题 | 全部 |
+| username | UP 主用户名 | 个人空间、收藏夹、稍后再看、合集、视频列表下载 |
+| series_title | 合集标题 | 收藏夹、视频合集、视频列表下载 |
+| pubdate🕛 | 投稿日期 | 仅投稿视频 |
+| download_date🕛 | 下载日期 | 全部 |
+| owner_uid | UP 主 UID | 个人空间、收藏夹、稍后再看、合集、视频列表下载 |
+
+> **Note**
+>
+> 未来可能会对路径变量及默认路径模板进行调整
+
+## url 别名设置
+
+- 参数 `-af` 或 `--alias-file`
+- 配置项 `basic.aliases`
+- 默认值 `None`
+
+由于 CLI 和配置文件两种界面是不一致的,别名的配置方式有着较大的区别,下面分别介绍两者。
+
+### 别名文件路径设置(CLI)
+
+在 CLI,你需要通过 `-af`/`--alias-file` 来指定别名文件路径,并在该文件中写明别名的映射关系,使用空格或者 `=` 分隔,示例如下:
+
+```
+tensura1=https://www.bilibili.com/bangumi/play/ss25739/
+tensura2=https://www.bilibili.com/bangumi/play/ss36170/
+tensura-nikki=https://www.bilibili.com/bangumi/play/ss38221/
+```
+
+比如将上述内容存储到 `~/.yutto_alias`,则通过以下命令即可解析该文件:
+
+```bash
+yutto tensura1 --batch --alias-file='~/.yutto_alias'
+```
+
+当参数值为 `-` 时,会从标准输入中读取:
+
+```bash
+cat ~/.yutto_alias | yutto tensura-nikki --batch --alias-file -
+```
+
+### 别名配置设置(配置文件)
+
+因为配置文件本身就是外部文件,因此可以直接通过结构化数据来表明别名映射关系,示例如下:
+
+```toml
+[basic.aliases]
+tensura1 = "https://www.bilibili.com/bangumi/play/ss25739/"
+tensura2 = "https://www.bilibili.com/bangumi/play/ss36170/"
+tensura-nikki = "https://www.bilibili.com/bangumi/play/ss38221/"
+```
+
+## 指定媒体元数据值的格式
+
+当前仅支持 `premiered`
+
+- 参数 `--metadata-format-premiered`
+- 配置项 `basic.metadata_format_premiered`
+- 默认值 `"%Y-%m-%d"`
+- 常用值 `"%Y-%m-%d %H:%M:%S"`
+
+## 设置下载间隔
+
+- 参数 `--download-interval`
+- 配置项 `basic.download_interval`
+- 默认值 `0`
+
+设置两话之间的下载间隔(单位为秒),避免短时间內下载大量视频导致账号被封禁
+
+## 禁用下载镜像
+
+- 参数 `--banned-mirrors-pattern`
+- 配置项 `basic.banned_mirrors_pattern`
+- 默认值 `None`
+
+使用正则禁用特定镜像,比如 `--banned-mirrors-pattern "mirrorali"` 将禁用 url 中包含 `mirrorali` 的镜像
+
+## 严格校验大会员状态有效
+
+- 参数 `--vip-strict`
+- 配置项 `basic.vip_strict`
+- 默认值 `False`
+
+## 严格校验登录状态有效
+
+- 参数 `--login-strict`
+- 配置项 `basic.login_strict`
+- 默认值 `False`
+
+## 不显示颜色
+
+- 参数 `--no-color`
+- 配置项 `basic.no_color`
+- 默认值 `False`
+
+## 不显示进度条
+
+- 参数 `--no-progress`
+- 配置项 `basic.no_progress`
+- 默认值 `False`
+
+## 启用 Debug 模式
+
+- 参数 `--debug`
+- 配置项 `basic.debug`
+- 默认值 `False`
diff --git a/docs/guide/cli/batch.md b/docs/guide/cli/batch.md
new file mode 100644
index 000000000..8c2ad1f29
--- /dev/null
+++ b/docs/guide/cli/batch.md
@@ -0,0 +1,98 @@
+---
+aside: true
+---
+
+# 批量参数
+
+有些参数是只有批量下载时才可以使用的
+
+## 启用批量下载
+
+- 参数 `-b` 或 `--batch`
+- 配置项 「不支持」
+- 默认值 `False`
+
+只需要 `yutto --batch ` 即可启用批量下载功能。
+
+::: warning 该选项不支持配置项
+
+因为是否启用批量下载在大多数情况需要针对具体链接来选择,因此将其设置在配置项里基本是无意义的。
+
+:::
+
+## 选集
+
+- 参数 `-p` 或 `--episodes`
+- 配置项 「不支持」
+- 默认值 `1~-1`(也即全选)
+
+也就是选集咯,其语法是这样的
+
+- `` 单独下某一剧集
+ - 支持负数来选择倒数第几话
+ - 此外还可以使用 `$` 来代表 `-1`
+- `~` 使用 `~` 可以连续选取(如果起始为 1,或者终止为 -1 则可以省略)
+- `,,,...,` 使用 `,` 可以不连续选取
+
+emmm,直接看的话大概并不能知道我在说什么,所以我们通过几个小例子来了解其语法
+
+```bash
+# 假设要下载一个具有 24 话的番剧
+# 如果我们只想下载第 3 话,只需要这样
+yutto -b -p 3
+# 那如果我想下载第 5 话到第 7 话呢,使用 `~` 可以连续选中
+yutto -b -p 5~7
+# 那我想下载第 12 话和第 17 话又要怎么办?此时只需要 `,` 就可以将多个不连续的选集一起选中
+yutto -b -p 12,17
+# 那我突然又想将刚才那些都选中了呢?还是使用 `,` 呀,将它们连在一起即可
+yutto -b -p 3,5~7,12,17
+# 嗯,你已经把基本用法都了解过了,很简单吧~
+# 下面是一些语法糖,不了解也完全不会影响任何功能哒~
+# 那如果我只知道我想下载倒数第 3 话,而不想算倒数第三话是第几话应该怎么办?
+# 此时可以用负数哒~不过要注意的是,这种参数以 `-` 开头参数需要使用 `=` 来连接选项和参数
+yutto -b -p=-3
+# 那么如果想下载最后一话你可能会想到 `-p=-1` 对吧?不过我内置了符号 $ 用于代表最后一话
+# 像下面这样就可以直接下载最后一话啦~
+yutto -b -p $
+# 为了进一步方便表示一个范围选取,在从第一话开始选取或者以最后一话为终止时可以省略它们
+# 这样就是前三话啦(这里与以 `-` 开头类似,以 `~` 开头可能被识别为 $HOME,因此最好也用等号,或者使用引号包裹)
+yutto -b -p=~3
+# 这样就是后四话啦
+yutto -b -p=-4~
+# 所有语法都了解完啦,我们看一个稍微复杂的例子
+yutto -b -p "~3,10,12~14,16,-4~"
+# 很明显,上面的例子就是下载前 3 话、第 10 话、第 12 到 14 话、第 16 话以及后 4 话
+```
+
+下面是一些要注意的问题
+
+1. 这里使用的序号是视频的顺序序号,而不是番剧所标注的`第 n 话`,因为有可能会出现 `第 x.5 话` 等等的特殊情况,此时一定要按照顺序自行计数。
+2. 参数值里一定不要加空格
+3. 参数值开头为特殊符号时最好使用 `=` 来连接选项和参数,或者尝试使用引号包裹参数
+4. 个人空间、视频列表、收藏夹等批量下载暂不支持选集操作
+
+::: warning 该选项不支持配置项
+
+与「启用批量下载」相同,具体选集只有在具体链接时才能确定,为该选项指定配置项同样无意义。
+
+:::
+
+## 同时下载附加剧集
+
+- 参数 `-s` 或 `--with-section`
+- 配置项 `batch.with_section`
+- 默认值 `False`
+
+## 指定稿件发布时间范围
+
+- 参数 `--batch-filter-start-time` 和 `--batch-filter-end-time` 分别表示`开始`和`结束`时间,该区间**左闭右开**
+- 配置项 `batch.filter_start_time` 和 `batch.filter_end_time`
+- 默认 `不限制`
+- 支持的格式
+
+ - `%Y-%m-%d`
+ - `%Y-%m-%d %H:%M:%S`
+
+ 例如仅下载 2020 年投稿的视频,可以这样:
+
+ `--batch-filter-start-time=2020-01-01 --batch-filter-end-time=2021-01-01`
diff --git a/docs/guide/cli/danmaku.md b/docs/guide/cli/danmaku.md
new file mode 100644
index 000000000..80b8c6570
--- /dev/null
+++ b/docs/guide/cli/danmaku.md
@@ -0,0 +1,95 @@
+---
+aside: true
+---
+
+# 弹幕设置参数
+
+通过与 biliass 的集成,我提供了一些 ASS 弹幕选项,包括字号、字体、速度等~
+
+## 弹幕字体大小
+
+- 参数 `--danmaku-font-size`
+- 配置项 `danmaku.font_size`
+- 默认值 `video_width / 40`
+
+## 弹幕字体
+
+- 参数 `--danmaku-font`
+- 配置项 `danmaku.font`
+- 默认值 `"SimHei"`
+
+## 弹幕不透明度
+
+- 参数 `--danmaku-opacity`
+- 配置项 `danmaku.opacity`
+- 默认值 `0.8`
+
+## 弹幕显示区域与视频高度的比例
+
+- 参数 `--danmaku-display-region-ratio`
+- 配置项 `danmaku.display_region_ratio`
+- 默认值 `1.0`
+
+## 弹幕速度
+
+- 参数 `--danmaku-speed`
+- 配置项 `danmaku.speed`
+- 默认值 `1.0`
+
+## 屏蔽顶部弹幕
+
+- 参数 `--danmaku-block-top`
+- 配置项 `danmaku.block_top`
+- 默认值 `False`
+
+## 屏蔽底部弹幕
+
+- 参数 `--danmaku-block-bottom`
+- 配置项 `danmaku.block_bottom`
+- 默认值 `False`
+
+## 屏蔽滚动弹幕
+
+- 参数 `--danmaku-block-scroll`
+- 配置项 `danmaku.block_scroll`
+- 默认值 `False`
+
+## 屏蔽逆向弹幕
+
+- 参数 `--danmaku-block-reverse`
+- 配置项 `danmaku.block_reverse`
+- 默认值 `False`
+
+## 屏蔽固定弹幕(顶部、底部)
+
+- 参数 `--danmaku-block-fixed`
+- 配置项 `danmaku.block_fixed`
+- 默认值 `False`
+
+## 屏蔽高级弹幕
+
+- 参数 `--danmaku-block-special`
+- 配置项 `danmaku.block_special`
+- 默认值 `False`
+
+## 屏蔽彩色弹幕
+
+- 参数 `--danmaku-block-colorful`
+- 配置项 `danmaku.block_colorful`
+- 默认值 `False`
+
+## 屏蔽关键词
+
+- 参数 `--danmaku-block-keyword-patterns`
+- 配置项 `danmaku.block_keyword_patterns`
+- 默认值 `None`
+
+按关键词屏蔽,支持正则,作为 CLI 参数使用 `,` 分隔,作为配置项直接使用列表即可:
+
+```toml [yutto.toml]
+[danmaku]
+block_keyword_patterns = [
+ ".*keyword1.*",
+ ".*keyword2.*",
+]
+```
diff --git a/docs/guide/cli/introduction.md b/docs/guide/cli/introduction.md
new file mode 100644
index 000000000..03d8a9ea7
--- /dev/null
+++ b/docs/guide/cli/introduction.md
@@ -0,0 +1,106 @@
+# 命令行参数
+
+既然我是基于 CLI(Command Line Interface)的工具,那么自然而然,我支持很多命令行参数来让你更好地调度我。
+
+就比如说,你可以添加 `-d` 参数来指定下载的视频路径,或者使用 `-c` 参数来设置用于登录状态的 Cookie(准确来说是其中的 `SESSDATA`)。
+
+## 参数的使用方式
+
+如果你是第一次接触命令行,那么你可能会对这些参数的使用方式感到困惑。
+
+不过,不用担心,我会在这里为你详细地介绍一下。
+
+### 指定参数值
+
+比如你需要修改下载路径到 `/path/to/videos`,只需要
+
+```bash
+yutto --dir /path/to/videos
+# 或者使用短参数 -d
+yutto -d /path/to/videos
+# 你也可以使用 = 将参数 key 和 value 连接在一起
+yutto -d=/path/to/videos
+yutto --dir=/path/to/videos
+```
+
+### 切换 `True` or `False`
+
+对于那些不需要指定具体值,只切换 `True` or `False` 的参数,你也不需要在命令中指定值,比如开启强制覆盖已下载视频选项
+
+```bash
+yutto --overwrite
+# 或者
+yutto -w
+```
+
+### 多参数同时使用
+
+当然,同时使用多个参数也是允许的,只需要写在一起即可,而且 `` 和其它参数都不强制要求顺序,比如下面这些命令都是合法的
+
+```bash
+yutto --overwrite --dir=/path/to/videos
+yutto --overwrite -d /path/to/videos
+yutto -w --d=/path/to/videos
+```
+
+## 更多参数
+
+当然,这些只是冰山一角啦,我支持的参数远不止这些,你可以通过 `yutto --help` 来查看所有支持的参数。也可以前往以下页面查看具体介绍:
+
+- [基础参数](./basic)
+- [资源选择参数](./resource)
+- [弹幕设置参数](./danmaku)
+- [批量下载参数](./batch)
+
+## 配置文件
+
+当你熟悉 CLI 界面后,可能每次下载视频的时候都需要输入一长串的参数,你可能会希望有一种方式来保存常用的参数,下次下载时直接使用,这时候配置文件就派上用场啦~
+
+你可以通过 `--config` 参数来指定配置文件的路径,比如
+
+```bash
+yutto --config /path/to/config.toml
+```
+
+我还支持配置自动发现,也就是说,如果不指定配置文件路径,我也会自动去以下路径查找配置文件的:
+
+- 当前目录下的 `yutto.toml`
+- [`XDG_CONFIG_HOME`](https://specifications.freedesktop.org/basedir-spec/latest/) 下的 `yutto/yutto.toml` 文件
+- 非 Windows 系统下的 `~/.config/yutto/yutto.toml`,Windows 系统下的 `~/AppData/Roaming/yutto/yutto.toml`
+
+你可以通过配置文件来设置一些默认参数,整体上与命令行参数基本一致,下面以一些示例来展示配置文件的写法:
+
+```toml
+# yutto.toml
+#:schema https://raw.githubusercontent.com/yutto-dev/yutto/refs/heads/main/schemas/config.json
+[basic]
+# 设置下载目录
+dir = "/path/to/download"
+# 设置临时文件目录
+tmp_dir = "/path/to/tmp"
+# 设置 SESSDATA
+sessdata = "***************"
+# 设置大会员严格校验
+vip_strict = true
+# 设置登录严格校验
+login_strict = true
+
+[resource]
+# 不下载字幕
+require_subtitle = false
+
+[danmaku]
+# 设置弹幕速度
+speed = 2.0
+# 设置弹幕屏蔽关键词
+block_keyword_patterns = [
+ ".*keyword1.*",
+ ".*keyword2.*",
+]
+
+[batch]
+# 下载额外剧集
+with_section = true
+```
+
+如果你使用 VS Code 对配置文件编辑,强烈建议使用 [Even Better TOML](https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml) 扩展,配合我提供的 schema,可以获得最佳的提示体验。
diff --git a/docs/guide/cli/resource.md b/docs/guide/cli/resource.md
new file mode 100644
index 000000000..17f5b2eb4
--- /dev/null
+++ b/docs/guide/cli/resource.md
@@ -0,0 +1,142 @@
+---
+aside: true
+---
+
+# 资源选择参数
+
+这里有一些参数专用于资源选择,比如选择是否下载弹幕、音频、视频等等。
+
+## 仅下载视频流
+
+- 参数 `--video-only`
+- 默认值 `False`
+
+::: tip
+
+这里「仅下载视频流」是指视频中音视频流仅选择视频流,而不是仅仅下载视频而不下载弹幕字幕等资源,如果需要取消字幕等资源下载,请额外使用 `--no-danmaku` 等参数。
+
+「仅下载音频流」也是同样的。
+
+:::
+
+## 仅下载音频流
+
+- 参数 `--audio-only`
+- 默认值 `False`
+
+仅下载其中的音频流,保存为 `.m4a` 文件。
+
+## 不生成弹幕文件
+
+- 参数 `--no-danmaku`
+- 默认值 `False`
+
+## 仅生成弹幕文件
+
+- 参数 `--danmaku-only`
+- 默认值 `False`
+
+## 不生成字幕文件
+
+- 参数 `--no-subtitle`
+- 默认值 `False`
+
+## 仅生成字幕文件
+
+- 参数 `--subtitle-only`
+- 默认值 `False`
+
+## 生成媒体元数据文件
+
+- 参数 `--with-metadata`
+- 默认值 `False`
+
+目前媒体元数据生成尚在试验阶段,可能提取出的信息并不完整。
+
+## 仅生成媒体元数据文件
+
+- 参数 `--metadata-only`
+- 默认值 `False`
+
+## 不生成视频封面
+
+- 参数 `--no-cover`
+- 默认值 `False`
+
+::: tip
+
+当前仅支持为包含视频流的视频生成封面。
+
+:::
+
+## 生成视频流封面时单独保存封面
+
+- 参数 `--save-cover`
+- 默认值 `False`
+
+## 仅生成视频封面
+
+- 参数 `--cover-only`
+- 默认值 `False`
+
+## 不生成章节信息
+
+- 参数 `--no-chapter-info`
+- 默认值 `False`
+
+不生成章节信息,包含 MetaData 和嵌入视频流的章节信息。
+
+## 配置项
+
+与命令行界面完全不同,配置文件可以直接表明你要下载的资源类型,比如:
+
+```toml [yutto.toml]
+[resource]
+require_audio = false
+require_subtitle = false
+require_danmaku = false
+```
+
+如上配置表明了你不需要音频、字幕和弹幕资源。
+
+具体配置项如下:
+
+### 是否需要视频流
+
+- 配置项 `resource.video_only`
+- 默认值 `True`
+
+### 是否需要音频流
+
+- 配置项 `resource.require_audio`
+- 默认值 `True`
+
+### 是否需要弹幕
+
+- 配置项 `resource.require_danmaku`
+- 默认值 `True`
+
+### 是否需要字幕
+
+- 配置项 `resource.require_subtitle`
+- 默认值 `True`
+
+### 是否需要媒体元数据
+
+- 配置项 `resource.require_metadata`
+- 默认值 `False`
+
+### 是否需要视频封面
+
+- 配置项 `resource.require_cover`
+- 默认值 `True`
+
+### 是否需要章节信息
+
+- 配置项 `resource.require_chapter_info`
+- 默认值 `True`
+
+### 生成视频流封面时单独保存封面
+
+- 配置项 `resource.save_cover`
+- 默认值 `False`
diff --git a/docs/guide/faq.md b/docs/guide/faq.md
new file mode 100644
index 000000000..73e159aff
--- /dev/null
+++ b/docs/guide/faq.md
@@ -0,0 +1,17 @@
+# FAQ
+
+## 版本号为什么是 2.0
+
+因为 yutto 是 [bilili](https://github.com/yutto-dev/bilili) 的後輩呀~
+
+## 名字的由来
+
+[《転スラ日記》第一话 00:24](https://www.bilibili.com/bangumi/play/ep395211?t=24)
+
+## 何谓「任性」?
+
+我不一定会满足你的所有需求哦,从设计者的角度,为我添加任何特性都需要以保证可维护性为前提,因此我不会支持过于复杂的特性,只需要满足大多数用户的需求即可~
+
+## yutto 会替代 bilili 吗
+
+我自诞生以来已经过去三年多了,功能上基本可以替代 bilili 了,由于 B 站接口的不断变化,bilili 也不再适用于现在的环境,因此请 bilili 用户尽快迁移到 yutto ~
diff --git a/docs/guide/feedback.md b/docs/guide/feedback.md
new file mode 100644
index 000000000..0b2e8ca7e
--- /dev/null
+++ b/docs/guide/feedback.md
@@ -0,0 +1,7 @@
+# 交流和反馈
+
+在提出问题之前,请确定你已经大致地将本文档浏览过一遍,这样会节省彼此的一些时间。当然,如果你对文档的组织形式、内容等有任何问题的话,欢迎提出与贡献。
+
+如果你有一些新的想法,可以在 GitHub 上[发起 discussion](https://github.com/yutto-dev/yutto/discussions),如果你确定你发现了一个 Bug,或者想请求添加新的功能,也可以直接[发起 Issue](https://github.com/yutto-dev/yutto/issues/)。
+
+此外你也可以通过 [Discord](https://discord.com/invite/5cQGyFwsqC) 来与大家讨论,建议问题尽可能直奔主题,尽可能少询问不必要的信息。
diff --git a/docs/guide/notice.md b/docs/guide/notice.md
new file mode 100644
index 000000000..be8e78b77
--- /dev/null
+++ b/docs/guide/notice.md
@@ -0,0 +1,9 @@
+# 注意事项
+
+我的工作只是将 B 站的视频搬运到你的电脑上,**仅此而已**啦,但有些事情你可能需要知道。
+
+我不会帮你下载你没有权限访问的东西,因此我不是什么破解程序,该开大会员还是去乖乖开大会员,这是对 B 站的一种支持,所以请不要对我提让我为难的要求哦,无论现在还是以后。
+
+我所下载的东西只代表你有权限获取,请不要将我获取的东西随意分享破坏平台和创作者的权益,如果你这么做了的话,那就不要怪我绝情咯,只能一切后果自负哦。
+
+另外我本身的开源协议是 GPL-3.0,一方面我需要 FFmpeg 前辈和 [biliass](https://github.com/yutto-dev/yutto/tree/main/packages/biliass) 的帮忙,另一方面也尽可能维护 B 站本身的权益。不过我的文档采用的是 CC0-1.0 协议。
diff --git a/docs/guide/quick-start.md b/docs/guide/quick-start.md
new file mode 100644
index 000000000..2f0b26cee
--- /dev/null
+++ b/docs/guide/quick-start.md
@@ -0,0 +1,214 @@
+# 快速开始
+
+嗨~你好呀~这里是 yutto,一个可爱的命令行驱动的 B 站视频下载工具~
+
+我的工作方式非常简单快捷,你只需要提供给我 B 站的链接,我就可以帮你下载好视频啦~就像这样:
+
+
+
+
+❯ yutto https://www.bilibili.com/video/BV1ZEf9YiE2h/
+ INFO 发现配置文件 yutto.toml,加载中……
+ 大会员 成功以大会员身份登录~
+ 投稿视频 植物大战僵尸融合版2.2正式版宣传片
+ INFO 开始处理视频 植物大战僵尸融合版2.2正式版宣传片
+ INFO 共包含以下 15 个视频流:
+ INFO * 0 [AVC ] [1920x1080] <1080P 60帧> #3
+ INFO 1 [HEVC] [1920x1080] <1080P 60帧> #3
+ INFO 2 [AV1 ] [1920x1080] <1080P 60帧> #3
+ INFO 3 [AVC ] [1920x1080] <1080P 高清> #3
+ INFO 4 [HEVC] [1920x1080] <1080P 高清> #3
+ INFO 5 [AV1 ] [1920x1080] <1080P 高清> #3
+ INFO 6 [AVC ] [1280x720 ] <720P 高清 > #3
+ INFO 7 [HEVC] [1280x720 ] <720P 高清 > #3
+ INFO 8 [AV1 ] [1280x720 ] <720P 高清 > #3
+ INFO 9 [AVC ] [ 852x480 ] <480P 清晰 > #3
+ INFO 10 [HEVC] [ 852x480 ] <480P 清晰 > #3
+ INFO 11 [AV1 ] [ 852x480 ] <480P 清晰 > #3
+ INFO 12 [AVC ] [ 640x360 ] <360P 流畅 > #3
+ INFO 13 [HEVC] [ 640x360 ] <360P 流畅 > #3
+ INFO 14 [AV1 ] [ 640x360 ] <360P 流畅 > #3
+ INFO 共包含以下 3 个音频流:
+ INFO * 0 [MP4A] <320kbps >
+ INFO 1 [MP4A] < 64kbps >
+ INFO 2 [MP4A] <128kbps >
+ 弹幕 ASS 弹幕已生成
+ INFO 开始下载……
+━━━━━━━━━━━━━━━━━━━━━━━━━━━╸━━━━━━━━━━━━━━━━━━━━━━ 39.05 MiB/ 72.13 MiB 32.22 MiB/⚡
+
+
+
+
+下面我将会从安装开始介绍我的使用方式~
+
+## 环境配置
+
+::: tip 注意
+
+如果你使用 Homebrew、paru、Docker 等可以自动帮助你配置环境的方式来安装,此部分内容可以跳过~
+
+:::
+
+### Python 解释器安装
+
+你可能会好奇,我是怎么指挥你的设备来帮助你下载想要的视频的,其实这很大程度归功于 Python 前辈的帮忙,有了 TA,我才能和你的设备正常沟通。不过有一点需要注意的就是,必须要 3.9 以上版本的 Python 前辈才可以哦,不然可能 TA 也听不懂我的一些「方言」呢~
+
+如果你是 Windows,请自行去 [Python 官网](https://www.python.org/)下载并安装,安装时记得要勾选「Add to PATH」选项,不然可能需要你手动添加到环境变量。
+
+macOS 及 Linux 发行版一般都自带 Python 环境,但要注意版本。
+
+安装完成后可以通过 `python --version` 来确定是否正确安装,当然这里仍然需要再次注意一下版本号~
+
+### FFmpeg 下载与配置
+
+由于 B 站视频是需要混流合并的,因此我的正常运作离不开 FFmpeg 前辈的帮助,因此你需要事先将 TA 正确安装在你的设备上~
+
+如果你所使用的操作系统是 Windows,操作有些些麻烦,你需要[手动下载](https://ffmpeg.org/download.html)后,并将可执行文件所在路径设置到到你的环境变量中~
+
+::: details 详细操作
+
+打开下载链接后,在 「Get packages & executable files」 部分选择 Windows 徽标,在 「Windows EXE Files」 下找到 「Windows builds by BtbN」 并点击,会跳转到一个 GitHub Releases 页面,在 「Latest release」 里就能看到最新的构建版本了~
+
+下载后解压,并随便放到一个安全的地方,然后在文件夹中找到 `ffmpeg.exe`,复制其所在文件夹路径。
+
+右击「此电脑」,选择属性,在其中找到「高级系统设置」 → 「环境变量」,双击 PATH,在其中添加刚刚复制的路径(非 Win10 系统操作略有差异,请自行查阅「环境变量设置」的方法)。
+
+保存保存,完事啦~~~
+
+:::
+
+当然,如果你使用的是 macOS 或者 Linux 发行版的话,直接使用自己的包管理器就能一键完成该过程。
+
+:::: details 示例
+
+这里给出一些示例,不会一一列举,其它的大家可以自行搜索下~
+
+::: code-group
+
+```bash [macOS]
+brew install ffmpeg
+```
+
+```bash [Ubuntu]
+apt install ffmpeg
+```
+
+```bash [Arch]
+pacman -S ffmpeg
+```
+
+:::
+
+::::
+
+此时,你可以尝试在终端上使用 `ffmpeg -version` 命令来测试下安装是否正确,只要显示的不是 `Command not found` 之类的提示就说明成功啦~
+
+## 召唤 yutto
+
+当当当,是时候主角登场啦~不过在此之前仍然需要学习一点小小的咒语~
+
+你可以通过以下几种方式中的任意一种来召唤(安装)我,我随叫随到~
+
+### 包管理器一键安装啦
+
+我目前可以通过一些包管理器直接安装~这是最简单快捷的安装方式~
+
+使用 Homebrew 的小伙伴可以尝试下下面的命令:
+
+```bash
+brew tap siguremo/tap
+brew install yutto
+```
+
+使用 [paru](https://github.com/Morganamilo/paru)(Arch 上的 AUR 包管理器)的用户可以尝试下这样的命令(感谢 @ouuan):
+
+```bash
+paru -S yutto
+```
+
+### 使用 Docker
+
+你也可以尝试使用 docker 直接运行(运行时的更多参数需要参考下后面的内容~)
+
+```bash
+docker run --rm -it -v /path/to/download:/app siguremo/yutto [options]
+```
+
+与直接本机运行不同的是,这里的下载目标路径是通过 `-v :/app` 指定的,也就是说 docker 内的我会将内容下载到 docker 里的 `/app` 目录下,与之相对应的挂载点 `` 就是下载路径。你也可以直接挂载到 `$(pwd)`,此时就和本机运行我的默认行为一致啦,也是下载到当前目录下~
+
+### pip/pipx/uv 安装 需自行配置环境
+
+我的所有版本均已上传到 PyPI,因此你当然可以通过 pip 来安装啦~
+
+```bash
+pip install yutto
+```
+
+当然,你也可以通过 [pipx](https://github.com/pypa/pipx)/[uv](https://github.com/astral-sh/uv) 来安装(当然,前提是你要自己先安装 TA 们)
+
+```bash
+pipx install yutto # 使用 pipx
+uv tool install yutto # 或者使用 uv
+```
+
+pipx/uv 会类似 Homebrew 无感地为我创建一个独立的虚拟环境,与其余环境隔离开,避免污染 pip 的环境,因此相对于 pip,pipx/uv 是更推荐的安装方式(uv 会比 pipx 更快些~)。
+
+### 体验 main 分支最新特性 需自行配置环境
+
+有些时候有一些在 main 分支还没有发布的新特性或者 bugfix,你可以尝试直接安装 main 分支的代码,最快的方式仍然是通过 pip 安装,只不过需要使用 git 描述符
+
+```bash
+pip install git+https://github.com/yutto-dev/yutto@main # 通过 pip
+pipx install git+https://github.com/yutto-dev/yutto@main # 或者通过 pipx
+uv tool install git+https://github.com/yutto-dev/yutto.git@main # 或者通过 uv
+```
+
+## yutto 一下~
+
+嗯,跟随上面的指引后我应当可以正常工作啦,那么现在,请为我分配任务吧~
+
+```bash
+yutto
+```
+
+没错,为我分配任务的方式就是这么简单~
+
+不过值得注意的是这样只可以下载单个视频,如果有批量下载需求的话请添加 `-b/--batch` 参数:
+
+```bash
+yutto --batch
+# 或者使用其短参数
+yutto -b
+```
+
+此时我会认为该 url 是一个批量下载链接,会从其中解析出多个视频链接出来进行下载。
+
+下面举例说明一下:
+
+这里的 `` 是 [《転スラ日記》](https://www.bilibili.com/bangumi/play/ep395211) 第一话链接,那么如果你只想下载该话的话只需要运行:
+
+```bash
+yutto https://www.bilibili.com/bangumi/play/ep395211
+```
+
+或者如果你想要该番剧全集,请运行:
+
+```bash
+yutto -b https://www.bilibili.com/bangumi/play/ep395211
+```
+
+## 下一步
+
+很好,到此为止你已经了解如何让我来帮你下载视频啦~
+
+不过你可能会有一些问题,比如:
+
+- 为什么下载的视频不够清晰?我在线看的视频明明至少都有 1080P 的呀
+- 为什么需要这么冗长的 url 才能下载视频?是否有更简洁的方式?
+
+这里先简单卖个关子,因为这些答案你都可以在后续内容中找到,这才刚刚开始呢~
+
+这里给出一些推荐内容,你可以尝试:
+
+- 如果你希望了解我具体都支持哪些链接,可以尝试前往 [支持的链接](./supported-links) 查看
+- 如果你希望了解我的进阶用法,可以尝试前往 [命令行参数](./cli/introduction) 查看
diff --git a/docs/guide/supported-links.md b/docs/guide/supported-links.md
new file mode 100644
index 000000000..cd897ace7
--- /dev/null
+++ b/docs/guide/supported-links.md
@@ -0,0 +1,244 @@
+# 支持的链接
+
+本页面主要介绍了我所支持的链接类型,即 `yutto ` 中的 `` 具体可以是哪些值。
+
+## 一表速览
+
+
+| 类型 | 是否支持选集 | 示例链接 | 默认路径模板 |
+| - | - | - | - |
+| 投稿视频 | - | `https://www.bilibili.com/video/BV1vZ4y1M7mQ/`
`https://www.bilibili.com/video/av371660125/`
`https://www.bilibili.com/video/BV1vZ4y1M7mQ?p=1`
`av371660125`
`BV1vZ4y1M7mQ` | `{title}` |
+| 投稿视频 批量 | :white_check_mark: | `https://www.bilibili.com/video/BV1vZ4y1M7mQ/`
`https://www.bilibili.com/video/av371660125/`
`av371660125`
`BV1vZ4y1M7mQ` | `{title}/{name}` |
+| 番剧 | - | `https://www.bilibili.com/bangumi/play/ep395211`
`ep395211` | `{name}` |
+| 番剧 批量 | :white_check_mark: | `https://www.bilibili.com/bangumi/play/ep395211`
`https://www.bilibili.com/bangumi/play/ss38221`
`https://www.bilibili.com/bangumi/media/md28233903`
`ep395211`
`ss38221`
`md28233903` | `{title}/{name}` |
+| 课程 | - | `https://www.bilibili.com/cheese/play/ep6902` | `{name}` |
+| 课程 批量 | :white_check_mark: | `https://www.bilibili.com/cheese/play/ep6902`
`https://www.bilibili.com/cheese/play/ss298` | `{title}/{name}` |
+| 用户指定收藏夹 批量 | :x: | `https://space.bilibili.com/100969474/favlist?fid=1306978874&ftype=create` | `{username}的收藏夹/{series_title}/{title}/{name}` |
+| 当前用户稍后再看 批量 | :x: | `https://www.bilibili.com/watchlater` | `稍后再看/{title}/{name}` |
+| 用户全部收藏夹 批量 | :x: | `https://space.bilibili.com/100969474/favlist` | `{username}的收藏夹/{series_title}/{title}/{name}` |
+| UP 主个人空间 批量 | :x: | `https://space.bilibili.com/100969474/video` | `{username}的全部投稿视频/{title}/{name}` |
+| 合集 批量 | :white_check_mark: | `https://space.bilibili.com/3546619314178489/lists?sid=3221717?type=season`
`https://space.bilibili.com/3546619314178489/channel/collectiondetail?sid=3221717`旧版页面
`https://space.bilibili.com/100969474/favlist?fid=3221717&ftype=collect&ctype=21` | `{series_title}/{title}` |
+| 视频列表 批量 | :x: | `https://space.bilibili.com/100969474/lists/1947439?type=series`
`https://space.bilibili.com/100969474/channel/seriesdetail?sid=1947439`旧版页面
`https://www.bilibili.com/list/100969474?sid=1947439` | `{series_title}/{title}/{name}` |
+
+本表格展示了我所支持的所有类型的链接,以及最终下载的文件结构。
+
+值得注意的是,这里标记「批量」的视频都必须通过 `-b/--batch` 参数来下载,否则会按照单个视频来解析下载。
+
+::: tip 其他链接
+
+此外只要最终会重定向到我所支持的链接我都可以解析,比如以 `https://b23.tv/` 开头的短链接和 SEO 页面链接。
+
+:::
+
+## 投稿视频
+
+### 投稿视频单 P
+
+对于投稿视频,AV 号、BV 号的链接我都会支持,对于没有 `?p=n` 选集参数的页面,默认会认为是第一话。
+
+```bash
+yutto https://www.bilibili.com/video/BV1vZ4y1M7mQ/
+yutto https://www.bilibili.com/video/av371660125/
+yutto "https://www.bilibili.com/video/BV1vZ4y1M7mQ/?p=1"
+```
+
+另外,我还支持直接直接使用 AV 号和 BV 号作为视频链接的唯一标识符。
+
+```bash
+yutto BV1vZ4y1M7mQ
+yutto av371660125
+yutto "BV1vZ4y1M7mQ?p=1"
+```
+
+### 投稿视频全集
+
+与投稿视频单集相同,这同样支持 AV 号和 BV 号的链接,但 `?p=n` 的选集参数在此时是无效的,我会认为这只是一个入口链接,而你既然指定了要批量下载,那么我会解析该投稿视频的全集。如果你仍然想要指定下载剧集,请参考选集参数 `-p/--episodes`。
+
+```bash
+yutto -b https://www.bilibili.com/video/BV1vZ4y1M7mQ/
+yutto -b https://www.bilibili.com/video/av371660125/
+yutto -b BV1vZ4y1M7mQ
+yutto -b av371660125
+yutto -b "BV1vZ4y1M7mQ?p=2" # 仍然会下载全集
+yutto -b BV1vZ4y1M7mQ -p 2 # 这样才会只下载第二话
+```
+
+## 番剧
+
+### 番剧单话
+
+番剧的话,主要有三种入口链接,分别是能够代表单话唯一标识符的 EP 号链接、代表整季番剧的 MD 号和 SS 号。
+
+对于单话下载来说,MD 号和 SS 号均无法定位到具体某一话,因此单话下载不支持 MD 号和 SS 号,仅支持 EP 号。
+
+```bash
+yutto https://www.bilibili.com/bangumi/play/ep395211
+yutto ep395211
+```
+
+### 番剧全集
+
+对于番剧全集来说,MD 号、SS 号、EP 号均可以定位到这个番剧,因此是都支持的。
+
+```bash
+yutto -b https://www.bilibili.com/bangumi/play/ep395211
+yutto -b https://www.bilibili.com/bangumi/play/ss38221
+yutto -b https://www.bilibili.com/bangumi/media/md28233903
+yutto -b ep395211
+yutto -b ss38221
+yutto -b md28233903
+```
+
+当然,如果需要选集请使用 `-p/--episodes` 参数。
+
+```bash
+yutto -b md28233903 -p 2
+```
+
+## 课程
+
+### 课程单集
+
+课程的链接是以 `cheese` 开头的,与番剧非常类似,课程也是支持 EP 号的。
+
+```bash
+yutto https://www.bilibili.com/cheese/play/ep6902
+```
+
+注意,课程并不支持直接使用 EP 号作为唯一标识符,因为这会和番剧混淆。
+
+### 课程全集
+
+课程全集的下载方式也和番剧很类似,你可以使用 EP 号或者 SS 号来下载。
+
+```bash
+yutto -b https://www.bilibili.com/cheese/play/ep6902
+yutto -b https://www.bilibili.com/cheese/play/ss298
+```
+
+同样,你不可以直接使用 EP 号和 SS 号作为唯一标识符来下载以免混淆。
+
+## 用户个人空间
+
+::: warning ⚠️ 注意
+
+请注意公开性,比如在未登录的情况下,未公开的收藏夹是无法下载的,这可以在 `个人中心` -> `设置` 中进行调节。
+
+:::
+
+### 用户全部投稿视频
+
+如果需要下载全部投稿,只需要 `个人中心` -> `投稿` 页面链接即可。
+
+```bash
+yutto -b https://space.bilibili.com/100969474/video
+```
+
+### 用户全部收藏夹
+
+如果需要下载全部收藏夹,只需要 `个人中心` -> `收藏` 页面链接即可。
+
+```bash
+yutto -b https://space.bilibili.com/100969474/favlist
+```
+
+::: warning ⚠️ 注意
+
+用户收藏夹往往非常庞大,解析时很容易触发反爬机制。如遇该问题请稍等片刻后重试。(emmm,如果视频太多的话还是建议逐个收藏夹下载……)
+
+:::
+
+### 指定收藏夹
+
+对于指定收藏夹,自然就是在收藏页面再次点击具体收藏夹名称后的页面。
+
+```bash
+yutto -b "https://space.bilibili.com/100969474/favlist?fid=1306978874"
+```
+
+### 当前用户稍后再看
+
+稍后再看的页面链接也是支持的。
+
+```bash
+yutto -b https://www.bilibili.com/watchlater
+```
+
+当然,由于你无权访问其他用户的稍后再看,这里只支持当前用户的稍后再看下载。另一方面,这强依赖于你的登录状态,如果你处于未登录状态,那么我当然也是无法获取到你的稍后再看列表的哦~
+
+### 合集和列表
+
+与其他的相同,你可以在 `个人中心` -> `合集`(旧版页面为 `合集和列表`) 进入具体列表获取对应合集/列表的链接。
+
+```bash
+# 合集
+yutto -b "https://space.bilibili.com/3546619314178489/lists?sid=3221717?type=season"
+yutto -b "https://space.bilibili.com/3546619314178489/channel/collectiondetail?sid=3221717" # 旧版页面链接
+# 列表
+yutto -b "https://space.bilibili.com/100969474/lists/1947439?type=series"
+yutto -b "https://space.bilibili.com/100969474/channel/seriesdetail?sid=1947439" # 旧版页面链接
+```
+
+另外,视频列表的播放页面也可以唯一定位该视频列表
+
+```bash
+yutto -b "https://www.bilibili.com/list/100969474?sid=1947439"
+```
+
+## 任务列表
+
+如果你需要一次开启多个任务,可以试试将任务列表写在一个文件中,每行列出一个任务的参数。
+
+```text
+https://www.bilibili.com/bangumi/play/ss38221/ --batch -p $
+https://www.bilibili.com/bangumi/play/ss38260/ --batch -p $
+```
+
+然后运行
+
+```bash
+yutto file:///path/to/list
+```
+
+即可分别下载这两个番剧的最新一话。
+
+我会将这样的 file scheme 链接视为一个任务列表进行解析,为了方便使用,直接使用相对或者绝对路径也是可以的
+
+```bash
+yutto ./path/to/list
+```
+
+值得注意的是,在文件列表各项里的参数优先级是高于命令里的优先级的,比如文件中使用:
+
+```text
+rimuru1 --batch -p $ --no-danmaku --vcodec="hevc:copy"
+rimuru2 --batch -p $
+```
+
+而命令中则使用
+
+```text
+yutto file:///path/to/list --vcodec="avc:copy"
+```
+
+最终下载的 `rimuru1` 会是 `"hevc:copy"`,而 `rimuru2` 则会是 `"avc:copy"`
+
+另外说一点,列表也是支持嵌套的哦(虽然没什么用 2333)
+
+## 配置别名
+
+除去使用以上所示的链接,你可以通过配置别名来避免每次下载都去视频页面找链接。
+
+比如你可以为《転スラ日記》起一个别名 `rimuru-nikki`,我们将其存在一个文件中 `~/yutto-aliases`
+
+```text
+rimuru-nikki=https://www.bilibili.com/bangumi/play/ss38221/
+```
+
+之后下载最新话只需要
+
+```bash
+yutto -b rimuru-nikki --alias-file=~/yutto-aliases
+```
+
+当然,文件列表也是支持 alias 的,你完全可以为你的常用列表起一个别名,一个比较特别的用例是将你所有追番的内容放在一个文件里,然后为该文件起一个别名(比如 `subscription`),这样只需要 `yutto subscription --alias-file path/to/alias/file` 就可以达到追番效果啦~
diff --git a/docs/guide/thanks.md b/docs/guide/thanks.md
new file mode 100644
index 000000000..d9fb2176a
--- /dev/null
+++ b/docs/guide/thanks.md
@@ -0,0 +1,50 @@
+# 特别感谢
+
+## 平台以及创作者
+
+感谢 [bilibili](https://www.bilibili.com/) 平台以及平台上无数优质内容的创作者。
+
+## 依赖项目
+
+我的正常运作离不开以下项目的支持
+
+- [FFmpeg](https://github.com/FFmpeg/FFmpeg) 用于视频的合并
+- [biliass](https://github.com/yutto-dev/yutto/tree/main/packages/biliass) 用于 XML 弹幕转换为 ASS 弹幕
+- [VitePress](https://github.com/vuejs/vitepress) 本文档的生成器
+
+## 参考项目
+
+我在探索过程中得到了以下项目的帮助
+
+- 基本结构:
+- 协程下载:
+- 弹幕转换:
+- 样式设计:
+
+## 云服务
+
+- [Vercel](https://vercel.com/) 提供[文档托管](https://vercel.com/siguremo/yutto-docs)
+
+## 贡献者
+
+感谢每一位贡献者的辛勤付出
+
+
+
+## 赞助者
+
+感谢各位赞助者的资金援助
+
+
+
+
+
+
+
+
+## 以及你的支持~
+
+
diff --git a/docs/guide/tips.md b/docs/guide/tips.md
new file mode 100644
index 000000000..8af792a4d
--- /dev/null
+++ b/docs/guide/tips.md
@@ -0,0 +1,45 @@
+# 小技巧
+
+## 作为 log 输出到文件
+
+虽说我不像 bilili 前辈那样会全屏刷新,但进度条还是会一直刷新占据多行,可能影响 log 的阅读,另外颜色码也是难以阅读的,因此我们可以通过选项禁用他们:
+
+```bash
+yutto --no-color --no-progress > log
+```
+
+## 使用配置自定义默认参数
+
+如果你希望修改我的部分参数,那么可能每次运行都需要在后面加上长长一串选项,为了避免这个问题,你可以尝试使用配置文件
+
+```toml
+# ~/.config/yutto/yutto.toml
+#:schema https://raw.githubusercontent.com/yutto-dev/yutto/refs/heads/main/schemas/config.json
+[basic]
+dir = "~/Movies/yutto"
+sessdata = "***************"
+num_workers = 16
+vcodec = "av1:copy"
+```
+
+当然,请手动修改 `sessdata` 内容为自己的 `SESSDATA` 哦~
+
+:::: tip
+
+本方案可替代原有的「自定义命令别名」方式~
+
+::: details 原「自定义命令别名」方案
+
+在 `~/.zshrc` / `~/.bashrc` 中自定义一条 alias,像这样
+
+```bash
+alias ytt='yutto -d ~/Movies/yutto/ -c `cat ~/.sessdata` -n 16 --vcodec="av1:copy"'
+```
+
+这样我每次只需要 `ytt ` 就可以直接使用这些参数进行下载啦~
+
+由于我提前在 `~/.sessdata` 存储了我的 `SESSDATA`,所以避免每次都要手动输入 cookie 的问题。
+
+:::
+
+::::
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 000000000..6ec9c538b
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,55 @@
+---
+layout: home
+
+hero:
+ name: yutto
+ text: 🧊 一个可爱且任性的 B 站视频下载器
+ actions:
+ - theme: brand
+ text: 从零开始
+ link: /guide/quick-start.html
+ - theme: alt
+ text: 从 bilili 迁移
+ link: /migration/
+ - theme: alt
+ text: GitHub
+ link: https://github.com/yutto-dev/yutto
+ image:
+ src: /logo.png
+ alt: yutto-logo
+features:
+ - icon: ⚡️
+ title: 快速下载
+ details: 协程 + 分块下载,尽可能地利用并行性
+ - icon: 📜
+ title: 弹幕支持
+ details: 默认支持 ASS 弹幕生成
+ - icon: 🔁
+ title: 断点续传
+ details: 即便一次没下完也可以接着下载~
+ - icon: 🌈
+ title: 支持类型丰富
+ details: 支持投稿视频、番剧、视频合集、收藏夹等的下载
+---
+
+
diff --git a/docs/migration/index.md b/docs/migration/index.md
new file mode 100644
index 000000000..2fe261ea6
--- /dev/null
+++ b/docs/migration/index.md
@@ -0,0 +1,37 @@
+# 从 𝓫𝓲𝓵𝓲𝓵𝓲 迁移
+
+## 取消的功能
+
+- `- bilibili` 目录的生成
+- 播放列表生成
+- 源格式修改功能(不再支持 flv 源视频下载,如果仍有视频不支持 dash 源,请继续使用 bilili)
+- 对 Python3.8 的支持,最低支持 Python3.9
+- 下载前询问
+
+## 默认行为的修改
+
+- 使用协程而非多线程进行下载
+- 默认生成弹幕为 ASS
+- 默认启用从多镜像源下载的特性
+- 不仅可以控制是否使用系统代理,还能配置特定的代理服务器
+
+## 参数名修改
+
+- 「视频清晰度选择」 `-q`/`--quality` 修改为 `-q`/`--video-quality`
+- 「个人信息认证」 `-c`/`--sess-data` 修改为 `-c`/`--sessdata`
+- 「指定下载弹幕类型」 `--danmaku` 拆分为「弹幕格式选择」 `-df`/`--danmaku-format` 和「不生成弹幕文件」 `--no-danmaku` 两个参数
+- 「绕过系统代理」 `--disable-proxy` 集成到更为灵活的「代理设置」 `-x`/`--proxy` 参数
+
+## 新增的特性
+
+- 单视频下载与批量下载命令分离(`bilili` 命令与 `yutto --batch` 相类似)
+- 音频/视频编码选择
+- 可选仅下载音频/视频
+- 存放子路径的自由定制
+- 支持 url 别名
+- 支持文件列表
+- 更多的批下载支持(现已支持 UP 主全部投稿视频、视频合集、收藏夹等)
+- 更加完善的 warning 与 error 提示
+- 支持仅输入 id 即可下载(aid、bvid、episode_id 等)
+- 支持描述文件生成
+- 并行化链接解析(超快的~)
diff --git a/docs/package.json b/docs/package.json
new file mode 100644
index 000000000..2ee5cb251
--- /dev/null
+++ b/docs/package.json
@@ -0,0 +1,42 @@
+{
+ "name": "yutto-docs",
+ "version": "0.1.0",
+ "private": true,
+ "author": "Nyakku Shigure ",
+ "license": "CC0-1.0",
+ "repository": {
+ "type": "git",
+ "url": "git+ssh://git@github.com/yutto-dev/yutto.git"
+ },
+ "bugs": {
+ "url": "https://github.com/yutto-dev/yutto/issues"
+ },
+ "homepage": "https://github.com/yutto-dev/yutto#readme",
+ "packageManager": "pnpm@9.15.4",
+ "scripts": {
+ "dev": "vitepress dev",
+ "build": "vitepress build",
+ "serve": "vitepress serve",
+ "fmt": "prettier --write .",
+ "fmt:check": "prettier --check ."
+ },
+ "devDependencies": {
+ "@moefy-canvas/core": "^0.6.0",
+ "@moefy-canvas/theme-sparkler": "^0.6.0",
+ "prettier": "^3.4.2",
+ "vite": "^6.0.11",
+ "vitepress": "^1.6.3",
+ "vitepress-plugin-group-icons": "^1.3.5",
+ "vue": "^3.5.13"
+ },
+ "pnpm": {
+ "peerDependencyRules": {
+ "ignoreMissing": [
+ "@algolia/client-search",
+ "react",
+ "react-dom",
+ "@types/react"
+ ]
+ }
+ }
+}
diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml
new file mode 100644
index 000000000..426c1f85d
--- /dev/null
+++ b/docs/pnpm-lock.yaml
@@ -0,0 +1,2047 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ devDependencies:
+ '@moefy-canvas/core':
+ specifier: ^0.6.0
+ version: 0.6.0
+ '@moefy-canvas/theme-sparkler':
+ specifier: ^0.6.0
+ version: 0.6.0
+ prettier:
+ specifier: ^3.4.2
+ version: 3.4.2
+ vite:
+ specifier: ^6.0.11
+ version: 6.0.11
+ vitepress:
+ specifier: ^1.6.3
+ version: 1.6.3(@algolia/client-search@5.20.0)(postcss@8.5.1)(search-insights@2.17.3)
+ vitepress-plugin-group-icons:
+ specifier: ^1.3.5
+ version: 1.3.5
+ vue:
+ specifier: ^3.5.13
+ version: 3.5.13
+
+packages:
+
+ '@algolia/autocomplete-core@1.17.7':
+ resolution: {integrity: sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==}
+
+ '@algolia/autocomplete-plugin-algolia-insights@1.17.7':
+ resolution: {integrity: sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==}
+ peerDependencies:
+ search-insights: '>= 1 < 3'
+
+ '@algolia/autocomplete-preset-algolia@1.17.7':
+ resolution: {integrity: sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==}
+ peerDependencies:
+ '@algolia/client-search': '>= 4.9.1 < 6'
+ algoliasearch: '>= 4.9.1 < 6'
+
+ '@algolia/autocomplete-shared@1.17.7':
+ resolution: {integrity: sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==}
+ peerDependencies:
+ '@algolia/client-search': '>= 4.9.1 < 6'
+ algoliasearch: '>= 4.9.1 < 6'
+
+ '@algolia/client-abtesting@5.20.0':
+ resolution: {integrity: sha512-YaEoNc1Xf2Yk6oCfXXkZ4+dIPLulCx8Ivqj0OsdkHWnsI3aOJChY5qsfyHhDBNSOhqn2ilgHWxSfyZrjxBcAww==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-analytics@5.20.0':
+ resolution: {integrity: sha512-CIT9ni0+5sYwqehw+t5cesjho3ugKQjPVy/iPiJvtJX4g8Cdb6je6SPt2uX72cf2ISiXCAX9U3cY0nN0efnRDw==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-common@5.20.0':
+ resolution: {integrity: sha512-iSTFT3IU8KNpbAHcBUJw2HUrPnMXeXLyGajmCL7gIzWOsYM4GabZDHXOFx93WGiXMti1dymz8k8R+bfHv1YZmA==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-insights@5.20.0':
+ resolution: {integrity: sha512-w9RIojD45z1csvW1vZmAko82fqE/Dm+Ovsy2ElTsjFDB0HMAiLh2FO86hMHbEXDPz6GhHKgGNmBRiRP8dDPgJg==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-personalization@5.20.0':
+ resolution: {integrity: sha512-p/hftHhrbiHaEcxubYOzqVV4gUqYWLpTwK+nl2xN3eTrSW9SNuFlAvUBFqPXSVBqc6J5XL9dNKn3y8OA1KElSQ==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-query-suggestions@5.20.0':
+ resolution: {integrity: sha512-m4aAuis5vZi7P4gTfiEs6YPrk/9hNTESj3gEmGFgfJw3hO2ubdS4jSId1URd6dGdt0ax2QuapXufcrN58hPUcw==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/client-search@5.20.0':
+ resolution: {integrity: sha512-KL1zWTzrlN4MSiaK1ea560iCA/UewMbS4ZsLQRPoDTWyrbDKVbztkPwwv764LAqgXk0fvkNZvJ3IelcK7DqhjQ==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/ingestion@1.20.0':
+ resolution: {integrity: sha512-shj2lTdzl9un4XJblrgqg54DoK6JeKFO8K8qInMu4XhE2JuB8De6PUuXAQwiRigZupbI0xq8aM0LKdc9+qiLQA==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/monitoring@1.20.0':
+ resolution: {integrity: sha512-aF9blPwOhKtWvkjyyXh9P5peqmhCA1XxLBRgItT+K6pbT0q4hBDQrCid+pQZJYy4HFUKjB/NDDwyzFhj/rwKhw==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/recommend@5.20.0':
+ resolution: {integrity: sha512-T6B/WPdZR3b89/F9Vvk6QCbt/wrLAtrGoL8z4qPXDFApQ8MuTFWbleN/4rHn6APWO3ps+BUePIEbue2rY5MlRw==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/requester-browser-xhr@5.20.0':
+ resolution: {integrity: sha512-t6//lXsq8E85JMenHrI6mhViipUT5riNhEfCcvtRsTV+KIBpC6Od18eK864dmBhoc5MubM0f+sGpKOqJIlBSCg==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/requester-fetch@5.20.0':
+ resolution: {integrity: sha512-FHxYGqRY+6bgjKsK4aUsTAg6xMs2S21elPe4Y50GB0Y041ihvw41Vlwy2QS6K9ldoftX4JvXodbKTcmuQxywdQ==}
+ engines: {node: '>= 14.0.0'}
+
+ '@algolia/requester-node-http@5.20.0':
+ resolution: {integrity: sha512-kmtQClq/w3vtPteDSPvaW9SPZL/xrIgMrxZyAgsFwrJk0vJxqyC5/hwHmrCraDnStnGSADnLpBf4SpZnwnkwWw==}
+ engines: {node: '>= 14.0.0'}
+
+ '@antfu/install-pkg@0.4.1':
+ resolution: {integrity: sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==}
+
+ '@antfu/utils@0.7.10':
+ resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==}
+
+ '@babel/helper-string-parser@7.25.9':
+ resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.25.9':
+ resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.26.7':
+ resolution: {integrity: sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/types@7.26.7':
+ resolution: {integrity: sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==}
+ engines: {node: '>=6.9.0'}
+
+ '@docsearch/css@3.8.2':
+ resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==}
+
+ '@docsearch/js@3.8.2':
+ resolution: {integrity: sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==}
+
+ '@docsearch/react@3.8.2':
+ resolution: {integrity: sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==}
+ peerDependencies:
+ '@types/react': '>= 16.8.0 < 19.0.0'
+ react: '>= 16.8.0 < 19.0.0'
+ react-dom: '>= 16.8.0 < 19.0.0'
+ search-insights: '>= 1 < 3'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ search-insights:
+ optional: true
+
+ '@esbuild/aix-ppc64@0.21.5':
+ resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/aix-ppc64@0.24.2':
+ resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.21.5':
+ resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm64@0.24.2':
+ resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.21.5':
+ resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-arm@0.24.2':
+ resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.21.5':
+ resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/android-x64@0.24.2':
+ resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.21.5':
+ resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-arm64@0.24.2':
+ resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.21.5':
+ resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.24.2':
+ resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.21.5':
+ resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-arm64@0.24.2':
+ resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.21.5':
+ resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.24.2':
+ resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.21.5':
+ resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm64@0.24.2':
+ resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.21.5':
+ resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.24.2':
+ resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.21.5':
+ resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.24.2':
+ resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.21.5':
+ resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.24.2':
+ resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.21.5':
+ resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.24.2':
+ resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.21.5':
+ resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.24.2':
+ resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.21.5':
+ resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.24.2':
+ resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.21.5':
+ resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.24.2':
+ resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.21.5':
+ resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.24.2':
+ resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.24.2':
+ resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.21.5':
+ resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.24.2':
+ resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.24.2':
+ resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.21.5':
+ resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.24.2':
+ resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/sunos-x64@0.21.5':
+ resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/sunos-x64@0.24.2':
+ resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.21.5':
+ resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-arm64@0.24.2':
+ resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.21.5':
+ resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.24.2':
+ resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.21.5':
+ resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.24.2':
+ resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@iconify-json/logos@1.2.4':
+ resolution: {integrity: sha512-XC4If5D/hbaZvUkTV8iaZuGlQCyG6CNOlaAaJaGa13V5QMYwYjgtKk3vPP8wz3wtTVNVEVk3LRx1fOJz+YnSMw==}
+
+ '@iconify-json/simple-icons@1.2.23':
+ resolution: {integrity: sha512-ySyZ0ZXdNveWnR71t7XGV7jhknxSlTtpM2TyIR1cUHTUzZLP36hYHTNqb2pYYsCzH5ed85KTTKz7vYT33FyNIQ==}
+
+ '@iconify-json/vscode-icons@1.2.11':
+ resolution: {integrity: sha512-V0ldtWPUKe7ZB3CV/TjgDW1Gbz74AxjGPS2NBWDTSn/y25gTwFycI1YcrluDhuVSoQpDEIYmm3JQJkhtSefh7A==}
+
+ '@iconify/types@2.0.0':
+ resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
+
+ '@iconify/utils@2.2.1':
+ resolution: {integrity: sha512-0/7J7hk4PqXmxo5PDBDxmnecw5PxklZJfNjIVG9FM0mEfVrvfudS22rYWsqVk6gR3UJ/mSYS90X4R3znXnqfNA==}
+
+ '@jridgewell/sourcemap-codec@1.5.0':
+ resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
+
+ '@moefy-canvas/core@0.6.0':
+ resolution: {integrity: sha512-i3GUeqfiEVs6Uuk32x/LYw8W0g8E9jc7y28hjZj/H1/PASYhN++lFmvJc0MhbWqjNmaUBfaWkUFIYw3RqnGcjQ==}
+
+ '@moefy-canvas/theme-sparkler@0.6.0':
+ resolution: {integrity: sha512-w/a91ZhsuCW74vXloDbxAYziiRHex5Es2hmvKQBs0Tqbx1/P/qniULj1Zh5Et7oPCyCuPQt0A/GACZpxuVWt6w==}
+
+ '@moefy-canvas/utils@0.6.0':
+ resolution: {integrity: sha512-QYW5FP8PhXTG0Y7fBkGDBNFLFNp70amwMqJiDvVYcDjSJVZYiZuvxrgvfKZYp+piL9oKBbfxgzYir9gbwZpZjA==}
+
+ '@rollup/rollup-android-arm-eabi@4.34.0':
+ resolution: {integrity: sha512-Eeao7ewDq79jVEsrtWIj5RNqB8p2knlm9fhR6uJ2gqP7UfbLrTrxevudVrEPDM7Wkpn/HpRC2QfazH7MXLz3vQ==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.34.0':
+ resolution: {integrity: sha512-yVh0Kf1f0Fq4tWNf6mWcbQBCLDpDrDEl88lzPgKhrgTcDrTtlmun92ywEF9dCjmYO3EFiSuJeeo9cYRxl2FswA==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.34.0':
+ resolution: {integrity: sha512-gCs0ErAZ9s0Osejpc3qahTsqIPUDjSKIyxK/0BGKvL+Tn0n3Kwvj8BrCv7Y5sR1Ypz1K2qz9Ny0VvkVyoXBVUQ==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.34.0':
+ resolution: {integrity: sha512-aIB5Anc8hngk15t3GUkiO4pv42ykXHfmpXGS+CzM9CTyiWyT8HIS5ygRAy7KcFb/wiw4Br+vh1byqcHRTfq2tQ==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.34.0':
+ resolution: {integrity: sha512-kpdsUdMlVJMRMaOf/tIvxk8TQdzHhY47imwmASOuMajg/GXpw8GKNd8LNwIHE5Yd1onehNpcUB9jHY6wgw9nHQ==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.34.0':
+ resolution: {integrity: sha512-D0RDyHygOBCQiqookcPevrvgEarN0CttBecG4chOeIYCNtlKHmf5oi5kAVpXV7qs0Xh/WO2RnxeicZPtT50V0g==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.34.0':
+ resolution: {integrity: sha512-mCIw8j5LPDXmCOW8mfMZwT6F/Kza03EnSr4wGYEswrEfjTfVsFOxvgYfuRMxTuUF/XmRb9WSMD5GhCWDe2iNrg==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.34.0':
+ resolution: {integrity: sha512-AwwldAu4aCJPob7zmjuDUMvvuatgs8B/QiVB0KwkUarAcPB3W+ToOT+18TQwY4z09Al7G0BvCcmLRop5zBLTag==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.34.0':
+ resolution: {integrity: sha512-e7kDUGVP+xw05pV65ZKb0zulRploU3gTu6qH1qL58PrULDGxULIS0OSDQJLH7WiFnpd3ZKUU4VM3u/Z7Zw+e7Q==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.34.0':
+ resolution: {integrity: sha512-SXYJw3zpwHgaBqTXeAZ31qfW/v50wq4HhNVvKFhRr5MnptRX2Af4KebLWR1wpxGJtLgfS2hEPuALRIY3LPAAcA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loongarch64-gnu@4.34.0':
+ resolution: {integrity: sha512-e5XiCinINCI4RdyU3sFyBH4zzz7LiQRvHqDtRe9Dt8o/8hTBaYpdPimayF00eY2qy5j4PaaWK0azRgUench6WQ==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.34.0':
+ resolution: {integrity: sha512-3SWN3e0bAsm9ToprLFBSro8nJe6YN+5xmB11N4FfNf92wvLye/+Rh5JGQtKOpwLKt6e61R1RBc9g+luLJsc23A==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.34.0':
+ resolution: {integrity: sha512-B1Oqt3GLh7qmhvfnc2WQla4NuHlcxAD5LyueUi5WtMc76ZWY+6qDtQYqnxARx9r+7mDGfamD+8kTJO0pKUJeJA==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.34.0':
+ resolution: {integrity: sha512-UfUCo0h/uj48Jq2lnhX0AOhZPSTAq3Eostas+XZ+GGk22pI+Op1Y6cxQ1JkUuKYu2iU+mXj1QjPrZm9nNWV9rg==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.34.0':
+ resolution: {integrity: sha512-chZLTUIPbgcpm+Z7ALmomXW8Zh+wE2icrG+K6nt/HenPLmtwCajhQC5flNSk1Xy5EDMt/QAOz2MhzfOfJOLSiA==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.34.0':
+ resolution: {integrity: sha512-jo0UolK70O28BifvEsFD/8r25shFezl0aUk2t0VJzREWHkq19e+pcLu4kX5HiVXNz5qqkD+aAq04Ct8rkxgbyQ==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-win32-arm64-msvc@4.34.0':
+ resolution: {integrity: sha512-Vmg0NhAap2S54JojJchiu5An54qa6t/oKT7LmDaWggpIcaiL8WcWHEN6OQrfTdL6mQ2GFyH7j2T5/3YPEDOOGA==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.34.0':
+ resolution: {integrity: sha512-CV2aqhDDOsABKHKhNcs1SZFryffQf8vK2XrxP6lxC99ELZAdvsDgPklIBfd65R8R+qvOm1SmLaZ/Fdq961+m7A==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.34.0':
+ resolution: {integrity: sha512-g2ASy1QwHP88y5KWvblUolJz9rN+i4ZOsYzkEwcNfaNooxNUXG+ON6F5xFo0NIItpHqxcdAyls05VXpBnludGw==}
+ cpu: [x64]
+ os: [win32]
+
+ '@shikijs/core@2.3.0':
+ resolution: {integrity: sha512-N1r7sIXYm31Zju3CmH6bH6tgIftF0NlHxx0HiZ85X2BLWczgFLo61PJCoF7nFZUu8DeS0g8xhZsiL8zi+tV8YQ==}
+
+ '@shikijs/engine-javascript@2.3.0':
+ resolution: {integrity: sha512-/ITg36HXHXP486+6zaQgP7Y38LIV9V2Pir4aIk7zQ5XcM1CU8dOlUL9BuyA/E6BKg1XaAgN+rFg3qsaspt+x2A==}
+
+ '@shikijs/engine-oniguruma@2.3.0':
+ resolution: {integrity: sha512-8nBH/QwDrJLxbIFg7ifrfyEtrW0m9FCfanxU9SJFUEbA+rFNbyDGdoXZ4IxkC6ykT1+Utx2vW6EYVAUk3Q9gcg==}
+
+ '@shikijs/langs@2.3.0':
+ resolution: {integrity: sha512-gaNaqbUhncigokGehwhzGe5AY+IRJKDnp+1Zp3gjxhhv6RxMYtbn9zDu3cl9ngNZGEdtEtvruz6LasdY3n0MCA==}
+
+ '@shikijs/themes@2.3.0':
+ resolution: {integrity: sha512-2M3XKry66lB975B7v+kSesGyIJrhxsLdk/RyhB+hbkXmD2Myyuspyox0/2JTqWnM1Y9132NjeVsBl1ZI507ZXw==}
+
+ '@shikijs/transformers@2.3.0':
+ resolution: {integrity: sha512-y/9RIr/YWENiZpoMbo4GkKpxgYwuP1CZTFgi1lvnxBY9zvwRHhQz62rCH+md34A995Vap1jQmkkG+kye7wotgw==}
+
+ '@shikijs/types@2.3.0':
+ resolution: {integrity: sha512-rC8ZkfIE6m17RBGwRPoXqj/an4JPUnAB1JGHELPVrzygyB0Gqa9Lc7h4xYb8c3GWywAgrjryLAJSN3kpe1fqhw==}
+
+ '@shikijs/vscode-textmate@10.0.1':
+ resolution: {integrity: sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg==}
+
+ '@types/estree@1.0.6':
+ resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
+
+ '@types/hast@3.0.4':
+ resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
+
+ '@types/linkify-it@5.0.0':
+ resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
+
+ '@types/markdown-it@14.1.2':
+ resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
+
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/mdurl@2.0.0':
+ resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
+
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@types/web-bluetooth@0.0.20':
+ resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
+
+ '@ungap/structured-clone@1.3.0':
+ resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
+
+ '@vitejs/plugin-vue@5.2.1':
+ resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ peerDependencies:
+ vite: ^5.0.0 || ^6.0.0
+ vue: ^3.2.25
+
+ '@vue/compiler-core@3.5.13':
+ resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==}
+
+ '@vue/compiler-dom@3.5.13':
+ resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==}
+
+ '@vue/compiler-sfc@3.5.13':
+ resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==}
+
+ '@vue/compiler-ssr@3.5.13':
+ resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==}
+
+ '@vue/devtools-api@7.7.1':
+ resolution: {integrity: sha512-Cexc8GimowoDkJ6eNelOPdYIzsu2mgNyp0scOQ3tiaYSb9iok6LOESSsJvHaI+ib3joRfqRJNLkHFjhNuWA5dg==}
+
+ '@vue/devtools-kit@7.7.1':
+ resolution: {integrity: sha512-yhZ4NPnK/tmxGtLNQxmll90jIIXdb2jAhPF76anvn5M/UkZCiLJy28bYgPIACKZ7FCosyKoaope89/RsFJll1w==}
+
+ '@vue/devtools-shared@7.7.1':
+ resolution: {integrity: sha512-BtgF7kHq4BHG23Lezc/3W2UhK2ga7a8ohAIAGJMBr4BkxUFzhqntQtCiuL1ijo2ztWnmusymkirgqUrXoQKumA==}
+
+ '@vue/reactivity@3.5.13':
+ resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==}
+
+ '@vue/runtime-core@3.5.13':
+ resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==}
+
+ '@vue/runtime-dom@3.5.13':
+ resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==}
+
+ '@vue/server-renderer@3.5.13':
+ resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==}
+ peerDependencies:
+ vue: 3.5.13
+
+ '@vue/shared@3.5.13':
+ resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
+
+ '@vueuse/core@12.5.0':
+ resolution: {integrity: sha512-GVyH1iYqNANwcahAx8JBm6awaNgvR/SwZ1fjr10b8l1HIgDp82ngNbfzJUgOgWEoxjL+URAggnlilAEXwCOZtg==}
+
+ '@vueuse/integrations@12.5.0':
+ resolution: {integrity: sha512-HYLt8M6mjUfcoUOzyBcX2RjpfapIwHPBmQJtTmXOQW845Y/Osu9VuTJ5kPvnmWJ6IUa05WpblfOwZ+P0G4iZsQ==}
+ peerDependencies:
+ async-validator: ^4
+ axios: ^1
+ change-case: ^5
+ drauu: ^0.4
+ focus-trap: ^7
+ fuse.js: ^7
+ idb-keyval: ^6
+ jwt-decode: ^4
+ nprogress: ^0.2
+ qrcode: ^1.5
+ sortablejs: ^1
+ universal-cookie: ^7
+ peerDependenciesMeta:
+ async-validator:
+ optional: true
+ axios:
+ optional: true
+ change-case:
+ optional: true
+ drauu:
+ optional: true
+ focus-trap:
+ optional: true
+ fuse.js:
+ optional: true
+ idb-keyval:
+ optional: true
+ jwt-decode:
+ optional: true
+ nprogress:
+ optional: true
+ qrcode:
+ optional: true
+ sortablejs:
+ optional: true
+ universal-cookie:
+ optional: true
+
+ '@vueuse/metadata@12.5.0':
+ resolution: {integrity: sha512-Ui7Lo2a7AxrMAXRF+fAp9QsXuwTeeZ8fIB9wsLHqzq9MQk+2gMYE2IGJW48VMJ8ecvCB3z3GsGLKLbSasQ5Qlg==}
+
+ '@vueuse/shared@12.5.0':
+ resolution: {integrity: sha512-vMpcL1lStUU6O+kdj6YdHDixh0odjPAUM15uJ9f7MY781jcYkIwFA4iv2EfoIPO6vBmvutI1HxxAwmf0cx5ISQ==}
+
+ acorn@8.14.0:
+ resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ algoliasearch@5.20.0:
+ resolution: {integrity: sha512-groO71Fvi5SWpxjI9Ia+chy0QBwT61mg6yxJV27f5YFf+Mw+STT75K6SHySpP8Co5LsCrtsbCH5dJZSRtkSKaQ==}
+ engines: {node: '>= 14.0.0'}
+
+ birpc@0.2.19:
+ resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==}
+
+ ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+
+ character-entities-html4@2.1.0:
+ resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+
+ character-entities-legacy@3.0.0:
+ resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+
+ color2k@2.0.3:
+ resolution: {integrity: sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==}
+
+ comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+
+ confbox@0.1.8:
+ resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
+
+ copy-anything@3.0.5:
+ resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==}
+ engines: {node: '>=12.13'}
+
+ csstype@3.1.3:
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
+ debug@4.4.0:
+ resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
+ emoji-regex-xs@1.0.0:
+ resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==}
+
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
+ esbuild@0.21.5:
+ resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
+ engines: {node: '>=12'}
+ hasBin: true
+
+ esbuild@0.24.2:
+ resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ focus-trap@7.6.4:
+ resolution: {integrity: sha512-xx560wGBk7seZ6y933idtjJQc1l+ck+pI3sKvhKozdBV1dRZoKhkW5xoCaFv9tQiX5RH1xfSxjuNu6g+lmN/gw==}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ globals@15.14.0:
+ resolution: {integrity: sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==}
+ engines: {node: '>=18'}
+
+ hast-util-to-html@9.0.4:
+ resolution: {integrity: sha512-wxQzXtdbhiwGAUKrnQJXlOPmHnEehzphwkK7aluUPQ+lEc1xefC8pblMgpp2w5ldBTEfveRIrADcrhGIWrlTDA==}
+
+ hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+
+ hookable@5.5.3:
+ resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
+
+ html-void-elements@3.0.0:
+ resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+
+ is-what@4.1.16:
+ resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
+ engines: {node: '>=12.13'}
+
+ kolorist@1.8.0:
+ resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
+
+ local-pkg@0.5.1:
+ resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==}
+ engines: {node: '>=14'}
+
+ magic-string@0.30.17:
+ resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
+
+ mark.js@8.11.1:
+ resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==}
+
+ mdast-util-to-hast@13.2.0:
+ resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==}
+
+ micromark-util-character@2.1.1:
+ resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
+
+ micromark-util-encode@2.0.1:
+ resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
+
+ micromark-util-sanitize-uri@2.0.1:
+ resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
+
+ micromark-util-symbol@2.0.1:
+ resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
+
+ micromark-util-types@2.0.1:
+ resolution: {integrity: sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==}
+
+ minisearch@7.1.1:
+ resolution: {integrity: sha512-b3YZEYCEH4EdCAtYP7OlDyx7FdPwNzuNwLQ34SfJpM9dlbBZzeXndGavTrC+VCiRWomL21SWfMc6SCKO/U2ZNw==}
+
+ mitt@3.0.1:
+ resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
+
+ mlly@1.7.4:
+ resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ nanoid@3.3.8:
+ resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ oniguruma-to-es@3.1.0:
+ resolution: {integrity: sha512-BJ3Jy22YlgejHSO7Fvmz1kKazlaPmRSUH+4adTDUS/dKQ4wLxI+gALZ8updbaux7/m7fIlpgOZ5fp/Inq5jUAw==}
+
+ package-manager-detector@0.2.9:
+ resolution: {integrity: sha512-+vYvA/Y31l8Zk8dwxHhL3JfTuHPm6tlxM2A3GeQyl7ovYnSp1+mzAxClxaOr0qO1TtPxbQxetI7v5XqKLJZk7Q==}
+
+ pathe@2.0.2:
+ resolution: {integrity: sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==}
+
+ perfect-debounce@1.0.0:
+ resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ pkg-types@1.3.1:
+ resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
+
+ postcss@8.5.1:
+ resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ preact@10.25.4:
+ resolution: {integrity: sha512-jLdZDb+Q+odkHJ+MpW/9U5cODzqnB+fy2EiHSZES7ldV5LK7yjlVzTp7R8Xy6W6y75kfK8iWYtFVH7lvjwrCMA==}
+
+ prettier@3.4.2:
+ resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==}
+ engines: {node: '>=14'}
+ hasBin: true
+
+ property-information@6.5.0:
+ resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==}
+
+ regex-recursion@6.0.2:
+ resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
+
+ regex-utilities@2.3.0:
+ resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==}
+
+ regex@6.0.1:
+ resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==}
+
+ rfdc@1.4.1:
+ resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
+
+ rollup@4.34.0:
+ resolution: {integrity: sha512-+4C/cgJ9w6sudisA0nZz0+O7lTP9a3CzNLsoDwaRumM8QHwghUsu6tqHXiTmNUp/rqNiM14++7dkzHDyCRs0Jg==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ search-insights@2.17.3:
+ resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==}
+
+ shiki@2.3.0:
+ resolution: {integrity: sha512-wMmrvyxj4i8ft9r2dA+aIi5+G6PL0Dz19h5fr5xG7Jvo8uLIOWxaveSRl3LNcj58h+jUnhdkCh7tQIVULGNXJw==}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ space-separated-tokens@2.0.2:
+ resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+
+ speakingurl@14.0.1:
+ resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
+ engines: {node: '>=0.10.0'}
+
+ stringify-entities@4.0.4:
+ resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
+
+ superjson@2.2.2:
+ resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==}
+ engines: {node: '>=16'}
+
+ tabbable@6.2.0:
+ resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
+
+ tinyexec@0.3.2:
+ resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
+
+ trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+
+ ts-debounce@4.0.0:
+ resolution: {integrity: sha512-+1iDGY6NmOGidq7i7xZGA4cm8DAa6fqdYcvO5Z6yBevH++Bdo9Qt/mN0TzHUgcCcKv1gmh9+W5dHqz8pMWbCbg==}
+
+ ufo@1.5.4:
+ resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==}
+
+ unist-util-is@6.0.0:
+ resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==}
+
+ unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ unist-util-visit-parents@6.0.1:
+ resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==}
+
+ unist-util-visit@5.0.0:
+ resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
+
+ vfile-message@4.0.2:
+ resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
+ vite@5.4.14:
+ resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || >=20.0.0
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+
+ vite@6.0.11:
+ resolution: {integrity: sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+ jiti: '>=1.21.0'
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ vitepress-plugin-group-icons@1.3.5:
+ resolution: {integrity: sha512-1f1NP7osRYlNTR0yS5CAqcaasKHRSAzFKpeCUOfCPwYLAFxhCxsEbRtPBm0U1CfrDVa303MsjX18ngGpFGxIMA==}
+
+ vitepress@1.6.3:
+ resolution: {integrity: sha512-fCkfdOk8yRZT8GD9BFqusW3+GggWYZ/rYncOfmgcDtP3ualNHCAg+Robxp2/6xfH1WwPHtGpPwv7mbA3qomtBw==}
+ hasBin: true
+ peerDependencies:
+ markdown-it-mathjax3: ^4
+ postcss: ^8
+ peerDependenciesMeta:
+ markdown-it-mathjax3:
+ optional: true
+ postcss:
+ optional: true
+
+ vue@3.5.13:
+ resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+
+snapshots:
+
+ '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)(search-insights@2.17.3)':
+ dependencies:
+ '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)(search-insights@2.17.3)
+ '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - algoliasearch
+ - search-insights
+
+ '@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)(search-insights@2.17.3)':
+ dependencies:
+ '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
+ search-insights: 2.17.3
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - algoliasearch
+
+ '@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)':
+ dependencies:
+ '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
+ '@algolia/client-search': 5.20.0
+ algoliasearch: 5.20.0
+
+ '@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)':
+ dependencies:
+ '@algolia/client-search': 5.20.0
+ algoliasearch: 5.20.0
+
+ '@algolia/client-abtesting@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/client-analytics@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/client-common@5.20.0': {}
+
+ '@algolia/client-insights@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/client-personalization@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/client-query-suggestions@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/client-search@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/ingestion@1.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/monitoring@1.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/recommend@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ '@algolia/requester-browser-xhr@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+
+ '@algolia/requester-fetch@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+
+ '@algolia/requester-node-http@5.20.0':
+ dependencies:
+ '@algolia/client-common': 5.20.0
+
+ '@antfu/install-pkg@0.4.1':
+ dependencies:
+ package-manager-detector: 0.2.9
+ tinyexec: 0.3.2
+
+ '@antfu/utils@0.7.10': {}
+
+ '@babel/helper-string-parser@7.25.9': {}
+
+ '@babel/helper-validator-identifier@7.25.9': {}
+
+ '@babel/parser@7.26.7':
+ dependencies:
+ '@babel/types': 7.26.7
+
+ '@babel/types@7.26.7':
+ dependencies:
+ '@babel/helper-string-parser': 7.25.9
+ '@babel/helper-validator-identifier': 7.25.9
+
+ '@docsearch/css@3.8.2': {}
+
+ '@docsearch/js@3.8.2(@algolia/client-search@5.20.0)(search-insights@2.17.3)':
+ dependencies:
+ '@docsearch/react': 3.8.2(@algolia/client-search@5.20.0)(search-insights@2.17.3)
+ preact: 10.25.4
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - '@types/react'
+ - react
+ - react-dom
+ - search-insights
+
+ '@docsearch/react@3.8.2(@algolia/client-search@5.20.0)(search-insights@2.17.3)':
+ dependencies:
+ '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)(search-insights@2.17.3)
+ '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.20.0)(algoliasearch@5.20.0)
+ '@docsearch/css': 3.8.2
+ algoliasearch: 5.20.0
+ optionalDependencies:
+ search-insights: 2.17.3
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+
+ '@esbuild/aix-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/aix-ppc64@0.24.2':
+ optional: true
+
+ '@esbuild/android-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/android-arm@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm@0.24.2':
+ optional: true
+
+ '@esbuild/android-x64@0.21.5':
+ optional: true
+
+ '@esbuild/android-x64@0.24.2':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/darwin-x64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-x64@0.24.2':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.24.2':
+ optional: true
+
+ '@esbuild/linux-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/linux-arm@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm@0.24.2':
+ optional: true
+
+ '@esbuild/linux-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ia32@0.24.2':
+ optional: true
+
+ '@esbuild/linux-loong64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-loong64@0.24.2':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.21.5':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.24.2':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.24.2':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.24.2':
+ optional: true
+
+ '@esbuild/linux-s390x@0.21.5':
+ optional: true
+
+ '@esbuild/linux-s390x@0.24.2':
+ optional: true
+
+ '@esbuild/linux-x64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-x64@0.24.2':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.24.2':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.24.2':
+ optional: true
+
+ '@esbuild/sunos-x64@0.21.5':
+ optional: true
+
+ '@esbuild/sunos-x64@0.24.2':
+ optional: true
+
+ '@esbuild/win32-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/win32-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/win32-ia32@0.24.2':
+ optional: true
+
+ '@esbuild/win32-x64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-x64@0.24.2':
+ optional: true
+
+ '@iconify-json/logos@1.2.4':
+ dependencies:
+ '@iconify/types': 2.0.0
+
+ '@iconify-json/simple-icons@1.2.23':
+ dependencies:
+ '@iconify/types': 2.0.0
+
+ '@iconify-json/vscode-icons@1.2.11':
+ dependencies:
+ '@iconify/types': 2.0.0
+
+ '@iconify/types@2.0.0': {}
+
+ '@iconify/utils@2.2.1':
+ dependencies:
+ '@antfu/install-pkg': 0.4.1
+ '@antfu/utils': 0.7.10
+ '@iconify/types': 2.0.0
+ debug: 4.4.0
+ globals: 15.14.0
+ kolorist: 1.8.0
+ local-pkg: 0.5.1
+ mlly: 1.7.4
+ transitivePeerDependencies:
+ - supports-color
+
+ '@jridgewell/sourcemap-codec@1.5.0': {}
+
+ '@moefy-canvas/core@0.6.0': {}
+
+ '@moefy-canvas/theme-sparkler@0.6.0':
+ dependencies:
+ '@moefy-canvas/core': 0.6.0
+ '@moefy-canvas/utils': 0.6.0
+ color2k: 2.0.3
+ ts-debounce: 4.0.0
+
+ '@moefy-canvas/utils@0.6.0':
+ dependencies:
+ '@moefy-canvas/core': 0.6.0
+
+ '@rollup/rollup-android-arm-eabi@4.34.0':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.34.0':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.34.0':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.34.0':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.34.0':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.34.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.34.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.34.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.34.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.34.0':
+ optional: true
+
+ '@rollup/rollup-linux-loongarch64-gnu@4.34.0':
+ optional: true
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.34.0':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.34.0':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.34.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.34.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.34.0':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.34.0':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.34.0':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.34.0':
+ optional: true
+
+ '@shikijs/core@2.3.0':
+ dependencies:
+ '@shikijs/engine-javascript': 2.3.0
+ '@shikijs/engine-oniguruma': 2.3.0
+ '@shikijs/types': 2.3.0
+ '@shikijs/vscode-textmate': 10.0.1
+ '@types/hast': 3.0.4
+ hast-util-to-html: 9.0.4
+
+ '@shikijs/engine-javascript@2.3.0':
+ dependencies:
+ '@shikijs/types': 2.3.0
+ '@shikijs/vscode-textmate': 10.0.1
+ oniguruma-to-es: 3.1.0
+
+ '@shikijs/engine-oniguruma@2.3.0':
+ dependencies:
+ '@shikijs/types': 2.3.0
+ '@shikijs/vscode-textmate': 10.0.1
+
+ '@shikijs/langs@2.3.0':
+ dependencies:
+ '@shikijs/types': 2.3.0
+
+ '@shikijs/themes@2.3.0':
+ dependencies:
+ '@shikijs/types': 2.3.0
+
+ '@shikijs/transformers@2.3.0':
+ dependencies:
+ '@shikijs/core': 2.3.0
+ '@shikijs/types': 2.3.0
+
+ '@shikijs/types@2.3.0':
+ dependencies:
+ '@shikijs/vscode-textmate': 10.0.1
+ '@types/hast': 3.0.4
+
+ '@shikijs/vscode-textmate@10.0.1': {}
+
+ '@types/estree@1.0.6': {}
+
+ '@types/hast@3.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/linkify-it@5.0.0': {}
+
+ '@types/markdown-it@14.1.2':
+ dependencies:
+ '@types/linkify-it': 5.0.0
+ '@types/mdurl': 2.0.0
+
+ '@types/mdast@4.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/mdurl@2.0.0': {}
+
+ '@types/unist@3.0.3': {}
+
+ '@types/web-bluetooth@0.0.20': {}
+
+ '@ungap/structured-clone@1.3.0': {}
+
+ '@vitejs/plugin-vue@5.2.1(vite@5.4.14)(vue@3.5.13)':
+ dependencies:
+ vite: 5.4.14
+ vue: 3.5.13
+
+ '@vue/compiler-core@3.5.13':
+ dependencies:
+ '@babel/parser': 7.26.7
+ '@vue/shared': 3.5.13
+ entities: 4.5.0
+ estree-walker: 2.0.2
+ source-map-js: 1.2.1
+
+ '@vue/compiler-dom@3.5.13':
+ dependencies:
+ '@vue/compiler-core': 3.5.13
+ '@vue/shared': 3.5.13
+
+ '@vue/compiler-sfc@3.5.13':
+ dependencies:
+ '@babel/parser': 7.26.7
+ '@vue/compiler-core': 3.5.13
+ '@vue/compiler-dom': 3.5.13
+ '@vue/compiler-ssr': 3.5.13
+ '@vue/shared': 3.5.13
+ estree-walker: 2.0.2
+ magic-string: 0.30.17
+ postcss: 8.5.1
+ source-map-js: 1.2.1
+
+ '@vue/compiler-ssr@3.5.13':
+ dependencies:
+ '@vue/compiler-dom': 3.5.13
+ '@vue/shared': 3.5.13
+
+ '@vue/devtools-api@7.7.1':
+ dependencies:
+ '@vue/devtools-kit': 7.7.1
+
+ '@vue/devtools-kit@7.7.1':
+ dependencies:
+ '@vue/devtools-shared': 7.7.1
+ birpc: 0.2.19
+ hookable: 5.5.3
+ mitt: 3.0.1
+ perfect-debounce: 1.0.0
+ speakingurl: 14.0.1
+ superjson: 2.2.2
+
+ '@vue/devtools-shared@7.7.1':
+ dependencies:
+ rfdc: 1.4.1
+
+ '@vue/reactivity@3.5.13':
+ dependencies:
+ '@vue/shared': 3.5.13
+
+ '@vue/runtime-core@3.5.13':
+ dependencies:
+ '@vue/reactivity': 3.5.13
+ '@vue/shared': 3.5.13
+
+ '@vue/runtime-dom@3.5.13':
+ dependencies:
+ '@vue/reactivity': 3.5.13
+ '@vue/runtime-core': 3.5.13
+ '@vue/shared': 3.5.13
+ csstype: 3.1.3
+
+ '@vue/server-renderer@3.5.13(vue@3.5.13)':
+ dependencies:
+ '@vue/compiler-ssr': 3.5.13
+ '@vue/shared': 3.5.13
+ vue: 3.5.13
+
+ '@vue/shared@3.5.13': {}
+
+ '@vueuse/core@12.5.0':
+ dependencies:
+ '@types/web-bluetooth': 0.0.20
+ '@vueuse/metadata': 12.5.0
+ '@vueuse/shared': 12.5.0
+ vue: 3.5.13
+ transitivePeerDependencies:
+ - typescript
+
+ '@vueuse/integrations@12.5.0(focus-trap@7.6.4)':
+ dependencies:
+ '@vueuse/core': 12.5.0
+ '@vueuse/shared': 12.5.0
+ vue: 3.5.13
+ optionalDependencies:
+ focus-trap: 7.6.4
+ transitivePeerDependencies:
+ - typescript
+
+ '@vueuse/metadata@12.5.0': {}
+
+ '@vueuse/shared@12.5.0':
+ dependencies:
+ vue: 3.5.13
+ transitivePeerDependencies:
+ - typescript
+
+ acorn@8.14.0: {}
+
+ algoliasearch@5.20.0:
+ dependencies:
+ '@algolia/client-abtesting': 5.20.0
+ '@algolia/client-analytics': 5.20.0
+ '@algolia/client-common': 5.20.0
+ '@algolia/client-insights': 5.20.0
+ '@algolia/client-personalization': 5.20.0
+ '@algolia/client-query-suggestions': 5.20.0
+ '@algolia/client-search': 5.20.0
+ '@algolia/ingestion': 1.20.0
+ '@algolia/monitoring': 1.20.0
+ '@algolia/recommend': 5.20.0
+ '@algolia/requester-browser-xhr': 5.20.0
+ '@algolia/requester-fetch': 5.20.0
+ '@algolia/requester-node-http': 5.20.0
+
+ birpc@0.2.19: {}
+
+ ccount@2.0.1: {}
+
+ character-entities-html4@2.1.0: {}
+
+ character-entities-legacy@3.0.0: {}
+
+ color2k@2.0.3: {}
+
+ comma-separated-tokens@2.0.3: {}
+
+ confbox@0.1.8: {}
+
+ copy-anything@3.0.5:
+ dependencies:
+ is-what: 4.1.16
+
+ csstype@3.1.3: {}
+
+ debug@4.4.0:
+ dependencies:
+ ms: 2.1.3
+
+ dequal@2.0.3: {}
+
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
+ emoji-regex-xs@1.0.0: {}
+
+ entities@4.5.0: {}
+
+ esbuild@0.21.5:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.21.5
+ '@esbuild/android-arm': 0.21.5
+ '@esbuild/android-arm64': 0.21.5
+ '@esbuild/android-x64': 0.21.5
+ '@esbuild/darwin-arm64': 0.21.5
+ '@esbuild/darwin-x64': 0.21.5
+ '@esbuild/freebsd-arm64': 0.21.5
+ '@esbuild/freebsd-x64': 0.21.5
+ '@esbuild/linux-arm': 0.21.5
+ '@esbuild/linux-arm64': 0.21.5
+ '@esbuild/linux-ia32': 0.21.5
+ '@esbuild/linux-loong64': 0.21.5
+ '@esbuild/linux-mips64el': 0.21.5
+ '@esbuild/linux-ppc64': 0.21.5
+ '@esbuild/linux-riscv64': 0.21.5
+ '@esbuild/linux-s390x': 0.21.5
+ '@esbuild/linux-x64': 0.21.5
+ '@esbuild/netbsd-x64': 0.21.5
+ '@esbuild/openbsd-x64': 0.21.5
+ '@esbuild/sunos-x64': 0.21.5
+ '@esbuild/win32-arm64': 0.21.5
+ '@esbuild/win32-ia32': 0.21.5
+ '@esbuild/win32-x64': 0.21.5
+
+ esbuild@0.24.2:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.24.2
+ '@esbuild/android-arm': 0.24.2
+ '@esbuild/android-arm64': 0.24.2
+ '@esbuild/android-x64': 0.24.2
+ '@esbuild/darwin-arm64': 0.24.2
+ '@esbuild/darwin-x64': 0.24.2
+ '@esbuild/freebsd-arm64': 0.24.2
+ '@esbuild/freebsd-x64': 0.24.2
+ '@esbuild/linux-arm': 0.24.2
+ '@esbuild/linux-arm64': 0.24.2
+ '@esbuild/linux-ia32': 0.24.2
+ '@esbuild/linux-loong64': 0.24.2
+ '@esbuild/linux-mips64el': 0.24.2
+ '@esbuild/linux-ppc64': 0.24.2
+ '@esbuild/linux-riscv64': 0.24.2
+ '@esbuild/linux-s390x': 0.24.2
+ '@esbuild/linux-x64': 0.24.2
+ '@esbuild/netbsd-arm64': 0.24.2
+ '@esbuild/netbsd-x64': 0.24.2
+ '@esbuild/openbsd-arm64': 0.24.2
+ '@esbuild/openbsd-x64': 0.24.2
+ '@esbuild/sunos-x64': 0.24.2
+ '@esbuild/win32-arm64': 0.24.2
+ '@esbuild/win32-ia32': 0.24.2
+ '@esbuild/win32-x64': 0.24.2
+
+ estree-walker@2.0.2: {}
+
+ focus-trap@7.6.4:
+ dependencies:
+ tabbable: 6.2.0
+
+ fsevents@2.3.3:
+ optional: true
+
+ globals@15.14.0: {}
+
+ hast-util-to-html@9.0.4:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ comma-separated-tokens: 2.0.3
+ hast-util-whitespace: 3.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.0
+ property-information: 6.5.0
+ space-separated-tokens: 2.0.2
+ stringify-entities: 4.0.4
+ zwitch: 2.0.4
+
+ hast-util-whitespace@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hookable@5.5.3: {}
+
+ html-void-elements@3.0.0: {}
+
+ is-what@4.1.16: {}
+
+ kolorist@1.8.0: {}
+
+ local-pkg@0.5.1:
+ dependencies:
+ mlly: 1.7.4
+ pkg-types: 1.3.1
+
+ magic-string@0.30.17:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ mark.js@8.11.1: {}
+
+ mdast-util-to-hast@13.2.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@ungap/structured-clone': 1.3.0
+ devlop: 1.1.0
+ micromark-util-sanitize-uri: 2.0.1
+ trim-lines: 3.0.1
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.0.0
+ vfile: 6.0.3
+
+ micromark-util-character@2.1.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.1
+
+ micromark-util-encode@2.0.1: {}
+
+ micromark-util-sanitize-uri@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-encode: 2.0.1
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-symbol@2.0.1: {}
+
+ micromark-util-types@2.0.1: {}
+
+ minisearch@7.1.1: {}
+
+ mitt@3.0.1: {}
+
+ mlly@1.7.4:
+ dependencies:
+ acorn: 8.14.0
+ pathe: 2.0.2
+ pkg-types: 1.3.1
+ ufo: 1.5.4
+
+ ms@2.1.3: {}
+
+ nanoid@3.3.8: {}
+
+ oniguruma-to-es@3.1.0:
+ dependencies:
+ emoji-regex-xs: 1.0.0
+ regex: 6.0.1
+ regex-recursion: 6.0.2
+
+ package-manager-detector@0.2.9: {}
+
+ pathe@2.0.2: {}
+
+ perfect-debounce@1.0.0: {}
+
+ picocolors@1.1.1: {}
+
+ pkg-types@1.3.1:
+ dependencies:
+ confbox: 0.1.8
+ mlly: 1.7.4
+ pathe: 2.0.2
+
+ postcss@8.5.1:
+ dependencies:
+ nanoid: 3.3.8
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ preact@10.25.4: {}
+
+ prettier@3.4.2: {}
+
+ property-information@6.5.0: {}
+
+ regex-recursion@6.0.2:
+ dependencies:
+ regex-utilities: 2.3.0
+
+ regex-utilities@2.3.0: {}
+
+ regex@6.0.1:
+ dependencies:
+ regex-utilities: 2.3.0
+
+ rfdc@1.4.1: {}
+
+ rollup@4.34.0:
+ dependencies:
+ '@types/estree': 1.0.6
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.34.0
+ '@rollup/rollup-android-arm64': 4.34.0
+ '@rollup/rollup-darwin-arm64': 4.34.0
+ '@rollup/rollup-darwin-x64': 4.34.0
+ '@rollup/rollup-freebsd-arm64': 4.34.0
+ '@rollup/rollup-freebsd-x64': 4.34.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.34.0
+ '@rollup/rollup-linux-arm-musleabihf': 4.34.0
+ '@rollup/rollup-linux-arm64-gnu': 4.34.0
+ '@rollup/rollup-linux-arm64-musl': 4.34.0
+ '@rollup/rollup-linux-loongarch64-gnu': 4.34.0
+ '@rollup/rollup-linux-powerpc64le-gnu': 4.34.0
+ '@rollup/rollup-linux-riscv64-gnu': 4.34.0
+ '@rollup/rollup-linux-s390x-gnu': 4.34.0
+ '@rollup/rollup-linux-x64-gnu': 4.34.0
+ '@rollup/rollup-linux-x64-musl': 4.34.0
+ '@rollup/rollup-win32-arm64-msvc': 4.34.0
+ '@rollup/rollup-win32-ia32-msvc': 4.34.0
+ '@rollup/rollup-win32-x64-msvc': 4.34.0
+ fsevents: 2.3.3
+
+ search-insights@2.17.3: {}
+
+ shiki@2.3.0:
+ dependencies:
+ '@shikijs/core': 2.3.0
+ '@shikijs/engine-javascript': 2.3.0
+ '@shikijs/engine-oniguruma': 2.3.0
+ '@shikijs/langs': 2.3.0
+ '@shikijs/themes': 2.3.0
+ '@shikijs/types': 2.3.0
+ '@shikijs/vscode-textmate': 10.0.1
+ '@types/hast': 3.0.4
+
+ source-map-js@1.2.1: {}
+
+ space-separated-tokens@2.0.2: {}
+
+ speakingurl@14.0.1: {}
+
+ stringify-entities@4.0.4:
+ dependencies:
+ character-entities-html4: 2.1.0
+ character-entities-legacy: 3.0.0
+
+ superjson@2.2.2:
+ dependencies:
+ copy-anything: 3.0.5
+
+ tabbable@6.2.0: {}
+
+ tinyexec@0.3.2: {}
+
+ trim-lines@3.0.1: {}
+
+ ts-debounce@4.0.0: {}
+
+ ufo@1.5.4: {}
+
+ unist-util-is@6.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-stringify-position@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-parents@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.0
+
+ unist-util-visit@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.0
+ unist-util-visit-parents: 6.0.1
+
+ vfile-message@4.0.2:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-stringify-position: 4.0.0
+
+ vfile@6.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile-message: 4.0.2
+
+ vite@5.4.14:
+ dependencies:
+ esbuild: 0.21.5
+ postcss: 8.5.1
+ rollup: 4.34.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ vite@6.0.11:
+ dependencies:
+ esbuild: 0.24.2
+ postcss: 8.5.1
+ rollup: 4.34.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ vitepress-plugin-group-icons@1.3.5:
+ dependencies:
+ '@iconify-json/logos': 1.2.4
+ '@iconify-json/vscode-icons': 1.2.11
+ '@iconify/utils': 2.2.1
+ transitivePeerDependencies:
+ - supports-color
+
+ vitepress@1.6.3(@algolia/client-search@5.20.0)(postcss@8.5.1)(search-insights@2.17.3):
+ dependencies:
+ '@docsearch/css': 3.8.2
+ '@docsearch/js': 3.8.2(@algolia/client-search@5.20.0)(search-insights@2.17.3)
+ '@iconify-json/simple-icons': 1.2.23
+ '@shikijs/core': 2.3.0
+ '@shikijs/transformers': 2.3.0
+ '@shikijs/types': 2.3.0
+ '@types/markdown-it': 14.1.2
+ '@vitejs/plugin-vue': 5.2.1(vite@5.4.14)(vue@3.5.13)
+ '@vue/devtools-api': 7.7.1
+ '@vue/shared': 3.5.13
+ '@vueuse/core': 12.5.0
+ '@vueuse/integrations': 12.5.0(focus-trap@7.6.4)
+ focus-trap: 7.6.4
+ mark.js: 8.11.1
+ minisearch: 7.1.1
+ shiki: 2.3.0
+ vite: 5.4.14
+ vue: 3.5.13
+ optionalDependencies:
+ postcss: 8.5.1
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - '@types/node'
+ - '@types/react'
+ - async-validator
+ - axios
+ - change-case
+ - drauu
+ - fuse.js
+ - idb-keyval
+ - jwt-decode
+ - less
+ - lightningcss
+ - nprogress
+ - qrcode
+ - react
+ - react-dom
+ - sass
+ - sass-embedded
+ - search-insights
+ - sortablejs
+ - stylus
+ - sugarss
+ - terser
+ - typescript
+ - universal-cookie
+
+ vue@3.5.13:
+ dependencies:
+ '@vue/compiler-dom': 3.5.13
+ '@vue/compiler-sfc': 3.5.13
+ '@vue/runtime-dom': 3.5.13
+ '@vue/server-renderer': 3.5.13(vue@3.5.13)
+ '@vue/shared': 3.5.13
+
+ zwitch@2.0.4: {}
diff --git a/docs/public/logo-mini.svg b/docs/public/logo-mini.svg
new file mode 100644
index 000000000..3d2084922
--- /dev/null
+++ b/docs/public/logo-mini.svg
@@ -0,0 +1,108 @@
+
diff --git a/logo/logo.png b/docs/public/logo.png
similarity index 100%
rename from logo/logo.png
rename to docs/public/logo.png
diff --git a/docs/sponsor.md b/docs/sponsor.md
new file mode 100644
index 000000000..c9529d16c
--- /dev/null
+++ b/docs/sponsor.md
@@ -0,0 +1,17 @@
+# 赞助
+
+首先说明,由于我只是将 B 站的视频搬运到你的电脑上,是一件很简单的事情,请把最大的感激给予平台以及创作者。
+
+如果你想支持我的话,在 [GitHub 项目主页](https://github.com/yutto-dev/yutto)给予我一个 「Star」 就是对我的最大鼓励。
+
+此外,如果你想给予 Nyakku 一定资金支持以激励 Nyakku 的开发的话,你可以通过以下方式进行
+
+## 一次性赞助
+
+你可以通过[支付宝](https://img.nyakku.moe/sponsor/alipay.png)或者[微信](https://img.nyakku.moe/sponsor/wechat.png)来为 Nyakku 提供一笔开发资金。
+
+## 周期性赞助
+
+你可以通过 [Patreon](https://www.patreon.com/SigureMo) 或者[爱发电](https://afdian.net/@siguremo)来为 Nyakku 提供每月的资金支持,以激励 Nyakku 创作更多有趣、实用的开源项目。
+
+你的任何金额的赞助我都会无比珍惜,我会在[项目致谢](./guide/thanks)中标注你的 GitHub ID(需要在赞助时备注你的 GitHub ID,如果有资助后忘记留 ID 的可以联系我~)。
diff --git a/docs/tsconfig.json b/docs/tsconfig.json
new file mode 100644
index 000000000..622223491
--- /dev/null
+++ b/docs/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "declaration": true,
+ "declarationMap": true,
+ "lib": ["DOM", "ES2020"],
+ "module": "ESNext",
+ "moduleResolution": "node",
+ "jsx": "preserve",
+ "newLine": "lf",
+ "noEmitOnError": true,
+ "noImplicitAny": false,
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "sourceMap": true,
+ "strict": true,
+ "strictNullChecks": true,
+ "target": "ES2018"
+ },
+ "include": ["./.vitepress/**/*", "./.vitepress/env.d.ts"]
+}
diff --git a/justfile b/justfile
index 74f33bf2d..8605c6c7f 100644
--- a/justfile
+++ b/justfile
@@ -70,6 +70,7 @@ clean-builds:
generate-schema:
uv run scripts/generate-schema.py
+# CI specific
ci-install:
uv sync --all-extras --dev
@@ -85,6 +86,7 @@ ci-test:
ci-e2e-test:
uv run pytest -m "e2e and not (ci_skip or ignore)"
+# docker specific
docker-run *ARGS:
docker run --rm -it -v `pwd`:/app {{DOCKER_NAME}} {{ARGS}}
@@ -94,6 +96,13 @@ docker-build:
docker-publish:
docker buildx build --no-cache --platform=linux/amd64,linux/arm64 -t "{{DOCKER_NAME}}:{{VERSION}}" -t "{{DOCKER_NAME}}:latest" . --push
+# docs specific
+docs-dev:
+ cd docs; pnpm dev
+
+docs-build:
+ cd docs; pnpm build
+
# biliass specific
build-biliass:
cd packages/biliass; maturin build
diff --git a/src/yutto/cli/cli.py b/src/yutto/cli/cli.py
index 19b8b24b1..5244536b8 100644
--- a/src/yutto/cli/cli.py
+++ b/src/yutto/cli/cli.py
@@ -163,17 +163,17 @@ def cli() -> argparse.ArgumentParser:
default=settings.basic.banned_mirrors_pattern,
help="禁用下载链接的镜像源,使用正则匹配",
)
- group_basic.add_argument("--no-color", default=settings.basic.no_color, action="store_true", help="不使用颜色")
- group_basic.add_argument(
- "--no-progress", default=settings.basic.no_progress, action="store_true", help="不显示进度条"
- )
- group_basic.add_argument("--debug", default=settings.basic.debug, action="store_true", help="启用 debug 模式")
group_basic.add_argument(
"--vip-strict", default=settings.basic.vip_strict, action="store_true", help="启用严格检查大会员生效"
)
group_basic.add_argument(
"--login-strict", default=settings.basic.login_strict, action="store_true", help="启用严格检查登录状态"
)
+ group_basic.add_argument("--no-color", default=settings.basic.no_color, action="store_true", help="不使用颜色")
+ group_basic.add_argument(
+ "--no-progress", default=settings.basic.no_progress, action="store_true", help="不显示进度条"
+ )
+ group_basic.add_argument("--debug", default=settings.basic.debug, action="store_true", help="启用 debug 模式")
# 资源选择
group_resource = parser.add_argument_group("resource", "资源选择参数")
@@ -252,9 +252,9 @@ def cli() -> argparse.ArgumentParser:
group_resource.set_defaults(
require_video=settings.resource.require_video,
require_audio=settings.resource.require_audio,
+ require_danmaku=settings.resource.require_danmaku,
require_subtitle=settings.resource.require_subtitle,
require_metadata=settings.resource.require_metadata,
- require_danmaku=settings.resource.require_danmaku,
require_cover=settings.resource.require_cover,
require_chapter_info=settings.resource.require_chapter_info,
)
diff --git a/src/yutto/cli/settings.py b/src/yutto/cli/settings.py
index d1538485e..27c45f404 100644
--- a/src/yutto/cli/settings.py
+++ b/src/yutto/cli/settings.py
@@ -53,19 +53,19 @@ class YuttoBasicSettings(BaseModel):
metadata_format_premiered: Annotated[str, Field(TIME_DATE_FMT)]
download_interval: Annotated[int, Field(0)]
banned_mirrors_pattern: Annotated[Optional[str], Field(None)] # noqa: UP007
+ vip_strict: Annotated[bool, Field(False)]
+ login_strict: Annotated[bool, Field(False)]
no_color: Annotated[bool, Field(False)]
no_progress: Annotated[bool, Field(False)]
debug: Annotated[bool, Field(False)]
- vip_strict: Annotated[bool, Field(False)]
- login_strict: Annotated[bool, Field(False)]
class YuttoResourceSettings(BaseModel):
require_video: Annotated[bool, Field(True)]
require_audio: Annotated[bool, Field(True)]
+ require_danmaku: Annotated[bool, Field(True)]
require_subtitle: Annotated[bool, Field(True)]
require_metadata: Annotated[bool, Field(False)]
- require_danmaku: Annotated[bool, Field(True)]
require_cover: Annotated[bool, Field(True)]
require_chapter_info: Annotated[bool, Field(True)]
save_cover: Annotated[bool, Field(False)]
diff --git a/src/yutto/extractor/cheese.py b/src/yutto/extractor/cheese.py
index be9a2a695..7759791a1 100644
--- a/src/yutto/extractor/cheese.py
+++ b/src/yutto/extractor/cheese.py
@@ -38,9 +38,10 @@ class CheeseExtractor(SingleExtractor):
def resolve_shortcut(self, id: str) -> tuple[bool, str]:
matched = False
url = id
- if match_obj := self.REGEX_EP_ID.match(id):
- url = f"https://www.bilibili.com/cheese/play/ep{match_obj.group('episode_id')}"
- matched = True
+ # TODO 和番剧的快捷方式冲突,课程中暂时放弃快捷方式特性
+ # if match_obj := self.REGEX_EP_ID.match(id):
+ # url = f"https://www.bilibili.com/cheese/play/ep{match_obj.group('episode_id')}"
+ # matched = True
return matched, url
def match(self, url: str) -> bool: