UNPKG

@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.

145 lines 17.3 kB
/** * Centralized configuration for autonomy evaluation thresholds * * Issue #390 (Post-Review Improvement): Makes risk thresholds and step limits * configurable via environment variables. Previously, RISK_THRESHOLDS and * maxAutonomousSteps were hardcoded constants in autonomyEvaluator.ts. * * Environment variables follow the pattern: DOLLHOUSE_AUTONOMY_* * Values are clamped between safety floors and security ceilings. * * @example * // Override via environment variables (set before server starts) * // DOLLHOUSE_AUTONOMY_THRESHOLD_CONSERVATIVE=20 * // DOLLHOUSE_AUTONOMY_THRESHOLD_MODERATE=40 * // DOLLHOUSE_AUTONOMY_THRESHOLD_AGGRESSIVE=70 * // DOLLHOUSE_AUTONOMY_MAX_STEPS_DEFAULT=15 */ import { parseEnvInt } from './env-utils.js'; // ==================== HARD LIMITS (Security Ceiling) ==================== /** * Absolute maximum values — cannot be exceeded even with environment variable overrides. * Prevents nonsensical or dangerous configurations. */ export const AUTONOMY_HARD_LIMITS = { /** Max conservative threshold. Prevents it from being set so high it never triggers. */ thresholdConservative: 50, /** Max moderate threshold. */ thresholdModerate: 80, /** Max aggressive threshold. Must stay below 100 to retain some safety margin. */ thresholdAggressive: 95, /** Max step limit. Prevents runaway agents even with misconfiguration. */ maxStepsDefault: 100, }; // ==================== MIN LIMITS (Safety Floor) ==================== /** * Minimum values — configured values cannot go below these. * Ensures thresholds remain meaningful and agents don't immediately pause. */ export const AUTONOMY_MIN_LIMITS = { /** Min conservative threshold. Must be positive to allow very-low-risk actions. */ thresholdConservative: 5, /** Min moderate threshold. Must be above conservative floor. */ thresholdModerate: 20, /** Min aggressive threshold. Must be above moderate floor. */ thresholdAggressive: 40, /** Min step limit. Agents need at least 1 step to do anything. */ maxStepsDefault: 1, }; // ==================== DEFAULTS ==================== /** * Default values when no environment variable is set. * Matches the original hardcoded constants from autonomyEvaluator.ts. */ export const AUTONOMY_DEFAULTS = { /** * Conservative threshold (25): Pauses on any moderate risk. * Suitable for production, financial, or security-sensitive agents. */ thresholdConservative: 25, /** * Moderate threshold (50): Balances autonomy and safety. * Default for most agents. */ thresholdModerate: 50, /** * Aggressive threshold (75): Only pauses on high-risk actions. * For trusted, well-tested agents in controlled environments. */ thresholdAggressive: 75, /** * Default max autonomous steps (10): How many steps an agent can * take before requiring human check-in. */ maxStepsDefault: 10, }; // ==================== ENVIRONMENT VARIABLE MAPPING ==================== /** * Maps autonomy config keys to their environment variable names. * Exported for documentation and testing purposes. */ export const AUTONOMY_ENV_VARS = { thresholdConservative: 'DOLLHOUSE_AUTONOMY_THRESHOLD_CONSERVATIVE', thresholdModerate: 'DOLLHOUSE_AUTONOMY_THRESHOLD_MODERATE', thresholdAggressive: 'DOLLHOUSE_AUTONOMY_THRESHOLD_AGGRESSIVE', maxStepsDefault: 'DOLLHOUSE_AUTONOMY_MAX_STEPS_DEFAULT', }; // ==================== PUBLIC API ==================== /** * Get the conservative risk threshold. * * Actions with risk scores above this threshold require human approval * when an agent uses conservative risk tolerance. Low value means the * agent pauses on even moderate-risk actions. * * Suitable for production, financial, or security-sensitive agents. */ export function getAutonomyThresholdConservative() { return parseEnvInt(AUTONOMY_ENV_VARS.thresholdConservative, AUTONOMY_DEFAULTS.thresholdConservative, AUTONOMY_MIN_LIMITS.thresholdConservative, AUTONOMY_HARD_LIMITS.thresholdConservative, 'Autonomy threshold'); } /** * Get the moderate risk threshold. * * Balances autonomy and safety. Default for most agents. * Actions with risk scores above this value trigger a pause. */ export function getAutonomyThresholdModerate() { return parseEnvInt(AUTONOMY_ENV_VARS.thresholdModerate, AUTONOMY_DEFAULTS.thresholdModerate, AUTONOMY_MIN_LIMITS.thresholdModerate, AUTONOMY_HARD_LIMITS.thresholdModerate, 'Autonomy threshold'); } /** * Get the aggressive risk threshold. * * Only pauses on high-risk actions. For trusted, well-tested agents * in controlled environments where speed is prioritized. */ export function getAutonomyThresholdAggressive() { return parseEnvInt(AUTONOMY_ENV_VARS.thresholdAggressive, AUTONOMY_DEFAULTS.thresholdAggressive, AUTONOMY_MIN_LIMITS.thresholdAggressive, AUTONOMY_HARD_LIMITS.thresholdAggressive, 'Autonomy threshold'); } /** * Get the default maximum autonomous steps. * * Controls how many steps an agent can take before requiring * human check-in, when the agent doesn't specify its own limit. */ export function getAutonomyMaxStepsDefault() { return parseEnvInt(AUTONOMY_ENV_VARS.maxStepsDefault, AUTONOMY_DEFAULTS.maxStepsDefault, AUTONOMY_MIN_LIMITS.maxStepsDefault, AUTONOMY_HARD_LIMITS.maxStepsDefault, 'Autonomy limit'); } /** * Get all risk thresholds as a record keyed by tolerance level. * * Convenience function for callers that need the full threshold map * (e.g., the autonomy evaluator's checkRiskThreshold function). * * @returns Object with keys `conservative`, `moderate`, and `aggressive`, * each mapping to a risk score threshold (0–100). These keys correspond * to the `riskTolerance` field on `AgentAutonomyConfig`. Actions with * risk scores above the agent's tolerance threshold trigger a pause. */ export function getAutonomyRiskThresholds() { return { conservative: getAutonomyThresholdConservative(), moderate: getAutonomyThresholdModerate(), aggressive: getAutonomyThresholdAggressive(), }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0b25vbXktY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy9hdXRvbm9teS1jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFFSCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFN0MsMkVBQTJFO0FBQzNFOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHO0lBQ2xDLHdGQUF3RjtJQUN4RixxQkFBcUIsRUFBRSxFQUFFO0lBQ3pCLDhCQUE4QjtJQUM5QixpQkFBaUIsRUFBRSxFQUFFO0lBQ3JCLGtGQUFrRjtJQUNsRixtQkFBbUIsRUFBRSxFQUFFO0lBQ3ZCLDBFQUEwRTtJQUMxRSxlQUFlLEVBQUUsR0FBRztDQUNaLENBQUM7QUFFWCxzRUFBc0U7QUFDdEU7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUc7SUFDakMsbUZBQW1GO0lBQ25GLHFCQUFxQixFQUFFLENBQUM7SUFDeEIsZ0VBQWdFO0lBQ2hFLGlCQUFpQixFQUFFLEVBQUU7SUFDckIsOERBQThEO0lBQzlELG1CQUFtQixFQUFFLEVBQUU7SUFDdkIsa0VBQWtFO0lBQ2xFLGVBQWUsRUFBRSxDQUFDO0NBQ1YsQ0FBQztBQUVYLHFEQUFxRDtBQUNyRDs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRztJQUMvQjs7O09BR0c7SUFDSCxxQkFBcUIsRUFBRSxFQUFFO0lBQ3pCOzs7T0FHRztJQUNILGlCQUFpQixFQUFFLEVBQUU7SUFDckI7OztPQUdHO0lBQ0gsbUJBQW1CLEVBQUUsRUFBRTtJQUN2Qjs7O09BR0c7SUFDSCxlQUFlLEVBQUUsRUFBRTtDQUNYLENBQUM7QUFFWCx5RUFBeUU7QUFDekU7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUc7SUFDL0IscUJBQXFCLEVBQUUsMkNBQTJDO0lBQ2xFLGlCQUFpQixFQUFFLHVDQUF1QztJQUMxRCxtQkFBbUIsRUFBRSx5Q0FBeUM7SUFDOUQsZUFBZSxFQUFFLHNDQUFzQztDQUMvQyxDQUFDO0FBRVgsdURBQXVEO0FBRXZEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLGdDQUFnQztJQUM5QyxPQUFPLFdBQVcsQ0FDaEIsaUJBQWlCLENBQUMscUJBQXFCLEVBQ3ZDLGlCQUFpQixDQUFDLHFCQUFxQixFQUN2QyxtQkFBbUIsQ0FBQyxxQkFBcUIsRUFDekMsb0JBQW9CLENBQUMscUJBQXFCLEVBQzFDLG9CQUFvQixDQUNyQixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLDRCQUE0QjtJQUMxQyxPQUFPLFdBQVcsQ0FDaEIsaUJBQWlCLENBQUMsaUJBQWlCLEVBQ25DLGlCQUFpQixDQUFDLGlCQUFpQixFQUNuQyxtQkFBbUIsQ0FBQyxpQkFBaUIsRUFDckMsb0JBQW9CLENBQUMsaUJBQWlCLEVBQ3RDLG9CQUFvQixDQUNyQixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLDhCQUE4QjtJQUM1QyxPQUFPLFdBQVcsQ0FDaEIsaUJBQWlCLENBQUMsbUJBQW1CLEVBQ3JDLGlCQUFpQixDQUFDLG1CQUFtQixFQUNyQyxtQkFBbUIsQ0FBQyxtQkFBbUIsRUFDdkMsb0JBQW9CLENBQUMsbUJBQW1CLEVBQ3hDLG9CQUFvQixDQUNyQixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLDBCQUEwQjtJQUN4QyxPQUFPLFdBQVcsQ0FDaEIsaUJBQWlCLENBQUMsZUFBZSxFQUNqQyxpQkFBaUIsQ0FBQyxlQUFlLEVBQ2pDLG1CQUFtQixDQUFDLGVBQWUsRUFDbkMsb0JBQW9CLENBQUMsZUFBZSxFQUNwQyxnQkFBZ0IsQ0FDakIsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxVQUFVLHlCQUF5QjtJQUN2QyxPQUFPO1FBQ0wsWUFBWSxFQUFFLGdDQUFnQyxFQUFFO1FBQ2hELFFBQVEsRUFBRSw0QkFBNEIsRUFBRTtRQUN4QyxVQUFVLEVBQUUsOEJBQThCLEVBQUU7S0FDN0MsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENlbnRyYWxpemVkIGNvbmZpZ3VyYXRpb24gZm9yIGF1dG9ub215IGV2YWx1YXRpb24gdGhyZXNob2xkc1xuICpcbiAqIElzc3VlICMzOTAgKFBvc3QtUmV2aWV3IEltcHJvdmVtZW50KTogTWFrZXMgcmlzayB0aHJlc2hvbGRzIGFuZCBzdGVwIGxpbWl0c1xuICogY29uZmlndXJhYmxlIHZpYSBlbnZpcm9ubWVudCB2YXJpYWJsZXMuIFByZXZpb3VzbHksIFJJU0tfVEhSRVNIT0xEUyBhbmRcbiAqIG1heEF1dG9ub21vdXNTdGVwcyB3ZXJlIGhhcmRjb2RlZCBjb25zdGFudHMgaW4gYXV0b25vbXlFdmFsdWF0b3IudHMuXG4gKlxuICogRW52aXJvbm1lbnQgdmFyaWFibGVzIGZvbGxvdyB0aGUgcGF0dGVybjogRE9MTEhPVVNFX0FVVE9OT01ZXypcbiAqIFZhbHVlcyBhcmUgY2xhbXBlZCBiZXR3ZWVuIHNhZmV0eSBmbG9vcnMgYW5kIHNlY3VyaXR5IGNlaWxpbmdzLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBPdmVycmlkZSB2aWEgZW52aXJvbm1lbnQgdmFyaWFibGVzIChzZXQgYmVmb3JlIHNlcnZlciBzdGFydHMpXG4gKiAvLyBET0xMSE9VU0VfQVVUT05PTVlfVEhSRVNIT0xEX0NPTlNFUlZBVElWRT0yMFxuICogLy8gRE9MTEhPVVNFX0FVVE9OT01ZX1RIUkVTSE9MRF9NT0RFUkFURT00MFxuICogLy8gRE9MTEhPVVNFX0FVVE9OT01ZX1RIUkVTSE9MRF9BR0dSRVNTSVZFPTcwXG4gKiAvLyBET0xMSE9VU0VfQVVUT05PTVlfTUFYX1NURVBTX0RFRkFVTFQ9MTVcbiAqL1xuXG5pbXBvcnQgeyBwYXJzZUVudkludCB9IGZyb20gJy4vZW52LXV0aWxzLmpzJztcblxuLy8gPT09PT09PT09PT09PT09PT09PT0gSEFSRCBMSU1JVFMgKFNlY3VyaXR5IENlaWxpbmcpID09PT09PT09PT09PT09PT09PT09XG4vKipcbiAqIEFic29sdXRlIG1heGltdW0gdmFsdWVzIOKAlCBjYW5ub3QgYmUgZXhjZWVkZWQgZXZlbiB3aXRoIGVudmlyb25tZW50IHZhcmlhYmxlIG92ZXJyaWRlcy5cbiAqIFByZXZlbnRzIG5vbnNlbnNpY2FsIG9yIGRhbmdlcm91cyBjb25maWd1cmF0aW9ucy5cbiAqL1xuZXhwb3J0IGNvbnN0IEFVVE9OT01ZX0hBUkRfTElNSVRTID0ge1xuICAvKiogTWF4IGNvbnNlcnZhdGl2ZSB0aHJlc2hvbGQuIFByZXZlbnRzIGl0IGZyb20gYmVpbmcgc2V0IHNvIGhpZ2ggaXQgbmV2ZXIgdHJpZ2dlcnMuICovXG4gIHRocmVzaG9sZENvbnNlcnZhdGl2ZTogNTAsXG4gIC8qKiBNYXggbW9kZXJhdGUgdGhyZXNob2xkLiAqL1xuICB0aHJlc2hvbGRNb2RlcmF0ZTogODAsXG4gIC8qKiBNYXggYWdncmVzc2l2ZSB0aHJlc2hvbGQuIE11c3Qgc3RheSBiZWxvdyAxMDAgdG8gcmV0YWluIHNvbWUgc2FmZXR5IG1hcmdpbi4gKi9cbiAgdGhyZXNob2xkQWdncmVzc2l2ZTogOTUsXG4gIC8qKiBNYXggc3RlcCBsaW1pdC4gUHJldmVudHMgcnVuYXdheSBhZ2VudHMgZXZlbiB3aXRoIG1pc2NvbmZpZ3VyYXRpb24uICovXG4gIG1heFN0ZXBzRGVmYXVsdDogMTAwLFxufSBhcyBjb25zdDtcblxuLy8gPT09PT09PT09PT09PT09PT09PT0gTUlOIExJTUlUUyAoU2FmZXR5IEZsb29yKSA9PT09PT09PT09PT09PT09PT09PVxuLyoqXG4gKiBNaW5pbXVtIHZhbHVlcyDigJQgY29uZmlndXJlZCB2YWx1ZXMgY2Fubm90IGdvIGJlbG93IHRoZXNlLlxuICogRW5zdXJlcyB0aHJlc2hvbGRzIHJlbWFpbiBtZWFuaW5nZnVsIGFuZCBhZ2VudHMgZG9uJ3QgaW1tZWRpYXRlbHkgcGF1c2UuXG4gKi9cbmV4cG9ydCBjb25zdCBBVVRPTk9NWV9NSU5fTElNSVRTID0ge1xuICAvKiogTWluIGNvbnNlcnZhdGl2ZSB0aHJlc2hvbGQuIE11c3QgYmUgcG9zaXRpdmUgdG8gYWxsb3cgdmVyeS1sb3ctcmlzayBhY3Rpb25zLiAqL1xuICB0aHJlc2hvbGRDb25zZXJ2YXRpdmU6IDUsXG4gIC8qKiBNaW4gbW9kZXJhdGUgdGhyZXNob2xkLiBNdXN0IGJlIGFib3ZlIGNvbnNlcnZhdGl2ZSBmbG9vci4gKi9cbiAgdGhyZXNob2xkTW9kZXJhdGU6IDIwLFxuICAvKiogTWluIGFnZ3Jlc3NpdmUgdGhyZXNob2xkLiBNdXN0IGJlIGFib3ZlIG1vZGVyYXRlIGZsb29yLiAqL1xuICB0aHJlc2hvbGRBZ2dyZXNzaXZlOiA0MCxcbiAgLyoqIE1pbiBzdGVwIGxpbWl0LiBBZ2VudHMgbmVlZCBhdCBsZWFzdCAxIHN0ZXAgdG8gZG8gYW55dGhpbmcuICovXG4gIG1heFN0ZXBzRGVmYXVsdDogMSxcbn0gYXMgY29uc3Q7XG5cbi8vID09PT09PT09PT09PT09PT09PT09IERFRkFVTFRTID09PT09PT09PT09PT09PT09PT09XG4vKipcbiAqIERlZmF1bHQgdmFsdWVzIHdoZW4gbm8gZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgc2V0LlxuICogTWF0Y2hlcyB0aGUgb3JpZ2luYWwgaGFyZGNvZGVkIGNvbnN0YW50cyBmcm9tIGF1dG9ub215RXZhbHVhdG9yLnRzLlxuICovXG5leHBvcnQgY29uc3QgQVVUT05PTVlfREVGQVVMVFMgPSB7XG4gIC8qKlxuICAgKiBDb25zZXJ2YXRpdmUgdGhyZXNob2xkICgyNSk6IFBhdXNlcyBvbiBhbnkgbW9kZXJhdGUgcmlzay5cbiAgICogU3VpdGFibGUgZm9yIHByb2R1Y3Rpb24sIGZpbmFuY2lhbCwgb3Igc2VjdXJpdHktc2Vuc2l0aXZlIGFnZW50cy5cbiAgICovXG4gIHRocmVzaG9sZENvbnNlcnZhdGl2ZTogMjUsXG4gIC8qKlxuICAgKiBNb2RlcmF0ZSB0aHJlc2hvbGQgKDUwKTogQmFsYW5jZXMgYXV0b25vbXkgYW5kIHNhZmV0eS5cbiAgICogRGVmYXVsdCBmb3IgbW9zdCBhZ2VudHMuXG4gICAqL1xuICB0aHJlc2hvbGRNb2RlcmF0ZTogNTAsXG4gIC8qKlxuICAgKiBBZ2dyZXNzaXZlIHRocmVzaG9sZCAoNzUpOiBPbmx5IHBhdXNlcyBvbiBoaWdoLXJpc2sgYWN0aW9ucy5cbiAgICogRm9yIHRydXN0ZWQsIHdlbGwtdGVzdGVkIGFnZW50cyBpbiBjb250cm9sbGVkIGVudmlyb25tZW50cy5cbiAgICovXG4gIHRocmVzaG9sZEFnZ3Jlc3NpdmU6IDc1LFxuICAvKipcbiAgICogRGVmYXVsdCBtYXggYXV0b25vbW91cyBzdGVwcyAoMTApOiBIb3cgbWFueSBzdGVwcyBhbiBhZ2VudCBjYW5cbiAgICogdGFrZSBiZWZvcmUgcmVxdWlyaW5nIGh1bWFuIGNoZWNrLWluLlxuICAgKi9cbiAgbWF4U3RlcHNEZWZhdWx0OiAxMCxcbn0gYXMgY29uc3Q7XG5cbi8vID09PT09PT09PT09PT09PT09PT09IEVOVklST05NRU5UIFZBUklBQkxFIE1BUFBJTkcgPT09PT09PT09PT09PT09PT09PT1cbi8qKlxuICogTWFwcyBhdXRvbm9teSBjb25maWcga2V5cyB0byB0aGVpciBlbnZpcm9ubWVudCB2YXJpYWJsZSBuYW1lcy5cbiAqIEV4cG9ydGVkIGZvciBkb2N1bWVudGF0aW9uIGFuZCB0ZXN0aW5nIHB1cnBvc2VzLlxuICovXG5leHBvcnQgY29uc3QgQVVUT05PTVlfRU5WX1ZBUlMgPSB7XG4gIHRocmVzaG9sZENvbnNlcnZhdGl2ZTogJ0RPTExIT1VTRV9BVVRPTk9NWV9USFJFU0hPTERfQ09OU0VSVkFUSVZFJyxcbiAgdGhyZXNob2xkTW9kZXJhdGU6ICdET0xMSE9VU0VfQVVUT05PTVlfVEhSRVNIT0xEX01PREVSQVRFJyxcbiAgdGhyZXNob2xkQWdncmVzc2l2ZTogJ0RPTExIT1VTRV9BVVRPTk9NWV9USFJFU0hPTERfQUdHUkVTU0lWRScsXG4gIG1heFN0ZXBzRGVmYXVsdDogJ0RPTExIT1VTRV9BVVRPTk9NWV9NQVhfU1RFUFNfREVGQVVMVCcsXG59IGFzIGNvbnN0O1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PSBQVUJMSUMgQVBJID09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogR2V0IHRoZSBjb25zZXJ2YXRpdmUgcmlzayB0aHJlc2hvbGQuXG4gKlxuICogQWN0aW9ucyB3aXRoIHJpc2sgc2NvcmVzIGFib3ZlIHRoaXMgdGhyZXNob2xkIHJlcXVpcmUgaHVtYW4gYXBwcm92YWxcbiAqIHdoZW4gYW4gYWdlbnQgdXNlcyBjb25zZXJ2YXRpdmUgcmlzayB0b2xlcmFuY2UuIExvdyB2YWx1ZSBtZWFucyB0aGVcbiAqIGFnZW50IHBhdXNlcyBvbiBldmVuIG1vZGVyYXRlLXJpc2sgYWN0aW9ucy5cbiAqXG4gKiBTdWl0YWJsZSBmb3IgcHJvZHVjdGlvbiwgZmluYW5jaWFsLCBvciBzZWN1cml0eS1zZW5zaXRpdmUgYWdlbnRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXV0b25vbXlUaHJlc2hvbGRDb25zZXJ2YXRpdmUoKTogbnVtYmVyIHtcbiAgcmV0dXJuIHBhcnNlRW52SW50KFxuICAgIEFVVE9OT01ZX0VOVl9WQVJTLnRocmVzaG9sZENvbnNlcnZhdGl2ZSxcbiAgICBBVVRPTk9NWV9ERUZBVUxUUy50aHJlc2hvbGRDb25zZXJ2YXRpdmUsXG4gICAgQVVUT05PTVlfTUlOX0xJTUlUUy50aHJlc2hvbGRDb25zZXJ2YXRpdmUsXG4gICAgQVVUT05PTVlfSEFSRF9MSU1JVFMudGhyZXNob2xkQ29uc2VydmF0aXZlLFxuICAgICdBdXRvbm9teSB0aHJlc2hvbGQnXG4gICk7XG59XG5cbi8qKlxuICogR2V0IHRoZSBtb2RlcmF0ZSByaXNrIHRocmVzaG9sZC5cbiAqXG4gKiBCYWxhbmNlcyBhdXRvbm9teSBhbmQgc2FmZXR5LiBEZWZhdWx0IGZvciBtb3N0IGFnZW50cy5cbiAqIEFjdGlvbnMgd2l0aCByaXNrIHNjb3JlcyBhYm92ZSB0aGlzIHZhbHVlIHRyaWdnZXIgYSBwYXVzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEF1dG9ub215VGhyZXNob2xkTW9kZXJhdGUoKTogbnVtYmVyIHtcbiAgcmV0dXJuIHBhcnNlRW52SW50KFxuICAgIEFVVE9OT01ZX0VOVl9WQVJTLnRocmVzaG9sZE1vZGVyYXRlLFxuICAgIEFVVE9OT01ZX0RFRkFVTFRTLnRocmVzaG9sZE1vZGVyYXRlLFxuICAgIEFVVE9OT01ZX01JTl9MSU1JVFMudGhyZXNob2xkTW9kZXJhdGUsXG4gICAgQVVUT05PTVlfSEFSRF9MSU1JVFMudGhyZXNob2xkTW9kZXJhdGUsXG4gICAgJ0F1dG9ub215IHRocmVzaG9sZCdcbiAgKTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIGFnZ3Jlc3NpdmUgcmlzayB0aHJlc2hvbGQuXG4gKlxuICogT25seSBwYXVzZXMgb24gaGlnaC1yaXNrIGFjdGlvbnMuIEZvciB0cnVzdGVkLCB3ZWxsLXRlc3RlZCBhZ2VudHNcbiAqIGluIGNvbnRyb2xsZWQgZW52aXJvbm1lbnRzIHdoZXJlIHNwZWVkIGlzIHByaW9yaXRpemVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXV0b25vbXlUaHJlc2hvbGRBZ2dyZXNzaXZlKCk6IG51bWJlciB7XG4gIHJldHVybiBwYXJzZUVudkludChcbiAgICBBVVRPTk9NWV9FTlZfVkFSUy50aHJlc2hvbGRBZ2dyZXNzaXZlLFxuICAgIEFVVE9OT01ZX0RFRkFVTFRTLnRocmVzaG9sZEFnZ3Jlc3NpdmUsXG4gICAgQVVUT05PTVlfTUlOX0xJTUlUUy50aHJlc2hvbGRBZ2dyZXNzaXZlLFxuICAgIEFVVE9OT01ZX0hBUkRfTElNSVRTLnRocmVzaG9sZEFnZ3Jlc3NpdmUsXG4gICAgJ0F1dG9ub215IHRocmVzaG9sZCdcbiAgKTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIGRlZmF1bHQgbWF4aW11bSBhdXRvbm9tb3VzIHN0ZXBzLlxuICpcbiAqIENvbnRyb2xzIGhvdyBtYW55IHN0ZXBzIGFuIGFnZW50IGNhbiB0YWtlIGJlZm9yZSByZXF1aXJpbmdcbiAqIGh1bWFuIGNoZWNrLWluLCB3aGVuIHRoZSBhZ2VudCBkb2Vzbid0IHNwZWNpZnkgaXRzIG93biBsaW1pdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEF1dG9ub215TWF4U3RlcHNEZWZhdWx0KCk6IG51bWJlciB7XG4gIHJldHVybiBwYXJzZUVudkludChcbiAgICBBVVRPTk9NWV9FTlZfVkFSUy5tYXhTdGVwc0RlZmF1bHQsXG4gICAgQVVUT05PTVlfREVGQVVMVFMubWF4U3RlcHNEZWZhdWx0LFxuICAgIEFVVE9OT01ZX01JTl9MSU1JVFMubWF4U3RlcHNEZWZhdWx0LFxuICAgIEFVVE9OT01ZX0hBUkRfTElNSVRTLm1heFN0ZXBzRGVmYXVsdCxcbiAgICAnQXV0b25vbXkgbGltaXQnXG4gICk7XG59XG5cbi8qKlxuICogR2V0IGFsbCByaXNrIHRocmVzaG9sZHMgYXMgYSByZWNvcmQga2V5ZWQgYnkgdG9sZXJhbmNlIGxldmVsLlxuICpcbiAqIENvbnZlbmllbmNlIGZ1bmN0aW9uIGZvciBjYWxsZXJzIHRoYXQgbmVlZCB0aGUgZnVsbCB0aHJlc2hvbGQgbWFwXG4gKiAoZS5nLiwgdGhlIGF1dG9ub215IGV2YWx1YXRvcidzIGNoZWNrUmlza1RocmVzaG9sZCBmdW5jdGlvbikuXG4gKlxuICogQHJldHVybnMgT2JqZWN0IHdpdGgga2V5cyBgY29uc2VydmF0aXZlYCwgYG1vZGVyYXRlYCwgYW5kIGBhZ2dyZXNzaXZlYCxcbiAqICAgZWFjaCBtYXBwaW5nIHRvIGEgcmlzayBzY29yZSB0aHJlc2hvbGQgKDDigJMxMDApLiBUaGVzZSBrZXlzIGNvcnJlc3BvbmRcbiAqICAgdG8gdGhlIGByaXNrVG9sZXJhbmNlYCBmaWVsZCBvbiBgQWdlbnRBdXRvbm9teUNvbmZpZ2AuIEFjdGlvbnMgd2l0aFxuICogICByaXNrIHNjb3JlcyBhYm92ZSB0aGUgYWdlbnQncyB0b2xlcmFuY2UgdGhyZXNob2xkIHRyaWdnZXIgYSBwYXVzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEF1dG9ub215Umlza1RocmVzaG9sZHMoKTogUmVjb3JkPHN0cmluZywgbnVtYmVyPiB7XG4gIHJldHVybiB7XG4gICAgY29uc2VydmF0aXZlOiBnZXRBdXRvbm9teVRocmVzaG9sZENvbnNlcnZhdGl2ZSgpLFxuICAgIG1vZGVyYXRlOiBnZXRBdXRvbm9teVRocmVzaG9sZE1vZGVyYXRlKCksXG4gICAgYWdncmVzc2l2ZTogZ2V0QXV0b25vbXlUaHJlc2hvbGRBZ2dyZXNzaXZlKCksXG4gIH07XG59XG4iXX0=