@neuxnet/neux-cli 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +438 -0
  2. package/README.zh-CN.md +554 -0
  3. package/assets/container/assets/index.css +1 -0
  4. package/assets/container/assets/index.js +137 -0
  5. package/assets/container/assets/pageFrame.css +1 -0
  6. package/assets/container/assets/pageFrame.js +56 -0
  7. package/assets/container/assets/service.js +6 -0
  8. package/assets/container/assets/vconsole.js +931 -0
  9. package/assets/container/favicon.ico +0 -0
  10. package/assets/container/images/icon-arrow.png +0 -0
  11. package/assets/container/images/mini-action-white.png +0 -0
  12. package/assets/container/images/mini-action.png +0 -0
  13. package/assets/container/images/mini-arrow-left-white.png +0 -0
  14. package/assets/container/images/mini-arrow-left.jpg +0 -0
  15. package/assets/container/images/mini-arrow-left.png +0 -0
  16. package/assets/container/images/mini-close-white.png +0 -0
  17. package/assets/container/images/mini-close.png +0 -0
  18. package/assets/container/images/more.png +0 -0
  19. package/assets/container/images/search.jpg +0 -0
  20. package/assets/container/index.html +1 -0
  21. package/assets/container/pageFrame.html +1 -0
  22. package/assets/init/tabbar/home-active.png +0 -0
  23. package/assets/init/tabbar/home.png +0 -0
  24. package/assets/init/tabbar/list-active.png +0 -0
  25. package/assets/init/tabbar/list.png +0 -0
  26. package/assets/init/types/neux-api.d.ts +1402 -0
  27. package/package.json +68 -0
  28. package/scripts/generate-init-types.js +210 -0
  29. package/scripts/sync-compiler.js +22 -0
  30. package/scripts/sync-web-container.js +34 -0
  31. package/src/bin/cli.js +646 -0
  32. package/src/core/brand.js +11 -0
  33. package/src/core/compiler.js +305 -0
  34. package/src/core/defaults.js +12 -0
  35. package/src/core/dev.js +15 -0
  36. package/src/core/errors.js +17 -0
  37. package/src/core/fs.js +66 -0
  38. package/src/core/i18n.js +37 -0
  39. package/src/core/init.js +866 -0
  40. package/src/core/lifecycle.js +32 -0
  41. package/src/core/manifest.js +72 -0
  42. package/src/core/pack.js +156 -0
  43. package/src/core/package-info.js +27 -0
  44. package/src/core/preview-server.js +123 -0
  45. package/src/core/project.js +101 -0
  46. package/src/core/prompts.js +71 -0
  47. package/src/core/proxy-security.js +141 -0
  48. package/src/core/proxy.js +156 -0
  49. package/src/core/qr.js +41 -0
  50. package/src/core/terminal-qr.js +72 -0
  51. package/src/core/update.js +278 -0
  52. package/src/core/watch.js +113 -0
  53. package/src/core/web.js +649 -0
  54. package/src/core/zip.js +120 -0
  55. package/src/index.js +20 -0
  56. package/src/providers/service-client.js +149 -0
  57. package/src/providers/service-config.js +264 -0
  58. package/src/providers/service.js +146 -0
  59. package/src/providers/upload.js +112 -0
  60. package/vendor/dimina-compiler/bin/index.cjs +265 -0
  61. package/vendor/dimina-compiler/bin/index.js +263 -0
  62. package/vendor/dimina-compiler/compatibility-B-DoZtUX.cjs +395 -0
  63. package/vendor/dimina-compiler/compatibility-Cl3-DO6V.js +366 -0
  64. package/vendor/dimina-compiler/core/logic-compiler.cjs +378 -0
  65. package/vendor/dimina-compiler/core/logic-compiler.js +374 -0
  66. package/vendor/dimina-compiler/core/style-compiler.cjs +392 -0
  67. package/vendor/dimina-compiler/core/style-compiler.js +377 -0
  68. package/vendor/dimina-compiler/core/view-compiler.cjs +1601 -0
  69. package/vendor/dimina-compiler/core/view-compiler.js +1582 -0
  70. package/vendor/dimina-compiler/index.cjs +762 -0
  71. package/vendor/dimina-compiler/index.js +751 -0
  72. package/vendor/dimina-compiler/sourcemap-BgtIgqkC.cjs +1377 -0
  73. package/vendor/dimina-compiler/sourcemap-CKjhV9h7.js +1135 -0
@@ -0,0 +1,554 @@
1
+ # Neux CLI 中文文档
2
+
3
+ Neux CLI 是面向小程序项目的独立命令行工具,覆盖本地开发、`.wgt` 交付包构建、调试预览、上传、提审、状态查询,以及未来 IDE Node 侧集成。
4
+
5
+ ## 快速开始
6
+
7
+ ### npm 公仓全局安装
8
+
9
+ Neux CLI 已发布到 npm 公仓的 `@neuxnet` scope 下。如果本机 `.npmrc` 曾经把
10
+ `@neuxnet` scope 指向私仓,安装时需要显式覆盖为 npm 公仓:
11
+
12
+ 全局安装:
13
+
14
+ ```sh
15
+ npm install -g @neuxnet/neux-cli --registry=https://registry.npmjs.org/
16
+ neux --version
17
+ neux --help
18
+ ```
19
+
20
+ 升级到 npm 公仓最新版本:
21
+
22
+ ```sh
23
+ npm install -g @neuxnet/neux-cli@latest --registry=https://registry.npmjs.org/
24
+ ```
25
+
26
+ 如果本机配置中的 `@neuxnet:registry` 仍然覆盖命令行参数,请临时移除该配置,
27
+ 或使用单独的 npm user config,并将其 `registry` 设置为
28
+ `https://registry.npmjs.org/`。
29
+
30
+ 创建一个新小程序:
31
+
32
+ ```sh
33
+ npx @neuxnet/neux-cli init my-miniapp --app-id touristappid --name "My Miniapp"
34
+ cd my-miniapp
35
+ ```
36
+
37
+ 在已有小程序项目中安装 CLI:
38
+
39
+ ```sh
40
+ npm install -D @neuxnet/neux-cli
41
+ ```
42
+
43
+ 推荐在小程序项目的 `package.json` 中保留短命令:
44
+
45
+ ```json
46
+ {
47
+ "scripts": {
48
+ "build": "neux build",
49
+ "dev": "neux dev",
50
+ "upload": "neux upload --preview",
51
+ "debug": "neux debug",
52
+ "submit": "neux submit"
53
+ }
54
+ }
55
+ ```
56
+
57
+ 初始化项目时会把当前正在执行的 CLI 作为项目级 `devDependency` 写入
58
+ `package.json`。这是为了让 `npm run dev/build/debug/...` 优先从项目自己的
59
+ `node_modules/.bin` 解析 `neux`,从而让本机开发者、协作者和 CI 使用项目声明的
60
+ 同一版本范围,而不是依赖每台机器上未受项目管理的全局 CLI。提交初始化后生成的
61
+ lockfile 可以进一步锁定精确版本。版本号由 `neux init` 从当前 CLI 包的
62
+ `package.json` 动态读取,不再硬编码旧版本。
63
+
64
+ 这个依赖从“能否执行命令”的角度不是绝对必要:如果始终全局安装 CLI,脚本也
65
+ 可能运行。但不声明项目级依赖就无法保证不同机器和 CI 使用相同版本,容易出现
66
+ 编译、构建或上传行为不一致。因此推荐保留。若只想使用全局 CLI,可以删除该
67
+ `devDependency`,但同时应自行确保所有环境的 CLI 版本一致。
68
+
69
+ 常用命令:
70
+
71
+ ```sh
72
+ npx @neuxnet/neux-cli init my-miniapp
73
+ npm run dev
74
+ npm run build
75
+ npm run debug
76
+ npm run upload
77
+ npm run submit
78
+ ```
79
+
80
+ `npm run build` 会编译小程序并在项目内生成 `dist/release/<appId>.wgt`。`.wgt` 是当前唯一交付物。
81
+
82
+ `npm run dev` 启动的 H5 开发服务会在同一端口提供 `/proxy`。小程序中的
83
+ `wx.request` 在浏览器环境由 Container 转发到该路径,因此不需要每个小程序单独
84
+ 维护代理脚本。代理只用于本地 `dev`/`web`,不会进入 `.wgt` 或宿主运行时。
85
+
86
+ 代理请求体沿用小程序网络 API 的开发适配格式:
87
+
88
+ ```json
89
+ {
90
+ "url": "https://api.example.com/path",
91
+ "method": "POST",
92
+ "data": {},
93
+ "header": {}
94
+ }
95
+ ```
96
+
97
+ 开发服务只允许来自本机的浏览器 Origin,并拒绝私有网段、回环地址和保留地址的
98
+ 目标,避免把开发代理变成任意内网转发器。需要允许额外开发 Origin 时,可设置
99
+ `DIMINA_PROXY_ALLOWED_ORIGINS`,多个 Origin 使用逗号分隔。
100
+
101
+ ## 常用命令
102
+
103
+ ```sh
104
+ neux init ./my-miniapp --app-id touristappid --name "My Miniapp"
105
+ neux --version
106
+ neux cli-version --json
107
+ neux inspect --json
108
+ neux dev --port 7788
109
+ neux build --version 1.0.1 --json
110
+ neux config doctor --server-url https://miniapp.example.com --json
111
+ neux debug --page-path pages/index/index --query foo=bar
112
+ neux upload --preview --changelog "Release notes" --channel test
113
+ neux submit --version-id 123 --channel test
114
+ neux status --json
115
+ neux meta --json
116
+ neux audit-status --version-id 123 --json
117
+ ```
118
+
119
+ 当命令在小程序项目根目录中执行时,`--project` 默认指向当前目录。
120
+
121
+ ## 初始化小程序
122
+
123
+ `neux init <dir>` 会创建一个可运行的示例小程序,包含计数器、双 Tab 页面和列表渲染示例,同时生成 AI 开发上下文文件:
124
+
125
+ ```text
126
+ project.config.json
127
+ package.json
128
+ app.json
129
+ app.js
130
+ app.nxss
131
+ pages/index/index.json
132
+ pages/index/index.js
133
+ pages/index/index.nxml
134
+ pages/index/index.nxss
135
+ AGENTS.md
136
+ llms.txt
137
+ mcp.example.json
138
+ ```
139
+
140
+ 示例:
141
+
142
+ ```sh
143
+ neux init ./my-miniapp --app-id touristappid --name "My Miniapp"
144
+ cd my-miniapp
145
+ neux dev
146
+ neux build
147
+ ```
148
+
149
+ 直接在终端执行 `neux init ./my-miniapp` 时,CLI 会交互式询问 `Project name`、`App ID`、`Server URL` 和隐藏输入的 `CLI Key`。`Server URL` 默认是 `https://demo-c.paas.superapp.neuvision.cn`,按回车即可使用。App ID 和 Server URL 写入项目;CLI Key 按 App ID 保存到用户级 `~/.neux/config.json`,不会写入项目文件或 Git。初始化模板还会生成 `AGENTS.md`、`llms.txt` 和 `mcp.example.json`,其中包含官方 AI 文档、LLM 文本导出、MCP endpoint 和 Agent Skill 入口。目标目录必须不存在或为空;如果需要写入已有目录,可以使用 `--force`。
150
+
151
+ 初始化后可以这样运行:
152
+
153
+ ```sh
154
+ cd my-miniapp
155
+ npm install
156
+ npm run dev
157
+ npm run debug
158
+ ```
159
+
160
+ 修改当前项目的 CLI Key:
161
+
162
+ ```sh
163
+ neux config set
164
+ ```
165
+
166
+ 也可以直接传入新 Key:
167
+
168
+ ```sh
169
+ neux config set --key NEW_CLI_KEY
170
+ ```
171
+
172
+ 脚本或 CI 可以使用 `--no-interactive`,并通过 `--app-id`、`--server-url`、`--key` 传值。`--json` 也会自动关闭交互。
173
+
174
+ ## 命令说明
175
+
176
+ | 命令 | 作用 |
177
+ | --- | --- |
178
+ | `neux init <dir>` | 从 0 创建一个新的小程序项目 |
179
+ | `neux inspect` | 读取小程序项目信息 |
180
+ | `neux dev` | 编译、打开 H5 容器、监听文件并热更新 |
181
+ | `neux build` | 构建客户端 `.wgt` 交付包,默认输出到 `dist/release` |
182
+ | `neux upload` | 上传 signed service 体验包 |
183
+ | `neux debug` | 上传调试预览包,并输出 deeplink 与可扫码终端二维码 |
184
+ | `neux submit` | 提交体验版本审核 |
185
+ | `neux status` / `neux meta` | 查询 signed service 版本信息 |
186
+ | `neux audit-status` | 查询审核状态 |
187
+ | `neux config doctor` | 诊断 signed service 配置 |
188
+ | `neux config set` | 交互式修改当前项目的 CLI Key |
189
+ | `neux update` | 检查并更新 CLI |
190
+ | `neux --version` / `neux cli-version` | 查看当前安装的 CLI 版本 |
191
+ | `neux compile` | 仅执行内置小程序编译 |
192
+ | `neux wgt` | `neux build` 的兼容别名 |
193
+
194
+ 兼容命令包括 `debug-preview`、`service-preview`、`submit-audit`、`version`、`audit`、`preview`、`web`。新脚本优先使用 `build`、`dev`、`debug`、`upload`、`submit`。
195
+
196
+ ## 更新 CLI
197
+
198
+ 手动检查更新:
199
+
200
+ ```sh
201
+ neux update --check
202
+ ```
203
+
204
+ 检查并更新到 npm registry 上的最新版本:
205
+
206
+ ```sh
207
+ neux update
208
+ ```
209
+
210
+ 未传 `--registry` 时,`neux update` 会优先读取当前 npm 配置里的 scope registry,例如 `@neuxnet:registry`,再回退到默认 `registry`。
211
+
212
+ 私服 registry:
213
+
214
+ ```sh
215
+ neux update --registry https://registry.example.com
216
+ ```
217
+
218
+ 自动更新默认关闭。需要自动更新时,可以在本次命令开启:
219
+
220
+ ```sh
221
+ NEUX_CLI_AUTO_UPDATE=1 neux dev
222
+ ```
223
+
224
+ 自动更新失败只会输出 warning,不会中断原命令。CI/CD 建议显式执行 `neux update --check --json` 或固定 CLI 版本,避免构建期间隐式变更工具链。
225
+
226
+ ## 默认输出目录
227
+
228
+ | 命令 | 默认输出 |
229
+ | --- | --- |
230
+ | `neux build` | `dist/release` |
231
+ | `neux wgt` | `dist/release` |
232
+ | `neux compile` | `dist/build` |
233
+ | `neux dev` | `dist/dev` |
234
+ | `neux web` | `dist/web` |
235
+ | `neux pack` | `dist/pack` |
236
+ | `neux preview` | `dist/preview` |
237
+
238
+ ## `.wgt` 交付包结构
239
+
240
+ `neux build`、`neux wgt` 和默认 signed service 上传命令都会生成客户端下载所需的 `.wgt` 文件。
241
+
242
+ 外层 `.wgt` 是 zip 文件,解压后必须只有两个文件:
243
+
244
+ ```text
245
+ config.json
246
+ <appId>.zip
247
+ ```
248
+
249
+ 内层 `<appId>.zip` 包含小程序生产/编译输出目录内的文件。CLI 不会直接压缩整个小程序源码目录。
250
+
251
+ ## 调试预览
252
+
253
+ `neux debug` 会先构建 `.wgt`,再上传调试预览包,并默认直接在终端展示可扫码的二维码:
254
+
255
+ ```sh
256
+ neux debug
257
+ ```
258
+
259
+ 可以指定启动页面和参数:
260
+
261
+ ```sh
262
+ neux debug \
263
+ --page-path pages/detail/index \
264
+ --query 'id=1' \
265
+ --scene 1001 \
266
+ --launch-from cli \
267
+ --location 31.2,121.5
268
+ ```
269
+
270
+ 二维码输出控制:
271
+
272
+ ```sh
273
+ neux debug --qr-format png --qr-output ./dist/release/preview.png
274
+ neux debug --qr-format terminal
275
+ neux debug --qr-format none
276
+ neux debug --qr-format none --qr-output ./dist/release/preview.qr.txt
277
+ neux debug --copy
278
+ ```
279
+
280
+ 默认终端二维码使用紧凑的 ANSI 上半块字符,显式设置字符上、下两个模块区域的黑白颜色,并保留 4 个模块静区。一个终端字符承载上下两行二维码模块,视觉比例接近正方形,同时减少终端默认前景色、背景色和行距差异对扫码的影响。PNG 仍可通过 `--qr-format png --qr-output <path>` 显式生成。
281
+
282
+ `--json` 模式不会默认创建图片,适合 CI 和 IDE 集成;如需图片,显式传入 `--qr-format png --qr-output <path>`:
283
+
284
+ ```sh
285
+ neux debug --json
286
+ ```
287
+
288
+ ## 上传与提审
289
+
290
+ 上传体验包:
291
+
292
+ ```sh
293
+ neux upload --preview --changelog "Release notes" --channel test
294
+ ```
295
+
296
+ `upload --preview` 返回预览信息时,即使服务端 `scanUrl` 只有 `appId` 和 `appVerType`,CLI 也会把本次打包的 `versionName` 追加为 deeplink 的 `version` 查询参数。
297
+
298
+ 提交审核:
299
+
300
+ ```sh
301
+ neux submit --version-id 123 --channel test
302
+ ```
303
+
304
+ 查询版本信息:
305
+
306
+ ```sh
307
+ neux status --json
308
+ neux meta --json
309
+ ```
310
+
311
+ 查询审核状态:
312
+
313
+ ```sh
314
+ neux audit-status --version-id 123 --json
315
+ ```
316
+
317
+ `--changelog` 会作为上传变更说明,同时兼容填充 `desc`。`--channel` 用于测试通道、灰度通道或后端定义的环境通道。
318
+
319
+ ## Signed Service 配置
320
+
321
+ signed service 使用 `appId + key` 对机器请求签名。请求头包含:
322
+
323
+ - `X-App-Id`
324
+ - `X-Timestamp`
325
+ - `X-Nonce`
326
+ - `X-Signature`
327
+
328
+ 配置优先级:
329
+
330
+ 1. CLI 参数:`--server-url`、`--app-id`、`--key`、`--profile`
331
+ 2. 环境变量:`NEUX_CLI_SERVER_URL`、`NEUX_CLI_APP_ID`、`NEUX_CLI_PROFILE`、应用或 profile 专属 key、`NEUX_CLI_KEY`
332
+ 3. 项目配置:`neux.config.json`,或 `project.config.json` 顶层字段
333
+ 4. 用户 profile:`$NEUX_CLI_CONFIG` 或 `~/.neux/config.json`
334
+
335
+ 项目配置示例:
336
+
337
+ ```json
338
+ {
339
+ "appId": "app_xxx",
340
+ "profile": "demo-private",
341
+ "versionName": "1.2.3",
342
+ "versionCode": 12
343
+ }
344
+ ```
345
+
346
+ 也可以写在 `project.config.json` 中:
347
+
348
+ ```json
349
+ {
350
+ "appid": "app_xxx",
351
+ "compileType": "miniprogram",
352
+ "miniprogramRoot": "",
353
+ "neuxCli": {
354
+ "serverUrl": "https://demo-c.paas.superapp.neuvision.cn"
355
+ },
356
+ "versionName": "1.2.3",
357
+ "versionCode": 12
358
+ }
359
+ ```
360
+
361
+ `serverUrl` 也可以写在 `project.config.json` 顶层;模板默认使用 `neuxCli.serverUrl`,便于和 IDE 项目字段区分。`project.private.config.json` 可以覆盖本地非敏感配置,例如 `appid`、`projectname`、`versionName`、`versionCode`、`setting`、`packOptions`、`neuxCli.serverUrl`。
362
+
363
+ CLI Key 不写入项目配置或 Git,而是按 App ID 保存在用户级 `~/.neux/config.json` 的 `keys` 字段中。需要切换或更新时执行 `neux config set`;CI 仍建议使用 `--key` 或环境变量。
364
+
365
+ ## 多小程序与 CI/CD
366
+
367
+ 推荐为每个小程序注入应用专属 key:
368
+
369
+ ```sh
370
+ export NEUX_CLI_SERVER_URL=https://miniapp.example.com
371
+ export NEUX_CLI_KEY_WXBAF4B47DE04F1D8A=key_xxx
372
+ npm run upload
373
+ ```
374
+
375
+ 环境变量后缀会把 appId 或 profile 转成大写,并把非字母数字字符替换为 `_`。
376
+
377
+ key 解析顺序:
378
+
379
+ 1. `--key`
380
+ 2. `NEUX_CLI_KEY_<APPID_NORMALIZED>`
381
+ 3. `NEUX_CLI_KEY_<PROFILE_NORMALIZED>`
382
+ 4. `NEUX_CLI_KEY`
383
+ 5. 用户级 `~/.neux/config.json` 中当前 App ID 对应的 CLI Key
384
+
385
+ GitHub Actions 示例:
386
+
387
+ ```yaml
388
+ env:
389
+ NEUX_CLI_SERVER_URL: https://miniapp.example.com
390
+ NEUX_CLI_KEY_WXBAF4B47DE04F1D8A: ${{ env.MINIAPP_BASE_KEY }}
391
+
392
+ steps:
393
+ - run: npm run upload
394
+ ```
395
+
396
+ 配置缺失时,可以运行:
397
+
398
+ ```sh
399
+ neux config doctor --json
400
+ ```
401
+
402
+ 诊断输出会显示缺失字段、配置来源、可用 key 环境变量名和 key 是否存在,但不会打印 key 值。
403
+
404
+ ## 版本号与版本 code
405
+
406
+ `neux build` 和 signed service 上传命令按以下顺序读取版本:
407
+
408
+ 1. CLI 参数:`--version-name`、`--version`、`--version-code`
409
+ 2. 项目配置:`neux.config.json`、`project.config.json` 顶层 `versionName` / `versionCode`
410
+ 3. `package.json` 的 `version`,用于 `versionName`
411
+ 4. 默认值:`versionName = 1.0.0`,`versionCode = 1`
412
+
413
+ 示例:
414
+
415
+ ```sh
416
+ neux build --version-name 1.2.3 --version-code 12
417
+ neux upload --preview --version 1.2.3
418
+ ```
419
+
420
+ ## JSON 输出约定
421
+
422
+ 一次性命令在 `--json` 模式下只向 stdout 写入一个 JSON 对象:
423
+
424
+ ```sh
425
+ neux build --json
426
+ neux upload --preview --json
427
+ ```
428
+
429
+ 长时间运行的开发命令会输出 JSON Lines:
430
+
431
+ ```sh
432
+ neux dev --json
433
+ neux preview --json --stay
434
+ ```
435
+
436
+ 稳定事件名包括:
437
+
438
+ - `build-start`
439
+ - `build-success`
440
+ - `build-error`
441
+ - `ready`
442
+ - `reload`
443
+ - `close`
444
+
445
+ 在 JSON 模式下,编译进度日志会重定向到 stderr,stdout 保持机器可读。
446
+
447
+ ## Provider 适配器
448
+
449
+ 默认不传 `--provider` 时,`upload`、`debug`、`submit` 等命令使用 signed service。
450
+
451
+ 如果要测试自定义适配器,可以传入 provider 模块:
452
+
453
+ ```sh
454
+ neux upload --provider ./provider.mjs --json
455
+ neux debug-preview --provider ./provider.mjs --build --json
456
+ neux submit --provider ./provider.mjs --json
457
+ ```
458
+
459
+ provider 模块可以导出 `createProvider(options)`、默认 provider 对象或命名导出 `provider`:
460
+
461
+ ```js
462
+ export function createProvider(options) {
463
+ return {
464
+ async upload({ artifact, project }) {
465
+ return {
466
+ ok: true,
467
+ provider: 'example',
468
+ appId: project.appId,
469
+ packagePath: artifact.packagePath,
470
+ }
471
+ },
472
+ }
473
+ }
474
+ ```
475
+
476
+ `--provider local-file` 可用于 CI smoke test。它只写本地 JSON 记录,不访问远程服务。
477
+
478
+ ## Node API
479
+
480
+ CLI 是 Node API 的薄封装,未来 IDE 可以复用相同生命周期,而不需要解析终端输出。
481
+
482
+ ```js
483
+ import {
484
+ buildProject,
485
+ inspectProject,
486
+ packProject,
487
+ startDev,
488
+ startPreview,
489
+ startWeb,
490
+ } from '@neuxnet/neux-cli'
491
+
492
+ const info = await inspectProject({ project: './miniapp' })
493
+ const build = await buildProject({ project: './miniapp' })
494
+ const pack = await packProject({ project: './miniapp', out: './artifacts' })
495
+
496
+ const dev = await startDev({ project: './miniapp', port: 0, open: false })
497
+ console.log(dev.url)
498
+ await dev.close()
499
+ ```
500
+
501
+ 长时间运行的 API 支持 `onEvent(event)`,便于 IDE 消费稳定生命周期事件。
502
+
503
+ ## 内置编译器
504
+
505
+ 发布后的 CLI 会内置小程序编译器。小程序项目不需要显式安装额外的编译器包。
506
+
507
+ 在仓库内发布前刷新内置 compiler:
508
+
509
+ ```sh
510
+ pnpm --dir ../fe build
511
+ npm run sync:compiler
512
+ ```
513
+
514
+ 一键准备发布资源:
515
+
516
+ ```sh
517
+ npm run prepare:publish
518
+ ```
519
+
520
+ 仅在测试自定义 compiler 时使用:
521
+
522
+ ```sh
523
+ neux build --compiler-module ./mock-compiler.mjs
524
+ ```
525
+
526
+ ## 本地开发与验证
527
+
528
+ 在 `neux-cli` 包内运行:
529
+
530
+ ```sh
531
+ npm test
532
+ npm run smoke:help
533
+ npm run pack:dry
534
+ ```
535
+
536
+ 在示例小程序中验证 `.wgt`:
537
+
538
+ ```sh
539
+ cd ../fe/example/base
540
+ npm run build
541
+ unzip -l dist/release/*.wgt
542
+ ```
543
+
544
+ 外层 `.wgt` 应只包含 `config.json` 和 `<appId>.zip`。
545
+ ### 语言
546
+
547
+ CLI 默认使用英文。可以通过 `--lang zh-CN` 或 `NEUX_CLI_LANG=zh-CN` 切换 CLI 的帮助和终端结果标签:
548
+
549
+ ```bash
550
+ neux --help --lang zh-CN
551
+ NEUX_CLI_LANG=zh-CN neux init ./miniapp
552
+ ```
553
+
554
+ Web 容器默认使用英文。启动 `neux dev` 时,可以使用 `neux dev --lang zh-CN`,或者在页面 URL 中添加 `?lang=zh-CN`。`--json` 输出保持稳定的机器可读字段,不随语言改变。
@@ -0,0 +1 @@
1
+ .dimina-native-webview{width:100%;height:100%;display:flex;position:absolute;top:0;left:0}.dimina-native-webview.dimina-native-webview--custom-nav .dimina-native-webview__navigation{display:none}.dimina-native-webview.dimina-native-webview--custom-nav .dimina-native-webview__body{padding-top:0}.dimina-native-webview__navigation{box-sizing:content-box;z-index:10;background-color:#f7f7f7;height:50.336px;padding-top:50.336px;display:flex;position:absolute;top:0;left:0;right:0}.dimina-native-webview__navigation .dimina-native-webview__navigation-content{justify-content:center;align-items:center;width:100%;display:flex;position:relative}.dimina-native-webview__navigation .dimina-native-webview__navigation-content .dimina-native-webview__navigation-left-btn{cursor:pointer;width:11.44px;height:50.336px;position:absolute;top:0;left:19.448px}.dimina-native-webview__navigation .dimina-native-webview__navigation-content .dimina-native-webview__navigation-home-btn{cursor:pointer;background-position:50%;background-repeat:no-repeat;background-size:22.88px 22.88px;border-radius:50%;width:36.608px;height:36.608px;display:none;position:absolute;top:6.864px;left:17.16px}.dimina-native-webview__navigation .dimina-native-webview__navigation-content .dimina-native-webview__navigation-home-btn.dimina-native-webview__navigation-home-btn--after-back{left:42.328px}.dimina-native-webview__navigation .dimina-native-webview__navigation-title{text-align:center;font-size:19.448px}.dimina-native-webview__navigation.dimina-native-webview__navigation--white .dimina-native-webview__navigation-title{color:#fff}.dimina-native-webview__navigation.dimina-native-webview__navigation--white .dimina-native-webview__navigation-left-btn{background:url(/images/mini-arrow-left-white.png) 0/11.44px 20.02px no-repeat}.dimina-native-webview__navigation.dimina-native-webview__navigation--white .dimina-native-webview__navigation-home-btn{background-color:#ffffff3d;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z' fill='%23fff'/%3E%3C/svg%3E")}.dimina-native-webview__navigation.dimina-native-webview__navigation--black .dimina-native-webview__navigation-title{color:#000}.dimina-native-webview__navigation.dimina-native-webview__navigation--black .dimina-native-webview__navigation-left-btn{background:url(/images/mini-arrow-left.png) 0/11.44px 20.02px no-repeat}.dimina-native-webview__navigation.dimina-native-webview__navigation--black .dimina-native-webview__navigation-home-btn{background-color:#d6d6d6;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z' fill='%23000'/%3E%3C/svg%3E")}.dimina-native-webview__body{flex:1;padding-top:100.672px;display:flex}.dimina-native-webview__root{flex:1;position:relative;overflow:hidden}.dimina-native-webview__window{border:0;width:100%;height:100%;position:absolute;top:0;left:0}.dimina-mini-app,.dimina-mini-app__webviews,.dimina-mini-app__launch-screen{background-color:#fff;position:absolute;inset:0}.dimina-mini-app-navigation__actions{box-sizing:border-box;z-index:10;border-radius:18.304px;flex-direction:row;width:94.952px;height:36.608px;display:flex;position:absolute;top:46.904px;right:8.008px;overflow:hidden}.dimina-mini-app-navigation__actions.dimina-mini-app-navigation__actions--black{background-color:#fffc;border:1px solid #eaeaeacc}.dimina-mini-app-navigation__actions.dimina-mini-app-navigation__actions--black .dimina-mini-app-navigation__actions-variable{background-image:url(/images/mini-action.png)}.dimina-mini-app-navigation__actions.dimina-mini-app-navigation__actions--black .dimina-mini-app-navigation__actions-variable:after{background-color:#ccc}.dimina-mini-app-navigation__actions.dimina-mini-app-navigation__actions--black .dimina-mini-app-navigation__actions-close{background-image:url(/images/mini-close.png)}.dimina-mini-app-navigation__actions.dimina-mini-app-navigation__actions--white{background-color:#0003;border:1px solid #eaeaeacc}.dimina-mini-app-navigation__actions.dimina-mini-app-navigation__actions--white .dimina-mini-app-navigation__actions-variable{background-image:url(/images/mini-action-white.png)}.dimina-mini-app-navigation__actions.dimina-mini-app-navigation__actions--white .dimina-mini-app-navigation__actions-variable:after{background-color:#ccc}.dimina-mini-app-navigation__actions.dimina-mini-app-navigation__actions--white .dimina-mini-app-navigation__actions-close{background-image:url(/images/mini-close-white.png)}.dimina-mini-app-navigation__actions li{cursor:pointer;flex:1;list-style:none;position:relative}.dimina-mini-app-navigation__actions-variable{background-position:50%;background-repeat:no-repeat;background-size:21.736px}.dimina-mini-app-navigation__actions-variable:after{content:"";opacity:.8;width:1px;height:22.88px;position:absolute;top:50%;right:0;transform:translateY(-50%)}.dimina-mini-app-navigation__actions-close{background-position:50%;background-repeat:no-repeat;background-size:20.02px 20.02px}@keyframes animX{0%{left:-4.004px}to{left:72.644px}}@keyframes animY{0%{top:-4.004px}to{top:72.644px}}.dimina-mini-app__launch-screen{z-index:8;background-color:#fff;display:none}.dimina-mini-app__launch-screen .dimina-mini-app__launch-screen-content{flex-direction:column;align-items:center;display:flex;position:absolute;top:308.88px;left:50%;transform:translate(-50%)}.dimina-mini-app__launch-screen .dimina-mini-app__logo{width:76.648px;height:76.648px;position:relative}.dimina-mini-app__launch-screen .dimina-mini-app__logo .dimina-mini-app__logo-img{z-index:1;border-radius:50%;width:48.048px;height:48.048px;position:absolute;top:50%;left:50%;overflow:hidden;transform:translate(-50%,-50%)}.dimina-mini-app__launch-screen .dimina-mini-app__logo .dimina-mini-app__logo-img img{width:100%;height:100%;position:absolute;top:0;left:0}.dimina-mini-app__launch-screen .dimina-mini-app__logo .dimina-mini-app__logo-circle{z-index:2;box-sizing:border-box;border:1px solid #e9e9e9;border-radius:50%;width:76.648px;height:76.648px;position:absolute;top:0;left:0}.dimina-mini-app__launch-screen .dimina-mini-app__logo .dimina-mini-app__green-point{z-index:3;background-color:#fff;border-radius:50%;width:8.008px;height:8.008px;animation:.8s cubic-bezier(.36,0,.64,1) -400ms infinite alternate animX,.8s cubic-bezier(.36,0,.64,1) infinite alternate animY;position:absolute;top:0;left:0}.dimina-mini-app__launch-screen .dimina-mini-app__logo .dimina-mini-app__green-point:after{content:"";background-color:#59be6b;border-radius:50%;width:4.004px;height:4.004px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.dimina-mini-app__launch-screen .dimina-mini-app__name{color:#333;text-align:center;padding-top:20.592px;font-size:18.876px}.dimina-mini-app__webviews{z-index:1;box-sizing:border-box;padding-bottom:10px}.dimina-tabbar{min-height:56.056px;padding-bottom:env(safe-area-inset-bottom);box-sizing:border-box;justify-content:space-around;align-items:stretch;display:flex}.dimina-tabbar-item{flex-direction:column;flex:1;justify-content:center;align-items:center;gap:3.432px;min-width:0;padding:6.864px 0 5.72px;display:flex;position:relative}.dimina-tabbar-icon{object-fit:contain;flex-shrink:0;width:28.6px;height:28.6px}.dimina-tabbar-text{white-space:nowrap;text-overflow:ellipsis;max-width:100%;font-size:11.44px;line-height:1.2;overflow:hidden}.dimina-tabbar-badge{color:#fff;box-sizing:border-box;background:#fa5151;border-radius:10.296px;justify-content:center;align-items:center;min-width:20.592px;height:20.592px;padding:0 5.72px;font-size:10.296px;line-height:20.592px;position:absolute;top:4.576px;right:calc(50% - 16.016px);transform:translate(50%)}.dimina-tabbar-badge.is-red-dot,.dimina-tabbar-badge.is-empty{border-radius:50%;width:10.296px;min-width:10.296px;height:10.296px;padding:0;font-size:0;line-height:0}.dimina-mini-app-menu__mask{z-index:999;opacity:0;background:#0000006b;transition:opacity .24s ease-in-out;display:none;position:fixed;inset:0}.dimina-mini-app-menu__mask.show{opacity:1}.dimina-mini-app-menu{padding:0 16.016px 29.744px;padding-bottom:max(29.744px, 16.016px + env(safe-area-inset-bottom));z-index:1000;background:linear-gradient(#f8fafc 0%,#fff 18% 100%);border-radius:18.304px 18.304px 0 0;flex-direction:column;gap:0;max-height:240.24px;transition:transform .24s ease-in-out;display:flex;position:fixed;bottom:0;left:0;right:0;overflow:hidden;transform:translateY(100%);box-shadow:0 -3.432px 22.88px #0f172a1f}.dimina-mini-app-menu.show{transform:translateY(0)}.dimina-mini-app-menu__handle{background:#0f172a24;border-radius:999px;flex-shrink:0;width:41.184px;height:4.576px;margin:10.296px auto 13.728px}.dimina-mini-app-menu__app{align-items:center;width:100%;padding-bottom:12.584px;display:flex}.dimina-mini-app-menu__app-logo{background:#f1f5f9;border-radius:13.728px;flex-shrink:0;width:50.336px;height:50.336px;margin-right:11.44px;overflow:hidden;box-shadow:inset 0 0 0 1px #0f172a0f}.dimina-mini-app-menu__app-logo-img{object-fit:cover;width:100%;height:100%;display:block}.dimina-mini-app-menu__app-meta{flex:1;min-width:0}.dimina-mini-app-menu__app-name{color:#0f172a;margin:0 0 4.576px;font-size:19.448px;font-weight:700;line-height:1.3}.dimina-mini-app-menu__app-id{color:#94a3b8;word-break:break-all;margin:0 0 3.432px;font-size:12.584px;line-height:1.4}.dimina-mini-app-menu__app-desc{color:#64748b;word-break:break-all;margin:0;font-size:13.728px;line-height:1.5}.dimina-mini-app-menu__quick-actions{grid-template-columns:repeat(4,minmax(0,1fr));gap:9.152px;width:100%;padding-bottom:13.728px;display:grid}.dimina-mini-app-menu__quick-action{color:#0f172a;background:#f8fafc;border:0;border-radius:13.728px;flex-direction:column;justify-content:center;align-items:center;gap:5.72px;padding:9.152px 3.432px;display:flex;box-shadow:inset 0 0 0 1px #0f172a0d}.dimina-mini-app-menu__quick-action.is-danger{color:#dc2626}.dimina-mini-app-menu__quick-action.is-danger .dimina-mini-app-menu__quick-action-icon{color:#dc2626;background:#fee2e2}.dimina-mini-app-menu__quick-action-icon{background:#e2e8f0;border-radius:50%;justify-content:center;align-items:center;width:27.456px;height:27.456px;font-size:12.584px;font-weight:700;display:flex}.dimina-mini-app-menu__quick-action-label{font-size:11.44px;line-height:1.4}.dimina-mini-app-menu__footer{width:100%;margin-top:5.72px;display:block}.dimina-mini-app-menu__footer-btn{color:#0f172a;background:#eef2f7;border:0;border-radius:12.584px;width:100%;height:48.048px;font-size:16.016px;font-weight:600}.dimina-toast-mask{z-index:1040;pointer-events:auto;background:0 0;position:absolute;inset:0}.dimina-toast{z-index:1050;box-sizing:border-box;pointer-events:none;background-color:#4c4c4c;background-repeat:no-repeat;width:120px;height:120px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.dimina-toast.dimina-toast--text-only{border-radius:6px;width:auto;max-width:70%;height:auto;padding:12px 18px}.dimina-toast.dimina-toast--text-only p{color:#fff;text-align:center;white-space:pre-wrap;font-size:14px;line-height:1.4}.dimina-toast.dimina-toast--success{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKMAAACBCAYAAACsCAq9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAF7WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNi4wLWMwMDYgNzkuZGFiYWNiYiwgMjAyMS8wNC8xNC0wMDozOTo0NCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCAyMi40IChNYWNpbnRvc2gpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMy0wNS0yNFQwNzowOTo0MyswODowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjMtMDUtMjRUMDc6MTE6MzgrMDg6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjMtMDUtMjRUMDc6MTE6MzgrMDg6MDAiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6M2FkYzc0OWQtNzY3ZC00NTcyLWFlOGMtMDMyNDVjYTMyYzFhIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjc3RjM2Rjg1RTRFNzExRUQ5MDI1REY5OTdGMjQ0MDJDIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6NzdGMzZGODVFNEU3MTFFRDkwMjVERjk5N0YyNDQwMkMiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JHQiBJRUM2MTk2Ni0yLjEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3N0YzNkY4MkU0RTcxMUVEOTAyNURGOTk3RjI0NDAyQyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3N0YzNkY4M0U0RTcxMUVEOTAyNURGOTk3RjI0NDAyQyIvPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozYWRjNzQ5ZC03NjdkLTQ1NzItYWU4Yy0wMzI0NWNhMzJjMWEiIHN0RXZ0OndoZW49IjIwMjMtMDUtMjRUMDc6MTE6MzgrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMi40IChNYWNpbnRvc2gpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDwvcmRmOlNlcT4gPC94bXBNTTpIaXN0b3J5PiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvICKDoAAAVwSURBVHic7d1bVus4EEbhTa8zMDGyLkaGe0AwhZyHoCaE2PFFlyr53y/wgpM43xKJLdkvl8sFpTz05/Pzs/dzULF6B/4DrPSG/5TeoBq2xBVi/h0Kg/yn5MbUsCW+Ieb+RRhV4xK/IeaKghRGtVRiHmKuGEhhVHMlnkPMFQH58vHxcXQbarwS6yHe9gpMex9UI6O6L7EPIl9/l/Y+sDCq2xL7IeZ2gxRGlUsch5jbBVIYFZSFmNsMUhiVUR5ibhNIYTx3xvWwTM1WgxTG82bUh5hbBVIYz5nRDmLuKUhhPF9Ge4i5RZDCeK6MfhBzs48vjOfJ6A8RFg4jCeM5MnxAzCUegBTG8TN8Qcwl7kAK49gZPiHmEjcghXHcDN8Qc4kvkJrPOGZGDIi3vWpkHC8jIERgEsaxMoJCBH1mHCkjMEQQxlEygkMEYRwhYwCIIIzRMwaBCMIYOWMgiCCMUTMGgwjCGDEjFsSJlYv7dUm8WB1aJN+hiSvEVWlkjNPQEEEYozQ8RBDGCJ0CIgij904DEYTRc6eCCMLotdNBBGH02CkhgjB667QQQRi9lIgH8Y2CEEFnYDyUqHdJulq9UeEOWRoZ+5YQxP8Txn4lBPFHwtinhCD+ShjblxDEhwlj2xKCOJswtishiIsJY5sSgvi0WhiNWAdwa5YQxFXVwGhc12hEO6NQI0MQV1cao/FzsdCZQRqxFk5BR4hQFqPxeOefEaQhiJsrhdFY3vnvdH6hDTMEcVclMBrrdn6Ru7U7zxDE3R29cm1i+wd0Ny++cIYgHurIyJjY901xxBHSEMTD7cWYOHbIYiSQhiAWaQ/GRJljZyOANASxWFsxJsoexI0M0hDEom3BmKhzNiEiSEMQi7dlDUzNnZ+3bRUfo1RGPIirLknXu7UjY4uzKBFGSEMQq7XmOGPr03kThZdAFsoQxKo9Gxl7nFdO+JvpYghi9ZYw9pzgkPAD0hDEJs1h9DDTJtEfpCGIzXqE0egPMZfoB9IQxKbdYzT8vQGJ9iO14W8/PCs0RPj5bdrw/wa02OGG//1wX3iI8D0yGjHegNojpBFjP9w2BES4YjRivQG1QBqx9sMEvDAIRLhinHo/iR2VBvlOPIgeTwwcKmOMONSXAunhMNaWJgaECN+fGSfigrSDf5+KPJM2TQwKEX4f2okIcu8EC0F01qOD3mcAKYgOmzsdODJIQXTa0kSJEUEKouOeTSF75TpdPVJzIAXReWtmehvxQQpigLZcUcKIdWAYrm9q6vwctuZ+4VSttl7exIgHMlKnhQjb100b8f5lR+nUEGHfFSUMgSzd6SHC/mvtGAJZKkH86shVyAyBPJog3nT0YqGGQO5NEO8qdeVagdyWID7o6JVrb0v0X1oaIUGcqeTdDiZOeNZgY4K4UOn7wEwI5FyC+KQad8iaEMj7BHFFte4dOCGQOUFcWc27qk7EnBNZMkHcUMlv00tFm8JVIkHcWKv7TZ9thBTEHbXCCOcBKYg7a4kRxgcpiAdqjRHGBSmIB+uBEWIu9FpKEAvUCyOMM8FCEAu15aZENbKvn1HX1Yz6kaNLPUfGnBFzhBTEwnnACPFACmKFvGCEOCAFsVKeMIJ/kIJYMW8YwS9IQaycR4zgD6QgNsgrRvADUhAb5Rkj9AcpiA1rNZ/xaIn2Kw8FsXHeR8bcRLtlDBOD3ewnSlEwQhuQLR5DzRQJI9TFUnPbakXRMEIdNDW2qTYWESOU/Vw3IYguiooxd/Qb74Qguik6RtgPckIQXTUCRtgOckIQ3TUKRlgPckIQXTYSRni+0OsNQXTbaBhh/ny2Fk45b0SM8BukIAao9+rAmtnM78ppL5fLpfdzUAoY99+0Cthf4VNi31qSlvAAAAAASUVORK5CYII=);background-position:50% 30px;background-size:auto 24px;border-radius:10px}.dimina-toast.dimina-toast--loading{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAE9klEQVRIiYWXS4gcVRSGv3uremY6MXEmr5E8FDUItpGEVBa6UDoguPGxEdSQQJa68YGggkJ6dqIGQSJRIYK4kQ4oLly4kGkM6MIuRKRbkcAgE8cMI07IyLSR6f5d1Lk9tysTLCi6q/57zrn3nP88imazmczOzqbNZjOR5CR5Scns7GwqKbHbS3KNRsPbc1XSz5LmJG2J5SRdJyfJm76AOSIDXlLSbrcrkiq2KC0pCti01q/bAtbpdMZK68NGKpJizPulpSUBAhzgsyxz9gywE9gF+OhWhIfLA75Wqw3s/7fATysrK5Om1wEDuwEc5opEUmVubm5CUsXc7u1keyTtkDRuO/eSdkYnvl3SuHnKS3pS0u+S5iVNRScN4UglVZDkTWgsUhzitUnSXkn7zHDAdkWG7zBlXtJNZnRB0jNRyEKsg9tTD7gsywAG58+fHwC0Wq3g1n/tFjAVuzVy8yBy/Rlz6xxwrhSWpNvt+jzPAUTEtrCzRKPkGpO0W9LuhYWFTYbtCMddXV3dazL77KSXJD1QyopE0n7zXirJEzHvkKQDy8vLkxpldGqx2mN3ePeEpBOR4u/Nzc1S6myS9JqktqSvA6udpMTcczBy4VXgN2AtctXWkuuJfh1wBHgWeMHkAR4FnjNZgO8ML5hmghXgNmAyov6fwKUotiEt4nRyjKaMKFLwHWC/rVmzTf1o63CSHKN5mgB3AakJLQELhvWJc/F6owF7Hzhs/z+y+5qt83meO4xQlVKeeovrEUnbyrloMQxVLMZCytwr6aykyQ2wMUlpIFecb8MkL/2OYKXSOsQ6nc6YYaltMJYLmEdSxdKkKmlCUvXy5cub7TlmZ3zSNFI8UpODUXu31U49JWm7eW+q0+mMOUlHgS0lhoYrBxYjzOd5TpZlarVaANTr9SFmv6Fo3Ae8WiJhWHspkGkjo2yEZVnGBkZjufBuvGQ0vipOUgUYo8TQxcVFTU9P/xMJllNmqDTPc2ddrYxts83HmANWRrqTMfv/+qmPsajBDIkUKle73Y57dEyydCSdotbm5+fnq5Iek3RLOZ2izdwonQ5L+lhSdqN0cpKSbrebWBMfmCsy1gvAH8CXkauC6+KYxpgHTgAP2burwOvAFdYHib6TlEYKdlLU1wSg3+//lSTJV8Dfhvtut+t7vZ6yLItbnkypz/NcFu9jwFGKUgxFuTxnGxjEo8zDwONm9BrwzYULFz4zo+PA08CtGxgN/bsGPGVG+8AnwIvAD7bsEHD64sWLSbHVdaKcVDE1PChpotTaTkqakfRS9O6gipIaCHhG0odra2vHw7tIx92S3pJ01niUBHIlkm5W0eDjypNIulNSwwzvMGWbJb0t6bSkKVN2QNIHkt6TtL00YFRKmZIEVztg1YhQniIfMfxX4Eq9Xg+TZCBYUq1WHfCLxS8Fjtfr9SDvSjod4IKCcmsLi+6nKAIO+NxiF4SHii0j+sAbht1D0VodoJmZmWEr7Xa7HsAbMYLRPusMrVKkhAO+AHomvNGwFxSvRGQ61mq1BAxOnTpFnucJkNRqNQEDby6JczixXTkKdi+zPjmEPI1DMZwiDfuUYjyaMN3hQ8EHOzMzMyNfBmEScb1eT3bCN4F3KeVpJBN3pqBrBXgeeCXotYMMPVOr1YZfEuWxNnxJDIf7qM+GEvuyiukx7tsjMlGqpZJ8o9Hw9pWS/Ac0HxmxF+1AKQAAAABJRU5ErkJggg==);background-position:50% 30px;background-size:auto 24px;border-radius:10px}.dimina-toast p{color:#fff;text-overflow:ellipsis;text-align:center;justify-content:center;align-items:center;font-size:14px;line-height:160px;display:flex;overflow:hidden}.dimina-dialog-mask{z-index:1100;opacity:0;touch-action:none;overscroll-behavior:contain;background:#00000080;transition:opacity .2s;position:absolute;inset:0}.dimina-dialog-mask.show{opacity:1}.dimina-modal--occluded{display:none!important}.dimina-dialog{box-sizing:border-box;overscroll-behavior:contain;opacity:0;z-index:1110;pointer-events:none;background:#fff;border:0;border-radius:12px;outline:0;flex-direction:column;align-items:stretch;width:80%;max-width:320px;max-height:90%;padding:0;transition:transform .2s,opacity .2s;display:flex;position:absolute;top:50%;left:50%;overflow:hidden;transform:translate(-50%,-45%)scale(.92)}.dimina-dialog.show{opacity:1;pointer-events:auto;transform:translate(-50%,-50%)scale(1)}.dimina-dialog .dimina-dialog__title{color:#000;text-align:center;touch-action:none;margin:0;padding:24px 24px 8px;font-size:17px;font-weight:600;line-height:1.4}.dimina-dialog .dimina-dialog__content{color:#333;text-align:center;word-break:break-word;white-space:pre-wrap;overscroll-behavior:contain;touch-action:pan-y;-webkit-overflow-scrolling:touch;flex:auto;min-height:0;margin:0;padding:16px 24px 24px;font-size:15px;line-height:1.5;overflow-y:auto}.dimina-dialog .dimina-dialog__buttons{touch-action:none;border-top:1px solid #0000001a;width:100%;display:flex}.dimina-dialog .dimina-dialog__button{-webkit-user-select:none;user-select:none;text-align:center;color:#000;cursor:pointer;appearance:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;background:0 0;border:0;outline:none;flex:1;padding:12px 0;font-family:inherit;font-size:16px;font-weight:500;line-height:1.41176;text-decoration:none;display:block;position:relative;overflow:hidden}.dimina-dialog .dimina-dialog__button:focus,.dimina-dialog .dimina-dialog__button:focus-visible{outline:none}.dimina-dialog .dimina-dialog__button+.dimina-dialog__button:before{content:"";transform-origin:0 0;background:#0000001a;width:1px;position:absolute;top:0;bottom:0;left:0;transform:scaleX(.5)}.dimina-dialog .dimina-dialog__button:active{background:#0000000a}.dimina-action-sheet-mask{z-index:2000;opacity:0;background:#0006;transition:opacity .2s;position:fixed;inset:0}.dimina-action-sheet-mask.show{opacity:1}.dimina-action-sheet{z-index:2001;padding-bottom:env(safe-area-inset-bottom,12px);background:#fff;border-radius:24px 24px 0 0;transition:transform .2s;position:fixed;bottom:0;left:0;right:0;overflow:hidden;transform:translateY(100%);box-shadow:0 -2px 16px #00000014}.dimina-action-sheet .dimina-action-sheet-item{text-align:center;cursor:pointer;background:#fff;border-bottom:1px solid #f2f2f2;padding:18px 0;font-size:18px}.dimina-action-sheet .dimina-action-sheet-item:last-child{border-bottom:none}.dimina-action-sheet .dimina-action-sheet-cancel{text-align:center;color:#333;cursor:pointer;background:#fff;border-radius:12px;margin-top:8px;padding:18px 0;font-size:18px;box-shadow:0 1px 4px #00000008}.dimina-action-sheet.show{transform:translateY(0)}.dimina-mini-app__tabbar{z-index:100;position:absolute;bottom:0;left:0;right:0}.dimina-tabbar{box-sizing:border-box;height:69.784px;margin-bottom:env(safe-area-inset-bottom);border-top:1px solid #e0e0e0;flex-direction:row;justify-content:space-around;align-items:center;display:flex}.dimina-tabbar-item{cursor:pointer;-webkit-user-select:none;user-select:none;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:4.576px;transition:all .2s;display:flex;position:relative}.dimina-tabbar-item:active{opacity:.7}.dimina-tabbar-icon{object-fit:contain;width:24.024px;height:24.024px}.dimina-tabbar-icon-default{display:block}.dimina-tabbar-icon-selected{display:none}.dimina-tabbar-text{text-align:center;font-size:9.152px;line-height:1.2;transition:color .2s}.dimina-tabbar-badge{box-sizing:border-box;color:#fff;text-align:center;white-space:nowrap;text-overflow:ellipsis;pointer-events:none;background:#fa5151;border-radius:8.008px;min-width:16.016px;max-width:54.912px;padding:1.144px 4.576px;font-size:9.152px;line-height:1;position:absolute;top:8.008px;left:50%;overflow:hidden;transform:translate(8.008px)}.dimina-tabbar-red-dot{pointer-events:none;background:#fa5151;border-radius:50%;width:6.864px;height:6.864px;position:absolute;top:9.152px;left:50%;transform:translate(11.44px)}.dimina-native-window{position:absolute;inset:0}.dimina-application{z-index:1;background-color:#000;position:absolute;inset:0}.dimina-native-view{background-color:#0000;position:absolute;inset:0}.dimina-native-view--before-presenting{border-radius:40px;overflow:hidden}.dimina-native-view--presenting{transform-origin:50%;overflow:hidden;transform:scale(.9)translateY(10px)rotate(0);border-radius:40px!important}.dimina-native-view--before-enter{transform:translate(100%);box-shadow:-6px 0 16px #00000014,-3px 0 6px -4px #0000001f,-9px 0 28px 8px #0000000d}.dimina-native-view--enter-anima{transition:transform var(--dimina-present-transition-ms) cubic-bezier(.32, .72, 0, 1), border-radius var(--dimina-present-transition-ms) cubic-bezier(.32, .72, 0, 1)}.dimina-native-view--instage{transform:translate(0)!important}.dimina-native-view--slide-out{transform:translate(-100%)}.dimina-native-view--linear-anima{transition:transform var(--dimina-present-transition-ms) linear}.dimina-native-view--before-present{transform:translateY(100%);box-shadow:0 0 #0000,0 -10px 16px -4px #0000001f,0 0 #0000}.dimina-app__page-view{background-color:#ededed;position:absolute;inset:0}.dimina-app-navigation{box-sizing:content-box;z-index:10;background-color:#ededed;height:50.336px;padding-top:50.336px;display:flex;position:absolute;top:0;left:0;right:0}.dimina-app-navigation .dimina-app-navigation__content{justify-content:center;align-items:center;width:100%;display:flex;position:relative}.dimina-app-navigation .dimina-app-navigation__blank{background-size:11.44px 20.02px;width:11.44px;height:50.336px;position:absolute;top:0;left:19.448px}.dimina-app-navigation .dimina-app-navigation__left-btn{cursor:pointer;background:url(/images/mini-arrow-left.png) 0/11.44px 20.02px no-repeat;width:11.44px;height:50.336px;display:none;position:absolute;top:0;left:19.448px}.dimina-app-navigation .dimina-app-navigation__title{text-align:center;color:#333;font-size:19.448px}.dimina-app-navigation .dimina-app-navigation__right-btn{cursor:pointer;background:url(/images/more.png) 50%/20.02px no-repeat;width:25.74px;height:50.336px;position:absolute;top:0;right:18.876px}.dimina-app__mini-content{box-sizing:border-box;flex-direction:column;height:100%;min-height:0;padding-top:100.672px;display:flex}.dimina-app__mini-content .dimina-app__mini-search{background-color:#ededed;flex:none;padding:17.16px 9.152px}.dimina-app__mini-content .dimina-app__mini-search-input{background-color:#fff;border-radius:5.72px;justify-content:center;align-items:center;height:41.184px;display:flex}.dimina-app__mini-content .dimina-app__mini-search-input-placeholder{box-sizing:border-box;color:#000;text-align:left;background:url(/images/search.jpg) 22.88px/18.876px 18.876px no-repeat;border:none;outline:none;width:100%;height:100%;padding:0 22.88px 0 51.48px;font-size:18.876px;font-weight:300}.dimina-app__mini-content .dimina-app__mini-search-input-placeholder::placeholder{color:#b3b3b3}.dimina-app__mini-used{background-color:#fff;border-top:1px solid #e6e6e6;border-bottom:1px solid #e6e6e6;flex-direction:column;flex:auto;min-height:0;padding-left:18.304px;display:flex}.dimina-app__mini-used .dimina-app__mini-used-title{color:#737373;flex:none;padding:17.16px 0;font-size:14.872px;font-weight:400}.dimina-app__mini-used .dimina-app__mini-used-list{-webkit-overflow-scrolling:touch;flex:auto;min-height:0;overflow-y:auto}.dimina-app__mini-used .dimina-app__mini-used-list-item{-webkit-user-select:none;user-select:none;cursor:pointer;padding-left:90.376px;list-style:none;position:relative}.dimina-app__mini-used .dimina-app__mini-used-list-item:last-child .dimina-app__mini-used-name{border:none}.dimina-app__mini-used .dimina-app__mini-used-logo{border-radius:50%;width:57.2px;height:57.2px;position:absolute;top:50%;left:10.296px;overflow:hidden;transform:translateY(-50%)}.dimina-app__mini-used .dimina-app__mini-used-logo img{width:100%;height:100%}.dimina-app__mini-used .dimina-app__mini-used-name{color:#333;border-bottom:1px solid #e4e4e4;padding-top:37.752px;padding-bottom:37.752px;font-size:18.876px}.dimina-app__mini-used .dimina-app__mini-used-state{text-align:center;color:#8a8a8a;padding:54.912px 18.304px 68.64px 0;font-size:16.016px}#root{background:#eef2f7;justify-content:center;padding-top:20px;padding-bottom:20px;display:flex;position:absolute;inset:0;overflow-y:scroll}@media (hover:none) and (pointer:coarse),(width<=480px){#root{background:#000;padding:0;overflow-y:hidden}}:root{--x:0;--y:0;--xp:0;--yp:0;--hue:calc(0 + (var(--xp) * 500));--bg:#1a1a1a;--size:100px;--glow:radial-gradient(50% 50% at center, hsl(var(--hue) 80% 85%), hsl(var(--hue) 80% 70%), transparent) calc((var(--x) * 1px) - (var(--size) * .5)) calc((var(--y) * 1px) - (var(--size) * .5)) / var(--size) var(--size) no-repeat fixed}#iphone{background:#343232;border-radius:48px;width:429px;height:885px;position:relative}@media (hover:none) and (pointer:coarse),(width<=480px){#iphone{background:0 0;border-radius:0;width:100%;height:100%}}#iphone .iphone__screen{z-index:100;border-radius:40px;justify-content:center;display:flex;position:absolute;inset:10px;overflow:hidden}#iphone .iphone__screen .iphone__screen-sleep-mask{z-index:300;opacity:0;pointer-events:none;background:#000;transition:opacity 80ms ease-out;position:absolute;inset:0}#iphone .iphone__screen.iphone__screen--sleeping .iphone__screen-sleep-mask{opacity:1;pointer-events:auto}@media (hover:none) and (pointer:coarse),(width<=480px){#iphone .iphone__screen{border-radius:0;inset:0}}#iphone .iphone__screen .iphone__status-bar{z-index:100;pointer-events:none;letter-spacing:-.3px;justify-content:space-between;align-items:center;height:48px;padding:0 30px 0 40px;font-family:-apple-system,BlinkMacSystemFont,SF Pro Text,SF Pro Display,system-ui,sans-serif;font-size:17px;font-weight:590;display:flex;position:absolute;left:0;right:0}#iphone .iphone__screen .iphone__status-bar .status-bar__left{align-items:center;display:flex}#iphone .iphone__screen .iphone__status-bar .status-bar__right{align-items:center;gap:5.5px;font-size:17px;display:flex}#iphone .iphone__screen .iphone__status-bar .status-bar__signal{opacity:1;flex:none;width:20px;height:12px;display:block}#iphone .iphone__screen .iphone__status-bar .status-bar__wifi{opacity:1;flex:none;width:18px;height:14px;display:block}#iphone .iphone__screen .iphone__status-bar .status-bar__battery{opacity:1;width:27px;height:13px}#iphone .iphone__screen .iphone__status-bar.iphone__status-bar--white{color:#fff}#iphone .iphone__screen .iphone__status-bar.iphone__status-bar--white .status-bar__signal{fill:#fff}#iphone .iphone__screen .iphone__status-bar.iphone__status-bar--white .status-bar__wifi{fill:#fff;stroke:#fff}#iphone .iphone__screen .iphone__status-bar.iphone__status-bar--white .status-bar__battery rect:last-child,#iphone .iphone__screen .iphone__status-bar.iphone__status-bar--white .status-bar__battery path{fill:#fff}#iphone .iphone__screen .iphone__status-bar.iphone__status-bar--white .status-bar__battery rect:first-child{stroke:#fff}#iphone .iphone__screen .iphone__status-bar.iphone__status-bar--black{color:#000}#iphone .iphone__screen .iphone__status-bar.iphone__status-bar--black .status-bar__signal{fill:#000}#iphone .iphone__screen .iphone__status-bar.iphone__status-bar--black .status-bar__wifi{fill:#000;stroke:#000}#iphone .iphone__screen .iphone__status-bar.iphone__status-bar--black .status-bar__battery rect:last-child,#iphone .iphone__screen .iphone__status-bar.iphone__status-bar--black .status-bar__battery path{fill:#000}#iphone .iphone__screen .iphone__status-bar.iphone__status-bar--black .status-bar__battery rect:first-child{stroke:#000}#iphone .iphone__screen .iphone__screen_dynamic-island{-webkit-user-select:none;user-select:none;cursor:pointer;z-index:100;background:linear-gradient(var(--bg), var(--bg)) padding-box, var(--glow), linear-gradient(black, black) border-box;touch-action:none;border:2px solid #0000;border-radius:17px;justify-content:center;align-items:center;width:106px;height:27px;padding:0 10px;transition:background-size .24s,width .3s cubic-bezier(.34,1.56,.64,1),height .3s cubic-bezier(.34,1.56,.64,1),margin .3s cubic-bezier(.34,1.56,.64,1);display:flex;position:absolute;top:8px;box-shadow:inset 0 1px #ffffff26}#iphone .iphone__screen .iphone__screen_dynamic-island.island-hover{width:112px;height:28.5px;margin-top:-.7px;margin-left:-3px}#iphone .iphone__screen .iphone__screen_dynamic-island:hover img{opacity:1}#iphone .iphone__screen .iphone__screen_dynamic-island:before{content:"";background:var(--bg);z-index:2;pointer-events:none;border-radius:1rem;position:absolute;inset:0;box-shadow:inset 0 1px #ffffff26}#iphone .iphone__screen .iphone__screen_dynamic-island:after{content:"";filter:blur(20px);background:var(--glow);pointer-events:none;border:4px solid #0000;border-radius:1rem;position:absolute;inset:-4px}#iphone .iphone__screen .iphone__screen_dynamic-island span{background:var(--glow);color:#0000;z-index:2;-webkit-background-clip:text;background-clip:text;justify-content:center;align-items:center;width:100%;height:100%;line-height:27px;display:flex;position:relative;inset:0}#iphone .iphone__screen .iphone__screen_dynamic-island span img{opacity:.2;max-width:100%;height:auto;transition:opacity .3s;display:block}@media (hover:none) and (pointer:coarse) and (orientation:portrait),(width<=480px) and (orientation:portrait){#iphone .iphone__screen .iphone__screen_dynamic-island span img{opacity:1}}#iphone .iphone__screen .iphone__apps{width:100%;height:100%}#iphone .power-btn{z-index:120;cursor:pointer;touch-action:manipulation;transform-origin:0;background:#343232;border:0;border-radius:0 6px 6px 0;outline:none;width:9px;height:92px;padding:0;transition:transform 60ms,filter 80ms,box-shadow 80ms;position:absolute;top:216px;right:-7px;overflow:hidden;box-shadow:inset 1px 0 #ffffff14,inset -1px 0 1px #00000080,2px 0 4px #0003}#iphone .power-btn:before{content:"";opacity:.75;pointer-events:none;background:linear-gradient(90deg,#ffffff14,#0000 42%),linear-gradient(#ffffff29,#0000 22% 78%,#00000038);border-radius:0 5px 5px 0;position:absolute;inset:3px 1px 3px 2px}#iphone .power-btn:after{content:"";pointer-events:none;background:#343232;border-radius:1px 0 0 1px;width:3px;position:absolute;top:1px;bottom:1px;left:-1px;box-shadow:inset -1px 0 1px #00000052,inset 1px 0 #ffffff0d}#iphone .power-btn:hover{filter:brightness(1.28);background:#4a4646;box-shadow:inset 1px 0 #ffffff24,inset -1px 0 #ffffff2e,inset -2px 0 3px #ffffff1f,inset 0 1px 1px #ffffff29,inset 0 -1px 1px #00000047,3px 0 5px #0003}#iphone .power-btn:hover:before{opacity:1;background:linear-gradient(90deg,#ffffff3d,#0000 50%),linear-gradient(#fff3,#0000 20% 78%,#00000029)}#iphone .power-btn:focus-visible{box-shadow:0 0 0 2px #ffffff5c,inset 1px 0 #ffffff1f,inset -1px 0 1px #00000085,3px 0 6px #0000003d}#iphone .power-btn:active{filter:brightness(.86);transform:translate(-1px)scaleX(.88);box-shadow:inset 2px 0 2px #0000006b,1px 0 3px #0000003d}@media (hover:none) and (pointer:coarse),(width<=480px){#iphone .power-btn{display:none}}:root{--dimina-present-transition-ms:.54s}*{margin:0;padding:0}body{font-family:SF Pro SC,SF Pro Text,SF Pro Icons,PingFang SC,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:12px;font-weight:400}