dialogue-ts 0.0.1
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 +446 -0
- package/dist/client/index.cjs +393 -0
- package/dist/client/index.cjs.map +1 -0
- package/dist/client/index.d.cts +273 -0
- package/dist/client/index.d.ts +273 -0
- package/dist/client/index.js +365 -0
- package/dist/client/index.js.map +1 -0
- package/dist/src/index.cjs +1424 -0
- package/dist/src/index.cjs.map +1 -0
- package/dist/src/index.d.cts +664 -0
- package/dist/src/index.d.ts +664 -0
- package/dist/src/index.js +1389 -0
- package/dist/src/index.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
// client/dialogue-client.ts
|
|
2
|
+
import { io } from "socket.io-client";
|
|
3
|
+
|
|
4
|
+
// client/room-context.ts
|
|
5
|
+
function createRoomContext(socket, roomId, roomName, onLeave) {
|
|
6
|
+
const eventHandlers = /* @__PURE__ */ new Map();
|
|
7
|
+
const wildcardHandlers = /* @__PURE__ */ new Set();
|
|
8
|
+
const eventListener = (msg) => {
|
|
9
|
+
if (msg.roomId !== roomId) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const handlers = eventHandlers.get(msg.event);
|
|
13
|
+
if (handlers) {
|
|
14
|
+
for (const handler of handlers) {
|
|
15
|
+
handler(msg);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
for (const handler of wildcardHandlers) {
|
|
19
|
+
handler(msg.event, msg);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
socket.on("dialogue:event", eventListener);
|
|
23
|
+
const context = {
|
|
24
|
+
roomId,
|
|
25
|
+
roomName,
|
|
26
|
+
trigger(eventName, data, meta) {
|
|
27
|
+
socket.emit("dialogue:trigger", {
|
|
28
|
+
roomId,
|
|
29
|
+
event: eventName,
|
|
30
|
+
data,
|
|
31
|
+
...meta && { meta }
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
on(eventName, handler) {
|
|
35
|
+
let handlers = eventHandlers.get(eventName);
|
|
36
|
+
if (!handlers) {
|
|
37
|
+
handlers = /* @__PURE__ */ new Set();
|
|
38
|
+
eventHandlers.set(eventName, handlers);
|
|
39
|
+
}
|
|
40
|
+
handlers.add(handler);
|
|
41
|
+
return () => {
|
|
42
|
+
handlers?.delete(handler);
|
|
43
|
+
if (handlers?.size === 0) {
|
|
44
|
+
eventHandlers.delete(eventName);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
onAny(handler) {
|
|
49
|
+
wildcardHandlers.add(handler);
|
|
50
|
+
return () => {
|
|
51
|
+
wildcardHandlers.delete(handler);
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
subscribe(eventName) {
|
|
55
|
+
socket.emit("dialogue:subscribe", { roomId, eventName });
|
|
56
|
+
},
|
|
57
|
+
subscribeAll() {
|
|
58
|
+
socket.emit("dialogue:subscribeAll", { roomId });
|
|
59
|
+
},
|
|
60
|
+
unsubscribe(eventName) {
|
|
61
|
+
socket.emit("dialogue:unsubscribe", { roomId, eventName });
|
|
62
|
+
},
|
|
63
|
+
getHistory(eventName, start = 0, end = 50) {
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
const timeout = setTimeout(() => {
|
|
66
|
+
cleanup();
|
|
67
|
+
reject(new Error(`Timeout getting history for '${eventName}'`));
|
|
68
|
+
}, 5e3);
|
|
69
|
+
const cleanup = () => {
|
|
70
|
+
clearTimeout(timeout);
|
|
71
|
+
socket.off("dialogue:historyResponse", onResponse);
|
|
72
|
+
};
|
|
73
|
+
const onResponse = (data) => {
|
|
74
|
+
if (data.roomId === roomId && data.eventName === eventName) {
|
|
75
|
+
cleanup();
|
|
76
|
+
resolve(data.events);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
socket.on("dialogue:historyResponse", onResponse);
|
|
80
|
+
socket.emit("dialogue:getHistory", { roomId, eventName, start, end });
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
leave() {
|
|
84
|
+
socket.off("dialogue:event", eventListener);
|
|
85
|
+
eventHandlers.clear();
|
|
86
|
+
wildcardHandlers.clear();
|
|
87
|
+
socket.emit("dialogue:leave", { roomId });
|
|
88
|
+
onLeave();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
return context;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// client/dialogue-client.ts
|
|
95
|
+
function createDialogueClient(config) {
|
|
96
|
+
const socket = io(config.url, {
|
|
97
|
+
auth: config.auth,
|
|
98
|
+
autoConnect: config.autoConnect ?? true,
|
|
99
|
+
reconnection: config.reconnection ?? true,
|
|
100
|
+
reconnectionAttempts: config.reconnectionAttempts ?? 5
|
|
101
|
+
});
|
|
102
|
+
let connectionState = "disconnected";
|
|
103
|
+
let userIdValue = null;
|
|
104
|
+
const joinedRooms = /* @__PURE__ */ new Map();
|
|
105
|
+
const connectHandlers = /* @__PURE__ */ new Set();
|
|
106
|
+
const disconnectHandlers = /* @__PURE__ */ new Set();
|
|
107
|
+
const errorHandlers = /* @__PURE__ */ new Set();
|
|
108
|
+
const roomCreatedHandlers = /* @__PURE__ */ new Set();
|
|
109
|
+
const roomDeletedHandlers = /* @__PURE__ */ new Set();
|
|
110
|
+
const historyHandlers = /* @__PURE__ */ new Set();
|
|
111
|
+
const setupSocketListeners = () => {
|
|
112
|
+
socket.on("connect", () => {
|
|
113
|
+
connectionState = "connecting";
|
|
114
|
+
});
|
|
115
|
+
socket.on("dialogue:connected", (result) => {
|
|
116
|
+
connectionState = "connected";
|
|
117
|
+
userIdValue = result.userId;
|
|
118
|
+
for (const handler of connectHandlers) {
|
|
119
|
+
handler();
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
socket.on("disconnect", (reason) => {
|
|
123
|
+
connectionState = "disconnected";
|
|
124
|
+
for (const handler of disconnectHandlers) {
|
|
125
|
+
handler(reason);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
socket.on("connect_error", (error) => {
|
|
129
|
+
for (const handler of errorHandlers) {
|
|
130
|
+
handler(error);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
socket.on("dialogue:error", (error) => {
|
|
134
|
+
const err = new Error(`[${error.code}] ${error.message}`);
|
|
135
|
+
for (const handler of errorHandlers) {
|
|
136
|
+
handler(err);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
socket.on("dialogue:roomCreated", (room) => {
|
|
140
|
+
for (const handler of roomCreatedHandlers) {
|
|
141
|
+
handler(room);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
socket.on("dialogue:roomDeleted", (data) => {
|
|
145
|
+
const context = joinedRooms.get(data.roomId);
|
|
146
|
+
if (context) {
|
|
147
|
+
joinedRooms.delete(data.roomId);
|
|
148
|
+
}
|
|
149
|
+
for (const handler of roomDeletedHandlers) {
|
|
150
|
+
handler(data.roomId);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
socket.on("dialogue:history", (data) => {
|
|
154
|
+
for (const handler of historyHandlers) {
|
|
155
|
+
handler(data.roomId, data.events);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
};
|
|
159
|
+
setupSocketListeners();
|
|
160
|
+
return {
|
|
161
|
+
get userId() {
|
|
162
|
+
return userIdValue ?? "";
|
|
163
|
+
},
|
|
164
|
+
get connected() {
|
|
165
|
+
return connectionState === "connected";
|
|
166
|
+
},
|
|
167
|
+
get state() {
|
|
168
|
+
return connectionState;
|
|
169
|
+
},
|
|
170
|
+
connect() {
|
|
171
|
+
if (connectionState === "connected") {
|
|
172
|
+
return Promise.resolve();
|
|
173
|
+
}
|
|
174
|
+
return new Promise((resolve, reject) => {
|
|
175
|
+
const timeout = setTimeout(() => {
|
|
176
|
+
reject(new Error("Connection timeout"));
|
|
177
|
+
}, 1e4);
|
|
178
|
+
const cleanup = () => {
|
|
179
|
+
clearTimeout(timeout);
|
|
180
|
+
socket.off("dialogue:connected", onConnect);
|
|
181
|
+
socket.off("connect_error", onError);
|
|
182
|
+
};
|
|
183
|
+
const onConnect = () => {
|
|
184
|
+
cleanup();
|
|
185
|
+
resolve();
|
|
186
|
+
};
|
|
187
|
+
const onError = (error) => {
|
|
188
|
+
cleanup();
|
|
189
|
+
reject(error);
|
|
190
|
+
};
|
|
191
|
+
socket.once("dialogue:connected", onConnect);
|
|
192
|
+
socket.once("connect_error", onError);
|
|
193
|
+
if (!socket.connected) {
|
|
194
|
+
socket.connect();
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
},
|
|
198
|
+
disconnect() {
|
|
199
|
+
for (const [, context] of joinedRooms) {
|
|
200
|
+
context.leave();
|
|
201
|
+
}
|
|
202
|
+
joinedRooms.clear();
|
|
203
|
+
socket.disconnect();
|
|
204
|
+
},
|
|
205
|
+
join(roomId) {
|
|
206
|
+
const existing = joinedRooms.get(roomId);
|
|
207
|
+
if (existing) {
|
|
208
|
+
return Promise.resolve(existing);
|
|
209
|
+
}
|
|
210
|
+
return new Promise((resolve, reject) => {
|
|
211
|
+
const timeout = setTimeout(() => {
|
|
212
|
+
cleanup();
|
|
213
|
+
reject(new Error(`Timeout joining room '${roomId}'`));
|
|
214
|
+
}, 5e3);
|
|
215
|
+
const cleanup = () => {
|
|
216
|
+
clearTimeout(timeout);
|
|
217
|
+
socket.off("dialogue:joined", onJoined);
|
|
218
|
+
socket.off("dialogue:error", onError);
|
|
219
|
+
};
|
|
220
|
+
const onJoined = (result) => {
|
|
221
|
+
if (result.roomId !== roomId) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
cleanup();
|
|
225
|
+
const context = createRoomContext(
|
|
226
|
+
socket,
|
|
227
|
+
result.roomId,
|
|
228
|
+
result.roomName,
|
|
229
|
+
() => {
|
|
230
|
+
joinedRooms.delete(roomId);
|
|
231
|
+
}
|
|
232
|
+
);
|
|
233
|
+
joinedRooms.set(roomId, context);
|
|
234
|
+
resolve(context);
|
|
235
|
+
};
|
|
236
|
+
const onError = (error) => {
|
|
237
|
+
cleanup();
|
|
238
|
+
reject(new Error(`[${error.code}] ${error.message}`));
|
|
239
|
+
};
|
|
240
|
+
socket.on("dialogue:joined", onJoined);
|
|
241
|
+
socket.once("dialogue:error", onError);
|
|
242
|
+
socket.emit("dialogue:join", { roomId });
|
|
243
|
+
});
|
|
244
|
+
},
|
|
245
|
+
getRoom(roomId) {
|
|
246
|
+
return joinedRooms.get(roomId);
|
|
247
|
+
},
|
|
248
|
+
listRooms() {
|
|
249
|
+
return new Promise((resolve, reject) => {
|
|
250
|
+
const timeout = setTimeout(() => {
|
|
251
|
+
cleanup();
|
|
252
|
+
reject(new Error("Timeout listing rooms"));
|
|
253
|
+
}, 5e3);
|
|
254
|
+
const cleanup = () => {
|
|
255
|
+
clearTimeout(timeout);
|
|
256
|
+
socket.off("dialogue:rooms", onRooms);
|
|
257
|
+
};
|
|
258
|
+
const onRooms = (rooms) => {
|
|
259
|
+
cleanup();
|
|
260
|
+
resolve(rooms);
|
|
261
|
+
};
|
|
262
|
+
socket.once("dialogue:rooms", onRooms);
|
|
263
|
+
socket.emit("dialogue:listRooms");
|
|
264
|
+
});
|
|
265
|
+
},
|
|
266
|
+
createRoom(options) {
|
|
267
|
+
return new Promise((resolve, reject) => {
|
|
268
|
+
const timeout = setTimeout(() => {
|
|
269
|
+
cleanup();
|
|
270
|
+
reject(new Error("Timeout creating room"));
|
|
271
|
+
}, 5e3);
|
|
272
|
+
const cleanup = () => {
|
|
273
|
+
clearTimeout(timeout);
|
|
274
|
+
socket.off("dialogue:roomCreated", onCreated);
|
|
275
|
+
socket.off("dialogue:error", onError);
|
|
276
|
+
};
|
|
277
|
+
const onCreated = (room) => {
|
|
278
|
+
if (room.id === options.id) {
|
|
279
|
+
cleanup();
|
|
280
|
+
resolve(room);
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
const onError = (error) => {
|
|
284
|
+
cleanup();
|
|
285
|
+
reject(new Error(`[${error.code}] ${error.message}`));
|
|
286
|
+
};
|
|
287
|
+
socket.on("dialogue:roomCreated", onCreated);
|
|
288
|
+
socket.once("dialogue:error", onError);
|
|
289
|
+
socket.emit("dialogue:createRoom", {
|
|
290
|
+
id: options.id,
|
|
291
|
+
name: options.name,
|
|
292
|
+
description: options.description,
|
|
293
|
+
maxSize: options.maxSize
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
},
|
|
297
|
+
deleteRoom(roomId) {
|
|
298
|
+
return new Promise((resolve, reject) => {
|
|
299
|
+
const timeout = setTimeout(() => {
|
|
300
|
+
cleanup();
|
|
301
|
+
reject(new Error("Timeout deleting room"));
|
|
302
|
+
}, 5e3);
|
|
303
|
+
const cleanup = () => {
|
|
304
|
+
clearTimeout(timeout);
|
|
305
|
+
socket.off("dialogue:roomDeleted", onDeleted);
|
|
306
|
+
socket.off("dialogue:error", onError);
|
|
307
|
+
};
|
|
308
|
+
const onDeleted = (data) => {
|
|
309
|
+
if (data.roomId === roomId) {
|
|
310
|
+
cleanup();
|
|
311
|
+
resolve();
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
const onError = (error) => {
|
|
315
|
+
cleanup();
|
|
316
|
+
reject(new Error(`[${error.code}] ${error.message}`));
|
|
317
|
+
};
|
|
318
|
+
socket.on("dialogue:roomDeleted", onDeleted);
|
|
319
|
+
socket.once("dialogue:error", onError);
|
|
320
|
+
socket.emit("dialogue:deleteRoom", { roomId });
|
|
321
|
+
});
|
|
322
|
+
},
|
|
323
|
+
onRoomCreated(handler) {
|
|
324
|
+
roomCreatedHandlers.add(handler);
|
|
325
|
+
return () => {
|
|
326
|
+
roomCreatedHandlers.delete(handler);
|
|
327
|
+
};
|
|
328
|
+
},
|
|
329
|
+
onRoomDeleted(handler) {
|
|
330
|
+
roomDeletedHandlers.add(handler);
|
|
331
|
+
return () => {
|
|
332
|
+
roomDeletedHandlers.delete(handler);
|
|
333
|
+
};
|
|
334
|
+
},
|
|
335
|
+
onConnect(handler) {
|
|
336
|
+
connectHandlers.add(handler);
|
|
337
|
+
return () => {
|
|
338
|
+
connectHandlers.delete(handler);
|
|
339
|
+
};
|
|
340
|
+
},
|
|
341
|
+
onDisconnect(handler) {
|
|
342
|
+
disconnectHandlers.add(handler);
|
|
343
|
+
return () => {
|
|
344
|
+
disconnectHandlers.delete(handler);
|
|
345
|
+
};
|
|
346
|
+
},
|
|
347
|
+
onError(handler) {
|
|
348
|
+
errorHandlers.add(handler);
|
|
349
|
+
return () => {
|
|
350
|
+
errorHandlers.delete(handler);
|
|
351
|
+
};
|
|
352
|
+
},
|
|
353
|
+
onHistory(handler) {
|
|
354
|
+
historyHandlers.add(handler);
|
|
355
|
+
return () => {
|
|
356
|
+
historyHandlers.delete(handler);
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
export {
|
|
362
|
+
createDialogueClient,
|
|
363
|
+
createRoomContext
|
|
364
|
+
};
|
|
365
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../client/dialogue-client.ts","../../client/room-context.ts"],"sourcesContent":["import { io, type Socket } from \"socket.io-client\";\nimport { createRoomContext } from \"./room-context.ts\";\nimport type {\n ClientConfig,\n ConnectionResult,\n ConnectionState,\n CreateRoomOptions,\n DialogueError,\n EventMessage,\n HistoryResponse,\n JoinResult,\n RoomContext,\n RoomInfo,\n} from \"./types.ts\";\n\n/**\n * Dialogue client instance returned by createDialogueClient\n */\nexport interface DialogueClientInstance {\n /** User ID assigned by the server */\n readonly userId: string;\n /** Whether the client is connected to the server */\n readonly connected: boolean;\n /** Current connection state */\n readonly state: ConnectionState;\n\n /**\n * Connect to the server\n * @returns Promise that resolves when connected\n */\n connect(): Promise<void>;\n\n /**\n * Disconnect from the server\n */\n disconnect(): void;\n\n /**\n * Join a room\n * @param roomId - Room ID to join\n * @returns Promise resolving to RoomContext\n */\n join(roomId: string): Promise<RoomContext>;\n\n /**\n * Get a joined room context\n * @param roomId - Room ID\n * @returns RoomContext or undefined if not joined\n */\n getRoom(roomId: string): RoomContext | undefined;\n\n /**\n * List all available rooms on the server\n * @returns Promise resolving to array of room info\n */\n listRooms(): Promise<RoomInfo[]>;\n\n /**\n * Create a new room on the server\n * @param options - Room creation options\n * @returns Promise resolving to created room info\n */\n createRoom(options: CreateRoomOptions): Promise<RoomInfo>;\n\n /**\n * Delete a room on the server (only creator can delete)\n * @param roomId - Room ID to delete\n * @returns Promise resolving when deleted\n */\n deleteRoom(roomId: string): Promise<void>;\n\n /**\n * Register a handler for when a new room is created\n * @param handler - Called when a room is created\n * @returns Unsubscribe function\n */\n onRoomCreated(handler: (room: RoomInfo) => void): () => void;\n\n /**\n * Register a handler for when a room is deleted\n * @param handler - Called when a room is deleted\n * @returns Unsubscribe function\n */\n onRoomDeleted(handler: (roomId: string) => void): () => void;\n\n /**\n * Register a connection handler\n * @param handler - Called when connected\n * @returns Unsubscribe function\n */\n onConnect(handler: () => void): () => void;\n\n /**\n * Register a disconnection handler\n * @param handler - Called when disconnected with reason\n * @returns Unsubscribe function\n */\n onDisconnect(handler: (reason: string) => void): () => void;\n\n /**\n * Register an error handler\n * @param handler - Called on errors\n * @returns Unsubscribe function\n */\n onError(handler: (error: Error) => void): () => void;\n\n /**\n * Register a handler for history events (sent when joining a room with syncHistoryOnJoin)\n * @param handler - Called when history is received\n * @returns Unsubscribe function\n */\n onHistory(\n handler: (roomId: string, events: EventMessage[]) => void\n ): () => void;\n}\n\n/**\n * Creates a Dialogue client for connecting to a Dialogue server from the frontend.\n * Manages WebSocket connection, room membership, and event handling.\n *\n * @param config - Client configuration\n * @returns DialogueClientInstance\n *\n * @example\n * const client = createDialogueClient({\n * url: 'ws://localhost:3000',\n * auth: { userId: 'user-123', token: 'jwt-token' }\n * })\n *\n * await client.connect()\n *\n * const chat = await client.join('chat')\n * chat.on('message', (msg) => console.log(msg.data))\n * chat.trigger('message', { text: 'Hello!' })\n */\nexport function createDialogueClient(\n config: ClientConfig\n): DialogueClientInstance {\n const socket: Socket = io(config.url, {\n auth: config.auth,\n autoConnect: config.autoConnect ?? true,\n reconnection: config.reconnection ?? true,\n reconnectionAttempts: config.reconnectionAttempts ?? 5,\n });\n\n let connectionState: ConnectionState = \"disconnected\";\n let userIdValue: string | null = null;\n\n const joinedRooms = new Map<string, RoomContext>();\n const connectHandlers = new Set<() => void>();\n const disconnectHandlers = new Set<(reason: string) => void>();\n const errorHandlers = new Set<(error: Error) => void>();\n const roomCreatedHandlers = new Set<(room: RoomInfo) => void>();\n const roomDeletedHandlers = new Set<(roomId: string) => void>();\n const historyHandlers = new Set<\n (roomId: string, events: EventMessage[]) => void\n >();\n\n /** Sets up internal socket event listeners */\n const setupSocketListeners = (): void => {\n socket.on(\"connect\", () => {\n connectionState = \"connecting\";\n });\n\n socket.on(\"dialogue:connected\", (result: ConnectionResult) => {\n connectionState = \"connected\";\n userIdValue = result.userId;\n\n for (const handler of connectHandlers) {\n handler();\n }\n });\n\n socket.on(\"disconnect\", (reason) => {\n connectionState = \"disconnected\";\n\n for (const handler of disconnectHandlers) {\n handler(reason);\n }\n });\n\n socket.on(\"connect_error\", (error) => {\n for (const handler of errorHandlers) {\n handler(error);\n }\n });\n\n socket.on(\"dialogue:error\", (error: DialogueError) => {\n const err = new Error(`[${error.code}] ${error.message}`);\n for (const handler of errorHandlers) {\n handler(err);\n }\n });\n\n socket.on(\"dialogue:roomCreated\", (room: RoomInfo) => {\n for (const handler of roomCreatedHandlers) {\n handler(room);\n }\n });\n\n socket.on(\"dialogue:roomDeleted\", (data: { roomId: string }) => {\n // If we're in this room, clean up\n const context = joinedRooms.get(data.roomId);\n if (context) {\n joinedRooms.delete(data.roomId);\n }\n\n for (const handler of roomDeletedHandlers) {\n handler(data.roomId);\n }\n });\n\n // Handle history sync on join\n socket.on(\"dialogue:history\", (data: HistoryResponse) => {\n for (const handler of historyHandlers) {\n handler(data.roomId, data.events);\n }\n });\n };\n\n // Initialize socket listeners\n setupSocketListeners();\n\n return {\n get userId(): string {\n return userIdValue ?? \"\";\n },\n\n get connected(): boolean {\n return connectionState === \"connected\";\n },\n\n get state(): ConnectionState {\n return connectionState;\n },\n\n connect(): Promise<void> {\n if (connectionState === \"connected\") {\n return Promise.resolve();\n }\n\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Connection timeout\"));\n }, 10_000);\n\n const cleanup = () => {\n clearTimeout(timeout);\n socket.off(\"dialogue:connected\", onConnect);\n socket.off(\"connect_error\", onError);\n };\n\n const onConnect = () => {\n cleanup();\n resolve();\n };\n\n const onError = (error: Error) => {\n cleanup();\n reject(error);\n };\n\n socket.once(\"dialogue:connected\", onConnect);\n socket.once(\"connect_error\", onError);\n\n if (!socket.connected) {\n socket.connect();\n }\n });\n },\n\n disconnect(): void {\n for (const [, context] of joinedRooms) {\n context.leave();\n }\n joinedRooms.clear();\n socket.disconnect();\n },\n\n join(roomId: string): Promise<RoomContext> {\n const existing = joinedRooms.get(roomId);\n if (existing) {\n return Promise.resolve(existing);\n }\n\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error(`Timeout joining room '${roomId}'`));\n }, 5000);\n\n const cleanup = () => {\n clearTimeout(timeout);\n socket.off(\"dialogue:joined\", onJoined);\n socket.off(\"dialogue:error\", onError);\n };\n\n const onJoined = (result: JoinResult) => {\n if (result.roomId !== roomId) {\n return;\n }\n\n cleanup();\n\n const context = createRoomContext(\n socket,\n result.roomId,\n result.roomName,\n () => {\n joinedRooms.delete(roomId);\n }\n );\n\n joinedRooms.set(roomId, context);\n resolve(context);\n };\n\n const onError = (error: DialogueError) => {\n cleanup();\n reject(new Error(`[${error.code}] ${error.message}`));\n };\n\n socket.on(\"dialogue:joined\", onJoined);\n socket.once(\"dialogue:error\", onError);\n\n socket.emit(\"dialogue:join\", { roomId });\n });\n },\n\n getRoom(roomId: string): RoomContext | undefined {\n return joinedRooms.get(roomId);\n },\n\n listRooms(): Promise<RoomInfo[]> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error(\"Timeout listing rooms\"));\n }, 5000);\n\n const cleanup = () => {\n clearTimeout(timeout);\n socket.off(\"dialogue:rooms\", onRooms);\n };\n\n const onRooms = (rooms: RoomInfo[]) => {\n cleanup();\n resolve(rooms);\n };\n\n socket.once(\"dialogue:rooms\", onRooms);\n socket.emit(\"dialogue:listRooms\");\n });\n },\n\n createRoom(options: CreateRoomOptions): Promise<RoomInfo> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error(\"Timeout creating room\"));\n }, 5000);\n\n const cleanup = () => {\n clearTimeout(timeout);\n socket.off(\"dialogue:roomCreated\", onCreated);\n socket.off(\"dialogue:error\", onError);\n };\n\n const onCreated = (room: RoomInfo) => {\n // Only resolve if this is the room we created\n if (room.id === options.id) {\n cleanup();\n resolve(room);\n }\n };\n\n const onError = (error: DialogueError) => {\n cleanup();\n reject(new Error(`[${error.code}] ${error.message}`));\n };\n\n socket.on(\"dialogue:roomCreated\", onCreated);\n socket.once(\"dialogue:error\", onError);\n\n socket.emit(\"dialogue:createRoom\", {\n id: options.id,\n name: options.name,\n description: options.description,\n maxSize: options.maxSize,\n });\n });\n },\n\n deleteRoom(roomId: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error(\"Timeout deleting room\"));\n }, 5000);\n\n const cleanup = () => {\n clearTimeout(timeout);\n socket.off(\"dialogue:roomDeleted\", onDeleted);\n socket.off(\"dialogue:error\", onError);\n };\n\n const onDeleted = (data: { roomId: string }) => {\n if (data.roomId === roomId) {\n cleanup();\n resolve();\n }\n };\n\n const onError = (error: DialogueError) => {\n cleanup();\n reject(new Error(`[${error.code}] ${error.message}`));\n };\n\n socket.on(\"dialogue:roomDeleted\", onDeleted);\n socket.once(\"dialogue:error\", onError);\n\n socket.emit(\"dialogue:deleteRoom\", { roomId });\n });\n },\n\n onRoomCreated(handler: (room: RoomInfo) => void): () => void {\n roomCreatedHandlers.add(handler);\n return () => {\n roomCreatedHandlers.delete(handler);\n };\n },\n\n onRoomDeleted(handler: (roomId: string) => void): () => void {\n roomDeletedHandlers.add(handler);\n return () => {\n roomDeletedHandlers.delete(handler);\n };\n },\n\n onConnect(handler: () => void): () => void {\n connectHandlers.add(handler);\n return () => {\n connectHandlers.delete(handler);\n };\n },\n\n onDisconnect(handler: (reason: string) => void): () => void {\n disconnectHandlers.add(handler);\n return () => {\n disconnectHandlers.delete(handler);\n };\n },\n\n onError(handler: (error: Error) => void): () => void {\n errorHandlers.add(handler);\n return () => {\n errorHandlers.delete(handler);\n };\n },\n\n onHistory(\n handler: (roomId: string, events: EventMessage[]) => void\n ): () => void {\n historyHandlers.add(handler);\n return () => {\n historyHandlers.delete(handler);\n };\n },\n };\n}\n","import type { Socket } from \"socket.io-client\";\nimport type {\n EventHandler,\n EventMessage,\n HistoryResponsePaginated,\n RoomContext,\n WildcardHandler,\n} from \"./types.ts\";\n\n/**\n * Creates a room context for a joined room.\n * Manages event subscriptions and triggers for a specific room.\n *\n * @param socket - Socket.IO client socket\n * @param roomId - Room identifier\n * @param roomName - Human-readable room name\n * @param onLeave - Callback when leaving room\n * @returns RoomContext with methods for interacting with the room\n */\nexport function createRoomContext(\n socket: Socket,\n roomId: string,\n roomName: string,\n onLeave: () => void\n): RoomContext {\n const eventHandlers = new Map<string, Set<EventHandler>>();\n const wildcardHandlers = new Set<WildcardHandler>();\n\n /**\n * Internal handler for dialogue:event messages\n * Routes events to registered handlers\n */\n const eventListener = (msg: EventMessage<unknown>) => {\n if (msg.roomId !== roomId) {\n return;\n }\n\n const handlers = eventHandlers.get(msg.event);\n if (handlers) {\n for (const handler of handlers) {\n handler(msg);\n }\n }\n\n for (const handler of wildcardHandlers) {\n handler(msg.event, msg);\n }\n };\n\n socket.on(\"dialogue:event\", eventListener);\n\n const context: RoomContext = {\n roomId,\n roomName,\n\n trigger<T>(\n eventName: string,\n data: T,\n meta?: Record<string, unknown>\n ): void {\n socket.emit(\"dialogue:trigger\", {\n roomId,\n event: eventName,\n data,\n ...(meta && { meta }),\n });\n },\n\n on<T>(\n eventName: string,\n handler: (msg: EventMessage<T>) => void\n ): () => void {\n let handlers = eventHandlers.get(eventName);\n if (!handlers) {\n handlers = new Set();\n eventHandlers.set(eventName, handlers);\n }\n\n handlers.add(handler as EventHandler);\n\n return () => {\n handlers?.delete(handler as EventHandler);\n if (handlers?.size === 0) {\n eventHandlers.delete(eventName);\n }\n };\n },\n\n onAny(\n handler: (eventName: string, msg: EventMessage<unknown>) => void\n ): () => void {\n wildcardHandlers.add(handler);\n\n return () => {\n wildcardHandlers.delete(handler);\n };\n },\n\n subscribe(eventName: string): void {\n socket.emit(\"dialogue:subscribe\", { roomId, eventName });\n },\n\n subscribeAll(): void {\n socket.emit(\"dialogue:subscribeAll\", { roomId });\n },\n\n unsubscribe(eventName: string): void {\n socket.emit(\"dialogue:unsubscribe\", { roomId, eventName });\n },\n\n getHistory<T = unknown>(\n eventName: string,\n start = 0,\n end = 50\n ): Promise<EventMessage<T>[]> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n cleanup();\n reject(new Error(`Timeout getting history for '${eventName}'`));\n }, 5000);\n\n const cleanup = () => {\n clearTimeout(timeout);\n socket.off(\"dialogue:historyResponse\", onResponse);\n };\n\n const onResponse = (data: HistoryResponsePaginated) => {\n // Only resolve if this matches our request\n if (data.roomId === roomId && data.eventName === eventName) {\n cleanup();\n resolve(data.events as EventMessage<T>[]);\n }\n };\n\n socket.on(\"dialogue:historyResponse\", onResponse);\n socket.emit(\"dialogue:getHistory\", { roomId, eventName, start, end });\n });\n },\n\n leave(): void {\n socket.off(\"dialogue:event\", eventListener);\n eventHandlers.clear();\n wildcardHandlers.clear();\n\n socket.emit(\"dialogue:leave\", { roomId });\n onLeave();\n },\n };\n\n return context;\n}\n"],"mappings":";AAAA,SAAS,UAAuB;;;ACmBzB,SAAS,kBACd,QACA,QACA,UACA,SACa;AACb,QAAM,gBAAgB,oBAAI,IAA+B;AACzD,QAAM,mBAAmB,oBAAI,IAAqB;AAMlD,QAAM,gBAAgB,CAAC,QAA+B;AACpD,QAAI,IAAI,WAAW,QAAQ;AACzB;AAAA,IACF;AAEA,UAAM,WAAW,cAAc,IAAI,IAAI,KAAK;AAC5C,QAAI,UAAU;AACZ,iBAAW,WAAW,UAAU;AAC9B,gBAAQ,GAAG;AAAA,MACb;AAAA,IACF;AAEA,eAAW,WAAW,kBAAkB;AACtC,cAAQ,IAAI,OAAO,GAAG;AAAA,IACxB;AAAA,EACF;AAEA,SAAO,GAAG,kBAAkB,aAAa;AAEzC,QAAM,UAAuB;AAAA,IAC3B;AAAA,IACA;AAAA,IAEA,QACE,WACA,MACA,MACM;AACN,aAAO,KAAK,oBAAoB;AAAA,QAC9B;AAAA,QACA,OAAO;AAAA,QACP;AAAA,QACA,GAAI,QAAQ,EAAE,KAAK;AAAA,MACrB,CAAC;AAAA,IACH;AAAA,IAEA,GACE,WACA,SACY;AACZ,UAAI,WAAW,cAAc,IAAI,SAAS;AAC1C,UAAI,CAAC,UAAU;AACb,mBAAW,oBAAI,IAAI;AACnB,sBAAc,IAAI,WAAW,QAAQ;AAAA,MACvC;AAEA,eAAS,IAAI,OAAuB;AAEpC,aAAO,MAAM;AACX,kBAAU,OAAO,OAAuB;AACxC,YAAI,UAAU,SAAS,GAAG;AACxB,wBAAc,OAAO,SAAS;AAAA,QAChC;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MACE,SACY;AACZ,uBAAiB,IAAI,OAAO;AAE5B,aAAO,MAAM;AACX,yBAAiB,OAAO,OAAO;AAAA,MACjC;AAAA,IACF;AAAA,IAEA,UAAU,WAAyB;AACjC,aAAO,KAAK,sBAAsB,EAAE,QAAQ,UAAU,CAAC;AAAA,IACzD;AAAA,IAEA,eAAqB;AACnB,aAAO,KAAK,yBAAyB,EAAE,OAAO,CAAC;AAAA,IACjD;AAAA,IAEA,YAAY,WAAyB;AACnC,aAAO,KAAK,wBAAwB,EAAE,QAAQ,UAAU,CAAC;AAAA,IAC3D;AAAA,IAEA,WACE,WACA,QAAQ,GACR,MAAM,IACsB;AAC5B,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAM,UAAU,WAAW,MAAM;AAC/B,kBAAQ;AACR,iBAAO,IAAI,MAAM,gCAAgC,SAAS,GAAG,CAAC;AAAA,QAChE,GAAG,GAAI;AAEP,cAAM,UAAU,MAAM;AACpB,uBAAa,OAAO;AACpB,iBAAO,IAAI,4BAA4B,UAAU;AAAA,QACnD;AAEA,cAAM,aAAa,CAAC,SAAmC;AAErD,cAAI,KAAK,WAAW,UAAU,KAAK,cAAc,WAAW;AAC1D,oBAAQ;AACR,oBAAQ,KAAK,MAA2B;AAAA,UAC1C;AAAA,QACF;AAEA,eAAO,GAAG,4BAA4B,UAAU;AAChD,eAAO,KAAK,uBAAuB,EAAE,QAAQ,WAAW,OAAO,IAAI,CAAC;AAAA,MACtE,CAAC;AAAA,IACH;AAAA,IAEA,QAAc;AACZ,aAAO,IAAI,kBAAkB,aAAa;AAC1C,oBAAc,MAAM;AACpB,uBAAiB,MAAM;AAEvB,aAAO,KAAK,kBAAkB,EAAE,OAAO,CAAC;AACxC,cAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO;AACT;;;ADfO,SAAS,qBACd,QACwB;AACxB,QAAM,SAAiB,GAAG,OAAO,KAAK;AAAA,IACpC,MAAM,OAAO;AAAA,IACb,aAAa,OAAO,eAAe;AAAA,IACnC,cAAc,OAAO,gBAAgB;AAAA,IACrC,sBAAsB,OAAO,wBAAwB;AAAA,EACvD,CAAC;AAED,MAAI,kBAAmC;AACvC,MAAI,cAA6B;AAEjC,QAAM,cAAc,oBAAI,IAAyB;AACjD,QAAM,kBAAkB,oBAAI,IAAgB;AAC5C,QAAM,qBAAqB,oBAAI,IAA8B;AAC7D,QAAM,gBAAgB,oBAAI,IAA4B;AACtD,QAAM,sBAAsB,oBAAI,IAA8B;AAC9D,QAAM,sBAAsB,oBAAI,IAA8B;AAC9D,QAAM,kBAAkB,oBAAI,IAE1B;AAGF,QAAM,uBAAuB,MAAY;AACvC,WAAO,GAAG,WAAW,MAAM;AACzB,wBAAkB;AAAA,IACpB,CAAC;AAED,WAAO,GAAG,sBAAsB,CAAC,WAA6B;AAC5D,wBAAkB;AAClB,oBAAc,OAAO;AAErB,iBAAW,WAAW,iBAAiB;AACrC,gBAAQ;AAAA,MACV;AAAA,IACF,CAAC;AAED,WAAO,GAAG,cAAc,CAAC,WAAW;AAClC,wBAAkB;AAElB,iBAAW,WAAW,oBAAoB;AACxC,gBAAQ,MAAM;AAAA,MAChB;AAAA,IACF,CAAC;AAED,WAAO,GAAG,iBAAiB,CAAC,UAAU;AACpC,iBAAW,WAAW,eAAe;AACnC,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF,CAAC;AAED,WAAO,GAAG,kBAAkB,CAAC,UAAyB;AACpD,YAAM,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,MAAM,OAAO,EAAE;AACxD,iBAAW,WAAW,eAAe;AACnC,gBAAQ,GAAG;AAAA,MACb;AAAA,IACF,CAAC;AAED,WAAO,GAAG,wBAAwB,CAAC,SAAmB;AACpD,iBAAW,WAAW,qBAAqB;AACzC,gBAAQ,IAAI;AAAA,MACd;AAAA,IACF,CAAC;AAED,WAAO,GAAG,wBAAwB,CAAC,SAA6B;AAE9D,YAAM,UAAU,YAAY,IAAI,KAAK,MAAM;AAC3C,UAAI,SAAS;AACX,oBAAY,OAAO,KAAK,MAAM;AAAA,MAChC;AAEA,iBAAW,WAAW,qBAAqB;AACzC,gBAAQ,KAAK,MAAM;AAAA,MACrB;AAAA,IACF,CAAC;AAGD,WAAO,GAAG,oBAAoB,CAAC,SAA0B;AACvD,iBAAW,WAAW,iBAAiB;AACrC,gBAAQ,KAAK,QAAQ,KAAK,MAAM;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAGA,uBAAqB;AAErB,SAAO;AAAA,IACL,IAAI,SAAiB;AACnB,aAAO,eAAe;AAAA,IACxB;AAAA,IAEA,IAAI,YAAqB;AACvB,aAAO,oBAAoB;AAAA,IAC7B;AAAA,IAEA,IAAI,QAAyB;AAC3B,aAAO;AAAA,IACT;AAAA,IAEA,UAAyB;AACvB,UAAI,oBAAoB,aAAa;AACnC,eAAO,QAAQ,QAAQ;AAAA,MACzB;AAEA,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAM,UAAU,WAAW,MAAM;AAC/B,iBAAO,IAAI,MAAM,oBAAoB,CAAC;AAAA,QACxC,GAAG,GAAM;AAET,cAAM,UAAU,MAAM;AACpB,uBAAa,OAAO;AACpB,iBAAO,IAAI,sBAAsB,SAAS;AAC1C,iBAAO,IAAI,iBAAiB,OAAO;AAAA,QACrC;AAEA,cAAM,YAAY,MAAM;AACtB,kBAAQ;AACR,kBAAQ;AAAA,QACV;AAEA,cAAM,UAAU,CAAC,UAAiB;AAChC,kBAAQ;AACR,iBAAO,KAAK;AAAA,QACd;AAEA,eAAO,KAAK,sBAAsB,SAAS;AAC3C,eAAO,KAAK,iBAAiB,OAAO;AAEpC,YAAI,CAAC,OAAO,WAAW;AACrB,iBAAO,QAAQ;AAAA,QACjB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEA,aAAmB;AACjB,iBAAW,CAAC,EAAE,OAAO,KAAK,aAAa;AACrC,gBAAQ,MAAM;AAAA,MAChB;AACA,kBAAY,MAAM;AAClB,aAAO,WAAW;AAAA,IACpB;AAAA,IAEA,KAAK,QAAsC;AACzC,YAAM,WAAW,YAAY,IAAI,MAAM;AACvC,UAAI,UAAU;AACZ,eAAO,QAAQ,QAAQ,QAAQ;AAAA,MACjC;AAEA,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAM,UAAU,WAAW,MAAM;AAC/B,kBAAQ;AACR,iBAAO,IAAI,MAAM,yBAAyB,MAAM,GAAG,CAAC;AAAA,QACtD,GAAG,GAAI;AAEP,cAAM,UAAU,MAAM;AACpB,uBAAa,OAAO;AACpB,iBAAO,IAAI,mBAAmB,QAAQ;AACtC,iBAAO,IAAI,kBAAkB,OAAO;AAAA,QACtC;AAEA,cAAM,WAAW,CAAC,WAAuB;AACvC,cAAI,OAAO,WAAW,QAAQ;AAC5B;AAAA,UACF;AAEA,kBAAQ;AAER,gBAAM,UAAU;AAAA,YACd;AAAA,YACA,OAAO;AAAA,YACP,OAAO;AAAA,YACP,MAAM;AACJ,0BAAY,OAAO,MAAM;AAAA,YAC3B;AAAA,UACF;AAEA,sBAAY,IAAI,QAAQ,OAAO;AAC/B,kBAAQ,OAAO;AAAA,QACjB;AAEA,cAAM,UAAU,CAAC,UAAyB;AACxC,kBAAQ;AACR,iBAAO,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,MAAM,OAAO,EAAE,CAAC;AAAA,QACtD;AAEA,eAAO,GAAG,mBAAmB,QAAQ;AACrC,eAAO,KAAK,kBAAkB,OAAO;AAErC,eAAO,KAAK,iBAAiB,EAAE,OAAO,CAAC;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,IAEA,QAAQ,QAAyC;AAC/C,aAAO,YAAY,IAAI,MAAM;AAAA,IAC/B;AAAA,IAEA,YAAiC;AAC/B,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAM,UAAU,WAAW,MAAM;AAC/B,kBAAQ;AACR,iBAAO,IAAI,MAAM,uBAAuB,CAAC;AAAA,QAC3C,GAAG,GAAI;AAEP,cAAM,UAAU,MAAM;AACpB,uBAAa,OAAO;AACpB,iBAAO,IAAI,kBAAkB,OAAO;AAAA,QACtC;AAEA,cAAM,UAAU,CAAC,UAAsB;AACrC,kBAAQ;AACR,kBAAQ,KAAK;AAAA,QACf;AAEA,eAAO,KAAK,kBAAkB,OAAO;AACrC,eAAO,KAAK,oBAAoB;AAAA,MAClC,CAAC;AAAA,IACH;AAAA,IAEA,WAAW,SAA+C;AACxD,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAM,UAAU,WAAW,MAAM;AAC/B,kBAAQ;AACR,iBAAO,IAAI,MAAM,uBAAuB,CAAC;AAAA,QAC3C,GAAG,GAAI;AAEP,cAAM,UAAU,MAAM;AACpB,uBAAa,OAAO;AACpB,iBAAO,IAAI,wBAAwB,SAAS;AAC5C,iBAAO,IAAI,kBAAkB,OAAO;AAAA,QACtC;AAEA,cAAM,YAAY,CAAC,SAAmB;AAEpC,cAAI,KAAK,OAAO,QAAQ,IAAI;AAC1B,oBAAQ;AACR,oBAAQ,IAAI;AAAA,UACd;AAAA,QACF;AAEA,cAAM,UAAU,CAAC,UAAyB;AACxC,kBAAQ;AACR,iBAAO,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,MAAM,OAAO,EAAE,CAAC;AAAA,QACtD;AAEA,eAAO,GAAG,wBAAwB,SAAS;AAC3C,eAAO,KAAK,kBAAkB,OAAO;AAErC,eAAO,KAAK,uBAAuB;AAAA,UACjC,IAAI,QAAQ;AAAA,UACZ,MAAM,QAAQ;AAAA,UACd,aAAa,QAAQ;AAAA,UACrB,SAAS,QAAQ;AAAA,QACnB,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAAA,IAEA,WAAW,QAA+B;AACxC,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAM,UAAU,WAAW,MAAM;AAC/B,kBAAQ;AACR,iBAAO,IAAI,MAAM,uBAAuB,CAAC;AAAA,QAC3C,GAAG,GAAI;AAEP,cAAM,UAAU,MAAM;AACpB,uBAAa,OAAO;AACpB,iBAAO,IAAI,wBAAwB,SAAS;AAC5C,iBAAO,IAAI,kBAAkB,OAAO;AAAA,QACtC;AAEA,cAAM,YAAY,CAAC,SAA6B;AAC9C,cAAI,KAAK,WAAW,QAAQ;AAC1B,oBAAQ;AACR,oBAAQ;AAAA,UACV;AAAA,QACF;AAEA,cAAM,UAAU,CAAC,UAAyB;AACxC,kBAAQ;AACR,iBAAO,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,MAAM,OAAO,EAAE,CAAC;AAAA,QACtD;AAEA,eAAO,GAAG,wBAAwB,SAAS;AAC3C,eAAO,KAAK,kBAAkB,OAAO;AAErC,eAAO,KAAK,uBAAuB,EAAE,OAAO,CAAC;AAAA,MAC/C,CAAC;AAAA,IACH;AAAA,IAEA,cAAc,SAA+C;AAC3D,0BAAoB,IAAI,OAAO;AAC/B,aAAO,MAAM;AACX,4BAAoB,OAAO,OAAO;AAAA,MACpC;AAAA,IACF;AAAA,IAEA,cAAc,SAA+C;AAC3D,0BAAoB,IAAI,OAAO;AAC/B,aAAO,MAAM;AACX,4BAAoB,OAAO,OAAO;AAAA,MACpC;AAAA,IACF;AAAA,IAEA,UAAU,SAAiC;AACzC,sBAAgB,IAAI,OAAO;AAC3B,aAAO,MAAM;AACX,wBAAgB,OAAO,OAAO;AAAA,MAChC;AAAA,IACF;AAAA,IAEA,aAAa,SAA+C;AAC1D,yBAAmB,IAAI,OAAO;AAC9B,aAAO,MAAM;AACX,2BAAmB,OAAO,OAAO;AAAA,MACnC;AAAA,IACF;AAAA,IAEA,QAAQ,SAA6C;AACnD,oBAAc,IAAI,OAAO;AACzB,aAAO,MAAM;AACX,sBAAc,OAAO,OAAO;AAAA,MAC9B;AAAA,IACF;AAAA,IAEA,UACE,SACY;AACZ,sBAAgB,IAAI,OAAO;AAC3B,aAAO,MAAM;AACX,wBAAgB,OAAO,OAAO;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|