@v0-sdk/react 0.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.
@@ -0,0 +1,341 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React$1 from 'react';
3
+
4
+ /**
5
+ * Binary format for message content as returned by the v0 Platform API
6
+ * Each row is a tuple where the first element is the type and the rest are data
7
+ */
8
+ type MessageBinaryFormat = [number, ...any[]][];
9
+ /**
10
+ * Individual row in the message binary format
11
+ */
12
+ type MessageBinaryFormatRow = MessageBinaryFormat[number];
13
+ /**
14
+ * Props for the Message component
15
+ */
16
+ interface MessageProps {
17
+ /**
18
+ * The parsed content from the v0 Platform API
19
+ * This should be the JSON.parsed value of the 'content' field from API responses
20
+ */
21
+ content: MessageBinaryFormat;
22
+ /**
23
+ * Optional message ID for tracking purposes
24
+ */
25
+ messageId?: string;
26
+ /**
27
+ * Role of the message sender
28
+ */
29
+ role?: 'user' | 'assistant' | 'system' | 'tool';
30
+ /**
31
+ * Whether the message is currently being streamed
32
+ */
33
+ streaming?: boolean;
34
+ /**
35
+ * Whether this is the last message in the conversation
36
+ */
37
+ isLastMessage?: boolean;
38
+ /**
39
+ * Custom className for styling the root container
40
+ */
41
+ className?: string;
42
+ /**
43
+ * Custom component renderers (react-markdown style)
44
+ * Override specific components by name
45
+ * Can be either a React component or an object with className for simple styling
46
+ */
47
+ components?: {
48
+ CodeBlock?: React.ComponentType<{
49
+ language: string;
50
+ code: string;
51
+ className?: string;
52
+ }>;
53
+ MathPart?: React.ComponentType<{
54
+ content: string;
55
+ inline?: boolean;
56
+ className?: string;
57
+ }>;
58
+ CodeProjectPart?: React.ComponentType<{
59
+ title?: string;
60
+ filename?: string;
61
+ code?: string;
62
+ language?: string;
63
+ collapsed?: boolean;
64
+ className?: string;
65
+ }>;
66
+ ThinkingSection?: React.ComponentType<{
67
+ title?: string;
68
+ duration?: number;
69
+ thought?: string;
70
+ collapsed?: boolean;
71
+ onCollapse?: () => void;
72
+ className?: string;
73
+ children?: React.ReactNode;
74
+ brainIcon?: React.ReactNode;
75
+ chevronRightIcon?: React.ReactNode;
76
+ chevronDownIcon?: React.ReactNode;
77
+ }>;
78
+ TaskSection?: React.ComponentType<{
79
+ title?: string;
80
+ type?: string;
81
+ parts?: any[];
82
+ collapsed?: boolean;
83
+ onCollapse?: () => void;
84
+ className?: string;
85
+ children?: React.ReactNode;
86
+ taskIcon?: React.ReactNode;
87
+ chevronRightIcon?: React.ReactNode;
88
+ chevronDownIcon?: React.ReactNode;
89
+ }>;
90
+ Icon?: React.ComponentType<{
91
+ name: 'chevron-right' | 'chevron-down' | 'search' | 'folder' | 'settings' | 'file-text' | 'brain' | 'wrench';
92
+ className?: string;
93
+ }>;
94
+ p?: React.ComponentType<React.HTMLAttributes<HTMLParagraphElement>> | {
95
+ className?: string;
96
+ };
97
+ h1?: React.ComponentType<React.HTMLAttributes<HTMLHeadingElement>> | {
98
+ className?: string;
99
+ };
100
+ h2?: React.ComponentType<React.HTMLAttributes<HTMLHeadingElement>> | {
101
+ className?: string;
102
+ };
103
+ h3?: React.ComponentType<React.HTMLAttributes<HTMLHeadingElement>> | {
104
+ className?: string;
105
+ };
106
+ h4?: React.ComponentType<React.HTMLAttributes<HTMLHeadingElement>> | {
107
+ className?: string;
108
+ };
109
+ h5?: React.ComponentType<React.HTMLAttributes<HTMLHeadingElement>> | {
110
+ className?: string;
111
+ };
112
+ h6?: React.ComponentType<React.HTMLAttributes<HTMLHeadingElement>> | {
113
+ className?: string;
114
+ };
115
+ ul?: React.ComponentType<React.HTMLAttributes<HTMLUListElement>> | {
116
+ className?: string;
117
+ };
118
+ ol?: React.ComponentType<React.HTMLAttributes<HTMLOListElement>> | {
119
+ className?: string;
120
+ };
121
+ li?: React.ComponentType<React.HTMLAttributes<HTMLLIElement>> | {
122
+ className?: string;
123
+ };
124
+ blockquote?: React.ComponentType<React.HTMLAttributes<HTMLQuoteElement>> | {
125
+ className?: string;
126
+ };
127
+ code?: React.ComponentType<React.HTMLAttributes<HTMLElement>> | {
128
+ className?: string;
129
+ };
130
+ pre?: React.ComponentType<React.HTMLAttributes<HTMLPreElement>> | {
131
+ className?: string;
132
+ };
133
+ strong?: React.ComponentType<React.HTMLAttributes<HTMLElement>> | {
134
+ className?: string;
135
+ };
136
+ em?: React.ComponentType<React.HTMLAttributes<HTMLElement>> | {
137
+ className?: string;
138
+ };
139
+ a?: React.ComponentType<React.AnchorHTMLAttributes<HTMLAnchorElement>> | {
140
+ className?: string;
141
+ };
142
+ hr?: React.ComponentType<React.HTMLAttributes<HTMLHRElement>> | {
143
+ className?: string;
144
+ };
145
+ div?: React.ComponentType<React.HTMLAttributes<HTMLDivElement>> | {
146
+ className?: string;
147
+ };
148
+ span?: React.ComponentType<React.HTMLAttributes<HTMLSpanElement>> | {
149
+ className?: string;
150
+ };
151
+ };
152
+ /**
153
+ * @deprecated Use `components` instead. Will be removed in next major version.
154
+ */
155
+ renderers?: {
156
+ CodeBlock?: React.ComponentType<{
157
+ language: string;
158
+ code: string;
159
+ className?: string;
160
+ }>;
161
+ MathRenderer?: React.ComponentType<{
162
+ content: string;
163
+ inline?: boolean;
164
+ className?: string;
165
+ }>;
166
+ MathPart?: React.ComponentType<{
167
+ content: string;
168
+ inline?: boolean;
169
+ className?: string;
170
+ }>;
171
+ Icon?: React.ComponentType<{
172
+ name: 'chevron-right' | 'chevron-down' | 'search' | 'folder' | 'settings' | 'file-text' | 'brain' | 'wrench';
173
+ className?: string;
174
+ }>;
175
+ };
176
+ }
177
+ type MessageRendererProps = MessageProps;
178
+ type V0MessageRendererProps = MessageProps;
179
+
180
+ /**
181
+ * Core renderer component for v0 Platform API message content
182
+ */
183
+ declare function MessageImpl({ content, messageId, role: _role, streaming: _streaming, isLastMessage: _isLastMessage, className, components, renderers, }: MessageProps): react_jsx_runtime.JSX.Element;
184
+ /**
185
+ * Main component for rendering v0 Platform API message content
186
+ *
187
+ * @example
188
+ * ```tsx
189
+ * import { Message } from '@v0-sdk/react'
190
+ *
191
+ * function MyComponent({ apiResponse }) {
192
+ * const content = JSON.parse(apiResponse.content)
193
+ *
194
+ * return (
195
+ * <Message
196
+ * content={content}
197
+ * messageId={apiResponse.id}
198
+ * role={apiResponse.role}
199
+ * className="space-y-4"
200
+ * components={{
201
+ * p: ({ children, ...props }) => <p className="mb-4" {...props}>{children}</p>,
202
+ * h1: ({ children, ...props }) => <h1 className="mb-4 text-2xl font-bold" {...props}>{children}</h1>,
203
+ * CodeBlock: MyCustomCodeBlock,
204
+ * MathPart: MyCustomMathRenderer,
205
+ * }}
206
+ * />
207
+ * )
208
+ * }
209
+ * ```
210
+ */
211
+ declare const Message: React$1.MemoExoticComponent<typeof MessageImpl>;
212
+
213
+ interface IconProps {
214
+ name: 'chevron-right' | 'chevron-down' | 'search' | 'folder' | 'settings' | 'file-text' | 'brain' | 'wrench';
215
+ className?: string;
216
+ }
217
+ /**
218
+ * Generic icon component that can be customized by consumers.
219
+ * By default, renders a simple fallback. Consumers should provide
220
+ * their own icon implementation via context or props.
221
+ */
222
+ declare function Icon(props: IconProps): react_jsx_runtime.JSX.Element;
223
+
224
+ interface ThinkingSectionProps {
225
+ title?: string;
226
+ duration?: number;
227
+ thought?: string;
228
+ collapsed?: boolean;
229
+ onCollapse?: () => void;
230
+ className?: string;
231
+ children?: React$1.ReactNode;
232
+ iconRenderer?: React$1.ComponentType<IconProps>;
233
+ brainIcon?: React$1.ReactNode;
234
+ chevronRightIcon?: React$1.ReactNode;
235
+ chevronDownIcon?: React$1.ReactNode;
236
+ }
237
+ /**
238
+ * Generic thinking section component
239
+ * Renders a collapsible section with basic structure - consumers provide styling
240
+ */
241
+ declare function ThinkingSection({ title, duration, thought, collapsed: initialCollapsed, onCollapse, className, children, iconRenderer, brainIcon, chevronRightIcon, chevronDownIcon, }: ThinkingSectionProps): react_jsx_runtime.JSX.Element;
242
+
243
+ interface TaskSectionProps {
244
+ title?: string;
245
+ type?: string;
246
+ parts?: any[];
247
+ collapsed?: boolean;
248
+ onCollapse?: () => void;
249
+ className?: string;
250
+ children?: React$1.ReactNode;
251
+ iconRenderer?: React$1.ComponentType<IconProps>;
252
+ taskIcon?: React$1.ReactNode;
253
+ chevronRightIcon?: React$1.ReactNode;
254
+ chevronDownIcon?: React$1.ReactNode;
255
+ }
256
+ /**
257
+ * Generic task section component
258
+ * Renders a collapsible task section with basic structure - consumers provide styling
259
+ */
260
+ declare function TaskSection({ title, type, parts, collapsed: initialCollapsed, onCollapse, className, children, iconRenderer, taskIcon, chevronRightIcon, chevronDownIcon, }: TaskSectionProps): react_jsx_runtime.JSX.Element;
261
+
262
+ interface CodeProjectPartProps {
263
+ title?: string;
264
+ filename?: string;
265
+ code?: string;
266
+ language?: string;
267
+ collapsed?: boolean;
268
+ className?: string;
269
+ children?: React$1.ReactNode;
270
+ iconRenderer?: React$1.ComponentType<IconProps>;
271
+ }
272
+ /**
273
+ * Generic code project block component
274
+ * Renders a collapsible code project with basic structure - consumers provide styling
275
+ */
276
+ declare function CodeProjectPart({ title, filename, code, language, collapsed: initialCollapsed, className, children, iconRenderer, }: CodeProjectPartProps): react_jsx_runtime.JSX.Element;
277
+
278
+ interface ContentPartRendererProps {
279
+ part: any;
280
+ iconRenderer?: React$1.ComponentType<IconProps>;
281
+ thinkingSectionRenderer?: React$1.ComponentType<{
282
+ title?: string;
283
+ duration?: number;
284
+ thought?: string;
285
+ collapsed?: boolean;
286
+ className?: string;
287
+ children?: React$1.ReactNode;
288
+ brainIcon?: React$1.ReactNode;
289
+ chevronRightIcon?: React$1.ReactNode;
290
+ chevronDownIcon?: React$1.ReactNode;
291
+ }>;
292
+ taskSectionRenderer?: React$1.ComponentType<{
293
+ title?: string;
294
+ type?: string;
295
+ parts?: any[];
296
+ collapsed?: boolean;
297
+ className?: string;
298
+ children?: React$1.ReactNode;
299
+ taskIcon?: React$1.ReactNode;
300
+ chevronRightIcon?: React$1.ReactNode;
301
+ chevronDownIcon?: React$1.ReactNode;
302
+ }>;
303
+ brainIcon?: React$1.ReactNode;
304
+ chevronRightIcon?: React$1.ReactNode;
305
+ chevronDownIcon?: React$1.ReactNode;
306
+ searchIcon?: React$1.ReactNode;
307
+ folderIcon?: React$1.ReactNode;
308
+ settingsIcon?: React$1.ReactNode;
309
+ wrenchIcon?: React$1.ReactNode;
310
+ }
311
+ declare function ContentPartRenderer({ part, iconRenderer, thinkingSectionRenderer, taskSectionRenderer, brainIcon, chevronRightIcon, chevronDownIcon, searchIcon, folderIcon, settingsIcon, wrenchIcon, }: ContentPartRendererProps): react_jsx_runtime.JSX.Element;
312
+
313
+ interface MathPartProps {
314
+ content: string;
315
+ inline?: boolean;
316
+ className?: string;
317
+ children?: React$1.ReactNode;
318
+ displayMode?: boolean;
319
+ }
320
+ /**
321
+ * Generic math renderer component
322
+ * Renders plain math content by default - consumers should provide their own math rendering
323
+ */
324
+ declare function MathPart({ content, inline, className, children, }: MathPartProps): react_jsx_runtime.JSX.Element;
325
+
326
+ interface CodeBlockProps {
327
+ language: string;
328
+ code: string;
329
+ className?: string;
330
+ children?: React$1.ReactNode;
331
+ filename?: string;
332
+ }
333
+ /**
334
+ * Generic code block component
335
+ * Renders plain code by default - consumers should provide their own styling and highlighting
336
+ */
337
+ declare function CodeBlock({ language, code, className, children, }: CodeBlockProps): react_jsx_runtime.JSX.Element;
338
+
339
+ export { ContentPartRenderer as AssistantMessageContentPart, CodeBlock, CodeProjectPart as CodeProjectBlock, CodeProjectPart, ContentPartRenderer, Icon, MathPart, MathPart as MathRenderer, Message, Message as MessageContent, Message as MessageRenderer, TaskSection, ThinkingSection, Message as V0MessageRenderer };
340
+ export type { CodeBlockProps, CodeProjectPartProps as CodeProjectBlockProps, CodeProjectPartProps, ContentPartRendererProps, IconProps, MathPartProps, MathPartProps as MathRendererProps, MessageBinaryFormat, MessageBinaryFormatRow, MessageProps, MessageRendererProps, TaskSectionProps, ThinkingSectionProps, V0MessageRendererProps };
341
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sources":["../src/types.ts","../src/components/message.tsx","../src/components/icon.tsx","../src/components/thinking-section.tsx","../src/components/task-section.tsx","../src/components/code-project-part.tsx","../src/components/content-part-renderer.tsx","../src/components/math-part.tsx","../src/components/code-block.tsx"],"sourcesContent":["/**\n * Binary format for message content as returned by the v0 Platform API\n * Each row is a tuple where the first element is the type and the rest are data\n */\nexport type MessageBinaryFormat = [number, ...any[]][]\n\n/**\n * Individual row in the message binary format\n */\nexport type MessageBinaryFormatRow = MessageBinaryFormat[number]\n\n/**\n * Props for the Message component\n */\nexport interface MessageProps {\n /**\n * The parsed content from the v0 Platform API\n * This should be the JSON.parsed value of the 'content' field from API responses\n */\n content: MessageBinaryFormat\n\n /**\n * Optional message ID for tracking purposes\n */\n messageId?: string\n\n /**\n * Role of the message sender\n */\n role?: 'user' | 'assistant' | 'system' | 'tool'\n\n /**\n * Whether the message is currently being streamed\n */\n streaming?: boolean\n\n /**\n * Whether this is the last message in the conversation\n */\n isLastMessage?: boolean\n\n /**\n * Custom className for styling the root container\n */\n className?: string\n\n /**\n * Custom component renderers (react-markdown style)\n * Override specific components by name\n * Can be either a React component or an object with className for simple styling\n */\n components?: {\n // Content components\n CodeBlock?: React.ComponentType<{\n language: string\n code: string\n className?: string\n }>\n MathPart?: React.ComponentType<{\n content: string\n inline?: boolean\n className?: string\n }>\n CodeProjectPart?: React.ComponentType<{\n title?: string\n filename?: string\n code?: string\n language?: string\n collapsed?: boolean\n className?: string\n }>\n ThinkingSection?: React.ComponentType<{\n title?: string\n duration?: number\n thought?: string\n collapsed?: boolean\n onCollapse?: () => void\n className?: string\n children?: React.ReactNode\n brainIcon?: React.ReactNode\n chevronRightIcon?: React.ReactNode\n chevronDownIcon?: React.ReactNode\n }>\n TaskSection?: React.ComponentType<{\n title?: string\n type?: string\n parts?: any[]\n collapsed?: boolean\n onCollapse?: () => void\n className?: string\n children?: React.ReactNode\n taskIcon?: React.ReactNode\n chevronRightIcon?: React.ReactNode\n chevronDownIcon?: React.ReactNode\n }>\n Icon?: React.ComponentType<{\n name:\n | 'chevron-right'\n | 'chevron-down'\n | 'search'\n | 'folder'\n | 'settings'\n | 'file-text'\n | 'brain'\n | 'wrench'\n className?: string\n }>\n\n // HTML elements (react-markdown style)\n // Can be either a React component or an object with className\n p?:\n | React.ComponentType<React.HTMLAttributes<HTMLParagraphElement>>\n | { className?: string }\n h1?:\n | React.ComponentType<React.HTMLAttributes<HTMLHeadingElement>>\n | { className?: string }\n h2?:\n | React.ComponentType<React.HTMLAttributes<HTMLHeadingElement>>\n | { className?: string }\n h3?:\n | React.ComponentType<React.HTMLAttributes<HTMLHeadingElement>>\n | { className?: string }\n h4?:\n | React.ComponentType<React.HTMLAttributes<HTMLHeadingElement>>\n | { className?: string }\n h5?:\n | React.ComponentType<React.HTMLAttributes<HTMLHeadingElement>>\n | { className?: string }\n h6?:\n | React.ComponentType<React.HTMLAttributes<HTMLHeadingElement>>\n | { className?: string }\n ul?:\n | React.ComponentType<React.HTMLAttributes<HTMLUListElement>>\n | { className?: string }\n ol?:\n | React.ComponentType<React.HTMLAttributes<HTMLOListElement>>\n | { className?: string }\n li?:\n | React.ComponentType<React.HTMLAttributes<HTMLLIElement>>\n | { className?: string }\n blockquote?:\n | React.ComponentType<React.HTMLAttributes<HTMLQuoteElement>>\n | { className?: string }\n code?:\n | React.ComponentType<React.HTMLAttributes<HTMLElement>>\n | { className?: string }\n pre?:\n | React.ComponentType<React.HTMLAttributes<HTMLPreElement>>\n | { className?: string }\n strong?:\n | React.ComponentType<React.HTMLAttributes<HTMLElement>>\n | { className?: string }\n em?:\n | React.ComponentType<React.HTMLAttributes<HTMLElement>>\n | { className?: string }\n a?:\n | React.ComponentType<React.AnchorHTMLAttributes<HTMLAnchorElement>>\n | { className?: string }\n hr?:\n | React.ComponentType<React.HTMLAttributes<HTMLHRElement>>\n | { className?: string }\n div?:\n | React.ComponentType<React.HTMLAttributes<HTMLDivElement>>\n | { className?: string }\n span?:\n | React.ComponentType<React.HTMLAttributes<HTMLSpanElement>>\n | { className?: string }\n }\n\n /**\n * @deprecated Use `components` instead. Will be removed in next major version.\n */\n renderers?: {\n CodeBlock?: React.ComponentType<{\n language: string\n code: string\n className?: string\n }>\n MathRenderer?: React.ComponentType<{\n content: string\n inline?: boolean\n className?: string\n }>\n MathPart?: React.ComponentType<{\n content: string\n inline?: boolean\n className?: string\n }>\n Icon?: React.ComponentType<{\n name:\n | 'chevron-right'\n | 'chevron-down'\n | 'search'\n | 'folder'\n | 'settings'\n | 'file-text'\n | 'brain'\n | 'wrench'\n className?: string\n }>\n }\n}\n\n// Backward compatibility exports\nexport type MessageRendererProps = MessageProps\nexport type V0MessageRendererProps = MessageProps\n// Note: MessageStyles/MessageRendererStyles/V0MessageRendererStyles removed as styles prop is no longer supported\n","import React from 'react'\nimport { MessageProps } from '../types'\nimport { MathPart } from './math-part'\nimport { CodeBlock } from './code-block'\nimport { CodeProjectPart } from './code-project-part'\nimport { ContentPartRenderer } from './content-part-renderer'\nimport { cn } from '../utils/cn'\n\n// Helper function to render HTML elements with component or className config\nfunction renderHtmlElement(\n tagName: string,\n key: string,\n props: any,\n children: any[],\n className: string | undefined,\n componentOrConfig: any,\n components: MessageProps['components'],\n): React.ReactNode {\n if (typeof componentOrConfig === 'function') {\n const Component = componentOrConfig\n return (\n <Component key={key} {...props} className={className}>\n {renderChildren(children, key, components)}\n </Component>\n )\n } else if (componentOrConfig && typeof componentOrConfig === 'object') {\n const mergedClassName = cn(className, componentOrConfig.className)\n return React.createElement(\n tagName,\n { key, ...props, className: mergedClassName },\n renderChildren(children, key, components),\n )\n } else {\n return React.createElement(\n tagName,\n { key, ...props, className },\n renderChildren(children, key, components),\n )\n }\n}\n\n/**\n * Core renderer component for v0 Platform API message content\n */\nfunction MessageImpl({\n content,\n messageId = 'unknown',\n role: _role = 'assistant',\n streaming: _streaming = false,\n isLastMessage: _isLastMessage = false,\n className,\n components,\n renderers, // deprecated\n}: MessageProps) {\n if (!Array.isArray(content)) {\n console.warn(\n 'MessageContent: content must be an array (MessageBinaryFormat)',\n )\n return null\n }\n\n // Merge components and renderers (backward compatibility)\n const mergedComponents = {\n ...components,\n // Map legacy renderers to new component names\n ...(renderers?.CodeBlock && { CodeBlock: renderers.CodeBlock }),\n ...(renderers?.MathRenderer && { MathPart: renderers.MathRenderer }),\n ...(renderers?.MathPart && { MathPart: renderers.MathPart }),\n ...(renderers?.Icon && { Icon: renderers.Icon }),\n }\n\n const elements = content.map(([type, ...data], index) => {\n const key = `${messageId}-${index}`\n\n // Markdown/text content (type 0)\n if (type === 0) {\n const markdownData = data[0]\n if (!Array.isArray(markdownData)) {\n return null\n }\n\n return (\n <div key={key}>\n {markdownData.map((item: any, mdIndex: number) => {\n const mdKey = `${key}-md-${mdIndex}`\n return renderMarkdownElement(item, mdKey, mergedComponents)\n })}\n </div>\n )\n }\n\n // Code block (type 1)\n if (type === 1) {\n const [language, code] = data\n const CodeBlockComponent = mergedComponents?.CodeBlock || CodeBlock\n return (\n <CodeBlockComponent\n key={key}\n language={language || 'text'}\n code={code || ''}\n />\n )\n }\n\n // Math (type 2 for inline, type 3 for block)\n if (type === 2 || type === 3) {\n const mathContent = data[0] || ''\n const MathPartComponent = mergedComponents?.MathPart || MathPart\n return (\n <MathPartComponent\n key={key}\n content={mathContent}\n inline={type === 2}\n />\n )\n }\n\n // Unknown type - render as text for debugging\n return <div key={key}>[Unknown content type: {type}]</div>\n })\n\n return <div className={className}>{elements}</div>\n}\n\nfunction renderMarkdownElement(\n item: any,\n key: string,\n components?: MessageProps['components'],\n): React.ReactNode {\n if (typeof item === 'string') {\n return <span key={key}>{item}</span>\n }\n\n if (Array.isArray(item)) {\n const [tagName, props, ...children] = item\n\n // Handle special v0 Platform API elements\n if (tagName === 'AssistantMessageContentPart') {\n return (\n <ContentPartRenderer\n key={key}\n part={props.part}\n iconRenderer={components?.Icon}\n thinkingSectionRenderer={components?.ThinkingSection}\n taskSectionRenderer={components?.TaskSection}\n />\n )\n }\n\n if (tagName === 'Codeblock') {\n const CustomCodeProjectPart = components?.CodeProjectPart\n const CodeProjectComponent = CustomCodeProjectPart || CodeProjectPart\n return (\n <CodeProjectComponent\n key={key}\n language={props.lang}\n code={children[0]}\n iconRenderer={components?.Icon}\n />\n )\n }\n\n if (tagName === 'text') {\n return <span key={key}>{children[0]}</span>\n }\n\n // Handle standard markdown elements\n const className = props?.className\n\n switch (tagName) {\n case 'p': {\n const componentOrConfig = components?.p\n if (typeof componentOrConfig === 'function') {\n const Component = componentOrConfig\n return (\n <Component key={key} {...props} className={className}>\n {renderChildren(children, key, components)}\n </Component>\n )\n } else if (componentOrConfig && typeof componentOrConfig === 'object') {\n const mergedClassName = cn(className, componentOrConfig.className)\n return (\n <p key={key} {...props} className={mergedClassName}>\n {renderChildren(children, key, components)}\n </p>\n )\n } else {\n return (\n <p key={key} {...props} className={className}>\n {renderChildren(children, key, components)}\n </p>\n )\n }\n }\n case 'h1':\n return renderHtmlElement(\n 'h1',\n key,\n props,\n children,\n className,\n components?.h1,\n components,\n )\n case 'h2':\n return renderHtmlElement(\n 'h2',\n key,\n props,\n children,\n className,\n components?.h2,\n components,\n )\n case 'h3':\n return renderHtmlElement(\n 'h3',\n key,\n props,\n children,\n className,\n components?.h3,\n components,\n )\n case 'h4':\n return renderHtmlElement(\n 'h4',\n key,\n props,\n children,\n className,\n components?.h4,\n components,\n )\n case 'h5':\n return renderHtmlElement(\n 'h5',\n key,\n props,\n children,\n className,\n components?.h5,\n components,\n )\n case 'h6':\n return renderHtmlElement(\n 'h6',\n key,\n props,\n children,\n className,\n components?.h6,\n components,\n )\n case 'ul':\n return renderHtmlElement(\n 'ul',\n key,\n props,\n children,\n className,\n components?.ul,\n components,\n )\n case 'ol':\n return renderHtmlElement(\n 'ol',\n key,\n props,\n children,\n className,\n components?.ol,\n components,\n )\n case 'li':\n return renderHtmlElement(\n 'li',\n key,\n props,\n children,\n className,\n components?.li,\n components,\n )\n case 'blockquote':\n return renderHtmlElement(\n 'blockquote',\n key,\n props,\n children,\n className,\n components?.blockquote,\n components,\n )\n case 'code':\n return renderHtmlElement(\n 'code',\n key,\n props,\n children,\n className,\n components?.code,\n components,\n )\n case 'pre':\n return renderHtmlElement(\n 'pre',\n key,\n props,\n children,\n className,\n components?.pre,\n components,\n )\n case 'strong':\n return renderHtmlElement(\n 'strong',\n key,\n props,\n children,\n className,\n components?.strong,\n components,\n )\n case 'em':\n return renderHtmlElement(\n 'em',\n key,\n props,\n children,\n className,\n components?.em,\n components,\n )\n case 'a': {\n const componentOrConfig = components?.a\n if (typeof componentOrConfig === 'function') {\n const Component = componentOrConfig\n return (\n <Component\n key={key}\n {...props}\n className={className}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {renderChildren(children, key, components)}\n </Component>\n )\n } else if (componentOrConfig && typeof componentOrConfig === 'object') {\n const mergedClassName = cn(className, componentOrConfig.className)\n return (\n <a\n key={key}\n {...props}\n className={mergedClassName}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {renderChildren(children, key, components)}\n </a>\n )\n } else {\n return (\n <a\n key={key}\n {...props}\n className={className}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {renderChildren(children, key, components)}\n </a>\n )\n }\n }\n case 'br':\n return <br key={key} />\n case 'hr': {\n const componentOrConfig = components?.hr\n if (typeof componentOrConfig === 'function') {\n const Component = componentOrConfig\n return <Component key={key} {...props} className={className} />\n } else if (componentOrConfig && typeof componentOrConfig === 'object') {\n const mergedClassName = cn(className, componentOrConfig.className)\n return <hr key={key} {...props} className={mergedClassName} />\n } else {\n return <hr key={key} {...props} className={className} />\n }\n }\n case 'div':\n return renderHtmlElement(\n 'div',\n key,\n props,\n children,\n className,\n components?.div,\n components,\n )\n case 'span':\n return renderHtmlElement(\n 'span',\n key,\n props,\n children,\n className,\n components?.span,\n components,\n )\n default:\n return (\n <span key={key}>{renderChildren(children, key, components)}</span>\n )\n }\n }\n\n return null\n}\n\nfunction renderChildren(\n children: any[],\n parentKey: string,\n components?: MessageProps['components'],\n): React.ReactNode[] {\n return children\n .map((child, index) => {\n const key = `${parentKey}-child-${index}`\n return renderMarkdownElement(child, key, components)\n })\n .filter(Boolean)\n}\n\n/**\n * Main component for rendering v0 Platform API message content\n *\n * @example\n * ```tsx\n * import { Message } from '@v0-sdk/react'\n *\n * function MyComponent({ apiResponse }) {\n * const content = JSON.parse(apiResponse.content)\n *\n * return (\n * <Message\n * content={content}\n * messageId={apiResponse.id}\n * role={apiResponse.role}\n * className=\"space-y-4\"\n * components={{\n * p: ({ children, ...props }) => <p className=\"mb-4\" {...props}>{children}</p>,\n * h1: ({ children, ...props }) => <h1 className=\"mb-4 text-2xl font-bold\" {...props}>{children}</h1>,\n * CodeBlock: MyCustomCodeBlock,\n * MathPart: MyCustomMathRenderer,\n * }}\n * />\n * )\n * }\n * ```\n */\nexport const Message = React.memo(MessageImpl)\n","import React, { createContext, useContext } from 'react'\n\n// Context for providing custom icon implementation\nconst IconContext = createContext<React.ComponentType<IconProps> | null>(null)\n\nexport interface IconProps {\n name:\n | 'chevron-right'\n | 'chevron-down'\n | 'search'\n | 'folder'\n | 'settings'\n | 'file-text'\n | 'brain'\n | 'wrench'\n className?: string\n}\n\n/**\n * Generic icon component that can be customized by consumers.\n * By default, renders a simple fallback. Consumers should provide\n * their own icon implementation via context or props.\n */\nexport function Icon(props: IconProps) {\n const CustomIcon = useContext(IconContext)\n\n // Use custom icon implementation if provided via context\n if (CustomIcon) {\n return <CustomIcon {...props} />\n }\n\n // Fallback implementation - consumers should override this\n return (\n <span\n className={props.className}\n data-icon={props.name}\n suppressHydrationWarning\n aria-label={props.name.replace('-', ' ')}\n >\n {getIconFallback(props.name)}\n </span>\n )\n}\n\n/**\n * Provider for custom icon implementation\n */\nexport function IconProvider({\n children,\n component,\n}: {\n children: React.ReactNode\n component: React.ComponentType<IconProps>\n}) {\n return (\n <IconContext.Provider value={component}>{children}</IconContext.Provider>\n )\n}\n\nfunction getIconFallback(name: string): string {\n const iconMap: Record<string, string> = {\n 'chevron-right': '▶',\n 'chevron-down': '▼',\n search: '🔍',\n folder: '📁',\n settings: '⚙️',\n 'file-text': '📄',\n brain: '🧠',\n wrench: '🔧',\n }\n return iconMap[name] || '•'\n}\n","import React, { useState } from 'react'\nimport { Icon, IconProps } from './icon'\n\nexport interface ThinkingSectionProps {\n title?: string\n duration?: number\n thought?: string\n collapsed?: boolean\n onCollapse?: () => void\n className?: string\n children?: React.ReactNode\n iconRenderer?: React.ComponentType<IconProps>\n brainIcon?: React.ReactNode\n chevronRightIcon?: React.ReactNode\n chevronDownIcon?: React.ReactNode\n}\n\n/**\n * Generic thinking section component\n * Renders a collapsible section with basic structure - consumers provide styling\n */\nexport function ThinkingSection({\n title,\n duration,\n thought,\n collapsed: initialCollapsed = true,\n onCollapse,\n className,\n children,\n iconRenderer,\n brainIcon,\n chevronRightIcon,\n chevronDownIcon,\n}: ThinkingSectionProps) {\n const [internalCollapsed, setInternalCollapsed] = useState(initialCollapsed)\n const collapsed = onCollapse ? initialCollapsed : internalCollapsed\n const handleCollapse =\n onCollapse || (() => setInternalCollapsed(!internalCollapsed))\n\n // If children provided, use that (allows complete customization)\n if (children) {\n return <>{children}</>\n }\n\n return (\n <div className={className} data-component=\"thinking-section\">\n <button onClick={handleCollapse} data-expanded={!collapsed} data-button>\n <div data-icon-container>\n {collapsed ? (\n <>\n {brainIcon ||\n (iconRenderer ? (\n React.createElement(iconRenderer, { name: 'brain' })\n ) : (\n <Icon name=\"brain\" />\n ))}\n {chevronRightIcon ||\n (iconRenderer ? (\n React.createElement(iconRenderer, { name: 'chevron-right' })\n ) : (\n <Icon name=\"chevron-right\" />\n ))}\n </>\n ) : (\n chevronDownIcon ||\n (iconRenderer ? (\n React.createElement(iconRenderer, { name: 'chevron-down' })\n ) : (\n <Icon name=\"chevron-down\" />\n ))\n )}\n </div>\n <span data-title>\n {title || 'Thinking'}\n {duration && ` for ${Math.round(duration)}s`}\n </span>\n </button>\n {!collapsed && thought && (\n <div data-content>\n <div data-thought-container>\n {thought.split('\\n\\n').map((paragraph, index) => (\n <div key={index} data-paragraph>\n {paragraph}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n )\n}\n","import React, { useState } from 'react'\nimport { Icon, IconProps } from './icon'\n\nexport interface TaskSectionProps {\n title?: string\n type?: string\n parts?: any[]\n collapsed?: boolean\n onCollapse?: () => void\n className?: string\n children?: React.ReactNode\n iconRenderer?: React.ComponentType<IconProps>\n taskIcon?: React.ReactNode\n chevronRightIcon?: React.ReactNode\n chevronDownIcon?: React.ReactNode\n}\n\nfunction getTypeIcon(\n type?: string,\n title?: string,\n iconRenderer?: React.ComponentType<IconProps>,\n) {\n // Check title content for specific cases\n if (title?.includes('No issues found')) {\n return iconRenderer ? (\n React.createElement(iconRenderer, { name: 'wrench' })\n ) : (\n <Icon name=\"wrench\" />\n )\n }\n if (title?.includes('Analyzed codebase')) {\n return iconRenderer ? (\n React.createElement(iconRenderer, { name: 'search' })\n ) : (\n <Icon name=\"search\" />\n )\n }\n\n // Fallback to type-based icons\n switch (type) {\n case 'task-search-web-v1':\n return iconRenderer ? (\n React.createElement(iconRenderer, { name: 'search' })\n ) : (\n <Icon name=\"search\" />\n )\n case 'task-search-repo-v1':\n return iconRenderer ? (\n React.createElement(iconRenderer, { name: 'folder' })\n ) : (\n <Icon name=\"folder\" />\n )\n case 'task-diagnostics-v1':\n return iconRenderer ? (\n React.createElement(iconRenderer, { name: 'settings' })\n ) : (\n <Icon name=\"settings\" />\n )\n default:\n return iconRenderer ? (\n React.createElement(iconRenderer, { name: 'wrench' })\n ) : (\n <Icon name=\"wrench\" />\n )\n }\n}\n\nfunction renderTaskPart(\n part: any,\n index: number,\n iconRenderer?: React.ComponentType<IconProps>,\n) {\n if (part.type === 'search-web') {\n if (part.status === 'searching') {\n return <div key={index}>{`Searching \"${part.query}\"`}</div>\n }\n if (part.status === 'analyzing') {\n return <div key={index}>{`Analyzing ${part.count} results...`}</div>\n }\n if (part.status === 'complete' && part.answer) {\n return (\n <div key={index}>\n <p>{part.answer}</p>\n {part.sources && part.sources.length > 0 && (\n <div>\n {part.sources.map((source: any, sourceIndex: number) => (\n <a\n key={sourceIndex}\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {source.title}\n </a>\n ))}\n </div>\n )}\n </div>\n )\n }\n }\n\n if (part.type === 'search-repo') {\n if (part.status === 'searching') {\n return <div key={index}>{`Searching \"${part.query}\"`}</div>\n }\n if (part.status === 'reading' && part.files) {\n return (\n <div key={index}>\n <span>Reading files</span>\n {part.files.map((file: string, fileIndex: number) => (\n <span key={fileIndex}>\n {iconRenderer ? (\n React.createElement(iconRenderer, { name: 'file-text' })\n ) : (\n <Icon name=\"file-text\" />\n )}{' '}\n {file}\n </span>\n ))}\n </div>\n )\n }\n }\n\n if (part.type === 'diagnostics') {\n if (part.status === 'checking') {\n return <div key={index}>Checking for issues...</div>\n }\n if (part.status === 'complete' && part.issues === 0) {\n return <div key={index}>✅ No issues found</div>\n }\n }\n\n return <div key={index}>{JSON.stringify(part)}</div>\n}\n\n/**\n * Generic task section component\n * Renders a collapsible task section with basic structure - consumers provide styling\n */\nexport function TaskSection({\n title,\n type,\n parts = [],\n collapsed: initialCollapsed = true,\n onCollapse,\n className,\n children,\n iconRenderer,\n taskIcon,\n chevronRightIcon,\n chevronDownIcon,\n}: TaskSectionProps) {\n const [internalCollapsed, setInternalCollapsed] = useState(initialCollapsed)\n const collapsed = onCollapse ? initialCollapsed : internalCollapsed\n const handleCollapse =\n onCollapse || (() => setInternalCollapsed(!internalCollapsed))\n\n // If children provided, use that (allows complete customization)\n if (children) {\n return <>{children}</>\n }\n\n // Count meaningful parts (parts that would render something)\n const meaningfulParts = parts.filter((part) => {\n // Check if the part would render meaningful content\n if (part.type === 'search-web') {\n return (\n part.status === 'searching' ||\n part.status === 'analyzing' ||\n (part.status === 'complete' && part.answer)\n )\n }\n if (part.type === 'starting-repo-search' && part.query) return true\n if (part.type === 'select-files' && part.filePaths?.length > 0) return true\n if (part.type === 'starting-web-search' && part.query) return true\n if (part.type === 'got-results' && part.count) return true\n if (part.type === 'finished-web-search' && part.answer) return true\n if (part.type === 'diagnostics-passed') return true\n if (part.type === 'fetching-diagnostics') return true\n // Add more meaningful part types as needed\n return false\n })\n\n // If there's only one meaningful part, show just the content without the collapsible wrapper\n if (meaningfulParts.length === 1) {\n return (\n <div className={className} data-component=\"task-section-inline\">\n <div data-part>\n {renderTaskPart(meaningfulParts[0], 0, iconRenderer)}\n </div>\n </div>\n )\n }\n\n return (\n <div className={className} data-component=\"task-section\">\n <button onClick={handleCollapse} data-expanded={!collapsed} data-button>\n <div data-icon-container>\n <div data-task-icon>\n {taskIcon || getTypeIcon(type, title, iconRenderer)}\n </div>\n {collapsed\n ? chevronRightIcon ||\n (iconRenderer ? (\n React.createElement(iconRenderer, { name: 'chevron-right' })\n ) : (\n <Icon name=\"chevron-right\" />\n ))\n : chevronDownIcon ||\n (iconRenderer ? (\n React.createElement(iconRenderer, { name: 'chevron-down' })\n ) : (\n <Icon name=\"chevron-down\" />\n ))}\n </div>\n <span data-title>{title || 'Task'}</span>\n </button>\n {!collapsed && (\n <div data-content>\n <div data-parts-container>\n {parts.map((part, index) => (\n <div key={index} data-part>\n {renderTaskPart(part, index, iconRenderer)}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n )\n}\n","import React, { useState } from 'react'\nimport { CodeBlock } from './code-block'\nimport { Icon, IconProps } from './icon'\n\nexport interface CodeProjectPartProps {\n title?: string\n filename?: string\n code?: string\n language?: string\n collapsed?: boolean\n className?: string\n children?: React.ReactNode\n iconRenderer?: React.ComponentType<IconProps>\n}\n\n/**\n * Generic code project block component\n * Renders a collapsible code project with basic structure - consumers provide styling\n */\nexport function CodeProjectPart({\n title,\n filename,\n code,\n language = 'typescript',\n collapsed: initialCollapsed = true,\n className,\n children,\n iconRenderer,\n}: CodeProjectPartProps) {\n const [collapsed, setCollapsed] = useState(initialCollapsed)\n\n // If children provided, use that (allows complete customization)\n if (children) {\n return <>{children}</>\n }\n\n return (\n <div className={className} data-component=\"code-project-block\">\n <button\n onClick={() => setCollapsed(!collapsed)}\n data-expanded={!collapsed}\n >\n <div data-header>\n {iconRenderer ? (\n React.createElement(iconRenderer, { name: 'folder' })\n ) : (\n <Icon name=\"folder\" />\n )}\n <span data-title>{title || 'Code Project'}</span>\n </div>\n <span data-version>v1</span>\n </button>\n {!collapsed && (\n <div data-content>\n <div data-file-list>\n <div data-file data-active>\n {iconRenderer ? (\n React.createElement(iconRenderer, { name: 'file-text' })\n ) : (\n <Icon name=\"file-text\" />\n )}\n <span data-filename>{filename}</span>\n <span data-filepath>app/page.tsx</span>\n </div>\n {/* Additional files could be added here */}\n <div data-file>\n {iconRenderer ? (\n React.createElement(iconRenderer, { name: 'file-text' })\n ) : (\n <Icon name=\"file-text\" />\n )}\n <span data-filename>layout.tsx</span>\n <span data-filepath>app/layout.tsx</span>\n </div>\n <div data-file>\n {iconRenderer ? (\n React.createElement(iconRenderer, { name: 'file-text' })\n ) : (\n <Icon name=\"file-text\" />\n )}\n <span data-filename>globals.css</span>\n <span data-filepath>app/globals.css</span>\n </div>\n </div>\n {code && <CodeBlock language={language} code={code} />}\n </div>\n )}\n </div>\n )\n}\n","import React, { useState } from 'react'\nimport { ThinkingSection } from './thinking-section'\nimport { TaskSection } from './task-section'\nimport { IconProps } from './icon'\n\nexport interface ContentPartRendererProps {\n part: any\n iconRenderer?: React.ComponentType<IconProps>\n thinkingSectionRenderer?: React.ComponentType<{\n title?: string\n duration?: number\n thought?: string\n collapsed?: boolean\n className?: string\n children?: React.ReactNode\n brainIcon?: React.ReactNode\n chevronRightIcon?: React.ReactNode\n chevronDownIcon?: React.ReactNode\n }>\n taskSectionRenderer?: React.ComponentType<{\n title?: string\n type?: string\n parts?: any[]\n collapsed?: boolean\n className?: string\n children?: React.ReactNode\n taskIcon?: React.ReactNode\n chevronRightIcon?: React.ReactNode\n chevronDownIcon?: React.ReactNode\n }>\n // Individual icon props for direct icon usage\n brainIcon?: React.ReactNode\n chevronRightIcon?: React.ReactNode\n chevronDownIcon?: React.ReactNode\n searchIcon?: React.ReactNode\n folderIcon?: React.ReactNode\n settingsIcon?: React.ReactNode\n wrenchIcon?: React.ReactNode\n}\n\nexport function ContentPartRenderer({\n part,\n iconRenderer,\n thinkingSectionRenderer,\n taskSectionRenderer,\n brainIcon,\n chevronRightIcon,\n chevronDownIcon,\n searchIcon,\n folderIcon,\n settingsIcon,\n wrenchIcon,\n}: ContentPartRendererProps) {\n if (!part) return null\n\n const { type, parts = [], ...metadata } = part\n\n switch (type) {\n case 'task-thinking-v1': {\n const thinkingPart = parts.find((p: any) => p.type === 'thinking-end')\n const ThinkingComponent = thinkingSectionRenderer || ThinkingSection\n const [collapsed, setCollapsed] = useState(true)\n\n return (\n <ThinkingComponent\n title=\"Thought\"\n duration={thinkingPart?.duration}\n thought={thinkingPart?.thought}\n collapsed={collapsed}\n onCollapse={() => setCollapsed(!collapsed)}\n brainIcon={brainIcon}\n chevronRightIcon={chevronRightIcon}\n chevronDownIcon={chevronDownIcon}\n />\n )\n }\n\n case 'task-search-web-v1': {\n const TaskComponent = taskSectionRenderer || TaskSection\n const [collapsed, setCollapsed] = useState(true)\n\n return (\n <TaskComponent\n title={metadata.taskNameComplete || metadata.taskNameActive}\n type={type}\n parts={parts}\n collapsed={collapsed}\n onCollapse={() => setCollapsed(!collapsed)}\n taskIcon={searchIcon}\n chevronRightIcon={chevronRightIcon}\n chevronDownIcon={chevronDownIcon}\n />\n )\n }\n\n case 'task-search-repo-v1': {\n const TaskComponent = taskSectionRenderer || TaskSection\n const [collapsed, setCollapsed] = useState(true)\n\n return (\n <TaskComponent\n title={metadata.taskNameComplete || metadata.taskNameActive}\n type={type}\n parts={parts}\n collapsed={collapsed}\n onCollapse={() => setCollapsed(!collapsed)}\n taskIcon={folderIcon}\n chevronRightIcon={chevronRightIcon}\n chevronDownIcon={chevronDownIcon}\n />\n )\n }\n\n case 'task-diagnostics-v1': {\n const TaskComponent = taskSectionRenderer || TaskSection\n const [collapsed, setCollapsed] = useState(true)\n\n return (\n <TaskComponent\n title={metadata.taskNameComplete || metadata.taskNameActive}\n type={type}\n parts={parts}\n collapsed={collapsed}\n onCollapse={() => setCollapsed(!collapsed)}\n taskIcon={settingsIcon}\n chevronRightIcon={chevronRightIcon}\n chevronDownIcon={chevronDownIcon}\n />\n )\n }\n\n case 'task-start-v1':\n // Usually just indicates task start - can be hidden or show as status\n return null\n\n default:\n return <div data-unknown-part-type={type}>Unknown part type: {type}</div>\n }\n}\n","import React from 'react'\n\nexport interface MathPartProps {\n content: string\n inline?: boolean\n className?: string\n children?: React.ReactNode\n displayMode?: boolean\n}\n\n/**\n * Generic math renderer component\n * Renders plain math content by default - consumers should provide their own math rendering\n */\nexport function MathPart({\n content,\n inline = false,\n className = '',\n children,\n}: MathPartProps) {\n // If children provided, use that (allows complete customization)\n if (children) {\n return <>{children}</>\n }\n\n // Simple fallback - just render plain math content\n const Element = inline ? 'span' : 'div'\n\n return (\n <Element className={className} data-math-inline={inline}>\n {content}\n </Element>\n )\n}\n","import React from 'react'\n\nexport interface CodeBlockProps {\n language: string\n code: string\n className?: string\n children?: React.ReactNode\n filename?: string\n}\n\n/**\n * Generic code block component\n * Renders plain code by default - consumers should provide their own styling and highlighting\n */\nexport function CodeBlock({\n language,\n code,\n className = '',\n children,\n}: CodeBlockProps) {\n // If children provided, use that (allows complete customization)\n if (children) {\n return <>{children}</>\n }\n\n // Simple fallback - just render plain code\n return (\n <pre className={className} data-language={language}>\n <code>{code}</code>\n </pre>\n )\n}\n"],"names":[],"mappings":";;;AAAA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACO;AACP;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACA;;AC5KP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;AChCA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;ACRA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;ACjBA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;ACjBA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;ACdA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;AClCA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;ACXA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;;;"}