Selaa lähdekoodia

feat(openapi): 依据 api-v13 源码重新生成全量 API 规格

原规格停在 2022.12.8,只覆盖 14 个路径,后端已有 696 条路由。改为从源码生成:

- 新增 openapi/scripts/generate.php:读 route:list --json,再用 nikic/php-parser
  解析控制器,提取文档注释、$request->input()/query()、switch 的 case 枚举、
  validate() 规则与 *Resource::toArray() 的键
- 支持在控制器 docblock 里用 @queryParam / @bodyParam / @urlParam / @deprecated
  标注参数,描述里可写 Enum: / Default: / Example:
- 产出 285 个 path、777 个 operation,redocly lint 0 error
- servers 改为 /api(原来的 /api/v2 与现有 v2/v3/ops 三套前缀不符),
  统一声明 {ok, message, data} 信封与 bearer 认证
- 旧的手写 yaml 删除,改由 overrides/ 深度合并保留人工补充
- package.json 增加 generate / lint 脚本,README 重写

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
visuddhinanda 3 viikkoa sitten
vanhempi
sitoutus
a45b3ed43e
100 muutettua tiedostoa jossa 15106 lisäystä ja 76 poistoa
  1. 75 11
      openapi/README.md
  2. 4372 0
      openapi/package-lock.json
  3. 4 1
      openapi/package.json
  4. 626 38
      openapi/public/assets/protocol/main.yaml
  5. 14 0
      openapi/public/assets/protocol/overrides/README.md
  6. 0 13
      openapi/public/assets/protocol/resources/auth/users/index.yaml
  7. 0 13
      openapi/public/assets/protocol/resources/auth/users/sign-in.yaml
  8. 56 0
      openapi/public/assets/protocol/resources/auto/api-sentence-progress-daily-image.yaml
  9. 38 0
      openapi/public/assets/protocol/resources/auto/api-sentence-progress-image.yaml
  10. 37 0
      openapi/public/assets/protocol/resources/auto/ops-update-pali-synonyms-version.yaml
  11. 125 0
      openapi/public/assets/protocol/resources/auto/v2-access-token-access-token.yaml
  12. 99 0
      openapi/public/assets/protocol/resources/auto/v2-access-token.yaml
  13. 125 0
      openapi/public/assets/protocol/resources/auto/v2-ai-assistant-ai-assistant.yaml
  14. 90 0
      openapi/public/assets/protocol/resources/auto/v2-ai-assistant.yaml
  15. 143 0
      openapi/public/assets/protocol/resources/auto/v2-ai-model-ai-model.yaml
  16. 71 0
      openapi/public/assets/protocol/resources/auto/v2-ai-model-token-ai-model.yaml
  17. 124 0
      openapi/public/assets/protocol/resources/auto/v2-ai-model.yaml
  18. 130 0
      openapi/public/assets/protocol/resources/auto/v2-ai-translate-ai-translate.yaml
  19. 99 0
      openapi/public/assets/protocol/resources/auto/v2-ai-translate.yaml
  20. 167 0
      openapi/public/assets/protocol/resources/auto/v2-anthology-anthology.yaml
  21. 25 0
      openapi/public/assets/protocol/resources/auto/v2-anthology-my-number.yaml
  22. 105 0
      openapi/public/assets/protocol/resources/auto/v2-anthology.yaml
  23. 154 0
      openapi/public/assets/protocol/resources/auto/v2-api-api.yaml
  24. 90 0
      openapi/public/assets/protocol/resources/auto/v2-api.yaml
  25. 238 0
      openapi/public/assets/protocol/resources/auto/v2-article-article.yaml
  26. 125 0
      openapi/public/assets/protocol/resources/auto/v2-article-fts-article-ft.yaml
  27. 115 0
      openapi/public/assets/protocol/resources/auto/v2-article-fts.yaml
  28. 153 0
      openapi/public/assets/protocol/resources/auto/v2-article-map-article-map.yaml
  29. 131 0
      openapi/public/assets/protocol/resources/auto/v2-article-map.yaml
  30. 37 0
      openapi/public/assets/protocol/resources/auto/v2-article-my-number.yaml
  31. 125 0
      openapi/public/assets/protocol/resources/auto/v2-article-nav-article-nav.yaml
  32. 103 0
      openapi/public/assets/protocol/resources/auto/v2-article-nav.yaml
  33. 57 0
      openapi/public/assets/protocol/resources/auto/v2-article-preview-id.yaml
  34. 125 0
      openapi/public/assets/protocol/resources/auto/v2-article-progress-article-progress.yaml
  35. 107 0
      openapi/public/assets/protocol/resources/auto/v2-article-progress.yaml
  36. 191 0
      openapi/public/assets/protocol/resources/auto/v2-article.yaml
  37. 148 0
      openapi/public/assets/protocol/resources/auto/v2-attachment-attachment.yaml
  38. 119 0
      openapi/public/assets/protocol/resources/auto/v2-attachment.yaml
  39. 125 0
      openapi/public/assets/protocol/resources/auto/v2-attachments-attachment.yaml
  40. 104 0
      openapi/public/assets/protocol/resources/auto/v2-attachments.yaml
  41. 25 0
      openapi/public/assets/protocol/resources/auto/v2-auth-current.yaml
  42. 125 0
      openapi/public/assets/protocol/resources/auto/v2-auth-forgot-password-forgot-password.yaml
  43. 103 0
      openapi/public/assets/protocol/resources/auto/v2-auth-forgot-password.yaml
  44. 125 0
      openapi/public/assets/protocol/resources/auto/v2-auth-reset-password-reset-password.yaml
  45. 103 0
      openapi/public/assets/protocol/resources/auto/v2-auth-reset-password.yaml
  46. 125 0
      openapi/public/assets/protocol/resources/auto/v2-book-title-book-title.yaml
  47. 90 0
      openapi/public/assets/protocol/resources/auto/v2-book-title.yaml
  48. 125 0
      openapi/public/assets/protocol/resources/auto/v2-case-case.yaml
  49. 90 0
      openapi/public/assets/protocol/resources/auto/v2-case.yaml
  50. 215 0
      openapi/public/assets/protocol/resources/auto/v2-channel-channel.yaml
  51. 125 0
      openapi/public/assets/protocol/resources/auto/v2-channel-io-channel-io.yaml
  52. 101 0
      openapi/public/assets/protocol/resources/auto/v2-channel-io.yaml
  53. 31 0
      openapi/public/assets/protocol/resources/auto/v2-channel-my-number.yaml
  54. 33 0
      openapi/public/assets/protocol/resources/auto/v2-channel-name-name.yaml
  55. 36 0
      openapi/public/assets/protocol/resources/auto/v2-channel-progress.yaml
  56. 262 0
      openapi/public/assets/protocol/resources/auto/v2-channel.yaml
  57. 125 0
      openapi/public/assets/protocol/resources/auto/v2-chapter-chapter.yaml
  58. 146 0
      openapi/public/assets/protocol/resources/auto/v2-chapter-content-chapter-content.yaml
  59. 90 0
      openapi/public/assets/protocol/resources/auto/v2-chapter-content.yaml
  60. 125 0
      openapi/public/assets/protocol/resources/auto/v2-chapter-index-chapter-index.yaml
  61. 102 0
      openapi/public/assets/protocol/resources/auto/v2-chapter-index.yaml
  62. 125 0
      openapi/public/assets/protocol/resources/auto/v2-chapter-io-chapter-io.yaml
  63. 101 0
      openapi/public/assets/protocol/resources/auto/v2-chapter-io.yaml
  64. 102 0
      openapi/public/assets/protocol/resources/auto/v2-chapter.yaml
  65. 125 0
      openapi/public/assets/protocol/resources/auto/v2-chat-messages-chat-message.yaml
  66. 94 0
      openapi/public/assets/protocol/resources/auto/v2-chat-messages.yaml
  67. 125 0
      openapi/public/assets/protocol/resources/auto/v2-chats-chat.yaml
  68. 94 0
      openapi/public/assets/protocol/resources/auto/v2-chats.yaml
  69. 125 0
      openapi/public/assets/protocol/resources/auto/v2-command-command.yaml
  70. 101 0
      openapi/public/assets/protocol/resources/auto/v2-command.yaml
  71. 125 0
      openapi/public/assets/protocol/resources/auto/v2-compound-compound.yaml
  72. 108 0
      openapi/public/assets/protocol/resources/auto/v2-compound.yaml
  73. 58 0
      openapi/public/assets/protocol/resources/auto/v2-corpus-chapter-id.yaml
  74. 125 0
      openapi/public/assets/protocol/resources/auto/v2-corpus-corpu.yaml
  75. 43 0
      openapi/public/assets/protocol/resources/auto/v2-corpus-sent-id.yaml
  76. 38 0
      openapi/public/assets/protocol/resources/auto/v2-corpus-sentences-type-id.yaml
  77. 97 0
      openapi/public/assets/protocol/resources/auto/v2-corpus.yaml
  78. 203 0
      openapi/public/assets/protocol/resources/auto/v2-course-course.yaml
  79. 37 0
      openapi/public/assets/protocol/resources/auto/v2-course-curr.yaml
  80. 180 0
      openapi/public/assets/protocol/resources/auto/v2-course-member-course-member.yaml
  81. 38 0
      openapi/public/assets/protocol/resources/auto/v2-course-member-export.yaml
  82. 45 0
      openapi/public/assets/protocol/resources/auto/v2-course-member-set-channel.yaml
  83. 186 0
      openapi/public/assets/protocol/resources/auto/v2-course-member.yaml
  84. 25 0
      openapi/public/assets/protocol/resources/auto/v2-course-my-course.yaml
  85. 112 0
      openapi/public/assets/protocol/resources/auto/v2-course.yaml
  86. 125 0
      openapi/public/assets/protocol/resources/auto/v2-dict-dict.yaml
  87. 125 0
      openapi/public/assets/protocol/resources/auto/v2-dict-info-dict-info.yaml
  88. 97 0
      openapi/public/assets/protocol/resources/auto/v2-dict-info.yaml
  89. 125 0
      openapi/public/assets/protocol/resources/auto/v2-dict-meaning-dict-meaning.yaml
  90. 100 0
      openapi/public/assets/protocol/resources/auto/v2-dict-meaning.yaml
  91. 125 0
      openapi/public/assets/protocol/resources/auto/v2-dict-preference-dict-preference.yaml
  92. 90 0
      openapi/public/assets/protocol/resources/auto/v2-dict-preference.yaml
  93. 125 0
      openapi/public/assets/protocol/resources/auto/v2-dict-statistic-dict-statistic.yaml
  94. 90 0
      openapi/public/assets/protocol/resources/auto/v2-dict-statistic.yaml
  95. 125 0
      openapi/public/assets/protocol/resources/auto/v2-dict-vocabulary-dict-vocabulary.yaml
  96. 103 0
      openapi/public/assets/protocol/resources/auto/v2-dict-vocabulary.yaml
  97. 106 0
      openapi/public/assets/protocol/resources/auto/v2-dict.yaml
  98. 38 0
      openapi/public/assets/protocol/resources/auto/v2-discussion-anchor-id.yaml
  99. 125 0
      openapi/public/assets/protocol/resources/auto/v2-discussion-count-discussion-count.yaml
  100. 121 0
      openapi/public/assets/protocol/resources/auto/v2-discussion-count.yaml

+ 75 - 11
openapi/README.md

@@ -1,19 +1,83 @@
-# USAGE
+# MINT API 规格
+
+`public/assets/protocol/` 下的 OpenAPI 3.0.3 规格 **全部由脚本从 api-v13 的源码生成**,
+不要手改生成结果。
+
+## 重新生成
+
+后端路由或控制器改动之后:
 
 ```bash
-yarn install
-yarn run dev
+php scripts/generate.php      # 或 npm run generate
+npm run lint                  # redocly 校验,应为 0 error
+```
+
+脚本做的事:
+
+1. 读 `php artisan route:list --json`(在 `../api-v13` 下执行)拿到全部路由。
+2. 用 nikic/php-parser 解析每个控制器方法,提取
+   - 文档注释 → summary / description(Laravel 脚手架英文样板会被丢弃)
+   - 文档注释里的 `@queryParam` / `@bodyParam` / `@urlParam` / `@deprecated` 标签(见下)
+   - `$request->input()/query()/has()/boolean()/integer()` → 查询参数与默认值
+   - `switch ($request->input('view'))` 的 case → 参数枚举
+   - `validate([...])` / `Validator::make()` → 请求体字段、必填与类型
+   - 返回的 `App\Http\Resources\*Resource::toArray()` 的键 → 响应 schema
+3. 写出 `main.yaml` + 每个 path 一个 `resources/auto/<slug>.yaml`。
+
+## 在控制器里写参数说明(首选做法)
+
+与其在 `overrides/` 里手写 YAML,不如把说明写在控制器的文档注释里——离代码最近,改接口时不容易忘。
+语法是固定位置的:`@标签 <参数名> <类型> [required] <描述>`。
+
+```php
+/**
+ * 列出 channel(译文集)
+ *
+ * 按 view 指定的口径返回 channel 列表,支持关键字搜索、分页、排序。
+ *
+ * @queryParam view string required 查询口径。Enum: public,studio,system
+ * @queryParam view2 string 二级口径:my=我的,其余值=协作的。Default: my
+ * @queryParam updated_at string 只返回该时间之后更新的记录,用于离线包增量同步。
+ *             Example: 2023-09-18T05:39:51.000000Z
+ * @bodyParam name string required channel 名称,在同一 studio 内唯一
+ * @urlParam channel string required channel uid
+ */
 ```
 
-- Editor
+- `@queryParam` 出现在查询串,`@bodyParam` 出现在请求体,`@urlParam` 是路径参数。
+- 类型写 `string` / `integer` / `number` / `boolean` / `array` / `object`。
+- 描述里的 `Enum: a,b,c`、`Default: x`、`Example: y` 会被解析成对应的 schema 字段。
+- 描述换行时续行要缩进,会自动并入上一个参数。
+- 标注过的参数覆盖源码推断的结果;没标注的参数仍然按源码推断输出,不会丢。
+- `@deprecated` 会把该 operation 标成废弃。
 
-  ```bash
-  git clone https://github.com/swagger-api/swagger-editor.git
-  cd swagger-editor
-  npm install
-  npm run dev # http://localhost:3200
-  ```
+## 目录
+
+| 路径                                               | 说明                                             |
+| -------------------------------------------------- | ------------------------------------------------ |
+| `public/assets/protocol/main.yaml`                 | 入口,servers / components / paths(全部`$ref`) |
+| `public/assets/protocol/resources/auto/`           | 自动生成,每次重跑会被清空重建,**勿手改**       |
+| `public/assets/protocol/overrides/`                | 手写补充,按同名文件深度合并到自动结果之上       |
+| `public/assets/protocol/resources/list_query.yaml` | 列表接口通用分页/排序参数                        |
+| `scripts/generate.php`                             | 生成器                                           |
+
+`overrides/` 留给那些不适合写进 PHP 注释的东西(长篇示例响应、跨接口的说明)。
+注意合并规则是:同名键以 overrides 为准,**数组整体替换**——所以在 overrides 里写
+`parameters` 会覆盖掉自动生成的全部参数,一般不要这么做,优先用上面的文档注释标签。
+
+## 约定
+
+- 所有接口挂在 `/api` 下,业务路由带 `/v2`、`/v3` 前缀;`/ops` 为运维接口,需
+  `Authorization: Bearer <APP_OPS_TOKEN>`。
+- 响应统一封装 `{ok, message, data}`;业务失败时 HTTP 仍可能是 200,以 `ok` 为准。
+
+## 本地预览
+
+```bash
+npm install
+npm run dev
+```
 
-## Documents
+## 文档
 
 - [OpenAPI Guide](https://swagger.io/docs/specification/basic-structure/)

+ 4372 - 0
openapi/package-lock.json

@@ -0,0 +1,4372 @@
+{
+  "name": "openapi",
+  "version": "0.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "openapi",
+      "version": "0.0.0",
+      "dependencies": {
+        "@types/swagger-ui-react": "^4.11.0",
+        "react": "^18.2.0",
+        "react-dom": "^18.2.0",
+        "swagger-ui-react": "^4.15.5"
+      },
+      "devDependencies": {
+        "@redocly/cli": "^2.10.2",
+        "@types/react": "^18.0.24",
+        "@types/react-dom": "^18.0.8",
+        "@vitejs/plugin-react": "^2.2.0",
+        "typescript": "^4.6.4",
+        "vite": "^3.2.3"
+      }
+    },
+    "node_modules/@babel/code-frame": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
+      "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.29.7",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.1.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/compat-data": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
+      "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/core": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
+      "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.29.7",
+        "@babel/generator": "^7.29.7",
+        "@babel/helper-compilation-targets": "^7.29.7",
+        "@babel/helper-module-transforms": "^7.29.7",
+        "@babel/helpers": "^7.29.7",
+        "@babel/parser": "^7.29.7",
+        "@babel/template": "^7.29.7",
+        "@babel/traverse": "^7.29.7",
+        "@babel/types": "^7.29.7",
+        "@jridgewell/remapping": "^2.3.5",
+        "convert-source-map": "^2.0.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.2",
+        "json5": "^2.2.3",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/babel"
+      }
+    },
+    "node_modules/@babel/generator": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz",
+      "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.29.8",
+        "@babel/types": "^7.29.8",
+        "@jridgewell/gen-mapping": "^0.3.12",
+        "@jridgewell/trace-mapping": "^0.3.28",
+        "jsesc": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-annotate-as-pure": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz",
+      "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-compilation-targets": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
+      "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/compat-data": "^7.29.7",
+        "@babel/helper-validator-option": "^7.29.7",
+        "browserslist": "^4.24.0",
+        "lru-cache": "^5.1.1",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-globals": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
+      "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-imports": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
+      "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/traverse": "^7.29.7",
+        "@babel/types": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-transforms": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
+      "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7",
+        "@babel/traverse": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-plugin-utils": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
+      "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+      "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+      "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-option": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
+      "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helpers": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
+      "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/template": "^7.29.7",
+        "@babel/types": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.29.9",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz",
+      "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.29.8"
+      },
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-jsx": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz",
+      "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-react-jsx": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.29.7.tgz",
+      "integrity": "sha512-WsZulLVBUHXVj2cUcPVx6UE21TpalB6bHbSFErKT0Ib++ax24jjXe73FqlWvdylFOjiuPHYi6VCcgRad1ItN+A==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.29.7",
+        "@babel/helper-module-imports": "^7.29.7",
+        "@babel/helper-plugin-utils": "^7.29.7",
+        "@babel/plugin-syntax-jsx": "^7.29.7",
+        "@babel/types": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-react-jsx-development": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.29.7.tgz",
+      "integrity": "sha512-Xfy3UVMF04+ypnFbkhvfqtmvwfe92qwQdbGZVonhE+6v35GzlofmOnA1szaZqzb9xYWr0nl1e5EMmzi0DNON1g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/plugin-transform-react-jsx": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-react-jsx-self": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz",
+      "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-react-jsx-source": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz",
+      "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/runtime": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
+      "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/runtime-corejs3": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.29.7.tgz",
+      "integrity": "sha512-ppj9ouYku+RX0ljtgZd+KMO5mkM2bCqg8H2PYAFWnLsHEIKIdRojqbJ2i3eVHrisuxy7nOFCmngTDdWtUCdXUQ==",
+      "license": "MIT",
+      "dependencies": {
+        "core-js-pure": "^3.48.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/template": {
+      "version": "7.29.7",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
+      "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.29.7",
+        "@babel/parser": "^7.29.7",
+        "@babel/types": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz",
+      "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.29.7",
+        "@babel/generator": "^7.29.8",
+        "@babel/helper-globals": "^7.29.7",
+        "@babel/parser": "^7.29.8",
+        "@babel/template": "^7.29.7",
+        "@babel/types": "^7.29.8",
+        "debug": "^4.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/types": {
+      "version": "7.29.8",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
+      "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.29.7",
+        "@babel/helper-validator-identifier": "^7.29.7"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@braintree/sanitize-url": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.2.tgz",
+      "integrity": "sha512-Tbsj02wXCbqGmzdnXNk0SOF19ChhRU70BsroIi4Pm6Ehp56in6vch94mfbdQ17DozxkL3BAVjbZ4Qc1a0HFRAg==",
+      "license": "MIT"
+    },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz",
+      "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz",
+      "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@jridgewell/gen-mapping": {
+      "version": "0.3.13",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+      "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.5.0",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      }
+    },
+    "node_modules/@jridgewell/remapping": {
+      "version": "2.3.5",
+      "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+      "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      }
+    },
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+      "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz",
+      "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.31",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+      "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
+      }
+    },
+    "node_modules/@redocly/cli": {
+      "version": "2.53.3",
+      "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-2.53.3.tgz",
+      "integrity": "sha512-hzNAWzHCOZ05vwRx0ehTxNeJaxxizjGV505eKtfs9MR/8ieD/8lYhAK4GF5FaqRRwOEpLO0PvzQwBSKYXmxhRA==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "openapi": "bin/cli.js",
+        "redocly": "bin/cli.js"
+      },
+      "engines": {
+        "node": ">=22.12.0 || >=20.19.0 <21.0.0",
+        "npm": ">=10"
+      }
+    },
+    "node_modules/@scarf/scarf": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz",
+      "integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==",
+      "hasInstallScript": true,
+      "license": "Apache-2.0"
+    },
+    "node_modules/@swagger-api/apidom-ast": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-1.11.6.tgz",
+      "integrity": "sha512-HzudlOOzs17o2lDnDfcOFT5STKq4ckOYAK6jOaN5udDRA9luDm0axRuc3sHlImHDaOHFN+Yf+rp0zUpT+2Dsiw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "unraw": "^3.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-core": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-1.11.6.tgz",
+      "integrity": "sha512-OdHzm974FpfYuO0L+W5B5x+byBMjs9gWuQy37LZYjIe4K8X8IHsN00KAgODLSKgccGlnWi4QBBs8WfHNgRWqGA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-ast": "1.11.6",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "minim": "~0.23.8",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "short-unique-id": "^5.3.2",
+        "ts-mixer": "^6.0.3"
+      }
+    },
+    "node_modules/@swagger-api/apidom-error": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-error/-/apidom-error-1.11.6.tgz",
+      "integrity": "sha512-q44Zh9Ro0qDH/GLiFvGfe9tISSOSmq6ktrwmjuADVHwpAB//SfvhihIE9LwqNXYEZJTA4ExnFuxy01jiql++HQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.20.7"
+      }
+    },
+    "node_modules/@swagger-api/apidom-json-pointer": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.11.6.tgz",
+      "integrity": "sha512-sqRsfWsTEy+NQp5Ea3xwsGlPRYnXVLcf2WXCCrexcD2OrTOxhlZ6rCZQyc2trrUwAptna/Px/czVO+TjofXf4g==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@swaggerexpert/json-pointer": "^2.10.1"
+      }
+    },
+    "node_modules/@swagger-api/apidom-ns-api-design-systems": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.11.6.tgz",
+      "integrity": "sha512-lp7YvMSXoW/UQVxOzJYCLVFIIPU2NYsT7mljIiPQTjUZAFuQ20Vi6v93YHfgVIXUj0yQYSraAnvXuO4GciWlPQ==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-1": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "ts-mixer": "^6.0.3"
+      }
+    },
+    "node_modules/@swagger-api/apidom-ns-arazzo-1": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-arazzo-1/-/apidom-ns-arazzo-1-1.11.6.tgz",
+      "integrity": "sha512-GiAuYiAMwfX2AhUq4ANpmNmjJxSWiTV4QJYJUX3wHZpyU4EMXEM/BTaExGQpbmu7ewRPF4Nve/d9PKNouNXhJQ==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-json-schema-2020-12": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "ts-mixer": "^6.0.3"
+      }
+    },
+    "node_modules/@swagger-api/apidom-ns-asyncapi-2": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.11.6.tgz",
+      "integrity": "sha512-RHTv4qINvCKe40bDyoWkhve/2/qv6GObFY0umALw2Lv1KiW2hjHrBO63Y+kU8vYu34bnhFCUDIqyCyEmJt6zkQ==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-json-schema-draft-7": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "ts-mixer": "^6.0.3"
+      }
+    },
+    "node_modules/@swagger-api/apidom-ns-asyncapi-3": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-3/-/apidom-ns-asyncapi-3-1.11.6.tgz",
+      "integrity": "sha512-bGUXNP+vS9bjNl8ehjmoyUck1liWjxOUQReLZG4yqIix7dHWvLSeDw1hi0pq1A+VWjixPazAcb9Y6f/t5Bqvyg==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-asyncapi-2": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "ts-mixer": "^6.0.3"
+      }
+    },
+    "node_modules/@swagger-api/apidom-ns-json-schema-2019-09": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-2019-09/-/apidom-ns-json-schema-2019-09-1.11.6.tgz",
+      "integrity": "sha512-XZmo85MS8Y5bYzrxmYbbqvXOghWZt4tInhE26c5nGbKyCx5CbsLlhzcp0wMzkb5k22BnUmlwmniVFrnveYnOGQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@swagger-api/apidom-ns-json-schema-draft-7": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "ts-mixer": "^6.0.4"
+      }
+    },
+    "node_modules/@swagger-api/apidom-ns-json-schema-2020-12": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-2020-12/-/apidom-ns-json-schema-2020-12-1.11.6.tgz",
+      "integrity": "sha512-WU6Vw8aa0TLs1COGHjCFS2gz6MkQzSNZYFejs7EtZOnlAkgG3TN8H55BHVoif1QGBlrhTQ6o6RxCdk5bI1WneQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@swagger-api/apidom-ns-json-schema-2019-09": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "ts-mixer": "^6.0.4"
+      }
+    },
+    "node_modules/@swagger-api/apidom-ns-json-schema-draft-4": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.11.6.tgz",
+      "integrity": "sha512-kiYyTkUCsHBKS2EFTQgI0bF0yKjOlt+QMiPzsXKzHZ7+XqMmEeRBFn5wSfTF3h9aJ5JMgtmku4j3TtdlxEUvUA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-ast": "1.11.6",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "ts-mixer": "^6.0.4"
+      }
+    },
+    "node_modules/@swagger-api/apidom-ns-json-schema-draft-6": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.11.6.tgz",
+      "integrity": "sha512-vTlvnkmQ0UP0NeiPD8h6Kls2So8tNVruANah1n9BskJLUpvTVJV820HFDw88/+ocXUglAEg8aKENcPo0AWsrkw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@swagger-api/apidom-ns-json-schema-draft-4": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "ts-mixer": "^6.0.4"
+      }
+    },
+    "node_modules/@swagger-api/apidom-ns-json-schema-draft-7": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.11.6.tgz",
+      "integrity": "sha512-kddXboLPDceL0302icmJvltcg/LzwGPaK1W/35PiHbs0lCtgRg5bz8F0tzGbPa1zk6n2o5BSS8+YU0J6vGKf3g==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@swagger-api/apidom-ns-json-schema-draft-6": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "ts-mixer": "^6.0.4"
+      }
+    },
+    "node_modules/@swagger-api/apidom-ns-openapi-2": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.11.6.tgz",
+      "integrity": "sha512-eMlB/P7apYuiwiBPsCW5zc5cyb6T/ZY7VeMSLBBN/JDy8I4rtTpFQq3ltQKXJlFhU321CuCibRiZ6p7z45wWKw==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@swagger-api/apidom-ns-json-schema-draft-4": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "ts-mixer": "^6.0.3"
+      }
+    },
+    "node_modules/@swagger-api/apidom-ns-openapi-3-0": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.11.6.tgz",
+      "integrity": "sha512-RGngR9Daer9PtkPevSKgBqWZdXxCbDyjudadq0CImqFfjYd8OWhya20haKbPGpJuHDz7Rwmu2m92+0wZFjCcew==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@swagger-api/apidom-ns-json-schema-draft-4": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "ts-mixer": "^6.0.3"
+      }
+    },
+    "node_modules/@swagger-api/apidom-ns-openapi-3-1": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.11.6.tgz",
+      "integrity": "sha512-mZe+3NgDxTjUmitxxgvlmLyK9mWSNkQajqA26j9JxcFdEvN/lcp/EsjxMX5kST4E0Qm4tQKD0i1QnJmjBSaHWw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-ast": "1.11.6",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-json-pointer": "1.11.6",
+        "@swagger-api/apidom-ns-json-schema-2020-12": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-0": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "ts-mixer": "^6.0.3"
+      }
+    },
+    "node_modules/@swagger-api/apidom-ns-openapi-3-2": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-2/-/apidom-ns-openapi-3-2-1.11.6.tgz",
+      "integrity": "sha512-TBDgIDAZodphp/1DS+mTilPLfTS84e/IXGEoRCE/MFrLKa4GZFY7bx8hXQmgGJfDWwxsNcQk5Q/X+SCi+WQg0g==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-ast": "1.11.6",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-json-pointer": "1.11.6",
+        "@swagger-api/apidom-ns-json-schema-2020-12": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-0": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-1": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "ts-mixer": "^6.0.3"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-json": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.11.6.tgz",
+      "integrity": "sha512-vFwzMj6z5HBf8d8DM0eNjVkaI2hiewE4+RDkTYhpfydAUq8m8jTuzJCf7DDdQ0YdvHH7/Zwdj4EshYnzEAp8Aw==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-api-design-systems": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-json": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-yaml": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.11.6.tgz",
+      "integrity": "sha512-bwRh9F9phloYhpQJImsFuY3e8M5uf9lf436zqU413UCNnbU0F1p4HzIxKjFeIwXxiTzHfN89tCpsrPRsmLySaA==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-api-design-systems": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-yaml-1-2": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-arazzo-json-1": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-arazzo-json-1/-/apidom-parser-adapter-arazzo-json-1-1.11.6.tgz",
+      "integrity": "sha512-opQc80CzT9buTKr3Q4k8R1DxVFJpHuJ4ej1Z6V4glGd7d2gEoabMkLKT9v9nKy50XLhJUTLkA86MLEyZPHxsfQ==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-arazzo-1": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-json": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-arazzo-yaml-1": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-arazzo-yaml-1/-/apidom-parser-adapter-arazzo-yaml-1-1.11.6.tgz",
+      "integrity": "sha512-7wMLd6yGGNW0UI1ourkMfGJaR79fav1HntVCC0IvmcaO5u8X6gUIwDpqMcIuX71Ipw1FHX2x9PKSakMiWy5LJQ==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-arazzo-1": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-yaml-1-2": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-2": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.11.6.tgz",
+      "integrity": "sha512-jsx299Uconwq9oPHDNK51v3VPqm7JqkvovM2w/azW4aXQNv9u3ZcSqHMAbfC8KpYCbnx0LIuCU9OgRyH8dj8Nw==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-asyncapi-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-json": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-3": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-3/-/apidom-parser-adapter-asyncapi-json-3-1.11.6.tgz",
+      "integrity": "sha512-JePNK/AwnJk+U0yxUKDQynq6ER8Snx/zcZKxar+cBy/COMj1EV0Bif0vUdmF3RCEoPjoXNRq2HfBIbZ6yT+9AQ==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-asyncapi-3": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-json": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.11.6.tgz",
+      "integrity": "sha512-SJqn9y4tPSCq6dfE5hHYGpl45oLwogbXtrsbd4IWmAFrxT9VnbSUSyGmLm+bBYycQiXsvg0SJ7QRuecCeEJvfw==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-asyncapi-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-yaml-1-2": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-3": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-3/-/apidom-parser-adapter-asyncapi-yaml-3-1.11.6.tgz",
+      "integrity": "sha512-gTDh14ge0xBHu+44I/oBsKFC24sFK18yaL3paEdi0LGdSVKYmAbPyOaQbX3JEJ5BkOAwLvXAEQBm2snZ75JcXw==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-asyncapi-3": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-yaml-1-2": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-json": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.11.6.tgz",
+      "integrity": "sha512-LIbKkaydhviIJJ9VdMMmDrx96B2H21l1deH+osQt9QyrBr6Cdpo0NCv1xMr8TZi7CRjm6YD7+ec8mNmUNu54Bw==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-ast": "1.11.6",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "tree-sitter": "=0.21.1",
+        "tree-sitter-json": "=0.24.8",
+        "web-tree-sitter": "=0.24.5"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-2": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.11.6.tgz",
+      "integrity": "sha512-AeaRUdwEtQ1ThWQ3d47ZEH3WGLIHFR9Z5+uBhuYeT0jke0fHlLW6tnBWseZZ91Fk7Xo0sJR0fMnXRuCeBs4qTQ==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-json": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-0": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.11.6.tgz",
+      "integrity": "sha512-KJ9NyuwhRc17GKMMF9IS/wFbzJ2hRNssoza16v2mVhL+xs+1qYrUi5sOwb2vCWWfNtso8Wst/ILQWxYbhFfEHw==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-0": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-json": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-1": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.11.6.tgz",
+      "integrity": "sha512-9CG6vfA5usCEYf18g7+SYVRhD/zds8vvwV8gnF6gyrJOK+RbaAeVp1/Oeg499uRXy8D1LvypY07eB8aeVsaw3w==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-1": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-json": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-2": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-2/-/apidom-parser-adapter-openapi-json-3-2-1.11.6.tgz",
+      "integrity": "sha512-2EGjNq/tSFDJLVw46ApAaG2cRTxHF0Hhba5jEe5JiHTf52qZi0aPoi+YDxNnMvDKIzTrcEw34ZQddACu/JvOhQ==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-json": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-2": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.11.6.tgz",
+      "integrity": "sha512-ohy7FFWM0DN0bhIqHUZJrx8qCN0qGnvjf8xqJGx/cRfxmqToEeukAXvrBBhBhtz4eqLKiSeE9TkdgHPYRRDZWg==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-yaml-1-2": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.11.6.tgz",
+      "integrity": "sha512-6U+yTLDTdlMs68YLVKsOOpN3eFlFWeo0wbkkSSDQw7ugfpUi2PEEsjrQ+C6cviPYH3ZfZNchlj4EZaNFtMZ1/Q==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-0": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-yaml-1-2": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.11.6.tgz",
+      "integrity": "sha512-P3t3Q4uUt92ZUrm0zPlWacPRWDHfMFqlFXdzH5dJN5phyQMMu08vdPFMaWFPv+w48wcZFXbrT/GeilorAoPlDw==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-1": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-yaml-1-2": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-2": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-2/-/apidom-parser-adapter-openapi-yaml-3-2-1.11.6.tgz",
+      "integrity": "sha512-bty6P85OHEV4YCdbVlNTsJRXZPs4ii3ynzTISURoIuyn08Y28C/Pm9H484Pl4iC9t16d1TKGngTAWc5RX0ve1Q==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-yaml-1-2": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.11.6.tgz",
+      "integrity": "sha512-voxU8HMUypS36DYmZX8OsZ9pHz0hoT66GiBXjGKb1ETkXQR/8rVIYJnbxvVqtyXUI82aZy3dRTcXd6C2BHqH/A==",
+      "license": "Apache-2.0",
+      "optional": true,
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-ast": "1.11.6",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@tree-sitter-grammars/tree-sitter-yaml": "=0.7.1",
+        "@types/ramda": "~0.30.0",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0",
+        "tree-sitter": "=0.22.4",
+        "web-tree-sitter": "=0.24.5"
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2/node_modules/@tree-sitter-grammars/tree-sitter-yaml": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/@tree-sitter-grammars/tree-sitter-yaml/-/tree-sitter-yaml-0.7.1.tgz",
+      "integrity": "sha512-AynBwkIoQCTgjDR33bDUp9Mqq+YTco0is3n5hRApMqG9of/6A4eQsfC1/uSEeHSUyMQSYawcAWamsexnVpIP4Q==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "node-addon-api": "^8.3.1",
+        "node-gyp-build": "^4.8.4"
+      },
+      "peerDependencies": {
+        "tree-sitter": "^0.22.4"
+      },
+      "peerDependenciesMeta": {
+        "tree-sitter": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2/node_modules/tree-sitter": {
+      "version": "0.22.4",
+      "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.22.4.tgz",
+      "integrity": "sha512-usbHZP9/oxNsUY65MQUsduGRqDHQOou1cagUSwjhoSYAmSahjQDAVsh9s+SlZkn8X8+O1FULRGwHu7AFP3kjzg==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "node-addon-api": "^8.3.0",
+        "node-gyp-build": "^4.8.4"
+      }
+    },
+    "node_modules/@swagger-api/apidom-reference": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-1.11.6.tgz",
+      "integrity": "sha512-wAU/b6fBw0zS2KLvbiwY13apXbXO43N+CnlnHvGuOf4WjV+msdcb31OPUAehMENsC1BUcrf/vroQj+lJqz77dA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.26.10",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@types/ramda": "~0.30.0",
+        "axios": "^1.18.0",
+        "minimatch": "^10.2.6",
+        "ramda": "~0.30.0",
+        "ramda-adjunct": "^5.0.0"
+      },
+      "optionalDependencies": {
+        "@swagger-api/apidom-json-pointer": "1.11.6",
+        "@swagger-api/apidom-ns-arazzo-1": "1.11.6",
+        "@swagger-api/apidom-ns-asyncapi-2": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-2": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-0": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-1": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-api-design-systems-json": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-arazzo-json-1": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-arazzo-yaml-1": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-asyncapi-json-3": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-asyncapi-yaml-3": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-json": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-json-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-json-3-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-yaml-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-yaml-3-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-yaml-1-2": "1.11.6"
+      }
+    },
+    "node_modules/@swagger-api/apidom-reference/node_modules/balanced-match": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+      "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+      "license": "MIT",
+      "engines": {
+        "node": "18 || 20 || >=22"
+      }
+    },
+    "node_modules/@swagger-api/apidom-reference/node_modules/brace-expansion": {
+      "version": "5.0.12",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
+      "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^4.0.2"
+      },
+      "engines": {
+        "node": "20 || >=22"
+      }
+    },
+    "node_modules/@swagger-api/apidom-reference/node_modules/minimatch": {
+      "version": "10.2.6",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",
+      "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
+      "license": "BlueOak-1.0.0",
+      "dependencies": {
+        "brace-expansion": "^5.0.8"
+      },
+      "engines": {
+        "node": "18 || 20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@swaggerexpert/cookie": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@swaggerexpert/cookie/-/cookie-2.0.2.tgz",
+      "integrity": "sha512-DPI8YJ0Vznk4CT+ekn3rcFNq1uQwvUHZhH6WvTSPD0YKBIlMS9ur2RYKghXuxxOiqOam/i4lHJH4xTIiTgs3Mg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "apg-lite": "^1.0.3"
+      },
+      "engines": {
+        "node": ">=12.20.0"
+      }
+    },
+    "node_modules/@swaggerexpert/json-pointer": {
+      "version": "2.10.2",
+      "resolved": "https://registry.npmjs.org/@swaggerexpert/json-pointer/-/json-pointer-2.10.2.tgz",
+      "integrity": "sha512-qMx1nOrzoB+PF+pzb26Q4Tc2sOlrx9Ba2UBNX9hB31Omrq+QoZ2Gly0KLrQWw4Of1AQ4J9lnD+XOdwOdcdXqqw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "apg-lite": "^1.0.4"
+      },
+      "engines": {
+        "node": ">=12.20.0"
+      }
+    },
+    "node_modules/@types/hast": {
+      "version": "2.3.10",
+      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz",
+      "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/unist": "^2"
+      }
+    },
+    "node_modules/@types/hoist-non-react-statics": {
+      "version": "3.3.7",
+      "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz",
+      "integrity": "sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==",
+      "license": "MIT",
+      "dependencies": {
+        "hoist-non-react-statics": "^3.3.0"
+      },
+      "peerDependencies": {
+        "@types/react": "*"
+      }
+    },
+    "node_modules/@types/prop-types": {
+      "version": "15.7.15",
+      "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
+      "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
+      "license": "MIT"
+    },
+    "node_modules/@types/ramda": {
+      "version": "0.30.2",
+      "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.30.2.tgz",
+      "integrity": "sha512-PyzHvjCalm2BRYjAU6nIB3TprYwMNOUY/7P/N8bSzp9W/yM2YrtGtAnnVtaCNSeOZ8DzKyFDvaqQs7LnWwwmBA==",
+      "license": "MIT",
+      "dependencies": {
+        "types-ramda": "^0.30.1"
+      }
+    },
+    "node_modules/@types/react": {
+      "version": "18.3.31",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.31.tgz",
+      "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/prop-types": "*",
+        "csstype": "^3.2.2"
+      }
+    },
+    "node_modules/@types/react-dom": {
+      "version": "18.3.7",
+      "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
+      "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
+      "devOptional": true,
+      "license": "MIT",
+      "peerDependencies": {
+        "@types/react": "^18.0.0"
+      }
+    },
+    "node_modules/@types/swagger-ui-react": {
+      "version": "4.19.0",
+      "resolved": "https://registry.npmjs.org/@types/swagger-ui-react/-/swagger-ui-react-4.19.0.tgz",
+      "integrity": "sha512-uScp1xkLZJej0bt3/lO4U11ywWEBnI5CFCR0tqp+5Rvxl1Mj1v6VkGED0W70jJwqlBvbD+/a6bDiK8rjepCr8g==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/react": "*"
+      }
+    },
+    "node_modules/@types/unist": {
+      "version": "2.0.11",
+      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+      "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
+      "license": "MIT"
+    },
+    "node_modules/@types/use-sync-external-store": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
+      "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==",
+      "license": "MIT"
+    },
+    "node_modules/@vitejs/plugin-react": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-2.2.0.tgz",
+      "integrity": "sha512-FFpefhvExd1toVRlokZgxgy2JtnBOdp4ZDsq7ldCWaqGSGn9UhWMAVm/1lxPL14JfNS5yGz+s9yFrQY6shoStA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/core": "^7.19.6",
+        "@babel/plugin-transform-react-jsx": "^7.19.0",
+        "@babel/plugin-transform-react-jsx-development": "^7.18.6",
+        "@babel/plugin-transform-react-jsx-self": "^7.18.6",
+        "@babel/plugin-transform-react-jsx-source": "^7.19.6",
+        "magic-string": "^0.26.7",
+        "react-refresh": "^0.14.0"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "vite": "^3.0.0"
+      }
+    },
+    "node_modules/@yarnpkg/lockfile": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
+      "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/agent-base": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+      "license": "MIT",
+      "dependencies": {
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6.0.0"
+      }
+    },
+    "node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "license": "MIT",
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/apg-lite": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/apg-lite/-/apg-lite-1.0.5.tgz",
+      "integrity": "sha512-SlI+nLMQDzCZfS39ihzjGp3JNBQfJXyMi6cg9tkLOCPVErgFsUIAEdO9IezR7kbP5Xd0ozcPNQBkf9TO5cHgWw==",
+      "license": "BSD-2-Clause"
+    },
+    "node_modules/argparse": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+      "license": "Python-2.0"
+    },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+      "license": "MIT"
+    },
+    "node_modules/at-least-node": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+      "license": "ISC",
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/autolinker": {
+      "version": "3.16.2",
+      "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.16.2.tgz",
+      "integrity": "sha512-JiYl7j2Z19F9NdTmirENSUUIIL/9MytEWtmzhfmsKPCp9E+G35Y0UNCMoM9tFigxT59qSc8Ml2dlZXOCVTYwuA==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      }
+    },
+    "node_modules/available-typed-arrays": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+      "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+      "license": "MIT",
+      "dependencies": {
+        "possible-typed-array-names": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/axios": {
+      "version": "1.20.0",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.20.0.tgz",
+      "integrity": "sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg==",
+      "license": "MIT",
+      "dependencies": {
+        "follow-redirects": "^1.16.0",
+        "form-data": "^4.0.6",
+        "https-proxy-agent": "^5.0.1",
+        "proxy-from-env": "^2.1.0"
+      }
+    },
+    "node_modules/balanced-match": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+      "license": "MIT"
+    },
+    "node_modules/base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/baseline-browser-mapping": {
+      "version": "2.11.25",
+      "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.25.tgz",
+      "integrity": "sha512-gMmEShwwq7FJqMwvfRwvCl00v4kN+KOfJqXn+f4nrufak5gNHJOksd/60Dvjuz7sI8Y5WiSFBa8FEYr+zoyqCw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "bin": {
+        "baseline-browser-mapping": "dist/cli.cjs"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/brace-expansion": {
+      "version": "1.1.21",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz",
+      "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==",
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/braces": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+      "license": "MIT",
+      "dependencies": {
+        "fill-range": "^7.1.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/browserslist": {
+      "version": "4.29.0",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.0.tgz",
+      "integrity": "sha512-3GSvyjvDI4Dur1Meg2BekJquu5uF+9R9a1+5M1Mde192eZoXbeXjzgOsgqPS2V8D5wrrip0gR5Hf/GhWQ9ZzaA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "baseline-browser-mapping": "^2.11.23",
+        "caniuse-lite": "^1.0.30001810",
+        "electron-to-chromium": "^1.5.427",
+        "node-releases": "^2.0.55",
+        "update-browserslist-db": "^1.3.3"
+      },
+      "bin": {
+        "browserslist": "cli.js"
+      },
+      "engines": {
+        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+      }
+    },
+    "node_modules/call-bind": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz",
+      "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.2",
+        "es-define-property": "^1.0.1",
+        "get-intrinsic": "^1.3.0",
+        "set-function-length": "^1.2.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/call-bind-apply-helpers": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/call-bound": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+      "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.2",
+        "get-intrinsic": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/caniuse-lite": {
+      "version": "1.0.30001810",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz",
+      "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "CC-BY-4.0"
+    },
+    "node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/character-entities": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
+      "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/character-entities-legacy": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
+      "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/character-reference-invalid": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
+      "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/ci-info": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+      "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+      "license": "MIT"
+    },
+    "node_modules/classnames": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
+      "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
+      "license": "MIT"
+    },
+    "node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "license": "MIT",
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "license": "MIT"
+    },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "license": "MIT",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/comma-separated-tokens": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
+      "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+      "license": "MIT"
+    },
+    "node_modules/convert-source-map": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/copy-to-clipboard": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
+      "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
+      "license": "MIT",
+      "dependencies": {
+        "toggle-selection": "^1.0.6"
+      }
+    },
+    "node_modules/core-js-pure": {
+      "version": "3.50.0",
+      "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.50.0.tgz",
+      "integrity": "sha512-6GP3Pxz4IKyWjAfa747vIu/jilB5z29JWROLqH/b+pXVcpgh6tM06ZIBwSuglgVqzDYURhOK6oEzTrG0bCHitA==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
+      }
+    },
+    "node_modules/cross-spawn": {
+      "version": "6.0.6",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
+      "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
+      "license": "MIT",
+      "dependencies": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      },
+      "engines": {
+        "node": ">=4.8"
+      }
+    },
+    "node_modules/cross-spawn/node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/css.escape": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
+      "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
+      "license": "MIT"
+    },
+    "node_modules/csstype": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+      "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+      "license": "MIT"
+    },
+    "node_modules/debug": {
+      "version": "4.4.3",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+      "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/deep-extend": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/deepmerge": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+      "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/define-data-property": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+      "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+      "license": "MIT",
+      "dependencies": {
+        "es-define-property": "^1.0.0",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/dompurify": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.2.tgz",
+      "integrity": "sha512-B8c6JdiEpxAKnd8Dm++QQxJL4lfuc757scZtcapj6qjTjrQzyq5iAyznLKVvK+77eYNiFblHBlt7MM0fOeqoKw==",
+      "license": "(MPL-2.0 OR Apache-2.0)"
+    },
+    "node_modules/drange": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz",
+      "integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/dunder-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.2.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/electron-to-chromium": {
+      "version": "1.5.433",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.433.tgz",
+      "integrity": "sha512-5lCAbyZBjtmUt/RAGHRqrL2q0oEFRThDAsZHHDn9XHa89Qw7gMYOeSicBTy+AHfvo0r6vwsZvqNJTQIQy1BLzA==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/es-define-property": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-errors": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-object-atoms": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
+      "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-set-tostringtag": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.6",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/esbuild": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz",
+      "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/android-arm": "0.15.18",
+        "@esbuild/linux-loong64": "0.15.18",
+        "esbuild-android-64": "0.15.18",
+        "esbuild-android-arm64": "0.15.18",
+        "esbuild-darwin-64": "0.15.18",
+        "esbuild-darwin-arm64": "0.15.18",
+        "esbuild-freebsd-64": "0.15.18",
+        "esbuild-freebsd-arm64": "0.15.18",
+        "esbuild-linux-32": "0.15.18",
+        "esbuild-linux-64": "0.15.18",
+        "esbuild-linux-arm": "0.15.18",
+        "esbuild-linux-arm64": "0.15.18",
+        "esbuild-linux-mips64le": "0.15.18",
+        "esbuild-linux-ppc64le": "0.15.18",
+        "esbuild-linux-riscv64": "0.15.18",
+        "esbuild-linux-s390x": "0.15.18",
+        "esbuild-netbsd-64": "0.15.18",
+        "esbuild-openbsd-64": "0.15.18",
+        "esbuild-sunos-64": "0.15.18",
+        "esbuild-windows-32": "0.15.18",
+        "esbuild-windows-64": "0.15.18",
+        "esbuild-windows-arm64": "0.15.18"
+      }
+    },
+    "node_modules/esbuild-android-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz",
+      "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-android-arm64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz",
+      "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-darwin-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz",
+      "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-darwin-arm64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz",
+      "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-freebsd-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz",
+      "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-freebsd-arm64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz",
+      "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-32": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz",
+      "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz",
+      "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-arm": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz",
+      "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-arm64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz",
+      "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-mips64le": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz",
+      "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-ppc64le": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz",
+      "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-riscv64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz",
+      "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-s390x": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz",
+      "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-netbsd-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz",
+      "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-openbsd-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz",
+      "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-sunos-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz",
+      "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-windows-32": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz",
+      "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-windows-64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz",
+      "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-windows-arm64": {
+      "version": "0.15.18",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz",
+      "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+      "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/fast-json-patch": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz",
+      "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==",
+      "license": "MIT"
+    },
+    "node_modules/fault": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
+      "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
+      "license": "MIT",
+      "dependencies": {
+        "format": "^0.2.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/fill-range": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+      "license": "MIT",
+      "dependencies": {
+        "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/find-yarn-workspace-root": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz",
+      "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "micromatch": "^4.0.2"
+      }
+    },
+    "node_modules/follow-redirects": {
+      "version": "1.16.0",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
+      "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/for-each": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+      "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+      "license": "MIT",
+      "dependencies": {
+        "is-callable": "^1.2.7"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/form-data": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz",
+      "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==",
+      "license": "MIT",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "es-set-tostringtag": "^2.1.0",
+        "hasown": "^2.0.4",
+        "mime-types": "^2.1.35"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/format": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
+      "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==",
+      "engines": {
+        "node": ">=0.4.x"
+      }
+    },
+    "node_modules/fs-extra": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+      "license": "MIT",
+      "dependencies": {
+        "at-least-node": "^1.0.0",
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+      "license": "ISC"
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/gensync": {
+      "version": "1.0.0-beta.2",
+      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+      "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.2",
+        "es-define-property": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.1.1",
+        "function-bind": "^1.1.2",
+        "get-proto": "^1.0.1",
+        "gopd": "^1.2.0",
+        "has-symbols": "^1.1.0",
+        "hasown": "^2.0.2",
+        "math-intrinsics": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+      "license": "MIT",
+      "dependencies": {
+        "dunder-proto": "^1.0.1",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+      "license": "ISC",
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/gopd": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/graceful-fs": {
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+      "license": "ISC"
+    },
+    "node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/has-property-descriptors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+      "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+      "license": "MIT",
+      "dependencies": {
+        "es-define-property": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-symbols": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-tostringtag": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+      "license": "MIT",
+      "dependencies": {
+        "has-symbols": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/hasown": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
+      "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
+      "license": "MIT",
+      "dependencies": {
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/hast-util-parse-selector": {
+      "version": "2.2.5",
+      "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
+      "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==",
+      "license": "MIT",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/hastscript": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
+      "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/hast": "^2.0.0",
+        "comma-separated-tokens": "^1.0.0",
+        "hast-util-parse-selector": "^2.0.0",
+        "property-information": "^5.0.0",
+        "space-separated-tokens": "^1.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/highlight.js": {
+      "version": "10.7.3",
+      "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
+      "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/highlightjs-vue": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz",
+      "integrity": "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==",
+      "license": "CC0-1.0"
+    },
+    "node_modules/hoist-non-react-statics": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+      "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "react-is": "^16.7.0"
+      }
+    },
+    "node_modules/https-proxy-agent": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+      "license": "MIT",
+      "dependencies": {
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/immutable": {
+      "version": "3.8.4",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.4.tgz",
+      "integrity": "sha512-ZQv17KolYrYmsDoDB8N67zhIKsNi9mGYlk96y/yuxyAqJB2hLzSGSM7k/sB0/ZvO4kx27U9+fBeD/XlLGh/uXQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+      "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+      "license": "ISC",
+      "dependencies": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "license": "ISC"
+    },
+    "node_modules/invariant": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+      "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+      "license": "MIT",
+      "dependencies": {
+        "loose-envify": "^1.0.0"
+      }
+    },
+    "node_modules/is-alphabetical": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
+      "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/is-alphanumerical": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
+      "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
+      "license": "MIT",
+      "dependencies": {
+        "is-alphabetical": "^1.0.0",
+        "is-decimal": "^1.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/is-callable": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+      "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-ci": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+      "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+      "license": "MIT",
+      "dependencies": {
+        "ci-info": "^2.0.0"
+      },
+      "bin": {
+        "is-ci": "bin.js"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.17.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.17.0.tgz",
+      "integrity": "sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "hasown": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-decimal": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
+      "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/is-docker": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+      "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+      "license": "MIT",
+      "bin": {
+        "is-docker": "cli.js"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-hexadecimal": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
+      "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/is-typed-array": {
+      "version": "1.1.15",
+      "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+      "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+      "license": "MIT",
+      "dependencies": {
+        "which-typed-array": "^1.1.16"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-wsl": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+      "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+      "license": "MIT",
+      "dependencies": {
+        "is-docker": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/isarray": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+      "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+      "license": "MIT"
+    },
+    "node_modules/isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+      "license": "ISC"
+    },
+    "node_modules/js-file-download": {
+      "version": "0.4.12",
+      "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz",
+      "integrity": "sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==",
+      "license": "MIT"
+    },
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "license": "MIT"
+    },
+    "node_modules/js-yaml": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+      "license": "MIT",
+      "dependencies": {
+        "argparse": "^2.0.1"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
+      }
+    },
+    "node_modules/jsesc": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+      "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "jsesc": "bin/jsesc"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/json5": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "json5": "lib/cli.js"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/jsonfile": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz",
+      "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==",
+      "license": "MIT",
+      "dependencies": {
+        "universalify": "^2.0.0"
+      },
+      "optionalDependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/klaw-sync": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
+      "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==",
+      "license": "MIT",
+      "dependencies": {
+        "graceful-fs": "^4.1.11"
+      }
+    },
+    "node_modules/lodash": {
+      "version": "4.18.1",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+      "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
+      "license": "MIT"
+    },
+    "node_modules/lodash.debounce": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+      "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
+      "license": "MIT"
+    },
+    "node_modules/loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "license": "MIT",
+      "dependencies": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      },
+      "bin": {
+        "loose-envify": "cli.js"
+      }
+    },
+    "node_modules/lowlight": {
+      "version": "1.20.0",
+      "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
+      "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
+      "license": "MIT",
+      "dependencies": {
+        "fault": "^1.0.0",
+        "highlight.js": "~10.7.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/magic-string": {
+      "version": "0.26.7",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz",
+      "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "sourcemap-codec": "^1.4.8"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/math-intrinsics": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/micromatch": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+      "license": "MIT",
+      "dependencies": {
+        "braces": "^3.0.3",
+        "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/minim": {
+      "version": "0.23.8",
+      "resolved": "https://registry.npmjs.org/minim/-/minim-0.23.8.tgz",
+      "integrity": "sha512-bjdr2xW1dBCMsMGGsUeqM4eFI60m94+szhxWys+B1ztIt6gWSfeGBdSVCIawezeHYLYn0j6zrsXdQS/JllBzww==",
+      "license": "MIT",
+      "dependencies": {
+        "lodash": "^4.15.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/minimatch": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+      "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/minimist": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "license": "MIT"
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.19",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz",
+      "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/neotraverse": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-1.0.1.tgz",
+      "integrity": "sha512-WmmLty1YWwJl9yZi77v2dVIV6X2kuYV8YYBI/G3LWGKdGHmHUvL1z7FW0iDvEvGAwNEoc5x1tOOOyDnf5jJw/w==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/nice-try": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+      "license": "MIT"
+    },
+    "node_modules/node-abort-controller": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz",
+      "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==",
+      "license": "MIT"
+    },
+    "node_modules/node-addon-api": {
+      "version": "8.9.2",
+      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.9.2.tgz",
+      "integrity": "sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==",
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": "^18 || ^20 || >= 21"
+      }
+    },
+    "node_modules/node-gyp-build": {
+      "version": "4.8.4",
+      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
+      "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
+      "license": "MIT",
+      "optional": true,
+      "bin": {
+        "node-gyp-build": "bin.js",
+        "node-gyp-build-optional": "optional.js",
+        "node-gyp-build-test": "build-test.js"
+      }
+    },
+    "node_modules/node-releases": {
+      "version": "2.0.56",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.56.tgz",
+      "integrity": "sha512-x0InOIyzgdk+eyaWaRJFH5snEtiImgBgblZ2CyPrLmqqcuMQkEvcDPHbzqbD8eDsSeJbVOjn+crzyzHaM4D+/A==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+      "license": "ISC",
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/open": {
+      "version": "7.4.2",
+      "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
+      "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
+      "license": "MIT",
+      "dependencies": {
+        "is-docker": "^2.0.0",
+        "is-wsl": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/openapi-path-templating": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/openapi-path-templating/-/openapi-path-templating-2.2.1.tgz",
+      "integrity": "sha512-eN14VrDvl/YyGxxrkGOHkVkWEoPyhyeydOUrbvjoz8K5eIGgELASwN1eqFOJ2CTQMGCy2EntOK1KdtJ8ZMekcg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "apg-lite": "^1.0.4"
+      },
+      "engines": {
+        "node": ">=12.20.0"
+      }
+    },
+    "node_modules/openapi-server-url-templating": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/openapi-server-url-templating/-/openapi-server-url-templating-1.3.0.tgz",
+      "integrity": "sha512-DPlCms3KKEbjVQb0spV6Awfn6UWNheuG/+folQPzh/wUaKwuqvj8zt5gagD7qoyxtE03cIiKPgLFS3Q8Bz00uQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "apg-lite": "^1.0.4"
+      },
+      "engines": {
+        "node": ">=12.20.0"
+      }
+    },
+    "node_modules/os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/parse-entities": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
+      "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
+      "license": "MIT",
+      "dependencies": {
+        "character-entities": "^1.0.0",
+        "character-entities-legacy": "^1.0.0",
+        "character-reference-invalid": "^1.0.0",
+        "is-alphanumerical": "^1.0.0",
+        "is-decimal": "^1.0.0",
+        "is-hexadecimal": "^1.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/patch-package": {
+      "version": "6.5.1",
+      "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.1.tgz",
+      "integrity": "sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==",
+      "license": "MIT",
+      "dependencies": {
+        "@yarnpkg/lockfile": "^1.1.0",
+        "chalk": "^4.1.2",
+        "cross-spawn": "^6.0.5",
+        "find-yarn-workspace-root": "^2.0.0",
+        "fs-extra": "^9.0.0",
+        "is-ci": "^2.0.0",
+        "klaw-sync": "^6.0.0",
+        "minimist": "^1.2.6",
+        "open": "^7.4.2",
+        "rimraf": "^2.6.3",
+        "semver": "^5.6.0",
+        "slash": "^2.0.0",
+        "tmp": "^0.0.33",
+        "yaml": "^1.10.2"
+      },
+      "bin": {
+        "patch-package": "index.js"
+      },
+      "engines": {
+        "node": ">=10",
+        "npm": ">5"
+      }
+    },
+    "node_modules/patch-package/node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/path-parse": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/picomatch": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+      "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/possible-typed-array-names": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+      "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/postcss": {
+      "version": "8.5.28",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz",
+      "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "nanoid": "^3.3.18",
+        "picocolors": "^1.1.1",
+        "source-map-js": "^1.2.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/prismjs": {
+      "version": "1.30.0",
+      "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
+      "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/prop-types": {
+      "version": "15.8.1",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+      "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+      "license": "MIT",
+      "dependencies": {
+        "loose-envify": "^1.4.0",
+        "object-assign": "^4.1.1",
+        "react-is": "^16.13.1"
+      }
+    },
+    "node_modules/property-information": {
+      "version": "5.6.0",
+      "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
+      "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
+      "license": "MIT",
+      "dependencies": {
+        "xtend": "^4.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/proxy-from-env": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
+      "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/querystringify": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+      "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
+      "license": "MIT"
+    },
+    "node_modules/ramda": {
+      "version": "0.30.1",
+      "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz",
+      "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==",
+      "license": "MIT",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/ramda"
+      }
+    },
+    "node_modules/ramda-adjunct": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz",
+      "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==",
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.3"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/ramda-adjunct"
+      },
+      "peerDependencies": {
+        "ramda": ">= 0.30.0"
+      }
+    },
+    "node_modules/randexp": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz",
+      "integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==",
+      "license": "MIT",
+      "dependencies": {
+        "drange": "^1.0.2",
+        "ret": "^0.2.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "license": "MIT",
+      "dependencies": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/react": {
+      "version": "18.3.1",
+      "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+      "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+      "license": "MIT",
+      "dependencies": {
+        "loose-envify": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/react-copy-to-clipboard": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz",
+      "integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==",
+      "license": "MIT",
+      "dependencies": {
+        "copy-to-clipboard": "^3.3.1",
+        "prop-types": "^15.8.1"
+      },
+      "peerDependencies": {
+        "react": "^15.3.0 || 16 || 17 || 18"
+      }
+    },
+    "node_modules/react-debounce-input": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.3.0.tgz",
+      "integrity": "sha512-VEqkvs8JvY/IIZvh71Z0TC+mdbxERvYF33RcebnodlsUZ8RSgyKe2VWaHXv4+/8aoOgXLxWrdsYs2hDhcwbUgA==",
+      "license": "MIT",
+      "dependencies": {
+        "lodash.debounce": "^4",
+        "prop-types": "^15.8.1"
+      },
+      "peerDependencies": {
+        "react": "^15.3.0 || 16 || 17 || 18"
+      }
+    },
+    "node_modules/react-dom": {
+      "version": "18.3.1",
+      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+      "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+      "license": "MIT",
+      "dependencies": {
+        "loose-envify": "^1.1.0",
+        "scheduler": "^0.23.2"
+      },
+      "peerDependencies": {
+        "react": "^18.3.1"
+      }
+    },
+    "node_modules/react-immutable-proptypes": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz",
+      "integrity": "sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ==",
+      "license": "MIT",
+      "dependencies": {
+        "invariant": "^2.2.2"
+      },
+      "peerDependencies": {
+        "immutable": ">=3.6.2"
+      }
+    },
+    "node_modules/react-immutable-pure-component": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-2.2.2.tgz",
+      "integrity": "sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A==",
+      "license": "MIT",
+      "peerDependencies": {
+        "immutable": ">= 2 || >= 4.0.0-rc",
+        "react": ">= 16.6",
+        "react-dom": ">= 16.6"
+      }
+    },
+    "node_modules/react-inspector": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.2.tgz",
+      "integrity": "sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ==",
+      "license": "MIT",
+      "peerDependencies": {
+        "react": "^16.8.4 || ^17.0.0 || ^18.0.0"
+      }
+    },
+    "node_modules/react-is": {
+      "version": "16.13.1",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+      "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+      "license": "MIT"
+    },
+    "node_modules/react-redux": {
+      "version": "8.1.3",
+      "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz",
+      "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.12.1",
+        "@types/hoist-non-react-statics": "^3.3.1",
+        "@types/use-sync-external-store": "^0.0.3",
+        "hoist-non-react-statics": "^3.3.2",
+        "react-is": "^18.0.0",
+        "use-sync-external-store": "^1.0.0"
+      },
+      "peerDependencies": {
+        "@types/react": "^16.8 || ^17.0 || ^18.0",
+        "@types/react-dom": "^16.8 || ^17.0 || ^18.0",
+        "react": "^16.8 || ^17.0 || ^18.0",
+        "react-dom": "^16.8 || ^17.0 || ^18.0",
+        "react-native": ">=0.59",
+        "redux": "^4 || ^5.0.0-beta.0"
+      },
+      "peerDependenciesMeta": {
+        "@types/react": {
+          "optional": true
+        },
+        "@types/react-dom": {
+          "optional": true
+        },
+        "react-dom": {
+          "optional": true
+        },
+        "react-native": {
+          "optional": true
+        },
+        "redux": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/react-redux/node_modules/react-is": {
+      "version": "18.3.1",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+      "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+      "license": "MIT"
+    },
+    "node_modules/react-refresh": {
+      "version": "0.14.2",
+      "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
+      "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/react-syntax-highlighter": {
+      "version": "15.6.6",
+      "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.6.6.tgz",
+      "integrity": "sha512-DgXrc+AZF47+HvAPEmn7Ua/1p10jNoVZVI/LoPiYdtY+OM+/nG5yefLHKJwdKqY1adMuHFbeyBaG9j64ML7vTw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.3.1",
+        "highlight.js": "^10.4.1",
+        "highlightjs-vue": "^1.0.0",
+        "lowlight": "^1.17.0",
+        "prismjs": "^1.30.0",
+        "refractor": "^3.6.0"
+      },
+      "peerDependencies": {
+        "react": ">= 0.14.0"
+      }
+    },
+    "node_modules/redux": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
+      "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.9.2"
+      }
+    },
+    "node_modules/redux-immutable": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/redux-immutable/-/redux-immutable-4.0.0.tgz",
+      "integrity": "sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg==",
+      "license": "BSD-3-Clause",
+      "peerDependencies": {
+        "immutable": "^3.8.1 || ^4.0.0-rc.1"
+      }
+    },
+    "node_modules/refractor": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz",
+      "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==",
+      "license": "MIT",
+      "dependencies": {
+        "hastscript": "^6.0.0",
+        "parse-entities": "^2.0.0",
+        "prismjs": "~1.27.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/refractor/node_modules/prismjs": {
+      "version": "1.27.0",
+      "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
+      "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/remarkable": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-2.0.1.tgz",
+      "integrity": "sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA==",
+      "license": "MIT",
+      "dependencies": {
+        "argparse": "^1.0.10",
+        "autolinker": "^3.11.0"
+      },
+      "bin": {
+        "remarkable": "bin/remarkable.js"
+      },
+      "engines": {
+        "node": ">= 6.0.0"
+      }
+    },
+    "node_modules/remarkable/node_modules/argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "license": "MIT",
+      "dependencies": {
+        "sprintf-js": "~1.0.2"
+      }
+    },
+    "node_modules/repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/requires-port": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+      "license": "MIT"
+    },
+    "node_modules/reselect": {
+      "version": "4.1.8",
+      "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
+      "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==",
+      "license": "MIT"
+    },
+    "node_modules/resolve": {
+      "version": "1.22.12",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz",
+      "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "is-core-module": "^2.16.1",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/ret": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz",
+      "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/rimraf": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+      "deprecated": "Rimraf versions prior to v4 are no longer supported",
+      "license": "ISC",
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      }
+    },
+    "node_modules/rollup": {
+      "version": "2.80.0",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.80.0.tgz",
+      "integrity": "sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "license": "MIT"
+    },
+    "node_modules/scheduler": {
+      "version": "0.23.2",
+      "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+      "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+      "license": "MIT",
+      "dependencies": {
+        "loose-envify": "^1.1.0"
+      }
+    },
+    "node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/serialize-error": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz",
+      "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==",
+      "license": "MIT",
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/set-function-length": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+      "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+      "license": "MIT",
+      "dependencies": {
+        "define-data-property": "^1.1.4",
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2",
+        "get-intrinsic": "^1.2.4",
+        "gopd": "^1.0.1",
+        "has-property-descriptors": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/sha.js": {
+      "version": "2.4.12",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz",
+      "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==",
+      "license": "(MIT AND BSD-3-Clause)",
+      "dependencies": {
+        "inherits": "^2.0.4",
+        "safe-buffer": "^5.2.1",
+        "to-buffer": "^1.2.0"
+      },
+      "bin": {
+        "sha.js": "bin.js"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+      "license": "MIT",
+      "dependencies": {
+        "shebang-regex": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/short-unique-id": {
+      "version": "5.3.2",
+      "resolved": "https://registry.npmjs.org/short-unique-id/-/short-unique-id-5.3.2.tgz",
+      "integrity": "sha512-KRT/hufMSxXKEDSQujfVE0Faa/kZ51ihUcZQAcmP04t00DvPj7Ox5anHke1sJYUtzSuiT/Y5uyzg/W7bBEGhCg==",
+      "license": "Apache-2.0",
+      "bin": {
+        "short-unique-id": "bin/short-unique-id",
+        "suid": "bin/short-unique-id"
+      }
+    },
+    "node_modules/slash": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+      "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sourcemap-codec": {
+      "version": "1.4.8",
+      "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
+      "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
+      "deprecated": "Please use @jridgewell/sourcemap-codec instead",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/space-separated-tokens": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
+      "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==",
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/sprintf-js": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+      "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "license": "MIT",
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/swagger-client": {
+      "version": "3.38.2",
+      "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.38.2.tgz",
+      "integrity": "sha512-MrMYADBRg7nY5Y+CY9E76/Zm2LSghhln4wNNU6jGn3bNZ76BRQ3hQRyCHCyJK9tVgTDUmYCcYgYWrwGruL1mIw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.22.15",
+        "@scarf/scarf": "=1.4.0",
+        "@swagger-api/apidom-core": "1.11.6",
+        "@swagger-api/apidom-error": "1.11.6",
+        "@swagger-api/apidom-json-pointer": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-1": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-3-2": "1.11.6",
+        "@swagger-api/apidom-reference": "1.11.6",
+        "@swaggerexpert/cookie": "^2.0.2",
+        "deepmerge": "~4.3.0",
+        "fast-json-patch": "^3.0.0-1",
+        "js-yaml": "^4.3.2",
+        "neotraverse": "=1.0.1",
+        "node-abort-controller": "^3.1.1",
+        "openapi-path-templating": "^2.2.1",
+        "openapi-server-url-templating": "^1.3.0",
+        "ramda": "^0.30.1",
+        "ramda-adjunct": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=22"
+      },
+      "optionalDependencies": {
+        "@swagger-api/apidom-ns-asyncapi-2": "1.11.6",
+        "@swagger-api/apidom-ns-asyncapi-3": "1.11.6",
+        "@swagger-api/apidom-ns-openapi-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-api-design-systems-json": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-arazzo-json-1": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-arazzo-yaml-1": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-asyncapi-json-3": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-asyncapi-yaml-3": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-json": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-json-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-json-3-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-yaml-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-openapi-yaml-3-2": "1.11.6",
+        "@swagger-api/apidom-parser-adapter-yaml-1-2": "1.11.6"
+      }
+    },
+    "node_modules/swagger-client/node_modules/js-yaml": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
+      "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/puzrin"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/nodeca"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "argparse": "^2.0.1"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
+      }
+    },
+    "node_modules/swagger-ui-react": {
+      "version": "4.19.1",
+      "resolved": "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-4.19.1.tgz",
+      "integrity": "sha512-km83cp5ZlmCfROOq6QD1E7bM9f0RsvNrM2C1756UqZ6rRM0J3ex3ySyWa5+mcJRltn0eUB5NahqW8c6I4qwC6A==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime-corejs3": "^7.22.5",
+        "@braintree/sanitize-url": "=6.0.2",
+        "base64-js": "^1.5.1",
+        "classnames": "^2.3.1",
+        "css.escape": "1.5.1",
+        "deep-extend": "0.6.0",
+        "dompurify": "=3.0.2",
+        "ieee754": "^1.2.1",
+        "immutable": "^3.x.x",
+        "js-file-download": "^0.4.12",
+        "js-yaml": "=4.1.0",
+        "lodash": "^4.17.21",
+        "patch-package": "^6.5.0",
+        "prop-types": "^15.8.1",
+        "randexp": "^0.5.3",
+        "randombytes": "^2.1.0",
+        "react-copy-to-clipboard": "5.1.0",
+        "react-debounce-input": "=3.3.0",
+        "react-immutable-proptypes": "2.2.0",
+        "react-immutable-pure-component": "^2.2.0",
+        "react-inspector": "^6.0.1",
+        "react-redux": "^8.0.5",
+        "react-syntax-highlighter": "^15.5.0",
+        "redux": "^4.1.2",
+        "redux-immutable": "^4.0.0",
+        "remarkable": "^2.0.1",
+        "reselect": "^4.1.8",
+        "serialize-error": "^8.1.0",
+        "sha.js": "^2.4.11",
+        "swagger-client": "^3.19.8",
+        "url-parse": "^1.5.8",
+        "xml": "=1.0.1",
+        "xml-but-prettier": "^1.0.1",
+        "zenscroll": "^4.0.2"
+      },
+      "peerDependencies": {
+        "react": ">=17.0.0",
+        "react-dom": ">=17.0.0"
+      }
+    },
+    "node_modules/tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "license": "MIT",
+      "dependencies": {
+        "os-tmpdir": "~1.0.2"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/to-buffer": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz",
+      "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==",
+      "license": "MIT",
+      "dependencies": {
+        "isarray": "^2.0.5",
+        "safe-buffer": "^5.2.1",
+        "typed-array-buffer": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "license": "MIT",
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/toggle-selection": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
+      "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==",
+      "license": "MIT"
+    },
+    "node_modules/tree-sitter": {
+      "version": "0.21.1",
+      "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.21.1.tgz",
+      "integrity": "sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "node-addon-api": "^8.0.0",
+        "node-gyp-build": "^4.8.0"
+      }
+    },
+    "node_modules/tree-sitter-json": {
+      "version": "0.24.8",
+      "resolved": "https://registry.npmjs.org/tree-sitter-json/-/tree-sitter-json-0.24.8.tgz",
+      "integrity": "sha512-Tc9ZZYwHyWZ3Tt1VEw7Pa2scu1YO7/d2BCBbKTx5hXwig3UfdQjsOPkPyLpDJOn/m1UBEWYAtSdGAwCSyagBqQ==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "node-addon-api": "^8.2.2",
+        "node-gyp-build": "^4.8.2"
+      },
+      "peerDependencies": {
+        "tree-sitter": "^0.21.1"
+      },
+      "peerDependenciesMeta": {
+        "tree-sitter": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/ts-mixer": {
+      "version": "6.0.4",
+      "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
+      "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==",
+      "license": "MIT"
+    },
+    "node_modules/ts-toolbelt": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz",
+      "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/tslib": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+      "license": "0BSD"
+    },
+    "node_modules/type-fest": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+      "license": "(MIT OR CC0-1.0)",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/typed-array-buffer": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+      "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3",
+        "es-errors": "^1.3.0",
+        "is-typed-array": "^1.1.14"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/types-ramda": {
+      "version": "0.30.1",
+      "resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.30.1.tgz",
+      "integrity": "sha512-1HTsf5/QVRmLzcGfldPFvkVsAdi1db1BBKzi7iW3KBUlOICg/nKnFS+jGqDJS3YD8VsWbAh7JiHeBvbsw8RPxA==",
+      "license": "MIT",
+      "dependencies": {
+        "ts-toolbelt": "^9.6.0"
+      }
+    },
+    "node_modules/typescript": {
+      "version": "4.9.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=4.2.0"
+      }
+    },
+    "node_modules/universalify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10.0.0"
+      }
+    },
+    "node_modules/unraw": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/unraw/-/unraw-3.0.0.tgz",
+      "integrity": "sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg==",
+      "license": "MIT"
+    },
+    "node_modules/update-browserslist-db": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz",
+      "integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "escalade": "^3.2.0",
+        "picocolors": "^1.1.1"
+      },
+      "bin": {
+        "update-browserslist-db": "cli.js"
+      },
+      "peerDependencies": {
+        "browserslist": ">= 4.21.0"
+      }
+    },
+    "node_modules/url-parse": {
+      "version": "1.5.10",
+      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+      "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+      "license": "MIT",
+      "dependencies": {
+        "querystringify": "^2.1.1",
+        "requires-port": "^1.0.0"
+      }
+    },
+    "node_modules/use-sync-external-store": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.7.0.tgz",
+      "integrity": "sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==",
+      "license": "MIT",
+      "peerDependencies": {
+        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+      }
+    },
+    "node_modules/vite": {
+      "version": "3.2.11",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-3.2.11.tgz",
+      "integrity": "sha512-K/jGKL/PgbIgKCiJo5QbASQhFiV02X9Jh+Qq0AKCRCRKZtOTVi4t6wh75FDpGf2N9rYOnzH87OEFQNaFy6pdxQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "esbuild": "^0.15.9",
+        "postcss": "^8.4.18",
+        "resolve": "^1.22.1",
+        "rollup": "^2.79.1"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      },
+      "peerDependencies": {
+        "@types/node": ">= 14",
+        "less": "*",
+        "sass": "*",
+        "stylus": "*",
+        "sugarss": "*",
+        "terser": "^5.4.0"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        },
+        "less": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "stylus": {
+          "optional": true
+        },
+        "sugarss": {
+          "optional": true
+        },
+        "terser": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/web-tree-sitter": {
+      "version": "0.24.5",
+      "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.24.5.tgz",
+      "integrity": "sha512-+J/2VSHN8J47gQUAvF8KDadrfz6uFYVjxoxbKWDoXVsH2u7yLdarCnIURnrMA6uSRkgX3SdmqM5BOoQjPdSh5w==",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "license": "ISC",
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
+    "node_modules/which-typed-array": {
+      "version": "1.1.24",
+      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.24.tgz",
+      "integrity": "sha512-wk4Mf4pR5mRP7eYuuTBCIQ9d0ud2Fv2jRLQpfgnRjbOxAFHmjKFValgTpitVKzJJS8ajnYQV2Du1SZ8j6b/EUQ==",
+      "license": "MIT",
+      "dependencies": {
+        "available-typed-arrays": "^1.0.7",
+        "call-bind": "^1.0.9",
+        "call-bound": "^1.0.4",
+        "for-each": "^0.3.5",
+        "get-proto": "^1.0.1",
+        "gopd": "^1.2.0",
+        "has-tostringtag": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+      "license": "ISC"
+    },
+    "node_modules/xml": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
+      "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==",
+      "license": "MIT"
+    },
+    "node_modules/xml-but-prettier": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/xml-but-prettier/-/xml-but-prettier-1.0.1.tgz",
+      "integrity": "sha512-C2CJaadHrZTqESlH03WOyw0oZTtoy2uEg6dSDF6YRg+9GnYNub53RRemLpnvtbHDFelxMx4LajiFsYeR6XJHgQ==",
+      "license": "MIT",
+      "dependencies": {
+        "repeat-string": "^1.5.2"
+      }
+    },
+    "node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/yaml": {
+      "version": "1.10.3",
+      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz",
+      "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==",
+      "license": "ISC",
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/zenscroll": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/zenscroll/-/zenscroll-4.0.2.tgz",
+      "integrity": "sha512-jEA1znR7b4C/NnaycInCU6h/d15ZzCd1jmsruqOKnZP6WXQSMH3W2GL+OXbkruslU4h+Tzuos0HdswzRUk/Vgg==",
+      "license": "Unlicense"
+    }
+  }
+}

+ 4 - 1
openapi/package.json

@@ -4,6 +4,8 @@
   "version": "0.0.0",
   "type": "module",
   "scripts": {
+    "generate": "php scripts/generate.php",
+    "lint": "redocly lint public/assets/protocol/main.yaml",
     "dev": "vite",
     "build": "tsc && vite build",
     "preview": "vite preview"
@@ -19,6 +21,7 @@
     "@types/react-dom": "^18.0.8",
     "@vitejs/plugin-react": "^2.2.0",
     "typescript": "^4.6.4",
-    "vite": "^3.2.3"
+    "vite": "^3.2.3",
+    "@redocly/cli": "^2.10.2"
   }
 }

+ 626 - 38
openapi/public/assets/protocol/main.yaml

@@ -1,41 +1,629 @@
-openapi: 3.0.0
+# 由 openapi/scripts/generate.php 生成,请勿手改
+openapi: 3.0.3
 info:
-  title: MINT API
-  description: International Academy Of Pali Tipitaka(国际巴利三藏学院)
-  version: 2022.12.8
+  title: 'MINT API'
+  description: |-
+    International Academy Of Pali Tipitaka(国际巴利三藏学院)
+
+    由 `php openapi/scripts/generate.php` 依据 api-v13 的路由与控制器源码生成。
+    响应统一封装为 `{ok, message, data}`;`ok=false` 时 `message` 为错误信息。
+  version: 2026.9.21
 servers:
-  - url: https://staging.wikipali.org/api/v2
-    description: Internal staging server for testing
-  - url: https://www.wikipali.org/api/v2
-    description: Main production server
-  - url: https://www.wikipali.cc/api/v2
-    description: Main production server in china
-  - url: http://127.0.0.1:8000/api/v2
-    description: local dev
+  -
+    url: 'https://www.wikipali.org/api'
+    description: 生产
+  -
+    url: 'https://www.wikipali.cc/api'
+    description: 生产(中国)
+  -
+    url: 'https://staging.wikipali.org/api'
+    description: 测试
+  -
+    url: 'http://127.0.0.1:8000/api'
+    description: 本地开发
+components:
+  securitySchemes:
+    bearerAuth:
+      type: http
+      scheme: bearer
+      description: '用户 token 或 access token'
+  responses:
+    Unauthorized:
+      description: 未登录或无权限
+      content:
+        application/json:
+          schema:
+            $ref: '#/components/schemas/Envelope'
+    ValidationError:
+      description: 参数校验失败
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              message: { type: string }
+              errors: { type: object, additionalProperties: { type: array, items: { type: string } } }
+  schemas:
+    Envelope:
+      type: object
+      properties:
+        ok:
+          type: boolean
+        message:
+          type: string
+        data:
+          description: 业务数据,形状随接口而定
+security:
+  -
+    bearerAuth: []
 paths:
-  /users:
-    $ref: "./resources/auth/users/index.yaml"
-  /users/sign-in:
-    $ref: "./resources/auth/users/sign-in.yaml"
-  /channel:
-    $ref: "./resources/channel/index.yaml"
-  /channel/{channelId}:
-    $ref: "./resources/channel/show.yaml"
-  /palitext:
-    $ref: "./resources/corpus/pali-text/index.yaml"
-  /discussion:
-    $ref: "./resources/discussion/index.yaml"
-  /channel-io:
-    $ref: "./resources/io/channel/export.yaml"
-  /chapter-io:
-    $ref: "./resources/io/chapter/export.yaml"
-  /sentence-io:
-    $ref: "./resources/io/sentence/export.yaml"
-  /progress:
-    $ref: "./resources/progress/index.yaml"
-  /sentence:
-    $ref: "./resources/sentence/index.yaml"
-  /corpus:
-    $ref: "./resources/corpus/corpus/index.yaml"
-  /chapter-index:
-    $ref: "./resources/chapter-index/index.yaml"
+  /api/sentence/progress/daily/image:
+    $ref: ./resources/auto/api-sentence-progress-daily-image.yaml
+  /api/sentence/progress/image:
+    $ref: ./resources/auto/api-sentence-progress-image.yaml
+  '/ops/update-pali-synonyms/{version}':
+    $ref: ./resources/auto/ops-update-pali-synonyms-version.yaml
+  /v2/access-token:
+    $ref: ./resources/auto/v2-access-token.yaml
+  '/v2/access-token/{access_token}':
+    $ref: ./resources/auto/v2-access-token-access-token.yaml
+  /v2/ai-assistant:
+    $ref: ./resources/auto/v2-ai-assistant.yaml
+  '/v2/ai-assistant/{ai_assistant}':
+    $ref: ./resources/auto/v2-ai-assistant-ai-assistant.yaml
+  /v2/ai-model:
+    $ref: ./resources/auto/v2-ai-model.yaml
+  '/v2/ai-model-token/{ai_model}':
+    $ref: ./resources/auto/v2-ai-model-token-ai-model.yaml
+  '/v2/ai-model/{ai_model}':
+    $ref: ./resources/auto/v2-ai-model-ai-model.yaml
+  /v2/ai-translate:
+    $ref: ./resources/auto/v2-ai-translate.yaml
+  '/v2/ai-translate/{ai_translate}':
+    $ref: ./resources/auto/v2-ai-translate-ai-translate.yaml
+  /v2/anthology:
+    $ref: ./resources/auto/v2-anthology.yaml
+  /v2/anthology-my-number:
+    $ref: ./resources/auto/v2-anthology-my-number.yaml
+  '/v2/anthology/{anthology}':
+    $ref: ./resources/auto/v2-anthology-anthology.yaml
+  /v2/api:
+    $ref: ./resources/auto/v2-api.yaml
+  '/v2/api/{api}':
+    $ref: ./resources/auto/v2-api-api.yaml
+  /v2/article:
+    $ref: ./resources/auto/v2-article.yaml
+  /v2/article-fts:
+    $ref: ./resources/auto/v2-article-fts.yaml
+  '/v2/article-fts/{article_ft}':
+    $ref: ./resources/auto/v2-article-fts-article-ft.yaml
+  /v2/article-map:
+    $ref: ./resources/auto/v2-article-map.yaml
+  '/v2/article-map/{article_map}':
+    $ref: ./resources/auto/v2-article-map-article-map.yaml
+  /v2/article-my-number:
+    $ref: ./resources/auto/v2-article-my-number.yaml
+  /v2/article-nav:
+    $ref: ./resources/auto/v2-article-nav.yaml
+  '/v2/article-nav/{article_nav}':
+    $ref: ./resources/auto/v2-article-nav-article-nav.yaml
+  '/v2/article-preview/{id}':
+    $ref: ./resources/auto/v2-article-preview-id.yaml
+  /v2/article-progress:
+    $ref: ./resources/auto/v2-article-progress.yaml
+  '/v2/article-progress/{article_progress}':
+    $ref: ./resources/auto/v2-article-progress-article-progress.yaml
+  '/v2/article/{article}':
+    $ref: ./resources/auto/v2-article-article.yaml
+  /v2/attachment:
+    $ref: ./resources/auto/v2-attachment.yaml
+  '/v2/attachment/{attachment}':
+    $ref: ./resources/auto/v2-attachment-attachment.yaml
+  /v2/attachments:
+    $ref: ./resources/auto/v2-attachments.yaml
+  '/v2/attachments/{attachment}':
+    $ref: ./resources/auto/v2-attachments-attachment.yaml
+  /v2/auth/current:
+    $ref: ./resources/auto/v2-auth-current.yaml
+  /v2/auth/forgot-password:
+    $ref: ./resources/auto/v2-auth-forgot-password.yaml
+  '/v2/auth/forgot-password/{forgot_password}':
+    $ref: ./resources/auto/v2-auth-forgot-password-forgot-password.yaml
+  /v2/auth/reset-password:
+    $ref: ./resources/auto/v2-auth-reset-password.yaml
+  '/v2/auth/reset-password/{reset_password}':
+    $ref: ./resources/auto/v2-auth-reset-password-reset-password.yaml
+  /v2/book-title:
+    $ref: ./resources/auto/v2-book-title.yaml
+  '/v2/book-title/{book_title}':
+    $ref: ./resources/auto/v2-book-title-book-title.yaml
+  /v2/case:
+    $ref: ./resources/auto/v2-case.yaml
+  '/v2/case/{case}':
+    $ref: ./resources/auto/v2-case-case.yaml
+  /v2/channel:
+    $ref: ./resources/auto/v2-channel.yaml
+  /v2/channel-io:
+    $ref: ./resources/auto/v2-channel-io.yaml
+  '/v2/channel-io/{channel_io}':
+    $ref: ./resources/auto/v2-channel-io-channel-io.yaml
+  /v2/channel-my-number:
+    $ref: ./resources/auto/v2-channel-my-number.yaml
+  '/v2/channel-name/{name}':
+    $ref: ./resources/auto/v2-channel-name-name.yaml
+  /v2/channel-progress:
+    $ref: ./resources/auto/v2-channel-progress.yaml
+  '/v2/channel/{channel}':
+    $ref: ./resources/auto/v2-channel-channel.yaml
+  /v2/chapter:
+    $ref: ./resources/auto/v2-chapter.yaml
+  /v2/chapter-content:
+    $ref: ./resources/auto/v2-chapter-content.yaml
+  '/v2/chapter-content/{chapter_content}':
+    $ref: ./resources/auto/v2-chapter-content-chapter-content.yaml
+  /v2/chapter-index:
+    $ref: ./resources/auto/v2-chapter-index.yaml
+  '/v2/chapter-index/{chapter_index}':
+    $ref: ./resources/auto/v2-chapter-index-chapter-index.yaml
+  /v2/chapter-io:
+    $ref: ./resources/auto/v2-chapter-io.yaml
+  '/v2/chapter-io/{chapter_io}':
+    $ref: ./resources/auto/v2-chapter-io-chapter-io.yaml
+  '/v2/chapter/{chapter}':
+    $ref: ./resources/auto/v2-chapter-chapter.yaml
+  /v2/chat-messages:
+    $ref: ./resources/auto/v2-chat-messages.yaml
+  '/v2/chat-messages/{chat_message}':
+    $ref: ./resources/auto/v2-chat-messages-chat-message.yaml
+  /v2/chats:
+    $ref: ./resources/auto/v2-chats.yaml
+  '/v2/chats/{chat}':
+    $ref: ./resources/auto/v2-chats-chat.yaml
+  /v2/command:
+    $ref: ./resources/auto/v2-command.yaml
+  '/v2/command/{command}':
+    $ref: ./resources/auto/v2-command-command.yaml
+  /v2/compound:
+    $ref: ./resources/auto/v2-compound.yaml
+  '/v2/compound/{compound}':
+    $ref: ./resources/auto/v2-compound-compound.yaml
+  /v2/corpus:
+    $ref: ./resources/auto/v2-corpus.yaml
+  '/v2/corpus-chapter/{id}':
+    $ref: ./resources/auto/v2-corpus-chapter-id.yaml
+  '/v2/corpus-sent/{id}':
+    $ref: ./resources/auto/v2-corpus-sent-id.yaml
+  '/v2/corpus-sentences/{type}/{id}':
+    $ref: ./resources/auto/v2-corpus-sentences-type-id.yaml
+  '/v2/corpus/{corpu}':
+    $ref: ./resources/auto/v2-corpus-corpu.yaml
+  /v2/course:
+    $ref: ./resources/auto/v2-course.yaml
+  /v2/course-curr:
+    $ref: ./resources/auto/v2-course-curr.yaml
+  /v2/course-member:
+    $ref: ./resources/auto/v2-course-member.yaml
+  /v2/course-member-export:
+    $ref: ./resources/auto/v2-course-member-export.yaml
+  '/v2/course-member/{course_member}':
+    $ref: ./resources/auto/v2-course-member-course-member.yaml
+  /v2/course-member_set-channel:
+    $ref: ./resources/auto/v2-course-member-set-channel.yaml
+  /v2/course-my-course:
+    $ref: ./resources/auto/v2-course-my-course.yaml
+  '/v2/course/{course}':
+    $ref: ./resources/auto/v2-course-course.yaml
+  /v2/dict:
+    $ref: ./resources/auto/v2-dict.yaml
+  /v2/dict-info:
+    $ref: ./resources/auto/v2-dict-info.yaml
+  '/v2/dict-info/{dict_info}':
+    $ref: ./resources/auto/v2-dict-info-dict-info.yaml
+  /v2/dict-meaning:
+    $ref: ./resources/auto/v2-dict-meaning.yaml
+  '/v2/dict-meaning/{dict_meaning}':
+    $ref: ./resources/auto/v2-dict-meaning-dict-meaning.yaml
+  /v2/dict-preference:
+    $ref: ./resources/auto/v2-dict-preference.yaml
+  '/v2/dict-preference/{dict_preference}':
+    $ref: ./resources/auto/v2-dict-preference-dict-preference.yaml
+  /v2/dict-statistic:
+    $ref: ./resources/auto/v2-dict-statistic.yaml
+  '/v2/dict-statistic/{dict_statistic}':
+    $ref: ./resources/auto/v2-dict-statistic-dict-statistic.yaml
+  /v2/dict-vocabulary:
+    $ref: ./resources/auto/v2-dict-vocabulary.yaml
+  '/v2/dict-vocabulary/{dict_vocabulary}':
+    $ref: ./resources/auto/v2-dict-vocabulary-dict-vocabulary.yaml
+  '/v2/dict/{dict}':
+    $ref: ./resources/auto/v2-dict-dict.yaml
+  /v2/discussion:
+    $ref: ./resources/auto/v2-discussion.yaml
+  '/v2/discussion-anchor/{id}':
+    $ref: ./resources/auto/v2-discussion-anchor-id.yaml
+  /v2/discussion-count:
+    $ref: ./resources/auto/v2-discussion-count.yaml
+  '/v2/discussion-count/{discussion_count}':
+    $ref: ./resources/auto/v2-discussion-count-discussion-count.yaml
+  '/v2/discussion/{discussion}':
+    $ref: ./resources/auto/v2-discussion-discussion.yaml
+  /v2/editable-sentence:
+    $ref: ./resources/auto/v2-editable-sentence.yaml
+  '/v2/editable-sentence/{editable_sentence}':
+    $ref: ./resources/auto/v2-editable-sentence-editable-sentence.yaml
+  /v2/email-certification:
+    $ref: ./resources/auto/v2-email-certification.yaml
+  '/v2/email-certification/{email_certification}':
+    $ref: ./resources/auto/v2-email-certification-email-certification.yaml
+  /v2/exercise:
+    $ref: ./resources/auto/v2-exercise.yaml
+  '/v2/exercise/{exercise}':
+    $ref: ./resources/auto/v2-exercise-exercise.yaml
+  /v2/export:
+    $ref: ./resources/auto/v2-export.yaml
+  '/v2/export/{export}':
+    $ref: ./resources/auto/v2-export-export.yaml
+  /v2/export_wbw:
+    $ref: ./resources/auto/v2-export-wbw.yaml
+  /v2/grammar-guide:
+    $ref: ./resources/auto/v2-grammar-guide.yaml
+  '/v2/grammar-guide/{grammar_guide}':
+    $ref: ./resources/auto/v2-grammar-guide-grammar-guide.yaml
+  /v2/group:
+    $ref: ./resources/auto/v2-group.yaml
+  /v2/group-member:
+    $ref: ./resources/auto/v2-group-member.yaml
+  '/v2/group-member/{group_member}':
+    $ref: ./resources/auto/v2-group-member-group-member.yaml
+  /v2/group-my-number:
+    $ref: ./resources/auto/v2-group-my-number.yaml
+  '/v2/group/{group}':
+    $ref: ./resources/auto/v2-group-group.yaml
+  /v2/health-check:
+    $ref: ./resources/auto/v2-health-check.yaml
+  '/v2/health-check/{health_check}':
+    $ref: ./resources/auto/v2-health-check-health-check.yaml
+  /v2/heartbeat:
+    $ref: ./resources/auto/v2-heartbeat.yaml
+  '/v2/heartbeat/{heartbeat}':
+    $ref: ./resources/auto/v2-heartbeat-heartbeat.yaml
+  /v2/interactive:
+    $ref: ./resources/auto/v2-interactive.yaml
+  '/v2/interactive/{interactive}':
+    $ref: ./resources/auto/v2-interactive-interactive.yaml
+  /v2/invite:
+    $ref: ./resources/auto/v2-invite.yaml
+  '/v2/invite/{invite}':
+    $ref: ./resources/auto/v2-invite-invite.yaml
+  /v2/like:
+    $ref: ./resources/auto/v2-like.yaml
+  '/v2/like/{like}':
+    $ref: ./resources/auto/v2-like-like.yaml
+  /v2/milestone:
+    $ref: ./resources/auto/v2-milestone.yaml
+  '/v2/milestone/{milestone}':
+    $ref: ./resources/auto/v2-milestone-milestone.yaml
+  /v2/mock/openai/chat/completions:
+    $ref: ./resources/auto/v2-mock-openai-chat-completions.yaml
+  /v2/mock/openai/completions:
+    $ref: ./resources/auto/v2-mock-openai-completions.yaml
+  /v2/mock/openai/models:
+    $ref: ./resources/auto/v2-mock-openai-models.yaml
+  /v2/model-log:
+    $ref: ./resources/auto/v2-model-log.yaml
+  '/v2/model-log/{model_log}':
+    $ref: ./resources/auto/v2-model-log-model-log.yaml
+  /v2/nav-article:
+    $ref: ./resources/auto/v2-nav-article.yaml
+  '/v2/nav-article/{nav_article}':
+    $ref: ./resources/auto/v2-nav-article-nav-article.yaml
+  /v2/nav-cs-para:
+    $ref: ./resources/auto/v2-nav-cs-para.yaml
+  '/v2/nav-cs-para/{nav_cs_para}':
+    $ref: ./resources/auto/v2-nav-cs-para-nav-cs-para.yaml
+  /v2/nav-page:
+    $ref: ./resources/auto/v2-nav-page.yaml
+  '/v2/nav-page/{nav_page}':
+    $ref: ./resources/auto/v2-nav-page-nav-page.yaml
+  /v2/nissaya-card:
+    $ref: ./resources/auto/v2-nissaya-card.yaml
+  '/v2/nissaya-card/{nissaya_card}':
+    $ref: ./resources/auto/v2-nissaya-card-nissaya-card.yaml
+  /v2/nissaya-cover:
+    $ref: ./resources/auto/v2-nissaya-cover.yaml
+  '/v2/nissaya-cover/{nissaya_cover}':
+    $ref: ./resources/auto/v2-nissaya-cover-nissaya-cover.yaml
+  /v2/nissaya-ending:
+    $ref: ./resources/auto/v2-nissaya-ending.yaml
+  /v2/nissaya-ending-export:
+    $ref: ./resources/auto/v2-nissaya-ending-export.yaml
+  /v2/nissaya-ending-import:
+    $ref: ./resources/auto/v2-nissaya-ending-import.yaml
+  /v2/nissaya-ending-vocabulary:
+    $ref: ./resources/auto/v2-nissaya-ending-vocabulary.yaml
+  '/v2/nissaya-ending/{nissaya_ending}':
+    $ref: ./resources/auto/v2-nissaya-ending-nissaya-ending.yaml
+  /v2/notification:
+    $ref: ./resources/auto/v2-notification.yaml
+  '/v2/notification/{notification}':
+    $ref: ./resources/auto/v2-notification-notification.yaml
+  /v2/offline-index:
+    $ref: ./resources/auto/v2-offline-index.yaml
+  '/v2/offline-index/{offline_index}':
+    $ref: ./resources/auto/v2-offline-index-offline-index.yaml
+  /v2/pali-book-category:
+    $ref: ./resources/auto/v2-pali-book-category.yaml
+  '/v2/pali-book-category/{pali_book_category}':
+    $ref: ./resources/auto/v2-pali-book-category-pali-book-category.yaml
+  /v2/pali-search-data:
+    $ref: ./resources/auto/v2-pali-search-data.yaml
+  '/v2/pali-search-data/{pali_search_datum}':
+    $ref: ./resources/auto/v2-pali-search-data-pali-search-datum.yaml
+  /v2/pali-word-index:
+    $ref: ./resources/auto/v2-pali-word-index.yaml
+  '/v2/pali-word-index/{pali_word_index}':
+    $ref: ./resources/auto/v2-pali-word-index-pali-word-index.yaml
+  /v2/palitext:
+    $ref: ./resources/auto/v2-palitext.yaml
+  '/v2/palitext/{palitext}':
+    $ref: ./resources/auto/v2-palitext-palitext.yaml
+  /v2/para-info:
+    $ref: ./resources/auto/v2-para-info.yaml
+  '/v2/para-info/{para_info}':
+    $ref: ./resources/auto/v2-para-info-para-info.yaml
+  /v2/paragraph-content:
+    $ref: ./resources/auto/v2-paragraph-content.yaml
+  '/v2/paragraph-content/{paragraph_content}':
+    $ref: ./resources/auto/v2-paragraph-content-paragraph-content.yaml
+  /v2/pg-pali-dict-download:
+    $ref: ./resources/auto/v2-pg-pali-dict-download.yaml
+  '/v2/pg-pali-dict-download/{pg_pali_dict_download}':
+    $ref: ./resources/auto/v2-pg-pali-dict-download-pg-pali-dict-download.yaml
+  /v2/progress:
+    $ref: ./resources/auto/v2-progress.yaml
+  /v2/progress-img:
+    $ref: ./resources/auto/v2-progress-img.yaml
+  '/v2/progress-img/{progress_img}':
+    $ref: ./resources/auto/v2-progress-img-progress-img.yaml
+  '/v2/progress/{progress}':
+    $ref: ./resources/auto/v2-progress-progress.yaml
+  /v2/project:
+    $ref: ./resources/auto/v2-project.yaml
+  /v2/project-tree:
+    $ref: ./resources/auto/v2-project-tree.yaml
+  '/v2/project-tree/{project_tree}':
+    $ref: ./resources/auto/v2-project-tree-project-tree.yaml
+  '/v2/project/{project}':
+    $ref: ./resources/auto/v2-project-project.yaml
+  /v2/recent:
+    $ref: ./resources/auto/v2-recent.yaml
+  '/v2/recent/{recent}':
+    $ref: ./resources/auto/v2-recent-recent.yaml
+  /v2/related-paragraph:
+    $ref: ./resources/auto/v2-related-paragraph.yaml
+  '/v2/related-paragraph/{related_paragraph}':
+    $ref: ./resources/auto/v2-related-paragraph-related-paragraph.yaml
+  /v2/relation:
+    $ref: ./resources/auto/v2-relation.yaml
+  /v2/relation-export:
+    $ref: ./resources/auto/v2-relation-export.yaml
+  /v2/relation-import:
+    $ref: ./resources/auto/v2-relation-import.yaml
+  '/v2/relation/{relation}':
+    $ref: ./resources/auto/v2-relation-relation.yaml
+  /v2/search:
+    $ref: ./resources/auto/v2-search.yaml
+  /v2/search-book-list:
+    $ref: ./resources/auto/v2-search-book-list.yaml
+  /v2/search-page-number:
+    $ref: ./resources/auto/v2-search-page-number.yaml
+  '/v2/search-page-number/{search_page_number}':
+    $ref: ./resources/auto/v2-search-page-number-search-page-number.yaml
+  /v2/search-pali-wbw:
+    $ref: ./resources/auto/v2-search-pali-wbw.yaml
+  /v2/search-pali-wbw-books:
+    $ref: ./resources/auto/v2-search-pali-wbw-books.yaml
+  '/v2/search-pali-wbw/{search_pali_wbw}':
+    $ref: ./resources/auto/v2-search-pali-wbw-search-pali-wbw.yaml
+  /v2/search-title-index:
+    $ref: ./resources/auto/v2-search-title-index.yaml
+  '/v2/search-title-index/{search_title_index}':
+    $ref: ./resources/auto/v2-search-title-index-search-title-index.yaml
+  /v2/search-word-slice:
+    $ref: ./resources/auto/v2-search-word-slice.yaml
+  '/v2/search-word-slice/{search_word_slouse}':
+    $ref: ./resources/auto/v2-search-word-slice-search-word-slouse.yaml
+  '/v2/search/{search}':
+    $ref: ./resources/auto/v2-search-search.yaml
+  /v2/sent-discussion-tree:
+    $ref: ./resources/auto/v2-sent-discussion-tree.yaml
+  /v2/sent-in-channel:
+    $ref: ./resources/auto/v2-sent-in-channel.yaml
+  '/v2/sent-in-channel/{sent_in_channel}':
+    $ref: ./resources/auto/v2-sent-in-channel-sent-in-channel.yaml
+  /v2/sent-pr-tree:
+    $ref: ./resources/auto/v2-sent-pr-tree.yaml
+  /v2/sent-sim:
+    $ref: ./resources/auto/v2-sent-sim.yaml
+  '/v2/sent-sim/{sent_sim}':
+    $ref: ./resources/auto/v2-sent-sim-sent-sim.yaml
+  /v2/sent_history:
+    $ref: ./resources/auto/v2-sent-history.yaml
+  '/v2/sent_history/{sent_history}':
+    $ref: ./resources/auto/v2-sent-history-sent-history.yaml
+  /v2/sent_history_contribution:
+    $ref: ./resources/auto/v2-sent-history-contribution.yaml
+  /v2/sentence:
+    $ref: ./resources/auto/v2-sentence.yaml
+  /v2/sentence-attachment:
+    $ref: ./resources/auto/v2-sentence-attachment.yaml
+  '/v2/sentence-attachment/{sentence_attachment}':
+    $ref: ./resources/auto/v2-sentence-attachment-sentence-attachment.yaml
+  /v2/sentence-info:
+    $ref: ./resources/auto/v2-sentence-info.yaml
+  '/v2/sentence-info/{sentence_info}':
+    $ref: ./resources/auto/v2-sentence-info-sentence-info.yaml
+  /v2/sentence-io:
+    $ref: ./resources/auto/v2-sentence-io.yaml
+  '/v2/sentence-io/{sentence_io}':
+    $ref: ./resources/auto/v2-sentence-io-sentence-io.yaml
+  '/v2/sentence/{sentence}':
+    $ref: ./resources/auto/v2-sentence-sentence.yaml
+  /v2/sentences-in-chapter:
+    $ref: ./resources/auto/v2-sentences-in-chapter.yaml
+  '/v2/sentences-in-chapter/{sentences_in_chapter}':
+    $ref: ./resources/auto/v2-sentences-in-chapter-sentences-in-chapter.yaml
+  /v2/sentpr:
+    $ref: ./resources/auto/v2-sentpr.yaml
+  '/v2/sentpr/{sentpr}':
+    $ref: ./resources/auto/v2-sentpr-sentpr.yaml
+  /v2/share:
+    $ref: ./resources/auto/v2-share.yaml
+  '/v2/share/{share}':
+    $ref: ./resources/auto/v2-share-share.yaml
+  /v2/sign-in:
+    $ref: ./resources/auto/v2-sign-in.yaml
+  /v2/sign-up:
+    $ref: ./resources/auto/v2-sign-up.yaml
+  '/v2/sign-up/{sign_up}':
+    $ref: ./resources/auto/v2-sign-up-sign-up.yaml
+  /v2/site-info:
+    $ref: ./resources/auto/v2-site-info.yaml
+  '/v2/site-info/{site_info}':
+    $ref: ./resources/auto/v2-site-info-site-info.yaml
+  /v2/snowflake:
+    $ref: ./resources/auto/v2-snowflake.yaml
+  '/v2/snowflake/{snowflake}':
+    $ref: ./resources/auto/v2-snowflake-snowflake.yaml
+  /v2/studio:
+    $ref: ./resources/auto/v2-studio.yaml
+  '/v2/studio/{studio}':
+    $ref: ./resources/auto/v2-studio-studio.yaml
+  /v2/system-model:
+    $ref: ./resources/auto/v2-system-model.yaml
+  '/v2/system-model/{system_model}':
+    $ref: ./resources/auto/v2-system-model-system-model.yaml
+  '/v2/system-term/{lang}/{word}':
+    $ref: ./resources/auto/v2-system-term-lang-word.yaml
+  /v2/tag:
+    $ref: ./resources/auto/v2-tag.yaml
+  /v2/tag-map:
+    $ref: ./resources/auto/v2-tag-map.yaml
+  '/v2/tag-map/{tag_map}':
+    $ref: ./resources/auto/v2-tag-map-tag-map.yaml
+  '/v2/tag/{tag}':
+    $ref: ./resources/auto/v2-tag-tag.yaml
+  /v2/tags-in-chapter:
+    $ref: ./resources/auto/v2-tags-in-chapter.yaml
+  '/v2/tags-in-chapter/{tags_in_chapter}':
+    $ref: ./resources/auto/v2-tags-in-chapter-tags-in-chapter.yaml
+  /v2/task:
+    $ref: ./resources/auto/v2-task.yaml
+  /v2/task-group:
+    $ref: ./resources/auto/v2-task-group.yaml
+  '/v2/task-group/{task_group}':
+    $ref: ./resources/auto/v2-task-group-task-group.yaml
+  /v2/task-status:
+    $ref: ./resources/auto/v2-task-status.yaml
+  '/v2/task-status/{task_status}':
+    $ref: ./resources/auto/v2-task-status-task-status.yaml
+  '/v2/task/{task}':
+    $ref: ./resources/auto/v2-task-task.yaml
+  /v2/term-summary:
+    $ref: ./resources/auto/v2-term-summary.yaml
+  '/v2/term-summary/{term_summary}':
+    $ref: ./resources/auto/v2-term-summary-term-summary.yaml
+  /v2/term-vocabulary:
+    $ref: ./resources/auto/v2-term-vocabulary.yaml
+  '/v2/term-vocabulary/{term_vocabulary}':
+    $ref: ./resources/auto/v2-term-vocabulary-term-vocabulary.yaml
+  /v2/terms:
+    $ref: ./resources/auto/v2-terms.yaml
+  /v2/terms-export:
+    $ref: ./resources/auto/v2-terms-export.yaml
+  '/v2/terms-export/{terms_export}':
+    $ref: ./resources/auto/v2-terms-export-terms-export.yaml
+  /v2/terms-import:
+    $ref: ./resources/auto/v2-terms-import.yaml
+  '/v2/terms/{term}':
+    $ref: ./resources/auto/v2-terms-term.yaml
+  /v2/tipitaka-content:
+    $ref: ./resources/auto/v2-tipitaka-content.yaml
+  '/v2/tipitaka-content/{tipitaka_content}':
+    $ref: ./resources/auto/v2-tipitaka-content-tipitaka-content.yaml
+  /v2/transfer:
+    $ref: ./resources/auto/v2-transfer.yaml
+  '/v2/transfer/{transfer}':
+    $ref: ./resources/auto/v2-transfer-transfer.yaml
+  /v2/user:
+    $ref: ./resources/auto/v2-user.yaml
+  /v2/user-milestone:
+    $ref: ./resources/auto/v2-user-milestone.yaml
+  '/v2/user-milestone/{user_milestone}':
+    $ref: ./resources/auto/v2-user-milestone-user-milestone.yaml
+  /v2/user-operation-daily:
+    $ref: ./resources/auto/v2-user-operation-daily.yaml
+  '/v2/user-operation-daily/{user_operation_daily}':
+    $ref: ./resources/auto/v2-user-operation-daily-user-operation-daily.yaml
+  /v2/user-statistic:
+    $ref: ./resources/auto/v2-user-statistic.yaml
+  '/v2/user-statistic/{user_statistic}':
+    $ref: ./resources/auto/v2-user-statistic-user-statistic.yaml
+  '/v2/user/{user}':
+    $ref: ./resources/auto/v2-user-user.yaml
+  /v2/userdict:
+    $ref: ./resources/auto/v2-userdict.yaml
+  '/v2/userdict/{userdict}':
+    $ref: ./resources/auto/v2-userdict-userdict.yaml
+  /v2/view:
+    $ref: ./resources/auto/v2-view.yaml
+  '/v2/view/{view}':
+    $ref: ./resources/auto/v2-view-view.yaml
+  /v2/vocabulary:
+    $ref: ./resources/auto/v2-vocabulary.yaml
+  '/v2/vocabulary/{vocabulary}':
+    $ref: ./resources/auto/v2-vocabulary-vocabulary.yaml
+  /v2/wbw:
+    $ref: ./resources/auto/v2-wbw.yaml
+  /v2/wbw-sentence:
+    $ref: ./resources/auto/v2-wbw-sentence.yaml
+  '/v2/wbw-sentence/{wbw_sentence}':
+    $ref: ./resources/auto/v2-wbw-sentence-wbw-sentence.yaml
+  '/v2/wbw/{wbw}':
+    $ref: ./resources/auto/v2-wbw-wbw.yaml
+  /v2/wbw_templates:
+    $ref: ./resources/auto/v2-wbw-templates.yaml
+  '/v2/wbw_templates/{wbw_template}':
+    $ref: ./resources/auto/v2-wbw-templates-wbw-template.yaml
+  /v2/wbwlookup:
+    $ref: ./resources/auto/v2-wbwlookup.yaml
+  '/v2/wbwlookup/{wbwlookup}':
+    $ref: ./resources/auto/v2-wbwlookup-wbwlookup.yaml
+  /v2/webhook:
+    $ref: ./resources/auto/v2-webhook.yaml
+  '/v2/webhook/{webhook}':
+    $ref: ./resources/auto/v2-webhook-webhook.yaml
+  /v3/progress:
+    $ref: ./resources/auto/v3-progress.yaml
+  '/v3/progress/{progress}':
+    $ref: ./resources/auto/v3-progress-progress.yaml
+  /v3/search:
+    $ref: ./resources/auto/v3-search.yaml
+  /v3/search-suggest:
+    $ref: ./resources/auto/v3-search-suggest.yaml
+  '/v3/search-suggest/{search_suggest}':
+    $ref: ./resources/auto/v3-search-suggest-search-suggest.yaml
+  '/v3/search/{search}':
+    $ref: ./resources/auto/v3-search-search.yaml
+  /v3/tipitaka-read-chapter:
+    $ref: ./resources/auto/v3-tipitaka-read-chapter.yaml
+  '/v3/tipitaka-read-chapter/{tipitaka_read_chapter}':
+    $ref: ./resources/auto/v3-tipitaka-read-chapter-tipitaka-read-chapter.yaml
+  /v3/tipitaka-read-para:
+    $ref: ./resources/auto/v3-tipitaka-read-para.yaml
+  '/v3/tipitaka-read-para/{tipitaka_read_para}':
+    $ref: ./resources/auto/v3-tipitaka-read-para-tipitaka-read-para.yaml
+  /v3/upgrade:
+    $ref: ./resources/auto/v3-upgrade.yaml
+  '/v3/upgrade/{upgrade}':
+    $ref: ./resources/auto/v3-upgrade-upgrade.yaml

+ 14 - 0
openapi/public/assets/protocol/overrides/README.md

@@ -0,0 +1,14 @@
+# 手写补充
+
+`resources/auto/` 全部由 `openapi/scripts/generate.php` 自动生成,重跑会覆盖。
+
+**首选做法不是在这里写 YAML**,而是把参数说明写进控制器的文档注释
+(`@queryParam` / `@bodyParam` / `@urlParam`,见 `openapi/README.md`),
+那样说明离代码最近,改接口时不容易忘记同步。
+
+这里只放不适合写进 PHP 注释的东西:长篇示例响应、跨接口的补充说明等。
+建同名文件(例如 `v2-channel.yaml`),内容按 OpenAPI Path Item 结构写,
+生成时深度合并到自动结果之上。
+
+合并规则:同名键以 overrides 为准,**数组整体替换**。所以在这里写 `parameters`
+会覆盖掉自动生成的全部参数,通常不是你想要的。

+ 0 - 13
openapi/public/assets/protocol/resources/auth/users/index.yaml

@@ -1,13 +0,0 @@
-get:
-  summary: Returns a list of users.
-  tags:
-    - auth
-  responses:
-    "200":
-      description: A JSON array of user names
-      content:
-        application/json:
-          schema:
-            type: array
-            items:
-              type: string

+ 0 - 13
openapi/public/assets/protocol/resources/auth/users/sign-in.yaml

@@ -1,13 +0,0 @@
-post:
-  summary: Sign in.
-  tags:
-    - auth
-  responses:
-    "200": # status code
-      description: A JSON array of user names
-      content:
-        application/json:
-          schema:
-            type: array
-            items:
-              type: string

+ 56 - 0
openapi/public/assets/protocol/resources/auto/api-sentence-progress-daily-image.yaml

@@ -0,0 +1,56 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/api-sentence-progress-daily-image.yaml
+get:
+  summary: 'showprogressdaily api/api/sentence/progress/daily/image'
+  tags:
+    - api
+  operationId: get_api_api_sentence_progress_daily_image
+  description: 实现:`SentenceInfoController@showprogressdaily`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+    -
+      name: type
+      in: query
+      schema:
+        type: string
+    -
+      name: channel
+      in: query
+      schema:
+        type: string
+    -
+      name: from
+      in: query
+      schema:
+        type: string
+    -
+      name: to
+      in: query
+      schema:
+        type: string
+    -
+      name: book
+      in: query
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 38 - 0
openapi/public/assets/protocol/resources/auto/api-sentence-progress-image.yaml

@@ -0,0 +1,38 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/api-sentence-progress-image.yaml
+get:
+  summary: 输出一张图片显示进度
+  tags:
+    - api
+  operationId: get_api_api_sentence_progress_image
+  description: |-
+    http://127.0.0.1:8000/api/sentence/progress/image?channel=00ae2c48-c204-4082-ae79-79ba2740d506&&book=168&from=916&to=926&view=page&pages=400
+
+    实现:`SentenceInfoController@showprogress`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - percent
+          - strlen
+          - page
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 37 - 0
openapi/public/assets/protocol/resources/auto/ops-update-pali-synonyms-version.yaml

@@ -0,0 +1,37 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/ops-update-pali-synonyms-version.yaml
+put:
+  summary: '更新索引使用的 pali 同义词文件版本'
+  tags:
+    - update-pali-synonyms
+  operationId: put_api_ops_update_pali_synonyms_version_
+  description: |-
+    将 pali_synonyms filter 的 synonyms_path 指向
+    analysis/pali-synonyms-{$version}.txt,该文件须已上传到
+    OpenSearch 各节点的 config 目录。
+
+    实现:`UpdatePaliSynonymsController@update`
+  parameters:
+    -
+      name: version
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-access-token-access-token.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-access-token-access-token.yaml
+get:
+  summary: '获取单个 access-token/{access_token}'
+  tags:
+    - access-token
+  operationId: get_api_v2_access_token_access_token_
+  description: 实现:`AccessTokenController@show`
+  parameters:
+    -
+      name: access_token
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 access-token/{access_token}'
+  tags:
+    - access-token
+  operationId: put_api_v2_access_token_access_token_
+  description: 实现:`AccessTokenController@update`
+  parameters:
+    -
+      name: access_token
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 access-token/{access_token}'
+  tags:
+    - access-token
+  operationId: patch_api_v2_access_token_access_token_
+  description: 实现:`AccessTokenController@update`
+  parameters:
+    -
+      name: access_token
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 access-token/{access_token}'
+  tags:
+    - access-token
+  operationId: delete_api_v2_access_token_access_token_
+  description: 实现:`AccessTokenController@destroy`
+  parameters:
+    -
+      name: access_token
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 99 - 0
openapi/public/assets/protocol/resources/auto/v2-access-token.yaml

@@ -0,0 +1,99 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-access-token.yaml
+get:
+  summary: '列出 access-token'
+  tags:
+    - access-token
+  operationId: get_api_v2_access_token
+  description: 实现:`AccessTokenController@index`
+  parameters:
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 access-token'
+  tags:
+    - access-token
+  operationId: post_api_v2_access_token
+  description: 实现:`AccessTokenController@store`
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            payload:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-ai-assistant-ai-assistant.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-ai-assistant-ai-assistant.yaml
+get:
+  summary: '获取单个 ai-assistant/{ai_assistant}'
+  tags:
+    - ai-assistant
+  operationId: get_api_v2_ai_assistant_ai_assistant_
+  description: 实现:`AiAssistantController@show`
+  parameters:
+    -
+      name: ai_assistant
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 ai-assistant/{ai_assistant}'
+  tags:
+    - ai-assistant
+  operationId: put_api_v2_ai_assistant_ai_assistant_
+  description: 实现:`AiAssistantController@update`
+  parameters:
+    -
+      name: ai_assistant
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 ai-assistant/{ai_assistant}'
+  tags:
+    - ai-assistant
+  operationId: patch_api_v2_ai_assistant_ai_assistant_
+  description: 实现:`AiAssistantController@update`
+  parameters:
+    -
+      name: ai_assistant
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 ai-assistant/{ai_assistant}'
+  tags:
+    - ai-assistant
+  operationId: delete_api_v2_ai_assistant_ai_assistant_
+  description: 实现:`AiAssistantController@destroy`
+  parameters:
+    -
+      name: ai_assistant
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 90 - 0
openapi/public/assets/protocol/resources/auto/v2-ai-assistant.yaml

@@ -0,0 +1,90 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-ai-assistant.yaml
+get:
+  summary: '列出 ai-assistant'
+  tags:
+    - ai-assistant
+  operationId: get_api_v2_ai_assistant
+  description: 实现:`AiAssistantController@index`
+  parameters:
+    -
+      name: keyword
+      in: query
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      schema:
+        type: string
+        default: created_at
+    -
+      name: dir
+      in: query
+      schema:
+        type: string
+        default: asc
+    -
+      name: offset
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 ai-assistant'
+  tags:
+    - ai-assistant
+  operationId: post_api_v2_ai_assistant
+  description: 实现:`AiAssistantController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 143 - 0
openapi/public/assets/protocol/resources/auto/v2-ai-model-ai-model.yaml

@@ -0,0 +1,143 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-ai-model-ai-model.yaml
+get:
+  summary: '获取单个 ai-model/{ai_model}'
+  tags:
+    - ai-model
+  operationId: get_api_v2_ai_model_ai_model_
+  description: 实现:`AiModelController@show`
+  parameters:
+    -
+      name: ai_model
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 ai-model/{ai_model}'
+  tags:
+    - ai-model
+  operationId: put_api_v2_ai_model_ai_model_
+  description: 实现:`AiModelController@update`
+  parameters:
+    -
+      name: ai_model
+      in: path
+      required: true
+      schema:
+        type: string
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            name:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 ai-model/{ai_model}'
+  tags:
+    - ai-model
+  operationId: patch_api_v2_ai_model_ai_model_
+  description: 实现:`AiModelController@update`
+  parameters:
+    -
+      name: ai_model
+      in: path
+      required: true
+      schema:
+        type: string
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            name:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 ai-model/{ai_model}'
+  tags:
+    - ai-model
+  operationId: delete_api_v2_ai_model_ai_model_
+  description: 实现:`AiModelController@destroy`
+  parameters:
+    -
+      name: ai_model
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 71 - 0
openapi/public/assets/protocol/resources/auto/v2-ai-model-token-ai-model.yaml

@@ -0,0 +1,71 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-ai-model-token-ai-model.yaml
+get:
+  summary: '取得指定 AI 模型的 user token。'
+  tags:
+    - ai-model-token
+  operationId: get_api_v2_ai_model_token_ai_model_
+  description: |-
+    仅模型 owner 本人可调用(设计决策:模型只挂个人 studio,不支持 group studio)。
+    签出的 token 有效期 30 天,可用 destroy() 提前撤销;属高敏感凭据,故记入 ops 日志。
+
+    实现:`AiModelTokenController@show`
+  parameters:
+    -
+      name: ai_model
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '撤销该模型已签出的全部身份 token。'
+  tags:
+    - ai-model-token
+  operationId: delete_api_v2_ai_model_token_ai_model_
+  description: |-
+    版本号自增后,旧 token 里的 ver 立即对不上(见 AuthService::current())。
+    无法只撤销其中一张——凭据泄漏时本就该全部作废。
+
+    实现:`AiModelTokenController@destroy`
+  parameters:
+    -
+      name: ai_model
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 124 - 0
openapi/public/assets/protocol/resources/auto/v2-ai-model.yaml

@@ -0,0 +1,124 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-ai-model.yaml
+get:
+  summary: '列出 ai-model'
+  tags:
+    - ai-model
+  operationId: get_api_v2_ai_model
+  description: 实现:`AiModelController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - all
+          - studio
+          - usable
+          - chat
+    -
+      name: name
+      in: query
+      schema:
+        type: string
+    -
+      name: user_id
+      in: query
+      schema:
+        type: string
+    -
+      name: keyword
+      in: query
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      schema:
+        type: string
+        default: created_at
+    -
+      name: dir
+      in: query
+      schema:
+        type: string
+        default: asc
+    -
+      name: offset
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 ai-model'
+  tags:
+    - ai-model
+  operationId: post_api_v2_ai_model
+  description: 实现:`AiModelController@store`
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            studio_name:
+              type: string
+            name:
+              type: string
+            privacy:
+              type: string
+              default: private
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 130 - 0
openapi/public/assets/protocol/resources/auto/v2-ai-translate-ai-translate.yaml

@@ -0,0 +1,130 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-ai-translate-ai-translate.yaml
+get:
+  summary: '获取单个 ai-translate/{ai_translate}'
+  tags:
+    - ai-translate
+  operationId: get_api_v2_ai_translate_ai_translate_
+  description: 实现:`AiTranslateController@show`
+  parameters:
+    -
+      name: ai_translate
+      in: path
+      required: true
+      schema:
+        type: string
+    -
+      name: engin
+      in: query
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 ai-translate/{ai_translate}'
+  tags:
+    - ai-translate
+  operationId: put_api_v2_ai_translate_ai_translate_
+  description: 实现:`AiTranslateController@update`
+  parameters:
+    -
+      name: ai_translate
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 ai-translate/{ai_translate}'
+  tags:
+    - ai-translate
+  operationId: patch_api_v2_ai_translate_ai_translate_
+  description: 实现:`AiTranslateController@update`
+  parameters:
+    -
+      name: ai_translate
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 ai-translate/{ai_translate}'
+  tags:
+    - ai-translate
+  operationId: delete_api_v2_ai_translate_ai_translate_
+  description: 实现:`AiTranslateController@destroy`
+  parameters:
+    -
+      name: ai_translate
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 99 - 0
openapi/public/assets/protocol/resources/auto/v2-ai-translate.yaml

@@ -0,0 +1,99 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-ai-translate.yaml
+get:
+  summary: '列出 ai-translate'
+  tags:
+    - ai-translate
+  operationId: get_api_v2_ai_translate
+  description: 实现:`AiTranslateController@index`
+  parameters:
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 ai-translate'
+  tags:
+    - ai-translate
+  operationId: post_api_v2_ai_translate
+  description: 实现:`AiTranslateController@store`
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            origin:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 167 - 0
openapi/public/assets/protocol/resources/auto/v2-anthology-anthology.yaml

@@ -0,0 +1,167 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-anthology-anthology.yaml
+get:
+  summary: '获取单个 anthology/{anthology}'
+  tags:
+    - anthology
+  operationId: get_api_v2_anthology_anthology_
+  description: 实现:`CollectionController@show`
+  parameters:
+    -
+      name: anthology
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 anthology/{anthology}'
+  tags:
+    - anthology
+  operationId: put_api_v2_anthology_anthology_
+  description: 实现:`CollectionController@update`
+  parameters:
+    -
+      name: anthology
+      in: path
+      required: true
+      schema:
+        type: string
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            title:
+              type: string
+            subtitle:
+              type: string
+            summary:
+              type: string
+            lang:
+              type: string
+            status:
+              type: string
+            default_channel:
+              type: string
+            aritcle_list:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 anthology/{anthology}'
+  tags:
+    - anthology
+  operationId: patch_api_v2_anthology_anthology_
+  description: 实现:`CollectionController@update`
+  parameters:
+    -
+      name: anthology
+      in: path
+      required: true
+      schema:
+        type: string
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            title:
+              type: string
+            subtitle:
+              type: string
+            summary:
+              type: string
+            lang:
+              type: string
+            status:
+              type: string
+            default_channel:
+              type: string
+            aritcle_list:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 anthology/{anthology}'
+  tags:
+    - anthology
+  operationId: delete_api_v2_anthology_anthology_
+  description: 实现:`CollectionController@destroy`
+  parameters:
+    -
+      name: anthology
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 25 - 0
openapi/public/assets/protocol/resources/auto/v2-anthology-my-number.yaml

@@ -0,0 +1,25 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-anthology-my-number.yaml
+get:
+  summary: 'showMyNumber anthology-my-number'
+  tags:
+    - anthology-my-number
+  operationId: get_api_v2_anthology_my_number
+  description: 实现:`CollectionController@showMyNumber`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 105 - 0
openapi/public/assets/protocol/resources/auto/v2-anthology.yaml

@@ -0,0 +1,105 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-anthology.yaml
+get:
+  summary: '列出 anthology'
+  tags:
+    - anthology
+  operationId: get_api_v2_anthology
+  description: 实现:`CollectionController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+    -
+      name: studio
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      schema:
+        type: string
+    -
+      name: offset
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 anthology'
+  tags:
+    - anthology
+  operationId: post_api_v2_anthology
+  description: 实现:`CollectionController@store`
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            studio:
+              type: string
+            title:
+              type: string
+            lang:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 154 - 0
openapi/public/assets/protocol/resources/auto/v2-api-api.yaml

@@ -0,0 +1,154 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-api-api.yaml
+get:
+  summary: '获取单个 api/{api}'
+  tags:
+    - api
+  operationId: get_api_v2_api_api_
+  description: 实现:`ApiController@show`
+  parameters:
+    -
+      name: api
+      in: path
+      required: true
+      schema:
+        type: string
+    -
+      name: item
+      in: query
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 api/{api}'
+  tags:
+    - api
+  operationId: put_api_v2_api_api_
+  description: 实现:`ApiController@update`
+  parameters:
+    -
+      name: api
+      in: path
+      required: true
+      schema:
+        type: string
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            api:
+              type: string
+              default: all
+            item:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 api/{api}'
+  tags:
+    - api
+  operationId: patch_api_v2_api_api_
+  description: 实现:`ApiController@update`
+  parameters:
+    -
+      name: api
+      in: path
+      required: true
+      schema:
+        type: string
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            api:
+              type: string
+              default: all
+            item:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 api/{api}'
+  tags:
+    - api
+  operationId: delete_api_v2_api_api_
+  description: 实现:`ApiController@destroy`
+  parameters:
+    -
+      name: api
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 90 - 0
openapi/public/assets/protocol/resources/auto/v2-api.yaml

@@ -0,0 +1,90 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-api.yaml
+get:
+  summary: '列出 api'
+  tags:
+    - api
+  operationId: get_api_v2_api
+  description: 实现:`ApiController@index`
+  parameters:
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 api'
+  tags:
+    - api
+  operationId: post_api_v2_api
+  description: 实现:`ApiController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 238 - 0
openapi/public/assets/protocol/resources/auto/v2-article-article.yaml

@@ -0,0 +1,238 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-article-article.yaml
+get:
+  summary: '查看单篇 article(文章)'
+  tags:
+    - article
+  operationId: get_api_v2_article_article_
+  description: |-
+    前端阅读页最常用的接口。允许匿名访问:status=30(公开)的文章任何人可读;
+    非公开文章需要登录,且满足以下之一——是文章 owner、对该文章有只读以上共享权限(power>=10)、
+    或对该文章所在的(同一 owner 的)文集有只读以上共享权限,否则返回 403。
+
+    实现:`ArticleController@show`
+  parameters:
+    -
+      name: article
+      in: path
+      required: true
+      schema:
+        type: string
+      description: '文章 uid(路由模型绑定到 Article,主键即 uid)'
+    -
+      name: anthology
+      in: query
+      schema:
+        type: string
+      description: '所在文集 uid,用于在返回结果里渲染文集路径(path)'
+    -
+      name: channel
+      in: query
+      schema:
+        type: string
+      description: '渲染标题所用的 channel uid,多个用下划线分隔;不传则回退到文集的默认 channel'
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 article(文章)'
+  tags:
+    - article
+  operationId: put_api_v2_article_article_
+  description: |-
+    需要登录。权限:必须是文章 owner,或对文章有编辑以上共享权限(power>=20),
+    或对文章所在的同 owner 文集有编辑以上权限,否则返回 401。
+    字段会整体覆盖:title/subtitle 截断到 128 字,summary 截断到 1024 字,
+    status 未传时会被重置为 10(非公开),即部分更新也必须带全字段。
+    副作用:to_tpl=true 时把正文转成模版——按行切句,正文中的句子被替换成 {{book-para-start-end}} 占位,
+    同时把原文逐句写入 sentences 表(必要时为文集新建 CustomBook 与 channel),该过程需要对应 channel 的写权限。
+
+    实现:`ArticleController@update`
+  parameters:
+    -
+      name: article
+      in: path
+      required: true
+      schema:
+        type: string
+      description: '文章 uid(路由模型绑定)'
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            content:
+              type: string
+              description: 正文(markdown)
+            to_tpl:
+              type: boolean
+              description: '是否把正文转换为模版并把原文切句入库,必须是布尔 true 才生效'
+            anthology_id:
+              type: string
+              description: 'to_tpl=true 时必填,文集 uid,用于定位/创建书号与 channel'
+            title:
+              type: string
+              description: '标题,最多 128 字'
+            subtitle:
+              type: string
+              description: '副标题,最多 128 字'
+            summary:
+              type: string
+              description: '摘要,最多 1024 字'
+            lang:
+              type: string
+              description: 语言代码
+            status:
+              type: integer
+              description: '公开状态,30 表示公开'
+              default: '10'
+          required:
+            - title
+            - content
+            - lang
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 article(文章)'
+  tags:
+    - article
+  operationId: patch_api_v2_article_article_
+  description: |-
+    需要登录。权限:必须是文章 owner,或对文章有编辑以上共享权限(power>=20),
+    或对文章所在的同 owner 文集有编辑以上权限,否则返回 401。
+    字段会整体覆盖:title/subtitle 截断到 128 字,summary 截断到 1024 字,
+    status 未传时会被重置为 10(非公开),即部分更新也必须带全字段。
+    副作用:to_tpl=true 时把正文转成模版——按行切句,正文中的句子被替换成 {{book-para-start-end}} 占位,
+    同时把原文逐句写入 sentences 表(必要时为文集新建 CustomBook 与 channel),该过程需要对应 channel 的写权限。
+
+    实现:`ArticleController@update`
+  parameters:
+    -
+      name: article
+      in: path
+      required: true
+      schema:
+        type: string
+      description: '文章 uid(路由模型绑定)'
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            content:
+              type: string
+              description: 正文(markdown)
+            to_tpl:
+              type: boolean
+              description: '是否把正文转换为模版并把原文切句入库,必须是布尔 true 才生效'
+            anthology_id:
+              type: string
+              description: 'to_tpl=true 时必填,文集 uid,用于定位/创建书号与 channel'
+            title:
+              type: string
+              description: '标题,最多 128 字'
+            subtitle:
+              type: string
+              description: '副标题,最多 128 字'
+            summary:
+              type: string
+              description: '摘要,最多 1024 字'
+            lang:
+              type: string
+              description: 语言代码
+            status:
+              type: integer
+              description: '公开状态,30 表示公开'
+              default: '10'
+          required:
+            - title
+            - content
+            - lang
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 article(文章)'
+  tags:
+    - article
+  operationId: delete_api_v2_article_article_
+  description: |-
+    需要登录,且只有文章 owner 本人可以删除(协作者不行),否则返回鉴权失败。
+    副作用:在事务中删除文章记录,并同步把该文章从所有文集目录(article_collections)中摘除。
+
+    实现:`ArticleController@destroy`
+  parameters:
+    -
+      name: article
+      in: path
+      required: true
+      schema:
+        type: string
+      description: '文章 uid(路由模型绑定)'
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-article-fts-article-ft.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-article-fts-article-ft.yaml
+get:
+  summary: '获取单个 article-fts/{article_ft}'
+  tags:
+    - article-fts
+  operationId: get_api_v2_article_fts_article_ft_
+  description: 实现:`ArticleFtsController@show`
+  parameters:
+    -
+      name: article_ft
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 article-fts/{article_ft}'
+  tags:
+    - article-fts
+  operationId: put_api_v2_article_fts_article_ft_
+  description: 实现:`ArticleFtsController@update`
+  parameters:
+    -
+      name: article_ft
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 article-fts/{article_ft}'
+  tags:
+    - article-fts
+  operationId: patch_api_v2_article_fts_article_ft_
+  description: 实现:`ArticleFtsController@update`
+  parameters:
+    -
+      name: article_ft
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 article-fts/{article_ft}'
+  tags:
+    - article-fts
+  operationId: delete_api_v2_article_fts_article_ft_
+  description: 实现:`ArticleFtsController@destroy`
+  parameters:
+    -
+      name: article_ft
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 115 - 0
openapi/public/assets/protocol/resources/auto/v2-article-fts.yaml

@@ -0,0 +1,115 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-article-fts.yaml
+get:
+  summary: 'http://127.0.0.1:8000/api/v2/article-fts?id=df6c6609-6fc1-42d0-9ef1-535ef3e702c9&anthology=697c9169-cb9d-4a60-8848-92745e467bab&channesl=7fea264d-7a26-40f8-bef7-bc95102760fb'
+  tags:
+    - article-fts
+  operationId: get_api_v2_article_fts
+  description: 实现:`ArticleFtsController@index`
+  parameters:
+    -
+      name: from
+      in: query
+      schema:
+        type: string
+    -
+      name: anthology
+      in: query
+      schema:
+        type: string
+    -
+      name: id
+      in: query
+      schema:
+        type: string
+    -
+      name: channels
+      in: query
+      schema:
+        type: string
+    -
+      name: key
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 article-fts'
+  tags:
+    - article-fts
+  operationId: post_api_v2_article_fts
+  description: 实现:`ArticleFtsController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 153 - 0
openapi/public/assets/protocol/resources/auto/v2-article-map-article-map.yaml

@@ -0,0 +1,153 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-article-map-article-map.yaml
+get:
+  summary: '获取单个 article-map/{article_map}'
+  tags:
+    - article-map
+  operationId: get_api_v2_article_map_article_map_
+  description: 实现:`ArticleMapController@show`
+  parameters:
+    -
+      name: article_map
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 article-map/{article_map}'
+  tags:
+    - article-map
+  operationId: put_api_v2_article_map_article_map_
+  description: 实现:`ArticleMapController@update`
+  parameters:
+    -
+      name: article_map
+      in: path
+      required: true
+      schema:
+        type: string
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            operation:
+              type: string
+              description: 规则:required
+            data:
+              type: string
+          required:
+            - operation
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 article-map/{article_map}'
+  tags:
+    - article-map
+  operationId: patch_api_v2_article_map_article_map_
+  description: 实现:`ArticleMapController@update`
+  parameters:
+    -
+      name: article_map
+      in: path
+      required: true
+      schema:
+        type: string
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            operation:
+              type: string
+              description: 规则:required
+            data:
+              type: string
+          required:
+            - operation
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 article-map/{article_map}'
+  tags:
+    - article-map
+  operationId: delete_api_v2_article_map_article_map_
+  description: 实现:`ArticleMapController@destroy`
+  parameters:
+    -
+      name: article_map
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 131 - 0
openapi/public/assets/protocol/resources/auto/v2-article-map.yaml

@@ -0,0 +1,131 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-article-map.yaml
+get:
+  summary: '列出 article-map'
+  tags:
+    - article-map
+  operationId: get_api_v2_article_map
+  description: 实现:`ArticleMapController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - anthology
+          - article
+    -
+      name: id
+      in: query
+      schema:
+        type: string
+    -
+      name: parent
+      in: query
+      schema:
+        type: string
+    -
+      name: lazy
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 article-map'
+  tags:
+    - article-map
+  operationId: post_api_v2_article_map
+  description: 实现:`ArticleMapController@store`
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            anthology_id:
+              type: string
+              description: 规则:required
+            operation:
+              type: string
+              description: 规则:required
+            article_id:
+              type: string
+          required:
+            - anthology_id
+            - operation
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 37 - 0
openapi/public/assets/protocol/resources/auto/v2-article-my-number.yaml

@@ -0,0 +1,37 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-article-my-number.yaml
+get:
+  summary: 统计我的文章数量
+  tags:
+    - article-my-number
+  operationId: get_api_v2_article_my_number
+  description: |-
+    返回指定 studio 下「我的」和「协作的」两类文章条数。
+    需要登录,且当前登录用户必须就是 studio 的拥有者,否则返回鉴权失败。
+
+    实现:`ArticleController@showMyNumber`
+  parameters:
+    -
+      name: studio
+      in: query
+      schema:
+        type: string
+      description: 'studio 名称,必须与当前登录用户一致'
+      required: true
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-article-nav-article-nav.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-article-nav-article-nav.yaml
+get:
+  summary: '获取单个 article-nav/{article_nav}'
+  tags:
+    - article-nav
+  operationId: get_api_v2_article_nav_article_nav_
+  description: 实现:`ArticleNavController@show`
+  parameters:
+    -
+      name: article_nav
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 article-nav/{article_nav}'
+  tags:
+    - article-nav
+  operationId: put_api_v2_article_nav_article_nav_
+  description: 实现:`ArticleNavController@update`
+  parameters:
+    -
+      name: article_nav
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 article-nav/{article_nav}'
+  tags:
+    - article-nav
+  operationId: patch_api_v2_article_nav_article_nav_
+  description: 实现:`ArticleNavController@update`
+  parameters:
+    -
+      name: article_nav
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 article-nav/{article_nav}'
+  tags:
+    - article-nav
+  operationId: delete_api_v2_article_nav_article_nav_
+  description: 实现:`ArticleNavController@destroy`
+  parameters:
+    -
+      name: article_nav
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 103 - 0
openapi/public/assets/protocol/resources/auto/v2-article-nav.yaml

@@ -0,0 +1,103 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-article-nav.yaml
+get:
+  summary: '列出 article-nav'
+  tags:
+    - article-nav
+  operationId: get_api_v2_article_nav
+  description: 实现:`ArticleNavController@index`
+  parameters:
+    -
+      name: type
+      in: query
+      schema:
+        type: string
+        enum:
+          - chapter
+          - para
+    -
+      name: id
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 article-nav'
+  tags:
+    - article-nav
+  operationId: post_api_v2_article_nav
+  description: 实现:`ArticleNavController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 57 - 0
openapi/public/assets/protocol/resources/auto/v2-article-preview-id.yaml

@@ -0,0 +1,57 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-article-preview-id.yaml
+put:
+  summary: 预览文章正文
+  tags:
+    - article-preview
+  operationId: put_api_v2_article_preview_id_
+  description: |-
+    PUT /api/v2/article-preview/{id}。用请求体里的 content 覆盖文章正文后走一遍渲染再返回,
+    不写数据库,用于编辑器里的即时预览。
+    权限与查看文章一致:公开文章匿名可预览,否则需要读权限,无权限返回 401。
+    未传 content 时返回 error('no content'),但 HTTP 状态码仍是 200。
+
+    实现:`ArticleController@preview`
+  parameters:
+    -
+      name: id
+      in: path
+      required: true
+      schema:
+        type: string
+      description: '文章 uid'
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            content:
+              type: string
+              description: 待预览的正文内容(markdown)
+            anthology:
+              type: string
+              description: '所在文集 uid,用于渲染文集路径'
+            channel:
+              type: string
+              description: '渲染所用 channel uid,多个用下划线分隔'
+          required:
+            - content
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-article-progress-article-progress.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-article-progress-article-progress.yaml
+get:
+  summary: '获取单个 article-progress/{article_progress}'
+  tags:
+    - article-progress
+  operationId: get_api_v2_article_progress_article_progress_
+  description: 实现:`ArticleProgressController@show`
+  parameters:
+    -
+      name: article_progress
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 article-progress/{article_progress}'
+  tags:
+    - article-progress
+  operationId: put_api_v2_article_progress_article_progress_
+  description: 实现:`ArticleProgressController@update`
+  parameters:
+    -
+      name: article_progress
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 article-progress/{article_progress}'
+  tags:
+    - article-progress
+  operationId: patch_api_v2_article_progress_article_progress_
+  description: 实现:`ArticleProgressController@update`
+  parameters:
+    -
+      name: article_progress
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 article-progress/{article_progress}'
+  tags:
+    - article-progress
+  operationId: delete_api_v2_article_progress_article_progress_
+  description: 实现:`ArticleProgressController@destroy`
+  parameters:
+    -
+      name: article_progress
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 107 - 0
openapi/public/assets/protocol/resources/auto/v2-article-progress.yaml

@@ -0,0 +1,107 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-article-progress.yaml
+get:
+  summary: '列出 article-progress'
+  tags:
+    - article-progress
+  operationId: get_api_v2_article_progress
+  description: 实现:`ArticleProgressController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - chapter
+    -
+      name: book
+      in: query
+      schema:
+        type: string
+    -
+      name: para
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 article-progress'
+  tags:
+    - article-progress
+  operationId: post_api_v2_article_progress
+  description: 实现:`ArticleProgressController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 191 - 0
openapi/public/assets/protocol/resources/auto/v2-article.yaml

@@ -0,0 +1,191 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-article.yaml
+get:
+  summary: '列出 article(文章)'
+  tags:
+    - article
+  operationId: get_api_v2_article
+  description: |-
+    按 view 指定的口径返回文章列表,支持关键字搜索、分页、排序。
+    默认只返回列表字段(uid、title、subtitle、summary、owner、lang、status、editor_id、时间),
+    content=true 时才附带正文与正文类型。
+    view=studio 需要登录,且当前登录用户必须就是 name 指定的 studio 的拥有者,否则返回 401/403。
+
+    实现:`ArticleController@index`
+  parameters:
+    -
+      name: content
+      in: query
+      schema:
+        type: string
+      description: '是否返回文章正文。传 true 时结果附带 content 与 content_type'
+      example: 'true'
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - template
+          - studio
+          - public
+      description: '查询口径。template=按 studio_name 取该 studio 的全部文章(模版库);studio=取某 studio 内的文章,需要登录;public=只取已公开(status=30)的文章'
+      required: true
+    -
+      name: studio_name
+      in: query
+      schema:
+        type: string
+      description: 'view=template 时使用,指定 studio 的名称'
+    -
+      name: name
+      in: query
+      schema:
+        type: string
+      description: 'view=studio 时使用,指定 studio 的名称,必须与当前登录用户一致'
+    -
+      name: view2
+      in: query
+      schema:
+        type: string
+        default: my
+      description: 'view=studio 时的二级口径:my=我创建的(owner 为该 studio),其余值=协作的(别人共享给我的,res_type=3)'
+    -
+      name: anthology
+      in: query
+      schema:
+        type: string
+        enum:
+          - all
+          - none
+      description: 'view=studio 时按文集过滤。all=不过滤;none=不属于我任何文集的文章;其余值按文集 uid 过滤'
+    -
+      name: search
+      in: query
+      schema:
+        type: string
+      description: '按标题模糊搜索(title like %search%)'
+    -
+      name: subtitle
+      in: query
+      schema:
+        type: string
+      description: '按副标题过滤(subtitle like,需自行带通配符)'
+    -
+      name: order
+      in: query
+      schema:
+        type: string
+        default: updated_at
+      description: 排序字段
+    -
+      name: dir
+      in: query
+      schema:
+        type: string
+        enum:
+          - asc
+          - desc
+        default: desc
+      description: 排序方向
+    -
+      name: offset
+      in: query
+      schema:
+        type: integer
+        default: '0'
+      description: 分页起始位置
+    -
+      name: limit
+      in: query
+      schema:
+        type: integer
+        default: '1000'
+      description: 每页条数
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 article(文章)'
+  tags:
+    - article
+  operationId: post_api_v2_article
+  description: |-
+    需要登录。权限:当前用户必须是 studio 的拥有者;若不是,则必须对 anthologyId 指定的文集
+    拥有大于只读的权限(power>10),否则返回 403。
+    副作用:整个新建过程在事务中执行——写入 articles 表,若给了 anthologyId 则同时把文章挂进文集;
+    若再给了 parentNode,会按目录树重建该文集的 article_collections 记录(删除后整表重插)并刷新文集缓存。
+    标题超过 128 字会被截断。
+
+    实现:`ArticleController@store`
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            studio:
+              type: string
+              description: 'studio 名称,文章归属的 studio'
+            anthologyId:
+              type: string
+              description: '文集 uid,传入则把新文章加入该文集'
+            title:
+              type: string
+              description: '文章标题,最多 128 字,超出截断'
+            lang:
+              type: string
+              description: 文章语言代码
+            status:
+              type: integer
+              description: '公开状态,30 表示公开。不传则用数据库默认值'
+            parentId:
+              type: string
+              description: '父文章 uid,写入 articles.parent'
+            parentNode:
+              type: string
+              description: '文集目录中的挂接点文章 uid,新文章作为它的子节点插入; 不传则作为一级节点(level=1)追加到文集末尾'
+          required:
+            - studio
+            - title
+            - lang
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 148 - 0
openapi/public/assets/protocol/resources/auto/v2-attachment-attachment.yaml

@@ -0,0 +1,148 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-attachment-attachment.yaml
+get:
+  summary: '获取单个 attachment/{attachment}'
+  tags:
+    - attachment
+  operationId: get_api_v2_attachment_attachment_
+  description: 实现:`AttachmentController@show`
+  parameters:
+    -
+      name: attachment
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 attachment/{attachment}'
+  tags:
+    - attachment
+  operationId: put_api_v2_attachment_attachment_
+  description: 实现:`AttachmentController@update`
+  parameters:
+    -
+      name: attachment
+      in: path
+      required: true
+      schema:
+        type: string
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            title:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 attachment/{attachment}'
+  tags:
+    - attachment
+  operationId: patch_api_v2_attachment_attachment_
+  description: 实现:`AttachmentController@update`
+  parameters:
+    -
+      name: attachment
+      in: path
+      required: true
+      schema:
+        type: string
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            title:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 attachment/{attachment}'
+  tags:
+    - attachment
+  operationId: delete_api_v2_attachment_attachment_
+  description: 实现:`AttachmentController@destroy`
+  parameters:
+    -
+      name: attachment
+      in: path
+      required: true
+      schema:
+        type: string
+    -
+      name: name
+      in: query
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 119 - 0
openapi/public/assets/protocol/resources/auto/v2-attachment.yaml

@@ -0,0 +1,119 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-attachment.yaml
+get:
+  summary: '列出 attachment'
+  tags:
+    - attachment
+  operationId: get_api_v2_attachment
+  description: 实现:`AttachmentController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - studio
+    -
+      name: studio
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      schema:
+        type: string
+    -
+      name: content_type
+      in: query
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      schema:
+        type: string
+        default: updated_at
+    -
+      name: dir
+      in: query
+      schema:
+        type: string
+        default: desc
+    -
+      name: offset
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 attachment'
+  tags:
+    - attachment
+  operationId: post_api_v2_attachment
+  description: 实现:`AttachmentController@store`
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            file:
+              type: string
+              description: 规则:required
+            id:
+              type: string
+            type:
+              type: string
+            studio:
+              type: string
+          required:
+            - file
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-attachments-attachment.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-attachments-attachment.yaml
+get:
+  summary: '获取单个 attachments/{attachment}'
+  tags:
+    - attachments
+  operationId: get_api_v2_attachments_attachment_
+  description: 实现:`UploadController@show`
+  parameters:
+    -
+      name: attachment
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 attachments/{attachment}'
+  tags:
+    - attachments
+  operationId: put_api_v2_attachments_attachment_
+  description: 实现:`UploadController@update`
+  parameters:
+    -
+      name: attachment
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 attachments/{attachment}'
+  tags:
+    - attachments
+  operationId: patch_api_v2_attachments_attachment_
+  description: 实现:`UploadController@update`
+  parameters:
+    -
+      name: attachment
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 attachments/{attachment}'
+  tags:
+    - attachments
+  operationId: delete_api_v2_attachments_attachment_
+  description: 实现:`UploadController@destroy`
+  parameters:
+    -
+      name: attachment
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 104 - 0
openapi/public/assets/protocol/resources/auto/v2-attachments.yaml

@@ -0,0 +1,104 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-attachments.yaml
+get:
+  summary: '列出 attachments'
+  tags:
+    - attachments
+  operationId: get_api_v2_attachments
+  description: 实现:`UploadController@index`
+  parameters:
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 attachments'
+  tags:
+    - attachments
+  operationId: post_api_v2_attachments
+  description: 实现:`UploadController@store`
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            file:
+              type: string
+              description: 规则:required
+            is_tmp:
+              type: string
+          required:
+            - file
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 25 - 0
openapi/public/assets/protocol/resources/auto/v2-auth-current.yaml

@@ -0,0 +1,25 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-auth-current.yaml
+get:
+  summary: 'getUserInfoByToken auth/current'
+  tags:
+    - auth
+  operationId: get_api_v2_auth_current
+  description: 实现:`AuthController@getUserInfoByToken`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-auth-forgot-password-forgot-password.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-auth-forgot-password-forgot-password.yaml
+get:
+  summary: '获取单个 auth/forgot-password/{forgot_password}'
+  tags:
+    - auth
+  operationId: get_api_v2_auth_forgot_password_forgot_password_
+  description: 实现:`ForgotPasswordController@show`
+  parameters:
+    -
+      name: forgot_password
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 auth/forgot-password/{forgot_password}'
+  tags:
+    - auth
+  operationId: put_api_v2_auth_forgot_password_forgot_password_
+  description: 实现:`ForgotPasswordController@update`
+  parameters:
+    -
+      name: forgot_password
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 auth/forgot-password/{forgot_password}'
+  tags:
+    - auth
+  operationId: patch_api_v2_auth_forgot_password_forgot_password_
+  description: 实现:`ForgotPasswordController@update`
+  parameters:
+    -
+      name: forgot_password
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 auth/forgot-password/{forgot_password}'
+  tags:
+    - auth
+  operationId: delete_api_v2_auth_forgot_password_forgot_password_
+  description: 实现:`ForgotPasswordController@destroy`
+  parameters:
+    -
+      name: forgot_password
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 103 - 0
openapi/public/assets/protocol/resources/auto/v2-auth-forgot-password.yaml

@@ -0,0 +1,103 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-auth-forgot-password.yaml
+get:
+  summary: '列出 auth/forgot-password'
+  tags:
+    - auth
+  operationId: get_api_v2_auth_forgot_password
+  description: 实现:`ForgotPasswordController@index`
+  parameters:
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 auth/forgot-password'
+  tags:
+    - auth
+  operationId: post_api_v2_auth_forgot_password
+  description: 实现:`ForgotPasswordController@store`
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            email:
+              type: string
+            lang:
+              type: string
+            dashboard:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-auth-reset-password-reset-password.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-auth-reset-password-reset-password.yaml
+get:
+  summary: 根据token获取用户名.
+  tags:
+    - auth
+  operationId: get_api_v2_auth_reset_password_reset_password_
+  description: 实现:`ResetPasswordController@show`
+  parameters:
+    -
+      name: reset_password
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 auth/reset-password/{reset_password}'
+  tags:
+    - auth
+  operationId: put_api_v2_auth_reset_password_reset_password_
+  description: 实现:`ResetPasswordController@update`
+  parameters:
+    -
+      name: reset_password
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 auth/reset-password/{reset_password}'
+  tags:
+    - auth
+  operationId: patch_api_v2_auth_reset_password_reset_password_
+  description: 实现:`ResetPasswordController@update`
+  parameters:
+    -
+      name: reset_password
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 auth/reset-password/{reset_password}'
+  tags:
+    - auth
+  operationId: delete_api_v2_auth_reset_password_reset_password_
+  description: 实现:`ResetPasswordController@destroy`
+  parameters:
+    -
+      name: reset_password
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 103 - 0
openapi/public/assets/protocol/resources/auto/v2-auth-reset-password.yaml

@@ -0,0 +1,103 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-auth-reset-password.yaml
+get:
+  summary: '列出 auth/reset-password'
+  tags:
+    - auth
+  operationId: get_api_v2_auth_reset_password
+  description: 实现:`ResetPasswordController@index`
+  parameters:
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 auth/reset-password'
+  tags:
+    - auth
+  operationId: post_api_v2_auth_reset_password
+  description: 实现:`ResetPasswordController@store`
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            token:
+              type: string
+            username:
+              type: string
+            password:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-book-title-book-title.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-book-title-book-title.yaml
+get:
+  summary: '获取单个 book-title/{book_title}'
+  tags:
+    - book-title
+  operationId: get_api_v2_book_title_book_title_
+  description: 实现:`BookTitleController@show`
+  parameters:
+    -
+      name: book_title
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 book-title/{book_title}'
+  tags:
+    - book-title
+  operationId: put_api_v2_book_title_book_title_
+  description: 实现:`BookTitleController@update`
+  parameters:
+    -
+      name: book_title
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 book-title/{book_title}'
+  tags:
+    - book-title
+  operationId: patch_api_v2_book_title_book_title_
+  description: 实现:`BookTitleController@update`
+  parameters:
+    -
+      name: book_title
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 book-title/{book_title}'
+  tags:
+    - book-title
+  operationId: delete_api_v2_book_title_book_title_
+  description: 实现:`BookTitleController@destroy`
+  parameters:
+    -
+      name: book_title
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 90 - 0
openapi/public/assets/protocol/resources/auto/v2-book-title.yaml

@@ -0,0 +1,90 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-book-title.yaml
+get:
+  summary: '列出 book-title'
+  tags:
+    - book-title
+  operationId: get_api_v2_book_title
+  description: 实现:`BookTitleController@index`
+  parameters:
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 book-title'
+  tags:
+    - book-title
+  operationId: post_api_v2_book_title
+  description: 实现:`BookTitleController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-case-case.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-case-case.yaml
+get:
+  summary: 输入一个单词,输出三藏中所有可能的变形
+  tags:
+    - case
+  operationId: get_api_v2_case_case_
+  description: 实现:`CaseController@show`
+  parameters:
+    -
+      name: case
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 case/{case}'
+  tags:
+    - case
+  operationId: put_api_v2_case_case_
+  description: 实现:`CaseController@update`
+  parameters:
+    -
+      name: case
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 case/{case}'
+  tags:
+    - case
+  operationId: patch_api_v2_case_case_
+  description: 实现:`CaseController@update`
+  parameters:
+    -
+      name: case
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 case/{case}'
+  tags:
+    - case
+  operationId: delete_api_v2_case_case_
+  description: 实现:`CaseController@destroy`
+  parameters:
+    -
+      name: case
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 90 - 0
openapi/public/assets/protocol/resources/auto/v2-case.yaml

@@ -0,0 +1,90 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-case.yaml
+get:
+  summary: '列出 case'
+  tags:
+    - case
+  operationId: get_api_v2_case
+  description: 实现:`CaseController@index`
+  parameters:
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 case'
+  tags:
+    - case
+  operationId: post_api_v2_case
+  description: 实现:`CaseController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 215 - 0
openapi/public/assets/protocol/resources/auto/v2-channel-channel.yaml

@@ -0,0 +1,215 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-channel-channel.yaml
+get:
+  summary: '获取单个 channel'
+  tags:
+    - channel
+  operationId: get_api_v2_channel_channel_
+  description: |-
+    返回 channel 详情,附带所属 studio 与作者信息。
+
+    实现:`ChannelController@show`
+  parameters:
+    -
+      name: channel
+      in: path
+      required: true
+      schema:
+        type: string
+      description: 'channel uid'
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '整体更新 channel'
+  tags:
+    - channel
+  operationId: put_api_v2_channel_channel_
+  description: |-
+    覆盖式更新,未传的字段会被写成 null;只改部分字段请用 PATCH /channel。
+    系统 channel 不可修改;非 owner 需要 30 以上的协作权限。
+
+    实现:`ChannelController@update`
+  parameters:
+    -
+      name: channel
+      in: path
+      required: true
+      schema:
+        type: string
+      description: 'channel uid'
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            id:
+              type: string
+            name:
+              type: string
+              description: 'channel 名称'
+            type:
+              type: integer
+              description: 'channel 类型'
+            summary:
+              type: string
+              description: 简介
+            lang:
+              type: string
+              description: 译文语言代码
+            status:
+              type: integer
+              description: '状态。30 为全网公开'
+            source_type:
+              type: string
+              description: 来源类型,传入才会更新
+            source_id:
+              type: string
+              description: '来源 id,传入才会更新'
+          required:
+            - name
+            - type
+            - summary
+            - lang
+            - status
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '整体更新 channel'
+  tags:
+    - channel
+  operationId: patch_api_v2_channel_channel_
+  description: |-
+    覆盖式更新,未传的字段会被写成 null;只改部分字段请用 PATCH /channel。
+    系统 channel 不可修改;非 owner 需要 30 以上的协作权限。
+
+    实现:`ChannelController@update`
+  parameters:
+    -
+      name: channel
+      in: path
+      required: true
+      schema:
+        type: string
+      description: 'channel uid'
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            id:
+              type: string
+            name:
+              type: string
+              description: 'channel 名称'
+            type:
+              type: integer
+              description: 'channel 类型'
+            summary:
+              type: string
+              description: 简介
+            lang:
+              type: string
+              description: 译文语言代码
+            status:
+              type: integer
+              description: '状态。30 为全网公开'
+            source_type:
+              type: string
+              description: 来源类型,传入才会更新
+            source_id:
+              type: string
+              description: '来源 id,传入才会更新'
+          required:
+            - name
+            - type
+            - summary
+            - lang
+            - status
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 channel'
+  tags:
+    - channel
+  operationId: delete_api_v2_channel_channel_
+  description: |-
+    只有 owner 可以删除。channel 下已有译文、术语或逐词解析数据时拒绝删除。
+
+    实现:`ChannelController@destroy`
+  parameters:
+    -
+      name: channel
+      in: path
+      required: true
+      schema:
+        type: string
+      description: 'channel uid'
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-channel-io-channel-io.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-channel-io-channel-io.yaml
+get:
+  summary: '获取单个 channel-io/{channel_io}'
+  tags:
+    - channel-io
+  operationId: get_api_v2_channel_io_channel_io_
+  description: 实现:`ChannelIOController@show`
+  parameters:
+    -
+      name: channel_io
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 channel-io/{channel_io}'
+  tags:
+    - channel-io
+  operationId: put_api_v2_channel_io_channel_io_
+  description: 实现:`ChannelIOController@update`
+  parameters:
+    -
+      name: channel_io
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 channel-io/{channel_io}'
+  tags:
+    - channel-io
+  operationId: patch_api_v2_channel_io_channel_io_
+  description: 实现:`ChannelIOController@update`
+  parameters:
+    -
+      name: channel_io
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 channel-io/{channel_io}'
+  tags:
+    - channel-io
+  operationId: delete_api_v2_channel_io_channel_io_
+  description: 实现:`ChannelIOController@destroy`
+  parameters:
+    -
+      name: channel_io
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 101 - 0
openapi/public/assets/protocol/resources/auto/v2-channel-io.yaml

@@ -0,0 +1,101 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-channel-io.yaml
+get:
+  summary: '列出 channel-io'
+  tags:
+    - channel-io
+  operationId: get_api_v2_channel_io
+  description: 实现:`ChannelIOController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - public
+    -
+      name: updated_at
+      in: query
+      schema:
+        type: string
+        default: '2000-1-1'
+    -
+      name: offset
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 channel-io'
+  tags:
+    - channel-io
+  operationId: post_api_v2_channel_io
+  description: 实现:`ChannelIOController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 31 - 0
openapi/public/assets/protocol/resources/auto/v2-channel-my-number.yaml

@@ -0,0 +1,31 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-channel-my-number.yaml
+get:
+  summary: 获取我的,和协作channel数量
+  tags:
+    - channel-my-number
+  operationId: get_api_v2_channel_my_number
+  description: 实现:`ChannelController@showMyNumber`
+  parameters:
+    -
+      name: studio
+      in: query
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 33 - 0
openapi/public/assets/protocol/resources/auto/v2-channel-name-name.yaml

@@ -0,0 +1,33 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-channel-name-name.yaml
+get:
+  summary: '按名称获取 channel'
+  tags:
+    - channel-name
+  operationId: get_api_v2_channel_name_name_
+  description: 实现:`ChannelController@showByName`
+  parameters:
+    -
+      name: name
+      in: path
+      required: true
+      schema:
+        type: string
+      description: 'channel 名称'
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 36 - 0
openapi/public/assets/protocol/resources/auto/v2-channel-progress.yaml

@@ -0,0 +1,36 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-channel-progress.yaml
+post:
+  summary: 获取章节的进度
+  tags:
+    - channel-progress
+  operationId: post_api_v2_channel_progress
+  description: 实现:`ChannelController@progress`
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            sentence:
+              type: string
+            owner:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 262 - 0
openapi/public/assets/protocol/resources/auto/v2-channel.yaml

@@ -0,0 +1,262 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-channel.yaml
+get:
+  summary: '列出 channel(译文集)'
+  tags:
+    - channel
+  operationId: get_api_v2_channel
+  description: |-
+    按 view 指定的口径返回 channel 列表,支持关键字搜索、分页、排序。
+    需要登录的口径:studio、studio-all、user-edit、user-in-chapter。
+
+    实现:`ChannelController@index`
+  parameters:
+    -
+      name: book
+      in: query
+      schema:
+        type: integer
+      description: 'view=user-in-chapter 时的典籍 id;传入后会联查该章节的翻译进度'
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - public
+          - studio
+          - studio-all
+          - user-edit
+          - user-in-chapter
+          - system
+          - paragraphs
+          - id
+      description: 查询口径
+      required: true
+    -
+      name: name
+      in: query
+      schema:
+        type: string
+      description: 'studio 名称,view=studio / studio-all 时必填'
+    -
+      name: view2
+      in: query
+      schema:
+        type: string
+        default: my
+      description: 'view=studio 时的二级口径:my=我的,其余值=协作的'
+    -
+      name: collaborator
+      in: query
+      schema:
+        type: string
+        default: all
+      description: 'view=studio 且 view2 为协作时,按协作者 uid 过滤'
+    -
+      name: para
+      in: query
+      schema:
+        type: string
+      description: 'view=user-in-chapter 时的段落号'
+    -
+      name: book_id
+      in: query
+      schema:
+        type: integer
+      description: 'view=paragraphs 时的典籍 id'
+    -
+      name: id
+      in: query
+      schema:
+        type: string
+      description: 'view=id 时的 channel uid 列表,逗号分隔'
+    -
+      name: paragraph
+      in: query
+      schema:
+        type: string
+      description: '联查 progress_chapters 时的段落号,与 book 配合使用'
+    -
+      name: search
+      in: query
+      schema:
+        type: string
+    -
+      name: type
+      in: query
+      schema:
+        type: integer
+      description: '按 channel 类型过滤'
+    -
+      name: updated_at
+      in: query
+      schema:
+        type: string
+      description: 只返回该时间之后更新的记录,用于离线包增量同步
+      example: '2023-09-18T05:39:51.000000Z'
+    -
+      name: created_at
+      in: query
+      schema:
+        type: string
+      description: 只返回该时间之后新建的记录
+    -
+      name: order
+      in: query
+      schema:
+        type: string
+        default: created_at
+    -
+      name: dir
+      in: query
+      schema:
+        type: string
+        default: desc
+    -
+      name: offset
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+    -
+      name: progress
+      in: query
+      schema:
+        type: string
+      description: '传入则在每行附带 final 逐句完成情况,依赖 book 与 para'
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 channel'
+  tags:
+    - channel
+  operationId: post_api_v2_channel
+  description: |-
+    在指定 studio 下新建译文集。同一 studio 内不允许重名。
+    调用者必须对该 studio 有管理权限。
+
+    实现:`ChannelController@store`
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            studio:
+              type: string
+              description: '所属 studio 名称'
+            name:
+              type: string
+              description: 'channel 名称,在同一 studio 内唯一'
+            type:
+              type: integer
+              description: 'channel 类型'
+            lang:
+              type: string
+              description: 译文语言代码
+              example: zh-Hans
+          required:
+            - studio
+            - name
+            - type
+            - lang
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '局部更新 channel'
+  tags:
+    - channel
+  operationId: patch_api_v2_channel
+  description: |-
+    只更新请求体中出现的字段。系统 channel 不可修改;非 owner 需要 30 以上的协作权限。
+
+    实现:`ChannelController@patch`
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            id:
+              type: string
+            name:
+              type: string
+              description: 'channel 名称'
+            type:
+              type: integer
+              description: 'channel 类型'
+            summary:
+              type: string
+              description: 简介
+            lang:
+              type: string
+              description: 译文语言代码
+            status:
+              type: integer
+              description: '状态。30 为全网公开'
+            config:
+              type: string
+              description: 'channel 配置'
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-chapter-chapter.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-chapter-chapter.yaml
+get:
+  summary: '获取单个 chapter/{chapter}'
+  tags:
+    - chapter
+  operationId: get_api_v2_chapter_chapter_
+  description: 实现:`ChapterController@show`
+  parameters:
+    -
+      name: chapter
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 chapter/{chapter}'
+  tags:
+    - chapter
+  operationId: put_api_v2_chapter_chapter_
+  description: 实现:`ChapterController@update`
+  parameters:
+    -
+      name: chapter
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 chapter/{chapter}'
+  tags:
+    - chapter
+  operationId: patch_api_v2_chapter_chapter_
+  description: 实现:`ChapterController@update`
+  parameters:
+    -
+      name: chapter
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 chapter/{chapter}'
+  tags:
+    - chapter
+  operationId: delete_api_v2_chapter_chapter_
+  description: 实现:`ChapterController@destroy`
+  parameters:
+    -
+      name: chapter
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 146 - 0
openapi/public/assets/protocol/resources/auto/v2-chapter-content-chapter-content.yaml

@@ -0,0 +1,146 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-chapter-content-chapter-content.yaml
+get:
+  summary: '获取单个 chapter-content/{chapter_content}'
+  tags:
+    - chapter-content
+  operationId: get_api_v2_chapter_content_chapter_content_
+  description: 实现:`ChapterContentController@show`
+  parameters:
+    -
+      name: chapter_content
+      in: path
+      required: true
+      schema:
+        type: string
+    -
+      name: channels
+      in: query
+      schema:
+        type: string
+    -
+      name: mode
+      in: query
+      schema:
+        type: string
+        default: read
+    -
+      name: from
+      in: query
+      schema:
+        type: string
+    -
+      name: to
+      in: query
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 chapter-content/{chapter_content}'
+  tags:
+    - chapter-content
+  operationId: put_api_v2_chapter_content_chapter_content_
+  description: 实现:`ChapterContentController@update`
+  parameters:
+    -
+      name: chapter_content
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 chapter-content/{chapter_content}'
+  tags:
+    - chapter-content
+  operationId: patch_api_v2_chapter_content_chapter_content_
+  description: 实现:`ChapterContentController@update`
+  parameters:
+    -
+      name: chapter_content
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 chapter-content/{chapter_content}'
+  tags:
+    - chapter-content
+  operationId: delete_api_v2_chapter_content_chapter_content_
+  description: 实现:`ChapterContentController@destroy`
+  parameters:
+    -
+      name: chapter_content
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 90 - 0
openapi/public/assets/protocol/resources/auto/v2-chapter-content.yaml

@@ -0,0 +1,90 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-chapter-content.yaml
+get:
+  summary: '列出 chapter-content'
+  tags:
+    - chapter-content
+  operationId: get_api_v2_chapter_content
+  description: 实现:`ChapterContentController@index`
+  parameters:
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 chapter-content'
+  tags:
+    - chapter-content
+  operationId: post_api_v2_chapter_content
+  description: 实现:`ChapterContentController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-chapter-index-chapter-index.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-chapter-index-chapter-index.yaml
+get:
+  summary: '获取单个 chapter-index/{chapter_index}'
+  tags:
+    - chapter-index
+  operationId: get_api_v2_chapter_index_chapter_index_
+  description: 实现:`ChapterIndexController@show`
+  parameters:
+    -
+      name: chapter_index
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 chapter-index/{chapter_index}'
+  tags:
+    - chapter-index
+  operationId: put_api_v2_chapter_index_chapter_index_
+  description: 实现:`ChapterIndexController@update`
+  parameters:
+    -
+      name: chapter_index
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 chapter-index/{chapter_index}'
+  tags:
+    - chapter-index
+  operationId: patch_api_v2_chapter_index_chapter_index_
+  description: 实现:`ChapterIndexController@update`
+  parameters:
+    -
+      name: chapter_index
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 chapter-index/{chapter_index}'
+  tags:
+    - chapter-index
+  operationId: delete_api_v2_chapter_index_chapter_index_
+  description: 实现:`ChapterIndexController@destroy`
+  parameters:
+    -
+      name: chapter_index
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 102 - 0
openapi/public/assets/protocol/resources/auto/v2-chapter-index.yaml

@@ -0,0 +1,102 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-chapter-index.yaml
+get:
+  summary: '列出 chapter-index'
+  tags:
+    - chapter-index
+  operationId: get_api_v2_chapter_index
+  description: 实现:`ChapterIndexController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - public
+    -
+      name: updated_at
+      in: query
+      schema:
+        type: string
+    -
+      name: created_at
+      in: query
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      schema:
+        type: string
+        default: created_at
+    -
+      name: dir
+      in: query
+      schema:
+        type: string
+        default: desc
+    -
+      name: offset
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 chapter-index'
+  tags:
+    - chapter-index
+  operationId: post_api_v2_chapter_index
+  description: 实现:`ChapterIndexController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-chapter-io-chapter-io.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-chapter-io-chapter-io.yaml
+get:
+  summary: '获取单个 chapter-io/{chapter_io}'
+  tags:
+    - chapter-io
+  operationId: get_api_v2_chapter_io_chapter_io_
+  description: 实现:`ChapterIOController@show`
+  parameters:
+    -
+      name: chapter_io
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 chapter-io/{chapter_io}'
+  tags:
+    - chapter-io
+  operationId: put_api_v2_chapter_io_chapter_io_
+  description: 实现:`ChapterIOController@update`
+  parameters:
+    -
+      name: chapter_io
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 chapter-io/{chapter_io}'
+  tags:
+    - chapter-io
+  operationId: patch_api_v2_chapter_io_chapter_io_
+  description: 实现:`ChapterIOController@update`
+  parameters:
+    -
+      name: chapter_io
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 chapter-io/{chapter_io}'
+  tags:
+    - chapter-io
+  operationId: delete_api_v2_chapter_io_chapter_io_
+  description: 实现:`ChapterIOController@destroy`
+  parameters:
+    -
+      name: chapter_io
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 101 - 0
openapi/public/assets/protocol/resources/auto/v2-chapter-io.yaml

@@ -0,0 +1,101 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-chapter-io.yaml
+get:
+  summary: '列出 chapter-io'
+  tags:
+    - chapter-io
+  operationId: get_api_v2_chapter_io
+  description: 实现:`ChapterIOController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - public
+    -
+      name: updated_at
+      in: query
+      schema:
+        type: string
+        default: '2000-1-1'
+    -
+      name: offset
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 chapter-io'
+  tags:
+    - chapter-io
+  operationId: post_api_v2_chapter_io
+  description: 实现:`ChapterIOController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 102 - 0
openapi/public/assets/protocol/resources/auto/v2-chapter.yaml

@@ -0,0 +1,102 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-chapter.yaml
+get:
+  summary: '列出 chapter'
+  tags:
+    - chapter
+  operationId: get_api_v2_chapter
+  description: 实现:`ChapterController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - toc
+    -
+      name: book
+      in: query
+      schema:
+        type: string
+    -
+      name: para
+      in: query
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      schema:
+        type: string
+        default: paragraph
+    -
+      name: dir
+      in: query
+      schema:
+        type: string
+        default: asc
+    -
+      name: offset
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 chapter'
+  tags:
+    - chapter
+  operationId: post_api_v2_chapter
+  description: 实现:`ChapterController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-chat-messages-chat-message.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-chat-messages-chat-message.yaml
+get:
+  summary: '获取单个 chat-messages/{chat_message}'
+  tags:
+    - chat-messages
+  operationId: get_api_v2_chat_messages_chat_message_
+  description: 实现:`ChatMessageController@show`
+  parameters:
+    -
+      name: chat_message
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 chat-messages/{chat_message}'
+  tags:
+    - chat-messages
+  operationId: put_api_v2_chat_messages_chat_message_
+  description: 实现:`ChatMessageController@update`
+  parameters:
+    -
+      name: chat_message
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 chat-messages/{chat_message}'
+  tags:
+    - chat-messages
+  operationId: patch_api_v2_chat_messages_chat_message_
+  description: 实现:`ChatMessageController@update`
+  parameters:
+    -
+      name: chat_message
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 chat-messages/{chat_message}'
+  tags:
+    - chat-messages
+  operationId: delete_api_v2_chat_messages_chat_message_
+  description: 实现:`ChatMessageController@destroy`
+  parameters:
+    -
+      name: chat_message
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 94 - 0
openapi/public/assets/protocol/resources/auto/v2-chat-messages.yaml

@@ -0,0 +1,94 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-chat-messages.yaml
+get:
+  summary: '列出 chat-messages'
+  tags:
+    - chat-messages
+  operationId: get_api_v2_chat_messages
+  description: 实现:`ChatMessageController@index`
+  parameters:
+    -
+      name: chat
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 chat-messages'
+  tags:
+    - chat-messages
+  operationId: post_api_v2_chat_messages
+  description: 实现:`ChatMessageController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-chats-chat.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-chats-chat.yaml
+get:
+  summary: '获取单个 chats/{chat}'
+  tags:
+    - chats
+  operationId: get_api_v2_chats_chat_
+  description: 实现:`ChatController@show`
+  parameters:
+    -
+      name: chat
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 chats/{chat}'
+  tags:
+    - chats
+  operationId: put_api_v2_chats_chat_
+  description: 实现:`ChatController@update`
+  parameters:
+    -
+      name: chat
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 chats/{chat}'
+  tags:
+    - chats
+  operationId: patch_api_v2_chats_chat_
+  description: 实现:`ChatController@update`
+  parameters:
+    -
+      name: chat
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: 单个软删除
+  tags:
+    - chats
+  operationId: delete_api_v2_chats_chat_
+  description: 实现:`ChatController@destroy`
+  parameters:
+    -
+      name: chat
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 94 - 0
openapi/public/assets/protocol/resources/auto/v2-chats.yaml

@@ -0,0 +1,94 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-chats.yaml
+get:
+  summary: '列出 chats'
+  tags:
+    - chats
+  operationId: get_api_v2_chats
+  description: 实现:`ChatController@index`
+  parameters:
+    -
+      name: user_id
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 chats'
+  tags:
+    - chats
+  operationId: post_api_v2_chats
+  description: 实现:`ChatController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-command-command.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-command-command.yaml
+get:
+  summary: '获取单个 command/{command}'
+  tags:
+    - command
+  operationId: get_api_v2_command_command_
+  description: 实现:`CommandController@show`
+  parameters:
+    -
+      name: command
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 command/{command}'
+  tags:
+    - command
+  operationId: put_api_v2_command_command_
+  description: 实现:`CommandController@update`
+  parameters:
+    -
+      name: command
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 command/{command}'
+  tags:
+    - command
+  operationId: patch_api_v2_command_command_
+  description: 实现:`CommandController@update`
+  parameters:
+    -
+      name: command
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 command/{command}'
+  tags:
+    - command
+  operationId: delete_api_v2_command_command_
+  description: 实现:`CommandController@destroy`
+  parameters:
+    -
+      name: command
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 101 - 0
openapi/public/assets/protocol/resources/auto/v2-command.yaml

@@ -0,0 +1,101 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-command.yaml
+get:
+  summary: '列出 command'
+  tags:
+    - command
+  operationId: get_api_v2_command
+  description: 实现:`CommandController@index`
+  parameters:
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 command'
+  tags:
+    - command
+  operationId: post_api_v2_command
+  description: 实现:`CommandController@store`
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            name:
+              type: string
+            param:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-compound-compound.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-compound-compound.yaml
+get:
+  summary: '获取单个 compound/{compound}'
+  tags:
+    - compound
+  operationId: get_api_v2_compound_compound_
+  description: 实现:`CompoundController@show`
+  parameters:
+    -
+      name: compound
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 compound/{compound}'
+  tags:
+    - compound
+  operationId: put_api_v2_compound_compound_
+  description: 实现:`CompoundController@update`
+  parameters:
+    -
+      name: compound
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 compound/{compound}'
+  tags:
+    - compound
+  operationId: patch_api_v2_compound_compound_
+  description: 实现:`CompoundController@update`
+  parameters:
+    -
+      name: compound
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 compound/{compound}'
+  tags:
+    - compound
+  operationId: delete_api_v2_compound_compound_
+  description: 实现:`CompoundController@destroy`
+  parameters:
+    -
+      name: compound
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 108 - 0
openapi/public/assets/protocol/resources/auto/v2-compound.yaml

@@ -0,0 +1,108 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-compound.yaml
+get:
+  summary: '列出 compound'
+  tags:
+    - compound
+  operationId: get_api_v2_compound
+  description: 实现:`CompoundController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - only-word
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 compound'
+  tags:
+    - compound
+  operationId: post_api_v2_compound
+  description: 实现:`CompoundController@store`
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            index:
+              type: string
+            words:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 58 - 0
openapi/public/assets/protocol/resources/auto/v2-corpus-chapter-id.yaml

@@ -0,0 +1,58 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-corpus-chapter-id.yaml
+get:
+  summary: 'showChapter corpus-chapter/{id}'
+  tags:
+    - corpus-chapter
+  operationId: get_api_v2_corpus_chapter_id_
+  description: 实现:`CorpusController@showChapter`
+  parameters:
+    -
+      name: id
+      in: path
+      required: true
+      schema:
+        type: string
+    -
+      name: debug
+      in: query
+      schema:
+        type: string
+    -
+      name: channels
+      in: query
+      schema:
+        type: string
+    -
+      name: mode
+      in: query
+      schema:
+        type: string
+        default: read
+    -
+      name: from
+      in: query
+      schema:
+        type: string
+    -
+      name: to
+      in: query
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-corpus-corpu.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-corpus-corpu.yaml
+get:
+  summary: '获取单个 corpus/{corpu}'
+  tags:
+    - corpus
+  operationId: get_api_v2_corpus_corpu_
+  description: 实现:`CorpusController@show`
+  parameters:
+    -
+      name: corpu
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 corpus/{corpu}'
+  tags:
+    - corpus
+  operationId: put_api_v2_corpus_corpu_
+  description: 实现:`CorpusController@update`
+  parameters:
+    -
+      name: corpu
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 corpus/{corpu}'
+  tags:
+    - corpus
+  operationId: patch_api_v2_corpus_corpu_
+  description: 实现:`CorpusController@update`
+  parameters:
+    -
+      name: corpu
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 corpus/{corpu}'
+  tags:
+    - corpus
+  operationId: delete_api_v2_corpus_corpu_
+  description: 实现:`CorpusController@destroy`
+  parameters:
+    -
+      name: corpu
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 43 - 0
openapi/public/assets/protocol/resources/auto/v2-corpus-sent-id.yaml

@@ -0,0 +1,43 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-corpus-sent-id.yaml
+get:
+  summary: 'showSent corpus-sent/{id}'
+  tags:
+    - corpus-sent
+  operationId: get_api_v2_corpus_sent_id_
+  description: 实现:`CorpusController@showSent`
+  parameters:
+    -
+      name: id
+      in: path
+      required: true
+      schema:
+        type: string
+    -
+      name: channels
+      in: query
+      schema:
+        type: string
+    -
+      name: mode
+      in: query
+      schema:
+        type: string
+        default: edit
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 38 - 0
openapi/public/assets/protocol/resources/auto/v2-corpus-sentences-type-id.yaml

@@ -0,0 +1,38 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-corpus-sentences-type-id.yaml
+get:
+  summary: 获取某句子的全部译文
+  tags:
+    - corpus-sentences
+  operationId: get_api_v2_corpus_sentences_type_id_
+  description: 实现:`CorpusController@showSentences`
+  parameters:
+    -
+      name: type
+      in: path
+      required: true
+      schema:
+        type: string
+    -
+      name: id
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 97 - 0
openapi/public/assets/protocol/resources/auto/v2-corpus.yaml

@@ -0,0 +1,97 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-corpus.yaml
+get:
+  summary: '列出 corpus'
+  tags:
+    - corpus
+  operationId: get_api_v2_corpus
+  description: 实现:`CorpusController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - para
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 corpus'
+  tags:
+    - corpus
+  operationId: post_api_v2_corpus
+  description: 实现:`CorpusController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 203 - 0
openapi/public/assets/protocol/resources/auto/v2-course-course.yaml

@@ -0,0 +1,203 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-course-course.yaml
+get:
+  summary: '获取单个 course/{course}'
+  tags:
+    - course
+  operationId: get_api_v2_course_course_
+  description: 实现:`CourseController@show`
+  parameters:
+    -
+      name: course
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 course/{course}'
+  tags:
+    - course
+  operationId: put_api_v2_course_course_
+  description: 实现:`CourseController@update`
+  parameters:
+    -
+      name: course
+      in: path
+      required: true
+      schema:
+        type: string
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            title:
+              type: string
+            subtitle:
+              type: string
+            summary:
+              type: string
+            number:
+              type: string
+            cover:
+              type: string
+            content:
+              type: string
+            sign_up_message:
+              type: string
+            teacher_id:
+              type: string
+            anthology_id:
+              type: string
+            channel_id:
+              type: string
+            publicity:
+              type: string
+            start_at:
+              type: string
+            end_at:
+              type: string
+            sign_up_start_at:
+              type: string
+            sign_up_end_at:
+              type: string
+            join:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 course/{course}'
+  tags:
+    - course
+  operationId: patch_api_v2_course_course_
+  description: 实现:`CourseController@update`
+  parameters:
+    -
+      name: course
+      in: path
+      required: true
+      schema:
+        type: string
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            title:
+              type: string
+            subtitle:
+              type: string
+            summary:
+              type: string
+            number:
+              type: string
+            cover:
+              type: string
+            content:
+              type: string
+            sign_up_message:
+              type: string
+            teacher_id:
+              type: string
+            anthology_id:
+              type: string
+            channel_id:
+              type: string
+            publicity:
+              type: string
+            start_at:
+              type: string
+            end_at:
+              type: string
+            sign_up_start_at:
+              type: string
+            sign_up_end_at:
+              type: string
+            join:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 course/{course}'
+  tags:
+    - course
+  operationId: delete_api_v2_course_course_
+  description: 实现:`CourseController@destroy`
+  parameters:
+    -
+      name: course
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 37 - 0
openapi/public/assets/protocol/resources/auto/v2-course-curr.yaml

@@ -0,0 +1,37 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-course-curr.yaml
+get:
+  summary: '获取当前用户在指定课程中的角色与 channel'
+  tags:
+    - course-curr
+  operationId: get_api_v2_course_curr
+  description: |-
+    必须登录。只读取 is_current=true 的记录,返回 role 与 channel_id 两个字段。
+    当前用户不是该课程成员时返回 not member。
+
+    实现:`CourseMemberController@curr`
+  parameters:
+    -
+      name: course_id
+      in: query
+      schema:
+        type: string
+      description: 'course uid'
+      required: true
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 180 - 0
openapi/public/assets/protocol/resources/auto/v2-course-member-course-member.yaml

@@ -0,0 +1,180 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-course-member-course-member.yaml
+get:
+  summary: 查询某用户在指定课程中的当前成员记录
+  tags:
+    - course-member
+  operationId: get_api_v2_course_member_course_member_
+  description: |-
+    必须登录。默认查当前登录用户,传 user_uid 可查他人(无额外权限校验)。
+    只返回 is_current=true 的那条记录;查不到返回 no result(HTTP 200)。
+
+    实现:`CourseMemberController@show`
+  parameters:
+    -
+      name: course_member
+      in: path
+      required: true
+      schema:
+        type: string
+    -
+      name: user_uid
+      in: query
+      schema:
+        type: string
+      description: '要查询的用户 uid,缺省为当前登录用户'
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: 更新课程成员(以新增记录的方式保留历史)
+  tags:
+    - course-member
+  operationId: put_api_v2_course_member_course_member_
+  description: |-
+    必须登录。不会就地修改原记录:先复制一条新记录,把原记录 is_current 置为 false,
+    再把请求中出现的字段写到新记录上,原记录作为历史保留。
+    修改 channel_id 只允许成员本人操作,否则返回 auth.failed。
+
+    实现:`CourseMemberController@update`
+  parameters:
+    -
+      name: course_member
+      in: path
+      required: true
+      schema:
+        type: string
+      description: '要更新的 course_member 记录 id'
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            channel_id:
+              type: string
+              description: '该成员在课程中使用的 channel uid,仅本人可改'
+            status:
+              type: string
+              description: 新的成员状态
+              example: joined
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: 更新课程成员(以新增记录的方式保留历史)
+  tags:
+    - course-member
+  operationId: patch_api_v2_course_member_course_member_
+  description: |-
+    必须登录。不会就地修改原记录:先复制一条新记录,把原记录 is_current 置为 false,
+    再把请求中出现的字段写到新记录上,原记录作为历史保留。
+    修改 channel_id 只允许成员本人操作,否则返回 auth.failed。
+
+    实现:`CourseMemberController@update`
+  parameters:
+    -
+      name: course_member
+      in: path
+      required: true
+      schema:
+        type: string
+      description: '要更新的 course_member 记录 id'
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            channel_id:
+              type: string
+              description: '该成员在课程中使用的 channel uid,仅本人可改'
+            status:
+              type: string
+              description: 新的成员状态
+              example: joined
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: 删除课程成员记录
+  tags:
+    - course-member
+  operationId: delete_api_v2_course_member_course_member_
+  description: |-
+    必须登录。课程所有者(course.studio_id 等于当前用户)可以直接删除;
+    否则按当前用户在该课程中的角色判断权限,普通 student 无删除权限,返回 auth.failed。
+
+    实现:`CourseMemberController@destroy`
+  parameters:
+    -
+      name: course_member
+      in: path
+      required: true
+      schema:
+        type: string
+      description: '要删除的 course_member 记录 id'
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 38 - 0
openapi/public/assets/protocol/resources/auto/v2-course-member-export.yaml

@@ -0,0 +1,38 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-course-member-export.yaml
+get:
+  summary: '导出课程成员名单为 Excel'
+  tags:
+    - course-member-export
+  operationId: get_api_v2_course_member_export
+  description: |-
+    导出该课程全部 is_current 成员,表头为 nickname、username、role、status、created_at,
+    昵称与用户名通过 UserApi 按 user_id 逐条查询。
+    直接以 xlsx 附件(course_member.xlsx)写入输出流,不返回 JSON,且不做登录与权限校验。
+
+    实现:`CourseMemberController@export`
+  parameters:
+    -
+      name: course_id
+      in: query
+      schema:
+        type: string
+      description: 'course uid'
+      required: true
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 45 - 0
openapi/public/assets/protocol/resources/auto/v2-course-member-set-channel.yaml

@@ -0,0 +1,45 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-course-member-set-channel.yaml
+put:
+  summary: '设置当前用户在某课程中使用的 channel'
+  tags:
+    - course-member_set-channel
+  operationId: put_api_v2_course_member_set_channel
+  description: |-
+    必须登录。就地修改当前用户在该 course 的 is_current 记录(不产生历史记录)。
+    未传 channel_id、或当前用户不是该课程的当前成员,都返回 auth.failed。
+
+    实现:`CourseMemberController@set_channel`
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            channel_id:
+              type: string
+              description: '作业所用的 channel uid'
+            course_id:
+              type: string
+              description: 'course uid'
+          required:
+            - course_id
+            - channel_id
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 186 - 0
openapi/public/assets/protocol/resources/auto/v2-course-member.yaml

@@ -0,0 +1,186 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-course-member.yaml
+get:
+  summary: 列出课程成员
+  tags:
+    - course-member
+  operationId: get_api_v2_course_member
+  description: |-
+    按 view 指定的口径返回课程成员列表,支持角色/状态过滤、按昵称搜索、分页与排序。
+    必须登录,且当前用户必须已经是该 course 的成员(在 course_member 中有 role),否则返回 403。
+    返回 rows(成员列表)、role(当前用户在该 course 中的当前角色)、count(过滤后的总数)。
+
+    实现:`CourseMemberController@index`
+  parameters:
+    -
+      name: id
+      in: query
+      schema:
+        type: string
+      description: 'course uid。view=timeline 时也用于权限校验'
+      required: true
+    -
+      name: course
+      in: query
+      schema:
+        type: string
+      description: '权限校验与 timeline 口径使用的 course uid,缺省时回退到 id'
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - course
+          - timeline
+      description: 查询口径。course=课程内全部当前成员;timeline=某用户的成员变更时间线
+      required: true
+    -
+      name: userId
+      in: query
+      schema:
+        type: string
+      description: 'view=timeline 时必填,要查看时间线的用户 uid'
+    -
+      name: timeline
+      in: query
+      schema:
+        type: string
+        default: current
+      description: 'view=timeline 时的范围:current=只看 course 参数指定的课程,其余值=该用户全部课程'
+    -
+      name: role
+      in: query
+      schema:
+        type: string
+      description: '按角色过滤,all 表示不过滤'
+      example: student
+    -
+      name: status
+      in: query
+      schema:
+        type: string
+      description: 按状态过滤,逗号分隔可多选
+      example: 'joined,applied'
+    -
+      name: search
+      in: query
+      schema:
+        type: string
+      description: 按成员昵称模糊搜索
+    -
+      name: order
+      in: query
+      schema:
+        type: string
+        default: created_at
+      description: 排序字段
+    -
+      name: dir
+      in: query
+      schema:
+        type: string
+        enum:
+          - asc
+          - desc
+        default: asc
+      description: 排序方向
+    -
+      name: offset
+      in: query
+      schema:
+        type: integer
+        default: '0'
+      description: 跳过的记录数
+    -
+      name: limit
+      in: query
+      schema:
+        type: integer
+        default: '1000'
+      description: 返回条数上限
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: 新增课程成员记录(加入/申请/邀请)
+  tags:
+    - course-member
+  operationId: post_api_v2_course_member
+  description: |-
+    必须登录。status=invited 表示由当前用户邀请他人,成员归属 user_id 指定的用户;
+    其余情况(自己加入或申请)一律忽略 user_id,成员归属当前登录用户。
+    非 invited 时若该 user 已在该 course 中存在任何记录,返回 member exists(HTTP 200)。
+    写入前会把同一 course + user 的旧记录 is_current 置为 false,新记录成为当前记录。
+    状态必须与课程加入方式匹配:course.join=open 只接受 joined/invited,manual 只接受 applied/invited,
+    不匹配返回 invalid course(HTTP 200)。course 不存在返回 invalid course。
+
+    实现:`CourseMemberController@store`
+  requestBody:
+    required: true
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            user_id:
+              type: string
+              description: '成员用户 uid,仅在 status=invited 时生效'
+            course_id:
+              type: string
+              description: 'course uid'
+            role:
+              type: string
+              description: 成员角色
+              example: student
+            status:
+              type: string
+              description: 成员状态
+              enum:
+                - joined
+                - applied
+                - invited
+          required:
+            - user_id
+            - course_id
+            - role
+            - status
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 25 - 0
openapi/public/assets/protocol/resources/auto/v2-course-my-course.yaml

@@ -0,0 +1,25 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-course-my-course.yaml
+get:
+  summary: 'showMyCourseNumber course-my-course'
+  tags:
+    - course-my-course
+  operationId: get_api_v2_course_my_course
+  description: 实现:`CourseController@showMyCourseNumber`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 112 - 0
openapi/public/assets/protocol/resources/auto/v2-course.yaml

@@ -0,0 +1,112 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-course.yaml
+get:
+  summary: '列出 course'
+  tags:
+    - course
+  operationId: get_api_v2_course
+  description: 实现:`CourseController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - new
+          - open
+          - close
+          - create
+          - study
+          - teach
+    -
+      name: studio
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      schema:
+        type: string
+        default: updated_at
+    -
+      name: dir
+      in: query
+      schema:
+        type: string
+        default: desc
+    -
+      name: offset
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 course'
+  tags:
+    - course
+  operationId: post_api_v2_course
+  description: 实现:`CourseController@store`
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            studio:
+              type: string
+            title:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-dict-dict.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-dict-dict.yaml
+get:
+  summary: '获取单个 dict/{dict}'
+  tags:
+    - dict
+  operationId: get_api_v2_dict_dict_
+  description: 实现:`DictController@show`
+  parameters:
+    -
+      name: dict
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 dict/{dict}'
+  tags:
+    - dict
+  operationId: put_api_v2_dict_dict_
+  description: 实现:`DictController@update`
+  parameters:
+    -
+      name: dict
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 dict/{dict}'
+  tags:
+    - dict
+  operationId: patch_api_v2_dict_dict_
+  description: 实现:`DictController@update`
+  parameters:
+    -
+      name: dict
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 dict/{dict}'
+  tags:
+    - dict
+  operationId: delete_api_v2_dict_dict_
+  description: 实现:`DictController@destroy`
+  parameters:
+    -
+      name: dict
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-dict-info-dict-info.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-dict-info-dict-info.yaml
+get:
+  summary: '获取单个 dict-info/{dict_info}'
+  tags:
+    - dict-info
+  operationId: get_api_v2_dict_info_dict_info_
+  description: 实现:`DictInfoController@show`
+  parameters:
+    -
+      name: dict_info
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 dict-info/{dict_info}'
+  tags:
+    - dict-info
+  operationId: put_api_v2_dict_info_dict_info_
+  description: 实现:`DictInfoController@update`
+  parameters:
+    -
+      name: dict_info
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 dict-info/{dict_info}'
+  tags:
+    - dict-info
+  operationId: patch_api_v2_dict_info_dict_info_
+  description: 实现:`DictInfoController@update`
+  parameters:
+    -
+      name: dict_info
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 dict-info/{dict_info}'
+  tags:
+    - dict-info
+  operationId: delete_api_v2_dict_info_dict_info_
+  description: 实现:`DictInfoController@destroy`
+  parameters:
+    -
+      name: dict_info
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 97 - 0
openapi/public/assets/protocol/resources/auto/v2-dict-info.yaml

@@ -0,0 +1,97 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-dict-info.yaml
+get:
+  summary: '列出 dict-info'
+  tags:
+    - dict-info
+  operationId: get_api_v2_dict_info
+  description: 实现:`DictInfoController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - name
+    -
+      name: name
+      in: query
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      schema:
+        type: string
+        default: updated_at
+    -
+      name: dir
+      in: query
+      schema:
+        type: string
+        default: desc
+    -
+      name: offset
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 dict-info'
+  tags:
+    - dict-info
+  operationId: post_api_v2_dict_info
+  description: 实现:`DictInfoController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-dict-meaning-dict-meaning.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-dict-meaning-dict-meaning.yaml
+get:
+  summary: '获取单个 dict-meaning/{dict_meaning}'
+  tags:
+    - dict-meaning
+  operationId: get_api_v2_dict_meaning_dict_meaning_
+  description: 实现:`DictMeaningController@show`
+  parameters:
+    -
+      name: dict_meaning
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 dict-meaning/{dict_meaning}'
+  tags:
+    - dict-meaning
+  operationId: put_api_v2_dict_meaning_dict_meaning_
+  description: 实现:`DictMeaningController@update`
+  parameters:
+    -
+      name: dict_meaning
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 dict-meaning/{dict_meaning}'
+  tags:
+    - dict-meaning
+  operationId: patch_api_v2_dict_meaning_dict_meaning_
+  description: 实现:`DictMeaningController@update`
+  parameters:
+    -
+      name: dict_meaning
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 dict-meaning/{dict_meaning}'
+  tags:
+    - dict-meaning
+  operationId: delete_api_v2_dict_meaning_dict_meaning_
+  description: 实现:`DictMeaningController@destroy`
+  parameters:
+    -
+      name: dict_meaning
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 100 - 0
openapi/public/assets/protocol/resources/auto/v2-dict-meaning.yaml

@@ -0,0 +1,100 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-dict-meaning.yaml
+get:
+  summary: '列出 dict-meaning'
+  tags:
+    - dict-meaning
+  operationId: get_api_v2_dict_meaning
+  description: 实现:`DictMeaningController@index`
+  parameters:
+    -
+      name: word
+      in: query
+      schema:
+        type: string
+    -
+      name: lang
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 dict-meaning'
+  tags:
+    - dict-meaning
+  operationId: post_api_v2_dict_meaning
+  description: 实现:`DictMeaningController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-dict-preference-dict-preference.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-dict-preference-dict-preference.yaml
+get:
+  summary: '获取单个 dict-preference/{dict_preference}'
+  tags:
+    - dict-preference
+  operationId: get_api_v2_dict_preference_dict_preference_
+  description: 实现:`DictPreferenceController@show`
+  parameters:
+    -
+      name: dict_preference
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 dict-preference/{dict_preference}'
+  tags:
+    - dict-preference
+  operationId: put_api_v2_dict_preference_dict_preference_
+  description: 实现:`DictPreferenceController@update`
+  parameters:
+    -
+      name: dict_preference
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 dict-preference/{dict_preference}'
+  tags:
+    - dict-preference
+  operationId: patch_api_v2_dict_preference_dict_preference_
+  description: 实现:`DictPreferenceController@update`
+  parameters:
+    -
+      name: dict_preference
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 dict-preference/{dict_preference}'
+  tags:
+    - dict-preference
+  operationId: delete_api_v2_dict_preference_dict_preference_
+  description: 实现:`DictPreferenceController@destroy`
+  parameters:
+    -
+      name: dict_preference
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 90 - 0
openapi/public/assets/protocol/resources/auto/v2-dict-preference.yaml

@@ -0,0 +1,90 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-dict-preference.yaml
+get:
+  summary: '列出 dict-preference'
+  tags:
+    - dict-preference
+  operationId: get_api_v2_dict_preference
+  description: 实现:`DictPreferenceController@index`
+  parameters:
+    -
+      name: keyword
+      in: query
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      schema:
+        type: string
+        default: word_indices.count
+    -
+      name: dir
+      in: query
+      schema:
+        type: string
+        default: desc
+    -
+      name: offset
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 dict-preference'
+  tags:
+    - dict-preference
+  operationId: post_api_v2_dict_preference
+  description: 实现:`DictPreferenceController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-dict-statistic-dict-statistic.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-dict-statistic-dict-statistic.yaml
+get:
+  summary: '获取单个 dict-statistic/{dict_statistic}'
+  tags:
+    - dict-statistic
+  operationId: get_api_v2_dict_statistic_dict_statistic_
+  description: 实现:`DictStatisticController@show`
+  parameters:
+    -
+      name: dict_statistic
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 dict-statistic/{dict_statistic}'
+  tags:
+    - dict-statistic
+  operationId: put_api_v2_dict_statistic_dict_statistic_
+  description: 实现:`DictStatisticController@update`
+  parameters:
+    -
+      name: dict_statistic
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 dict-statistic/{dict_statistic}'
+  tags:
+    - dict-statistic
+  operationId: patch_api_v2_dict_statistic_dict_statistic_
+  description: 实现:`DictStatisticController@update`
+  parameters:
+    -
+      name: dict_statistic
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 dict-statistic/{dict_statistic}'
+  tags:
+    - dict-statistic
+  operationId: delete_api_v2_dict_statistic_dict_statistic_
+  description: 实现:`DictStatisticController@destroy`
+  parameters:
+    -
+      name: dict_statistic
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 90 - 0
openapi/public/assets/protocol/resources/auto/v2-dict-statistic.yaml

@@ -0,0 +1,90 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-dict-statistic.yaml
+get:
+  summary: '列出 dict-statistic'
+  tags:
+    - dict-statistic
+  operationId: get_api_v2_dict_statistic
+  description: 实现:`DictStatisticController@index`
+  parameters:
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 dict-statistic'
+  tags:
+    - dict-statistic
+  operationId: post_api_v2_dict_statistic
+  description: 实现:`DictStatisticController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-dict-vocabulary-dict-vocabulary.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-dict-vocabulary-dict-vocabulary.yaml
+get:
+  summary: '获取单个 dict-vocabulary/{dict_vocabulary}'
+  tags:
+    - dict-vocabulary
+  operationId: get_api_v2_dict_vocabulary_dict_vocabulary_
+  description: 实现:`DictVocabularyController@show`
+  parameters:
+    -
+      name: dict_vocabulary
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 dict-vocabulary/{dict_vocabulary}'
+  tags:
+    - dict-vocabulary
+  operationId: put_api_v2_dict_vocabulary_dict_vocabulary_
+  description: 实现:`DictVocabularyController@update`
+  parameters:
+    -
+      name: dict_vocabulary
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 dict-vocabulary/{dict_vocabulary}'
+  tags:
+    - dict-vocabulary
+  operationId: patch_api_v2_dict_vocabulary_dict_vocabulary_
+  description: 实现:`DictVocabularyController@update`
+  parameters:
+    -
+      name: dict_vocabulary
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 dict-vocabulary/{dict_vocabulary}'
+  tags:
+    - dict-vocabulary
+  operationId: delete_api_v2_dict_vocabulary_dict_vocabulary_
+  description: 实现:`DictVocabularyController@destroy`
+  parameters:
+    -
+      name: dict_vocabulary
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 103 - 0
openapi/public/assets/protocol/resources/auto/v2-dict-vocabulary.yaml

@@ -0,0 +1,103 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-dict-vocabulary.yaml
+get:
+  summary: '列出 dict-vocabulary'
+  tags:
+    - dict-vocabulary
+  operationId: get_api_v2_dict_vocabulary
+  description: 实现:`DictVocabularyController@index`
+  parameters:
+    -
+      name: view
+      in: query
+      schema:
+        type: string
+        enum:
+          - dict_name
+          - dict_short_name
+    -
+      name: name
+      in: query
+      schema:
+        type: string
+    -
+      name: stream
+      in: query
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      schema:
+        type: string
+        default: asc
+    -
+      name: offset
+      in: query
+      schema:
+        type: string
+    -
+      name: limit
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 dict-vocabulary'
+  tags:
+    - dict-vocabulary
+  operationId: post_api_v2_dict_vocabulary
+  description: 实现:`DictVocabularyController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 106 - 0
openapi/public/assets/protocol/resources/auto/v2-dict.yaml

@@ -0,0 +1,106 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-dict.yaml
+get:
+  summary: '列出 dict'
+  tags:
+    - dict
+  operationId: get_api_v2_dict
+  description: 实现:`DictController@index`
+  parameters:
+    -
+      name: word
+      in: query
+      schema:
+        type: string
+    -
+      name: lang
+      in: query
+      schema:
+        type: string
+        default: zh
+    -
+      name: content
+      in: query
+      schema:
+        type: string
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: '新建 dict'
+  tags:
+    - dict
+  operationId: post_api_v2_dict
+  description: 实现:`DictController@store`
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 38 - 0
openapi/public/assets/protocol/resources/auto/v2-discussion-anchor-id.yaml

@@ -0,0 +1,38 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-discussion-anchor-id.yaml
+get:
+  summary: '获取 discussion 锚点的数据'
+  tags:
+    - discussion-anchor
+  operationId: get_api_v2_discussion_anchor_id_
+  description: |-
+    以句子为最小单位返回锚点上下文:res_type=wbw 时,由单词定位到所属 wbw block 与巴利句子,
+    再用该 block 的 channel 渲染出句子内容的 markdown。其他 res_type 暂返回空字符串。
+    不做登录与权限校验;wbw、wbw block 或句子任一查不到时分别返回 no wbw data / no wbwBlock data / no sent data。
+
+    实现:`DiscussionController@anchor`
+  parameters:
+    -
+      name: id
+      in: path
+      required: true
+      schema:
+        type: string
+      description: '讨论 id'
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 125 - 0
openapi/public/assets/protocol/resources/auto/v2-discussion-count-discussion-count.yaml

@@ -0,0 +1,125 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-discussion-count-discussion-count.yaml
+get:
+  summary: '获取单个 discussion-count/{discussion_count}'
+  tags:
+    - discussion-count
+  operationId: get_api_v2_discussion_count_discussion_count_
+  description: 实现:`DiscussionCountController@show`
+  parameters:
+    -
+      name: discussion_count
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+put:
+  summary: '更新 discussion-count/{discussion_count}'
+  tags:
+    - discussion-count
+  operationId: put_api_v2_discussion_count_discussion_count_
+  description: 实现:`DiscussionCountController@update`
+  parameters:
+    -
+      name: discussion_count
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+patch:
+  summary: '更新 discussion-count/{discussion_count}'
+  tags:
+    - discussion-count
+  operationId: patch_api_v2_discussion_count_discussion_count_
+  description: 实现:`DiscussionCountController@update`
+  parameters:
+    -
+      name: discussion_count
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+delete:
+  summary: '删除 discussion-count/{discussion_count}'
+  tags:
+    - discussion-count
+  operationId: delete_api_v2_discussion_count_discussion_count_
+  description: 实现:`DiscussionCountController@destroy`
+  parameters:
+    -
+      name: discussion_count
+      in: path
+      required: true
+      schema:
+        type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

+ 121 - 0
openapi/public/assets/protocol/resources/auto/v2-discussion-count.yaml

@@ -0,0 +1,121 @@
+# 由 openapi/scripts/generate.php 生成,请勿手改;补充写到 overrides/v2-discussion-count.yaml
+get:
+  summary: '列出 discussion-count'
+  tags:
+    - discussion-count
+  operationId: get_api_v2_discussion_count
+  description: 实现:`DiscussionCountController@index`
+  parameters:
+    -
+      name: search
+      in: query
+      description: 搜索关键字
+      schema:
+        type: string
+    -
+      name: order
+      in: query
+      description: 排序字段
+      schema:
+        type: string
+    -
+      name: dir
+      in: query
+      description: 排序方向
+      schema:
+        type: string
+        enum:
+          - desc
+          - asc
+    -
+      name: limit
+      in: query
+      description: 每页记录数
+      schema:
+        type: number
+    -
+      name: offset
+      in: query
+      description: 从第几条记录开始提取
+      schema:
+        type: number
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+                properties:
+                  rows:
+                    type: array
+                    items:
+                      type: object
+                  count:
+                    type: integer
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'
+post:
+  summary: 课程模式业务逻辑
+  tags:
+    - discussion-count
+  operationId: post_api_v2_discussion_count
+  description: |-
+    标准答案channel:学生提问
+    学生channel: 老师批改作业
+    老师:
+    标准答案channel: 本期学生,老师(区分已经回复,未回复)
+    学生channel: 本期学生,老师
+    学生:
+    标准答案channel:我自己topic(区分已经回复,未回复)
+    学生自己channel: 我自己,本期老师
+    输入:
+    句子列表
+    courseId
+    返回数据
+    resId
+    type:'discussion':
+    my:number
+    myReplied:number
+    all:number
+    allReplied:number
+
+    实现:`DiscussionCountController@store`
+  requestBody:
+    required: false
+    content:
+      application/json:
+        schema:
+          type: object
+          properties:
+            course_id:
+              type: string
+            sentences:
+              type: string
+  responses:
+    200:
+      description: '成功。业务失败时 HTTP 仍可能为 200,以 ok 字段为准。'
+      content:
+        application/json:
+          schema:
+            type: object
+            properties:
+              ok:
+                type: boolean
+              message:
+                type: string
+              data:
+                type: object
+    401:
+      $ref: '../../main.yaml#/components/responses/Unauthorized'
+    422:
+      $ref: '../../main.yaml#/components/responses/ValidationError'

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä