@blade-hq/agent-kit 0.4.5 → 0.4.7
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 +39 -1
- package/dist/{SkillStatusBar-DItrW2vv.d.ts → SkillStatusBar-DQyipdzn.d.ts} +112 -8
- package/dist/chunk-2UP7MG3J.js +66 -0
- package/dist/chunk-2UP7MG3J.js.map +1 -0
- package/dist/chunk-4VWLTG5L.js +2984 -0
- package/dist/chunk-4VWLTG5L.js.map +1 -0
- package/dist/chunk-7LEKQI47.js +32 -0
- package/dist/chunk-7LEKQI47.js.map +1 -0
- package/dist/chunk-CGOQI7ZL.js +8124 -0
- package/dist/chunk-CGOQI7ZL.js.map +1 -0
- package/dist/chunk-DQCXSPHP.js +33 -0
- package/dist/chunk-DQCXSPHP.js.map +1 -0
- package/dist/chunk-I3FFV63W.js +30 -0
- package/dist/chunk-I3FFV63W.js.map +1 -0
- package/dist/chunk-J3XVFPOV.js +58 -0
- package/dist/chunk-J3XVFPOV.js.map +1 -0
- package/dist/chunk-JCJFFJ42.js +39 -0
- package/dist/chunk-JCJFFJ42.js.map +1 -0
- package/dist/chunk-OKQWPNE3.js +1077 -0
- package/dist/chunk-OKQWPNE3.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/chunk-TC5BBLWO.js +29 -0
- package/dist/chunk-TC5BBLWO.js.map +1 -0
- package/dist/chunk-VD4CKRMT.js +127 -0
- package/dist/chunk-VD4CKRMT.js.map +1 -0
- package/dist/chunk-X6MEYCU7.js +1401 -0
- package/dist/chunk-X6MEYCU7.js.map +1 -0
- package/dist/client/index.js +24 -1052
- package/dist/client/index.js.map +1 -1
- package/dist/react/api/licenses.js +11 -1470
- package/dist/react/api/licenses.js.map +1 -1
- package/dist/react/api/vibe-coding.js +25 -1481
- package/dist/react/api/vibe-coding.js.map +1 -1
- package/dist/react/cards/register.js +45 -138
- package/dist/react/cards/register.js.map +1 -1
- package/dist/react/components/chat/index.d.ts +7 -21
- package/dist/react/components/chat/index.js +28 -11366
- package/dist/react/components/chat/index.js.map +1 -1
- package/dist/react/components/plan/index.js +135 -3054
- package/dist/react/components/plan/index.js.map +1 -1
- package/dist/react/components/session/index.js +21 -1499
- package/dist/react/components/session/index.js.map +1 -1
- package/dist/react/components/workspace/index.js +116 -1715
- package/dist/react/components/workspace/index.js.map +1 -1
- package/dist/react/devtools/bridge-devtools/index.js +8 -51
- package/dist/react/devtools/bridge-devtools/index.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +625 -14035
- package/dist/react/index.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,7 +17,11 @@ SDK 通过两个子包暴露能力:
|
|
|
17
17
|
pnpm install
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
第三方项目可安装发布包,并按需要选择子包入口:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @blade-hq/agent-kit @tanstack/react-query react react-dom sonner
|
|
24
|
+
```
|
|
21
25
|
|
|
22
26
|
```ts
|
|
23
27
|
import { BladeClient } from "@blade-hq/agent-kit/client"
|
|
@@ -27,6 +31,40 @@ import "@blade-hq/agent-kit/style.css"
|
|
|
27
31
|
|
|
28
32
|
如果使用 `@blade-hq/agent-kit/chat`、`@blade-hq/agent-kit/session` 等预制 React UI,应用入口必须导入 `@blade-hq/agent-kit/style.css`。只使用 `/client` 或 hooks 自行渲染 UI 时不需要导入这份样式。
|
|
29
33
|
|
|
34
|
+
## ChatView 自定义渲染
|
|
35
|
+
|
|
36
|
+
`ChatView` 默认负责会话数据、Socket.IO 流式更新、历史加载、输入框、技能状态和滚动行为。第三方应用可以只改样式,也可以替换局部渲染。
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import { ChatView, type ToolRendererProps } from "@blade-hq/agent-kit/chat"
|
|
40
|
+
|
|
41
|
+
function BashTool({ toolCall }: ToolRendererProps) {
|
|
42
|
+
return <pre>{toolCall.arguments}</pre>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
<ChatView
|
|
46
|
+
sessionId={sessionId}
|
|
47
|
+
classNames={{
|
|
48
|
+
root: "bg-white text-slate-950",
|
|
49
|
+
messageListContent: "max-w-4xl",
|
|
50
|
+
userMessage: "text-right",
|
|
51
|
+
assistantText: "text-base leading-7",
|
|
52
|
+
chatInputRoot: "border-t",
|
|
53
|
+
}}
|
|
54
|
+
components={{
|
|
55
|
+
EmptyState: () => <div className="py-16 text-center">开始一个新任务</div>,
|
|
56
|
+
SkillStatusBar: ({ sessionId }) => <div>当前会话:{sessionId}</div>,
|
|
57
|
+
}}
|
|
58
|
+
renderers={{
|
|
59
|
+
tool: {
|
|
60
|
+
Bash: BashTool,
|
|
61
|
+
},
|
|
62
|
+
}}
|
|
63
|
+
/>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
如果需要完全自建聊天界面,可以直接使用 `useChat(sessionId)` 和 `skillsApi` / `useSkills()`。技能选择、`@skill` mention、会话技能状态等能力仍由现有 skills API 提供;`ChatView` 的 `components.SkillStatusBar` 可替换默认技能状态条,用来接入宿主自己的 Anthropic-style skills 入口或展示方式。
|
|
67
|
+
|
|
30
68
|
## 认证
|
|
31
69
|
|
|
32
70
|
SDK 支持 cookie 会话和 Bearer Token 两种模式。
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
|
-
import { ReactNode } from 'react';
|
|
4
|
-
import {
|
|
3
|
+
import { ComponentType, ReactNode } from 'react';
|
|
4
|
+
import { C as ChatMessage, A as AskUserAnswerData, T as ToolCallInfo, M as MessageContent } from './AskUserQuestionBlock-CjvG_pUY.js';
|
|
5
5
|
import * as zustand from 'zustand';
|
|
6
6
|
import { M as ModeId, S as SessionInfo, a as SessionStatus } from './session-CDeiO81j.js';
|
|
7
7
|
import { m as BladeClient } from './blade-client-nOsdVlb1.js';
|
|
8
|
+
import { C as ContentBlock } from './projection-DIfyh6RK.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* 把 whatif-rerun 后端组装的 prompt 文本解析成可折叠展示的结构。
|
|
@@ -68,7 +69,102 @@ declare function splitFilesBySize(files: FileList | File[], limitBytes?: number)
|
|
|
68
69
|
rejected: OversizedFileInfo[];
|
|
69
70
|
};
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
type UserChatMessage = ChatMessage & {
|
|
73
|
+
role: "user";
|
|
74
|
+
};
|
|
75
|
+
type ErrorChatMessage = ChatMessage & {
|
|
76
|
+
role: "error";
|
|
77
|
+
};
|
|
78
|
+
declare function isUserMessage(message: ChatMessage): message is UserChatMessage;
|
|
79
|
+
declare function isErrorMessage(message: ChatMessage): message is ErrorChatMessage;
|
|
80
|
+
interface UserMessageProps {
|
|
81
|
+
message: UserChatMessage;
|
|
82
|
+
className?: string;
|
|
83
|
+
}
|
|
84
|
+
declare function UserMessageBubble({ message, className }: UserMessageProps): react_jsx_runtime.JSX.Element;
|
|
85
|
+
declare function ErrorMessageBlock({ message, className, }: {
|
|
86
|
+
message: ErrorChatMessage;
|
|
87
|
+
className?: string;
|
|
88
|
+
}): react_jsx_runtime.JSX.Element;
|
|
89
|
+
|
|
90
|
+
type ChatViewClassNames = Partial<{
|
|
91
|
+
root: string;
|
|
92
|
+
viewerBanner: string;
|
|
93
|
+
messageListRoot: string;
|
|
94
|
+
messageListContent: string;
|
|
95
|
+
messageListInner: string;
|
|
96
|
+
emptyState: string;
|
|
97
|
+
userMessage: string;
|
|
98
|
+
errorMessage: string;
|
|
99
|
+
assistantTurn: string;
|
|
100
|
+
assistantText: string;
|
|
101
|
+
toolCall: string;
|
|
102
|
+
chatInputRoot: string;
|
|
103
|
+
chatInputInner: string;
|
|
104
|
+
skillStatusBarRoot: string;
|
|
105
|
+
skillStatusBarInner: string;
|
|
106
|
+
}>;
|
|
107
|
+
interface ChatViewComponents {
|
|
108
|
+
EmptyState?: ComponentType;
|
|
109
|
+
UserMessage?: ComponentType<{
|
|
110
|
+
message: UserChatMessage;
|
|
111
|
+
className?: string;
|
|
112
|
+
}>;
|
|
113
|
+
ErrorMessage?: ComponentType<{
|
|
114
|
+
message: ErrorChatMessage;
|
|
115
|
+
className?: string;
|
|
116
|
+
}>;
|
|
117
|
+
AssistantTurn?: ComponentType<AssistantTurnComponentProps>;
|
|
118
|
+
ToolCall?: ComponentType<ToolCallComponentProps>;
|
|
119
|
+
SkillStatusBar?: ComponentType<SkillStatusBarComponentProps>;
|
|
120
|
+
}
|
|
121
|
+
interface ChatViewRenderers {
|
|
122
|
+
tool?: Record<string, ComponentType<ToolRendererProps>>;
|
|
123
|
+
}
|
|
124
|
+
interface ChatViewCustomization {
|
|
125
|
+
classNames?: ChatViewClassNames;
|
|
126
|
+
components?: ChatViewComponents;
|
|
127
|
+
renderers?: ChatViewRenderers;
|
|
128
|
+
}
|
|
129
|
+
interface AssistantTurnComponentProps {
|
|
130
|
+
turnKey: string;
|
|
131
|
+
sessionId: string;
|
|
132
|
+
messages: ChatMessage[];
|
|
133
|
+
isStreaming?: boolean;
|
|
134
|
+
isLastTurn?: boolean;
|
|
135
|
+
askAnswers?: Record<string, AskUserAnswerData>;
|
|
136
|
+
onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void;
|
|
137
|
+
sessionStatus?: string;
|
|
138
|
+
level?: 1 | 2;
|
|
139
|
+
forceExpanded?: boolean;
|
|
140
|
+
customization?: ChatViewCustomization;
|
|
141
|
+
}
|
|
142
|
+
interface ToolCallComponentProps {
|
|
143
|
+
toolCall: ToolCallInfo;
|
|
144
|
+
onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void;
|
|
145
|
+
answered?: boolean;
|
|
146
|
+
answerData?: AskUserAnswerData;
|
|
147
|
+
sessionId?: string;
|
|
148
|
+
sessionStatus?: string;
|
|
149
|
+
level?: 1 | 2;
|
|
150
|
+
turnBlocks?: ContentBlock[];
|
|
151
|
+
reasoning?: string;
|
|
152
|
+
customization?: ChatViewCustomization;
|
|
153
|
+
}
|
|
154
|
+
interface ToolRendererProps {
|
|
155
|
+
toolCall: ToolCallInfo;
|
|
156
|
+
sessionId?: string;
|
|
157
|
+
}
|
|
158
|
+
interface SkillStatusBarComponentProps {
|
|
159
|
+
sessionId: string;
|
|
160
|
+
onResync?: () => void;
|
|
161
|
+
isResyncing?: boolean;
|
|
162
|
+
vertical?: boolean;
|
|
163
|
+
className?: string;
|
|
164
|
+
innerClassName?: string;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
interface ChatViewProps extends ChatViewCustomization {
|
|
72
168
|
sessionId: string;
|
|
73
169
|
renderAttachments?: () => ReactNode;
|
|
74
170
|
onBeforeSend?: (content: MessageContent) => MessageContent;
|
|
@@ -77,7 +173,7 @@ interface ChatViewProps {
|
|
|
77
173
|
onResyncSkills?: () => void;
|
|
78
174
|
isResyncingSkills?: boolean;
|
|
79
175
|
}
|
|
80
|
-
declare function ChatView({ sessionId, renderAttachments, onBeforeSend, onCommand, canShareSession, onResyncSkills, isResyncingSkills, }: ChatViewProps): react_jsx_runtime.JSX.Element;
|
|
176
|
+
declare function ChatView({ sessionId, renderAttachments, onBeforeSend, onCommand, canShareSession, onResyncSkills, isResyncingSkills, classNames, components, renderers, }: ChatViewProps): react_jsx_runtime.JSX.Element;
|
|
81
177
|
|
|
82
178
|
type SessionMode = ModeId;
|
|
83
179
|
interface SessionState extends ClientAwareState {
|
|
@@ -160,6 +256,11 @@ interface Props$2 {
|
|
|
160
256
|
};
|
|
161
257
|
/** Tailwind class for the inner max-width wrapper. Defaults to `max-w-3xl`. */
|
|
162
258
|
maxWidthClassName?: string;
|
|
259
|
+
className?: string;
|
|
260
|
+
innerClassName?: string;
|
|
261
|
+
SkillStatusBarComponent?: ComponentType<SkillStatusBarComponentProps>;
|
|
262
|
+
skillStatusBarClassName?: string;
|
|
263
|
+
skillStatusBarInnerClassName?: string;
|
|
163
264
|
onResyncSkills?: () => void;
|
|
164
265
|
isResyncingSkills?: boolean;
|
|
165
266
|
}
|
|
@@ -174,7 +275,7 @@ type FileComposerAttachment = {
|
|
|
174
275
|
uploadedPath?: string;
|
|
175
276
|
textContent?: string | null;
|
|
176
277
|
};
|
|
177
|
-
declare function ChatInput({ onSend, onStop, isStreaming, mode, onToggleMode, renderAttachments, onBeforeSend, ensureSession, onCommand, canShareSession, slotAboveTextarea, externalDraft, externalAttachments, maxWidthClassName, onResyncSkills, isResyncingSkills, }: Props$2): react_jsx_runtime.JSX.Element;
|
|
278
|
+
declare function ChatInput({ onSend, onStop, isStreaming, mode, onToggleMode, renderAttachments, onBeforeSend, ensureSession, onCommand, canShareSession, slotAboveTextarea, externalDraft, externalAttachments, maxWidthClassName, className, innerClassName, SkillStatusBarComponent, skillStatusBarClassName, skillStatusBarInnerClassName, onResyncSkills, isResyncingSkills, }: Props$2): react_jsx_runtime.JSX.Element;
|
|
178
279
|
|
|
179
280
|
interface Props$1 {
|
|
180
281
|
open: boolean;
|
|
@@ -190,14 +291,17 @@ interface Props {
|
|
|
190
291
|
onAnswer?: (answer: string, toolCallId: string, answerData: AskUserAnswerData) => void;
|
|
191
292
|
sessionStatus?: string;
|
|
192
293
|
onConfirmPlan?: (action: "execute" | "revise", text?: string) => void;
|
|
294
|
+
customization?: ChatViewCustomization;
|
|
193
295
|
}
|
|
194
|
-
declare function MessageList({ sessionId, messages: rawMessages, onAnswer, sessionStatus, onConfirmPlan, }: Props): react_jsx_runtime.JSX.Element;
|
|
296
|
+
declare function MessageList({ sessionId, messages: rawMessages, onAnswer, sessionStatus, onConfirmPlan, customization, }: Props): react_jsx_runtime.JSX.Element;
|
|
195
297
|
|
|
196
|
-
declare function SkillStatusBar({ sessionId, onResync, isResyncing, vertical, }: {
|
|
298
|
+
declare function SkillStatusBar({ sessionId, onResync, isResyncing, vertical, className, innerClassName, }: {
|
|
197
299
|
sessionId: string;
|
|
198
300
|
onResync?: () => void;
|
|
199
301
|
isResyncing?: boolean;
|
|
200
302
|
vertical?: boolean;
|
|
303
|
+
className?: string;
|
|
304
|
+
innerClassName?: string;
|
|
201
305
|
}): react_jsx_runtime.JSX.Element;
|
|
202
306
|
|
|
203
|
-
export {
|
|
307
|
+
export { type AssistantTurnComponentProps as A, type BuildWhatIfPromptInput as B, type ChatViewCustomization as C, ErrorMessageBlock as E, type FileComposerAttachment as F, MessageList as M, type OversizedFileInfo as O, type ParsedWhatIfPrompt as P, SkillStatusBar as S, type ToolCallComponentProps as T, UserMessageBubble as U, type WhatIfQuote as W, ChatInput as a, ChatView as b, type ChatViewClassNames as c, type ChatViewComponents as d, type ChatViewProps as e, type ChatViewRenderers as f, FileSizeLimitDialog as g, type SkillStatusBarComponentProps as h, type ToolRendererProps as i, isErrorMessage as j, isUserMessage as k, type ClientAwareState as l, ATTACHMENT_SIZE_LIMIT_BYTES as m, buildWhatIfPrompt as n, formatFileSize as o, invalidateHomeSidebarSessions as p, parseWhatIfPrompt as q, splitFilesBySize as s, useSessionStore as u };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// src/react/lib/card-registry.ts
|
|
2
|
+
var CardComponentRegistry = class {
|
|
3
|
+
components;
|
|
4
|
+
constructor(initial) {
|
|
5
|
+
if (initial instanceof Map) {
|
|
6
|
+
this.components = new Map(initial);
|
|
7
|
+
} else if (initial) {
|
|
8
|
+
this.components = new Map(Object.entries(initial));
|
|
9
|
+
} else {
|
|
10
|
+
this.components = /* @__PURE__ */ new Map();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
register(type, component) {
|
|
14
|
+
this.components.set(type, component);
|
|
15
|
+
}
|
|
16
|
+
get(type) {
|
|
17
|
+
return this.components.get(type);
|
|
18
|
+
}
|
|
19
|
+
has(type) {
|
|
20
|
+
return this.components.has(type);
|
|
21
|
+
}
|
|
22
|
+
keys() {
|
|
23
|
+
return Array.from(this.components.keys());
|
|
24
|
+
}
|
|
25
|
+
clear() {
|
|
26
|
+
this.components.clear();
|
|
27
|
+
}
|
|
28
|
+
get size() {
|
|
29
|
+
return this.components.size;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var cardRegistry = new CardComponentRegistry();
|
|
33
|
+
var CardJSON = {
|
|
34
|
+
safeParseJSON(text) {
|
|
35
|
+
try {
|
|
36
|
+
const value = JSON.parse(text);
|
|
37
|
+
return { ok: true, value };
|
|
38
|
+
} catch (error) {
|
|
39
|
+
return {
|
|
40
|
+
ok: false,
|
|
41
|
+
error: error instanceof Error ? error.message : "Unknown parsing error"
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
toCardArray(value) {
|
|
46
|
+
if (value && typeof value === "object" && "type" in value && typeof value.type === "string") {
|
|
47
|
+
return [value];
|
|
48
|
+
}
|
|
49
|
+
if (Array.isArray(value)) {
|
|
50
|
+
const cards = value.filter(
|
|
51
|
+
(item) => item && typeof item === "object" && "type" in item && typeof item.type === "string"
|
|
52
|
+
);
|
|
53
|
+
return cards.length > 0 ? cards : null;
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
},
|
|
57
|
+
isCardsLanguage(lang) {
|
|
58
|
+
return lang === "card+json";
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export {
|
|
63
|
+
cardRegistry,
|
|
64
|
+
CardJSON
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=chunk-2UP7MG3J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/lib/card-registry.ts"],"sourcesContent":["import type { ComponentType } from \"react\"\n\nexport interface Card {\n type: string\n title?: string\n payload?: Record<string, unknown>\n data?: unknown\n id?: string\n}\n\nexport interface CardComponentProps {\n card: Card\n sendMessage?: (content: string) => Promise<void>\n sessionId?: string\n}\n\nexport type CardComponent = ComponentType<CardComponentProps>\n\nexport class CardComponentRegistry {\n private readonly components: Map<string, CardComponent>\n\n constructor(initial?: Record<string, CardComponent> | Map<string, CardComponent>) {\n if (initial instanceof Map) {\n this.components = new Map(initial)\n } else if (initial) {\n this.components = new Map(Object.entries(initial))\n } else {\n this.components = new Map()\n }\n }\n\n register(type: string, component: CardComponent): void {\n this.components.set(type, component)\n }\n\n get(type: string): CardComponent | undefined {\n return this.components.get(type)\n }\n\n has(type: string): boolean {\n return this.components.has(type)\n }\n\n keys(): string[] {\n return Array.from(this.components.keys())\n }\n\n clear(): void {\n this.components.clear()\n }\n\n get size(): number {\n return this.components.size\n }\n}\n\nexport const cardRegistry = new CardComponentRegistry()\n\nexport interface ParseResult<T> {\n ok: boolean\n value?: T\n error?: string\n}\n\nexport const CardJSON = {\n safeParseJSON<T = unknown>(text: string): ParseResult<T> {\n try {\n const value = JSON.parse(text) as T\n return { ok: true, value }\n } catch (error) {\n return {\n ok: false,\n error: error instanceof Error ? error.message : \"Unknown parsing error\",\n }\n }\n },\n\n toCardArray(value: unknown): Card[] | null {\n if (\n value &&\n typeof value === \"object\" &&\n \"type\" in (value as Record<string, unknown>) &&\n typeof (value as { type?: unknown }).type === \"string\"\n ) {\n return [value as Card]\n }\n\n if (Array.isArray(value)) {\n const cards = value.filter(\n (item): item is Card =>\n item &&\n typeof item === \"object\" &&\n \"type\" in (item as Record<string, unknown>) &&\n typeof (item as { type?: unknown }).type === \"string\",\n )\n return cards.length > 0 ? cards : null\n }\n\n return null\n },\n\n isCardsLanguage(lang?: string): boolean {\n return lang === \"card+json\"\n },\n}\n"],"mappings":";AAkBO,IAAM,wBAAN,MAA4B;AAAA,EAChB;AAAA,EAEjB,YAAY,SAAsE;AAChF,QAAI,mBAAmB,KAAK;AAC1B,WAAK,aAAa,IAAI,IAAI,OAAO;AAAA,IACnC,WAAW,SAAS;AAClB,WAAK,aAAa,IAAI,IAAI,OAAO,QAAQ,OAAO,CAAC;AAAA,IACnD,OAAO;AACL,WAAK,aAAa,oBAAI,IAAI;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,SAAS,MAAc,WAAgC;AACrD,SAAK,WAAW,IAAI,MAAM,SAAS;AAAA,EACrC;AAAA,EAEA,IAAI,MAAyC;AAC3C,WAAO,KAAK,WAAW,IAAI,IAAI;AAAA,EACjC;AAAA,EAEA,IAAI,MAAuB;AACzB,WAAO,KAAK,WAAW,IAAI,IAAI;AAAA,EACjC;AAAA,EAEA,OAAiB;AACf,WAAO,MAAM,KAAK,KAAK,WAAW,KAAK,CAAC;AAAA,EAC1C;AAAA,EAEA,QAAc;AACZ,SAAK,WAAW,MAAM;AAAA,EACxB;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,WAAW;AAAA,EACzB;AACF;AAEO,IAAM,eAAe,IAAI,sBAAsB;AAQ/C,IAAM,WAAW;AAAA,EACtB,cAA2B,MAA8B;AACvD,QAAI;AACF,YAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,aAAO,EAAE,IAAI,MAAM,MAAM;AAAA,IAC3B,SAAS,OAAO;AACd,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY,OAA+B;AACzC,QACE,SACA,OAAO,UAAU,YACjB,UAAW,SACX,OAAQ,MAA6B,SAAS,UAC9C;AACA,aAAO,CAAC,KAAa;AAAA,IACvB;AAEA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,YAAM,QAAQ,MAAM;AAAA,QAClB,CAAC,SACC,QACA,OAAO,SAAS,YAChB,UAAW,QACX,OAAQ,KAA4B,SAAS;AAAA,MACjD;AACA,aAAO,MAAM,SAAS,IAAI,QAAQ;AAAA,IACpC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB,MAAwB;AACtC,WAAO,SAAS;AAAA,EAClB;AACF;","names":[]}
|