@revenium/litellm 0.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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +630 -0
  3. package/dist/client.d.ts +17 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +713 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/config.d.ts +42 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +332 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/constants.d.ts +15 -0
  12. package/dist/constants.d.ts.map +1 -0
  13. package/dist/constants.js +101 -0
  14. package/dist/constants.js.map +1 -0
  15. package/dist/index.d.ts +42 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +189 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/prompt-extraction.d.ts +11 -0
  20. package/dist/prompt-extraction.d.ts.map +1 -0
  21. package/dist/prompt-extraction.js +201 -0
  22. package/dist/prompt-extraction.js.map +1 -0
  23. package/dist/tracking.d.ts +47 -0
  24. package/dist/tracking.d.ts.map +1 -0
  25. package/dist/tracking.js +299 -0
  26. package/dist/tracking.js.map +1 -0
  27. package/dist/types.d.ts +348 -0
  28. package/dist/types.d.ts.map +1 -0
  29. package/dist/types.js +3 -0
  30. package/dist/types.js.map +1 -0
  31. package/dist/utils/circuit-breaker.d.ts +114 -0
  32. package/dist/utils/circuit-breaker.d.ts.map +1 -0
  33. package/dist/utils/circuit-breaker.js +216 -0
  34. package/dist/utils/circuit-breaker.js.map +1 -0
  35. package/dist/utils/error-handling.d.ts +166 -0
  36. package/dist/utils/error-handling.d.ts.map +1 -0
  37. package/dist/utils/error-handling.js +306 -0
  38. package/dist/utils/error-handling.js.map +1 -0
  39. package/dist/utils/logger-types.d.ts +171 -0
  40. package/dist/utils/logger-types.d.ts.map +1 -0
  41. package/dist/utils/logger-types.js +210 -0
  42. package/dist/utils/logger-types.js.map +1 -0
  43. package/dist/utils/provider-detection.d.ts +43 -0
  44. package/dist/utils/provider-detection.d.ts.map +1 -0
  45. package/dist/utils/provider-detection.js +103 -0
  46. package/dist/utils/provider-detection.js.map +1 -0
  47. package/dist/utils/stop-reason.d.ts +58 -0
  48. package/dist/utils/stop-reason.d.ts.map +1 -0
  49. package/dist/utils/stop-reason.js +136 -0
  50. package/dist/utils/stop-reason.js.map +1 -0
  51. package/dist/utils/summary-printer.d.ts +23 -0
  52. package/dist/utils/summary-printer.d.ts.map +1 -0
  53. package/dist/utils/summary-printer.js +234 -0
  54. package/dist/utils/summary-printer.js.map +1 -0
  55. package/dist/utils/trace-fields.d.ts +10 -0
  56. package/dist/utils/trace-fields.d.ts.map +1 -0
  57. package/dist/utils/trace-fields.js +117 -0
  58. package/dist/utils/trace-fields.js.map +1 -0
  59. package/dist/utils/validation.d.ts +121 -0
  60. package/dist/utils/validation.d.ts.map +1 -0
  61. package/dist/utils/validation.js +451 -0
  62. package/dist/utils/validation.js.map +1 -0
  63. package/examples/README.md +321 -0
  64. package/examples/litellm-basic.ts +240 -0
  65. package/examples/litellm-streaming.ts +309 -0
  66. package/examples/prompt-capture.ts +128 -0
  67. package/package.json +85 -0
package/dist/index.js ADDED
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resetHttpClientManager = exports.resetConfigManager = exports.resetConfig = exports.getLogger = exports.getConfig = void 0;
4
+ exports.configure = configure;
5
+ exports.isMiddlewareInitialized = isMiddlewareInitialized;
6
+ exports.getInitializationState = getInitializationState;
7
+ exports.resetInitializationState = resetInitializationState;
8
+ exports.getStatus = getStatus;
9
+ exports.enable = enable;
10
+ exports.disable = disable;
11
+ exports.setCustomLogger = setCustomLogger;
12
+ exports.initialize = initialize;
13
+ const config_1 = require("./config");
14
+ const client_1 = require("./client");
15
+ /**
16
+ * Track initialization state
17
+ */
18
+ let isInitialized = false;
19
+ // Global logger
20
+ const logger = (0, config_1.getLogger)();
21
+ // Global config
22
+ const config = (0, config_1.getConfig)();
23
+ /**
24
+ * Initialize the Revenium LiteLLM middleware
25
+ */
26
+ function initialize() {
27
+ if (isInitialized) {
28
+ logger.debug("Revenium LiteLLM middleware already initialized");
29
+ return true;
30
+ }
31
+ logger.debug("Initializing Revenium LiteLLM middleware");
32
+ // Try to load configuration from environment
33
+ const configLoaded = (0, config_1.initializeConfig)();
34
+ if (!configLoaded) {
35
+ logger.warn("Revenium LiteLLM middleware not initialized - missing configuration");
36
+ logger.info("Required environment variables: REVENIUM_METERING_API_KEY, LITELLM_PROXY_URL");
37
+ logger.info("See env.example for complete configuration options");
38
+ return false;
39
+ }
40
+ // Patch HTTP client to intercept LiteLLM Proxy requests
41
+ const patchSuccess = (0, client_1.patchHttpClient)();
42
+ if (!patchSuccess) {
43
+ logger.error("Failed to patch HTTP client - middleware disabled");
44
+ return false;
45
+ }
46
+ isInitialized = true;
47
+ logger.info("🚀 Revenium LiteLLM middleware initialized successfully");
48
+ logger.info("All requests to your LiteLLM Proxy will now be tracked automatically");
49
+ if (config) {
50
+ logger.debug("Configuration details", {
51
+ reveniumMeteringBaseUrl: config.reveniumMeteringBaseUrl,
52
+ litellmProxyUrl: config.litellmProxyUrl,
53
+ hasProxyKey: !!config.litellmApiKey,
54
+ organizationId: config.organizationId,
55
+ });
56
+ }
57
+ return true;
58
+ }
59
+ /**
60
+ * Auto-initialize when module is imported (zero-touch experience)
61
+ *
62
+ * This follows the industry standard pattern used by Sentry, DataDog, New Relic, etc.
63
+ * If environment variables are properly set, the middleware will automatically start
64
+ * tracking LiteLLM requests with zero configuration required.
65
+ *
66
+ * If auto-initialization fails (missing env vars), it gracefully falls back
67
+ * to allow manual configuration via initialize() or configure().
68
+ *
69
+ * Usage patterns:
70
+ *
71
+ * Zero-touch (90% of users):
72
+ * import '@revenium/litellm';
73
+ * // Done! All LiteLLM requests are now tracked
74
+ *
75
+ * Explicit control (10% of users):
76
+ * import { initialize, configure } from '@revenium/litellm';
77
+ * initialize(); // or configure({...})
78
+ */
79
+ try {
80
+ const autoInitialized = initialize();
81
+ if (autoInitialized)
82
+ logger.debug("Revenium LiteLLM middleware auto-initialized successfully");
83
+ }
84
+ catch (error) {
85
+ // Graceful fallback - don't throw, just log debug message
86
+ // This allows manual configuration later via initialize() or configure()
87
+ logger.debug("Auto-initialization skipped - manual configuration available", {
88
+ reason: error instanceof Error ? error.message : String(error),
89
+ hint: "Use initialize() or configure() for manual setup",
90
+ });
91
+ }
92
+ // Export public API
93
+ /**
94
+ * Manually set configuration (alternative to environment variables)
95
+ */
96
+ function configure(config) {
97
+ try {
98
+ (0, config_1.setConfig)(config);
99
+ logger.info("Revenium LiteLLM configuration updated manually");
100
+ // Re-initialize with new configuration
101
+ if (!(0, client_1.isHttpClientPatched)()) {
102
+ const patchSuccess = (0, client_1.patchHttpClient)();
103
+ if (patchSuccess) {
104
+ isInitialized = true;
105
+ logger.info("🚀 Revenium LiteLLM middleware enabled with manual configuration");
106
+ }
107
+ return patchSuccess;
108
+ }
109
+ return true;
110
+ }
111
+ catch (error) {
112
+ logger.error("Failed to set Revenium LiteLLM configuration", {
113
+ error: error instanceof Error ? error.message : String(error),
114
+ });
115
+ return false;
116
+ }
117
+ }
118
+ /**
119
+ * Check if middleware is initialized and working
120
+ */
121
+ function isMiddlewareInitialized() {
122
+ return isInitialized && (0, client_1.isHttpClientPatched)();
123
+ }
124
+ /**
125
+ * Check if the middleware has been initialized (for testing)
126
+ */
127
+ function getInitializationState() {
128
+ return isInitialized;
129
+ }
130
+ /**
131
+ * Reset initialization state (for testing)
132
+ */
133
+ function resetInitializationState() {
134
+ isInitialized = false;
135
+ }
136
+ /**
137
+ * Get detailed status information
138
+ */
139
+ function getStatus() {
140
+ return {
141
+ initialized: isInitialized,
142
+ patched: (0, client_1.isHttpClientPatched)(),
143
+ hasConfig: !!config,
144
+ proxyUrl: config?.litellmProxyUrl,
145
+ };
146
+ }
147
+ /**
148
+ * Enable the middleware (patch HTTP client)
149
+ */
150
+ function enable() {
151
+ if (!config) {
152
+ logger.error("Cannot enable middleware without configuration");
153
+ return false;
154
+ }
155
+ const success = (0, client_1.patchHttpClient)();
156
+ if (success) {
157
+ isInitialized = true;
158
+ logger.info("Revenium LiteLLM middleware enabled");
159
+ }
160
+ return success;
161
+ }
162
+ /**
163
+ * Disable the middleware (unpatch HTTP client)
164
+ */
165
+ function disable() {
166
+ const success = (0, client_1.unpatchHttpClient)();
167
+ if (success) {
168
+ isInitialized = false;
169
+ logger.info("Revenium LiteLLM middleware disabled");
170
+ }
171
+ return success;
172
+ }
173
+ /**
174
+ * Set a custom logger
175
+ */
176
+ function setCustomLogger(logger) {
177
+ (0, config_1.setLogger)(logger);
178
+ }
179
+ // Export configuration functions for advanced usage
180
+ var config_2 = require("./config");
181
+ Object.defineProperty(exports, "getConfig", { enumerable: true, get: function () { return config_2.getConfig; } });
182
+ Object.defineProperty(exports, "getLogger", { enumerable: true, get: function () { return config_2.getLogger; } });
183
+ Object.defineProperty(exports, "resetConfig", { enumerable: true, get: function () { return config_2.resetConfig; } });
184
+ Object.defineProperty(exports, "resetConfigManager", { enumerable: true, get: function () { return config_2.resetConfigManager; } });
185
+ // Export HTTP client management functions for testing
186
+ var client_2 = require("./client");
187
+ Object.defineProperty(exports, "resetHttpClientManager", { enumerable: true, get: function () { return client_2.resetHttpClientManager; } });
188
+ // Testing utilities are exported above with their function declarations
189
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { UsageMetadata, LiteLLMChatCompletionRequest, LiteLLMChatCompletionResponse } from "./types.js";
2
+ export declare function getMaxPromptSize(metadata?: UsageMetadata): number;
3
+ export interface PromptData {
4
+ systemPrompt?: string;
5
+ inputMessages?: string;
6
+ outputResponse?: string;
7
+ promptsTruncated: boolean;
8
+ }
9
+ export declare function shouldCapturePrompts(metadata?: UsageMetadata): boolean;
10
+ export declare function extractPrompts(request: LiteLLMChatCompletionRequest, response: LiteLLMChatCompletionResponse, metadata?: UsageMetadata): PromptData | null;
11
+ //# sourceMappingURL=prompt-extraction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-extraction.d.ts","sourceRoot":"","sources":["../src/prompt-extraction.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,4BAA4B,EAC5B,6BAA6B,EAC9B,MAAM,YAAY,CAAC;AAMpB,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,MAAM,CAmBjE;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AA+KD,wBAAgB,oBAAoB,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,OAAO,CAgBtE;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,4BAA4B,EACrC,QAAQ,EAAE,6BAA6B,EACvC,QAAQ,CAAC,EAAE,aAAa,GACvB,UAAU,GAAG,IAAI,CAmCnB"}
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMaxPromptSize = getMaxPromptSize;
4
+ exports.shouldCapturePrompts = shouldCapturePrompts;
5
+ exports.extractPrompts = extractPrompts;
6
+ const config_js_1 = require("./config.js");
7
+ const DEFAULT_MAX_PROMPT_SIZE = 50000;
8
+ const CAPTURE_PROMPTS_DEFAULT = false;
9
+ function getMaxPromptSize(metadata) {
10
+ if (metadata?.maxPromptSize && metadata.maxPromptSize > 0) {
11
+ return metadata.maxPromptSize;
12
+ }
13
+ const config = (0, config_js_1.getConfig)();
14
+ if (config?.maxPromptSize && config.maxPromptSize > 0) {
15
+ return config.maxPromptSize;
16
+ }
17
+ const envValue = process.env.REVENIUM_MAX_PROMPT_SIZE;
18
+ if (envValue) {
19
+ const parsed = parseInt(envValue, 10);
20
+ if (!isNaN(parsed) && parsed > 0) {
21
+ return parsed;
22
+ }
23
+ }
24
+ return DEFAULT_MAX_PROMPT_SIZE;
25
+ }
26
+ function sanitizeCredentials(text) {
27
+ const patterns = [
28
+ {
29
+ regex: /sk-proj-[a-zA-Z0-9_-]{48,}/g,
30
+ replacement: "sk-proj-***REDACTED***",
31
+ },
32
+ { regex: /sk-[a-zA-Z0-9_-]{20,}/g, replacement: "sk-***REDACTED***" },
33
+ {
34
+ regex: /Bearer\s+[a-zA-Z0-9_\-\.]+/gi,
35
+ replacement: "Bearer ***REDACTED***",
36
+ },
37
+ {
38
+ regex: /api[_-]?key["\s:=]+[a-zA-Z0-9_\-\.\+\/=]{20,}/gi,
39
+ replacement: "api_key: ***REDACTED***",
40
+ },
41
+ {
42
+ regex: /token["\s:=]+[a-zA-Z0-9_\-\.]{20,}/gi,
43
+ replacement: "token: ***REDACTED***",
44
+ },
45
+ {
46
+ regex: /password["\s:=]+[^\s"']{8,}/gi,
47
+ replacement: "password: ***REDACTED***",
48
+ },
49
+ ];
50
+ let sanitized = text;
51
+ for (const pattern of patterns) {
52
+ sanitized = sanitized.replace(pattern.regex, pattern.replacement);
53
+ }
54
+ return sanitized;
55
+ }
56
+ function truncateString(str, maxLength) {
57
+ if (!str || str.length === 0) {
58
+ return { value: "", truncated: false };
59
+ }
60
+ const sanitized = sanitizeCredentials(str);
61
+ if (sanitized.length <= maxLength) {
62
+ return { value: sanitized, truncated: false };
63
+ }
64
+ return { value: sanitized.substring(0, maxLength), truncated: true };
65
+ }
66
+ function extractSystemPrompt(request) {
67
+ if (!request.messages || !Array.isArray(request.messages)) {
68
+ return "";
69
+ }
70
+ const systemMessages = request.messages
71
+ .filter((msg) => msg.role === "system")
72
+ .map((msg) => {
73
+ const content = msg.content;
74
+ if (typeof content === "string") {
75
+ return content;
76
+ }
77
+ if (Array.isArray(content)) {
78
+ return content
79
+ .map((block) => {
80
+ if (block.type === "text" && block.text) {
81
+ return block.text;
82
+ }
83
+ if (block.type === "image_url") {
84
+ return "[IMAGE]";
85
+ }
86
+ return "";
87
+ })
88
+ .filter(Boolean)
89
+ .join("\n");
90
+ }
91
+ return "";
92
+ })
93
+ .filter(Boolean);
94
+ return systemMessages.join("\n\n");
95
+ }
96
+ function extractInputMessages(request) {
97
+ if (!request.messages || !Array.isArray(request.messages)) {
98
+ return "";
99
+ }
100
+ return request.messages
101
+ .map((message) => {
102
+ const role = message.role;
103
+ let content = "";
104
+ const msgContent = message.content;
105
+ if (typeof msgContent === "string") {
106
+ content = msgContent;
107
+ }
108
+ else if (Array.isArray(msgContent)) {
109
+ content = msgContent
110
+ .map((block) => {
111
+ if (block.type === "text" && block.text) {
112
+ return block.text;
113
+ }
114
+ if (block.type === "image_url") {
115
+ return "[IMAGE]";
116
+ }
117
+ if (block.type === "tool_use") {
118
+ const toolName = block.name || "unknown";
119
+ return `[TOOL_USE: ${toolName}]`;
120
+ }
121
+ if (block.type === "tool_result") {
122
+ return "[TOOL_RESULT]";
123
+ }
124
+ return "";
125
+ })
126
+ .filter(Boolean)
127
+ .join("\n");
128
+ }
129
+ const msgWithTools = message;
130
+ if (msgWithTools.tool_calls && Array.isArray(msgWithTools.tool_calls)) {
131
+ const toolCalls = msgWithTools.tool_calls
132
+ .map((tc) => `[TOOL_USE: ${tc.function?.name || "unknown"}]`)
133
+ .join("\n");
134
+ content = content ? `${content}\n${toolCalls}` : toolCalls;
135
+ }
136
+ return `[${role}]\n${content}`;
137
+ })
138
+ .join("\n\n");
139
+ }
140
+ function extractOutputResponse(response) {
141
+ if (!response.choices || response.choices.length === 0) {
142
+ return "";
143
+ }
144
+ const choice = response.choices[0];
145
+ const parts = [];
146
+ if (choice.message?.content) {
147
+ parts.push(choice.message.content);
148
+ }
149
+ const message = choice.message;
150
+ if (message?.tool_calls && Array.isArray(message.tool_calls)) {
151
+ message.tool_calls.forEach((toolCall) => {
152
+ if (toolCall.function?.name) {
153
+ parts.push(`[TOOL_USE: ${toolCall.function.name}]`);
154
+ }
155
+ });
156
+ }
157
+ return parts.join("\n");
158
+ }
159
+ function shouldCapturePrompts(metadata) {
160
+ if (metadata?.capturePrompts !== undefined) {
161
+ return metadata.capturePrompts;
162
+ }
163
+ const config = (0, config_js_1.getConfig)();
164
+ if (config?.capturePrompts !== undefined) {
165
+ return config.capturePrompts;
166
+ }
167
+ const envValue = process.env.REVENIUM_CAPTURE_PROMPTS;
168
+ if (envValue !== undefined) {
169
+ return envValue.toLowerCase() === "true";
170
+ }
171
+ return CAPTURE_PROMPTS_DEFAULT;
172
+ }
173
+ function extractPrompts(request, response, metadata) {
174
+ if (!shouldCapturePrompts(metadata)) {
175
+ return null;
176
+ }
177
+ const maxSize = getMaxPromptSize(metadata);
178
+ let anyTruncated = false;
179
+ const systemPromptRaw = extractSystemPrompt(request);
180
+ const systemPromptResult = truncateString(systemPromptRaw, maxSize);
181
+ anyTruncated = anyTruncated || systemPromptResult.truncated;
182
+ const inputMessagesRaw = extractInputMessages(request);
183
+ const inputMessagesResult = truncateString(inputMessagesRaw, maxSize);
184
+ anyTruncated = anyTruncated || inputMessagesResult.truncated;
185
+ const outputResponseRaw = extractOutputResponse(response);
186
+ const outputResponseResult = truncateString(outputResponseRaw, maxSize);
187
+ anyTruncated = anyTruncated || outputResponseResult.truncated;
188
+ const hasAnyContent = systemPromptResult.value ||
189
+ inputMessagesResult.value ||
190
+ outputResponseResult.value;
191
+ if (!hasAnyContent) {
192
+ return null;
193
+ }
194
+ return {
195
+ systemPrompt: systemPromptResult.value || undefined,
196
+ inputMessages: inputMessagesResult.value || undefined,
197
+ outputResponse: outputResponseResult.value || undefined,
198
+ promptsTruncated: anyTruncated,
199
+ };
200
+ }
201
+ //# sourceMappingURL=prompt-extraction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-extraction.js","sourceRoot":"","sources":["../src/prompt-extraction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { UsageMetadata, LiteLLMChatCompletionResponse, LiteLLMChatCompletionRequest } from "./types";
2
+ export declare function sendReveniumMetrics(data: {
3
+ requestId: string;
4
+ model: string;
5
+ promptTokens: number;
6
+ completionTokens: number;
7
+ totalTokens: number;
8
+ reasoningTokens?: number;
9
+ cachedTokens?: number;
10
+ duration: number;
11
+ finishReason: string | null;
12
+ usageMetadata?: UsageMetadata;
13
+ isStreamed?: boolean;
14
+ timeToFirstToken?: number;
15
+ operationType?: "CHAT" | "EMBED";
16
+ responseFormat?: any;
17
+ request?: LiteLLMChatCompletionRequest;
18
+ response?: LiteLLMChatCompletionResponse;
19
+ }): Promise<void>;
20
+ /**
21
+ * Fire-and-forget async tracking wrapper
22
+ * This ensures tracking never blocks the main application flow
23
+ */
24
+ export declare function trackUsageAsync(trackingData: Parameters<typeof sendReveniumMetrics>[0]): void;
25
+ /**
26
+ * Fire-and-forget async tracking wrapper specifically for embeddings
27
+ * This ensures embeddings tracking never blocks the main application flow
28
+ */
29
+ export declare function trackEmbeddingsUsageAsync(data: {
30
+ requestId: string;
31
+ model: string;
32
+ promptTokens: number;
33
+ totalTokens: number;
34
+ duration: number;
35
+ usageMetadata?: UsageMetadata;
36
+ }): void;
37
+ export declare function extractMetadataFromHeaders(headers: Record<string, string>): UsageMetadata;
38
+ /**
39
+ * Process LiteLLM response and extract token usage
40
+ */
41
+ export declare function extractUsageFromResponse(response: LiteLLMChatCompletionResponse): {
42
+ promptTokens: number;
43
+ completionTokens: number;
44
+ totalTokens: number;
45
+ finishReason: string | null;
46
+ };
47
+ //# sourceMappingURL=tracking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracking.d.ts","sourceRoot":"","sources":["../src/tracking.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EACb,6BAA6B,EAC7B,4BAA4B,EAE7B,MAAM,SAAS,CAAC;AAuCjB,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,cAAc,CAAC,EAAE,GAAG,CAAC;IACrB,OAAO,CAAC,EAAE,4BAA4B,CAAC;IACvC,QAAQ,CAAC,EAAE,6BAA6B,CAAC;CAC1C,GAAG,OAAO,CAAC,IAAI,CAAC,CA8PhB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,GACtD,IAAI,CAiBN;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,GAAG,IAAI,CASP;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,aAAa,CA2Bf;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,6BAA6B,GACtC;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAUA"}