@getspot/spot-widget 1.4.0 → 2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @getspot/spot-widget
2
2
 
3
+ ## 2.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - ccc78eb: Fix npm docs generation for interfaces and types
8
+
9
+ ## 2.0.0
10
+
11
+ ### Major Changes
12
+
13
+ - 4c59d56: Typescript support
14
+
3
15
  ## 1.4.0
4
16
 
5
17
  ### Minor Changes
package/README.md CHANGED
@@ -1,12 +1,569 @@
1
- # Spot Widget
1
+ # @getspot/spot-widget
2
2
 
3
- ## Description
4
- This is a UI component for displaying a quote offer to users in a checkout flow
3
+ Core JavaScript/TypeScript library for integrating Spot's refund guarantee widget into your applications.
5
4
 
6
5
  ## Installation
7
6
 
8
7
  ```bash
9
- npm install --save @getspot/spot-widget
8
+ npm install @getspot/spot-widget
10
9
  ```
11
10
 
12
- ## Usage
11
+ ## Quick Start
12
+
13
+ ```javascript
14
+ import SpotWidget from '@getspot/spot-widget';
15
+
16
+ // Create widget instance
17
+ const widget = new SpotWidget({
18
+ location: '#spot-widget-container', // CSS selector or DOM element
19
+ apiConfig: {
20
+ environment: 'production', // 'sandbox' for testing
21
+ partnerId: 'your-partner-id'
22
+ },
23
+ quoteRequestData: {
24
+ startDate: '2024-01-01T00:00:00Z',
25
+ endDate: '2024-01-07T23:59:59Z',
26
+ currencyCode: 'USD',
27
+ eventType: 'Ski Trip',
28
+ productType: 'Trip',
29
+ productDuration: 'Trip',
30
+ productPrice: 500,
31
+ productId: 'ski-trip-2024',
32
+ cartId: 'cart-123',
33
+ productName: 'Aspen Ski Trip 2024'
34
+ },
35
+ callbacks: {
36
+ onOptIn: (data) => {
37
+ console.log('User opted in:', data);
38
+ // Handle opt-in logic
39
+ },
40
+ onOptOut: (data) => {
41
+ console.log('User opted out:', data);
42
+ // Handle opt-out logic
43
+ },
44
+ onQuoteRetrieved: (quote) => {
45
+ console.log('Quote retrieved:', quote);
46
+ },
47
+ onError: (error) => {
48
+ console.error('Widget error:', error);
49
+ }
50
+ }
51
+ });
52
+ ```
53
+
54
+ ## TypeScript Support
55
+
56
+ This package is written in TypeScript and includes full type definitions.
57
+
58
+ ```typescript
59
+ import SpotWidget, { SpotWidgetOptions, SelectionData, Quote } from '@getspot/spot-widget';
60
+
61
+ const options: SpotWidgetOptions = {
62
+ // ... your configuration
63
+ };
64
+
65
+ const widget = new SpotWidget(options);
66
+ ```
67
+
68
+ ## Configuration
69
+
70
+ ### SpotWidgetOptions
71
+
72
+ | Option | Type | Required | Default | Description |
73
+ |--------|------|----------|---------|-------------|
74
+ | `location` | `string \| HTMLElement` | No | `"body"` | Target element for the widget |
75
+ | `apiConfig` | `ApiConfig` | Yes | - | API configuration |
76
+ | `quoteRequestData` | `QuoteRequestData` | Yes | - | Quote request information |
77
+ | `showTable` | `boolean` | No | `true` | Whether to show payout table |
78
+ | `optInSelected` | `boolean` | No | `false` | Pre-select opt-in option |
79
+ | `theme` | `Theme` | No | - | Custom styling |
80
+ | `callbacks` | `Callbacks` | No | `{}` | Event callbacks |
81
+
82
+ ### ApiConfig
83
+
84
+ ```typescript
85
+ {
86
+ environment: 'production' | 'sandbox' | 'local';
87
+ partnerId: string;
88
+ customEndpoint?: string; // Optional custom API endpoint
89
+ }
90
+ ```
91
+
92
+ ### QuoteRequestData
93
+
94
+ #### Single Product Quote
95
+
96
+ ```typescript
97
+ {
98
+ startDate: string; // ISO 8601 date
99
+ endDate: string; // ISO 8601 date
100
+ currencyCode: 'USD' | 'CAD' | 'AUD';
101
+ eventType: string; // Event description
102
+ productType: 'Pass' | 'Trip' | 'Registration';
103
+ productDuration: 'Daily' | 'Seasonal' | 'Trip' | 'Event';
104
+ productPrice: number; // Price in specified currency
105
+ productId: string; // Unique product identifier
106
+ cartId: string; // Shopping cart identifier
107
+ productName: string; // Human-readable product name
108
+ participantDescription?: string; // Optional participant info
109
+ }
110
+ ```
111
+
112
+ #### Batch Quote (Multiple Products)
113
+
114
+ ```typescript
115
+ {
116
+ cartInfo: {
117
+ cartId: string;
118
+ cartName: string;
119
+ currencyCode: 'USD' | 'CAD' | 'AUD';
120
+ };
121
+ items: Array<{
122
+ // All single product fields except cartId and currencyCode
123
+ cartItemId?: string; // Optional item identifier
124
+ }>;
125
+ }
126
+ ```
127
+
128
+ ## Widget Methods
129
+
130
+ ### updateQuote(newQuoteRequestData)
131
+
132
+ Update the widget with new quote data.
133
+
134
+ ```javascript
135
+ const success = await widget.updateQuote({
136
+ // new quote request data
137
+ });
138
+ console.log('Update successful:', success);
139
+ ```
140
+
141
+ **Returns:** `Promise<boolean>`
142
+
143
+ ### getSelection()
144
+
145
+ Get the current user selection.
146
+
147
+ ```javascript
148
+ const selection = widget.getSelection();
149
+ console.log('User selection:', selection);
150
+ ```
151
+
152
+ **Returns:** `SelectionData | null`
153
+
154
+ ### validateSelection()
155
+
156
+ Check if the user has made a selection.
157
+
158
+ ```javascript
159
+ const isValid = widget.validateSelection();
160
+ if (!isValid) {
161
+ console.log('Please make a selection');
162
+ }
163
+ ```
164
+
165
+ **Returns:** `boolean`
166
+
167
+ ### destroy()
168
+
169
+ Clean up the widget instance.
170
+
171
+ ```javascript
172
+ widget.destroy();
173
+ ```
174
+
175
+ ## Callbacks
176
+
177
+ ### onOptIn(data: SelectionData)
178
+
179
+ Called when user opts into the refund guarantee.
180
+
181
+ ```javascript
182
+ {
183
+ onOptIn: (data) => {
184
+ console.log('Opt-in data:', data);
185
+ // data.status === 'QUOTE_ACCEPTED'
186
+ // data.quoteId - unique quote identifier
187
+ // data.spotPrice - refund guarantee price
188
+ }
189
+ }
190
+ ```
191
+
192
+ ### onOptOut(data: SelectionData)
193
+
194
+ Called when user opts out of the refund guarantee.
195
+
196
+ ```javascript
197
+ {
198
+ onOptOut: (data) => {
199
+ console.log('Opt-out data:', data);
200
+ // data.status === 'QUOTE_DECLINED'
201
+ // data.quoteId - unique quote identifier
202
+ }
203
+ }
204
+ ```
205
+
206
+ ### onQuoteRetrieved(quote: Quote)
207
+
208
+ Called when a quote is successfully retrieved.
209
+
210
+ ```javascript
211
+ {
212
+ onQuoteRetrieved: (quote) => {
213
+ console.log('Quote:', quote);
214
+ // quote.id - quote identifier
215
+ // quote.spotPrice - refund guarantee price
216
+ // quote.communication - display text and labels
217
+ }
218
+ }
219
+ ```
220
+
221
+ ### onError(error: ErrorData)
222
+
223
+ Called when an error occurs.
224
+
225
+ ```javascript
226
+ {
227
+ onError: (error) => {
228
+ console.error('Error:', error);
229
+ // error.message - error description
230
+ // error.status - HTTP status code (if applicable)
231
+ // error.responseBody - API response (if applicable)
232
+ }
233
+ }
234
+ ```
235
+
236
+ ### noMatchingQuote(data)
237
+
238
+ Called when no quote is available for the request.
239
+
240
+ ```javascript
241
+ {
242
+ noMatchingQuote: (data) => {
243
+ console.log('No quote available:', data);
244
+ // Handle case where product isn't eligible
245
+ }
246
+ }
247
+ ```
248
+
249
+ ## Styling
250
+
251
+ Customize the widget appearance using the `theme` option:
252
+
253
+ ```javascript
254
+ const widget = new SpotWidget({
255
+ // ... other options
256
+ theme: {
257
+ primaryColor: '#007bff',
258
+ secondaryColor: '#6c757d',
259
+ borderRadius: '8px',
260
+ fontFamily: 'Arial, sans-serif',
261
+ fontSize: '14px'
262
+ // Any CSS custom properties (without -- prefix)
263
+ }
264
+ });
265
+ ```
266
+
267
+ ## Error Handling
268
+
269
+ Always implement comprehensive error handling:
270
+
271
+ ```javascript
272
+ const widget = new SpotWidget({
273
+ // ... configuration
274
+ callbacks: {
275
+ onError: (error) => {
276
+ // Log for debugging
277
+ console.error('Spot Widget Error:', error);
278
+
279
+ // Handle different error types
280
+ if (error.status === 404) {
281
+ console.log('Product not eligible for refund guarantee');
282
+ } else if (error.status >= 500) {
283
+ console.log('Service temporarily unavailable');
284
+ }
285
+
286
+ // Track in analytics
287
+ if (window.analytics) {
288
+ window.analytics.track('spot_widget_error', {
289
+ message: error.message,
290
+ status: error.status
291
+ });
292
+ }
293
+ },
294
+ noMatchingQuote: (data) => {
295
+ console.log('No refund guarantee available');
296
+ // Hide widget or show alternative messaging
297
+ }
298
+ }
299
+ });
300
+ ```
301
+
302
+ ## Environments
303
+
304
+ ### Sandbox (Development)
305
+
306
+ Use the sandbox environment for testing:
307
+
308
+ ```javascript
309
+ {
310
+ apiConfig: {
311
+ environment: 'sandbox',
312
+ partnerId: 'your-sandbox-partner-id'
313
+ }
314
+ }
315
+ ```
316
+
317
+ ### Production
318
+
319
+ Use the production environment for live applications:
320
+
321
+ ```javascript
322
+ {
323
+ apiConfig: {
324
+ environment: 'production',
325
+ partnerId: 'your-production-partner-id'
326
+ }
327
+ }
328
+ ```
329
+
330
+
331
+
332
+ ## API Reference
333
+
334
+ This package exports the following types and interfaces:
335
+
336
+ ### Interfaces
337
+
338
+ #### ApiConfig
339
+
340
+ ```typescript
341
+ export interface ApiConfig {
342
+ environment: 'sandbox' | 'production' | 'local';
343
+ partnerId: string;
344
+ customEndpoint?: string;
345
+ }
346
+ ```
347
+
348
+ #### QuoteMetadata
349
+
350
+ ```typescript
351
+ export interface QuoteMetadata {
352
+ segment?: string;
353
+ operator?: string;
354
+ channel?: string;
355
+ consumerId?: string;
356
+ }
357
+ ```
358
+
359
+ #### CartInfo
360
+
361
+ ```typescript
362
+ export interface CartInfo {
363
+ cartId: string;
364
+ cartName: string;
365
+ currencyCode: 'USD' | 'CAD' | 'AUD';
366
+ metadata?: QuoteMetadata;
367
+ isPartialPayment?: boolean;
368
+ }
369
+ ```
370
+
371
+ #### QuoteItem
372
+
373
+ ```typescript
374
+ export interface QuoteItem {
375
+ productPrice: number;
376
+ productType: 'Pass' | 'Trip' | 'Registration';
377
+ productDuration: 'Daily' | 'Seasonal' | 'Trip' | 'Event';
378
+ productId: string;
379
+ cartId: string;
380
+ cartName: string;
381
+ productName: string;
382
+ participantDescription?: string;
383
+ eventType: string;
384
+ currencyCode: 'USD' | 'CAD' | 'AUD';
385
+ startDate: string;
386
+ endDate: string;
387
+ partnerRiskEnd?: Date;
388
+ metadata?: QuoteMetadata;
389
+ isPartialPayment?: boolean;
390
+ hostCountry?: string;
391
+ hostCountryState?: string;
392
+ destinations?: string[];
393
+ dob?: string;
394
+ }
395
+ ```
396
+
397
+ #### BatchQuoteRequest
398
+
399
+ ```typescript
400
+ export interface BatchQuoteRequest {
401
+ cartInfo: CartInfo;
402
+ items: BatchQuoteItem[];
403
+ }
404
+ ```
405
+
406
+ #### QualifyingReason
407
+
408
+ ```typescript
409
+ export interface QualifyingReason {
410
+ rank: number;
411
+ name?: string;
412
+ benefitType?: {
413
+ name: string;
414
+ };
415
+ }
416
+ ```
417
+
418
+ #### PayoutScheduleItem
419
+
420
+ ```typescript
421
+ export interface PayoutScheduleItem {
422
+ text: string;
423
+ percent: string | number;
424
+ amount: number;
425
+ }
426
+ ```
427
+
428
+ #### Communication
429
+
430
+ ```typescript
431
+ export interface Communication {
432
+ name: string;
433
+ description: string;
434
+ bulletPoints: string[];
435
+ yesOptionText: string;
436
+ noOptionText: string;
437
+ legalDisclaimer: string;
438
+ termsAndConditionsUrl: string;
439
+ paymentTerms?: string;
440
+ }
441
+ ```
442
+
443
+ #### Quote
444
+
445
+ ```typescript
446
+ export interface Quote {
447
+ id: string;
448
+ cartItemId?: string;
449
+ spotPrice: number;
450
+ currencyCode: string;
451
+ communication: Communication;
452
+ payoutSchedule: PayoutScheduleItem[];
453
+ qualifyingReasons?: QualifyingReason[];
454
+ coveredItems?: string[];
455
+ originalQuotes?: Quote[];
456
+ }
457
+ ```
458
+
459
+ #### ApiResponse
460
+
461
+ ```typescript
462
+ export interface ApiResponse {
463
+ status: 'QUOTE_AVAILABLE' | 'QUOTES_AVAILABLE' | 'NO_MATCHING_QUOTE';
464
+ data?: Quote;
465
+ quotes?: Quote[];
466
+ totalSpotPrice?: number;
467
+ spotPrice?: number;
468
+ currencyCode?: string;
469
+ communication?: Communication;
470
+ payoutSchedule?: PayoutScheduleItem[];
471
+ coveredItems?: string[];
472
+ }
473
+ ```
474
+
475
+ #### SelectionData
476
+
477
+ ```typescript
478
+ export interface SelectionData {
479
+ status: 'QUOTE_ACCEPTED' | 'QUOTE_DECLINED';
480
+ spotPrice?: number;
481
+ quoteId?: string;
482
+ selection?: string;
483
+ batchQuoteDetails?: Array<{
484
+ quoteId: string;
485
+ productPrice: number;
486
+ cartItemId: string;
487
+ }>;
488
+ }
489
+ ```
490
+
491
+ #### Callbacks
492
+
493
+ ```typescript
494
+ export interface Callbacks {
495
+ onOptIn?: (data: SelectionData) => void;
496
+ onOptOut?: (data: SelectionData) => void;
497
+ onQuoteRetrieved?: (quote: Quote) => void;
498
+ onError?: (error: { message: string; status?: number; responseBody?: any }) => void;
499
+ noMatchingQuote?: (data: { status: string; data: QuoteRequestData }) => void;
500
+ }
501
+ ```
502
+
503
+ #### Theme
504
+
505
+ ```typescript
506
+ export interface Theme {
507
+ [key: string]: string;
508
+ }
509
+ ```
510
+
511
+ #### SpotWidgetOptions
512
+
513
+ ```typescript
514
+ export interface SpotWidgetOptions {
515
+ location?: string | HTMLElement;
516
+ showTable?: boolean;
517
+ optInSelected?: boolean;
518
+ apiConfig: ApiConfig;
519
+ quoteRequestData: QuoteRequestData;
520
+ callbacks?: Callbacks;
521
+ theme?: Theme;
522
+ isPartialPayment?: boolean;
523
+ }
524
+ ```
525
+
526
+ #### ElementOptions
527
+
528
+ ```typescript
529
+ export interface ElementOptions {
530
+ text?: string;
531
+ className?: string;
532
+ parent?: HTMLElement;
533
+ innerHTML?: string;
534
+ href?: string;
535
+ target?: string;
536
+ }
537
+ ```
538
+
539
+ ### Type Aliases
540
+
541
+ #### QuoteRequestData
542
+
543
+ ```typescript
544
+ export type QuoteRequestData = QuoteItem | BatchQuoteRequest;
545
+ ```
546
+
547
+ ## Framework Integration
548
+
549
+ This is the core library. For framework-specific wrappers:
550
+
551
+ - **React**: [@getspot/spot-widget-react](../react)
552
+ - **Vue 3**: [@getspot/spot-widget-vue](../vue)
553
+ - **Vue 2**: [@getspot/spot-widget-vue2](../vue2)
554
+
555
+ ## Browser Support
556
+
557
+ - Modern browsers (ES2020+)
558
+ - Chrome 80+
559
+ - Firefox 74+
560
+ - Safari 13+
561
+ - Edge 80+
562
+
563
+ ## License
564
+
565
+ See the main package for license information.
566
+
567
+ ## Support
568
+
569
+ For support, please contact [support@getspot.com](mailto:support@getspot.com).
@@ -0,0 +1,12 @@
1
+ /// <reference types="jest" />
2
+ export declare const renderHeader: jest.Mock<any, any, any>;
3
+ export declare const renderBenefits: jest.Mock<any, any, any>;
4
+ export declare const renderQualifyingReasons: jest.Mock<any, any, any>;
5
+ export declare const renderPayoutTable: jest.Mock<any, any, any>;
6
+ export declare const renderConsentSection: jest.Mock<any, any, any>;
7
+ export declare const renderError: jest.Mock<any, any, any>;
8
+ export declare const renderNoMatchingQuote: jest.Mock<any, any, any>;
9
+ export declare const addEventListeners: jest.Mock<any, any, any>;
10
+ export declare const toggleOptIn: jest.Mock<any, any, any>;
11
+ export declare const updateQualifyingReasonVisibility: jest.Mock<any, any, any>;
12
+ //# sourceMappingURL=ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/__mocks__/ui.ts"],"names":[],"mappings":";AAEA,eAAO,MAAM,YAAY,0BAA2D,CAAC;AACrF,eAAO,MAAM,cAAc,0BAAY,CAAC;AACxC,eAAO,MAAM,uBAAuB,0BAAY,CAAC;AACjD,eAAO,MAAM,iBAAiB,0BAAY,CAAC;AAC3C,eAAO,MAAM,oBAAoB,0BAAY,CAAC;AAC9C,eAAO,MAAM,WAAW,0BAAY,CAAC;AACrC,eAAO,MAAM,qBAAqB,0BAAY,CAAC;AAC/C,eAAO,MAAM,iBAAiB,0BAAY,CAAC;AAC3C,eAAO,MAAM,WAAW,0BAAY,CAAC;AACrC,eAAO,MAAM,gCAAgC,0BAAY,CAAC"}
package/dist/api.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ import type { ApiResponse, QuoteRequestData, BatchQuoteRequest } from './types.js';
2
+ /**
3
+ * Retrieve quote from Spot API
4
+ * @param endpoint – Spot API URL
5
+ * @param partnerId – partner UUID
6
+ * @param payload – quoteRequestData
7
+ * @returns Promise resolving to API response
8
+ */
9
+ export declare function fetchQuote(endpoint: string, partnerId: string, payload: QuoteRequestData): Promise<ApiResponse>;
10
+ /**
11
+ * Retrieve batch quote from Spot API
12
+ * @param endpoint – Spot API URL
13
+ * @param partnerId – partner UUID
14
+ * @param batchPayload – batch request data with items array
15
+ * @returns Promise resolving to API response
16
+ */
17
+ export declare function fetchBatchQuote(endpoint: string, partnerId: string, batchPayload: any): Promise<ApiResponse>;
18
+ /**
19
+ * Retrieve multiple quotes in parallel from Spot API
20
+ * @param endpoint – Spot API URL
21
+ * @param partnerId – partner UUID
22
+ * @param batchData – batch quote data with cartInfo and items
23
+ * @returns Promise resolving to formatted API response
24
+ */
25
+ export declare function fetchMultipleQuotes(endpoint: string, partnerId: string, batchData: BatchQuoteRequest): Promise<ApiResponse>;
26
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAY,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE7F;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,WAAW,CAAC,CAwBtB;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,GAAG,GAChB,OAAO,CAAC,WAAW,CAAC,CAyBtB;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,iBAAiB,GAC3B,OAAO,CAAC,WAAW,CAAC,CA8EtB"}
@@ -0,0 +1,25 @@
1
+ import type { SpotWidgetOptions, SelectionData } from "./types.js";
2
+ declare class SpotWidget {
3
+ private options;
4
+ private root;
5
+ private currentSelection;
6
+ private container?;
7
+ private paymentTermsEl?;
8
+ private errorEl?;
9
+ private quote?;
10
+ private _onResize;
11
+ constructor(options?: Partial<SpotWidgetOptions>);
12
+ private _init;
13
+ private _renderWidget;
14
+ private _updateLayout;
15
+ private _setupOptionListeners;
16
+ showSelectionError(): void;
17
+ hideSelectionError(): void;
18
+ validateSelection(): boolean;
19
+ updateQuote(newQuoteRequestData: SpotWidgetOptions['quoteRequestData']): Promise<boolean>;
20
+ getSelection(): SelectionData | null;
21
+ destroy(): void;
22
+ }
23
+ export default SpotWidget;
24
+ export type { SpotWidgetOptions, SelectionData, Quote, ApiConfig, QuoteRequestData, QuoteItem, BatchQuoteItem, BatchQuoteRequest, CartInfo, QualifyingReason, PayoutScheduleItem, Communication, ApiResponse, ApiError, ElementOptions, QuoteMetadata, Callbacks, Theme } from './types.js';
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,iBAAiB,EAAS,aAAa,EAAqB,MAAM,YAAY,CAAC;AAkB7F,cAAM,UAAU;IACd,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,IAAI,CAAc;IAC1B,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,SAAS,CAAC,CAAc;IAChC,OAAO,CAAC,cAAc,CAAC,CAAc;IACrC,OAAO,CAAC,OAAO,CAAC,CAAc;IAC9B,OAAO,CAAC,KAAK,CAAC,CAAQ;IACtB,OAAO,CAAC,SAAS,CAAa;gBAElB,OAAO,GAAE,OAAO,CAAC,iBAAiB,CAAM;YAqBtC,KAAK;IAgFnB,OAAO,CAAC,aAAa;IAiDrB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,qBAAqB;IA6F7B,kBAAkB,IAAI,IAAI;IAgB1B,kBAAkB,IAAI,IAAI;IAM1B,iBAAiB,IAAI,OAAO;IAgBtB,WAAW,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAqE/F,YAAY,IAAI,aAAa,GAAG,IAAI;IAiCpC,OAAO,IAAI,IAAI;CAMhB;AAED,eAAe,UAAU,CAAC;AAC1B,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,KAAK,EACL,SAAS,EACT,gBAAgB,EAChB,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACR,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,QAAQ,EACR,cAAc,EACd,aAAa,EACb,SAAS,EACT,KAAK,EACN,MAAM,YAAY,CAAC"}