@zitadel/cli 0.0.0

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ZITADEL
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,345 @@
1
+ # @zitadel/cli
2
+
3
+ Scaffolds Zitadel auth (login, register, profile, middleware) into a Next.js app.
4
+
5
+ ```sh
6
+ npx @zitadel/cli@latest setup --framework next --server <your-zitadel-server>
7
+ ```
8
+
9
+ > **Beta.** This is the **next-generation Zitadel**, a ground-up rewrite of the platform. It is distinct from the established Zitadel at [github.com/zitadel/zitadel](https://github.com/zitadel/zitadel). APIs and CLI flags will change.
10
+
11
+ ## Requirements
12
+
13
+ - Node 20+
14
+ - A Next.js project created with `create-next-app`
15
+ - A running next-generation Zitadel server to point at:
16
+ - **Zitadel Cloud** — coming soon
17
+ - **Self-hosted** — grab a binary from [github.com/zitadel/nextgen/releases](https://github.com/zitadel/nextgen/releases) and run it locally
18
+
19
+ ## Quickstart
20
+
21
+ ```sh
22
+ npx create-next-app@latest my-app
23
+ cd my-app
24
+ npx @zitadel/cli@latest setup --framework next --server http://localhost:8080
25
+ npm run dev
26
+ ```
27
+
28
+ `setup` creates a project on the Zitadel server, scaffolds `app/login`, `app/register`, `app/profile`, and `middleware.ts`, and writes `.env.local` and `.zitadel/`. The project's default user schema and login flow are provisioned server-side at creation time, so the CLI does not scaffold or upload them. Open `http://localhost:3000/login` to see the login page.
29
+
30
+ ## Other commands
31
+
32
+ - `zitadel doctor` — verify the generated files and local state
33
+ - `zitadel status` — summarise the local project
34
+ - `zitadel eject` — remove what setup wrote (alias: `zitadel uninstall`)
35
+
36
+ ## Reference
37
+
38
+ <details>
39
+ <summary>Full command reference</summary>
40
+
41
+ <!-- commands -->
42
+ * [`zitadel autocomplete [SHELL]`](#zitadel-autocomplete-shell)
43
+ * [`zitadel commands`](#zitadel-commands)
44
+ * [`zitadel doctor`](#zitadel-doctor)
45
+ * [`zitadel eject`](#zitadel-eject)
46
+ * [`zitadel help [COMMAND]`](#zitadel-help-command)
47
+ * [`zitadel search`](#zitadel-search)
48
+ * [`zitadel setup`](#zitadel-setup)
49
+ * [`zitadel status`](#zitadel-status)
50
+ * [`zitadel uninstall`](#zitadel-uninstall)
51
+ * [`zitadel version`](#zitadel-version)
52
+ * [`zitadel which`](#zitadel-which)
53
+
54
+ ## `zitadel autocomplete [SHELL]`
55
+
56
+ Display autocomplete installation instructions.
57
+
58
+ ```
59
+ USAGE
60
+ $ zitadel autocomplete [SHELL] [-r]
61
+
62
+ ARGUMENTS
63
+ [SHELL] (zsh|bash|powershell) Shell type
64
+
65
+ FLAGS
66
+ -r, --refresh-cache Refresh cache (ignores displaying instructions)
67
+
68
+ DESCRIPTION
69
+ Display autocomplete installation instructions.
70
+
71
+ EXAMPLES
72
+ $ zitadel autocomplete
73
+
74
+ $ zitadel autocomplete bash
75
+
76
+ $ zitadel autocomplete zsh
77
+
78
+ $ zitadel autocomplete powershell
79
+
80
+ $ zitadel autocomplete --refresh-cache
81
+ ```
82
+
83
+ _See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v3.2.50/src/commands/autocomplete/index.ts)_
84
+
85
+ ## `zitadel commands`
86
+
87
+ List all zitadel commands.
88
+
89
+ ```
90
+ USAGE
91
+ $ zitadel commands [--json] [-c id|plugin|summary|type... | --tree] [--deprecated] [-x | ] [--hidden]
92
+ [--no-truncate | ] [--sort id|plugin|summary|type | ]
93
+
94
+ FLAGS
95
+ -c, --columns=<option>... Only show provided columns (comma-separated).
96
+ <options: id|plugin|summary|type>
97
+ -x, --extended Show extra columns.
98
+ --deprecated Show deprecated commands.
99
+ --hidden Show hidden commands.
100
+ --no-truncate Do not truncate output.
101
+ --sort=<option> [default: id] Property to sort by.
102
+ <options: id|plugin|summary|type>
103
+ --tree Show tree of commands.
104
+
105
+ GLOBAL FLAGS
106
+ --json Format output as json.
107
+
108
+ DESCRIPTION
109
+ List all zitadel commands.
110
+ ```
111
+
112
+ _See code: [@oclif/plugin-commands](https://github.com/oclif/plugin-commands/blob/4.1.55/src/commands/commands.ts)_
113
+
114
+ ## `zitadel doctor`
115
+
116
+ Verify generated files and local state.
117
+
118
+ ```
119
+ USAGE
120
+ $ zitadel doctor [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug] [--fix]
121
+
122
+ FLAGS
123
+ -c, --cwd=<value> Project directory to operate on.
124
+ -f, --force Overwrite protected files on conflict.
125
+ -n, --non-interactive Disable prompts. Required when scripting or running as an agent.
126
+ -s, --server=<value> Override the resolved server URL.
127
+ --debug Debug logging.
128
+ --dry-run Preview without mutating files or the platform.
129
+ --fix Re-apply missing managed files.
130
+ --verbose Verbose logging.
131
+
132
+ GLOBAL FLAGS
133
+ --json Format output as json.
134
+
135
+ DESCRIPTION
136
+ Verify generated files and local state.
137
+ ```
138
+
139
+ ## `zitadel eject`
140
+
141
+ Remove managed files and local Zitadel state.
142
+
143
+ ```
144
+ USAGE
145
+ $ zitadel eject [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug]
146
+
147
+ FLAGS
148
+ -c, --cwd=<value> Project directory to operate on.
149
+ -f, --force Overwrite protected files on conflict.
150
+ -n, --non-interactive Disable prompts. Required when scripting or running as an agent.
151
+ -s, --server=<value> Override the resolved server URL.
152
+ --debug Debug logging.
153
+ --dry-run Preview without mutating files or the platform.
154
+ --verbose Verbose logging.
155
+
156
+ GLOBAL FLAGS
157
+ --json Format output as json.
158
+
159
+ DESCRIPTION
160
+ Remove managed files and local Zitadel state.
161
+
162
+ ALIASES
163
+ $ zitadel uninstall
164
+ ```
165
+
166
+ ## `zitadel help [COMMAND]`
167
+
168
+ Display help for zitadel.
169
+
170
+ ```
171
+ USAGE
172
+ $ zitadel help [COMMAND...] [-n]
173
+
174
+ ARGUMENTS
175
+ [COMMAND...] Command to show help for.
176
+
177
+ FLAGS
178
+ -n, --nested-commands Include all nested commands in the output.
179
+
180
+ DESCRIPTION
181
+ Display help for zitadel.
182
+ ```
183
+
184
+ _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/6.2.49/src/commands/help.ts)_
185
+
186
+ ## `zitadel search`
187
+
188
+ Search for a command.
189
+
190
+ ```
191
+ USAGE
192
+ $ zitadel search
193
+
194
+ DESCRIPTION
195
+ Search for a command.
196
+
197
+ Once you select a command, hit enter and it will show the help for that command.
198
+ ```
199
+
200
+ _See code: [@oclif/plugin-search](https://github.com/oclif/plugin-search/blob/v1.2.50/src/commands/search.ts)_
201
+
202
+ ## `zitadel setup`
203
+
204
+ Create a Zitadel project and scaffold local auth.
205
+
206
+ ```
207
+ USAGE
208
+ $ zitadel setup [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug]
209
+ [--framework next] [--renderer react|web-component]
210
+
211
+ FLAGS
212
+ -c, --cwd=<value> Project directory to operate on.
213
+ -f, --force Overwrite protected files on conflict.
214
+ -n, --non-interactive Disable prompts. Required when scripting or running as an agent.
215
+ -s, --server=<value> Override the resolved server URL.
216
+ --debug Debug logging.
217
+ --dry-run Preview without mutating files or the platform.
218
+ --framework=<option> Framework to target.
219
+ <options: next>
220
+ --renderer=<option> Renderer (default: react).
221
+ <options: react|web-component>
222
+ --verbose Verbose logging.
223
+
224
+ GLOBAL FLAGS
225
+ --json Format output as json.
226
+
227
+ DESCRIPTION
228
+ Create a Zitadel project and scaffold local auth.
229
+
230
+ EXAMPLES
231
+ $ zitadel setup --framework next
232
+ ```
233
+
234
+ ## `zitadel status`
235
+
236
+ Summarize the local project state.
237
+
238
+ ```
239
+ USAGE
240
+ $ zitadel status [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug]
241
+
242
+ FLAGS
243
+ -c, --cwd=<value> Project directory to operate on.
244
+ -f, --force Overwrite protected files on conflict.
245
+ -n, --non-interactive Disable prompts. Required when scripting or running as an agent.
246
+ -s, --server=<value> Override the resolved server URL.
247
+ --debug Debug logging.
248
+ --dry-run Preview without mutating files or the platform.
249
+ --verbose Verbose logging.
250
+
251
+ GLOBAL FLAGS
252
+ --json Format output as json.
253
+
254
+ DESCRIPTION
255
+ Summarize the local project state.
256
+ ```
257
+
258
+ ## `zitadel uninstall`
259
+
260
+ Remove managed files and local Zitadel state.
261
+
262
+ ```
263
+ USAGE
264
+ $ zitadel uninstall [--json] [-c <value>] [-s <value>] [-n] [-f] [--dry-run] [--verbose] [--debug]
265
+
266
+ FLAGS
267
+ -c, --cwd=<value> Project directory to operate on.
268
+ -f, --force Overwrite protected files on conflict.
269
+ -n, --non-interactive Disable prompts. Required when scripting or running as an agent.
270
+ -s, --server=<value> Override the resolved server URL.
271
+ --debug Debug logging.
272
+ --dry-run Preview without mutating files or the platform.
273
+ --verbose Verbose logging.
274
+
275
+ GLOBAL FLAGS
276
+ --json Format output as json.
277
+
278
+ DESCRIPTION
279
+ Remove managed files and local Zitadel state.
280
+
281
+ ALIASES
282
+ $ zitadel uninstall
283
+ ```
284
+
285
+ ## `zitadel version`
286
+
287
+ ```
288
+ USAGE
289
+ $ zitadel version [--json] [--verbose]
290
+
291
+ FLAGS
292
+ --verbose Show additional information about the CLI.
293
+
294
+ GLOBAL FLAGS
295
+ --json Format output as json.
296
+
297
+ FLAG DESCRIPTIONS
298
+ --verbose Show additional information about the CLI.
299
+
300
+ Additionally shows the architecture, node version, operating system, and versions of plugins that the CLI is using.
301
+ ```
302
+
303
+ _See code: [@oclif/plugin-version](https://github.com/oclif/plugin-version/blob/2.2.46/src/commands/version.ts)_
304
+
305
+ ## `zitadel which`
306
+
307
+ Show which plugin a command is in.
308
+
309
+ ```
310
+ USAGE
311
+ $ zitadel which [--json]
312
+
313
+ GLOBAL FLAGS
314
+ --json Format output as json.
315
+
316
+ DESCRIPTION
317
+ Show which plugin a command is in.
318
+
319
+ EXAMPLES
320
+ See which plugin the `help` command is in:
321
+
322
+ $ zitadel which help
323
+
324
+ Use colon separators.
325
+
326
+ $ zitadel which foo:bar:baz
327
+
328
+ Use spaces as separators.
329
+
330
+ $ zitadel which foo bar baz
331
+
332
+ Wrap command in quotes to use spaces as separators.
333
+
334
+ $ zitadel which "foo bar baz"
335
+ ```
336
+
337
+ _See code: [@oclif/plugin-which](https://github.com/oclif/plugin-which/blob/3.2.55/src/commands/which.ts)_
338
+ <!-- commandsstop -->
339
+
340
+ </details>
341
+
342
+ ## Links
343
+
344
+ - Repository: [github.com/zitadel/nextgen](https://github.com/zitadel/nextgen)
345
+ - Issues: [github.com/zitadel/nextgen/issues](https://github.com/zitadel/nextgen/issues)
package/SKILLS.md ADDED
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: zitadel-cli
3
+ description: >-
4
+ Set up and manage Zitadel authentication in a local project with the
5
+ agent-friendly `zitadel` CLI. Use when the user wants to add login,
6
+ registration, or session handling, create a Zitadel project, scaffold auth
7
+ routes for a Next.js App Router app, or plan and apply Zitadel config changes
8
+ from repo state.
9
+ ---
10
+
11
+ # Zitadel CLI
12
+
13
+ The `zitadel` CLI integrates Zitadel auth into an existing project and keeps the
14
+ local config (`zitadel.json` and `.zitadel/**`) as the source of truth. Every
15
+ command emits a JSON envelope, so you should drive it non-interactively and
16
+ parse the result rather than scraping human output.
17
+
18
+ ## Invocation rules
19
+
20
+ - Always pass `--non-interactive --json`. The envelope is the contract.
21
+ - Add `--cwd <path>` when operating outside the current working directory.
22
+ - Never run interactive prompts; `--non-interactive` (and `--json`) disable them.
23
+ - See `README.md` (its commands section is generated from the CLI's own
24
+ metadata) or run `zitadel <command> --help` for the full per-command flag list.
25
+
26
+ ```sh
27
+ npx @zitadel/cli@latest <command> --non-interactive --json
28
+ ```
29
+
30
+ ## Reading the envelope
31
+
32
+ Each invocation prints one JSON object:
33
+
34
+ - `status`: `ok` | `skipped` | `error`.
35
+ - `cli_version`, `command`, `source`: always present.
36
+ - On success: `data` with the command-specific payload.
37
+ - On a no-op: `reason` (e.g. `no-framework-detected`, `orphaned-config`).
38
+ - On failure: `code` (e.g. `E_VALIDATION`, `E_NETWORK`, `E_CONFLICT`) and
39
+ `message`.
40
+ - `next_commands`: the suggested follow-ups. Prefer these over free-text hints.
41
+
42
+ Exit codes mirror the error class (3 = validation, 4 = network, 5 = conflict,
43
+ 1 = auth, 2 = not-implemented). An unknown command is handled by the CLI's help
44
+ layer, not the envelope.
45
+
46
+ ## Commands
47
+
48
+ - `setup` — create a Zitadel project and scaffold local auth (routes,
49
+ middleware, `.zitadel/**`, env templates). The project's default user schema
50
+ and login flow are provisioned server-side at creation, so setup neither
51
+ scaffolds nor uploads them. Flags: `--framework`, `--renderer`.
52
+ - `plan` — validate config and preview the sync diff without mutating anything.
53
+ - `apply` — validate and upload repo config to the platform.
54
+ - `doctor` — verify generated files and local state; `--fix` re-applies missing
55
+ managed files.
56
+ - `status` — summarize the local project state.
57
+ - `eject` (alias `uninstall`) — remove managed files and local Zitadel state;
58
+ requires `--force` when non-interactive.
59
+
60
+ ## Golden path
61
+
62
+ ```sh
63
+ npx @zitadel/cli@latest setup --framework next --non-interactive --json
64
+ npx @zitadel/cli@latest doctor --non-interactive --json
65
+ npx @zitadel/cli@latest plan --non-interactive --json
66
+ npx @zitadel/cli@latest apply --non-interactive --json
67
+ ```
68
+
69
+ Repo config is authoritative: edit `zitadel.json` or files under `.zitadel/`,
70
+ then re-run `plan` and `apply`. Managed files carry a marker comment; `eject`
71
+ removes only files that still carry it, preserving anything the user replaced.
package/bin/run.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { execute } from "@oclif/core";
3
+
4
+ await execute({ dir: import.meta.url });
@@ -0,0 +1,62 @@
1
+ import { o as readZitadelSecret, s as BaseCommand } from "../project-C3pSfbao.mjs";
2
+ import { a as makeSyncers, i as runSyncLoop, n as summarizePlan, o as environmentSchema, r as buildSyncPlan, t as renderPlan } from "../sync-Cuyh-X1J.mjs";
3
+ import { Flags } from "@oclif/core";
4
+ import { consola as consola$1 } from "consola";
5
+ import { createZitadelClient } from "@zitadel/api/client";
6
+ //#region src/commands/apply.ts
7
+ /**
8
+ * `zitadel apply` — validate and upload repo config to the platform.
9
+ *
10
+ * Runs the sync loop to convergence, or (with `--dry-run`) previews the diff
11
+ * without mutating. All validation — structural shape and `${VAR}` / `*_env`
12
+ * reference presence — happens inside the sync engine ({@link buildSyncPlan}),
13
+ * so an invalid or under-configured file fails with `E_VALIDATION` before any
14
+ * platform call.
15
+ */
16
+ var Apply = class Apply extends BaseCommand {
17
+ static description = "Validate and upload repo config to the platform.";
18
+ static hidden = true;
19
+ static flags = { environment: Flags.string({
20
+ char: "e",
21
+ description: "Target environment (default: development).",
22
+ options: [...environmentSchema.options]
23
+ }) };
24
+ async run() {
25
+ const { flags } = await this.parse(Apply);
26
+ await this.toMeta(flags);
27
+ const { cwd, source, env, dryRun, isTTY } = this.meta;
28
+ const secret = await readZitadelSecret(cwd);
29
+ consola$1.info(`Project ${secret.project_id}`);
30
+ consola$1.info(`Server ${source}`);
31
+ const syncers = makeSyncers({
32
+ client: createZitadelClient({
33
+ baseUrl: source,
34
+ token: secret.project_secret
35
+ }),
36
+ projectId: secret.project_id,
37
+ env
38
+ });
39
+ if (!dryRun) {
40
+ consola$1.start("Syncing schemas and flows to Zitadel");
41
+ await runSyncLoop(cwd, syncers);
42
+ consola$1.success("Sync complete");
43
+ return this.emit({
44
+ status: "ok",
45
+ data: { synced: true }
46
+ });
47
+ }
48
+ consola$1.start("Building plan (dry run)");
49
+ const plan = await buildSyncPlan(cwd, syncers, true);
50
+ const summary = summarizePlan(plan);
51
+ consola$1.success(`Plan: ${summary.creates} create${summary.creates === 1 ? "" : "s"}, ${summary.updates} update${summary.updates === 1 ? "" : "s"}, ${summary.deletes} delete${summary.deletes === 1 ? "" : "s"}`);
52
+ return this.emit({
53
+ status: "ok",
54
+ data: summary,
55
+ pretty: renderPlan(plan, isTTY)
56
+ });
57
+ }
58
+ };
59
+ //#endregion
60
+ export { Apply as default };
61
+
62
+ //# sourceMappingURL=apply.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.mjs","names":[],"sources":["../../src/commands/apply.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport { consola } from \"consola\";\n\nimport { createZitadelClient } from \"@zitadel/api/client\";\n\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { environmentSchema } from \"../lib/environment\";\nimport { buildSyncPlan, makeSyncers, renderPlan, runSyncLoop, summarizePlan } from \"../lib/sync\";\nimport { readZitadelSecret } from \"../lib/project\";\n\n/**\n * `zitadel apply` — validate and upload repo config to the platform.\n *\n * Runs the sync loop to convergence, or (with `--dry-run`) previews the diff\n * without mutating. All validation — structural shape and `${VAR}` / `*_env`\n * reference presence — happens inside the sync engine ({@link buildSyncPlan}),\n * so an invalid or under-configured file fails with `E_VALIDATION` before any\n * platform call.\n */\nexport default class Apply extends BaseCommand {\n static override description = \"Validate and upload repo config to the platform.\";\n // Temporarily hidden while we collapse the dev workflow around `setup`'s\n // auto-apply. The logic stays wired up so re-exposing this command is a\n // one-line flip when we settle on the surface area.\n static override hidden = true;\n static override flags = {\n environment: Flags.string({\n char: \"e\",\n description: \"Target environment (default: development).\",\n options: [...environmentSchema.options],\n }),\n };\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Apply);\n await this.toMeta(flags);\n const { cwd, source, env, dryRun, isTTY } = this.meta;\n\n const secret = await readZitadelSecret(cwd);\n consola.info(`Project ${secret.project_id}`);\n consola.info(`Server ${source}`);\n const client = createZitadelClient({\n baseUrl: source,\n token: secret.project_secret,\n });\n const syncers = makeSyncers({ client, projectId: secret.project_id, env });\n\n if (!dryRun) {\n consola.start(\"Syncing schemas and flows to Zitadel\");\n await runSyncLoop(cwd, syncers);\n consola.success(\"Sync complete\");\n return this.emit({ status: \"ok\", data: { synced: true } });\n }\n\n consola.start(\"Building plan (dry run)\");\n const plan = await buildSyncPlan(cwd, syncers, true);\n const summary = summarizePlan(plan);\n consola.success(\n `Plan: ${summary.creates} create${summary.creates === 1 ? \"\" : \"s\"}, ` +\n `${summary.updates} update${summary.updates === 1 ? \"\" : \"s\"}, ` +\n `${summary.deletes} delete${summary.deletes === 1 ? \"\" : \"s\"}`,\n );\n return this.emit({\n status: \"ok\",\n data: summary,\n pretty: renderPlan(plan, isTTY),\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAmBA,IAAqB,QAArB,MAAqB,cAAc,YAAY;CAC7C,OAAgB,cAAc;CAI9B,OAAgB,SAAS;CACzB,OAAgB,QAAQ,EACtB,aAAa,MAAM,OAAO;EACxB,MAAM;EACN,aAAa;EACb,SAAS,CAAC,GAAG,kBAAkB,QAAQ;EACxC,CAAC,EACH;CAED,MAAM,MAA6B;EACjC,MAAM,EAAE,UAAU,MAAM,KAAK,MAAM,MAAM;AACzC,QAAM,KAAK,OAAO,MAAM;EACxB,MAAM,EAAE,KAAK,QAAQ,KAAK,QAAQ,UAAU,KAAK;EAEjD,MAAM,SAAS,MAAM,kBAAkB,IAAI;AAC3C,YAAQ,KAAK,aAAa,OAAO,aAAa;AAC9C,YAAQ,KAAK,aAAa,SAAS;EAKnC,MAAM,UAAU,YAAY;GAAE,QAJf,oBAAoB;IACjC,SAAS;IACT,OAAO,OAAO;IACf,CACmC;GAAE,WAAW,OAAO;GAAY;GAAK,CAAC;AAE1E,MAAI,CAAC,QAAQ;AACX,aAAQ,MAAM,uCAAuC;AACrD,SAAM,YAAY,KAAK,QAAQ;AAC/B,aAAQ,QAAQ,gBAAgB;AAChC,UAAO,KAAK,KAAK;IAAE,QAAQ;IAAM,MAAM,EAAE,QAAQ,MAAM;IAAE,CAAC;;AAG5D,YAAQ,MAAM,0BAA0B;EACxC,MAAM,OAAO,MAAM,cAAc,KAAK,SAAS,KAAK;EACpD,MAAM,UAAU,cAAc,KAAK;AACnC,YAAQ,QACN,SAAS,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC9D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,IAAI,IAC1D,QAAQ,QAAQ,SAAS,QAAQ,YAAY,IAAI,KAAK,MAC5D;AACD,SAAO,KAAK,KAAK;GACf,QAAQ;GACR,MAAM;GACN,QAAQ,WAAW,MAAM,MAAM;GAChC,CAAC"}