@crowdedkingdomstudios/crowdyjs 1.0.7 → 2.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.
Files changed (68) hide show
  1. package/README.md +439 -12
  2. package/dist/auth-state.d.ts +21 -0
  3. package/dist/auth-state.d.ts.map +1 -0
  4. package/dist/auth-state.js +30 -0
  5. package/dist/client.d.ts +27 -21
  6. package/dist/client.d.ts.map +1 -1
  7. package/dist/client.js +27 -196
  8. package/dist/crowdy-client.d.ts +44 -24
  9. package/dist/crowdy-client.d.ts.map +1 -1
  10. package/dist/crowdy-client.js +42 -81
  11. package/dist/domains/actors.d.ts +22 -0
  12. package/dist/domains/actors.d.ts.map +1 -0
  13. package/dist/domains/actors.js +42 -0
  14. package/dist/domains/appAccess.d.ts +23 -0
  15. package/dist/domains/appAccess.d.ts.map +1 -0
  16. package/dist/domains/appAccess.js +42 -0
  17. package/dist/domains/apps.d.ts +27 -0
  18. package/dist/domains/apps.d.ts.map +1 -0
  19. package/dist/domains/apps.js +49 -0
  20. package/dist/domains/auth.d.ts +32 -0
  21. package/dist/domains/auth.d.ts.map +1 -0
  22. package/dist/domains/auth.js +70 -0
  23. package/dist/domains/billing.d.ts +17 -0
  24. package/dist/domains/billing.d.ts.map +1 -0
  25. package/dist/domains/billing.js +31 -0
  26. package/dist/domains/chunks.d.ts +20 -0
  27. package/dist/domains/chunks.d.ts.map +1 -0
  28. package/dist/domains/chunks.js +40 -0
  29. package/dist/domains/organizations.d.ts +33 -0
  30. package/dist/domains/organizations.d.ts.map +1 -0
  31. package/dist/domains/organizations.js +90 -0
  32. package/dist/domains/payments.d.ts +20 -0
  33. package/dist/domains/payments.d.ts.map +1 -0
  34. package/dist/domains/payments.js +28 -0
  35. package/dist/domains/quotas.d.ts +20 -0
  36. package/dist/domains/quotas.d.ts.map +1 -0
  37. package/dist/domains/quotas.js +34 -0
  38. package/dist/domains/serverStatus.d.ts +21 -0
  39. package/dist/domains/serverStatus.d.ts.map +1 -0
  40. package/dist/domains/serverStatus.js +32 -0
  41. package/dist/domains/state.d.ts +16 -0
  42. package/dist/domains/state.d.ts.map +1 -0
  43. package/dist/domains/state.js +27 -0
  44. package/dist/domains/teleport.d.ts +13 -0
  45. package/dist/domains/teleport.d.ts.map +1 -0
  46. package/dist/domains/teleport.js +15 -0
  47. package/dist/domains/udp.d.ts +32 -0
  48. package/dist/domains/udp.d.ts.map +1 -0
  49. package/dist/domains/udp.js +55 -0
  50. package/dist/domains/users.d.ts +24 -0
  51. package/dist/domains/users.d.ts.map +1 -0
  52. package/dist/domains/users.js +53 -0
  53. package/dist/domains/voxels.d.ts +17 -0
  54. package/dist/domains/voxels.d.ts.map +1 -0
  55. package/dist/domains/voxels.js +31 -0
  56. package/dist/generated/graphql.d.ts +3571 -0
  57. package/dist/generated/graphql.d.ts.map +1 -0
  58. package/dist/generated/graphql.js +181 -0
  59. package/dist/index.d.ts +33 -3
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +34 -1
  62. package/dist/subscriptions.d.ts +36 -18
  63. package/dist/subscriptions.d.ts.map +1 -1
  64. package/dist/subscriptions.js +95 -181
  65. package/dist/types.d.ts +20 -17
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/types.js +3 -3
  68. package/package.json +12 -1
package/dist/client.js CHANGED
@@ -1,28 +1,46 @@
1
1
  /**
2
- * Core GraphQL client for HTTP queries and mutations
2
+ * Minimal HTTP GraphQL client. Reads its bearer token from `AuthState` so the
3
+ * WebSocket subscription manager and HTTP client always agree on who's
4
+ * authenticated. The `login` / `register` / `connectUdpProxy` /
5
+ * `sendActorUpdate` / etc. shortcuts that used to live here are gone -
6
+ * everything goes through the typed sub-clients on `CrowdyClient` (e.g.
7
+ * `client.auth.login`, `client.udp.sendActorUpdate`).
3
8
  */
9
+ import { print } from 'graphql';
4
10
  export class GraphQLClient {
5
- constructor(config = {}) {
6
- this.token = null;
7
- this.graphqlEndpoint = config.graphqlEndpoint || 'http://localhost:3000/graphql';
11
+ constructor(config = {}, authState) {
12
+ this.graphqlEndpoint =
13
+ config.graphqlEndpoint || 'http://localhost:3000/graphql';
8
14
  this.timeout = config.timeout || 60000;
15
+ this.authState = authState;
9
16
  }
10
- setAuthToken(token) {
11
- this.token = token;
17
+ getEndpoint() {
18
+ return this.graphqlEndpoint;
12
19
  }
13
- getAuthToken() {
14
- return this.token;
20
+ /**
21
+ * Execute a typed GraphQL operation produced by codegen and return the
22
+ * `data` payload. Throws on transport errors, GraphQL errors, or timeouts.
23
+ */
24
+ async request(document, variables) {
25
+ const queryStr = print(document);
26
+ return this.query(queryStr, (variables ?? {}));
15
27
  }
28
+ /**
29
+ * Internal escape hatch for raw query strings (used by hand-written
30
+ * adapters that haven't migrated to typed documents yet). Prefer
31
+ * `request()` with a `TypedDocumentNode`.
32
+ */
16
33
  async query(query, variables = {}) {
17
34
  const controller = new AbortController();
18
35
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
36
+ const token = this.authState.getToken();
19
37
  try {
20
38
  const requestBody = { query, variables };
21
39
  const response = await fetch(this.graphqlEndpoint, {
22
40
  method: 'POST',
23
41
  headers: {
24
42
  'Content-Type': 'application/json',
25
- ...(this.token && { Authorization: `Bearer ${this.token}` }),
43
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
26
44
  },
27
45
  body: JSON.stringify(requestBody),
28
46
  signal: controller.signal,
@@ -38,7 +56,6 @@ export class GraphQLClient {
38
56
  const errorMessage = Array.isArray(error.message)
39
57
  ? error.message.join(', ')
40
58
  : error.message;
41
- console.error('GraphQL error:', error);
42
59
  throw new Error(errorMessage);
43
60
  }
44
61
  return result.data;
@@ -54,190 +71,4 @@ export class GraphQLClient {
54
71
  throw new Error(`Network error: ${error}`);
55
72
  }
56
73
  }
57
- async login(email, password) {
58
- const data = await this.query(`
59
- mutation Login($input: LoginUserInput!) {
60
- login(loginUserInput: $input) {
61
- token
62
- gameTokenId
63
- user {
64
- userId
65
- email
66
- gamertag
67
- }
68
- }
69
- }
70
- `, {
71
- input: { email, password },
72
- });
73
- if (data.login?.token) {
74
- this.setAuthToken(data.login.token);
75
- return data.login;
76
- }
77
- throw new Error('Login failed');
78
- }
79
- async register(email, password, gamertag) {
80
- const data = await this.query(`
81
- mutation Register($input: RegisterUserInput!) {
82
- register(registerUserInput: $input) {
83
- token
84
- gameTokenId
85
- user {
86
- userId
87
- email
88
- gamertag
89
- }
90
- }
91
- }
92
- `, {
93
- input: { email, password, gamertag },
94
- });
95
- if (data.register?.token) {
96
- this.setAuthToken(data.register.token);
97
- return data.register;
98
- }
99
- throw new Error('Registration failed');
100
- }
101
- async connectUdpProxy() {
102
- const data = await this.query(`
103
- mutation ConnectUdpProxy {
104
- connectUdpProxy {
105
- connected
106
- serverIp6
107
- serverClientPort
108
- lastMessageTime
109
- }
110
- }
111
- `);
112
- return data.connectUdpProxy;
113
- }
114
- async disconnectUdpProxy() {
115
- const data = await this.query(`
116
- mutation DisconnectUdpProxy {
117
- disconnectUdpProxy
118
- }
119
- `);
120
- return data.disconnectUdpProxy;
121
- }
122
- async getConnectionStatus() {
123
- const data = await this.query(`
124
- query GetConnectionStatus {
125
- udpProxyConnectionStatus {
126
- connected
127
- serverIp6
128
- serverClientPort
129
- lastMessageTime
130
- }
131
- }
132
- `);
133
- return data.udpProxyConnectionStatus;
134
- }
135
- async sendActorUpdate(input) {
136
- const normalizedInput = {
137
- mapId: String(input.mapId),
138
- chunk: {
139
- x: String(input.chunk.x),
140
- y: String(input.chunk.y),
141
- z: String(input.chunk.z),
142
- },
143
- uuid: String(input.uuid),
144
- state: String(input.state),
145
- distance: input.distance ?? 8,
146
- decayRate: input.decayRate ?? 0,
147
- sequenceNumber: input.sequenceNumber ?? 0,
148
- };
149
- const data = await this.query(`
150
- mutation SendActorUpdate($input: ActorUpdateRequestInput!) {
151
- sendActorUpdate(input: $input)
152
- }
153
- `, { input: normalizedInput });
154
- return data.sendActorUpdate;
155
- }
156
- async sendVoxelUpdate(input) {
157
- const normalizedInput = {
158
- mapId: String(input.mapId),
159
- chunk: {
160
- x: String(input.chunk.x),
161
- y: String(input.chunk.y),
162
- z: String(input.chunk.z),
163
- },
164
- uuid: String(input.uuid),
165
- voxel: input.voxel,
166
- voxelType: input.voxelType,
167
- voxelState: String(input.voxelState),
168
- distance: input.distance ?? 8,
169
- decayRate: input.decayRate ?? 0,
170
- sequenceNumber: input.sequenceNumber ?? 0,
171
- };
172
- const data = await this.query(`
173
- mutation SendVoxelUpdate($input: VoxelUpdateRequestInput!) {
174
- sendVoxelUpdate(input: $input)
175
- }
176
- `, { input: normalizedInput });
177
- return data.sendVoxelUpdate;
178
- }
179
- async sendAudioPacket(input) {
180
- const normalizedInput = {
181
- mapId: String(input.mapId),
182
- chunk: {
183
- x: String(input.chunk.x),
184
- y: String(input.chunk.y),
185
- z: String(input.chunk.z),
186
- },
187
- uuid: String(input.uuid),
188
- audioData: String(input.audioData),
189
- distance: input.distance ?? 1,
190
- decayRate: input.decayRate ?? 0,
191
- sequenceNumber: input.sequenceNumber ?? 0,
192
- };
193
- const data = await this.query(`
194
- mutation SendAudioPacket($input: ClientAudioPacketInput!) {
195
- sendAudioPacket(input: $input)
196
- }
197
- `, { input: normalizedInput });
198
- return data.sendAudioPacket;
199
- }
200
- async sendTextPacket(input) {
201
- const normalizedInput = {
202
- mapId: String(input.mapId),
203
- chunk: {
204
- x: String(input.chunk.x),
205
- y: String(input.chunk.y),
206
- z: String(input.chunk.z),
207
- },
208
- uuid: String(input.uuid),
209
- text: String(input.text),
210
- distance: input.distance ?? 1,
211
- decayRate: input.decayRate ?? 0,
212
- sequenceNumber: input.sequenceNumber ?? 0,
213
- };
214
- const data = await this.query(`
215
- mutation SendTextPacket($input: ClientTextPacketInput!) {
216
- sendTextPacket(input: $input)
217
- }
218
- `, { input: normalizedInput });
219
- return data.sendTextPacket;
220
- }
221
- async sendClientEvent(input) {
222
- const normalizedInput = {
223
- mapId: String(input.mapId),
224
- chunk: {
225
- x: String(input.chunk.x),
226
- y: String(input.chunk.y),
227
- z: String(input.chunk.z),
228
- },
229
- uuid: String(input.uuid),
230
- eventType: input.eventType,
231
- state: String(input.state),
232
- distance: input.distance ?? 8,
233
- decayRate: input.decayRate ?? 0,
234
- sequenceNumber: input.sequenceNumber ?? 0,
235
- };
236
- const data = await this.query(`
237
- mutation SendClientEvent($input: ClientEventNotificationInput!) {
238
- sendClientEvent(input: $input)
239
- }
240
- `, { input: normalizedInput });
241
- return data.sendClientEvent;
242
- }
243
74
  }
@@ -1,31 +1,51 @@
1
1
  /**
2
- * Main CrowdyClient class - public API for the SDK
2
+ * Public surface of the SDK. Construct one `CrowdyClient` per session and
3
+ * access everything via the typed sub-clients (`client.auth`, `client.udp`,
4
+ * `client.orgs`, ...). The legacy `client.login()` / `client.sendActorUpdate`
5
+ * shortcuts are gone - use `client.auth.login()` / `client.udp.sendActorUpdate()`
6
+ * instead.
3
7
  */
4
- import type { CrowdyClientConfig, AuthResponse, UdpProxyConnectionStatus, ActorUpdateRequestInput, VoxelUpdateRequestInput, ClientAudioPacketInput, ClientTextPacketInput, ClientEventNotificationInput, ActorUpdateHandler, ActorUpdateResponseHandler, VoxelUpdateHandler, VoxelUpdateResponseHandler, ClientAudioHandler, ClientTextHandler, ClientEventHandler, ServerEventHandler, GenericErrorHandler, UnsubscribeFn } from './types.js';
8
+ import { AuthAPI } from './domains/auth.js';
9
+ import { UsersAPI } from './domains/users.js';
10
+ import { OrganizationsAPI } from './domains/organizations.js';
11
+ import { AppsAPI } from './domains/apps.js';
12
+ import { AppAccessAPI } from './domains/appAccess.js';
13
+ import { BillingAPI } from './domains/billing.js';
14
+ import { QuotasAPI } from './domains/quotas.js';
15
+ import { PaymentsAPI } from './domains/payments.js';
16
+ import { ChunksAPI } from './domains/chunks.js';
17
+ import { VoxelsAPI } from './domains/voxels.js';
18
+ import { ActorsAPI } from './domains/actors.js';
19
+ import { TeleportAPI } from './domains/teleport.js';
20
+ import { StateAPI } from './domains/state.js';
21
+ import { ServerStatusAPI } from './domains/serverStatus.js';
22
+ import { UdpAPI } from './domains/udp.js';
23
+ export interface CrowdyClientConfig {
24
+ graphqlEndpoint?: string;
25
+ wsEndpoint?: string;
26
+ timeout?: number;
27
+ }
5
28
  export declare class CrowdyClient {
6
- private client;
7
- private subscriptions;
29
+ private readonly authState;
30
+ private readonly client;
31
+ private readonly subscriptions;
32
+ readonly auth: AuthAPI;
33
+ readonly users: UsersAPI;
34
+ readonly orgs: OrganizationsAPI;
35
+ readonly apps: AppsAPI;
36
+ readonly appAccess: AppAccessAPI;
37
+ readonly billing: BillingAPI;
38
+ readonly quotas: QuotasAPI;
39
+ readonly payments: PaymentsAPI;
40
+ readonly chunks: ChunksAPI;
41
+ readonly voxels: VoxelsAPI;
42
+ readonly actors: ActorsAPI;
43
+ readonly teleport: TeleportAPI;
44
+ readonly state: StateAPI;
45
+ readonly serverStatus: ServerStatusAPI;
46
+ readonly udp: UdpAPI;
8
47
  constructor(config?: CrowdyClientConfig);
9
- login(email: string, password: string): Promise<AuthResponse>;
10
- register(email: string, password: string, gamertag?: string): Promise<AuthResponse>;
11
- getAuthToken(): string | null;
12
- connectUdpProxy(): Promise<UdpProxyConnectionStatus>;
13
- disconnectUdpProxy(): Promise<boolean>;
14
- getConnectionStatus(): Promise<UdpProxyConnectionStatus>;
15
- sendActorUpdate(input: ActorUpdateRequestInput): Promise<boolean>;
16
- sendVoxelUpdate(input: VoxelUpdateRequestInput): Promise<boolean>;
17
- sendAudioPacket(input: ClientAudioPacketInput): Promise<boolean>;
18
- sendTextPacket(input: ClientTextPacketInput): Promise<boolean>;
19
- sendClientEvent(input: ClientEventNotificationInput): Promise<boolean>;
20
- onActorUpdate(handler: ActorUpdateHandler): UnsubscribeFn;
21
- onActorUpdateResponse(handler: ActorUpdateResponseHandler): UnsubscribeFn;
22
- onVoxelUpdate(handler: VoxelUpdateHandler): UnsubscribeFn;
23
- onVoxelUpdateResponse(handler: VoxelUpdateResponseHandler): UnsubscribeFn;
24
- onClientAudio(handler: ClientAudioHandler): UnsubscribeFn;
25
- onClientText(handler: ClientTextHandler): UnsubscribeFn;
26
- onClientEvent(handler: ClientEventHandler): UnsubscribeFn;
27
- onServerEvent(handler: ServerEventHandler): UnsubscribeFn;
28
- onGenericError(handler: GenericErrorHandler): UnsubscribeFn;
48
+ /** Closes the WebSocket and clears the in-memory auth token. */
29
49
  close(): void;
30
50
  }
31
51
  //# sourceMappingURL=crowdy-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"crowdy-client.d.ts","sourceRoot":"","sources":["../src/crowdy-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,qBAAqB,EACrB,4BAA4B,EAC5B,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,aAAa,CAAsB;gBAE/B,MAAM,GAAE,kBAAuB;IAYrC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAM7D,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAMzF,YAAY,IAAI,MAAM,GAAG,IAAI;IAKvB,eAAe,IAAI,OAAO,CAAC,wBAAwB,CAAC;IAIpD,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;IAItC,mBAAmB,IAAI,OAAO,CAAC,wBAAwB,CAAC;IAKxD,eAAe,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC;IAKjE,eAAe,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC;IAKjE,eAAe,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,OAAO,CAAC;IAIhE,cAAc,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC;IAI9D,eAAe,CAAC,KAAK,EAAE,4BAA4B,GAAG,OAAO,CAAC,OAAO,CAAC;IAK5E,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa;IAIzD,qBAAqB,CAAC,OAAO,EAAE,0BAA0B,GAAG,aAAa;IAIzE,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa;IAIzD,qBAAqB,CAAC,OAAO,EAAE,0BAA0B,GAAG,aAAa;IAIzE,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa;IAIzD,YAAY,CAAC,OAAO,EAAE,iBAAiB,GAAG,aAAa;IAIvD,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa;IAIzD,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa;IAIzD,cAAc,CAAC,OAAO,EAAE,mBAAmB,GAAG,aAAa;IAK3D,KAAK,IAAI,IAAI;CAId"}
1
+ {"version":3,"file":"crowdy-client.d.ts","sourceRoot":"","sources":["../src/crowdy-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,YAAY;IAGvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsB;IAGpD,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC;IACvC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;gBAET,MAAM,GAAE,kBAAuB;IA4B3C,gEAAgE;IAChE,KAAK,IAAI,IAAI;CAId"}
@@ -1,91 +1,52 @@
1
1
  /**
2
- * Main CrowdyClient class - public API for the SDK
2
+ * Public surface of the SDK. Construct one `CrowdyClient` per session and
3
+ * access everything via the typed sub-clients (`client.auth`, `client.udp`,
4
+ * `client.orgs`, ...). The legacy `client.login()` / `client.sendActorUpdate`
5
+ * shortcuts are gone - use `client.auth.login()` / `client.udp.sendActorUpdate()`
6
+ * instead.
3
7
  */
8
+ import { AuthState } from './auth-state.js';
4
9
  import { GraphQLClient } from './client.js';
5
10
  import { SubscriptionManager } from './subscriptions.js';
11
+ import { AuthAPI } from './domains/auth.js';
12
+ import { UsersAPI } from './domains/users.js';
13
+ import { OrganizationsAPI } from './domains/organizations.js';
14
+ import { AppsAPI } from './domains/apps.js';
15
+ import { AppAccessAPI } from './domains/appAccess.js';
16
+ import { BillingAPI } from './domains/billing.js';
17
+ import { QuotasAPI } from './domains/quotas.js';
18
+ import { PaymentsAPI } from './domains/payments.js';
19
+ import { ChunksAPI } from './domains/chunks.js';
20
+ import { VoxelsAPI } from './domains/voxels.js';
21
+ import { ActorsAPI } from './domains/actors.js';
22
+ import { TeleportAPI } from './domains/teleport.js';
23
+ import { StateAPI } from './domains/state.js';
24
+ import { ServerStatusAPI } from './domains/serverStatus.js';
25
+ import { UdpAPI } from './domains/udp.js';
6
26
  export class CrowdyClient {
7
27
  constructor(config = {}) {
8
- this.client = new GraphQLClient({
9
- graphqlEndpoint: config.graphqlEndpoint,
10
- timeout: config.timeout,
11
- });
12
- this.subscriptions = new SubscriptionManager({
13
- wsEndpoint: config.wsEndpoint,
14
- });
15
- }
16
- // Authentication
17
- async login(email, password) {
18
- const response = await this.client.login(email, password);
19
- this.subscriptions.setAuthToken(response.token);
20
- return response;
21
- }
22
- async register(email, password, gamertag) {
23
- const response = await this.client.register(email, password, gamertag);
24
- this.subscriptions.setAuthToken(response.token);
25
- return response;
26
- }
27
- getAuthToken() {
28
- return this.client.getAuthToken();
29
- }
30
- // UDP Proxy
31
- async connectUdpProxy() {
32
- return this.client.connectUdpProxy();
33
- }
34
- async disconnectUdpProxy() {
35
- return this.client.disconnectUdpProxy();
36
- }
37
- async getConnectionStatus() {
38
- return this.client.getConnectionStatus();
39
- }
40
- // Actor Updates
41
- async sendActorUpdate(input) {
42
- return this.client.sendActorUpdate(input);
43
- }
44
- // Voxel Updates
45
- async sendVoxelUpdate(input) {
46
- return this.client.sendVoxelUpdate(input);
47
- }
48
- // Client Packets
49
- async sendAudioPacket(input) {
50
- return this.client.sendAudioPacket(input);
51
- }
52
- async sendTextPacket(input) {
53
- return this.client.sendTextPacket(input);
54
- }
55
- async sendClientEvent(input) {
56
- return this.client.sendClientEvent(input);
57
- }
58
- // Type-specific subscription handlers
59
- onActorUpdate(handler) {
60
- return this.subscriptions.onActorUpdate(handler);
61
- }
62
- onActorUpdateResponse(handler) {
63
- return this.subscriptions.onActorUpdateResponse(handler);
64
- }
65
- onVoxelUpdate(handler) {
66
- return this.subscriptions.onVoxelUpdate(handler);
67
- }
68
- onVoxelUpdateResponse(handler) {
69
- return this.subscriptions.onVoxelUpdateResponse(handler);
70
- }
71
- onClientAudio(handler) {
72
- return this.subscriptions.onClientAudio(handler);
73
- }
74
- onClientText(handler) {
75
- return this.subscriptions.onClientText(handler);
76
- }
77
- onClientEvent(handler) {
78
- return this.subscriptions.onClientEvent(handler);
79
- }
80
- onServerEvent(handler) {
81
- return this.subscriptions.onServerEvent(handler);
82
- }
83
- onGenericError(handler) {
84
- return this.subscriptions.onGenericError(handler);
85
- }
86
- // Cleanup
28
+ this.authState = new AuthState();
29
+ this.client = new GraphQLClient({ graphqlEndpoint: config.graphqlEndpoint, timeout: config.timeout }, this.authState);
30
+ this.subscriptions = new SubscriptionManager({ wsEndpoint: config.wsEndpoint }, this.authState);
31
+ this.auth = new AuthAPI(this.client, this.authState);
32
+ this.users = new UsersAPI(this.client);
33
+ this.orgs = new OrganizationsAPI(this.client);
34
+ this.apps = new AppsAPI(this.client);
35
+ this.appAccess = new AppAccessAPI(this.client);
36
+ this.billing = new BillingAPI(this.client);
37
+ this.quotas = new QuotasAPI(this.client);
38
+ this.payments = new PaymentsAPI(this.client);
39
+ this.chunks = new ChunksAPI(this.client);
40
+ this.voxels = new VoxelsAPI(this.client);
41
+ this.actors = new ActorsAPI(this.client);
42
+ this.teleport = new TeleportAPI(this.client);
43
+ this.state = new StateAPI(this.client);
44
+ this.serverStatus = new ServerStatusAPI(this.client);
45
+ this.udp = new UdpAPI(this.client, this.subscriptions);
46
+ }
47
+ /** Closes the WebSocket and clears the in-memory auth token. */
87
48
  close() {
88
49
  this.subscriptions.close();
89
- this.client.setAuthToken(null);
50
+ this.authState.setToken(null);
90
51
  }
91
52
  }
@@ -0,0 +1,22 @@
1
+ import type { GraphQLClient } from '../client.js';
2
+ import { type ActorQuery, type ActorQueryVariables, type ActorsQuery, type ActorsQueryVariables, type BatchLookupActorsQuery, type BatchLookupActorsQueryVariables, type CreateActorMutation, type CreateActorMutationVariables, type UpdateActorMutation, type UpdateActorMutationVariables, type DeleteActorMutation, type DeleteActorMutationVariables, type UpdateActorStateMutation, type UpdateActorStateMutationVariables } from '../generated/graphql.js';
3
+ /**
4
+ * Actor (player / NPC) CRUD and filtering.
5
+ *
6
+ * Note: this is the persisted-actor API. For high-frequency replication see
7
+ * the existing `client.sendActorUpdate()` UDP path (unchanged).
8
+ *
9
+ * Exposed as `client.actors`.
10
+ */
11
+ export declare class ActorsAPI {
12
+ private gql;
13
+ constructor(gql: GraphQLClient);
14
+ get(uuid: ActorQueryVariables['uuid']): Promise<ActorQuery['actor']>;
15
+ list(filter?: ActorsQueryVariables['filter']): Promise<ActorsQuery['actors']>;
16
+ batchLookup(input: BatchLookupActorsQueryVariables['input']): Promise<BatchLookupActorsQuery['batchLookupActors']>;
17
+ create(input: CreateActorMutationVariables['input']): Promise<CreateActorMutation['createActor']>;
18
+ update(uuid: UpdateActorMutationVariables['uuid'], input: UpdateActorMutationVariables['input']): Promise<UpdateActorMutation['updateActor']>;
19
+ delete(uuid: DeleteActorMutationVariables['uuid']): Promise<DeleteActorMutation['deleteActor']>;
20
+ updateState(uuid: UpdateActorStateMutationVariables['uuid'], input: UpdateActorStateMutationVariables['input']): Promise<UpdateActorStateMutation['updateActorState']>;
21
+ }
22
+ //# sourceMappingURL=actors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actors.d.ts","sourceRoot":"","sources":["../../src/domains/actors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,mBAAmB,EAExB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EAEzB,KAAK,sBAAsB,EAC3B,KAAK,+BAA+B,EAEpC,KAAK,mBAAmB,EACxB,KAAK,4BAA4B,EAEjC,KAAK,mBAAmB,EACxB,KAAK,4BAA4B,EAEjC,KAAK,mBAAmB,EACxB,KAAK,4BAA4B,EAEjC,KAAK,wBAAwB,EAC7B,KAAK,iCAAiC,EACvC,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;GAOG;AACH,qBAAa,SAAS;IACR,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,aAAa;IAEhC,GAAG,CAAC,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAKpE,IAAI,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAK7E,WAAW,CACf,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,GAC9C,OAAO,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,CAAC;IAKjD,MAAM,CACV,KAAK,EAAE,4BAA4B,CAAC,OAAO,CAAC,GAC3C,OAAO,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAKxC,MAAM,CACV,IAAI,EAAE,4BAA4B,CAAC,MAAM,CAAC,EAC1C,KAAK,EAAE,4BAA4B,CAAC,OAAO,CAAC,GAC3C,OAAO,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAKxC,MAAM,CACV,IAAI,EAAE,4BAA4B,CAAC,MAAM,CAAC,GACzC,OAAO,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAKxC,WAAW,CACf,IAAI,EAAE,iCAAiC,CAAC,MAAM,CAAC,EAC/C,KAAK,EAAE,iCAAiC,CAAC,OAAO,CAAC,GAChD,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC,CAAC;CAIzD"}
@@ -0,0 +1,42 @@
1
+ import { ActorDocument, ActorsDocument, BatchLookupActorsDocument, CreateActorDocument, UpdateActorDocument, DeleteActorDocument, UpdateActorStateDocument, } from '../generated/graphql.js';
2
+ /**
3
+ * Actor (player / NPC) CRUD and filtering.
4
+ *
5
+ * Note: this is the persisted-actor API. For high-frequency replication see
6
+ * the existing `client.sendActorUpdate()` UDP path (unchanged).
7
+ *
8
+ * Exposed as `client.actors`.
9
+ */
10
+ export class ActorsAPI {
11
+ constructor(gql) {
12
+ this.gql = gql;
13
+ }
14
+ async get(uuid) {
15
+ const data = await this.gql.request(ActorDocument, { uuid });
16
+ return data.actor;
17
+ }
18
+ async list(filter) {
19
+ const data = await this.gql.request(ActorsDocument, { filter });
20
+ return data.actors;
21
+ }
22
+ async batchLookup(input) {
23
+ const data = await this.gql.request(BatchLookupActorsDocument, { input });
24
+ return data.batchLookupActors;
25
+ }
26
+ async create(input) {
27
+ const data = await this.gql.request(CreateActorDocument, { input });
28
+ return data.createActor;
29
+ }
30
+ async update(uuid, input) {
31
+ const data = await this.gql.request(UpdateActorDocument, { uuid, input });
32
+ return data.updateActor;
33
+ }
34
+ async delete(uuid) {
35
+ const data = await this.gql.request(DeleteActorDocument, { uuid });
36
+ return data.deleteActor;
37
+ }
38
+ async updateState(uuid, input) {
39
+ const data = await this.gql.request(UpdateActorStateDocument, { uuid, input });
40
+ return data.updateActorState;
41
+ }
42
+ }
@@ -0,0 +1,23 @@
1
+ import type { GraphQLClient } from '../client.js';
2
+ import { type AppAccessTiersQuery, type AppAccessTiersQueryVariables, type MyAppAccessQuery, type MyAppAccessQueryVariables, type AppUserAccessByAppQuery, type AppUserAccessByAppQueryVariables, type CreateAccessTierMutation, type CreateAccessTierMutationVariables, type UpdateAccessTierMutation, type UpdateAccessTierMutationVariables, type ArchiveAccessTierMutationVariables, type GrantAppAccessMutation, type GrantAppAccessMutationVariables, type RevokeAppAccessMutation, type RevokeAppAccessMutationVariables } from '../generated/graphql.js';
3
+ /**
4
+ * App access tiers + per-user app access management. Exposed as
5
+ * `client.appAccess`.
6
+ */
7
+ export declare class AppAccessAPI {
8
+ private gql;
9
+ constructor(gql: GraphQLClient);
10
+ listTiers(appId: AppAccessTiersQueryVariables['appId']): Promise<AppAccessTiersQuery['appAccessTiers']>;
11
+ myAccess(appId: MyAppAccessQueryVariables['appId']): Promise<MyAppAccessQuery['myAppAccess']>;
12
+ listAccess(args: AppUserAccessByAppQueryVariables): Promise<AppUserAccessByAppQuery['appUserAccessByApp']>;
13
+ createTier(input: CreateAccessTierMutationVariables['input']): Promise<CreateAccessTierMutation['createAccessTier']>;
14
+ updateTier(args: UpdateAccessTierMutationVariables): Promise<UpdateAccessTierMutation['updateAccessTier']>;
15
+ archiveTier(tierId: ArchiveAccessTierMutationVariables['tierId']): Promise<{
16
+ tierId: any;
17
+ status: string;
18
+ updatedAt: any;
19
+ }>;
20
+ grant(input: GrantAppAccessMutationVariables['input']): Promise<GrantAppAccessMutation['grantAppAccess']>;
21
+ revoke(args: RevokeAppAccessMutationVariables): Promise<RevokeAppAccessMutation['revokeAppAccess']>;
22
+ }
23
+ //# sourceMappingURL=appAccess.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appAccess.d.ts","sourceRoot":"","sources":["../../src/domains/appAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,4BAA4B,EAEjC,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,EAE9B,KAAK,uBAAuB,EAC5B,KAAK,gCAAgC,EAErC,KAAK,wBAAwB,EAC7B,KAAK,iCAAiC,EAEtC,KAAK,wBAAwB,EAC7B,KAAK,iCAAiC,EAEtC,KAAK,kCAAkC,EAEvC,KAAK,sBAAsB,EAC3B,KAAK,+BAA+B,EAEpC,KAAK,uBAAuB,EAC5B,KAAK,gCAAgC,EACtC,MAAM,yBAAyB,CAAC;AAEjC;;;GAGG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,aAAa;IAEhC,SAAS,CACb,KAAK,EAAE,4BAA4B,CAAC,OAAO,CAAC,GAC3C,OAAO,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;IAK3C,QAAQ,CACZ,KAAK,EAAE,yBAAyB,CAAC,OAAO,CAAC,GACxC,OAAO,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;IAKrC,UAAU,CACd,IAAI,EAAE,gCAAgC,GACrC,OAAO,CAAC,uBAAuB,CAAC,oBAAoB,CAAC,CAAC;IAKnD,UAAU,CACd,KAAK,EAAE,iCAAiC,CAAC,OAAO,CAAC,GAChD,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC,CAAC;IAKlD,UAAU,CACd,IAAI,EAAE,iCAAiC,GACtC,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC,CAAC;IAKlD,WAAW,CACf,MAAM,EAAE,kCAAkC,CAAC,QAAQ,CAAC,GACnD,OAAO,CAAC;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,GAAG,CAAA;KAAE,CAAC;IAKrD,KAAK,CACT,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,GAC9C,OAAO,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;IAK9C,MAAM,CACV,IAAI,EAAE,gCAAgC,GACrC,OAAO,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;CAIvD"}
@@ -0,0 +1,42 @@
1
+ import { AppAccessTiersDocument, MyAppAccessDocument, AppUserAccessByAppDocument, CreateAccessTierDocument, UpdateAccessTierDocument, ArchiveAccessTierDocument, GrantAppAccessDocument, RevokeAppAccessDocument, } from '../generated/graphql.js';
2
+ /**
3
+ * App access tiers + per-user app access management. Exposed as
4
+ * `client.appAccess`.
5
+ */
6
+ export class AppAccessAPI {
7
+ constructor(gql) {
8
+ this.gql = gql;
9
+ }
10
+ async listTiers(appId) {
11
+ const data = await this.gql.request(AppAccessTiersDocument, { appId });
12
+ return data.appAccessTiers;
13
+ }
14
+ async myAccess(appId) {
15
+ const data = await this.gql.request(MyAppAccessDocument, { appId });
16
+ return data.myAppAccess;
17
+ }
18
+ async listAccess(args) {
19
+ const data = await this.gql.request(AppUserAccessByAppDocument, args);
20
+ return data.appUserAccessByApp;
21
+ }
22
+ async createTier(input) {
23
+ const data = await this.gql.request(CreateAccessTierDocument, { input });
24
+ return data.createAccessTier;
25
+ }
26
+ async updateTier(args) {
27
+ const data = await this.gql.request(UpdateAccessTierDocument, args);
28
+ return data.updateAccessTier;
29
+ }
30
+ async archiveTier(tierId) {
31
+ const data = await this.gql.request(ArchiveAccessTierDocument, { tierId });
32
+ return data.archiveAccessTier;
33
+ }
34
+ async grant(input) {
35
+ const data = await this.gql.request(GrantAppAccessDocument, { input });
36
+ return data.grantAppAccess;
37
+ }
38
+ async revoke(args) {
39
+ const data = await this.gql.request(RevokeAppAccessDocument, args);
40
+ return data.revokeAppAccess;
41
+ }
42
+ }
@@ -0,0 +1,27 @@
1
+ import type { GraphQLClient } from '../client.js';
2
+ import { type AppQuery, type AppQueryVariables, type AppBySlugQuery, type AppBySlugQueryVariables, type MyAppsQuery, type AppsForOrgQuery, type AppsForOrgQueryVariables, type MarketplaceAppsQuery, type MarketplaceAppsQueryVariables, type CreateAppMutation, type CreateAppMutationVariables, type UpdateAppMutation, type UpdateAppMutationVariables, type ArchiveAppMutationVariables, type SetAppVisibilityMutation, type SetAppVisibilityMutationVariables } from '../generated/graphql.js';
3
+ /**
4
+ * App (game / world) lifecycle and discovery. Exposed as `client.apps`.
5
+ *
6
+ * `marketplace()` is a public listing (no auth) of every app where
7
+ * visibility = PUBLIC and status = LIVE; the rest of the methods require
8
+ * either org-membership permissions or super admin.
9
+ */
10
+ export declare class AppsAPI {
11
+ private gql;
12
+ constructor(gql: GraphQLClient);
13
+ marketplace(args?: MarketplaceAppsQueryVariables): Promise<MarketplaceAppsQuery['apps']>;
14
+ byId(appId: AppQueryVariables['appId']): Promise<AppQuery['app']>;
15
+ bySlug(args: AppBySlugQueryVariables): Promise<AppBySlugQuery['appBySlug']>;
16
+ myApps(): Promise<MyAppsQuery['myApps']>;
17
+ forOrg(orgSlug: AppsForOrgQueryVariables['orgSlug']): Promise<AppsForOrgQuery['appsForOrg']>;
18
+ create(input: CreateAppMutationVariables['input']): Promise<CreateAppMutation['createApp']>;
19
+ update(args: UpdateAppMutationVariables): Promise<UpdateAppMutation['updateApp']>;
20
+ archive(appId: ArchiveAppMutationVariables['appId']): Promise<{
21
+ appId: any;
22
+ status: string;
23
+ updatedAt: any;
24
+ }>;
25
+ setVisibility(args: SetAppVisibilityMutationVariables): Promise<SetAppVisibilityMutation['setAppVisibility']>;
26
+ }
27
+ //# sourceMappingURL=apps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/domains/apps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,iBAAiB,EAEtB,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAE5B,KAAK,WAAW,EAEhB,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAE7B,KAAK,oBAAoB,EACzB,KAAK,6BAA6B,EAElC,KAAK,iBAAiB,EACtB,KAAK,0BAA0B,EAE/B,KAAK,iBAAiB,EACtB,KAAK,0BAA0B,EAE/B,KAAK,2BAA2B,EAEhC,KAAK,wBAAwB,EAC7B,KAAK,iCAAiC,EACvC,MAAM,yBAAyB,CAAC;AAEjC;;;;;;GAMG;AACH,qBAAa,OAAO;IACN,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,aAAa;IAEhC,WAAW,CACf,IAAI,GAAE,6BAAkC,GACvC,OAAO,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAKlC,IAAI,CAAC,KAAK,EAAE,iBAAiB,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAKjE,MAAM,CACV,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;IAKjC,MAAM,IAAI,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAKxC,MAAM,CACV,OAAO,EAAE,wBAAwB,CAAC,SAAS,CAAC,GAC3C,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;IAKnC,MAAM,CACV,KAAK,EAAE,0BAA0B,CAAC,OAAO,CAAC,GACzC,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAKpC,MAAM,CACV,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAKpC,OAAO,CACX,KAAK,EAAE,2BAA2B,CAAC,OAAO,CAAC,GAC1C,OAAO,CAAC;QAAE,KAAK,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,GAAG,CAAA;KAAE,CAAC;IAKpD,aAAa,CACjB,IAAI,EAAE,iCAAiC,GACtC,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC,CAAC;CAIzD"}