@myscheme/voice-navigation-sdk 0.1.6 → 0.1.8

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.
@@ -9,12 +9,7 @@ function getSignatureKey(key, dateStamp, region, service) {
9
9
  const kSigning = sign(kService, "aws4_request");
10
10
  return kSigning;
11
11
  }
12
- export async function bedrockHandler(req, res) {
13
- if (req.method !== "POST") {
14
- res.setHeader("Allow", ["POST"]);
15
- res.status(405).json({ error: "Method not allowed" });
16
- return;
17
- }
12
+ async function invokeBedrock(requestBody) {
18
13
  const region = process.env.AWS_REGION || "ap-south-1";
19
14
  const accessKey = process.env.AWS_ACCESS_KEY_ID;
20
15
  const secretKey = process.env.AWS_SECRET_ACCESS_KEY;
@@ -22,16 +17,21 @@ export async function bedrockHandler(req, res) {
22
17
  const modelId = process.env.AWS_MODEL_ID || "anthropic.claude-3-sonnet-20240229-v1:0";
23
18
  if (!accessKey || !secretKey) {
24
19
  console.error("[VoiceNavigation] Missing AWS credentials. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in your .env file");
25
- res.status(500).json({
26
- error: "Missing AWS credentials",
27
- hint: "Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables",
28
- });
29
- return;
20
+ return {
21
+ success: false,
22
+ statusCode: 500,
23
+ error: {
24
+ error: "Missing AWS credentials",
25
+ hint: "Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables",
26
+ },
27
+ };
30
28
  }
31
- const requestBody = req.body?.body;
32
29
  if (!requestBody) {
33
- res.status(400).json({ error: "Missing request body" });
34
- return;
30
+ return {
31
+ success: false,
32
+ statusCode: 400,
33
+ error: { error: "Missing request body" },
34
+ };
35
35
  }
36
36
  const body = JSON.stringify(requestBody);
37
37
  const service = "bedrock";
@@ -95,20 +95,77 @@ export async function bedrockHandler(req, res) {
95
95
  if (!response.ok) {
96
96
  const errorText = await response.text();
97
97
  console.error("[VoiceNavigation] Bedrock API error:", response.status, errorText);
98
- res.status(response.status).json({
99
- error: "Bedrock API error",
100
- details: errorText,
101
- });
102
- return;
98
+ return {
99
+ success: false,
100
+ statusCode: response.status,
101
+ error: {
102
+ error: "Bedrock API error",
103
+ details: errorText,
104
+ },
105
+ };
103
106
  }
104
107
  const json = await response.json();
105
- res.status(200).json(json);
108
+ return {
109
+ success: true,
110
+ statusCode: 200,
111
+ data: json,
112
+ };
106
113
  }
107
114
  catch (error) {
108
115
  console.error("[VoiceNavigation] Bedrock action extraction error:", error);
109
- res.status(500).json({
110
- error: "Failed to extract action",
116
+ return {
117
+ success: false,
118
+ statusCode: 500,
119
+ error: {
120
+ error: "Failed to extract action",
121
+ message: error instanceof Error ? error.message : "Unknown error",
122
+ },
123
+ };
124
+ }
125
+ }
126
+ export async function bedrockHandler(req, res) {
127
+ if (req.method !== "POST") {
128
+ res.setHeader("Allow", ["POST"]);
129
+ res.status(405).json({ error: "Method not allowed" });
130
+ return;
131
+ }
132
+ const requestBody = req.body?.body;
133
+ const result = await invokeBedrock(requestBody);
134
+ if (result.success && result.data) {
135
+ res.status(result.statusCode).json(result.data);
136
+ }
137
+ else {
138
+ res.status(result.statusCode).json(result.error);
139
+ }
140
+ }
141
+ export async function BedrockPOST(request) {
142
+ try {
143
+ const body = await request.json();
144
+ const requestBody = body?.body;
145
+ const result = await invokeBedrock(requestBody);
146
+ const headers = {
147
+ "Content-Type": "application/json",
148
+ };
149
+ if (result.success && result.data) {
150
+ return new Response(JSON.stringify(result.data), {
151
+ status: result.statusCode,
152
+ headers,
153
+ });
154
+ }
155
+ else {
156
+ return new Response(JSON.stringify(result.error), {
157
+ status: result.statusCode,
158
+ headers,
159
+ });
160
+ }
161
+ }
162
+ catch (error) {
163
+ return new Response(JSON.stringify({
164
+ error: "Invalid request",
111
165
  message: error instanceof Error ? error.message : "Unknown error",
166
+ }), {
167
+ status: 400,
168
+ headers: { "Content-Type": "application/json" },
112
169
  });
113
170
  }
114
171
  }
@@ -2,6 +2,9 @@ export { azureSpeechTokenHandler } from "./azure-speech-handler.js";
2
2
  export { bedrockHandler } from "./bedrock-handler.js";
3
3
  export { bedrockEmbeddingHandler } from "./bedrock-embedding-handler.js";
4
4
  export { openSearchSearchHandler, openSearchSuggestHandler, } from "./opensearch-env-handler.js";
5
+ export { POST } from "./azure-speech-handler.js";
6
+ export { BedrockPOST } from "./bedrock-handler.js";
7
+ export { BedrockEmbeddingPOST } from "./bedrock-embedding-handler.js";
5
8
  export { createOpenSearchProxyHandler, DEFAULT_OPENSEARCH_PROXY_PATH, } from "./opensearch-handler.js";
6
9
  export type { VectorSearchProxyRequest, VectorSearchProxyResponse, } from "./opensearch-handler.js";
7
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EACL,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,4BAA4B,EAC5B,6BAA6B,GAC9B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAkCA,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EACL,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAGtE,OAAO,EACL,4BAA4B,EAC5B,6BAA6B,GAC9B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC"}
@@ -2,4 +2,7 @@ export { azureSpeechTokenHandler } from "./azure-speech-handler.js";
2
2
  export { bedrockHandler } from "./bedrock-handler.js";
3
3
  export { bedrockEmbeddingHandler } from "./bedrock-embedding-handler.js";
4
4
  export { openSearchSearchHandler, openSearchSuggestHandler, } from "./opensearch-env-handler.js";
5
+ export { POST } from "./azure-speech-handler.js";
6
+ export { BedrockPOST } from "./bedrock-handler.js";
7
+ export { BedrockEmbeddingPOST } from "./bedrock-embedding-handler.js";
5
8
  export { createOpenSearchProxyHandler, DEFAULT_OPENSEARCH_PROXY_PATH, } from "./opensearch-handler.js";
@@ -27,5 +27,8 @@ export declare class BedrockService {
27
27
  embedText(text: string): Promise<number[]>;
28
28
  private embedTextViaProxy;
29
29
  private embedTextDirect;
30
+ generateFeedbackMessage(prompt: string, language: string): Promise<string>;
31
+ private generateFeedbackViaProxy;
32
+ private generateFeedbackDirect;
30
33
  }
31
34
  //# sourceMappingURL=bedrock.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bedrock.d.ts","sourceRoot":"","sources":["../../src/services/bedrock.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAmB,MAAM,aAAa,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAE5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAmCD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,MAAM,EAAE,aAAa;IA6CjC,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAO7C,OAAO,CAAC,iBAAiB;IA+BnB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAWtD,qBAAqB;YA2ErB,mBAAmB;IAyEjC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc;IAO9C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAWlC,iBAAiB;YAkFjB,eAAe;CAoF9B"}
1
+ {"version":3,"file":"bedrock.d.ts","sourceRoot":"","sources":["../../src/services/bedrock.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAmB,MAAM,aAAa,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAE5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAqDD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,MAAM,EAAE,aAAa;IA6CjC,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAO7C,OAAO,CAAC,iBAAiB;IA+BnB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAWtD,qBAAqB;YA2ErB,mBAAmB;IAyEjC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc;IAO9C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAWlC,iBAAiB;YAkFjB,eAAe;IAwFvB,uBAAuB,CAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;YA0BJ,wBAAwB;YAwExB,sBAAsB;CA+DrC"}
@@ -23,11 +23,29 @@ EXAMPLES:
23
23
  - User says "scroll down" → {"action": "scroll_down"}
24
24
  - User says "find schemes" → {"action": "search_content", "query": "schemes"}
25
25
  - User says "type hello world" → {"action": "type_text", "text": "hello world"}
26
+ - User says "tab" or "tab next" → {"action": "tab_next"}
27
+ - User says "tab previous" or "tab back" → {"action": "tab_back"}
28
+ - User says "focus next" → {"action": "focus_next"}
29
+ - User says "focus previous" → {"action": "focus_previous"}
30
+ - User says "go back" or "back" (browser history) → {"action": "go_back"}
31
+ - User says "click" → {"action": "click"}
26
32
 
27
33
  MATCHING RULES FOR PAGE NAVIGATION:
28
34
  - Match user's words to page names and keywords
29
35
  - Choose the navigate_ action that best matches
30
- - If user says "go to X" or "open X" or "show me X", find the page with that name or keyword`;
36
+ - If user says "go to X" or "open X" or "show me X", find the page with that name or keyword
37
+
38
+ SPECIAL PRIORITY RULES FOR STATES AND MINISTRIES:
39
+ - If user mentions a state/UT name (like "Assam", "Delhi", "Tamil Nadu", "Maharashtra"), ALWAYS use the state navigation action (navigate_state_*)
40
+ - If user mentions a ministry name or ministry keywords (like "education", "health", "agriculture"), ALWAYS use the ministry navigation action (navigate_ministry_*)
41
+ - User does NOT need to say "state of" or "ministry of" - the name alone is enough
42
+ - Examples:
43
+ * "go to Assam" → {"action": "navigate_state_assam"}
44
+ * "open Delhi" → {"action": "navigate_state_delhi"}
45
+ * "show Kerala" → {"action": "navigate_state_kerala"}
46
+ * "go to education" → {"action": "navigate_ministry_education"}
47
+ * "open health ministry" → {"action": "navigate_ministry_health"}
48
+ * "ministry of agriculture" → {"action": "navigate_ministry_agriculture"}`;
31
49
  const DEFAULT_EMBEDDING_MODEL_ID = "cohere.embed-multilingual-v3";
32
50
  export class BedrockService {
33
51
  constructor(config) {
@@ -338,4 +356,120 @@ export class BedrockService {
338
356
  throw error;
339
357
  }
340
358
  }
359
+ async generateFeedbackMessage(prompt, language) {
360
+ console.log("[Bedrock] generateFeedbackMessage called for language:", language);
361
+ const systemPrompt = `You are a voice navigation assistant providing spoken feedback.
362
+ Generate brief, natural, conversational feedback messages (maximum 10 words).
363
+ Be specific and clear about what action was performed.
364
+ Use the language: ${language}
365
+ Respond with ONLY the feedback message text, no JSON, no explanations.`;
366
+ const userPrompt = prompt;
367
+ console.log("[Bedrock] Using proxy mode:", this.useProxy);
368
+ if (this.useProxy) {
369
+ return this.generateFeedbackViaProxy(systemPrompt, userPrompt);
370
+ }
371
+ else {
372
+ return this.generateFeedbackDirect(systemPrompt, userPrompt);
373
+ }
374
+ }
375
+ async generateFeedbackViaProxy(systemPrompt, userPrompt) {
376
+ if (!this.bedrockEndpoint) {
377
+ throw new Error("Bedrock endpoint not configured");
378
+ }
379
+ console.log("[Bedrock] Calling proxy endpoint:", this.bedrockEndpoint);
380
+ try {
381
+ const requestBody = {
382
+ anthropic_version: "bedrock-2023-05-31",
383
+ max_tokens: 50,
384
+ system: systemPrompt,
385
+ messages: [
386
+ {
387
+ role: "user",
388
+ content: [
389
+ {
390
+ type: "text",
391
+ text: userPrompt,
392
+ },
393
+ ],
394
+ },
395
+ ],
396
+ };
397
+ const response = await fetch(this.bedrockEndpoint, {
398
+ method: "POST",
399
+ headers: {
400
+ "Content-Type": "application/json",
401
+ },
402
+ body: JSON.stringify({
403
+ body: requestBody,
404
+ }),
405
+ });
406
+ if (!response.ok) {
407
+ throw new Error(`Bedrock proxy error: ${response.status}`);
408
+ }
409
+ const result = (await response.json());
410
+ console.log("[Bedrock] Proxy response received:", result);
411
+ if (result.content &&
412
+ Array.isArray(result.content) &&
413
+ result.content[0]?.text) {
414
+ const message = result.content[0].text.trim();
415
+ console.log("[Bedrock] Extracted message from proxy:", message);
416
+ return message;
417
+ }
418
+ if (typeof result === "object" && result !== null && "text" in result) {
419
+ const message = String(result.text).trim();
420
+ console.log("[Bedrock] Extracted text from proxy:", message);
421
+ return message;
422
+ }
423
+ throw new Error("Unexpected feedback response format");
424
+ }
425
+ catch (error) {
426
+ console.error("[Bedrock] Proxy generation error:", error);
427
+ throw error;
428
+ }
429
+ }
430
+ async generateFeedbackDirect(systemPrompt, userPrompt) {
431
+ if (!this.client || !this.actionModelId) {
432
+ throw new Error("Bedrock client not configured");
433
+ }
434
+ console.log("[Bedrock] Using direct AWS SDK with model:", this.actionModelId);
435
+ const payload = {
436
+ anthropic_version: "bedrock-2023-05-31",
437
+ max_tokens: 50,
438
+ temperature: 0.7,
439
+ system: systemPrompt,
440
+ messages: [
441
+ {
442
+ role: "user",
443
+ content: userPrompt,
444
+ },
445
+ ],
446
+ };
447
+ const input = {
448
+ modelId: this.actionModelId,
449
+ contentType: "application/json",
450
+ accept: "application/json",
451
+ body: JSON.stringify(payload),
452
+ };
453
+ try {
454
+ const command = new InvokeModelCommand(input);
455
+ const response = await this.client.send(command);
456
+ if (!response.body) {
457
+ throw new Error("No response from Bedrock");
458
+ }
459
+ const decoded = JSON.parse(new TextDecoder().decode(response.body));
460
+ console.log("[Bedrock] Direct SDK response received");
461
+ if (decoded.content &&
462
+ Array.isArray(decoded.content) &&
463
+ decoded.content[0]?.text) {
464
+ const message = decoded.content[0].text.trim();
465
+ console.log("[Bedrock] Extracted message from direct:", message);
466
+ return message;
467
+ }
468
+ throw new Error("Unexpected feedback response format");
469
+ }
470
+ catch (error) {
471
+ console.error("[Bedrock] Direct generation error:", error);
472
+ throw error;
473
+ }
474
+ }
341
475
  }
@@ -0,0 +1,46 @@
1
+ import type { NavigationAction, ActionResult } from "../types.js";
2
+ import type { AzureSpeechService } from "./azure-speech.js";
3
+ import type { BedrockService } from "./bedrock.js";
4
+ interface VoiceFeedbackConfig {
5
+ enabled?: boolean;
6
+ language?: string;
7
+ azureSpeechService: AzureSpeechService;
8
+ bedrockService: BedrockService;
9
+ }
10
+ interface FeedbackContext {
11
+ action: NavigationAction;
12
+ actionResult?: ActionResult;
13
+ transcript?: string;
14
+ elementInfo?: {
15
+ tag?: string;
16
+ label?: string;
17
+ text?: string;
18
+ type?: string;
19
+ };
20
+ }
21
+ export declare class VoiceFeedbackService {
22
+ private enabled;
23
+ private language;
24
+ private azureSpeechService;
25
+ private bedrockService;
26
+ private synthesizer;
27
+ private isSpeaking;
28
+ constructor(config: VoiceFeedbackConfig);
29
+ setEnabled(enabled: boolean): void;
30
+ isEnabled(): boolean;
31
+ setLanguage(language: string): void;
32
+ private initializeSynthesizer;
33
+ private getVoiceForLanguage;
34
+ private generateFeedbackMessage;
35
+ private buildPromptForAction;
36
+ private getFallbackMessage;
37
+ private speak;
38
+ private stopSpeaking;
39
+ provideFeedback(context: FeedbackContext): Promise<void>;
40
+ provideImmediateFeedback(message: string): Promise<void>;
41
+ announceFocusChange(element: HTMLElement, direction: "next" | "previous"): Promise<void>;
42
+ private extractElementInfo;
43
+ dispose(): void;
44
+ }
45
+ export {};
46
+ //# sourceMappingURL=voice-feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-feedback.d.ts","sourceRoot":"","sources":["../../src/services/voice-feedback.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,UAAU,mBAAmB;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,UAAU,CAAkB;gBAExB,MAAM,EAAE,mBAAmB;IAiBvC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAclC,SAAS,IAAI,OAAO;IAOpB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;YAQrB,qBAAqB;IAmCnC,OAAO,CAAC,mBAAmB;YAsBb,uBAAuB;IAsCrC,OAAO,CAAC,oBAAoB;IA4C5B,OAAO,CAAC,kBAAkB;YAgCZ,KAAK;IA0EnB,OAAO,CAAC,YAAY;IAkBd,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAoFxD,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxD,mBAAmB,CACvB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,GAAG,UAAU,GAC7B,OAAO,CAAC,IAAI,CAAC;IAwBhB,OAAO,CAAC,kBAAkB;IAwF1B,OAAO,IAAI,IAAI;CAOhB"}