@raba7ni/raba7ni 1.0.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 ADDED
@@ -0,0 +1,56 @@
1
+ # @raba7ni/raba7ni
2
+
3
+ Official TypeScript SDK for the Raba7ni Coffee Loyalty Platform Developer API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @raba7ni/raba7ni
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { Raba7niSDK } from '@raba7ni/raba7ni';
15
+
16
+ const sdk = new Raba7niSDK({
17
+ appId: 'app_abc123def456789...',
18
+ apiKey: 'dev_xyz789uvw456...',
19
+ baseUrl: 'https://your-domain.com' // optional, defaults to production
20
+ });
21
+
22
+ // Validate a member
23
+ const result = await sdk.validateMember(5, '+1234567890');
24
+ console.log(result.is_member); // true/false
25
+
26
+ // Find or create a member with points
27
+ const member = await sdk.findOrCreateMember({
28
+ card_id: 5,
29
+ name: 'John Doe',
30
+ email: 'john@example.com',
31
+ phone_number: '+1234567890',
32
+ order: {
33
+ award_points: true,
34
+ total_amount: 50.00
35
+ }
36
+ });
37
+ ```
38
+
39
+ ## Features
40
+
41
+ - ✅ Full TypeScript support with comprehensive types
42
+ - ✅ Automatic authentication handling
43
+ - ✅ Rate limiting with automatic retry logic
44
+ - ✅ Comprehensive error handling
45
+ - ✅ Input validation
46
+ - ✅ Webhook signature verification utilities
47
+ - ✅ Node.js 18+ support
48
+ - ✅ ES modules and CommonJS compatibility
49
+
50
+ ## Documentation
51
+
52
+ For complete API documentation, see the [Developer API Documentation](https://docs.raba7ni.com/developer-api).
53
+
54
+ ## License
55
+
56
+ MIT © Raba7ni
@@ -0,0 +1,56 @@
1
+ import { AxiosRequestConfig } from 'axios';
2
+ import { Raba7niConfig, ApiResponse, RateLimitInfo } from './types';
3
+ /**
4
+ * Core API client for Raba7ni Developer API
5
+ */
6
+ export declare class Raba7niClient {
7
+ private axiosInstance;
8
+ private config;
9
+ private rateLimitInfo;
10
+ constructor(config: Raba7niConfig);
11
+ /**
12
+ * Extract rate limit information from response headers
13
+ */
14
+ private extractRateLimitInfo;
15
+ /**
16
+ * Handle API errors and convert to appropriate error classes
17
+ */
18
+ private handleApiError;
19
+ /**
20
+ * Make HTTP request with retry logic
21
+ */
22
+ private request;
23
+ /**
24
+ * Sleep helper for retry delays
25
+ */
26
+ private sleep;
27
+ /**
28
+ * Get current rate limit information
29
+ */
30
+ getRateLimitInfo(): RateLimitInfo;
31
+ /**
32
+ * Make GET request
33
+ */
34
+ get<T = any>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>>;
35
+ /**
36
+ * Make POST request
37
+ */
38
+ post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>>;
39
+ /**
40
+ * Make PUT request
41
+ */
42
+ put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>>;
43
+ /**
44
+ * Make PATCH request
45
+ */
46
+ patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>>;
47
+ /**
48
+ * Make DELETE request
49
+ */
50
+ delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>>;
51
+ /**
52
+ * Update configuration
53
+ */
54
+ updateConfig(config: Partial<Raba7niConfig>): void;
55
+ }
56
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAc,EAAiB,kBAAkB,EAA6B,MAAM,OAAO,CAAC;AAC5F,OAAO,EACL,aAAa,EACb,WAAW,EAEX,aAAa,EAMd,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,aAAa,CAKnB;gBAEU,MAAM,EAAE,aAAa;IAiEjC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAW5B;;OAEG;IACH,OAAO,CAAC,cAAc;IA0DtB;;OAEG;YACW,OAAO;IAkDrB;;OAEG;IACH,OAAO,CAAC,KAAK;IAeb;;OAEG;IACI,gBAAgB,IAAI,aAAa;IAIxC;;OAEG;IACU,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAI5F;;OAEG;IACU,IAAI,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAIzG;;OAEG;IACU,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAIxG;;OAEG;IACU,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAI1G;;OAEG;IACU,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAI/F;;OAEG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI;CAgB1D"}
@@ -0,0 +1,497 @@
1
+ import { AxiosRequestConfig } from 'axios';
2
+
3
+ /**
4
+ * Configuration options for the Raba7ni SDK
5
+ */
6
+ interface Raba7niConfig {
7
+ /** Application ID (starts with 'app_') */
8
+ appId: string;
9
+ /** API key (starts with 'dev_') */
10
+ apiKey: string;
11
+ /** Base URL for API requests */
12
+ baseUrl?: string;
13
+ /** Locale for API requests (default: 'en') */
14
+ locale?: string;
15
+ /** Request timeout in milliseconds (default: 30000) */
16
+ timeout?: number;
17
+ /** Maximum number of retry attempts (default: 3) */
18
+ maxRetries?: number;
19
+ /** Initial retry delay in milliseconds (default: 1000) */
20
+ retryDelay?: number;
21
+ }
22
+ /**
23
+ * Standard API response wrapper
24
+ */
25
+ interface ApiResponse<T = any> {
26
+ success: boolean;
27
+ data?: T;
28
+ message?: string;
29
+ }
30
+ /**
31
+ * API error response structure
32
+ */
33
+ interface ApiError {
34
+ error: string;
35
+ message: string;
36
+ errors?: Record<string, string[]>;
37
+ }
38
+ /**
39
+ * Rate limit information from response headers
40
+ */
41
+ interface RateLimitInfo {
42
+ hourlyLimit: number;
43
+ hourlyRemaining: number;
44
+ dailyLimit: number;
45
+ dailyRemaining: number;
46
+ resetTime?: string;
47
+ }
48
+ /**
49
+ * Member validation request
50
+ */
51
+ interface ValidateMemberRequest {
52
+ card_id: number;
53
+ phone_number: string;
54
+ include_member_data?: boolean;
55
+ }
56
+ /**
57
+ * Member validation response
58
+ */
59
+ interface ValidateMemberResponse {
60
+ card_id: number;
61
+ phone_number: string;
62
+ is_member: boolean;
63
+ validated_at: string;
64
+ member?: Member;
65
+ }
66
+ /**
67
+ * Member details request
68
+ */
69
+ interface MemberDetailsRequest {
70
+ card_id: number;
71
+ phone_number: string;
72
+ }
73
+ /**
74
+ * Member details response
75
+ */
76
+ interface MemberDetailsResponse {
77
+ member: Member;
78
+ card_relationship: CardRelationship;
79
+ }
80
+ /**
81
+ * Find or create member request
82
+ */
83
+ interface FindOrCreateMemberRequest {
84
+ card_id: number;
85
+ name: string;
86
+ email: string;
87
+ phone_number: string;
88
+ create_order?: boolean;
89
+ order?: Order;
90
+ }
91
+ /**
92
+ * Order information for find/create member
93
+ */
94
+ interface Order {
95
+ award_points?: boolean;
96
+ total_amount: number;
97
+ delivery_cost?: number;
98
+ items?: OrderItem[];
99
+ }
100
+ /**
101
+ * Order item
102
+ */
103
+ interface OrderItem {
104
+ name: string;
105
+ amount: number;
106
+ metadata?: Record<string, any>;
107
+ }
108
+ /**
109
+ * Find or create member response
110
+ */
111
+ interface FindOrCreateMemberResponse {
112
+ member: Member;
113
+ is_new: boolean;
114
+ matched_by: 'email' | 'phone' | null;
115
+ card_id: number;
116
+ order?: OrderResponse;
117
+ transaction?: Transaction;
118
+ }
119
+ /**
120
+ * Order response
121
+ */
122
+ interface OrderResponse {
123
+ id: number;
124
+ total_amount: string;
125
+ delivery_cost?: string;
126
+ items?: OrderItem[];
127
+ points_awarded: boolean;
128
+ status: string;
129
+ created_at: string;
130
+ }
131
+ /**
132
+ * Card information
133
+ */
134
+ interface Card {
135
+ id: number;
136
+ name: string;
137
+ description?: string;
138
+ club_id: number;
139
+ club_name: string;
140
+ reward_type: 'points' | 'stamps';
141
+ is_active: boolean;
142
+ created_at: string;
143
+ }
144
+ /**
145
+ * Member information
146
+ */
147
+ interface Member {
148
+ id: number;
149
+ first_name?: string;
150
+ last_name?: string;
151
+ name?: string;
152
+ email?: string;
153
+ phone?: string;
154
+ created_at: string;
155
+ }
156
+ /**
157
+ * Card relationship information
158
+ */
159
+ interface CardRelationship {
160
+ card_id: number;
161
+ points: number;
162
+ stamps: number;
163
+ joined_at: string;
164
+ last_updated: string;
165
+ }
166
+ /**
167
+ * Transaction information
168
+ */
169
+ interface Transaction {
170
+ id: number;
171
+ points?: number;
172
+ stamps?: number;
173
+ event: string;
174
+ created_at: string;
175
+ }
176
+ /**
177
+ * Available API scope
178
+ */
179
+ interface Scope {
180
+ id: string;
181
+ name: string;
182
+ description: string;
183
+ }
184
+ /**
185
+ * Available webhook event
186
+ */
187
+ interface WebhookEvent {
188
+ id: string;
189
+ name: string;
190
+ description: string;
191
+ data_structure: string;
192
+ }
193
+ /**
194
+ * Webhook payload structure
195
+ */
196
+ interface WebhookPayload<T = any> {
197
+ event: string;
198
+ application_id: number;
199
+ timestamp: string;
200
+ data: T;
201
+ }
202
+ /**
203
+ * Member joined webhook data
204
+ */
205
+ interface MemberJoinedWebhookData {
206
+ member: Member;
207
+ card: Card;
208
+ }
209
+ /**
210
+ * Member left webhook data
211
+ */
212
+ interface MemberLeftWebhookData {
213
+ member: Member;
214
+ card: Card;
215
+ }
216
+ /**
217
+ * Points earned webhook data
218
+ */
219
+ interface PointsEarnedWebhookData {
220
+ member: Member;
221
+ card: Card;
222
+ transaction: Transaction;
223
+ }
224
+ /**
225
+ * Points redeemed webhook data
226
+ */
227
+ interface PointsRedeemedWebhookData {
228
+ member: Member;
229
+ card: Card;
230
+ transaction: Transaction;
231
+ }
232
+ /**
233
+ * Transaction created webhook data
234
+ */
235
+ interface TransactionCreatedWebhookData {
236
+ transaction: Transaction;
237
+ member: Member;
238
+ card: Card;
239
+ }
240
+ /**
241
+ * SDK initialization error
242
+ */
243
+ declare class Raba7niError extends Error {
244
+ code?: string | undefined;
245
+ statusCode?: number | undefined;
246
+ response?: any | undefined;
247
+ constructor(message: string, code?: string | undefined, statusCode?: number | undefined, response?: any | undefined);
248
+ }
249
+ /**
250
+ * Authentication error
251
+ */
252
+ declare class AuthenticationError extends Raba7niError {
253
+ constructor(message?: string);
254
+ }
255
+ /**
256
+ * Rate limit error
257
+ */
258
+ declare class RateLimitError extends Raba7niError {
259
+ retryAfter?: number | undefined;
260
+ constructor(message?: string, retryAfter?: number | undefined);
261
+ }
262
+ /**
263
+ * Validation error
264
+ */
265
+ declare class ValidationError extends Raba7niError {
266
+ validationErrors?: Record<string, string[]> | undefined;
267
+ constructor(message: string, validationErrors?: Record<string, string[]> | undefined);
268
+ }
269
+ /**
270
+ * Network error
271
+ */
272
+ declare class NetworkError extends Raba7niError {
273
+ originalError?: Error | undefined;
274
+ constructor(message: string, originalError?: Error | undefined);
275
+ }
276
+
277
+ /**
278
+ * Main Raba7ni SDK class
279
+ */
280
+ declare class Raba7niSDK {
281
+ private client;
282
+ constructor(config: Raba7niConfig);
283
+ /**
284
+ * Validate if a phone number is a member of a specific card
285
+ */
286
+ validateMember(cardId: number | string, phoneNumber: string, options?: {
287
+ include_member_data?: boolean;
288
+ }): Promise<ValidateMemberResponse>;
289
+ /**
290
+ * Get detailed information about a member for a specific card
291
+ */
292
+ getMemberDetails(cardId: number | string, phoneNumber: string): Promise<MemberDetailsResponse>;
293
+ /**
294
+ * Find an existing member by email/phone, or create a new account.
295
+ * Optionally create an online order and/or award points.
296
+ */
297
+ findOrCreateMember(request: FindOrCreateMemberRequest): Promise<FindOrCreateMemberResponse>;
298
+ /**
299
+ * Get card information
300
+ */
301
+ getCardInfo(cardId: number | string): Promise<Card>;
302
+ /**
303
+ * Get available API scopes
304
+ */
305
+ getScopes(): Promise<Scope[]>;
306
+ /**
307
+ * Get available webhook events
308
+ */
309
+ getWebhookEvents(): Promise<WebhookEvent[]>;
310
+ /**
311
+ * Get current rate limit information
312
+ */
313
+ getRateLimitInfo(): RateLimitInfo;
314
+ /**
315
+ * Update SDK configuration
316
+ */
317
+ updateConfig(config: Partial<Raba7niConfig>): void;
318
+ /**
319
+ * Helper method to make custom API requests
320
+ */
321
+ request<T = any>(method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', endpoint: string, data?: any, options?: any): Promise<T>;
322
+ }
323
+
324
+ /**
325
+ * Core API client for Raba7ni Developer API
326
+ */
327
+ declare class Raba7niClient {
328
+ private axiosInstance;
329
+ private config;
330
+ private rateLimitInfo;
331
+ constructor(config: Raba7niConfig);
332
+ /**
333
+ * Extract rate limit information from response headers
334
+ */
335
+ private extractRateLimitInfo;
336
+ /**
337
+ * Handle API errors and convert to appropriate error classes
338
+ */
339
+ private handleApiError;
340
+ /**
341
+ * Make HTTP request with retry logic
342
+ */
343
+ private request;
344
+ /**
345
+ * Sleep helper for retry delays
346
+ */
347
+ private sleep;
348
+ /**
349
+ * Get current rate limit information
350
+ */
351
+ getRateLimitInfo(): RateLimitInfo;
352
+ /**
353
+ * Make GET request
354
+ */
355
+ get<T = any>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>>;
356
+ /**
357
+ * Make POST request
358
+ */
359
+ post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>>;
360
+ /**
361
+ * Make PUT request
362
+ */
363
+ put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>>;
364
+ /**
365
+ * Make PATCH request
366
+ */
367
+ patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>>;
368
+ /**
369
+ * Make DELETE request
370
+ */
371
+ delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>>;
372
+ /**
373
+ * Update configuration
374
+ */
375
+ updateConfig(config: Partial<Raba7niConfig>): void;
376
+ }
377
+
378
+ /**
379
+ * Webhook signature verification utilities
380
+ */
381
+ /**
382
+ * Verify webhook signature
383
+ */
384
+ declare function verifyWebhookSignature(payload: string, signature: string, secret: string): boolean;
385
+ /**
386
+ * Parse webhook payload with type safety
387
+ */
388
+ declare function parseWebhookPayload<T = any>(payload: string): WebhookPayload<T>;
389
+ /**
390
+ * Type guard for member joined webhook
391
+ */
392
+ declare function isMemberJoinedWebhook(payload: WebhookPayload): payload is WebhookPayload<MemberJoinedWebhookData>;
393
+ /**
394
+ * Type guard for member left webhook
395
+ */
396
+ declare function isMemberLeftWebhook(payload: WebhookPayload): payload is WebhookPayload<MemberLeftWebhookData>;
397
+ /**
398
+ * Type guard for points earned webhook
399
+ */
400
+ declare function isPointsEarnedWebhook(payload: WebhookPayload): payload is WebhookPayload<PointsEarnedWebhookData>;
401
+ /**
402
+ * Type guard for points redeemed webhook
403
+ */
404
+ declare function isPointsRedeemedWebhook(payload: WebhookPayload): payload is WebhookPayload<PointsRedeemedWebhookData>;
405
+ /**
406
+ * Type guard for transaction created webhook
407
+ */
408
+ declare function isTransactionCreatedWebhook(payload: WebhookPayload): payload is WebhookPayload<TransactionCreatedWebhookData>;
409
+ /**
410
+ * Webhook handler class
411
+ */
412
+ declare class WebhookHandler {
413
+ private secret;
414
+ constructor(secret: string);
415
+ /**
416
+ * Verify and parse incoming webhook
417
+ */
418
+ verifyAndParse<T = any>(payload: string, signature: string): Promise<WebhookPayload<T>>;
419
+ /**
420
+ * Verify webhook signature
421
+ */
422
+ verifyWebhookSignature(payload: string, signature: string): boolean;
423
+ /**
424
+ * Parse webhook payload
425
+ */
426
+ parseWebhookPayload<T = any>(payload: string): WebhookPayload<T>;
427
+ /**
428
+ * Handle webhook with event-specific callbacks
429
+ */
430
+ handleWebhook(payload: string, signature: string, handlers: {
431
+ onMemberJoined?: (data: MemberJoinedWebhookData) => Promise<void> | void;
432
+ onMemberLeft?: (data: MemberLeftWebhookData) => Promise<void> | void;
433
+ onPointsEarned?: (data: PointsEarnedWebhookData) => Promise<void> | void;
434
+ onPointsRedeemed?: (data: PointsRedeemedWebhookData) => Promise<void> | void;
435
+ onTransactionCreated?: (data: TransactionCreatedWebhookData) => Promise<void> | void;
436
+ onUnknownEvent?: (event: string, data: any) => Promise<void> | void;
437
+ }): Promise<void>;
438
+ /**
439
+ * Update webhook secret
440
+ */
441
+ updateSecret(secret: string): void;
442
+ /**
443
+ * Get current secret
444
+ */
445
+ getSecret(): string;
446
+ }
447
+
448
+ /**
449
+ * Utility functions for the Raba7ni SDK
450
+ */
451
+ /**
452
+ * Normalize phone number to E.164 format
453
+ */
454
+ declare function normalizePhoneNumber(phoneNumber: string): string;
455
+ /**
456
+ * Validate email format
457
+ */
458
+ declare function validateEmail(email: string): boolean;
459
+ /**
460
+ * Validate card ID
461
+ */
462
+ declare function validateCardId(cardId: number | string): number;
463
+ /**
464
+ * Validate monetary amount
465
+ */
466
+ declare function validateAmount(amount: number | string): number;
467
+ /**
468
+ * Sanitize string input
469
+ */
470
+ declare function sanitizeString(input: string, maxLength?: number): string;
471
+ /**
472
+ * Validate name field
473
+ */
474
+ declare function validateName(name: string): string;
475
+ /**
476
+ * Deep clone object
477
+ */
478
+ declare function deepClone<T>(obj: T): T;
479
+ /**
480
+ * Retry delay calculation with exponential backoff
481
+ */
482
+ declare function calculateRetryDelay(attempt: number, baseDelay?: number): number;
483
+ /**
484
+ * Generate random string for request tracking
485
+ */
486
+ declare function generateRequestId(): string;
487
+ /**
488
+ * Check if a value is a valid ISO date string
489
+ */
490
+ declare function isValidISODate(dateString: string): boolean;
491
+ /**
492
+ * Format date to ISO string
493
+ */
494
+ declare function formatDate(date: Date | string): string;
495
+
496
+ export { AuthenticationError, NetworkError, Raba7niClient, Raba7niError, Raba7niSDK, RateLimitError, ValidationError, WebhookHandler, calculateRetryDelay, deepClone, Raba7niSDK as default, formatDate, generateRequestId, isMemberJoinedWebhook, isMemberLeftWebhook, isPointsEarnedWebhook, isPointsRedeemedWebhook, isTransactionCreatedWebhook, isValidISODate, normalizePhoneNumber, parseWebhookPayload, sanitizeString, validateAmount, validateCardId, validateEmail, validateName, verifyWebhookSignature };
497
+ export type { ApiError, ApiResponse, Card, CardRelationship, FindOrCreateMemberRequest, FindOrCreateMemberResponse, Member, MemberDetailsRequest, MemberDetailsResponse, MemberJoinedWebhookData, MemberLeftWebhookData, Order, OrderItem, OrderResponse, PointsEarnedWebhookData, PointsRedeemedWebhookData, Raba7niConfig, RateLimitInfo, Scope, Transaction, TransactionCreatedWebhookData, ValidateMemberRequest, ValidateMemberResponse, WebhookEvent, WebhookPayload };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAGnC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACrB,uBAAuB,EACvB,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,cAAc,EACd,YAAY,EACZ,cAAc,EACd,SAAS,EACT,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,UAAU,EACX,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,aAAa,EACb,WAAW,EACX,QAAQ,EACR,aAAa,EACb,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,EACzB,0BAA0B,EAC1B,KAAK,EACL,SAAS,EACT,aAAa,EACb,IAAI,EACJ,MAAM,EACN,gBAAgB,EAChB,WAAW,EACX,KAAK,EACL,YAAY,EACZ,cAAc,EACd,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,6BAA6B,EAC9B,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,YAAY,EACb,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,UAAU,IAAI,OAAO,EAAE,MAAM,OAAO,CAAC"}