@dollhousemcp/mcp-server
Version:
DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.
99 lines • 12.7 kB
JavaScript
/**
* Portfolio Tool Configuration Constants
*
* Centralized configuration for timeout values, file size limits,
* retry behavior, and other portfolio-related constants.
*
* All values can be overridden via environment variables for flexibility.
*/
/**
* GitHub API timeout configuration
* Used for collection submission API calls
*/
export const GITHUB_API_TIMEOUT = {
// Default timeout for GitHub API requests (milliseconds)
DEFAULT: Number.parseInt(process.env.DOLLHOUSE_GITHUB_API_TIMEOUT || '30000'),
// Minimum allowed timeout (5 seconds)
MIN: 5000,
// Maximum allowed timeout (5 minutes)
MAX: 300000
};
/**
* File size limits for portfolio submissions
*/
export const FILE_SIZE_LIMITS = {
// Maximum file size for portfolio submissions (10MB)
MAX_FILE_SIZE: Number.parseInt(process.env.DOLLHOUSE_MAX_FILE_SIZE || String(10 * 1024 * 1024)),
// Human-readable description of the limit
MAX_FILE_SIZE_MB: 10
};
/**
* Retry configuration for API operations
*/
export const RETRY_CONFIG = {
// Maximum number of retry attempts
MAX_ATTEMPTS: Number.parseInt(process.env.DOLLHOUSE_MAX_RETRY_ATTEMPTS || '3'),
// Initial delay between retries (milliseconds)
INITIAL_DELAY: Number.parseInt(process.env.DOLLHOUSE_INITIAL_RETRY_DELAY || '1000'),
// Maximum delay between retries (milliseconds)
MAX_DELAY: Number.parseInt(process.env.DOLLHOUSE_MAX_RETRY_DELAY || '5000'),
// Backoff multiplier for exponential backoff
BACKOFF_MULTIPLIER: 2
};
/**
* Search and similarity matching configuration
*/
export const SEARCH_CONFIG = {
// Minimum similarity score for name suggestions (0.0 to 1.0)
MIN_SIMILARITY_SCORE: Number.parseFloat(process.env.DOLLHOUSE_MIN_SIMILARITY || '0.3'),
// Maximum number of suggestions to return
MAX_SUGGESTIONS: Number.parseInt(process.env.DOLLHOUSE_MAX_SUGGESTIONS || '5')
};
/**
* Environment variable names for documentation
*/
export const ENV_VARS = {
GITHUB_API_TIMEOUT: 'DOLLHOUSE_GITHUB_API_TIMEOUT',
MAX_FILE_SIZE: 'DOLLHOUSE_MAX_FILE_SIZE',
MAX_RETRY_ATTEMPTS: 'DOLLHOUSE_MAX_RETRY_ATTEMPTS',
INITIAL_RETRY_DELAY: 'DOLLHOUSE_INITIAL_RETRY_DELAY',
MAX_RETRY_DELAY: 'DOLLHOUSE_MAX_RETRY_DELAY',
MIN_SIMILARITY: 'DOLLHOUSE_MIN_SIMILARITY',
MAX_SUGGESTIONS: 'DOLLHOUSE_MAX_SUGGESTIONS'
};
/**
* Validation helper to ensure timeout is within acceptable bounds
*/
export function getValidatedTimeout() {
const timeout = GITHUB_API_TIMEOUT.DEFAULT;
if (timeout < GITHUB_API_TIMEOUT.MIN) {
return GITHUB_API_TIMEOUT.MIN;
}
if (timeout > GITHUB_API_TIMEOUT.MAX) {
return GITHUB_API_TIMEOUT.MAX;
}
return timeout;
}
/**
* GitHub API rate limiting configuration
* Implements client-side rate limiting to respect GitHub's API limits
*/
export const GITHUB_API_RATE_LIMITS = {
// GitHub API limits: 5000/hour authenticated, 60/hour unauthenticated
AUTHENTICATED_LIMIT: Number.parseInt(process.env.DOLLHOUSE_GITHUB_RATE_LIMIT_AUTH || '5000'),
UNAUTHENTICATED_LIMIT: Number.parseInt(process.env.DOLLHOUSE_GITHUB_RATE_LIMIT_UNAUTH || '60'),
// Time window for rate limiting (1 hour)
WINDOW_MS: 60 * 60 * 1000,
// Minimum delay between API calls to prevent rapid-fire requests
MIN_DELAY_MS: Number.parseInt(process.env.DOLLHOUSE_GITHUB_MIN_DELAY || '1000'),
// Buffer percentage - stay below actual limits to avoid hitting them
BUFFER_PERCENTAGE: Number.parseFloat(process.env.DOLLHOUSE_GITHUB_RATE_BUFFER || '0.9')
};
/**
* Calculate retry delay using exponential backoff
*/
export function calculateRetryDelay(attempt) {
const delay = Math.min(RETRY_CONFIG.INITIAL_DELAY * Math.pow(RETRY_CONFIG.BACKOFF_MULTIPLIER, attempt - 1), RETRY_CONFIG.MAX_DELAY);
return delay;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9ydGZvbGlvLWNvbnN0YW50cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25maWcvcG9ydGZvbGlvLWNvbnN0YW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7OztHQU9HO0FBY0g7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUc7SUFDaEMseURBQXlEO0lBQ3pELE9BQU8sRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLElBQUksT0FBTyxDQUFDO0lBRTdFLHNDQUFzQztJQUN0QyxHQUFHLEVBQUUsSUFBSTtJQUVULHNDQUFzQztJQUN0QyxHQUFHLEVBQUUsTUFBTTtDQUNILENBQUM7QUFFWDs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHO0lBQzlCLHFEQUFxRDtJQUNyRCxhQUFhLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixJQUFJLE1BQU0sQ0FBQyxFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDO0lBRS9GLDBDQUEwQztJQUMxQyxnQkFBZ0IsRUFBRSxFQUFFO0NBQ1osQ0FBQztBQUVYOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHO0lBQzFCLG1DQUFtQztJQUNuQyxZQUFZLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixJQUFJLEdBQUcsQ0FBQztJQUU5RSwrQ0FBK0M7SUFDL0MsYUFBYSxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsSUFBSSxNQUFNLENBQUM7SUFFbkYsK0NBQStDO0lBQy9DLFNBQVMsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLElBQUksTUFBTSxDQUFDO0lBRTNFLDZDQUE2QztJQUM3QyxrQkFBa0IsRUFBRSxDQUFDO0NBQ2IsQ0FBQztBQUVYOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHO0lBQzNCLDZEQUE2RDtJQUM3RCxvQkFBb0IsRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0JBQXdCLElBQUksS0FBSyxDQUFDO0lBRXRGLDBDQUEwQztJQUMxQyxlQUFlLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHlCQUF5QixJQUFJLEdBQUcsQ0FBQztDQUN0RSxDQUFDO0FBRVg7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxRQUFRLEdBQUc7SUFDdEIsa0JBQWtCLEVBQUUsOEJBQThCO0lBQ2xELGFBQWEsRUFBRSx5QkFBeUI7SUFDeEMsa0JBQWtCLEVBQUUsOEJBQThCO0lBQ2xELG1CQUFtQixFQUFFLCtCQUErQjtJQUNwRCxlQUFlLEVBQUUsMkJBQTJCO0lBQzVDLGNBQWMsRUFBRSwwQkFBMEI7SUFDMUMsZUFBZSxFQUFFLDJCQUEyQjtDQUNwQyxDQUFDO0FBRVg7O0dBRUc7QUFDSCxNQUFNLFVBQVUsbUJBQW1CO0lBQ2pDLE1BQU0sT0FBTyxHQUFHLGtCQUFrQixDQUFDLE9BQU8sQ0FBQztJQUUzQyxJQUFJLE9BQU8sR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNyQyxPQUFPLGtCQUFrQixDQUFDLEdBQUcsQ0FBQztJQUNoQyxDQUFDO0lBRUQsSUFBSSxPQUFPLEdBQUcsa0JBQWtCLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDckMsT0FBTyxrQkFBa0IsQ0FBQyxHQUFHLENBQUM7SUFDaEMsQ0FBQztJQUVELE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRztJQUNwQyxzRUFBc0U7SUFDdEUsbUJBQW1CLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGdDQUFnQyxJQUFJLE1BQU0sQ0FBQztJQUM1RixxQkFBcUIsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0NBQWtDLElBQUksSUFBSSxDQUFDO0lBRTlGLHlDQUF5QztJQUN6QyxTQUFTLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJO0lBRXpCLGlFQUFpRTtJQUNqRSxZQUFZLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixJQUFJLE1BQU0sQ0FBQztJQUUvRSxxRUFBcUU7SUFDckUsaUJBQWlCLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixJQUFJLEtBQUssQ0FBQztDQUMvRSxDQUFDO0FBRVg7O0dBRUc7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQUMsT0FBZTtJQUNqRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUNwQixZQUFZLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLGtCQUFrQixFQUFFLE9BQU8sR0FBRyxDQUFDLENBQUMsRUFDbkYsWUFBWSxDQUFDLFNBQVMsQ0FDdkIsQ0FBQztJQUNGLE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUG9ydGZvbGlvIFRvb2wgQ29uZmlndXJhdGlvbiBDb25zdGFudHNcbiAqIFxuICogQ2VudHJhbGl6ZWQgY29uZmlndXJhdGlvbiBmb3IgdGltZW91dCB2YWx1ZXMsIGZpbGUgc2l6ZSBsaW1pdHMsXG4gKiByZXRyeSBiZWhhdmlvciwgYW5kIG90aGVyIHBvcnRmb2xpby1yZWxhdGVkIGNvbnN0YW50cy5cbiAqIFxuICogQWxsIHZhbHVlcyBjYW4gYmUgb3ZlcnJpZGRlbiB2aWEgZW52aXJvbm1lbnQgdmFyaWFibGVzIGZvciBmbGV4aWJpbGl0eS5cbiAqL1xuXG4vKipcbiAqIFBvcnRmb2xpbyBlbGVtZW50IG1ldGFkYXRhIGludGVyZmFjZSBmb3IgdHlwZSBzYWZldHlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQb3J0Zm9saW9FbGVtZW50TWV0YWRhdGEge1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGF1dGhvcjogc3RyaW5nO1xuICBjcmVhdGVkOiBzdHJpbmc7XG4gIHVwZGF0ZWQ6IHN0cmluZztcbiAgdmVyc2lvbjogc3RyaW5nO1xufVxuXG4vKipcbiAqIEdpdEh1YiBBUEkgdGltZW91dCBjb25maWd1cmF0aW9uXG4gKiBVc2VkIGZvciBjb2xsZWN0aW9uIHN1Ym1pc3Npb24gQVBJIGNhbGxzXG4gKi9cbmV4cG9ydCBjb25zdCBHSVRIVUJfQVBJX1RJTUVPVVQgPSB7XG4gIC8vIERlZmF1bHQgdGltZW91dCBmb3IgR2l0SHViIEFQSSByZXF1ZXN0cyAobWlsbGlzZWNvbmRzKVxuICBERUZBVUxUOiBOdW1iZXIucGFyc2VJbnQocHJvY2Vzcy5lbnYuRE9MTEhPVVNFX0dJVEhVQl9BUElfVElNRU9VVCB8fCAnMzAwMDAnKSxcbiAgXG4gIC8vIE1pbmltdW0gYWxsb3dlZCB0aW1lb3V0ICg1IHNlY29uZHMpXG4gIE1JTjogNTAwMCxcbiAgXG4gIC8vIE1heGltdW0gYWxsb3dlZCB0aW1lb3V0ICg1IG1pbnV0ZXMpXG4gIE1BWDogMzAwMDAwXG59IGFzIGNvbnN0O1xuXG4vKipcbiAqIEZpbGUgc2l6ZSBsaW1pdHMgZm9yIHBvcnRmb2xpbyBzdWJtaXNzaW9uc1xuICovXG5leHBvcnQgY29uc3QgRklMRV9TSVpFX0xJTUlUUyA9IHtcbiAgLy8gTWF4aW11bSBmaWxlIHNpemUgZm9yIHBvcnRmb2xpbyBzdWJtaXNzaW9ucyAoMTBNQilcbiAgTUFYX0ZJTEVfU0laRTogTnVtYmVyLnBhcnNlSW50KHByb2Nlc3MuZW52LkRPTExIT1VTRV9NQVhfRklMRV9TSVpFIHx8IFN0cmluZygxMCAqIDEwMjQgKiAxMDI0KSksXG4gIFxuICAvLyBIdW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUgbGltaXRcbiAgTUFYX0ZJTEVfU0laRV9NQjogMTBcbn0gYXMgY29uc3Q7XG5cbi8qKlxuICogUmV0cnkgY29uZmlndXJhdGlvbiBmb3IgQVBJIG9wZXJhdGlvbnNcbiAqL1xuZXhwb3J0IGNvbnN0IFJFVFJZX0NPTkZJRyA9IHtcbiAgLy8gTWF4aW11bSBudW1iZXIgb2YgcmV0cnkgYXR0ZW1wdHNcbiAgTUFYX0FUVEVNUFRTOiBOdW1iZXIucGFyc2VJbnQocHJvY2Vzcy5lbnYuRE9MTEhPVVNFX01BWF9SRVRSWV9BVFRFTVBUUyB8fCAnMycpLFxuICBcbiAgLy8gSW5pdGlhbCBkZWxheSBiZXR3ZWVuIHJldHJpZXMgKG1pbGxpc2Vjb25kcylcbiAgSU5JVElBTF9ERUxBWTogTnVtYmVyLnBhcnNlSW50KHByb2Nlc3MuZW52LkRPTExIT1VTRV9JTklUSUFMX1JFVFJZX0RFTEFZIHx8ICcxMDAwJyksXG4gIFxuICAvLyBNYXhpbXVtIGRlbGF5IGJldHdlZW4gcmV0cmllcyAobWlsbGlzZWNvbmRzKVxuICBNQVhfREVMQVk6IE51bWJlci5wYXJzZUludChwcm9jZXNzLmVudi5ET0xMSE9VU0VfTUFYX1JFVFJZX0RFTEFZIHx8ICc1MDAwJyksXG4gIFxuICAvLyBCYWNrb2ZmIG11bHRpcGxpZXIgZm9yIGV4cG9uZW50aWFsIGJhY2tvZmZcbiAgQkFDS09GRl9NVUxUSVBMSUVSOiAyXG59IGFzIGNvbnN0O1xuXG4vKipcbiAqIFNlYXJjaCBhbmQgc2ltaWxhcml0eSBtYXRjaGluZyBjb25maWd1cmF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBTRUFSQ0hfQ09ORklHID0ge1xuICAvLyBNaW5pbXVtIHNpbWlsYXJpdHkgc2NvcmUgZm9yIG5hbWUgc3VnZ2VzdGlvbnMgKDAuMCB0byAxLjApXG4gIE1JTl9TSU1JTEFSSVRZX1NDT1JFOiBOdW1iZXIucGFyc2VGbG9hdChwcm9jZXNzLmVudi5ET0xMSE9VU0VfTUlOX1NJTUlMQVJJVFkgfHwgJzAuMycpLFxuICBcbiAgLy8gTWF4aW11bSBudW1iZXIgb2Ygc3VnZ2VzdGlvbnMgdG8gcmV0dXJuXG4gIE1BWF9TVUdHRVNUSU9OUzogTnVtYmVyLnBhcnNlSW50KHByb2Nlc3MuZW52LkRPTExIT1VTRV9NQVhfU1VHR0VTVElPTlMgfHwgJzUnKVxufSBhcyBjb25zdDtcblxuLyoqXG4gKiBFbnZpcm9ubWVudCB2YXJpYWJsZSBuYW1lcyBmb3IgZG9jdW1lbnRhdGlvblxuICovXG5leHBvcnQgY29uc3QgRU5WX1ZBUlMgPSB7XG4gIEdJVEhVQl9BUElfVElNRU9VVDogJ0RPTExIT1VTRV9HSVRIVUJfQVBJX1RJTUVPVVQnLFxuICBNQVhfRklMRV9TSVpFOiAnRE9MTEhPVVNFX01BWF9GSUxFX1NJWkUnLFxuICBNQVhfUkVUUllfQVRURU1QVFM6ICdET0xMSE9VU0VfTUFYX1JFVFJZX0FUVEVNUFRTJyxcbiAgSU5JVElBTF9SRVRSWV9ERUxBWTogJ0RPTExIT1VTRV9JTklUSUFMX1JFVFJZX0RFTEFZJyxcbiAgTUFYX1JFVFJZX0RFTEFZOiAnRE9MTEhPVVNFX01BWF9SRVRSWV9ERUxBWScsXG4gIE1JTl9TSU1JTEFSSVRZOiAnRE9MTEhPVVNFX01JTl9TSU1JTEFSSVRZJyxcbiAgTUFYX1NVR0dFU1RJT05TOiAnRE9MTEhPVVNFX01BWF9TVUdHRVNUSU9OUydcbn0gYXMgY29uc3Q7XG5cbi8qKlxuICogVmFsaWRhdGlvbiBoZWxwZXIgdG8gZW5zdXJlIHRpbWVvdXQgaXMgd2l0aGluIGFjY2VwdGFibGUgYm91bmRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRWYWxpZGF0ZWRUaW1lb3V0KCk6IG51bWJlciB7XG4gIGNvbnN0IHRpbWVvdXQgPSBHSVRIVUJfQVBJX1RJTUVPVVQuREVGQVVMVDtcbiAgXG4gIGlmICh0aW1lb3V0IDwgR0lUSFVCX0FQSV9USU1FT1VULk1JTikge1xuICAgIHJldHVybiBHSVRIVUJfQVBJX1RJTUVPVVQuTUlOO1xuICB9XG4gIFxuICBpZiAodGltZW91dCA+IEdJVEhVQl9BUElfVElNRU9VVC5NQVgpIHtcbiAgICByZXR1cm4gR0lUSFVCX0FQSV9USU1FT1VULk1BWDtcbiAgfVxuICBcbiAgcmV0dXJuIHRpbWVvdXQ7XG59XG5cbi8qKlxuICogR2l0SHViIEFQSSByYXRlIGxpbWl0aW5nIGNvbmZpZ3VyYXRpb25cbiAqIEltcGxlbWVudHMgY2xpZW50LXNpZGUgcmF0ZSBsaW1pdGluZyB0byByZXNwZWN0IEdpdEh1YidzIEFQSSBsaW1pdHNcbiAqL1xuZXhwb3J0IGNvbnN0IEdJVEhVQl9BUElfUkFURV9MSU1JVFMgPSB7XG4gIC8vIEdpdEh1YiBBUEkgbGltaXRzOiA1MDAwL2hvdXIgYXV0aGVudGljYXRlZCwgNjAvaG91ciB1bmF1dGhlbnRpY2F0ZWRcbiAgQVVUSEVOVElDQVRFRF9MSU1JVDogTnVtYmVyLnBhcnNlSW50KHByb2Nlc3MuZW52LkRPTExIT1VTRV9HSVRIVUJfUkFURV9MSU1JVF9BVVRIIHx8ICc1MDAwJyksXG4gIFVOQVVUSEVOVElDQVRFRF9MSU1JVDogTnVtYmVyLnBhcnNlSW50KHByb2Nlc3MuZW52LkRPTExIT1VTRV9HSVRIVUJfUkFURV9MSU1JVF9VTkFVVEggfHwgJzYwJyksXG4gIFxuICAvLyBUaW1lIHdpbmRvdyBmb3IgcmF0ZSBsaW1pdGluZyAoMSBob3VyKVxuICBXSU5ET1dfTVM6IDYwICogNjAgKiAxMDAwLFxuICBcbiAgLy8gTWluaW11bSBkZWxheSBiZXR3ZWVuIEFQSSBjYWxscyB0byBwcmV2ZW50IHJhcGlkLWZpcmUgcmVxdWVzdHNcbiAgTUlOX0RFTEFZX01TOiBOdW1iZXIucGFyc2VJbnQocHJvY2Vzcy5lbnYuRE9MTEhPVVNFX0dJVEhVQl9NSU5fREVMQVkgfHwgJzEwMDAnKSxcbiAgXG4gIC8vIEJ1ZmZlciBwZXJjZW50YWdlIC0gc3RheSBiZWxvdyBhY3R1YWwgbGltaXRzIHRvIGF2b2lkIGhpdHRpbmcgdGhlbVxuICBCVUZGRVJfUEVSQ0VOVEFHRTogTnVtYmVyLnBhcnNlRmxvYXQocHJvY2Vzcy5lbnYuRE9MTEhPVVNFX0dJVEhVQl9SQVRFX0JVRkZFUiB8fCAnMC45Jylcbn0gYXMgY29uc3Q7XG5cbi8qKlxuICogQ2FsY3VsYXRlIHJldHJ5IGRlbGF5IHVzaW5nIGV4cG9uZW50aWFsIGJhY2tvZmZcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVJldHJ5RGVsYXkoYXR0ZW1wdDogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3QgZGVsYXkgPSBNYXRoLm1pbihcbiAgICBSRVRSWV9DT05GSUcuSU5JVElBTF9ERUxBWSAqIE1hdGgucG93KFJFVFJZX0NPTkZJRy5CQUNLT0ZGX01VTFRJUExJRVIsIGF0dGVtcHQgLSAxKSxcbiAgICBSRVRSWV9DT05GSUcuTUFYX0RFTEFZXG4gICk7XG4gIHJldHVybiBkZWxheTtcbn0iXX0=