catalist-support-agent 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.
Files changed (140) hide show
  1. package/dist/admin-portal.d.ts +43 -0
  2. package/dist/admin-portal.d.ts.map +1 -0
  3. package/dist/admin-portal.js +166 -0
  4. package/dist/admin-portal.js.map +1 -0
  5. package/dist/analysis/entities.d.ts +73 -0
  6. package/dist/analysis/entities.d.ts.map +1 -0
  7. package/dist/analysis/entities.js +378 -0
  8. package/dist/analysis/entities.js.map +1 -0
  9. package/dist/analysis/index.d.ts +44 -0
  10. package/dist/analysis/index.d.ts.map +1 -0
  11. package/dist/analysis/index.js +243 -0
  12. package/dist/analysis/index.js.map +1 -0
  13. package/dist/analysis/intent.d.ts +49 -0
  14. package/dist/analysis/intent.d.ts.map +1 -0
  15. package/dist/analysis/intent.js +320 -0
  16. package/dist/analysis/intent.js.map +1 -0
  17. package/dist/analysis/sentiment.d.ts +57 -0
  18. package/dist/analysis/sentiment.d.ts.map +1 -0
  19. package/dist/analysis/sentiment.js +351 -0
  20. package/dist/analysis/sentiment.js.map +1 -0
  21. package/dist/brand/compliance.d.ts +122 -0
  22. package/dist/brand/compliance.d.ts.map +1 -0
  23. package/dist/brand/compliance.js +378 -0
  24. package/dist/brand/compliance.js.map +1 -0
  25. package/dist/brand/forbidden-terms.d.ts +99 -0
  26. package/dist/brand/forbidden-terms.d.ts.map +1 -0
  27. package/dist/brand/forbidden-terms.js +265 -0
  28. package/dist/brand/forbidden-terms.js.map +1 -0
  29. package/dist/brand/index.d.ts +10 -0
  30. package/dist/brand/index.d.ts.map +1 -0
  31. package/dist/brand/index.js +12 -0
  32. package/dist/brand/index.js.map +1 -0
  33. package/dist/config.d.ts +325 -0
  34. package/dist/config.d.ts.map +1 -0
  35. package/dist/config.js +492 -0
  36. package/dist/config.js.map +1 -0
  37. package/dist/delivery/index.d.ts +84 -0
  38. package/dist/delivery/index.d.ts.map +1 -0
  39. package/dist/delivery/index.js +435 -0
  40. package/dist/delivery/index.js.map +1 -0
  41. package/dist/embeddings/cache.d.ts +96 -0
  42. package/dist/embeddings/cache.d.ts.map +1 -0
  43. package/dist/embeddings/cache.js +193 -0
  44. package/dist/embeddings/cache.js.map +1 -0
  45. package/dist/embeddings/index.d.ts +152 -0
  46. package/dist/embeddings/index.d.ts.map +1 -0
  47. package/dist/embeddings/index.js +337 -0
  48. package/dist/embeddings/index.js.map +1 -0
  49. package/dist/embeddings/openai-client.d.ts +67 -0
  50. package/dist/embeddings/openai-client.d.ts.map +1 -0
  51. package/dist/embeddings/openai-client.js +190 -0
  52. package/dist/embeddings/openai-client.js.map +1 -0
  53. package/dist/errors.d.ts +302 -0
  54. package/dist/errors.d.ts.map +1 -0
  55. package/dist/errors.js +508 -0
  56. package/dist/errors.js.map +1 -0
  57. package/dist/escalation/index.d.ts +93 -0
  58. package/dist/escalation/index.d.ts.map +1 -0
  59. package/dist/escalation/index.js +436 -0
  60. package/dist/escalation/index.js.map +1 -0
  61. package/dist/extraction/deduplication.d.ts +97 -0
  62. package/dist/extraction/deduplication.d.ts.map +1 -0
  63. package/dist/extraction/deduplication.js +271 -0
  64. package/dist/extraction/deduplication.js.map +1 -0
  65. package/dist/extraction/gmail-extractor.d.ts +160 -0
  66. package/dist/extraction/gmail-extractor.d.ts.map +1 -0
  67. package/dist/extraction/gmail-extractor.js +396 -0
  68. package/dist/extraction/gmail-extractor.js.map +1 -0
  69. package/dist/extraction/gmail-token-manager.d.ts +36 -0
  70. package/dist/extraction/gmail-token-manager.d.ts.map +1 -0
  71. package/dist/extraction/gmail-token-manager.js +146 -0
  72. package/dist/extraction/gmail-token-manager.js.map +1 -0
  73. package/dist/extraction/index.d.ts +13 -0
  74. package/dist/extraction/index.d.ts.map +1 -0
  75. package/dist/extraction/index.js +20 -0
  76. package/dist/extraction/index.js.map +1 -0
  77. package/dist/extraction/pii-handler.d.ts +100 -0
  78. package/dist/extraction/pii-handler.d.ts.map +1 -0
  79. package/dist/extraction/pii-handler.js +295 -0
  80. package/dist/extraction/pii-handler.js.map +1 -0
  81. package/dist/extraction/pipeline.d.ts +94 -0
  82. package/dist/extraction/pipeline.d.ts.map +1 -0
  83. package/dist/extraction/pipeline.js +380 -0
  84. package/dist/extraction/pipeline.js.map +1 -0
  85. package/dist/extraction/quality-filter.d.ts +99 -0
  86. package/dist/extraction/quality-filter.d.ts.map +1 -0
  87. package/dist/extraction/quality-filter.js +370 -0
  88. package/dist/extraction/quality-filter.js.map +1 -0
  89. package/dist/extraction/rate-limiter.d.ts +90 -0
  90. package/dist/extraction/rate-limiter.d.ts.map +1 -0
  91. package/dist/extraction/rate-limiter.js +242 -0
  92. package/dist/extraction/rate-limiter.js.map +1 -0
  93. package/dist/extraction/state-manager.d.ts +126 -0
  94. package/dist/extraction/state-manager.d.ts.map +1 -0
  95. package/dist/extraction/state-manager.js +344 -0
  96. package/dist/extraction/state-manager.js.map +1 -0
  97. package/dist/generation/index.d.ts +75 -0
  98. package/dist/generation/index.d.ts.map +1 -0
  99. package/dist/generation/index.js +641 -0
  100. package/dist/generation/index.js.map +1 -0
  101. package/dist/index.d.ts +96 -0
  102. package/dist/index.d.ts.map +1 -0
  103. package/dist/index.js +233 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/intake/index.d.ts +15 -0
  106. package/dist/intake/index.d.ts.map +1 -0
  107. package/dist/intake/index.js +19 -0
  108. package/dist/intake/index.js.map +1 -0
  109. package/dist/intake/normalizer.d.ts +163 -0
  110. package/dist/intake/normalizer.d.ts.map +1 -0
  111. package/dist/intake/normalizer.js +309 -0
  112. package/dist/intake/normalizer.js.map +1 -0
  113. package/dist/intake/postmark.d.ts +72 -0
  114. package/dist/intake/postmark.d.ts.map +1 -0
  115. package/dist/intake/postmark.js +276 -0
  116. package/dist/intake/postmark.js.map +1 -0
  117. package/dist/intake/slack.d.ts +106 -0
  118. package/dist/intake/slack.d.ts.map +1 -0
  119. package/dist/intake/slack.js +378 -0
  120. package/dist/intake/slack.js.map +1 -0
  121. package/dist/intake/twilio.d.ts +86 -0
  122. package/dist/intake/twilio.d.ts.map +1 -0
  123. package/dist/intake/twilio.js +283 -0
  124. package/dist/intake/twilio.js.map +1 -0
  125. package/dist/knowledge/index.d.ts +100 -0
  126. package/dist/knowledge/index.d.ts.map +1 -0
  127. package/dist/knowledge/index.js +516 -0
  128. package/dist/knowledge/index.js.map +1 -0
  129. package/dist/knowledge/invoice-resolver.d.ts +62 -0
  130. package/dist/knowledge/invoice-resolver.d.ts.map +1 -0
  131. package/dist/knowledge/invoice-resolver.js +267 -0
  132. package/dist/knowledge/invoice-resolver.js.map +1 -0
  133. package/dist/types.d.ts +535 -0
  134. package/dist/types.d.ts.map +1 -0
  135. package/dist/types.js +48 -0
  136. package/dist/types.js.map +1 -0
  137. package/ga-service-account.json +13 -0
  138. package/gmail-knowledge-migration.sql +149 -0
  139. package/nul +1 -0
  140. package/package.json +55 -0
@@ -0,0 +1,283 @@
1
+ /**
2
+ * Twilio SMS Webhook Handler
3
+ *
4
+ * Receives incoming SMS messages via Twilio webhook, validates signatures,
5
+ * and normalizes SMS content into the standard message format.
6
+ */
7
+ import { createHmac, timingSafeEqual } from 'crypto';
8
+ import { config } from '../config.js';
9
+ import { IntakeError, WebhookValidationError } from '../errors.js';
10
+ import { normalizeTwilioSms, generateContentHash, validateMessageContent, scanAndAnnotateMessage, normalizePhoneNumber, } from './normalizer.js';
11
+ // =============================================================================
12
+ // Signature Validation
13
+ // =============================================================================
14
+ /**
15
+ * Validate Twilio webhook signature using HMAC-SHA1
16
+ *
17
+ * Twilio signs webhooks using the auth token and the full URL + params
18
+ */
19
+ export function validateTwilioSignature(signature, url, params, authToken) {
20
+ if (!signature || !authToken) {
21
+ return false;
22
+ }
23
+ // Build the string to sign
24
+ // Twilio sorts the params alphabetically and concatenates
25
+ const sortedKeys = Object.keys(params).sort();
26
+ const paramString = sortedKeys.map((key) => `${key}${params[key]}`).join('');
27
+ const stringToSign = url + paramString;
28
+ // Generate expected signature
29
+ const expectedSignature = createHmac('sha1', authToken)
30
+ .update(stringToSign, 'utf-8')
31
+ .digest('base64');
32
+ // Timing-safe comparison
33
+ try {
34
+ const sig1 = Buffer.from(signature);
35
+ const sig2 = Buffer.from(expectedSignature);
36
+ if (sig1.length !== sig2.length) {
37
+ return false;
38
+ }
39
+ return timingSafeEqual(sig1, sig2);
40
+ }
41
+ catch {
42
+ return false;
43
+ }
44
+ }
45
+ /**
46
+ * Validate Twilio webhook request
47
+ */
48
+ export function validateTwilioWebhook(signature, url, params) {
49
+ const authToken = config.twilio.authToken;
50
+ if (!authToken) {
51
+ // If no auth token configured, skip signature validation but check required fields
52
+ return !!(params.MessageSid && params.From && params.To);
53
+ }
54
+ return validateTwilioSignature(signature, url, params, authToken);
55
+ }
56
+ // =============================================================================
57
+ // SMS Processing
58
+ // =============================================================================
59
+ /**
60
+ * Parse Twilio webhook body (URL-encoded)
61
+ */
62
+ export function parseTwilioBody(body) {
63
+ const params = new URLSearchParams(body);
64
+ const result = {};
65
+ for (const [key, value] of params.entries()) {
66
+ result[key] = value;
67
+ }
68
+ return result;
69
+ }
70
+ /**
71
+ * Process an inbound Twilio SMS
72
+ */
73
+ export async function processTwilioSms(payload) {
74
+ try {
75
+ // Normalize the SMS into standard message format
76
+ const message = normalizeTwilioSms(payload);
77
+ // Validate content exists
78
+ validateMessageContent(message);
79
+ // Generate content hash for deduplication
80
+ const contentHash = generateContentHash(message);
81
+ // Scan for forbidden terms
82
+ const { hasForbiddenTerms, detectedTerms } = scanAndAnnotateMessage(message);
83
+ return {
84
+ success: true,
85
+ message,
86
+ contentHash,
87
+ hasForbiddenTerms,
88
+ detectedTerms,
89
+ };
90
+ }
91
+ catch (error) {
92
+ if (error instanceof IntakeError) {
93
+ return {
94
+ success: false,
95
+ hasForbiddenTerms: false,
96
+ detectedTerms: [],
97
+ error: error.message,
98
+ };
99
+ }
100
+ return {
101
+ success: false,
102
+ hasForbiddenTerms: false,
103
+ detectedTerms: [],
104
+ error: error instanceof Error ? error.message : 'Unknown error processing SMS',
105
+ };
106
+ }
107
+ }
108
+ /**
109
+ * Full webhook handler for Twilio inbound SMS
110
+ */
111
+ export async function handleTwilioInbound(rawBody, signature, webhookUrl) {
112
+ // Parse URL-encoded body
113
+ const payload = parseTwilioBody(rawBody);
114
+ // Convert to params object for signature validation
115
+ const params = {};
116
+ for (const [key, value] of Object.entries(payload)) {
117
+ if (typeof value === 'string') {
118
+ params[key] = value;
119
+ }
120
+ }
121
+ // Validate webhook signature
122
+ if (!validateTwilioWebhook(signature, webhookUrl, params)) {
123
+ throw new WebhookValidationError('sms', {
124
+ context: { reason: 'Invalid Twilio signature' },
125
+ });
126
+ }
127
+ // Process the SMS
128
+ return processTwilioSms(payload);
129
+ }
130
+ // =============================================================================
131
+ // SMS Utilities
132
+ // =============================================================================
133
+ /**
134
+ * Check if message is a STOP/unsubscribe request
135
+ */
136
+ export function isOptOutMessage(body) {
137
+ const normalized = body.trim().toLowerCase();
138
+ const optOutKeywords = [
139
+ 'stop',
140
+ 'unsubscribe',
141
+ 'cancel',
142
+ 'end',
143
+ 'quit',
144
+ 'optout',
145
+ 'opt out',
146
+ 'stopall',
147
+ 'stop all',
148
+ ];
149
+ return optOutKeywords.includes(normalized);
150
+ }
151
+ /**
152
+ * Check if message is a help request
153
+ */
154
+ export function isHelpRequest(body) {
155
+ const normalized = body.trim().toLowerCase();
156
+ const helpKeywords = ['help', 'info', 'support'];
157
+ return helpKeywords.includes(normalized);
158
+ }
159
+ /**
160
+ * Classify SMS message type
161
+ */
162
+ export function classifySms(sms) {
163
+ const body = sms.Body?.trim() ?? '';
164
+ if (!body) {
165
+ return {
166
+ shouldProcess: false,
167
+ reason: 'Empty message',
168
+ classification: 'empty',
169
+ };
170
+ }
171
+ if (isOptOutMessage(body)) {
172
+ return {
173
+ shouldProcess: false,
174
+ reason: 'Opt-out request',
175
+ classification: 'opt_out',
176
+ };
177
+ }
178
+ if (isHelpRequest(body)) {
179
+ return {
180
+ shouldProcess: true,
181
+ classification: 'help',
182
+ };
183
+ }
184
+ return {
185
+ shouldProcess: true,
186
+ classification: 'support',
187
+ };
188
+ }
189
+ // =============================================================================
190
+ // MMS Handling
191
+ // =============================================================================
192
+ /**
193
+ * Check if SMS includes media attachments (MMS)
194
+ */
195
+ export function hasMmsAttachments(sms) {
196
+ const numMedia = parseInt(sms.NumMedia || '0', 10);
197
+ return numMedia > 0;
198
+ }
199
+ /**
200
+ * Extract MMS media URLs
201
+ */
202
+ export function extractMmsMedia(sms) {
203
+ const numMedia = parseInt(sms.NumMedia || '0', 10);
204
+ const media = [];
205
+ for (let i = 0; i < numMedia; i++) {
206
+ const urlKey = `MediaUrl${i}`;
207
+ const typeKey = `MediaContentType${i}`;
208
+ const url = sms[urlKey];
209
+ const contentType = sms[typeKey] || 'application/octet-stream';
210
+ if (url) {
211
+ media.push({ url, contentType });
212
+ }
213
+ }
214
+ return media;
215
+ }
216
+ // =============================================================================
217
+ // Phone Number Utilities
218
+ // =============================================================================
219
+ /**
220
+ * Extract country code from phone number
221
+ */
222
+ export function extractCountryCode(phone) {
223
+ const normalized = normalizePhoneNumber(phone);
224
+ // Common country codes
225
+ const countryCodes = {
226
+ '+1': 'US/CA',
227
+ '+44': 'UK',
228
+ '+61': 'AU',
229
+ '+49': 'DE',
230
+ '+33': 'FR',
231
+ '+34': 'ES',
232
+ '+39': 'IT',
233
+ '+81': 'JP',
234
+ '+86': 'CN',
235
+ '+91': 'IN',
236
+ };
237
+ for (const [code, country] of Object.entries(countryCodes)) {
238
+ if (normalized.startsWith(code)) {
239
+ return country;
240
+ }
241
+ }
242
+ return undefined;
243
+ }
244
+ /**
245
+ * Determine if phone number is US/Canada
246
+ */
247
+ export function isNorthAmericanNumber(phone) {
248
+ const normalized = normalizePhoneNumber(phone);
249
+ return normalized.startsWith('+1');
250
+ }
251
+ // =============================================================================
252
+ // Response Generation for Twilio
253
+ // =============================================================================
254
+ /**
255
+ * Generate TwiML response for immediate reply
256
+ */
257
+ export function generateTwimlResponse(message) {
258
+ if (!message) {
259
+ // Empty response - no auto-reply
260
+ return '<?xml version="1.0" encoding="UTF-8"?><Response></Response>';
261
+ }
262
+ // Escape XML entities
263
+ const escaped = message
264
+ .replace(/&/g, '&amp;')
265
+ .replace(/</g, '&lt;')
266
+ .replace(/>/g, '&gt;')
267
+ .replace(/"/g, '&quot;')
268
+ .replace(/'/g, '&apos;');
269
+ return `<?xml version="1.0" encoding="UTF-8"?><Response><Message>${escaped}</Message></Response>`;
270
+ }
271
+ /**
272
+ * Generate TwiML for opt-out confirmation
273
+ */
274
+ export function generateOptOutResponse() {
275
+ return generateTwimlResponse("You've been unsubscribed from Catalist support messages. Reply HELP if you need assistance.");
276
+ }
277
+ /**
278
+ * Generate TwiML for help response
279
+ */
280
+ export function generateHelpResponse() {
281
+ return generateTwimlResponse('Catalist Support: Reply with your question and we\'ll get back to you. For urgent matters, email support@catalist.deals');
282
+ }
283
+ //# sourceMappingURL=twilio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"twilio.js","sourceRoot":"","sources":["../../src/intake/twilio.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Knowledge Retrieval Module
3
+ *
4
+ * Retrieves relevant context for response generation:
5
+ * - Customer data from clients table
6
+ * - Product information from catalog
7
+ * - Order history and status
8
+ * - Policy and FAQ content
9
+ * - Similar historical conversations
10
+ * - Pre-approved response templates
11
+ */
12
+ import { type Config } from '../config.js';
13
+ import type { KnowledgeContext, CustomerContext, ProductContext, OrderContext, SimilarConversation, ResponseTemplate, InboundMessage, AnalysisResult, IntentCategory, CustomerId } from '../types.js';
14
+ export declare class KnowledgeRetrievalService {
15
+ private supabase;
16
+ private embeddingService;
17
+ private effectiveConfig;
18
+ constructor(configOverride?: Config);
19
+ /**
20
+ * Retrieve complete knowledge context for a message
21
+ */
22
+ retrieveContext(message: InboundMessage, analysis: AnalysisResult): Promise<KnowledgeContext>;
23
+ /**
24
+ * Retrieve customer data by sender identifiers
25
+ *
26
+ * Note: Uses the "User" table (not "Client") per actual Catalist schema
27
+ */
28
+ retrieveCustomerData(message: InboundMessage): Promise<CustomerContext | undefined>;
29
+ /**
30
+ * Map database User record to CustomerContext
31
+ */
32
+ private mapUserToCustomerContext;
33
+ /**
34
+ * Retrieve order history for a customer with associated Invoice data
35
+ *
36
+ * Note: Uses "PurchaseOrder" table (not "Order") per actual Catalist schema
37
+ * Also fetches Invoice data for each order via the Invoice table
38
+ */
39
+ retrieveOrderHistory(customerId: CustomerId, specificOrderNumbers?: string[]): Promise<OrderContext[]>;
40
+ /**
41
+ * Retrieve product information by name or SKU
42
+ *
43
+ * Note: Uses actual Catalist Catalog schema with selling_price, selling_status
44
+ */
45
+ retrieveProductInfo(productNames?: string[], productSkus?: string[]): Promise<ProductContext[]>;
46
+ /**
47
+ * Map Catalog record to ProductContext
48
+ *
49
+ * Note: Catalist uses selling_status (boolean) not quantity
50
+ */
51
+ private mapCatalogToProductContext;
52
+ /**
53
+ * Retrieve response templates/knowledge for an intent
54
+ *
55
+ * Note: Uses support_knowledge table which stores Q&A pairs
56
+ */
57
+ retrieveTemplates(intent: IntentCategory): Promise<ResponseTemplate[]>;
58
+ /**
59
+ * Retrieve similar historical conversations using semantic search
60
+ *
61
+ * Uses pgvector for embedding similarity search against gmail_knowledge_entries.
62
+ * Falls back to full-text search if embedding service is unavailable.
63
+ */
64
+ retrieveSimilarConversations(messageText: string, intent: IntentCategory): Promise<SimilarConversation[]>;
65
+ /**
66
+ * Map resolution indicator string to ResolutionType enum
67
+ */
68
+ private mapResolutionIndicator;
69
+ /**
70
+ * Build a summary string from question subject and text
71
+ */
72
+ private buildConversationSummary;
73
+ }
74
+ export declare function getKnowledgeRetrievalService(configOverride?: Config): KnowledgeRetrievalService;
75
+ /**
76
+ * Retrieve knowledge context for a message
77
+ */
78
+ export declare function retrieveKnowledgeContext(message: InboundMessage, analysis: AnalysisResult): Promise<KnowledgeContext>;
79
+ /**
80
+ * Quick customer lookup
81
+ */
82
+ export declare function lookupCustomer(message: InboundMessage): Promise<CustomerContext | undefined>;
83
+ /**
84
+ * Check if knowledge context has sufficient data for autonomous response
85
+ */
86
+ export declare function hassufficientContext(context: KnowledgeContext): boolean;
87
+ /**
88
+ * Calculate overall context confidence
89
+ */
90
+ export declare function calculateContextConfidence(context: KnowledgeContext): number;
91
+ export { InvoiceResolverService, getInvoiceResolverService, resolveInvoice, isInvoiceRelatedQuery, } from './invoice-resolver.js';
92
+ /**
93
+ * Alias for getKnowledgeRetrievalService (used by main index.ts)
94
+ */
95
+ export declare const getKnowledgeService: typeof getKnowledgeRetrievalService;
96
+ /**
97
+ * Alias for retrieveKnowledgeContext (used by main index.ts)
98
+ */
99
+ export declare const retrieveKnowledge: typeof retrieveKnowledgeContext;
100
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/knowledge/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAInD,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,YAAY,EAGZ,mBAAmB,EACnB,gBAAgB,EAEhB,cAAc,EACd,cAAc,EACd,cAAc,EACd,UAAU,EACX,MAAM,aAAa,CAAC;AAOrB,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,eAAe,CAAS;gBAEpB,cAAc,CAAC,EAAE,MAAM;IAmBnC;;OAEG;IACG,eAAe,CACnB,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,gBAAgB,CAAC;IAsG5B;;;;OAIG;IACG,oBAAoB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAsCzF;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAoBhC;;;;;OAKG;IACG,oBAAoB,CACxB,UAAU,EAAE,UAAU,EACtB,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAC9B,OAAO,CAAC,YAAY,EAAE,CAAC;IAsE1B;;;;OAIG;IACG,mBAAmB,CACvB,YAAY,CAAC,EAAE,MAAM,EAAE,EACvB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,cAAc,EAAE,CAAC;IAsC5B;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;IAgClC;;;;OAIG;IACG,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAwC5E;;;;;OAKG;IACG,4BAA4B,CAChC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAkEjC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAuB9B;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAiBjC;AAQD,wBAAgB,4BAA4B,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,yBAAyB,CAU/F;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAE3B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAEtC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAUvE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAe5E;AAMD,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,cAAc,EACd,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAM/B;;GAEG;AACH,eAAO,MAAM,mBAAmB,qCAA+B,CAAC;AAEhE;;GAEG;AACH,eAAO,MAAM,iBAAiB,iCAA2B,CAAC"}