@pulsemcp/air-adapter-codex 0.5.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/README.md +83 -0
- package/dist/codex-adapter.d.ts +226 -0
- package/dist/codex-adapter.d.ts.map +1 -0
- package/dist/codex-adapter.js +967 -0
- package/dist/codex-adapter.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/scan-local-skills.d.ts +11 -0
- package/dist/scan-local-skills.d.ts.map +1 -0
- package/dist/scan-local-skills.js +92 -0
- package/dist/scan-local-skills.js.map +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# @pulsemcp/air-adapter-codex
|
|
2
|
+
|
|
3
|
+
AIR adapter extension for the [OpenAI Codex CLI](https://github.com/openai/codex). Translates AIR artifacts into Codex's native formats and prepares working directories for agent sessions.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @pulsemcp/air-adapter-codex
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### With the AIR CLI
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Install the adapter globally alongside the CLI
|
|
17
|
+
npm install -g @pulsemcp/air-cli @pulsemcp/air-adapter-codex
|
|
18
|
+
|
|
19
|
+
# Start a Codex session
|
|
20
|
+
air start codex --root web-app
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Programmatic
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { resolveArtifacts } from "@pulsemcp/air-core";
|
|
27
|
+
import { CodexAdapter } from "@pulsemcp/air-adapter-codex";
|
|
28
|
+
|
|
29
|
+
const artifacts = await resolveArtifacts("./air.json");
|
|
30
|
+
const adapter = new CodexAdapter();
|
|
31
|
+
|
|
32
|
+
// Prepare a working directory for a Codex session
|
|
33
|
+
const session = await adapter.prepareSession(artifacts, "./my-project", {
|
|
34
|
+
root: artifacts.roots["web-app"],
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// session.configFiles — [] (Codex config is TOML, see "Secrets" below)
|
|
38
|
+
// session.skillPaths — skill dirs created in .agents/skills/
|
|
39
|
+
// session.hookPaths — hook dirs created in .codex/hooks/
|
|
40
|
+
// session.startCommand — { command: "codex", args: [], cwd: "..." }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## What `prepareSession()` does
|
|
44
|
+
|
|
45
|
+
1. **Writes `.codex/config.toml`** — translates AIR MCP server configs into `[mcp_servers.*]` tables and registers path-based hooks under `[[hooks.<Event>]]`. User-authored servers, hooks, and top-level keys are preserved; only AIR-owned keys are replaced.
|
|
46
|
+
2. **Injects skills** — copies `SKILL.md` files and associated content into `.agents/skills/{name}/`, where Codex discovers them.
|
|
47
|
+
3. **Injects hooks** — copies hook directories into `.codex/hooks/{name}/` and registers their command in `config.toml`, anchored to the repo root.
|
|
48
|
+
4. **Copies references** — attaches referenced documents into `{artifact}/references/`.
|
|
49
|
+
5. **Respects local priority** — if a skill or hook directory already exists in the target, it is not overwritten.
|
|
50
|
+
|
|
51
|
+
## Translation Details
|
|
52
|
+
|
|
53
|
+
| AIR Format | Codex Format |
|
|
54
|
+
|------------|--------------|
|
|
55
|
+
| `mcp.json` (flat map with `type`, `title`, `description`) | `[mcp_servers.<name>]` tables in `.codex/config.toml` (metadata stripped) |
|
|
56
|
+
| `stdio` servers | `{ command, args, env, env_vars }` |
|
|
57
|
+
| `sse` / `streamable-http` servers | `{ url, http_headers, env_http_headers }` (Codex auto-detects transport from the URL) |
|
|
58
|
+
| MCP `env` value `${VAR}` where key == `VAR` | `env_vars = ["VAR"]` (host env forwarding) |
|
|
59
|
+
| MCP `env` value `${OTHER}` (renamed) or literal | left in the `env` table |
|
|
60
|
+
| Header value `${VAR}` | `env_http_headers = { Header = "VAR" }` |
|
|
61
|
+
| Skills (`SKILL.md` + content) | `.agents/skills/{name}/` |
|
|
62
|
+
| Hooks (`HOOK.json` + scripts) | `.codex/hooks/{name}/` + `[[hooks.<Event>]]` registration |
|
|
63
|
+
| Hook events `session_start`, `pre_tool_call`, `post_tool_call`, `user_prompt_submit`, `stop` | Codex `SessionStart`, `PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `Stop` |
|
|
64
|
+
| References | `{artifact}/references/` |
|
|
65
|
+
|
|
66
|
+
## Secrets
|
|
67
|
+
|
|
68
|
+
Codex's config is TOML, which is outside AIR's JSON-based transform/validation pipeline. Instead of writing `${VAR}` placeholders, the adapter maps secret references to Codex's **native host-env forwarding** at translation time:
|
|
69
|
+
|
|
70
|
+
- `env: { GITHUB_TOKEN: "${GITHUB_TOKEN}" }` → `env_vars = ["GITHUB_TOKEN"]` — Codex injects the host's `GITHUB_TOKEN` at launch.
|
|
71
|
+
- `headers: { Authorization: "${API_TOKEN}" }` → `env_http_headers = { Authorization = "API_TOKEN" }`.
|
|
72
|
+
|
|
73
|
+
As a result, `prepareSession()` returns an **empty `configFiles` array** — there is no JSON config for secret transforms to post-process.
|
|
74
|
+
|
|
75
|
+
**Limitation — only whole-value, same-named refs forward.** Codex's `env_vars` forwards a host var to an env key of the *same name*, and `env_http_headers` forwards a host var as a *whole* header value. A renamed ref (`KEY = "${OTHER}"`) or a partial value (`"Bearer ${TOKEN}"`) can't be expressed either way, so it falls through to the literal `env` / `http_headers` table. Because the TOML never passes through AIR's `${VAR}` transform pipeline, Codex would inject the literal `${…}` string at runtime — so the adapter emits a `console.warn` for each such value instead of silently shipping a broken secret. Rewrite these as whole-value, same-named refs (or set the value directly).
|
|
76
|
+
|
|
77
|
+
## Known gaps
|
|
78
|
+
|
|
79
|
+
These AIR features have no static Codex equivalent and are handled out of band:
|
|
80
|
+
|
|
81
|
+
- **OAuth MCP servers** — AIR's detailed OAuth config (`clientId`/`scopes`/`redirectUri`/…) has no static `config.toml` form. Codex performs interactive OAuth via `codex mcp login <name>`.
|
|
82
|
+
- **Plugins** — Codex's marketplace plugins are remote-installed (`codex plugin add`). AIR treats plugins as composition sugar: a plugin's declared MCP servers / skills / hooks are expanded into the activation set and materialized as their underlying Codex-native artifacts.
|
|
83
|
+
- **Subagent context** — Codex has no `--append-system-prompt` flag, so subagent-root context is returned to the caller via `PreparedSession.subagentContext` rather than passed to the CLI.
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import type { AgentAdapter, AgentSessionConfig, StartCommand, ResolvedArtifacts, RootEntry, McpServerEntry, PluginEntry, PrepareSessionOptions, PreparedSession, CleanSessionOptions, CleanSessionResult, LocalArtifacts } from "@pulsemcp/air-core";
|
|
2
|
+
export declare class CodexAdapter implements AgentAdapter {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
/**
|
|
6
|
+
* Map AIR lifecycle event names to Codex `config.toml` hook event names.
|
|
7
|
+
*
|
|
8
|
+
* Accepts both snake_case AIR names and PascalCase Codex lifecycle names as
|
|
9
|
+
* identity mappings, so hook authors targeting the Codex runtime can write
|
|
10
|
+
* Codex-native event names directly without translating to snake_case.
|
|
11
|
+
*
|
|
12
|
+
* AIR events without a Codex equivalent (session_end, subagent_stop,
|
|
13
|
+
* pre_compact, notification) are intentionally absent — `reconcileConfigHooks`
|
|
14
|
+
* warns and skips registration when it encounters an unrecognized event.
|
|
15
|
+
* Codex's PermissionRequest event has no AIR analog and is therefore not
|
|
16
|
+
* generated by AIR (but user-authored PermissionRequest hooks are preserved).
|
|
17
|
+
*/
|
|
18
|
+
private static readonly AIR_TO_CODEX_EVENT;
|
|
19
|
+
isAvailable(): Promise<boolean>;
|
|
20
|
+
generateConfig(artifacts: ResolvedArtifacts, root?: RootEntry, _workDir?: string): AgentSessionConfig;
|
|
21
|
+
buildStartCommand(config: AgentSessionConfig): StartCommand;
|
|
22
|
+
/**
|
|
23
|
+
* Prepare a working directory for an OpenAI Codex CLI session.
|
|
24
|
+
*
|
|
25
|
+
* Writes `.codex/config.toml` (MCP servers under `[mcp_servers.*]` and hook
|
|
26
|
+
* registrations under `[hooks.*]`), injects skills + references into
|
|
27
|
+
* `.agents/skills/<name>/`, copies path-based hooks into `.codex/hooks/<name>/`,
|
|
28
|
+
* and returns the start command.
|
|
29
|
+
*
|
|
30
|
+
* Inputs to activation lists (root defaults, overrides, plugin-declared
|
|
31
|
+
* primitives) are accepted as either qualified (`@scope/id`) or short form;
|
|
32
|
+
* ambiguous short forms are rejected. Filesystem materialization uses
|
|
33
|
+
* shortnames — Codex's `config.toml`, `.agents/skills/`, `.codex/hooks/`,
|
|
34
|
+
* and the manifest are scope-naive. Two activated qualified IDs that share
|
|
35
|
+
* a shortname hard-fail with a clear "add one to exclude" message.
|
|
36
|
+
*
|
|
37
|
+
* NOTE: `configFiles` is intentionally returned empty. Codex's config is
|
|
38
|
+
* TOML, which is outside AIR's JSON-based transform/validation pipeline.
|
|
39
|
+
* Whole-value, same-named secret references (`${VAR}`) in MCP env/headers are
|
|
40
|
+
* mapped to Codex-native host-env forwarding (`env_vars`, `env_http_headers`)
|
|
41
|
+
* at translation time. Renamed or partial refs that can't be forwarded fall
|
|
42
|
+
* through to the literal table and emit a warning (see `warnUnforwardableSecret`),
|
|
43
|
+
* since the TOML never passes through the `${VAR}` transform pipeline.
|
|
44
|
+
*/
|
|
45
|
+
prepareSession(artifacts: ResolvedArtifacts, targetDir: string, options?: PrepareSessionOptions): Promise<PreparedSession>;
|
|
46
|
+
/**
|
|
47
|
+
* Enumerate skills checked into `<targetDir>/.agents/skills/`. Codex loads
|
|
48
|
+
* these directly from the filesystem regardless of AIR's involvement, so
|
|
49
|
+
* they're always active and must not be overwritten or removed. The TUI uses
|
|
50
|
+
* this list to surface them as read-only entries.
|
|
51
|
+
*/
|
|
52
|
+
listLocalArtifacts(targetDir: string): Promise<LocalArtifacts>;
|
|
53
|
+
/**
|
|
54
|
+
* Remove every artifact AIR has previously written into `targetDir`.
|
|
55
|
+
*
|
|
56
|
+
* Reads the per-target manifest, deletes each tracked skill / hook
|
|
57
|
+
* directory, and removes tracked MCP server keys + AIR-managed hook entries
|
|
58
|
+
* from `.codex/config.toml`. When every category is cleaned, the manifest
|
|
59
|
+
* itself is deleted; partial cleans (any `keep*` flag set) update the
|
|
60
|
+
* manifest with the kept entries so future runs continue to track them.
|
|
61
|
+
*
|
|
62
|
+
* Items in the manifest that no longer exist on disk are silently skipped
|
|
63
|
+
* — the manifest can drift if a user removed files manually between runs.
|
|
64
|
+
*/
|
|
65
|
+
cleanSession(targetDir: string, options?: CleanSessionOptions): Promise<CleanSessionResult>;
|
|
66
|
+
/**
|
|
67
|
+
* Read `.codex/config.toml` and return the subset of `ids` whose key is
|
|
68
|
+
* actually present under `[mcp_servers]`. Returns an empty list if the file
|
|
69
|
+
* can't be parsed — we'd rather under-report than claim to have removed
|
|
70
|
+
* entries we never touched.
|
|
71
|
+
*/
|
|
72
|
+
private mcpServerIdsPresent;
|
|
73
|
+
/**
|
|
74
|
+
* Resolve subagent roots from the root's default_subagent_roots.
|
|
75
|
+
* IDs are already qualified after composition-time canonicalization.
|
|
76
|
+
*/
|
|
77
|
+
private resolveSubagentRoots;
|
|
78
|
+
/**
|
|
79
|
+
* Merge subagent roots' default_mcp_servers and default_skills into the
|
|
80
|
+
* parent's activated sets (union, preserving order with parent first).
|
|
81
|
+
*/
|
|
82
|
+
private mergeSubagentArtifacts;
|
|
83
|
+
/**
|
|
84
|
+
* Build a system prompt section describing the subagent root dependencies.
|
|
85
|
+
*/
|
|
86
|
+
private buildSubagentContext;
|
|
87
|
+
/**
|
|
88
|
+
* Translate a shortname-keyed MCP server map into Codex's `[mcp_servers.*]`
|
|
89
|
+
* shape (as a plain object ready for TOML serialization). Callers convert
|
|
90
|
+
* qualified IDs to shortnames before invoking this — Codex's config is
|
|
91
|
+
* scope-naive.
|
|
92
|
+
*
|
|
93
|
+
* Secret handling is Codex-native: an env value that is exactly `${VAR}`
|
|
94
|
+
* and whose key matches `VAR` becomes an `env_vars` forward (Codex injects
|
|
95
|
+
* the host's `VAR` at launch); any other value is written literally into the
|
|
96
|
+
* `[mcp_servers.<name>.env]` table. For remote servers, a header value of
|
|
97
|
+
* `${VAR}` becomes an `env_http_headers` entry; other header values are
|
|
98
|
+
* written into `http_headers`.
|
|
99
|
+
*
|
|
100
|
+
* Codex's native forwarding only expresses *whole-value* refs: `env_vars`
|
|
101
|
+
* forwards a host var to an env key of the same name, and `env_http_headers`
|
|
102
|
+
* forwards a host var as a whole header value. A *renamed* whole-value ref
|
|
103
|
+
* (`KEY = "${OTHER}"`) or a *partial* value (`"Bearer ${TOKEN}"`) can't be
|
|
104
|
+
* expressed either way, so it falls through to the literal table — and since
|
|
105
|
+
* the TOML never passes through AIR's `${VAR}` transform pipeline, Codex
|
|
106
|
+
* would inject the literal `${…}` string at runtime. We warn loudly in that
|
|
107
|
+
* case rather than silently shipping a broken secret.
|
|
108
|
+
*/
|
|
109
|
+
translateMcpServersByShort(servers: Record<string, McpServerEntry>): Record<string, Record<string, unknown>>;
|
|
110
|
+
private translateMcpServer;
|
|
111
|
+
/**
|
|
112
|
+
* Warn that a secret reference can't be expressed via Codex's native host-env
|
|
113
|
+
* forwarding and will be written to `.codex/config.toml` as a literal `${…}`
|
|
114
|
+
* string. Codex would then inject that literal text at runtime — a silently
|
|
115
|
+
* broken secret. Only whole-value, same-named refs forward cleanly; renamed
|
|
116
|
+
* (`KEY = "${OTHER}"`) and partial (`"Bearer ${TOKEN}"`) refs land here.
|
|
117
|
+
*/
|
|
118
|
+
private warnUnforwardableSecret;
|
|
119
|
+
/**
|
|
120
|
+
* Translate an AIR plugin to a Codex-facing descriptor.
|
|
121
|
+
*
|
|
122
|
+
* Codex's marketplace plugins are remote-installed (`codex plugin add`) and
|
|
123
|
+
* have no local package file an adapter can materialize. AIR therefore treats
|
|
124
|
+
* plugins as composition sugar: a plugin's declared MCP servers / skills /
|
|
125
|
+
* hooks are expanded into the activation set and materialized as their
|
|
126
|
+
* underlying Codex-native artifacts. This descriptor is informational only.
|
|
127
|
+
*/
|
|
128
|
+
translatePlugin(shortId: string, plugin: PluginEntry): Record<string, unknown>;
|
|
129
|
+
/**
|
|
130
|
+
* Resolve a list of activation IDs (each qualified or short) into qualified
|
|
131
|
+
* IDs paired with shortnames suitable for filesystem materialization.
|
|
132
|
+
*
|
|
133
|
+
* Throws on:
|
|
134
|
+
* - unknown IDs (after attempting both qualified and short-form lookup)
|
|
135
|
+
* - ambiguous short references (multiple scopes contribute the shortname)
|
|
136
|
+
* - shortname collisions in the activation set itself (two qualified IDs
|
|
137
|
+
* with the same shortname can't share a single materialization dir)
|
|
138
|
+
*/
|
|
139
|
+
private resolveActivations;
|
|
140
|
+
/**
|
|
141
|
+
* Build the warning emitted when a registered artifact's `path` does not
|
|
142
|
+
* exist on disk at materialization time. The qualified ID encodes the
|
|
143
|
+
* declaring catalog's scope, so a reviewer can trace the offending entry
|
|
144
|
+
* back to its index file. Materialization is skipped for this artifact and
|
|
145
|
+
* the rest of the session proceeds.
|
|
146
|
+
*/
|
|
147
|
+
private missingSourceDirMessage;
|
|
148
|
+
private formatPoolKeys;
|
|
149
|
+
/**
|
|
150
|
+
* Copy referenced documents into a references/ subdirectory of the target.
|
|
151
|
+
* `refIds` are qualified IDs (post-canonicalization).
|
|
152
|
+
*/
|
|
153
|
+
private copyReferences;
|
|
154
|
+
/** Parse an existing `config.toml`, returning `{}` when absent/unparseable. */
|
|
155
|
+
private readToml;
|
|
156
|
+
/**
|
|
157
|
+
* Merge AIR-managed MCP servers and hook registrations into
|
|
158
|
+
* `.codex/config.toml`, preserving any user-authored config.
|
|
159
|
+
*
|
|
160
|
+
* - MCP: keys in `staleMcpIds` are removed; keys in `translatedServers`
|
|
161
|
+
* are set/replaced; other servers and top-level keys pass through.
|
|
162
|
+
* - Hooks: AIR-owned entries (tagged with `_air_hook_id`) whose ID is in
|
|
163
|
+
* `managedHookIds` are pruned, then the current selection is registered.
|
|
164
|
+
*
|
|
165
|
+
* Returns the path written.
|
|
166
|
+
*/
|
|
167
|
+
private writeCodexConfig;
|
|
168
|
+
/**
|
|
169
|
+
* Reconcile the `[hooks.*]` tables on the in-memory config object.
|
|
170
|
+
*
|
|
171
|
+
* Codex represents hooks as `hooks.<Event> = [ { matcher, hooks: [ {type,
|
|
172
|
+
* command, timeout?, statusMessage?} ] } ]`. AIR-owned matcher groups are
|
|
173
|
+
* identified by an `_air_hook_id` marker on the inner hook entry (Codex
|
|
174
|
+
* ignores unrecognized keys unless `--strict-config` is set). Groups whose ID
|
|
175
|
+
* is in `managedHookIds` are removed, then the current `newHookPaths` are
|
|
176
|
+
* registered for their mapped events.
|
|
177
|
+
*/
|
|
178
|
+
private reconcileConfigHooks;
|
|
179
|
+
private isManagedHookEntry;
|
|
180
|
+
/**
|
|
181
|
+
* Remove `mcpIds` from `[mcp_servers]` and AIR-managed hook entries (matched
|
|
182
|
+
* by `_air_hook_id` ∈ `managedHookIds`) from `[hooks.*]` in
|
|
183
|
+
* `.codex/config.toml`, preserving user-authored entries and other top-level
|
|
184
|
+
* fields. Returns the path of the file that was rewritten, or null if the
|
|
185
|
+
* file became empty and was deleted.
|
|
186
|
+
*/
|
|
187
|
+
private pruneCodexConfig;
|
|
188
|
+
/**
|
|
189
|
+
* Build a shell command string from HOOK.json's command and args fields.
|
|
190
|
+
*
|
|
191
|
+
* Hook authors write paths relative to their own hook directory. Codex
|
|
192
|
+
* invokes hooks with a working directory that is not guaranteed to be the
|
|
193
|
+
* project root, so hook-relative paths are anchored to the repository root
|
|
194
|
+
* via `"$(git rev-parse --show-toplevel)/.codex/hooks/<id>/<path>"` — the
|
|
195
|
+
* idiom used in Codex's own hook documentation. The double quotes keep the
|
|
196
|
+
* path safe for project directories with spaces.
|
|
197
|
+
*
|
|
198
|
+
* - `command` is anchored if it starts with `./` (explicit hook-relative).
|
|
199
|
+
* - Each `args` entry is anchored if it looks like a path AND the file
|
|
200
|
+
* exists under the hook's installed directory.
|
|
201
|
+
*
|
|
202
|
+
* Args that are not rewritten and contain shell metacharacters are
|
|
203
|
+
* single-quoted for safety.
|
|
204
|
+
*/
|
|
205
|
+
private buildHookCommand;
|
|
206
|
+
/**
|
|
207
|
+
* Wrap a project-root-relative path in `"$(git rev-parse --show-toplevel)/..."`
|
|
208
|
+
* so the resolved path is independent of the cwd at hook invocation. Double
|
|
209
|
+
* quotes are required so the command substitution runs; characters that are
|
|
210
|
+
* special inside double quotes (`$`, `` ` ``, `"`, `\`) are escaped in the
|
|
211
|
+
* path component so an unusual hook ID or filename can't break out of the
|
|
212
|
+
* quoting.
|
|
213
|
+
*/
|
|
214
|
+
private anchorHookPath;
|
|
215
|
+
/**
|
|
216
|
+
* If `arg` is a hook-relative path that points at a real file under the
|
|
217
|
+
* hook's installed directory, return its project-root-relative form
|
|
218
|
+
* (`.codex/hooks/<id>/<path>`) flagged as anchored so the caller can wrap it.
|
|
219
|
+
* Otherwise return `arg` unchanged with `anchored: false`.
|
|
220
|
+
*/
|
|
221
|
+
private rewriteHookArgPath;
|
|
222
|
+
/** Human-readable list of the supported AIR hook event names (snake_case only). */
|
|
223
|
+
private supportedEventList;
|
|
224
|
+
private copyDirRecursive;
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=codex-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-adapter.d.ts","sourceRoot":"","sources":["../src/codex-adapter.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EAEf,MAAM,oBAAoB,CAAC;AA4B5B,qBAAa,YAAa,YAAW,YAAY;IAC/C,IAAI,SAAW;IACf,WAAW,SAAkB;IAE7B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAexC;IAEI,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IASrC,cAAc,CACZ,SAAS,EAAE,iBAAiB,EAC5B,IAAI,CAAC,EAAE,SAAS,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,kBAAkB;IAmDrB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY;IAa3D;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,cAAc,CAClB,SAAS,EAAE,iBAAiB,EAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC;IAqM3B;;;;;OAKG;IACG,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAIpE;;;;;;;;;;;OAWG;IACG,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,kBAAkB,CAAC;IA6G9B;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAkB5B;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAwB9B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA4B5B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,0BAA0B,CACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GACtC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAQ1C,OAAO,CAAC,kBAAkB;IAgD1B;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;IAY/B;;;;;;;;OAQG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAQ9E;;;;;;;;;OASG;IACH,OAAO,CAAC,kBAAkB;IAgD1B;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,cAAc;IAStB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAyBtB,+EAA+E;IAC/E,OAAO,CAAC,QAAQ;IAShB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,gBAAgB;IAmCxB;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB;IAgG5B,OAAO,CAAC,kBAAkB;IAO1B;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IA4BxB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,gBAAgB;IA4BxB;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAKtB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAoB1B,mFAAmF;IACnF,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,gBAAgB;CAYzB"}
|