@clowder-ai/connector-feishu 0.0.0-stage → 0.1.0-alpha.5

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 (78) hide show
  1. package/README.en.md +54 -0
  2. package/README.md +25 -2
  3. package/assets/icon.svg +3 -0
  4. package/dist/FeishuAdapter.d.ts +250 -0
  5. package/dist/FeishuAdapter.d.ts.map +1 -0
  6. package/dist/FeishuAdapter.js +845 -0
  7. package/dist/FeishuAdapter.js.map +1 -0
  8. package/dist/FeishuQrBindClient.d.ts +23 -0
  9. package/dist/FeishuQrBindClient.d.ts.map +1 -0
  10. package/dist/FeishuQrBindClient.js +97 -0
  11. package/dist/FeishuQrBindClient.js.map +1 -0
  12. package/dist/FeishuTokenManager.d.ts +15 -0
  13. package/dist/FeishuTokenManager.d.ts.map +1 -0
  14. package/dist/FeishuTokenManager.js +35 -0
  15. package/dist/FeishuTokenManager.js.map +1 -0
  16. package/dist/command-ingress.d.ts +10 -0
  17. package/dist/command-ingress.d.ts.map +1 -0
  18. package/dist/command-ingress.js +15 -0
  19. package/dist/command-ingress.js.map +1 -0
  20. package/dist/execution-status.d.ts +27 -0
  21. package/dist/execution-status.d.ts.map +1 -0
  22. package/dist/execution-status.js +48 -0
  23. package/dist/execution-status.js.map +1 -0
  24. package/dist/feishu-card-formatter.d.ts +18 -0
  25. package/dist/feishu-card-formatter.d.ts.map +1 -0
  26. package/dist/feishu-card-formatter.js +58 -0
  27. package/dist/feishu-card-formatter.js.map +1 -0
  28. package/dist/inbound-download.d.ts +13 -0
  29. package/dist/inbound-download.d.ts.map +1 -0
  30. package/dist/inbound-download.js +70 -0
  31. package/dist/inbound-download.js.map +1 -0
  32. package/dist/inbound-media-source.d.ts +25 -0
  33. package/dist/inbound-media-source.d.ts.map +1 -0
  34. package/dist/inbound-media-source.js +111 -0
  35. package/dist/inbound-media-source.js.map +1 -0
  36. package/dist/index.d.ts +9 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +5 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/lifecycle-action.d.ts +30 -0
  41. package/dist/lifecycle-action.d.ts.map +1 -0
  42. package/dist/lifecycle-action.js +457 -0
  43. package/dist/lifecycle-action.js.map +1 -0
  44. package/dist/materialize-media.d.ts +7 -0
  45. package/dist/materialize-media.d.ts.map +1 -0
  46. package/dist/materialize-media.js +35 -0
  47. package/dist/materialize-media.js.map +1 -0
  48. package/dist/media-notice.d.ts +6 -0
  49. package/dist/media-notice.d.ts.map +1 -0
  50. package/dist/media-notice.js +50 -0
  51. package/dist/media-notice.js.map +1 -0
  52. package/dist/plugin-entrypoint.d.ts +9 -0
  53. package/dist/plugin-entrypoint.d.ts.map +1 -0
  54. package/dist/plugin-entrypoint.js +347 -0
  55. package/dist/plugin-entrypoint.js.map +1 -0
  56. package/dist/reply-sender-map.d.ts +10 -0
  57. package/dist/reply-sender-map.d.ts.map +1 -0
  58. package/dist/reply-sender-map.js +123 -0
  59. package/dist/reply-sender-map.js.map +1 -0
  60. package/dist/runtime.d.ts +190 -0
  61. package/dist/runtime.d.ts.map +1 -0
  62. package/dist/runtime.js +580 -0
  63. package/dist/runtime.js.map +1 -0
  64. package/dist/settings.d.ts +20 -0
  65. package/dist/settings.d.ts.map +1 -0
  66. package/dist/settings.js +35 -0
  67. package/dist/settings.js.map +1 -0
  68. package/dist/thread-mappings.d.ts +46 -0
  69. package/dist/thread-mappings.d.ts.map +1 -0
  70. package/dist/thread-mappings.js +62 -0
  71. package/dist/thread-mappings.js.map +1 -0
  72. package/dist/types.d.ts +54 -0
  73. package/dist/types.d.ts.map +1 -0
  74. package/dist/types.js +7 -0
  75. package/dist/types.js.map +1 -0
  76. package/npm-shrinkwrap.json +979 -0
  77. package/package.json +58 -4
  78. package/plugin.yaml +118 -0
package/README.en.md ADDED
@@ -0,0 +1,54 @@
1
+ # Feishu / Lark Connector
2
+
3
+ [Chinese](README.md) · English
4
+
5
+ `@clowder-ai/connector-feishu` packages authenticated Feishu/Lark webhook and long-connection message
6
+ parsing, interactive cards, media transfer, token refresh, and QR credential setup for a Clowder AI Host.
7
+
8
+ ## Configuration
9
+
10
+ The Host projects only the declared App ID, App Secret, connection mode, optional verification token, and
11
+ optional group mention aliases. The package does not read repository `.env` files or ambient Host state.
12
+
13
+ ## Security and authority
14
+
15
+ The Host owns installation, grants, secrets, webhook admission, connector bindings, wake policy, delivery,
16
+ and durable state. Ordinary message text, including `@`, cannot mint a binding or wake an Agent.
17
+
18
+ ## Lifecycle and recovery
19
+
20
+ Tenant tokens and downloaded media are transient runtime data. Rollback drains the package connection before
21
+ the preserved Core adapter starts, while Host-owned bindings and configuration remain unchanged.
22
+
23
+ The Host-loadable builtin runtime is implemented in this package and uses only the existing authenticated
24
+ binding and declared configuration/secret surfaces. No package-local persistence fallback is provided.
25
+
26
+ Inbound provider media locators remain in manifest-declared private plugin state. Public messages expose
27
+ only a `pmr_*` reference plus `sourceEventId`; the declared media source serves bounded chunks and removes
28
+ the locator when the Host settles the import.
29
+
30
+ ## Connection setup
31
+
32
+ The connector supports Feishu messages, media and verified webhooks. QR setup obtains credentials;
33
+ the Host saves them and controls activation.
34
+
35
+ ## Commands and configuration
36
+
37
+ The builtin entrypoint intercepts `/where`, `/new`, `/threads`, `/use`, `/thread`, `/commands`, `/cats`,
38
+ `/status`, `/history`, `/unbind`, `/allow-group`, `/deny-group`, `/focus`, and `/ask` before ordinary ingress.
39
+ Commands reply through the provider and keep their audit quiet. Only an explicit body in `/thread` or
40
+ `/ask` requests Agent invocation; successful delivery is acknowledged only after the Host accepts it.
41
+ `/use` traverses the owner-visible live thread inventory beyond the first 50 rows, deduplicates IDs and
42
+ rejects a non-progressing or exhausted traversal instead of selecting from an incomplete list.
43
+
44
+ Group whitelist, administrators and the group-command restriction keep their original configuration semantics.
45
+ Use normal configuration controls; no permission JSON, separate initialization or legacy import is required.
46
+ The initial group whitelist and command restriction are off and the administrator list is empty.
47
+ Group management commands still require an explicitly configured administrator; an empty list grants nobody administration.
48
+
49
+ The Host owns installation, grants, credentials and lifecycle; saving configuration preserves enable intent. The language link opens a separate document and does not imply automatic language selection.
50
+
51
+ ## Configuration and connection state
52
+
53
+ Setup and credential checks work while disabled. The Host saves successful credentials and preserves enable intent; only an enabled runtime opens the messaging connection. Saved credentials are not proof of a live connection. Use the current connection test to check runtime health.
54
+ App ID and App Secret remain required. QR setup writes those fields and connection mode, not the separate Webhook verification token. The optional group mention alias mapping is hidden from ordinary Settings.
package/README.md CHANGED
@@ -1,3 +1,26 @@
1
- # Temporary Holding Version
1
+ # 飞书连接器
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 简体中文 · [English](README.en.md)
4
+
5
+ 将飞书或 Lark 消息接入 Clowder AI,支持 Webhook 与长连接、交互卡片、媒体传输和扫码配置。
6
+
7
+ ## 开始使用
8
+
9
+ 1. 在飞书创建应用,选择连接模式,配置相应的回调或长连接。
10
+ 2. 在插件设置填写 `appId`、`appSecret`;也可使用扫码操作取得应用凭据。扫码可在停用状态完成,保存不会自行改变启用意图。
11
+ 3. 使用 Webhook 时,填写 `verificationToken`。它通过普通配置保存,不由扫码回写。
12
+ 4. 保存后启用插件建立消息连接;使用连接测试检查当前状态。保存了凭据不等于连接正在运行。
13
+
14
+ 群白名单、管理员和群命令限制使用正常配置控件。初始白名单和限制关闭,管理员为空;群管理命令仍只接受已配置管理员。群内机器人别名映射 `groupBotMentionsJson` 是隐藏设置,不在普通页面提供编辑入口。
15
+
16
+ ## 消息与恢复
17
+
18
+ 应用令牌和下载媒体是临时运行数据。宿主保存配置、对话绑定和检查点;停用先清理连接再允许其他连接器接管。媒体定位信息只在私有状态中保存,通过受限分块读取后清理,不写入对话正文。
19
+
20
+ ## 对话命令
21
+
22
+ 可使用 `/where`、`/new`、`/threads`、`/use`、`/thread`、`/commands`、`/cats`、`/status`、`/history`、`/unbind`、`/focus` 和 `/ask` 查看位置、切换对话或发起请求。`/thread`、`/ask` 只有显式携带正文时才请求猫执行,宿主接受投递后才确认成功。`/use` 会遍历可见对话,列表不完整时不猜测选择。
23
+
24
+ `/allow-group`、`/deny-group` 仅适用于支持群聊且已配置管理员的连接器,不能通过普通私聊文本取得管理权。
25
+
26
+ 宿主管理安装、授权、凭据和启停;配置保存不自动改变启用意图。英文文档是独立文件,互链不代表页面已支持自动语言切换。
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Feishu connector">
2
+ <rect width="64" height="64" rx="14" fill="#3370ff"/><path d="M18 18h28v10H30v18H18z" fill="#fff"/><path d="M34 32h12v14H34z" fill="#00d6b9"/>
3
+ </svg>
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Feishu (飞书/Lark) Bot Adapter
3
+ * Inbound: Parse webhook event → extract private text message
4
+ * Outbound: Send reply via Lark API
5
+ *
6
+ * Uses @larksuiteoapi/node-sdk for API calls.
7
+ * MVP: DM-only (p2p), text-only, single-owner.
8
+ *
9
+ * F088 Multi-Platform Chat Gateway
10
+ */
11
+ import { type ConnectorLogger, type MessageEnvelope, type RichBlock } from './types.js';
12
+ import type { FeishuTokenManager } from './FeishuTokenManager.js';
13
+ export declare const FEISHU_MEDIA_MAX_BYTES: {
14
+ readonly image: 10000000;
15
+ readonly file: 30000000;
16
+ readonly audio: 30000000;
17
+ };
18
+ export interface FeishuAttachment {
19
+ type: 'image' | 'file' | 'audio';
20
+ feishuKey: string;
21
+ fileName?: string;
22
+ duration?: number;
23
+ }
24
+ export interface FeishuInboundMessage {
25
+ chatId: string;
26
+ text: string;
27
+ messageId: string;
28
+ senderId: string;
29
+ /** F134: Display name resolved via Contact API (group chat) */
30
+ senderName?: string;
31
+ /** F134: 'p2p' for DM, 'group' for group chat */
32
+ chatType?: 'p2p' | 'group';
33
+ /** F134: Group chat name resolved via Chat API */
34
+ chatName?: string;
35
+ attachments?: FeishuAttachment[];
36
+ }
37
+ export interface FeishuCardAction {
38
+ eventId: string;
39
+ chatId: string;
40
+ senderId: string;
41
+ actionValue: Record<string, unknown>;
42
+ option?: string;
43
+ chatType?: 'p2p' | 'group';
44
+ }
45
+ export interface FeishuMediaPayload {
46
+ type: 'image' | 'file' | 'audio';
47
+ imageKey?: string;
48
+ fileKey?: string;
49
+ /** Host-authorized bytes. The package consumes them before the outbound action returns. */
50
+ content?: AsyncIterable<Uint8Array>;
51
+ /** Display name — used as file_name in Feishu upload and for file_type inference */
52
+ fileName?: string;
53
+ }
54
+ /**
55
+ * #1035: Outbound group-chat @mention alias.
56
+ * Bot Pollers filter inbound on `mentions[].id.open_id`; plain `@name` text in
57
+ * outbound body never produces such a mention. Map an alias (e.g. `胖胖虾`) to
58
+ * a real Feishu OpenID so the body `@胖胖虾` is rendered as a real `<at>` token.
59
+ */
60
+ export interface FeishuMentionAlias {
61
+ /** Feishu OpenID of the target user/bot (e.g. `ou_xxx`). */
62
+ openId: string;
63
+ /**
64
+ * Display name used in text-message `<at user_id="...">@displayName</at>`.
65
+ * Card markdown uses self-closing `<at id=ou_xxx></at>` and Feishu auto-renders the name.
66
+ */
67
+ displayName?: string;
68
+ }
69
+ export interface FeishuAdapterOptions {
70
+ /** Feishu Verification Token for webhook event authentication. If not set, token verification is skipped. */
71
+ verificationToken?: string | undefined;
72
+ /**
73
+ * #1035: Outbound `@alias` → Feishu `<at>` token resolution map (group-chat scoped).
74
+ * Keys are bare aliases (no leading `@`); values include the target OpenID.
75
+ * Unconfigured aliases pass through unchanged; `@` mid-token (e.g. inside an email) is not replaced.
76
+ */
77
+ groupBotMentions?: Record<string, FeishuMentionAlias>;
78
+ }
79
+ export declare class FeishuAdapter {
80
+ readonly connectorId = "feishu";
81
+ private readonly client;
82
+ private readonly log;
83
+ private readonly verificationToken;
84
+ private readonly groupBotMentions;
85
+ private tokenManager;
86
+ private uploadFetchFn;
87
+ private inboundFetchFn;
88
+ private inboundMediaTimeoutMs;
89
+ private sendMessageFn;
90
+ private editMessageFn;
91
+ private deleteMessageFn;
92
+ private addReactionFn;
93
+ private botOpenId;
94
+ private static CACHE_TTL_MS;
95
+ private senderNameCache;
96
+ private chatNameCache;
97
+ private chatTypeCache;
98
+ constructor(appId: string, appSecret: string, log: ConnectorLogger, options?: FeishuAdapterOptions);
99
+ downloadInboundMedia(locator: {
100
+ readonly sourceEventId: string;
101
+ readonly type: 'image' | 'file' | 'audio' | 'video';
102
+ readonly platformKey: string;
103
+ }): Promise<Buffer>;
104
+ /**
105
+ * Check if the request body is a Feishu URL verification challenge.
106
+ * Returns the challenge token if so, null otherwise.
107
+ */
108
+ isVerificationChallenge(body: unknown): {
109
+ challenge: string;
110
+ } | null;
111
+ /**
112
+ * Verify event callback token.
113
+ * Checks that the event body's header.token matches the configured verificationToken.
114
+ * If no verificationToken is configured, verification is skipped (returns true).
115
+ */
116
+ verifyEventToken(body: unknown): boolean;
117
+ /**
118
+ * Parse a Feishu event callback into an inbound message.
119
+ * Supports text, image, file, audio, and post message types.
120
+ * For group chats, only processes messages that @mention the bot.
121
+ * Returns null for unsupported events or group messages not mentioning bot.
122
+ */
123
+ parseEvent(eventBody: unknown): FeishuInboundMessage | null;
124
+ /**
125
+ * AC-14: Parse a Feishu card action callback (button click, etc.).
126
+ * Returns null for non-card-action events.
127
+ */
128
+ parseCardAction(eventBody: unknown): FeishuCardAction | null;
129
+ private sendLarkMessage;
130
+ /** Send a provider key or Host-authorized byte stream to a Feishu chat. */
131
+ sendMedia(externalChatId: string, payload: FeishuMediaPayload): Promise<void>;
132
+ private sendWithPlatformKey;
133
+ /**
134
+ * Feishu accepts only OPUS for `msg_type: audio`. The connector vocabulary
135
+ * grants no process capability, so there is no transcoder/subprocess to
136
+ * call: non-opus audio is delivered as the original file (`msg_type: file`,
137
+ * original name) rather than being converted or silently dropped.
138
+ */
139
+ private deliveryTypeFor;
140
+ /**
141
+ * Upload a local file to Feishu and return the platform key.
142
+ * Images → /im/v1/images, files/audio → /im/v1/files.
143
+ *
144
+ * Audio: only true OPUS input keeps `file_type: opus` / `msg_type: audio`;
145
+ * non-opus audio is uploaded as a plain file (see deliveryTypeFor).
146
+ */
147
+ private uploadToFeishu;
148
+ setBotOpenId(openId: string): void;
149
+ getBotOpenId(): string | null;
150
+ resolveSenderName(openId: string): Promise<string | undefined>;
151
+ /**
152
+ * Fallback: resolve sender name from the chat members API.
153
+ * Works even when Contact API returns 41050 (user not in app's contact scope).
154
+ * Uses the same senderNameCache as resolveSenderName().
155
+ */
156
+ resolveSenderNameFromChat(openId: string, chatId: string): Promise<string | undefined>;
157
+ resolveChatName(chatId: string): Promise<string | undefined>;
158
+ resolveChatType(chatId: string): Promise<'p2p' | 'group' | undefined>;
159
+ private prependAtMention;
160
+ /**
161
+ * #1035: Resolve `@alias` patterns in outbound body text to Feishu `<at>` tokens.
162
+ *
163
+ * - `text` mode → `<at user_id="ou_xxx">@displayName</at>` (for `msg_type: text`)
164
+ * - `card_markdown` mode → `<at id=ou_xxx></at>` (Feishu auto-renders display name in cards)
165
+ *
166
+ * Only matches `@` preceded by start-of-string or a delimiter (whitespace, brackets,
167
+ * Chinese open-quotes, full-width space), so `user@example.com` is NOT replaced.
168
+ * Unknown aliases pass through unchanged.
169
+ * Aliases are matched on bare unicode letters/digits/underscore (no leading `@` in the key).
170
+ */
171
+ private resolveBodyMentions;
172
+ sendReply(externalChatId: string, content: string, metadata?: Record<string, unknown>): Promise<void>;
173
+ sendRichMessage(externalChatId: string, textContent: string, blocks: RichBlock[], catDisplayName: string, metadata?: Record<string, unknown>): Promise<void>;
174
+ sendFormattedReply(externalChatId: string, envelope: MessageEnvelope, metadata?: Record<string, unknown>): Promise<void>;
175
+ sendPlaceholder(externalChatId: string, text: string): Promise<string>;
176
+ /**
177
+ * Edit an already-sent message card in place.
178
+ * Uses Lark im.message.patch API — only supports interactive (card) messages.
179
+ * The text is rendered as markdown inside the card body.
180
+ */
181
+ editMessage(_externalChatId: string, platformMessageId: string, text: string): Promise<boolean>;
182
+ /**
183
+ * Delete a message by its platform message ID.
184
+ * Used to clean up streaming placeholder cards after final outbound delivery.
185
+ */
186
+ deleteMessage(platformMessageId: string): Promise<void>;
187
+ /**
188
+ * F157: Add an emoji reaction to a message (e.g. ❤️ on user's inbound message).
189
+ * Fire-and-forget — errors are logged but never thrown.
190
+ */
191
+ addReaction(platformMessageId: string, emojiType: string): Promise<void>;
192
+ /**
193
+ * F157: Edit a streaming card to a truthful terminal state.
194
+ * Preferred over deleteMessage to avoid Feishu's "recalled" notification.
195
+ */
196
+ finalizeStreamCard(_externalChatId: string, platformMessageId: string, catDisplayName: string, outcome?: 'completed' | 'failed' | 'cancelled'): Promise<void>;
197
+ /**
198
+ * Test helper: inject a mock send function.
199
+ * @internal
200
+ */
201
+ _injectSendMessage(fn: (params: {
202
+ chatId: string;
203
+ content: string;
204
+ msgType: string;
205
+ }) => Promise<unknown>): void;
206
+ /**
207
+ * Test helper: inject a mock edit function.
208
+ * @internal
209
+ */
210
+ _injectEditMessage(fn: (params: {
211
+ messageId: string;
212
+ content: string;
213
+ }) => Promise<unknown>): void;
214
+ /**
215
+ * Test helper: inject a mock delete function.
216
+ * @internal
217
+ */
218
+ _injectDeleteMessage(fn: (params: {
219
+ messageId: string;
220
+ }) => Promise<unknown>): void;
221
+ /**
222
+ * Test helper: inject a mock addReaction function.
223
+ * @internal
224
+ */
225
+ _injectAddReaction(fn: (params: {
226
+ messageId: string;
227
+ emojiType: string;
228
+ }) => Promise<unknown>): void;
229
+ /**
230
+ * Test helper: inject a FeishuTokenManager.
231
+ * @internal
232
+ */
233
+ _injectTokenManager(tm: FeishuTokenManager): void;
234
+ /**
235
+ * Test helper: inject a mock fetch for upload APIs.
236
+ * @internal
237
+ */
238
+ _injectUploadFetch(fn: typeof fetch): void;
239
+ /** @internal */
240
+ _injectInboundFetch(fn: typeof fetch): void;
241
+ /** @internal */
242
+ _injectInboundMediaTimeout(timeoutMs: number): void;
243
+ /**
244
+ * Test helper: clear TTL caches.
245
+ * @internal
246
+ */
247
+ _clearCaches(): void;
248
+ }
249
+ export declare function inferFeishuFileType(fileName: string): string;
250
+ //# sourceMappingURL=FeishuAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeishuAdapter.d.ts","sourceRoot":"","sources":["../src/FeishuAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAyB,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC/G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAYlE,eAAO,MAAM,sBAAsB;;;;CAIzB,CAAC;AAIX,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IAC3B,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACpC,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,6GAA6G;IAC7G,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CACvD;AAED,qBAAa,aAAa;IACxB,QAAQ,CAAC,WAAW,YAAY;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAkB;IACtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAgB;IAClD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqC;IACtE,OAAO,CAAC,YAAY,CAAmC;IACvD,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,cAAc,CAAkC;IACxD,OAAO,CAAC,qBAAqB,CAA4B;IACzD,OAAO,CAAC,aAAa,CACd;IACP,OAAO,CAAC,aAAa,CAAuF;IAC5G,OAAO,CAAC,eAAe,CAAsE;IAC7F,OAAO,CAAC,aAAa,CAAyF;IAC9G,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAkB;IAC7C,OAAO,CAAC,eAAe,CAA0D;IACjF,OAAO,CAAC,aAAa,CAA0D;IAC/E,OAAO,CAAC,aAAa,CAAuE;gBAEhF,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,oBAAoB;IAc5F,oBAAoB,CAAC,OAAO,EAAE;QAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;QACpD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;KAC9B,GAAG,OAAO,CAAC,MAAM,CAAC;IA2BnB;;;OAGG;IACH,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IASpE;;;;OAIG;IACH,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IASxC;;;;;OAKG;IACH,UAAU,CAAC,SAAS,EAAE,OAAO,GAAG,oBAAoB,GAAG,IAAI;IA2I3D;;;OAGG;IACH,eAAe,CAAC,SAAS,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI;YA0C9C,eAAe;IAiB7B,2EAA2E;IACrE,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;YAoCrE,mBAAmB;IAYjC;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAMvB;;;;;;OAMG;YACW,cAAc;IA4D5B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIlC,YAAY,IAAI,MAAM,GAAG,IAAI;IAIvB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAiCpE;;;;OAIG;IACG,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IA+DtF,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAuB5D,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,OAAO,GAAG,SAAS,CAAC;IAwB3E,OAAO,CAAC,gBAAgB;IAKxB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,mBAAmB;IAkCrB,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrG,eAAe,CACnB,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,SAAS,EAAE,EACnB,cAAc,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAOV,kBAAkB,CACtB,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAiDV,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAW5E;;;;OAIG;IACG,WAAW,CAAC,eAAe,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAoBrG;;;OAGG;IACG,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW7D;;;OAGG;IACG,WAAW,CAAC,iBAAiB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe9E;;;OAGG;IACG,kBAAkB,CACtB,eAAe,EAAE,MAAM,EACvB,iBAAiB,EAAE,MAAM,EACzB,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE,WAAW,GAAG,QAAQ,GAAG,WAAyB,GAC1D,OAAO,CAAC,IAAI,CAAC;IA0BhB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAIhH;;;OAGG;IACH,kBAAkB,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAIlG;;;OAGG;IACH,oBAAoB,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAInF;;;OAGG;IACH,kBAAkB,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAIpG;;;OAGG;IACH,mBAAmB,CAAC,EAAE,EAAE,kBAAkB,GAAG,IAAI;IAIjD;;;OAGG;IACH,kBAAkB,CAAC,EAAE,EAAE,OAAO,KAAK,GAAG,IAAI;IAI1C,gBAAgB;IAChB,mBAAmB,CAAC,EAAE,EAAE,OAAO,KAAK,GAAG,IAAI;IAI3C,gBAAgB;IAChB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAInD;;;OAGG;IACH,YAAY,IAAI,IAAI;CAIrB;AAiBD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO5D"}