simple_node_characterai 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,6 +7,7 @@ Simple Node.js library for interacting with Character.AI via HTTP and WebSocket
7
7
  ## Features
8
8
  - Authenticate with a session token and initialize a WebSocket
9
9
  - Create one-on-one chats with characters
10
+ - Create group chats with characters
10
11
  - Send messages and await final replies
11
12
  - Fetch chat turns (messages) with pagination
12
13
  - Minimal, typed API with clear data models
@@ -112,6 +113,153 @@ app.get('/messages/:chatId', async (c) => {
112
113
  export default app
113
114
  ```
114
115
 
116
+ ## Group Chat Quick Start
117
+
118
+ **Warning**: Connection to room chat is cannot more than 1 connection. so you cannot mass use it.
119
+
120
+ ```ts
121
+ import {
122
+ authenticate,
123
+ createGroupChat
124
+ listGroupChat,
125
+ connectGroupChat,
126
+ sendGroupMessage,
127
+ generateTurnGroupMessage,
128
+ disconnectGroupChat
129
+ } from 'simple_node_characterai';
130
+
131
+ (async () => {
132
+ await authenticate('YOUR_SESSION_TOKEN');
133
+
134
+ // 1) List Groups
135
+ const listGroups = await listGroupChats();
136
+
137
+ // 2) Create Group Chat
138
+ const createGroupChat = await createGroupChat('My Group Chat', ['CHARACTER_ID_1', 'CHARACTER_ID_2']);
139
+
140
+ // Assuming we pick the first room or use a known ID
141
+ const roomId = 'ROOM_ID';
142
+
143
+ // 3) Connect
144
+ const connect = await connectGroupChat(roomId);
145
+
146
+ // 4) Send Message
147
+ const sendMessage = await sendGroupMessage('Hi!', roomId);
148
+ console.log(JSON.stringify(sendMessage, null, 4));
149
+
150
+ // 5) Generate Turn Message
151
+ const generateResponse = await generateTurnGroupMessage(roomId);
152
+ console.log(JSON.stringify(generateResponse.push, null, 4));
153
+
154
+ // 6) Disconnect
155
+ await disconnectGroupChat(roomId);
156
+ })();
157
+ ```
158
+
159
+ ## Example with Hono Route Handler (Group Chat)
160
+
161
+ ```ts
162
+ import { Hono } from 'hono'
163
+ import {
164
+ authenticate,
165
+ listGroupChat,
166
+ CreateGroupChat
167
+ connectGroupChat,
168
+ sendGroupMessage,
169
+ generateTurnGroupMessage,
170
+ disconnectGroupChat
171
+ } from 'simple_node_characterai';
172
+
173
+ const app = new Hono();
174
+
175
+ (async () => {
176
+ await authenticate(process.env.CHARACTERAI_TOKEN!);
177
+ })();
178
+
179
+ // List all group chats
180
+ app.get('/group', async (c) => {
181
+ try {
182
+ const list = await listGroupChat();
183
+ return c.json(list);
184
+ } catch (e) {
185
+ return c.json({ error: 'Failed to list groups' }, 500);
186
+ }
187
+ });
188
+
189
+ // Create a group chat
190
+ // Body: {title: string, characterIds: string | string[]}
191
+ // Store the id somewhere
192
+ app.post('/group', async (c) => {
193
+ try {
194
+ const body = await c.req.json();
195
+ const title = body?.title;
196
+ const characterIds = body?.characterIds;
197
+ if (!title || !characterIds) return c.json({ error: 'title and characterIds are required' }, 400);
198
+ const createGroupChat = await createGroupChat(title, characterIds);
199
+ return c.json(createGroupChat);
200
+ } catch (e) {
201
+ return c.json({ error: 'Failed to create group chat' }, 500);
202
+ }
203
+ });
204
+
205
+ // Connect to a group chat room
206
+ // Params: { roomId: string }
207
+ app.post('/group/:roomId/connect', async (c) => {
208
+ try {
209
+ const roomId = c.req.param('roomId');
210
+ if (!roomId) return c.json({ error: 'roomId is required' }, 400);
211
+ const connect = await connectGroupChat(roomId);
212
+ return c.json(connect);
213
+ } catch (e) {
214
+ return c.json({ error: 'Failed to connect' }, 500);
215
+ }
216
+ });
217
+
218
+ // Send a message to a group chat
219
+ // Body: { message: string }
220
+ // After sending a message, you must generate a turn to get the response, this message function is return your message, not the character reply itself
221
+ app.post('/group/:roomId/message', async (c) => {
222
+ try {
223
+ const roomId = c.req.param('roomId');
224
+ if (!roomId) return c.json({ error: 'roomId is required' }, 400);
225
+ const body = await c.req.json();
226
+ const message = body?.message;
227
+ if (!message) return c.json({ error: 'Message is required' }, 400);
228
+ const sendMessage = await sendGroupMessage(message, roomId);
229
+ return c.json(sendMessage);
230
+ } catch (e) {
231
+ return c.json({ error: 'Failed to send message' }, 500);
232
+ }
233
+ });
234
+
235
+ // Generate a turn in the group chat after sending a message
236
+ app.post('/group/:roomId/generate', async (c) => {
237
+ try {
238
+ const roomId = c.req.param('roomId');
239
+ if (!roomId) return c.json({ error: 'roomId is required' }, 400);
240
+ const generateResponse = await generateTurnGroupMessage(roomId);
241
+ return c.json(generateResponse);
242
+ } catch (e) {
243
+ return c.json({ error: 'Failed to generate turn' }, 500);
244
+ }
245
+ });
246
+
247
+ // Disconnect a group chat room
248
+ // Params: { roomId: string }
249
+ app.post('/group/:roomId/disconnect', async (c) => {
250
+ try {
251
+ const roomId = c.req.param('roomId');
252
+ if (!roomId) return c.json({ error: 'roomId is required' }, 400);
253
+ const disconnect = await disconnectGroupChat(roomId);
254
+ return c.json(disconnect);
255
+ } catch (e) {
256
+ return c.json({ error: 'Failed to disconnect' }, 500);
257
+ }
258
+ });
259
+
260
+ export default app
261
+ ```
262
+
115
263
  ## Find Authorization Token
116
264
  <img width="795" height="550" alt="image" src="https://github.com/user-attachments/assets/fefe6262-00cb-4a1f-82da-51a4c96ef299" />
117
265
 
@@ -159,10 +307,33 @@ https://character.ai/chat/{characterId}?hist={chatId}
159
307
  - Retrieves up to 50 turns for the given chat.
160
308
  - If a `token` is provided, fetches the next page of results using `next_token`.
161
309
 
310
+ ### Group Chat
311
+
312
+ #### listGroupChat(): Promise<{rooms: GroupChat[]}>
313
+ - Lists all group chats (rooms) the user is a member of.
314
+
315
+ #### createGroupChat(title: string, characters_id: string | string[]): Promise<GroupChat>
316
+ - Creates a new group chat room with specified characters.
317
+
318
+ #### connectGroupChat(roomId: string): Promise<ConnectGroupChatResponse>
319
+ - Connects to a specific group chat room via WebSocket.
320
+
321
+ #### disconnectGroupChat(roomId: string): Promise<disconnectGroupChatPayload>
322
+ - Disconnects from a specific group chat room via WebSocket.
323
+
324
+ #### sendGroupMessage(message: string, chatId: string): Promise<MessageGroupResponse>
325
+ - Sends a message to a group chat room.
326
+
327
+ #### generateTurnGroupMessage(chatId: string): Promise<MessageGroupGenerateTurnResponse>
328
+ - Triggers the characters in the group chat to generate a turn/reply.
329
+
162
330
  ## Notes
163
331
  - This package is intended for personal use.
164
332
  - Avoid logging tokens, cookies, or PII; keep sensitive information in memory.
165
333
  - When building client-side applications, follow CORS restrictions; this package is designed for server-side Node usage.
166
334
 
167
335
  ## Development
168
- Still in development but ready to use for basic chatting usage, more feature will be added in the future.
336
+ Still in development but ready to use for basic chatting usage, more feature will be added in the future.
337
+
338
+ ## Support
339
+ If you like this package, support me with stars in github, its help me so much
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAMtC;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAU,cAAc,MAAM,KAAI,OAAO,CAAC,IAAI,CAoBtE,CAAA;AAoBD;;;GAGG;AACH,eAAO,MAAM,UAAU,QAAQ,OAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAMtC;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAU,cAAc,MAAM,KAAI,OAAO,CAAC,IAAI,CA2BtE,CAAA;AAoBD;;;GAGG;AACH,eAAO,MAAM,UAAU,QAAQ,OAAe,CAAC"}
@@ -26,8 +26,13 @@ const authenticate = async (sessionToken) => {
26
26
  edgeRollout: "60",
27
27
  authorization: sessionToken
28
28
  });
29
+ await (0, Websocket_1.connectGroup)({
30
+ edgeRollout: "60",
31
+ authorization: sessionToken
32
+ });
29
33
  }
30
34
  catch (error) {
35
+ console.log(error);
31
36
  throw Error(`Failed to initialize Character AI, Error: ${error}`);
32
37
  }
33
38
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/Auth/index.ts"],"names":[],"mappings":";;;AACA,4CAAuC;AACvC,gCAA8C;AAE9C,IAAI,IAAI,GAAY,EAAa,CAAC;AAElC;;;;;GAKG;AACI,MAAM,YAAY,GAAG,KAAK,EAAE,YAAoB,EAAkB,EAAE;IACvE,IAAI,CAAC;QACD,IAAI,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,YAAY,GAAG,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;QAEnH,IAAA,iBAAW,EAAC,YAAY,CAAC,CAAC;QAE1B,MAAM,GAAG,GAAG,MAAM,IAAA,aAAO,EAAC,+CAA+C,EAAE;YACvE,MAAM,EAAE,KAAK;YACb,oBAAoB,EAAE,IAAI;SAC7B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAE1D,MAAM,WAAW,EAAE,CAAC;QACpB,MAAM,IAAA,mBAAO,EAAC;YACV,WAAW,EAAE,IAAI;YACjB,aAAa,EAAE,YAAY;SAC9B,CAAC,CAAC;IACP,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACtB,MAAM,KAAK,CAAC,6CAA6C,KAAK,EAAE,CAAC,CAAC;IACtE,CAAC;AACL,CAAC,CAAA;AApBY,QAAA,YAAY,gBAoBxB;AAED;;;;GAIG;AACH,MAAM,WAAW,GAAG,KAAK,IAAoB,EAAE;IAC3C,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAA,aAAO,EAAC,sCAAsC,EAAE;YACjE,MAAM,EAAE,KAAK;YACb,oBAAoB,EAAE,IAAI;SAC7B,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACtB,MAAM,KAAK,CAAC,oDAAoD,KAAK,EAAE,CAAC,CAAC;IAC7E,CAAC;AACL,CAAC,CAAA;AAED;;;GAGG;AACI,MAAM,UAAU,GAAG,GAAa,EAAE,CAAC,IAAI,CAAC;AAAlC,QAAA,UAAU,cAAwB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/Auth/index.ts"],"names":[],"mappings":";;;AACA,4CAAqD;AACrD,gCAA8C;AAE9C,IAAI,IAAI,GAAY,EAAa,CAAC;AAElC;;;;;GAKG;AACI,MAAM,YAAY,GAAG,KAAK,EAAE,YAAoB,EAAkB,EAAE;IACvE,IAAI,CAAC;QACD,IAAI,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,YAAY,GAAG,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;QAEnH,IAAA,iBAAW,EAAC,YAAY,CAAC,CAAC;QAE1B,MAAM,GAAG,GAAG,MAAM,IAAA,aAAO,EAAC,+CAA+C,EAAE;YACvE,MAAM,EAAE,KAAK;YACb,oBAAoB,EAAE,IAAI;SAC7B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAE1D,MAAM,WAAW,EAAE,CAAC;QAEpB,MAAM,IAAA,mBAAO,EAAC;YACV,WAAW,EAAE,IAAI;YACjB,aAAa,EAAE,YAAY;SAC9B,CAAC,CAAC;QAEH,MAAM,IAAA,wBAAY,EAAC;YACf,WAAW,EAAE,IAAI;YACjB,aAAa,EAAE,YAAY;SAC9B,CAAC,CAAC;IACP,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,MAAM,KAAK,CAAC,6CAA6C,KAAK,EAAE,CAAC,CAAC;IACtE,CAAC;AACL,CAAC,CAAA;AA3BY,QAAA,YAAY,gBA2BxB;AAED;;;;GAIG;AACH,MAAM,WAAW,GAAG,KAAK,IAAoB,EAAE;IAC3C,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAA,aAAO,EAAC,sCAAsC,EAAE;YACjE,MAAM,EAAE,KAAK;YACb,oBAAoB,EAAE,IAAI;SAC7B,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACtB,MAAM,KAAK,CAAC,oDAAoD,KAAK,EAAE,CAAC,CAAC;IAC7E,CAAC;AACL,CAAC,CAAA;AAED;;;GAGG;AACI,MAAM,UAAU,GAAG,GAAa,EAAE,CAAC,IAAI,CAAC;AAAlC,QAAA,UAAU,cAAwB"}
@@ -1,27 +1,18 @@
1
- import { AddTurnResponse, UpdateTurnResponse, Turn } from "../types/Chat";
1
+ import { AddTurnResponse, UpdateTurnResponse, Turn, ConnectGroupChatResponse, disconnectGroupChatPayload, GroupChat, MessageGroupResponse, MessageGroupGenerateTurnResponse } from "../types/Chat";
2
2
  /**
3
3
  * Creates a new one-on-one chat for the given character.
4
4
  * Opens a WebSocket request and resolves when the initial turn is added.
5
5
  * @param characterId - The ID of the character to start a chat with.
6
- * @returns AddTurnResponse containing chat metadata and the greeting turn.
6
+ * @returns {Promise<AddTurnResponse>} AddTurnResponse containing chat metadata and the greeting turn.
7
7
  */
8
8
  export declare const createNewConversation: (characterId: string) => Promise<AddTurnResponse>;
9
- /**
10
- * Sends a message to an existing chat and waits for the final reply.
11
- * Uses the WebSocket to create and generate a turn, resolving on final candidate.
12
- * @param message - The user's text message to send.
13
- * @param characterId - The target character's ID.
14
- * @param chatId - The ID of the chat where the message is posted.
15
- * @returns UpdateTurnResponse containing the generated turn with final candidate.
16
- */
17
- export declare const sendMessage: (message: string, characterId: string, chatId: string) => Promise<UpdateTurnResponse>;
18
9
  /**
19
10
  * Retrieves up to 50 messages (turns) for a given chat.
20
11
  * If a `token` is provided, it fetches the next page of results.
21
12
  * Token can be null in the end of the chat.
22
13
  * @param chatId - The ID of the chat whose messages are to be fetched.
23
14
  * @param token - Optional pagination token for retrieving the next batch.
24
- * @return Parsed JSON containing up to 50 messages in turns field, and the token for pagination in meta field.
15
+ * @returns {Promise<{turns: Turn[], meta: {next_token: string | null}}>} Parsed JSON containing up to 50 messages in turns field, and the token for pagination in meta field.
25
16
  */
26
17
  export declare const getMessages: (chatId: string, token?: string) => Promise<{
27
18
  turns: Turn[];
@@ -29,4 +20,54 @@ export declare const getMessages: (chatId: string, token?: string) => Promise<{
29
20
  next_token: string | null;
30
21
  };
31
22
  }>;
23
+ /**
24
+ * Sends a message to an existing chat and waits for the final reply.
25
+ * Uses the WebSocket to create and generate a turn, resolving on final candidate.
26
+ * @param message - The user's text message to send.
27
+ * @param characterId - The target character's ID.
28
+ * @param chatId - The ID of the chat where the message is posted.
29
+ * @returns {Promise<UpdateTurnResponse>} UpdateTurnResponse containing the generated turn with final candidate.
30
+ */
31
+ export declare const sendMessage: (message: string, characterId: string, chatId: string) => Promise<UpdateTurnResponse>;
32
+ /**
33
+ * Lists all group chats (rooms) the user is a member of.
34
+ * @returns {Promise<{rooms: GroupChat[]}>} Promise resolving to an object containing an array of GroupChat rooms.
35
+ */
36
+ export declare const listGroupChats: () => Promise<{
37
+ rooms: GroupChat[];
38
+ }>;
39
+ /**
40
+ * Creates a new group chat room with specified characters.
41
+ * @param title - The title of the group chat room.
42
+ * @param characters_id - A single character ID or an array of character IDs to include in the group.
43
+ * @returns {Promise<GroupChat>} Promise resolving to the created GroupChat object.
44
+ */
45
+ export declare const createGroupChat: (title: string, characters_id: string | string[]) => Promise<GroupChat>;
46
+ /**
47
+ * Connects to a specific group chat room via WebSocket.
48
+ * Subscribes to the room channel to receive updates.
49
+ * @param roomId - The ID of the room to connect to.
50
+ * @returns {Promise<ConnectGroupChatResponse>} Promise resolving to the connection response.
51
+ */
52
+ export declare const connectGroupChat: (roomId: string) => Promise<ConnectGroupChatResponse>;
53
+ /**
54
+ * Disconnects from a specific group chat room via WebSocket.
55
+ * Unsubscribes from the room channel.
56
+ * @param roomId - The ID of the room to disconnect from.
57
+ * @returns {Promise<disconnectGroupChatPayload>} Promise resolving to the disconnection payload/response.
58
+ */
59
+ export declare const disconnectGroupChat: (roomId: string) => Promise<disconnectGroupChatPayload>;
60
+ /**
61
+ * Sends a message to a group chat room.
62
+ * @param message - The text content of the message.
63
+ * @param chatId - The ID of the group chat (room ID) to send the message to.
64
+ * @returns {Promise<MessageGroupResponse>} Promise resolving to the message response, including the created turn.
65
+ */
66
+ export declare const sendGroupMessage: (message: string, chatId: string) => Promise<MessageGroupResponse>;
67
+ /**
68
+ * Triggers the characters in the group chat to generate a turn/reply.
69
+ * @param chatId - The ID of the group chat (room ID).
70
+ * @returns {Promise<MessageGroupGenerateTurnResponse>} Promise resolving to the generated turn response.
71
+ */
72
+ export declare const generateTurnGroupMessage: (chatId: string) => Promise<MessageGroupGenerateTurnResponse>;
32
73
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Chat/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAmD,kBAAkB,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAK3H;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAU,aAAa,MAAM,KAAG,OAAO,CAAC,eAAe,CA0CxF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAU,SAAS,MAAM,EAAE,aAAa,MAAM,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,kBAAkB,CAoFlH,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAU,QAAQ,MAAM,EAAE,QAAQ,MAAM,KAAI,OAAO,CAAC;IACxE,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,IAAI,EAAE;QACF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAC5B,CAAA;CACJ,CAcA,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Chat/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAmD,kBAAkB,EAAE,IAAI,EAA0B,wBAAwB,EAA2B,0BAA0B,EAAE,SAAS,EAAuB,oBAAoB,EAAmC,gCAAgC,EAAE,MAAM,eAAe,CAAC;AAK3V;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAU,aAAa,MAAM,KAAG,OAAO,CAAC,eAAe,CA8CxF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAU,QAAQ,MAAM,EAAE,QAAQ,MAAM,KAAI,OAAO,CAAC;IACxE,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,IAAI,EAAE;QACF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAC5B,CAAA;CACJ,CAcA,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAU,SAAS,MAAM,EAAE,aAAa,MAAM,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,kBAAkB,CAwFlH,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAc,OAAO,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAC,CAapE,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAU,OAAO,MAAM,EAAE,eAAe,MAAM,GAAG,MAAM,EAAE,KAAI,OAAO,CAAC,SAAS,CAuBzG,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAU,QAAQ,MAAM,KAAI,OAAO,CAAC,wBAAwB,CAgCxF,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAU,QAAQ,MAAM,KAAI,OAAO,CAAC,0BAA0B,CAgC7F,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAU,SAAS,MAAM,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,oBAAoB,CAgEpG,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,gCAAgC,CAkDvG,CAAC"}