canvu-react 0.3.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.
- package/LICENSE +21 -0
- package/README.md +156 -0
- package/dist/camera-BwQjm5oh.d.cts +50 -0
- package/dist/camera-KwCYYPhm.d.ts +50 -0
- package/dist/chatbot.cjs +221 -0
- package/dist/chatbot.cjs.map +1 -0
- package/dist/chatbot.d.cts +36 -0
- package/dist/chatbot.d.ts +36 -0
- package/dist/chatbot.js +218 -0
- package/dist/chatbot.js.map +1 -0
- package/dist/index.cjs +1920 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +276 -0
- package/dist/index.d.ts +276 -0
- package/dist/index.js +1867 -0
- package/dist/index.js.map +1 -0
- package/dist/native.cjs +2572 -0
- package/dist/native.cjs.map +1 -0
- package/dist/native.d.cts +217 -0
- package/dist/native.d.ts +217 -0
- package/dist/native.js +2562 -0
- package/dist/native.js.map +1 -0
- package/dist/react.cjs +8540 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +481 -0
- package/dist/react.d.ts +481 -0
- package/dist/react.js +8492 -0
- package/dist/react.js.map +1 -0
- package/dist/realtime.cjs +2338 -0
- package/dist/realtime.cjs.map +1 -0
- package/dist/realtime.d.cts +309 -0
- package/dist/realtime.d.ts +309 -0
- package/dist/realtime.js +2317 -0
- package/dist/realtime.js.map +1 -0
- package/dist/shape-builders-DTYvub8W.d.ts +93 -0
- package/dist/shape-builders-DxPoOecg.d.cts +93 -0
- package/dist/tldraw.cjs +1948 -0
- package/dist/tldraw.cjs.map +1 -0
- package/dist/tldraw.d.cts +98 -0
- package/dist/tldraw.d.ts +98 -0
- package/dist/tldraw.js +1941 -0
- package/dist/tldraw.js.map +1 -0
- package/dist/types--ALu1mF-.d.ts +356 -0
- package/dist/types-B58i5k-u.d.cts +35 -0
- package/dist/types-CB0TZZuk.d.cts +157 -0
- package/dist/types-CB0TZZuk.d.ts +157 -0
- package/dist/types-D1ftVsOQ.d.cts +356 -0
- package/dist/types-DgEArHkA.d.ts +35 -0
- package/package.json +103 -0
package/dist/chatbot.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { useChat } from '@ai-sdk/react';
|
|
2
|
+
import { DefaultChatTransport } from 'ai';
|
|
3
|
+
import { useId, useMemo, useState } from 'react';
|
|
4
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/react/plugins/chatbot/message-text.ts
|
|
7
|
+
function getMessageText(message) {
|
|
8
|
+
const parts = message.parts;
|
|
9
|
+
if (!parts?.length) return "";
|
|
10
|
+
return parts.filter((p) => p.type === "text").map((p) => p.text).join("");
|
|
11
|
+
}
|
|
12
|
+
var shell = {
|
|
13
|
+
position: "absolute",
|
|
14
|
+
right: 12,
|
|
15
|
+
bottom: 12,
|
|
16
|
+
width: 360,
|
|
17
|
+
maxWidth: "calc(100% - 24px)",
|
|
18
|
+
maxHeight: "min(420px, 70dvh)",
|
|
19
|
+
display: "flex",
|
|
20
|
+
flexDirection: "column",
|
|
21
|
+
borderRadius: 12,
|
|
22
|
+
border: "1px solid rgba(0,0,0,0.12)",
|
|
23
|
+
background: "rgba(255,255,255,0.97)",
|
|
24
|
+
boxShadow: "0 8px 24px rgba(0,0,0,0.1)",
|
|
25
|
+
pointerEvents: "auto",
|
|
26
|
+
overflow: "hidden"
|
|
27
|
+
};
|
|
28
|
+
var header = {
|
|
29
|
+
display: "flex",
|
|
30
|
+
alignItems: "center",
|
|
31
|
+
justifyContent: "space-between",
|
|
32
|
+
padding: "8px 12px",
|
|
33
|
+
borderBottom: "1px solid #e4e4e7",
|
|
34
|
+
fontSize: "0.8125rem",
|
|
35
|
+
fontWeight: 700,
|
|
36
|
+
color: "#18181b"
|
|
37
|
+
};
|
|
38
|
+
var messagesBox = {
|
|
39
|
+
flex: 1,
|
|
40
|
+
minHeight: 0,
|
|
41
|
+
overflowY: "auto",
|
|
42
|
+
padding: "10px 12px",
|
|
43
|
+
fontSize: "0.8125rem",
|
|
44
|
+
display: "flex",
|
|
45
|
+
flexDirection: "column",
|
|
46
|
+
gap: 8
|
|
47
|
+
};
|
|
48
|
+
var bubble = (role) => ({
|
|
49
|
+
alignSelf: role === "user" ? "flex-end" : "flex-start",
|
|
50
|
+
maxWidth: "92%",
|
|
51
|
+
padding: "8px 10px",
|
|
52
|
+
borderRadius: 10,
|
|
53
|
+
background: role === "user" ? "#2563eb" : "#f4f4f5",
|
|
54
|
+
color: role === "user" ? "#fff" : "#18181b",
|
|
55
|
+
whiteSpace: "pre-wrap",
|
|
56
|
+
wordBreak: "break-word"
|
|
57
|
+
});
|
|
58
|
+
var formStyle = {
|
|
59
|
+
display: "flex",
|
|
60
|
+
gap: 8,
|
|
61
|
+
padding: 8,
|
|
62
|
+
borderTop: "1px solid #e4e4e7"
|
|
63
|
+
};
|
|
64
|
+
var inputStyle = {
|
|
65
|
+
flex: 1,
|
|
66
|
+
minWidth: 0,
|
|
67
|
+
padding: "8px 10px",
|
|
68
|
+
borderRadius: 8,
|
|
69
|
+
border: "1px solid #d4d4d8",
|
|
70
|
+
fontSize: "0.8125rem",
|
|
71
|
+
outline: "none"
|
|
72
|
+
};
|
|
73
|
+
var btn = {
|
|
74
|
+
padding: "8px 12px",
|
|
75
|
+
borderRadius: 8,
|
|
76
|
+
border: "none",
|
|
77
|
+
background: "#18181b",
|
|
78
|
+
color: "#fff",
|
|
79
|
+
fontSize: "0.8125rem",
|
|
80
|
+
fontWeight: 600,
|
|
81
|
+
cursor: "pointer"
|
|
82
|
+
};
|
|
83
|
+
function ChatbotPluginPanel({
|
|
84
|
+
chatApi,
|
|
85
|
+
title = "Assistente"
|
|
86
|
+
}) {
|
|
87
|
+
const reactId = useId();
|
|
88
|
+
const chatId = useMemo(
|
|
89
|
+
() => `trazo-chatbot-${reactId.replace(/[^a-zA-Z0-9_-]/g, "_")}`,
|
|
90
|
+
[reactId]
|
|
91
|
+
);
|
|
92
|
+
const transport = useMemo(
|
|
93
|
+
() => new DefaultChatTransport({ api: chatApi }),
|
|
94
|
+
[chatApi]
|
|
95
|
+
);
|
|
96
|
+
const { messages, sendMessage, status, error, stop } = useChat({
|
|
97
|
+
id: chatId,
|
|
98
|
+
transport
|
|
99
|
+
});
|
|
100
|
+
const [input, setInput] = useState("");
|
|
101
|
+
const [open, setOpen] = useState(true);
|
|
102
|
+
const onSubmit = (e) => {
|
|
103
|
+
e.preventDefault();
|
|
104
|
+
const t = input.trim();
|
|
105
|
+
if (!t || status === "streaming" || status === "submitted") return;
|
|
106
|
+
void sendMessage({ text: t });
|
|
107
|
+
setInput("");
|
|
108
|
+
};
|
|
109
|
+
if (!open) {
|
|
110
|
+
return /* @__PURE__ */ jsx(
|
|
111
|
+
"button",
|
|
112
|
+
{
|
|
113
|
+
type: "button",
|
|
114
|
+
style: {
|
|
115
|
+
...btn,
|
|
116
|
+
position: "absolute",
|
|
117
|
+
right: 12,
|
|
118
|
+
bottom: 12,
|
|
119
|
+
pointerEvents: "auto",
|
|
120
|
+
borderRadius: 999,
|
|
121
|
+
padding: "10px 14px"
|
|
122
|
+
},
|
|
123
|
+
onClick: () => setOpen(true),
|
|
124
|
+
children: "Chat"
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
return /* @__PURE__ */ jsxs("aside", { style: shell, "aria-label": title, children: [
|
|
129
|
+
/* @__PURE__ */ jsxs("div", { style: header, children: [
|
|
130
|
+
/* @__PURE__ */ jsx("span", { children: title }),
|
|
131
|
+
/* @__PURE__ */ jsxs("span", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
|
|
132
|
+
(status === "streaming" || status === "submitted") && /* @__PURE__ */ jsx(
|
|
133
|
+
"button",
|
|
134
|
+
{
|
|
135
|
+
type: "button",
|
|
136
|
+
onClick: () => void stop(),
|
|
137
|
+
style: {
|
|
138
|
+
fontSize: "0.75rem",
|
|
139
|
+
color: "#71717a",
|
|
140
|
+
background: "none",
|
|
141
|
+
border: "none",
|
|
142
|
+
cursor: "pointer"
|
|
143
|
+
},
|
|
144
|
+
children: "Parar"
|
|
145
|
+
}
|
|
146
|
+
),
|
|
147
|
+
/* @__PURE__ */ jsx(
|
|
148
|
+
"button",
|
|
149
|
+
{
|
|
150
|
+
type: "button",
|
|
151
|
+
onClick: () => setOpen(false),
|
|
152
|
+
style: {
|
|
153
|
+
fontSize: "0.75rem",
|
|
154
|
+
color: "#71717a",
|
|
155
|
+
background: "none",
|
|
156
|
+
border: "none",
|
|
157
|
+
cursor: "pointer"
|
|
158
|
+
},
|
|
159
|
+
"aria-label": "Fechar chat",
|
|
160
|
+
children: "\u2212"
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
] })
|
|
164
|
+
] }),
|
|
165
|
+
/* @__PURE__ */ jsxs("div", { style: messagesBox, children: [
|
|
166
|
+
messages.length === 0 && /* @__PURE__ */ jsxs("p", { style: { margin: 0, color: "#71717a", fontSize: "0.75rem" }, children: [
|
|
167
|
+
"Mensagens aparecem aqui. O backend deve estar em",
|
|
168
|
+
" ",
|
|
169
|
+
/* @__PURE__ */ jsx("code", { style: { fontSize: "0.7rem" }, children: chatApi }),
|
|
170
|
+
"."
|
|
171
|
+
] }),
|
|
172
|
+
messages.map((m) => /* @__PURE__ */ jsx("div", { style: bubble(m.role), children: getMessageText(m) }, m.id)),
|
|
173
|
+
error && /* @__PURE__ */ jsx(
|
|
174
|
+
"div",
|
|
175
|
+
{
|
|
176
|
+
style: {
|
|
177
|
+
...bubble("assistant"),
|
|
178
|
+
background: "#fef2f2",
|
|
179
|
+
color: "#b91c1c"
|
|
180
|
+
},
|
|
181
|
+
children: error.message
|
|
182
|
+
}
|
|
183
|
+
)
|
|
184
|
+
] }),
|
|
185
|
+
/* @__PURE__ */ jsxs("form", { style: formStyle, onSubmit, children: [
|
|
186
|
+
/* @__PURE__ */ jsx(
|
|
187
|
+
"input",
|
|
188
|
+
{
|
|
189
|
+
style: inputStyle,
|
|
190
|
+
value: input,
|
|
191
|
+
onChange: (e) => setInput(e.target.value),
|
|
192
|
+
placeholder: "Escreva uma mensagem\u2026",
|
|
193
|
+
"aria-label": "Mensagem",
|
|
194
|
+
autoComplete: "off"
|
|
195
|
+
}
|
|
196
|
+
),
|
|
197
|
+
/* @__PURE__ */ jsx(
|
|
198
|
+
"button",
|
|
199
|
+
{
|
|
200
|
+
type: "submit",
|
|
201
|
+
style: btn,
|
|
202
|
+
disabled: status === "streaming" || status === "submitted",
|
|
203
|
+
children: "Enviar"
|
|
204
|
+
}
|
|
205
|
+
)
|
|
206
|
+
] })
|
|
207
|
+
] });
|
|
208
|
+
}
|
|
209
|
+
function chatbotPlugin(options) {
|
|
210
|
+
return {
|
|
211
|
+
id: "trazo.plugin.chatbot",
|
|
212
|
+
render: () => /* @__PURE__ */ jsx(ChatbotPluginPanel, { ...options })
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export { ChatbotPluginPanel, chatbotPlugin };
|
|
217
|
+
//# sourceMappingURL=chatbot.js.map
|
|
218
|
+
//# sourceMappingURL=chatbot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/plugins/chatbot/message-text.ts","../src/react/plugins/chatbot/ChatbotPluginPanel.tsx","../src/react/plugins/chatbot/chatbot-plugin.tsx"],"names":["jsx"],"mappings":"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","file":"chatbot.js","sourcesContent":["import type { UIMessage } from \"ai\";\n\n/** Flattens text parts from a UI message for simple transcript rendering. */\nexport function getMessageText(message: UIMessage): string {\n\tconst parts = message.parts;\n\tif (!parts?.length) return \"\";\n\treturn parts\n\t\t.filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n\t\t.map((p) => p.text)\n\t\t.join(\"\");\n}\n","\"use client\";\n\nimport { useChat } from \"@ai-sdk/react\";\nimport { DefaultChatTransport } from \"ai\";\nimport { type CSSProperties, type FormEvent, useId, useMemo, useState } from \"react\";\nimport { getMessageText } from \"./message-text\";\n\nconst shell: CSSProperties = {\n\tposition: \"absolute\",\n\tright: 12,\n\tbottom: 12,\n\twidth: 360,\n\tmaxWidth: \"calc(100% - 24px)\",\n\tmaxHeight: \"min(420px, 70dvh)\",\n\tdisplay: \"flex\",\n\tflexDirection: \"column\",\n\tborderRadius: 12,\n\tborder: \"1px solid rgba(0,0,0,0.12)\",\n\tbackground: \"rgba(255,255,255,0.97)\",\n\tboxShadow: \"0 8px 24px rgba(0,0,0,0.1)\",\n\tpointerEvents: \"auto\",\n\toverflow: \"hidden\",\n};\n\nconst header: CSSProperties = {\n\tdisplay: \"flex\",\n\talignItems: \"center\",\n\tjustifyContent: \"space-between\",\n\tpadding: \"8px 12px\",\n\tborderBottom: \"1px solid #e4e4e7\",\n\tfontSize: \"0.8125rem\",\n\tfontWeight: 700,\n\tcolor: \"#18181b\",\n};\n\nconst messagesBox: CSSProperties = {\n\tflex: 1,\n\tminHeight: 0,\n\toverflowY: \"auto\",\n\tpadding: \"10px 12px\",\n\tfontSize: \"0.8125rem\",\n\tdisplay: \"flex\",\n\tflexDirection: \"column\",\n\tgap: 8,\n};\n\nconst bubble = (role: string): CSSProperties => ({\n\talignSelf: role === \"user\" ? \"flex-end\" : \"flex-start\",\n\tmaxWidth: \"92%\",\n\tpadding: \"8px 10px\",\n\tborderRadius: 10,\n\tbackground: role === \"user\" ? \"#2563eb\" : \"#f4f4f5\",\n\tcolor: role === \"user\" ? \"#fff\" : \"#18181b\",\n\twhiteSpace: \"pre-wrap\",\n\twordBreak: \"break-word\",\n});\n\nconst formStyle: CSSProperties = {\n\tdisplay: \"flex\",\n\tgap: 8,\n\tpadding: 8,\n\tborderTop: \"1px solid #e4e4e7\",\n};\n\nconst inputStyle: CSSProperties = {\n\tflex: 1,\n\tminWidth: 0,\n\tpadding: \"8px 10px\",\n\tborderRadius: 8,\n\tborder: \"1px solid #d4d4d8\",\n\tfontSize: \"0.8125rem\",\n\toutline: \"none\",\n};\n\nconst btn: CSSProperties = {\n\tpadding: \"8px 12px\",\n\tborderRadius: 8,\n\tborder: \"none\",\n\tbackground: \"#18181b\",\n\tcolor: \"#fff\",\n\tfontSize: \"0.8125rem\",\n\tfontWeight: 600,\n\tcursor: \"pointer\",\n};\n\nexport type ChatbotPluginPanelProps = {\n\t/**\n\t * Chat completions endpoint (your Next route, Express, or external URL).\n\t * Must implement the [AI SDK UI stream protocol](https://ai-sdk.dev/docs/ai-sdk-ui/chatbot).\n\t */\n\tchatApi: string;\n\ttitle?: string;\n};\n\n/**\n * Floating chat panel powered by `useChat` + {@link DefaultChatTransport}.\n */\nexport function ChatbotPluginPanel({\n\tchatApi,\n\ttitle = \"Assistente\",\n}: ChatbotPluginPanelProps) {\n\tconst reactId = useId();\n\t/** Stable across SSR + hydration; `useChat` otherwise generates a random id per environment. */\n\tconst chatId = useMemo(\n\t\t() => `trazo-chatbot-${reactId.replace(/[^a-zA-Z0-9_-]/g, \"_\")}`,\n\t\t[reactId],\n\t);\n\n\tconst transport = useMemo(\n\t\t() => new DefaultChatTransport({ api: chatApi }),\n\t\t[chatApi],\n\t);\n\n\tconst { messages, sendMessage, status, error, stop } = useChat({\n\t\tid: chatId,\n\t\ttransport,\n\t});\n\n\tconst [input, setInput] = useState(\"\");\n\tconst [open, setOpen] = useState(true);\n\n\tconst onSubmit = (e: FormEvent) => {\n\t\te.preventDefault();\n\t\tconst t = input.trim();\n\t\tif (!t || status === \"streaming\" || status === \"submitted\") return;\n\t\tvoid sendMessage({ text: t });\n\t\tsetInput(\"\");\n\t};\n\n\tif (!open) {\n\t\treturn (\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tstyle={{\n\t\t\t\t\t...btn,\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tright: 12,\n\t\t\t\t\tbottom: 12,\n\t\t\t\t\tpointerEvents: \"auto\",\n\t\t\t\t\tborderRadius: 999,\n\t\t\t\t\tpadding: \"10px 14px\",\n\t\t\t\t}}\n\t\t\t\tonClick={() => setOpen(true)}\n\t\t\t>\n\t\t\t\tChat\n\t\t\t</button>\n\t\t);\n\t}\n\n\treturn (\n\t\t<aside style={shell} aria-label={title}>\n\t\t\t<div style={header}>\n\t\t\t\t<span>{title}</span>\n\t\t\t\t<span style={{ display: \"flex\", gap: 8, alignItems: \"center\" }}>\n\t\t\t\t\t{(status === \"streaming\" || status === \"submitted\") && (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={() => void stop()}\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tfontSize: \"0.75rem\",\n\t\t\t\t\t\t\t\tcolor: \"#71717a\",\n\t\t\t\t\t\t\t\tbackground: \"none\",\n\t\t\t\t\t\t\t\tborder: \"none\",\n\t\t\t\t\t\t\t\tcursor: \"pointer\",\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tParar\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => setOpen(false)}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tfontSize: \"0.75rem\",\n\t\t\t\t\t\t\tcolor: \"#71717a\",\n\t\t\t\t\t\t\tbackground: \"none\",\n\t\t\t\t\t\t\tborder: \"none\",\n\t\t\t\t\t\t\tcursor: \"pointer\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t\taria-label=\"Fechar chat\"\n\t\t\t\t\t>\n\t\t\t\t\t\t−\n\t\t\t\t\t</button>\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t<div style={messagesBox}>\n\t\t\t\t{messages.length === 0 && (\n\t\t\t\t\t<p style={{ margin: 0, color: \"#71717a\", fontSize: \"0.75rem\" }}>\n\t\t\t\t\t\tMensagens aparecem aqui. O backend deve estar em{\" \"}\n\t\t\t\t\t\t<code style={{ fontSize: \"0.7rem\" }}>{chatApi}</code>.\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\t\t\t\t{messages.map((m) => (\n\t\t\t\t\t<div key={m.id} style={bubble(m.role)}>\n\t\t\t\t\t\t{getMessageText(m)}\n\t\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t\t{error && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t...bubble(\"assistant\"),\n\t\t\t\t\t\t\tbackground: \"#fef2f2\",\n\t\t\t\t\t\t\tcolor: \"#b91c1c\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{error.message}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t<form style={formStyle} onSubmit={onSubmit}>\n\t\t\t\t<input\n\t\t\t\t\tstyle={inputStyle}\n\t\t\t\t\tvalue={input}\n\t\t\t\t\tonChange={(e) => setInput(e.target.value)}\n\t\t\t\t\tplaceholder=\"Escreva uma mensagem…\"\n\t\t\t\t\taria-label=\"Mensagem\"\n\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t/>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\tstyle={btn}\n\t\t\t\t\tdisabled={status === \"streaming\" || status === \"submitted\"}\n\t\t\t\t>\n\t\t\t\t\tEnviar\n\t\t\t\t</button>\n\t\t\t</form>\n\t\t</aside>\n\t);\n}\n","import type { CanvasPlugin } from \"../types\";\nimport {\n\tChatbotPluginPanel,\n\ttype ChatbotPluginPanelProps,\n} from \"./ChatbotPluginPanel\";\n\nexport type ChatbotPluginOptions = ChatbotPluginPanelProps;\n\n/**\n * First-party plugin: floating chat UI using the Vercel AI SDK (`useChat` + HTTP transport).\n * You **must** host a compatible POST endpoint at `chatApi` (see AI SDK UI chat protocol).\n *\n * @example\n * ```tsx\n * <VectorViewport\n * items={doc.items}\n * onItemsChange={doc.onItemsChange}\n * plugins={[chatbotPlugin({ chatApi: \"/api/chat\" })]}\n * />\n * ```\n */\nexport function chatbotPlugin(options: ChatbotPluginOptions): CanvasPlugin {\n\treturn {\n\t\tid: \"trazo.plugin.chatbot\",\n\t\trender: () => <ChatbotPluginPanel {...options} />,\n\t};\n}\n"]}
|