@aramisfa/openclaw-a2a-outbound 3.0.0 → 4.1.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 CHANGED
@@ -1,8 +1,20 @@
1
1
  # @aramisfa/openclaw-a2a-outbound
2
2
 
3
- Native OpenClaw outbound A2A delegation plugin.
3
+ OpenClaw outbound A2A delegation plugin with a zero-config local onboarding CLI.
4
4
 
5
- This package registers exactly one optional OpenClaw tool, `remote_agent`. The tool exposes five actions: `list_targets`, `send`, `watch`, `status`, and `cancel`.
5
+ ```bash
6
+ openclaw plugins install @aramisfa/openclaw-a2a-outbound
7
+ openclaw a2a demo run
8
+ ```
9
+
10
+ `openclaw a2a demo run` starts the packaged local demo peer, configures a temporary `local-demo` target in memory, exercises `list_targets`, task-bearing `send`, `watch`, `status`, and continuation replay, then prints the returned `summary.continuation`.
11
+
12
+ This package registers:
13
+
14
+ - the `openclaw a2a` CLI family for demos and diagnostics
15
+ - one optional OpenClaw tool, `remote_agent`, with actions `list_targets`, `send`, `watch`, `status`, and `cancel`
16
+
17
+ For a raw payload walkthrough, see [../../docs/quickstart.md](../../docs/quickstart.md).
6
18
 
7
19
  ## Installation
8
20
 
@@ -24,10 +36,31 @@ clawhub install a2a-delegation-setup
24
36
 
25
37
  The ClawHub skill is an optional guided setup helper for installing, enabling, configuring, verifying, updating, and troubleshooting `@aramisfa/openclaw-a2a-outbound`. The plugin itself still installs through `openclaw plugins install @aramisfa/openclaw-a2a-outbound`.
26
38
 
39
+ ## Routing Boundary
40
+
41
+ `@aramisfa/openclaw-a2a-outbound` is the only outbound A2A continuation surface in this repository.
42
+
43
+ - `summary.continuation` is for `remote_agent` follow-up only.
44
+ - Do not replay `summary.continuation` back through inbound channel delivery on channel `a2a`.
45
+ - Do not treat an inbound A2A channel turn, `OriginatingChannel`, `OriginatingTo`, or inbound `capabilities.reply` as proof that generic channel-level queued follow-up is supported.
46
+ - If you see `A2A_OUTBOUND_DELIVERY_UNSUPPORTED`, OpenClaw tried to route a queued follow-up through `openclaw-a2a-inbound`; switch the workflow back to persisted `summary.continuation` plus `remote_agent`.
47
+
27
48
  ## Requirements
28
49
 
29
50
  - Node.js `>=22.12.0`
30
- - OpenClaw `2026.3.2`
51
+ - OpenClaw `2026.4.15`
52
+
53
+ ## CLI
54
+
55
+ ```bash
56
+ openclaw a2a demo run [--json] [--write-continuation <path>]
57
+ openclaw a2a demo serve [--port <port>] [--json]
58
+ openclaw a2a doctor [--alias <alias>] [--json]
59
+ ```
60
+
61
+ - `demo run`: self-contained first-success path.
62
+ - `demo serve`: long-lived local peer that prints exact config commands and raw `remote_agent` payloads.
63
+ - `doctor`: read-only install/config/target/card diagnostics for real targets.
31
64
 
32
65
  ## OpenClaw Plugin Config
33
66
 
@@ -48,7 +81,7 @@ The ClawHub skill is an optional guided setup helper for installing, enabling, c
48
81
  "baseUrl": "https://support.example",
49
82
  "description": "Primary support lane",
50
83
  "tags": ["support"],
51
- "examples": ["Summarize this incident and propose next steps."],
84
+ "examples": ["Summarize this incident and propose immediate actions."],
52
85
  "default": true
53
86
  }
54
87
  ],
@@ -102,6 +135,19 @@ Snake_case tool fields are translated internally to the A2A SDK camelCase reques
102
135
 
103
136
  Failed `send` and `sendStream` calls include `error.details.capability_diagnostics` so remote validation or content-type rejections can be compared against the stored peer card without blocking permissive runtime sends.
104
137
 
138
+ ## Continuation Rules
139
+
140
+ This package returns continuation metadata under `summary.continuation`. Persist that subtree verbatim and use it to choose the next action.
141
+
142
+ - `summary.continuation.target`: the canonical persisted routing contract for machine follow-up. Persist `target_url`, `card_path`, and `preferred_transports` verbatim; `target_alias` is optional descriptive metadata.
143
+ - `summary.continuation.task`: the only machine-readable signal that a real remote task exists. Read `task_handle`, `task_id`, `status`, `can_resume_send`, `can_watch`, and the deprecated alias `can_send` from here, and use it for follow-up `send`, `watch`, `status`, and `cancel`.
144
+ - `summary.continuation.conversation`: send-only conversation continuity. Read `context_id` from here and use it only for follow-up `send`.
145
+ - `response_kind`: descriptive wire-shape classification only. `response_kind="message"` means the peer returned a `Message`; `response_kind="task"` means a task-bearing response or event appeared. `response_kind` does not replace `summary.continuation`.
146
+ - `summary.target_*` and other top-level compatibility aliases are descriptive only. Do not infer lifecycle continuity from flat `task_id`, flat `context_id`, or other top-level fields.
147
+ - `watch`, `status`, and `cancel` require `summary.continuation.task`.
148
+ - Conversation-only follow-up uses `context_id`, not task actions.
149
+ - `summary.continuation` is not a license to route follow-ups through channel `a2a`; it is the persisted contract for `remote_agent` only.
150
+
105
151
  Supported `send` modes:
106
152
 
107
153
  - new task: `send` with `target_alias`/`target_url` or a configured default target, and no continuation fields
@@ -109,24 +155,9 @@ Supported `send` modes:
109
155
  - related new task: `send` with `reference_task_ids`, optionally plus `context_id`, plus `target_alias`/`target_url` or a configured default target
110
156
  - new task in an existing conversation: `send` with a persisted conversation-only `continuation`; flat `context_id` plus `target_alias`/`target_url` remains manual compatibility only
111
157
 
112
- When a delegated task pauses in `input-required` or an approval workflow, resume it with `send` again. Persist `summary.continuation` verbatim and pass that subtree back directly. If the nested `task_handle` is expired or unavailable, the plugin automatically falls back within that nested contract to `continuation.target` + `continuation.task.task_id`; callers should not flatten persisted follow-up state back into `target_alias`/`task_id`.
113
-
114
- ## Reading Output Continuations
158
+ When a delegated task pauses in `input-required` or an approval workflow, resume it with `send` again. If the nested `task_handle` is expired or unavailable, the plugin automatically falls back within that nested contract to `continuation.target` + `continuation.task.task_id`; callers should not flatten persisted follow-up state back into `target_alias`/`task_id`.
115
159
 
116
- This package returns continuation metadata under `summary.continuation`.
117
-
118
- - `summary.continuation.target`: the canonical persisted routing contract for machine follow-up. Persist `target_url`, `card_path`, and `preferred_transports` verbatim; `target_alias` is optional descriptive metadata.
119
- - `summary.continuation.task`: the only machine-readable signal that a real remote task exists. Read `task_handle`, `task_id`, `status`, `can_resume_send`, `can_watch`, and the deprecated alias `can_send` from here, and use it for follow-up `send`, `watch`, `status`, and `cancel`.
120
- - `summary.continuation.conversation`: send-only conversation continuity. Read `context_id` from here and use it only for follow-up `send`. Do not use it to infer task continuity.
121
- - `response_kind`: descriptive wire-shape classification only. `response_kind="message"` means the peer returned a `Message`; `response_kind="task"` means a task-bearing response or event appeared. `response_kind` does not replace `summary.continuation`.
122
- - Do not poll from conversation continuity.
123
- - `watch`, `status`, and `cancel` require `summary.continuation.task`.
124
- - Message-only follow-up uses `context_id`, not task actions.
125
- - `task_handle` is returned only when the peer actually created a task.
126
- - `summary.target_*` is descriptive only for humans and logs; it is no longer part of the machine follow-up recipe.
127
- - Top-level compatibility aliases are descriptive only. Read task and conversation continuity from `summary.continuation`, and do not infer lifecycle continuity from flat `task_id`, flat `context_id`, or other top-level fields.
128
-
129
- Branch on `summary.continuation.task` vs `summary.continuation.conversation` before choosing the next action:
160
+ Choose the next action based on the continuation shape:
130
161
 
131
162
  ```ts
132
163
  const continuation = result.summary.continuation
@@ -144,8 +175,6 @@ if (task) {
144
175
  }
145
176
  ```
146
177
 
147
- Persist `summary.continuation` verbatim and branch on `summary.continuation.task` versus `summary.continuation.conversation`. `summary.continuation.task` is the only machine-readable authority for lifecycle follow-up. Conversation-only continuation remains send-only, and `watch`, `status`, and `cancel` require `summary.continuation.task`.
148
-
149
178
  ## Examples
150
179
 
151
180
  ### Discover Available Targets
@@ -166,9 +195,10 @@ Persist `summary.continuation` verbatim and branch on `summary.continuation.task
166
195
  "target_url": "https://support.example/",
167
196
  "default": true,
168
197
  "tags": ["support"],
169
- "examples": ["Summarize this incident and propose next steps."],
198
+ "examples": ["Summarize this incident and propose immediate actions."],
170
199
  "target_name": "Support Agent",
171
200
  "description": "Primary support lane",
201
+ "streaming_supported": true,
172
202
  "peer_card": {
173
203
  "preferred_transport": "JSONRPC",
174
204
  "additional_interfaces": [
@@ -194,7 +224,7 @@ Persist `summary.continuation` verbatim and branch on `summary.continuation.task
194
224
  "name": "Incident Triage",
195
225
  "description": "Summarize incidents and propose next actions.",
196
226
  "tags": ["support"],
197
- "examples": ["Summarize this incident and propose next steps."],
227
+ "examples": ["Summarize this incident and propose immediate actions."],
198
228
  "input_modes": ["application/json"],
199
229
  "output_modes": ["application/pdf"]
200
230
  }
@@ -217,7 +247,7 @@ Persist `summary.continuation` verbatim and branch on `summary.continuation.task
217
247
  "configuredDescription": "Primary support lane",
218
248
  "default": true,
219
249
  "tags": ["support"],
220
- "examples": ["Summarize this incident and propose next steps."],
250
+ "examples": ["Summarize this incident and propose immediate actions."],
221
251
  "card": {
222
252
  "displayName": "Support Agent",
223
253
  "description": "Summarize incidents and propose next actions.",
@@ -245,7 +275,7 @@ Persist `summary.continuation` verbatim and branch on `summary.continuation.task
245
275
  "name": "Incident Triage",
246
276
  "description": "Summarize incidents and propose next actions.",
247
277
  "tags": ["support"],
248
- "examples": ["Summarize this incident and propose next steps."],
278
+ "examples": ["Summarize this incident and propose immediate actions."],
249
279
  "inputModes": ["application/json"],
250
280
  "outputModes": ["application/pdf"]
251
281
  }
@@ -424,7 +454,7 @@ const followUpContext = conversation?.context_id
424
454
 
425
455
  ### Continue An Existing Remote Task With `task_handle`
426
456
 
427
- Prefer passing the persisted continuation subtree back directly when a delegated task reaches `input-required` or asks for approval:
457
+ Resend the persisted continuation subtree:
428
458
 
429
459
  ```json
430
460
  {
@@ -456,7 +486,7 @@ Prefer passing the persisted continuation subtree back directly when a delegated
456
486
 
457
487
  ### Continue An Existing Remote Task With `task_id`
458
488
 
459
- If `summary.continuation.task.task_handle` is unavailable, omit it and keep using the persisted nested target contract:
489
+ Use the persisted continuation without `task_handle`:
460
490
 
461
491
  ```json
462
492
  {
@@ -487,7 +517,7 @@ If `summary.continuation.task.task_handle` is unavailable, omit it and keep usin
487
517
 
488
518
  ### Start A New Task In An Existing Conversation
489
519
 
490
- Use `summary.continuation.conversation.context_id` when the prior result has conversation continuity without task continuity:
520
+ Use `summary.continuation.conversation.context_id` when only conversation continuity exists:
491
521
 
492
522
  ```json
493
523
  {
@@ -559,7 +589,7 @@ if (conversation) {
559
589
  }
560
590
  ```
561
591
 
562
- Do not poll from conversation continuity. `watch`, `status`, and `cancel` require `summary.continuation.task`.
592
+ Conversation continuity is send-only. `watch`, `status`, and `cancel` require `summary.continuation.task`.
563
593
 
564
594
  ### Check Task Status With `task_handle`
565
595
 
@@ -645,7 +675,7 @@ const nextSend = conversation
645
675
  : undefined
646
676
  ```
647
677
 
648
- When `summary.continuation.task.task_handle` is expired or unavailable, retry with the same persisted `continuation`; the plugin automatically falls back to `continuation.target` + `summary.continuation.task.task_id`:
678
+ If `summary.continuation.task.task_handle` is expired or unavailable, retry with the same persisted `continuation`:
649
679
 
650
680
  ```json
651
681
  {
@@ -665,7 +695,7 @@ When `summary.continuation.task.task_handle` is expired or unavailable, retry wi
665
695
  }
666
696
  ```
667
697
 
668
- `watch` and `cancel` use the same follow-up targeting rules, and both require `summary.continuation.task` from a prior result. Conversation continuity by itself is never enough for lifecycle actions:
698
+ `watch` and `cancel` require `summary.continuation.task` from a prior result:
669
699
 
670
700
  ```json
671
701
  { "action": "watch", "continuation": { "target": { "target_url": "https://support.example/", "card_path": "/.well-known/agent-card.json", "preferred_transports": ["JSONRPC", "HTTP+JSON"], "target_alias": "support" }, "task": { "task_handle": "rah_0a3ff8c2-4a6d-48cb-a57d-4ae6f3c589d0", "task_id": "task-456" } } }
@@ -0,0 +1,9 @@
1
+ declare const _default: {
2
+ id: string;
3
+ name: string;
4
+ description: string;
5
+ configSchema: import("openclaw/plugin-sdk/plugin-entry").OpenClawPluginConfigSchema;
6
+ register: NonNullable<import("openclaw/plugin-sdk/plugin-entry").OpenClawPluginDefinition["register"]>;
7
+ } & Pick<import("openclaw/plugin-sdk/plugin-entry").OpenClawPluginDefinition, "kind" | "reload" | "nodeHostCommands" | "securityAuditCollectors">;
8
+ export default _default;
9
+ //# sourceMappingURL=cli-metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-metadata.d.ts","sourceRoot":"","sources":["../src/cli-metadata.ts"],"names":[],"mappings":";;;;;;;AAQA,wBA6BG"}
@@ -0,0 +1,29 @@
1
+ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
2
+ import { registerA2ACli } from "./cli.js";
3
+ import { A2A_OUTBOUND_OPENCLAW_CONFIG_SCHEMA, } from "./config.js";
4
+ import { PLUGIN_ID } from "./constants.js";
5
+ export default definePluginEntry({
6
+ id: PLUGIN_ID,
7
+ name: "External A2A Delegation CLI Metadata",
8
+ description: "Registers the OpenClaw a2a CLI during command discovery.",
9
+ configSchema: A2A_OUTBOUND_OPENCLAW_CONFIG_SCHEMA,
10
+ register(api) {
11
+ const config = A2A_OUTBOUND_OPENCLAW_CONFIG_SCHEMA.parse?.(api.pluginConfig ?? {});
12
+ api.registerCli?.(({ program }) => {
13
+ registerA2ACli(program, {
14
+ pluginConfig: config,
15
+ rootConfig: api.config,
16
+ });
17
+ }, {
18
+ commands: ["a2a"],
19
+ descriptors: [
20
+ {
21
+ name: "a2a",
22
+ description: "A2A outbound demo and diagnostics",
23
+ hasSubcommands: true,
24
+ },
25
+ ],
26
+ });
27
+ },
28
+ });
29
+ //# sourceMappingURL=cli-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-metadata.js","sourceRoot":"","sources":["../src/cli-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EACL,mCAAmC,GAEpC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,eAAe,iBAAiB,CAAC;IAC/B,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,sCAAsC;IAC5C,WAAW,EAAE,0DAA0D;IACvE,YAAY,EAAE,mCAAmC;IACjD,QAAQ,CAAC,GAAG;QACV,MAAM,MAAM,GAAG,mCAAmC,CAAC,KAAK,EAAE,CACxD,GAAG,CAAC,YAAY,IAAI,EAAE,CACI,CAAC;QAE7B,GAAG,CAAC,WAAW,EAAE,CACf,CAAC,EAAE,OAAO,EAAwB,EAAE,EAAE;YACpC,cAAc,CAAC,OAA+C,EAAE;gBAC9D,YAAY,EAAE,MAAM;gBACpB,UAAU,EAAE,GAAG,CAAC,MAAM;aACvB,CAAC,CAAC;QACL,CAAC,EACD;YACE,QAAQ,EAAE,CAAC,KAAK,CAAC;YACjB,WAAW,EAAE;gBACX;oBACE,IAAI,EAAE,KAAK;oBACX,WAAW,EAAE,mCAAmC;oBAChD,cAAc,EAAE,IAAI;iBACrB;aACF;SACF,CACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,79 @@
1
+ import { LOCAL_DEMO_ALIAS, type StartedDemoPeer } from "./demo-peer.js";
2
+ import type { A2AOutboundPluginConfig } from "./config.js";
3
+ import type { RemoteAgentSummary } from "./result-shape.js";
4
+ type CliCommand = {
5
+ description(value: string): CliCommand;
6
+ command(value: string): CliCommand;
7
+ argument?(flags: string, description?: string): CliCommand;
8
+ option(flags: string, description?: string, defaultValue?: unknown): CliCommand;
9
+ action(handler: (opts: CommandOptions) => unknown): CliCommand;
10
+ };
11
+ type CliProgram = {
12
+ command(value: string): CliCommand;
13
+ };
14
+ type RegisterA2ACliOptions = {
15
+ pluginConfig: A2AOutboundPluginConfig;
16
+ rootConfig?: unknown;
17
+ };
18
+ type CommandOptions = Record<string, unknown>;
19
+ export type DemoRunOptions = {
20
+ writeContinuation?: string;
21
+ };
22
+ export type DemoRunStep = {
23
+ name: "list_targets" | "send" | "watch" | "status" | "continuation_send";
24
+ ok: boolean;
25
+ summary?: RemoteAgentSummary;
26
+ error?: unknown;
27
+ };
28
+ export type DemoRunResult = {
29
+ ok: boolean;
30
+ peer: {
31
+ base_url: string;
32
+ agent_card_url: string;
33
+ json_rpc_url: string;
34
+ };
35
+ alias: typeof LOCAL_DEMO_ALIAS;
36
+ steps: DemoRunStep[];
37
+ continuation?: NonNullable<RemoteAgentSummary["continuation"]>;
38
+ continuation_path?: string;
39
+ };
40
+ export type DemoServeInstructions = {
41
+ base_url: string;
42
+ agent_card_url: string;
43
+ json_rpc_url: string;
44
+ commands: {
45
+ configure_target: string;
46
+ };
47
+ remote_agent_payloads: {
48
+ list_targets: Record<string, unknown>;
49
+ send: Record<string, unknown>;
50
+ watch: Record<string, unknown>;
51
+ status: Record<string, unknown>;
52
+ continuation_replay: Record<string, unknown>;
53
+ };
54
+ };
55
+ export type DoctorCheck = {
56
+ name: "plugin_cli_loaded" | "plugins_global_enabled" | "plugin_entry_enabled" | "plugin_config_enabled" | "target_present" | "agent_card_reachable";
57
+ status: "pass" | "fail" | "warn";
58
+ message: string;
59
+ details?: Record<string, unknown>;
60
+ };
61
+ export type DoctorResult = {
62
+ ok: boolean;
63
+ alias: string;
64
+ checks: DoctorCheck[];
65
+ };
66
+ export declare function buildDemoServeInstructions(peer: Pick<StartedDemoPeer, "baseUrl" | "cardUrl" | "jsonRpcUrl">): DemoServeInstructions;
67
+ export declare function runDemoRun(options?: DemoRunOptions): Promise<DemoRunResult>;
68
+ export declare function runDoctor(params: {
69
+ alias?: string;
70
+ pluginConfig: A2AOutboundPluginConfig;
71
+ rootConfig?: unknown;
72
+ }): Promise<DoctorResult>;
73
+ export declare function registerA2ACli(program: CliProgram, options: RegisterA2ACliOptions): void;
74
+ export declare const DEMO_SERVE_PATHS: {
75
+ readonly agentCardPath: "/.well-known/agent-card.json";
76
+ readonly jsonRpcPath: "/a2a/jsonrpc";
77
+ };
78
+ export {};
79
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,gBAAgB,EAGhB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAiB,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE3E,KAAK,UAAU,GAAG;IAChB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACvC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IACnC,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC3D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAChF,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,OAAO,GAAG,UAAU,CAAC;CAChE,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;CACpC,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,YAAY,EAAE,uBAAuB,CAAC;IACtC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE9C,MAAM,MAAM,cAAc,GAAG;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,mBAAmB,CAAC;IACzE,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,KAAK,EAAE,OAAO,gBAAgB,CAAC;IAC/B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC;IAC/D,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE;QACR,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,qBAAqB,EAAE;QACrB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC9C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EACA,mBAAmB,GACnB,wBAAwB,GACxB,sBAAsB,GACtB,uBAAuB,GACvB,gBAAgB,GAChB,sBAAsB,CAAC;IAC3B,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,CAAC;AAgKF,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC,GAChE,qBAAqB,CAiDvB;AAED,wBAAsB,UAAU,CAC9B,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CA6GxB;AAoED,wBAAsB,SAAS,CAAC,MAAM,EAAE;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,uBAAuB,CAAC;IACtC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,OAAO,CAAC,YAAY,CAAC,CAiFxB;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,qBAAqB,GAC7B,IAAI,CAwFN;AAED,eAAO,MAAM,gBAAgB;;;CAGnB,CAAC"}