@serve.zone/dcrouter 11.0.22 → 11.0.25

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.
@@ -1,98 +0,0 @@
1
- import { PlatformError } from './base.errors.js';
2
- import type { IErrorContext } from './base.errors.js';
3
- /**
4
- * Error handler configuration
5
- */
6
- export interface IErrorHandlerConfig {
7
- /** Whether to log errors automatically */
8
- logErrors: boolean;
9
- /** Whether to include stack traces in prod environment */
10
- includeStacksInProd: boolean;
11
- /** Default retry options */
12
- retry: {
13
- /** Maximum retry attempts */
14
- maxAttempts: number;
15
- /** Base delay between retries in ms */
16
- baseDelay: number;
17
- /** Maximum delay between retries in ms */
18
- maxDelay: number;
19
- /** Backoff factor for exponential backoff */
20
- backoffFactor: number;
21
- };
22
- }
23
- /**
24
- * Error handler utility
25
- * Provides methods for consistent error handling across the platform
26
- */
27
- export declare class ErrorHandler {
28
- /**
29
- * Current configuration
30
- */
31
- static config: IErrorHandlerConfig;
32
- /**
33
- * Update error handler configuration
34
- *
35
- * @param newConfig New configuration (partial)
36
- */
37
- static configure(newConfig: Partial<IErrorHandlerConfig>): void;
38
- /**
39
- * Convert any error to a PlatformError
40
- *
41
- * @param error Error to convert
42
- * @param defaultCode Default error code if not a PlatformError
43
- * @param context Additional context
44
- * @returns PlatformError instance
45
- */
46
- static toPlatformError(error: any, defaultCode: string, context?: IErrorContext): PlatformError;
47
- /**
48
- * Format an error for API responses
49
- * Sanitizes errors for safe external exposure
50
- *
51
- * @param error Error to format
52
- * @param includeDetails Whether to include detailed information
53
- * @returns Formatted error object
54
- */
55
- static formatErrorForResponse(error: any, includeDetails?: boolean): Record<string, any>;
56
- /**
57
- * Handle an error with consistent logging and formatting
58
- *
59
- * @param error Error to handle
60
- * @param defaultCode Default error code if not a PlatformError
61
- * @param context Additional context
62
- * @returns Formatted error for response
63
- */
64
- static handleError(error: any, defaultCode: string, context?: IErrorContext): Record<string, any>;
65
- /**
66
- * Execute a function with error handling
67
- *
68
- * @param fn Function to execute
69
- * @param defaultCode Default error code if the function throws
70
- * @param context Additional context
71
- * @returns Function result or error
72
- */
73
- static execute<T>(fn: () => Promise<T>, defaultCode: string, context?: IErrorContext): Promise<T>;
74
- /**
75
- * Execute a function with retries and exponential backoff
76
- *
77
- * @param fn Function to execute
78
- * @param defaultCode Default error code if the function throws
79
- * @param options Retry options
80
- * @param context Additional context
81
- * @returns Function result or error after max retries
82
- */
83
- static executeWithRetry<T>(fn: () => Promise<T>, defaultCode: string, options?: {
84
- maxAttempts?: number;
85
- baseDelay?: number;
86
- maxDelay?: number;
87
- backoffFactor?: number;
88
- retryableErrorCodes?: string[];
89
- retryableErrorPatterns?: RegExp[];
90
- onRetry?: (error: PlatformError, attempt: number, delay: number) => void;
91
- }, context?: IErrorContext): Promise<T>;
92
- }
93
- /**
94
- * Create a middleware for handling errors in HTTP requests
95
- *
96
- * @returns Middleware function
97
- */
98
- export declare function createErrorHandlerMiddleware(): (error: any, req: any, res: any, next: any) => void;
@@ -1,282 +0,0 @@
1
- import { PlatformError } from './base.errors.js';
2
- import { ErrorCategory, ErrorRecoverability, ErrorSeverity } from './error.codes.js';
3
- import { logger } from '../logger.js';
4
- /**
5
- * Global error handler configuration
6
- */
7
- const config = {
8
- logErrors: true,
9
- includeStacksInProd: false,
10
- retry: {
11
- maxAttempts: 3,
12
- baseDelay: 1000,
13
- maxDelay: 30000,
14
- backoffFactor: 2
15
- }
16
- };
17
- /**
18
- * Error handler utility
19
- * Provides methods for consistent error handling across the platform
20
- */
21
- export class ErrorHandler {
22
- /**
23
- * Current configuration
24
- */
25
- static config = config;
26
- /**
27
- * Update error handler configuration
28
- *
29
- * @param newConfig New configuration (partial)
30
- */
31
- static configure(newConfig) {
32
- ErrorHandler.config = {
33
- ...ErrorHandler.config,
34
- ...newConfig,
35
- retry: {
36
- ...ErrorHandler.config.retry,
37
- ...(newConfig.retry || {})
38
- }
39
- };
40
- }
41
- /**
42
- * Convert any error to a PlatformError
43
- *
44
- * @param error Error to convert
45
- * @param defaultCode Default error code if not a PlatformError
46
- * @param context Additional context
47
- * @returns PlatformError instance
48
- */
49
- static toPlatformError(error, defaultCode, context = {}) {
50
- // If already a PlatformError, just add context
51
- if (error instanceof PlatformError) {
52
- // Add context if provided
53
- if (Object.keys(context).length > 0) {
54
- return new error.constructor(error.message, error.code, error.severity, error.category, error.recoverability, {
55
- ...error.context,
56
- ...context,
57
- data: {
58
- ...(error.context.data || {}),
59
- ...(context.data || {})
60
- }
61
- });
62
- }
63
- return error;
64
- }
65
- // Convert standard Error to PlatformError
66
- if (error instanceof Error) {
67
- return new PlatformError(error.message, defaultCode, ErrorSeverity.MEDIUM, ErrorCategory.OPERATION, ErrorRecoverability.NON_RECOVERABLE, {
68
- ...context,
69
- data: {
70
- ...(context.data || {}),
71
- originalError: {
72
- name: error.name,
73
- message: error.message,
74
- stack: error.stack
75
- }
76
- }
77
- });
78
- }
79
- // Not an Error instance
80
- return new PlatformError(typeof error === 'string' ? error : 'Unknown error', defaultCode, ErrorSeverity.MEDIUM, ErrorCategory.OPERATION, ErrorRecoverability.NON_RECOVERABLE, context);
81
- }
82
- /**
83
- * Format an error for API responses
84
- * Sanitizes errors for safe external exposure
85
- *
86
- * @param error Error to format
87
- * @param includeDetails Whether to include detailed information
88
- * @returns Formatted error object
89
- */
90
- static formatErrorForResponse(error, includeDetails = false) {
91
- const platformError = ErrorHandler.toPlatformError(error, 'PLATFORM_OPERATION_ERROR');
92
- // Basic error information
93
- const responseError = {
94
- code: platformError.code,
95
- message: platformError.getUserMessage(),
96
- requestId: platformError.context.requestId
97
- };
98
- // Include more details if requested
99
- if (includeDetails) {
100
- responseError.details = {
101
- severity: platformError.severity,
102
- category: platformError.category,
103
- rawMessage: platformError.message,
104
- data: platformError.context.data
105
- };
106
- // Only include stack trace in non-production or if explicitly enabled
107
- if (process.env.NODE_ENV !== 'production' || ErrorHandler.config.includeStacksInProd) {
108
- responseError.details.stack = platformError.stack;
109
- }
110
- }
111
- return responseError;
112
- }
113
- /**
114
- * Handle an error with consistent logging and formatting
115
- *
116
- * @param error Error to handle
117
- * @param defaultCode Default error code if not a PlatformError
118
- * @param context Additional context
119
- * @returns Formatted error for response
120
- */
121
- static handleError(error, defaultCode, context = {}) {
122
- const platformError = ErrorHandler.toPlatformError(error, defaultCode, context);
123
- // Log the error if enabled
124
- if (ErrorHandler.config.logErrors) {
125
- logger.error(platformError.message, {
126
- error_code: platformError.code,
127
- error_name: platformError.name,
128
- error_severity: platformError.severity,
129
- error_category: platformError.category,
130
- error_recoverability: platformError.recoverability,
131
- ...platformError.context,
132
- stack: platformError.stack
133
- });
134
- }
135
- // Return formatted error for response
136
- const isDetailedMode = process.env.NODE_ENV !== 'production';
137
- return ErrorHandler.formatErrorForResponse(platformError, isDetailedMode);
138
- }
139
- /**
140
- * Execute a function with error handling
141
- *
142
- * @param fn Function to execute
143
- * @param defaultCode Default error code if the function throws
144
- * @param context Additional context
145
- * @returns Function result or error
146
- */
147
- static async execute(fn, defaultCode, context = {}) {
148
- try {
149
- return await fn();
150
- }
151
- catch (error) {
152
- throw ErrorHandler.toPlatformError(error, defaultCode, context);
153
- }
154
- }
155
- /**
156
- * Execute a function with retries and exponential backoff
157
- *
158
- * @param fn Function to execute
159
- * @param defaultCode Default error code if the function throws
160
- * @param options Retry options
161
- * @param context Additional context
162
- * @returns Function result or error after max retries
163
- */
164
- static async executeWithRetry(fn, defaultCode, options = {}, context = {}) {
165
- const { maxAttempts = ErrorHandler.config.retry.maxAttempts, baseDelay = ErrorHandler.config.retry.baseDelay, maxDelay = ErrorHandler.config.retry.maxDelay, backoffFactor = ErrorHandler.config.retry.backoffFactor, retryableErrorCodes = [], retryableErrorPatterns = [], onRetry = () => { } } = options;
166
- let lastError;
167
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
168
- try {
169
- return await fn();
170
- }
171
- catch (error) {
172
- // Convert to PlatformError
173
- const platformError = ErrorHandler.toPlatformError(error, defaultCode, {
174
- ...context,
175
- retry: {
176
- currentRetry: attempt,
177
- maxRetries: maxAttempts,
178
- nextRetryAt: 0 // Will be set below if retrying
179
- }
180
- });
181
- lastError = platformError;
182
- // Check if we should retry
183
- const isLastAttempt = attempt >= maxAttempts - 1;
184
- if (isLastAttempt) {
185
- // No more retries
186
- throw platformError;
187
- }
188
- // Check if error is retryable
189
- const isRetryable =
190
- // Built-in recoverability
191
- platformError.recoverability === ErrorRecoverability.RECOVERABLE ||
192
- platformError.recoverability === ErrorRecoverability.MAYBE_RECOVERABLE ||
193
- platformError.recoverability === ErrorRecoverability.TRANSIENT ||
194
- // Specifically included error codes
195
- retryableErrorCodes.includes(platformError.code) ||
196
- // Matches error message patterns
197
- retryableErrorPatterns.some(pattern => pattern.test(platformError.message));
198
- if (!isRetryable) {
199
- throw platformError;
200
- }
201
- // Calculate delay with exponential backoff
202
- const delay = Math.min(baseDelay * Math.pow(backoffFactor, attempt), maxDelay);
203
- // Add jitter to prevent thundering herd problem (±20%)
204
- const jitter = 0.8 + Math.random() * 0.4;
205
- const actualDelay = Math.floor(delay * jitter);
206
- // Update nextRetryAt in error context
207
- const nextRetryAt = Date.now() + actualDelay;
208
- platformError.context.retry.nextRetryAt = nextRetryAt;
209
- // Log retry attempt
210
- logger.warn(`Retrying operation after error (attempt ${attempt + 1}/${maxAttempts}): ${platformError.message}`, {
211
- error_code: platformError.code,
212
- retry_attempt: attempt + 1,
213
- retry_max_attempts: maxAttempts,
214
- retry_delay_ms: actualDelay,
215
- retry_next_at: new Date(nextRetryAt).toISOString()
216
- });
217
- // Call onRetry callback
218
- onRetry(platformError, attempt + 1, actualDelay);
219
- // Wait before next retry
220
- await new Promise(resolve => setTimeout(resolve, actualDelay));
221
- }
222
- }
223
- // This should never happen, but TypeScript needs it
224
- throw lastError;
225
- }
226
- }
227
- /**
228
- * Create a middleware for handling errors in HTTP requests
229
- *
230
- * @returns Middleware function
231
- */
232
- export function createErrorHandlerMiddleware() {
233
- return (error, req, res, next) => {
234
- // Add request context
235
- const context = {
236
- requestId: req.headers['x-request-id'] || req.headers['x-correlation-id'],
237
- component: 'HttpServer',
238
- operation: `${req.method} ${req.url}`,
239
- data: {
240
- method: req.method,
241
- url: req.url,
242
- query: req.query,
243
- params: req.params,
244
- ip: req.ip || req.connection.remoteAddress,
245
- userAgent: req.headers['user-agent']
246
- }
247
- };
248
- // Handle the error
249
- const formattedError = ErrorHandler.handleError(error, 'PLATFORM_OPERATION_ERROR', context);
250
- // Set status code based on error type
251
- let statusCode = 500;
252
- if (error instanceof PlatformError) {
253
- // Map error categories to HTTP status codes
254
- switch (error.category) {
255
- case ErrorCategory.VALIDATION:
256
- statusCode = 400;
257
- break;
258
- case ErrorCategory.AUTHENTICATION:
259
- statusCode = 401;
260
- break;
261
- case ErrorCategory.RESOURCE:
262
- statusCode = 429;
263
- break;
264
- case ErrorCategory.OPERATION:
265
- statusCode = 400;
266
- break;
267
- default:
268
- statusCode = 500;
269
- }
270
- }
271
- else if (error.statusCode) {
272
- // Use provided status code if available
273
- statusCode = error.statusCode;
274
- }
275
- // Send error response
276
- res.status(statusCode).json({
277
- success: false,
278
- error: formattedError
279
- });
280
- };
281
- }
282
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3ItaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2Vycm9ycy9lcnJvci1oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVqRCxPQUFPLEVBQUUsYUFBYSxFQUFFLG1CQUFtQixFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3JGLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUE0QnRDOztHQUVHO0FBQ0gsTUFBTSxNQUFNLEdBQXdCO0lBQ2xDLFNBQVMsRUFBRSxJQUFJO0lBQ2YsbUJBQW1CLEVBQUUsS0FBSztJQUMxQixLQUFLLEVBQUU7UUFDTCxXQUFXLEVBQUUsQ0FBQztRQUNkLFNBQVMsRUFBRSxJQUFJO1FBQ2YsUUFBUSxFQUFFLEtBQUs7UUFDZixhQUFhLEVBQUUsQ0FBQztLQUNqQjtDQUNGLENBQUM7QUFFRjs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQUN2Qjs7T0FFRztJQUNJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBRTlCOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsU0FBUyxDQUFDLFNBQXVDO1FBQzdELFlBQVksQ0FBQyxNQUFNLEdBQUc7WUFDcEIsR0FBRyxZQUFZLENBQUMsTUFBTTtZQUN0QixHQUFHLFNBQVM7WUFDWixLQUFLLEVBQUU7Z0JBQ0wsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUs7Z0JBQzVCLEdBQUcsQ0FBQyxTQUFTLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQzthQUMzQjtTQUNGLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLE1BQU0sQ0FBQyxlQUFlLENBQzNCLEtBQVUsRUFDVixXQUFtQixFQUNuQixVQUF5QixFQUFFO1FBRTNCLCtDQUErQztRQUMvQyxJQUFJLEtBQUssWUFBWSxhQUFhLEVBQUUs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
@@ -1,54 +0,0 @@
1
- /**
2
- * Platform Service Error System
3
- *
4
- * This module provides a comprehensive error handling system for the Platform Service,
5
- * with structured error types, error codes, and consistent patterns for logging and recovery.
6
- */
7
- export * from './error.codes.js';
8
- export * from './base.errors.js';
9
- export * from './reputation.errors.js';
10
- export * from './error-handler.js';
11
- import { getErrorClassForCategory } from './base.errors.js';
12
- export { getErrorClassForCategory };
13
- import { PlatformError } from './base.errors.js';
14
- /**
15
- * Create a typed error from a standard Error
16
- * Useful for converting errors from external libraries or APIs
17
- *
18
- * @param error Standard error to convert
19
- * @param code Error code to assign
20
- * @param contextData Additional context data
21
- * @returns Typed PlatformError
22
- */
23
- export declare function fromError(error: Error, code: string, contextData?: Record<string, any>): PlatformError;
24
- /**
25
- * Determine if an error is retryable
26
- *
27
- * @param error Error to check
28
- * @returns Boolean indicating if the error should be retried
29
- */
30
- export declare function isRetryable(error: any): boolean;
31
- /**
32
- * Create a wrapped version of a function that catches errors
33
- * and converts them to typed PlatformErrors
34
- *
35
- * @param fn Function to wrap
36
- * @param errorCode Default error code to use
37
- * @param contextData Additional context data
38
- * @returns Wrapped function
39
- */
40
- export declare function withErrorHandling<T extends (...args: any[]) => Promise<any>>(fn: T, errorCode: string, contextData?: Record<string, any>): T;
41
- /**
42
- * Retry a function with exponential backoff
43
- *
44
- * @param fn Function to retry
45
- * @param options Retry options
46
- * @returns Function result or throws after max retries
47
- */
48
- export declare function retry<T>(fn: () => Promise<T>, options?: {
49
- maxRetries?: number;
50
- initialDelay?: number;
51
- maxDelay?: number;
52
- backoffFactor?: number;
53
- retryableErrors?: Array<string | RegExp>;
54
- }): Promise<T>;
@@ -1,136 +0,0 @@
1
- /**
2
- * Platform Service Error System
3
- *
4
- * This module provides a comprehensive error handling system for the Platform Service,
5
- * with structured error types, error codes, and consistent patterns for logging and recovery.
6
- */
7
- // Export error codes and types
8
- export * from './error.codes.js';
9
- // Export base error classes
10
- export * from './base.errors.js';
11
- // Export domain-specific error classes
12
- export * from './reputation.errors.js';
13
- // Export error handler
14
- export * from './error-handler.js';
15
- // Export utility function to create specific error types based on the error category
16
- import { getErrorClassForCategory } from './base.errors.js';
17
- export { getErrorClassForCategory };
18
- // Import needed classes for utility functions
19
- import { PlatformError } from './base.errors.js';
20
- import { ErrorSeverity, ErrorCategory, ErrorRecoverability } from './error.codes.js';
21
- /**
22
- * Create a typed error from a standard Error
23
- * Useful for converting errors from external libraries or APIs
24
- *
25
- * @param error Standard error to convert
26
- * @param code Error code to assign
27
- * @param contextData Additional context data
28
- * @returns Typed PlatformError
29
- */
30
- export function fromError(error, code, contextData = {}) {
31
- return new PlatformError(error.message, code, ErrorSeverity.MEDIUM, ErrorCategory.OPERATION, ErrorRecoverability.NON_RECOVERABLE, {
32
- data: {
33
- ...contextData,
34
- originalError: {
35
- name: error.name,
36
- message: error.message,
37
- stack: error.stack
38
- }
39
- }
40
- });
41
- }
42
- /**
43
- * Determine if an error is retryable
44
- *
45
- * @param error Error to check
46
- * @returns Boolean indicating if the error should be retried
47
- */
48
- export function isRetryable(error) {
49
- // If it's our platform error, use its recoverability property
50
- if (error && typeof error === 'object' && 'recoverability' in error) {
51
- return error.recoverability === ErrorRecoverability.RECOVERABLE ||
52
- error.recoverability === ErrorRecoverability.MAYBE_RECOVERABLE ||
53
- error.recoverability === ErrorRecoverability.TRANSIENT;
54
- }
55
- // Check if it's a network error (these are often transient)
56
- if (error && typeof error === 'object' && error.code) {
57
- const networkErrors = [
58
- 'ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'EHOSTUNREACH',
59
- 'ENETUNREACH', 'ENOTFOUND', 'EPROTO', 'ECONNABORTED'
60
- ];
61
- return networkErrors.includes(error.code);
62
- }
63
- // By default, we can't determine if the error is retryable
64
- return false;
65
- }
66
- /**
67
- * Create a wrapped version of a function that catches errors
68
- * and converts them to typed PlatformErrors
69
- *
70
- * @param fn Function to wrap
71
- * @param errorCode Default error code to use
72
- * @param contextData Additional context data
73
- * @returns Wrapped function
74
- */
75
- export function withErrorHandling(fn, errorCode, contextData = {}) {
76
- return (async function (...args) {
77
- try {
78
- return await fn(...args);
79
- }
80
- catch (error) {
81
- if (error && typeof error === 'object' && 'code' in error) {
82
- // Already a typed error, rethrow
83
- throw error;
84
- }
85
- throw fromError(error instanceof Error ? error : new Error(String(error)), errorCode, {
86
- ...contextData,
87
- fnName: fn.name,
88
- args: args.map(arg => typeof arg === 'object'
89
- ? '[Object]'
90
- : String(arg).substring(0, 100))
91
- });
92
- }
93
- });
94
- }
95
- /**
96
- * Retry a function with exponential backoff
97
- *
98
- * @param fn Function to retry
99
- * @param options Retry options
100
- * @returns Function result or throws after max retries
101
- */
102
- export async function retry(fn, options = {}) {
103
- const { maxRetries = 3, initialDelay = 1000, maxDelay = 30000, backoffFactor = 2, retryableErrors = [] } = options;
104
- let lastError;
105
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
106
- try {
107
- return await fn();
108
- }
109
- catch (error) {
110
- lastError = error instanceof Error
111
- ? error
112
- : new Error(String(error));
113
- // Check if we should retry
114
- const shouldRetry = attempt < maxRetries && (isRetryable(error) ||
115
- retryableErrors.some(pattern => {
116
- if (typeof pattern === 'string') {
117
- return lastError.message.includes(pattern);
118
- }
119
- return pattern.test(lastError.message);
120
- }));
121
- if (!shouldRetry) {
122
- throw lastError;
123
- }
124
- // Calculate delay with exponential backoff
125
- const delay = Math.min(initialDelay * Math.pow(backoffFactor, attempt), maxDelay);
126
- // Add jitter to prevent thundering herd problem (±20%)
127
- const jitter = 0.8 + Math.random() * 0.4;
128
- const actualDelay = Math.floor(delay * jitter);
129
- // Wait before next retry
130
- await new Promise(resolve => setTimeout(resolve, actualDelay));
131
- }
132
- }
133
- // This should never happen, but TypeScript needs it
134
- throw lastError;
135
- }
136
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9lcnJvcnMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0c7QUFFSCwrQkFBK0I7QUFDL0IsY0FBYyxrQkFBa0IsQ0FBQztBQUVqQyw0QkFBNEI7QUFDNUIsY0FBYyxrQkFBa0IsQ0FBQztBQUVqQyx1Q0FBdUM7QUFDdkMsY0FBYyx3QkFBd0IsQ0FBQztBQUV2Qyx1QkFBdUI7QUFDdkIsY0FBYyxvQkFBb0IsQ0FBQztBQUVuQyxxRkFBcUY7QUFDckYsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDNUQsT0FBTyxFQUFFLHdCQUF3QixFQUFFLENBQUM7QUFFcEMsOENBQThDO0FBQzlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXJGOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FDdkIsS0FBWSxFQUNaLElBQVksRUFDWixjQUFtQyxFQUFFO0lBRXJDLE9BQU8sSUFBSSxhQUFhLENBQ3RCLEtBQUssQ0FBQyxPQUFPLEVBQ2IsSUFBSSxFQUNKLGFBQWEsQ0FBQyxNQUFNLEVBQ3BCLGFBQWEsQ0FBQyxTQUFTLEVBQ3ZCLG1CQUFtQixDQUFDLGVBQWUsRUFDbkM7UUFDRSxJQUFJLEVBQUU7WUFDSixHQUFHLFdBQVc7WUFDZCxhQUFhLEVBQUU7Z0JBQ2IsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO2dCQUNoQixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87Z0JBQ3RCLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSzthQUNuQjtTQUNGO0tBQ0YsQ0FDRixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FBQyxLQUFVO0lB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