@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.
143 lines • 19.5 kB
JavaScript
/**
* Rule Engine Configuration for Agent Decision Making
*
* This configuration allows customization of the decision-making process
* without modifying the core Agent implementation.
*/
import { SecurityMonitor } from '../../security/securityMonitor.js';
// Default configuration
export const DEFAULT_RULE_ENGINE_CONFIG = {
ruleBased: {
priority: {
critical: 'critical',
high: 'high',
medium: 'medium',
low: 'low'
},
urgencyThresholds: {
immediate: 8,
high: 6,
medium: 4,
low: 2
},
confidence: {
critical: 0.95,
blocked: 0.9,
riskApproval: 0.85,
resourceLimit: 0.8,
default: 0.7
}
},
programmatic: {
scoreWeights: {
eisenhower: {
doFirst: 30,
schedule: 20,
delegate: 10,
eliminate: 0
},
risk: {
low: 20,
medium: 10,
high: -10
},
noDependencies: 15,
quickWin: 15,
successBonus: 10
},
actionThresholds: {
executeImmediately: 70,
proceed: 50,
schedule: 30
},
confidenceLevels: {
executeImmediately: 0.9,
proceed: 0.8,
schedule: 0.7,
review: 0.6
},
quickWinHours: 2,
successRateThreshold: 0.8
},
actions: {
executeImmediately: 'execute_immediately',
proceedWithGoal: 'proceed_with_goal',
scheduleForLater: 'schedule_for_later',
reviewAndRevise: 'review_and_revise',
waitForDependencies: 'wait_for_dependencies',
requestApproval: 'request_approval',
queueForLater: 'queue_for_later',
reviewManually: 'review_manually'
}
};
/**
* Validate rule engine configuration
*/
export function validateRuleEngineConfig(config) {
// SECURITY FIX: Add audit logging for configuration changes
SecurityMonitor.logSecurityEvent({
type: 'RULE_ENGINE_CONFIG_UPDATE',
severity: 'LOW',
source: 'validateRuleEngineConfig',
details: 'Rule engine configuration update attempted'
});
// Deep merge with defaults
const merged = JSON.parse(JSON.stringify(DEFAULT_RULE_ENGINE_CONFIG));
if (config.ruleBased) {
Object.assign(merged.ruleBased, config.ruleBased);
}
if (config.programmatic) {
if (config.programmatic.scoreWeights) {
Object.assign(merged.programmatic.scoreWeights, config.programmatic.scoreWeights);
}
if (config.programmatic.actionThresholds) {
Object.assign(merged.programmatic.actionThresholds, config.programmatic.actionThresholds);
}
if (config.programmatic.confidenceLevels) {
Object.assign(merged.programmatic.confidenceLevels, config.programmatic.confidenceLevels);
}
if (config.programmatic.quickWinHours !== undefined) {
merged.programmatic.quickWinHours = config.programmatic.quickWinHours;
}
if (config.programmatic.successRateThreshold !== undefined) {
merged.programmatic.successRateThreshold = config.programmatic.successRateThreshold;
}
}
if (config.actions) {
Object.assign(merged.actions, config.actions);
}
// Validate thresholds are in correct order
if (merged.programmatic.actionThresholds.executeImmediately <= merged.programmatic.actionThresholds.proceed) {
// SECURITY FIX: Log validation failures for audit trail
SecurityMonitor.logSecurityEvent({
type: 'RULE_ENGINE_CONFIG_VALIDATION_ERROR',
severity: 'MEDIUM',
source: 'validateRuleEngineConfig',
details: 'Invalid threshold configuration attempted'
});
throw new Error('executeImmediately threshold must be higher than proceed threshold');
}
if (merged.programmatic.actionThresholds.proceed <= merged.programmatic.actionThresholds.schedule) {
// SECURITY FIX: Log validation failures for audit trail
SecurityMonitor.logSecurityEvent({
type: 'RULE_ENGINE_CONFIG_VALIDATION_ERROR',
severity: 'MEDIUM',
source: 'validateRuleEngineConfig',
details: 'Invalid threshold configuration attempted'
});
throw new Error('proceed threshold must be higher than schedule threshold');
}
// Validate confidence levels are between 0 and 1
Object.values(merged.ruleBased.confidence).forEach(conf => {
if (conf < 0 || conf > 1) {
throw new Error('Confidence levels must be between 0 and 1');
}
});
Object.values(merged.programmatic.confidenceLevels).forEach(conf => {
if (conf < 0 || conf > 1) {
throw new Error('Confidence levels must be between 0 and 1');
}
});
return merged;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZUVuZ2luZUNvbmZpZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9lbGVtZW50cy9hZ2VudHMvcnVsZUVuZ2luZUNvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUVILE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQStFcEUsd0JBQXdCO0FBQ3hCLE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFxQjtJQUMxRCxTQUFTLEVBQUU7UUFDVCxRQUFRLEVBQUU7WUFDUixRQUFRLEVBQUUsVUFBVTtZQUNwQixJQUFJLEVBQUUsTUFBTTtZQUNaLE1BQU0sRUFBRSxRQUFRO1lBQ2hCLEdBQUcsRUFBRSxLQUFLO1NBQ1g7UUFDRCxpQkFBaUIsRUFBRTtZQUNqQixTQUFTLEVBQUUsQ0FBQztZQUNaLElBQUksRUFBRSxDQUFDO1lBQ1AsTUFBTSxFQUFFLENBQUM7WUFDVCxHQUFHLEVBQUUsQ0FBQztTQUNQO1FBQ0QsVUFBVSxFQUFFO1lBQ1YsUUFBUSxFQUFFLElBQUk7WUFDZCxPQUFPLEVBQUUsR0FBRztZQUNaLFlBQVksRUFBRSxJQUFJO1lBQ2xCLGFBQWEsRUFBRSxHQUFHO1lBQ2xCLE9BQU8sRUFBRSxHQUFHO1NBQ2I7S0FDRjtJQUVELFlBQVksRUFBRTtRQUNaLFlBQVksRUFBRTtZQUNaLFVBQVUsRUFBRTtnQkFDVixPQUFPLEVBQUUsRUFBRTtnQkFDWCxRQUFRLEVBQUUsRUFBRTtnQkFDWixRQUFRLEVBQUUsRUFBRTtnQkFDWixTQUFTLEVBQUUsQ0FBQzthQUNiO1lBQ0QsSUFBSSxFQUFFO2dCQUNKLEdBQUcsRUFBRSxFQUFFO2dCQUNQLE1BQU0sRUFBRSxFQUFFO2dCQUNWLElBQUksRUFBRSxDQUFDLEVBQUU7YUFDVjtZQUNELGNBQWMsRUFBRSxFQUFFO1lBQ2xCLFFBQVEsRUFBRSxFQUFFO1lBQ1osWUFBWSxFQUFFLEVBQUU7U0FDakI7UUFDRCxnQkFBZ0IsRUFB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R0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLDJDQUEyQyxDQUFDLENBQUM7UUFDL0QsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUnVsZSBFbmdpbmUgQ29uZmlndXJhdGlvbiBmb3IgQWdlbnQgRGVjaXNpb24gTWFraW5nXG4gKiBcbiAqIFRoaXMgY29uZmlndXJhdGlvbiBhbGxvd3MgY3VzdG9taXphdGlvbiBvZiB0aGUgZGVjaXNpb24tbWFraW5nIHByb2Nlc3NcbiAqIHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSBjb3JlIEFnZW50IGltcGxlbWVudGF0aW9uLlxuICovXG5cbmltcG9ydCB7IFNlY3VyaXR5TW9uaXRvciB9IGZyb20gJy4uLy4uL3NlY3VyaXR5L3NlY3VyaXR5TW9uaXRvci5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVsZUVuZ2luZUNvbmZpZyB7XG4gIC8vIFJ1bGUtYmFzZWQgZGVjaXNpb24gdGhyZXNob2xkc1xuICBydWxlQmFzZWQ6IHtcbiAgICBwcmlvcml0eToge1xuICAgICAgY3JpdGljYWw6ICdjcml0aWNhbCc7XG4gICAgICBoaWdoOiAnaGlnaCc7XG4gICAgICBtZWRpdW06ICdtZWRpdW0nO1xuICAgICAgbG93OiAnbG93JztcbiAgICB9O1xuICAgIHVyZ2VuY3lUaHJlc2hvbGRzOiB7XG4gICAgICBpbW1lZGlhdGU6IG51bWJlcjsgIC8vIERlZmF1bHQ6IDhcbiAgICAgIGhpZ2g6IG51bWJlcjsgICAgICAgLy8gRGVmYXVsdDogNlxuICAgICAgbWVkaXVtOiBudW1iZXI7ICAgICAvLyBEZWZhdWx0OiA0XG4gICAgICBsb3c6IG51bWJlcjsgICAgICAgIC8vIERlZmF1bHQ6IDJcbiAgICB9O1xuICAgIGNvbmZpZGVuY2U6IHtcbiAgICAgIGNyaXRpY2FsOiBudW1iZXI7ICAgICAgICAvLyBEZWZhdWx0OiAwLjk1XG4gICAgICBibG9ja2VkOiBudW1iZXI7ICAgICAgICAgLy8gRGVmYXVsdDogMC45XG4gICAgICByaXNrQXBwcm92YWw6IG51bWJlcjsgICAgLy8gRGVmYXVsdDogMC44NVxuICAgICAgcmVzb3VyY2VMaW1pdDogbnVtYmVyOyAgIC8vIERlZmF1bHQ6IDAuOFxuICAgICAgZGVmYXVsdDogbnVtYmVyOyAgICAgICAgIC8vIERlZmF1bHQ6IDAuN1xuICAgIH07XG4gIH07XG5cbiAgLy8gUHJvZ3JhbW1hdGljIGRlY2lzaW9uIHNjb3JpbmdcbiAgcHJvZ3JhbW1hdGljOiB7XG4gICAgLy8gU2NvcmUgd2VpZ2h0cyBmb3IgZGlmZmVyZW50IGZhY3RvcnNcbiAgICBzY29yZVdlaWdodHM6IHtcbiAgICAgIGVpc2VuaG93ZXI6IHtcbiAgICAgICAgZG9GaXJzdDogbnVtYmVyOyAgICAgLy8gRGVmYXVsdDogMzBcbiAgICAgICAgc2NoZWR1bGU6IG51bWJlcjsgICAgLy8gRGVmYXVsdDogMjBcbiAgICAgICAgZGVsZWdhdGU6IG51bWJlcjsgICAgLy8gRGVmYXVsdDogMTBcbiAgICAgICAgZWxpbWluYXRlOiBudW1iZXI7ICAgLy8gRGVmYXVsdDogMFxuICAgICAgfTtcbiAgICAgIHJpc2s6IHtcbiAgICAgICAgbG93OiBudW1iZXI7ICAgICAgICAgLy8gRGVmYXVsdDogMjBcbiAgICAgICAgbWVkaXVtOiBudW1iZXI7ICAgICAgLy8gRGVmYXVsdDogMTBcbiAgICAgICAgaGlnaDogbnVtYmVyOyAgICAgICAgLy8gRGVmYXVsdDogLTEwXG4gICAgICB9O1xuICAgICAgbm9EZXBlbmRlbmNpZXM6IG51bWJlcjsgLy8gRGVmYXVsdDogMTVcbiAgICAgIHF1aWNrV2luOiBudW1iZXI7ICAgICAgIC8vIERlZmF1bHQ6IDE1XG4gICAgICBzdWNjZXNzQm9udXM6IG51bWJlcjsgICAvLyBEZWZhdWx0OiAxMFxuICAgIH07XG4gICAgXG4gICAgLy8gU2NvcmUgdGhyZXNob2xkcyBmb3IgYWN0aW9uc1xuICAgIGFjdGlvblRocmVzaG9sZHM6IHtcbiAgICAgIGV4ZWN1dGVJbW1lZGlhdGVseTogbnVtYmVyOyAgLy8gRGVmYXVsdDogNzBcbiAgICAgIHByb2NlZWQ6IG51bWJlcjsgICAgICAgICAgICAgLy8gRGVmYXVsdDogNTBcbiAgICAgIHNjaGVkdWxlOiBudW1iZXI7ICAgICAgICAgICAgLy8gRGVmYXVsdDogMzBcbiAgICB9O1xuICAgIFxuICAgIC8vIENvbmZpZGVuY2UgbWFwcGluZ3NcbiAgICBjb25maWRlbmNlTGV2ZWxzOiB7XG4gICAgICBleGVjdXRlSW1tZWRpYXRlbHk6IG51bWJlcjsgIC8vIERlZmF1bHQ6IDAuOVxuICAgICAgcHJvY2VlZDogbnVtYmVyOyAgICAgICAgICAgICAvLyBEZWZhdWx0OiAwLjhcbiAgICAgIHNjaGVkdWxlOiBudW1iZXI7ICAgICAgICAgICAgLy8gRGVmYXVsdDogMC43XG4gICAgICByZXZpZXc6IG51bWJlcjsgICAgICAgICAgICAgIC8vIERlZmF1bHQ6IDAuNlxuICAgIH07XG4gICAgXG4gICAgLy8gT3RoZXIgdGhyZXNob2xkc1xuICAgIHF1aWNrV2luSG91cnM6IG51bWJlcjsgICAgICAgICAvLyBEZWZhdWx0OiAyXG4gICAgc3VjY2Vzc1JhdGVUaHJlc2hvbGQ6IG51bWJlcjsgIC8vIERlZmF1bHQ6IDAuOFxuICB9O1xuXG4gIC8vIEFjdGlvbiBkZWZpbml0aW9uc1xuICBhY3Rpb25zOiB7XG4gICAgZXhlY3V0ZUltbWVkaWF0ZWx5OiBzdHJpbmc7XG4gICAgcHJvY2VlZFdpdGhHb2FsOiBzdHJpbmc7XG4gICAgc2NoZWR1bGVGb3JMYXRlcjogc3RyaW5nO1xuICAgIHJldmlld0FuZFJldmlzZTogc3RyaW5nO1xuICAgIHdhaXRGb3JEZXBlbmRlbmNpZXM6IHN0cmluZztcbiAgICByZXF1ZXN0QXBwcm92YWw6IHN0cmluZztcbiAgICBxdWV1ZUZvckxhdGVyOiBzdHJpbmc7XG4gICAgcmV2aWV3TWFudWFsbHk6IHN0cmluZztcbiAgfTtcbn1cblxuLy8gRGVmYXVsdCBjb25maWd1cmF0aW9uXG5leHBvcnQgY29uc3QgREVGQVVMVF9SVUxFX0VOR0lORV9DT05GSUc6IFJ1bGVFbmdpbmVDb25maWcgPSB7XG4gIHJ1bGVCYXNlZDoge1xuICAgIHByaW9yaXR5OiB7XG4gICAgICBjcml0aWNhbDogJ2NyaXRpY2FsJyxcbiAgICAgIGhpZ2g6ICdoaWdoJyxcbiAgICAgIG1lZGl1bTogJ21lZGl1bScsXG4gICAgICBsb3c6ICdsb3cnXG4gICAgfSxcbiAgICB1cmdlbmN5VGhyZXNob2xkczoge1xuICAgICAgaW1tZWRpYXRlOiA4LFxuICAgICAgaGlnaDogNixcbiAgICAgIG1lZGl1bTogNCxcbiAgICAgIGxvdzogMlxuICAgIH0sXG4gICAgY29uZmlkZW5jZToge1xuICAgICAgY3JpdGljYWw6IDAuOTUsXG4gICAgICBibG9ja2VkOiAwLjksXG4gICAgICByaXNrQXBwcm92YWw6IDAuODUsXG4gICAgICByZXNvdXJjZUxpbWl0OiAwLjgsXG4gICAgICBkZWZhdWx0OiAwLjdcbiAgICB9XG4gIH0sXG4gIFxuICBwcm9ncmFtbWF0aWM6IHtcbiAgICBzY29yZVdlaWdodHM6IHtcbiAgICAgIGVpc2VuaG93ZXI6IHtcbiAgICAgICAgZG9GaXJzdDogMzAsXG4gICAgICAgIHNjaGVkdWxlOiAyMCxcbiAgICAgICAgZGVsZWdhdGU6IDEwLFxuICAgICAgICBlbGltaW5hdGU6IDBcbiAgICAgIH0sXG4gICAgICByaXNrOiB7XG4gICAgICAgIGxvdzogMjAsXG4gICAgICAgIG1lZGl1bTogMTAsXG4gICAgICAgIGhpZ2g6IC0xMFxuICAgICAgfSxcbiAgICAgIG5vRGVwZW5kZW5jaWVzOiAxNSxcbiAgICAgIHF1aWNrV2luOiAxNSxcbiAgICAgIHN1Y2Nlc3NCb251czogMTBcbiAgICB9LFxuICAgIGFjdGlvblRocmVzaG9sZHM6IHtcbiAgICAgIGV4ZWN1dGVJbW1lZGlhdGVseTogNzAsXG4gICAgICBwcm9jZWVkOiA1MCxcbiAgICAgIHNjaGVkdWxlOiAzMFxuICAgIH0sXG4gICAgY29uZmlkZW5jZUxldmVsczoge1xuICAgICAgZXhlY3V0ZUltbWVkaWF0ZWx5OiAwLjksXG4gICAgICBwcm9jZWVkOiAwLjgsXG4gICAgICBzY2hlZHVsZTogMC43LFxuICAgICAgcmV2aWV3OiAwLjZcbiAgICB9LFxuICAgIHF1aWNrV2luSG91cnM6IDIsXG4gICAgc3VjY2Vzc1JhdGVUaHJlc2hvbGQ6IDAuOFxuICB9LFxuICBcbiAgYWN0aW9uczoge1xuICAgIGV4ZWN1dGVJbW1lZGlhdGVseTogJ2V4ZWN1dGVfaW1tZWRpYXRlbHknLFxuICAgIHByb2NlZWRXaXRoR29hbDogJ3Byb2NlZWRfd2l0aF9nb2FsJyxcbiAgICBzY2hlZHVsZUZvckxhdGVyOiAnc2NoZWR1bGVfZm9yX2xhdGVyJyxcbiAgICByZXZpZXdBbmRSZXZpc2U6ICdyZXZpZXdfYW5kX3JldmlzZScsXG4gICAgd2FpdEZvckRlcGVuZGVuY2llczogJ3dhaXRfZm9yX2RlcGVuZGVuY2llcycsXG4gICAgcmVxdWVzdEFwcHJvdmFsOiAncmVxdWVzdF9hcHByb3ZhbCcsXG4gICAgcXVldWVGb3JMYXRlcjogJ3F1ZXVlX2Zvcl9sYXRlcicsXG4gICAgcmV2aWV3TWFudWFsbHk6ICdyZXZpZXdfbWFudWFsbHknXG4gIH1cbn07XG5cbi8qKlxuICogVmFsaWRhdGUgcnVsZSBlbmdpbmUgY29uZmlndXJhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVSdWxlRW5naW5lQ29uZmlnKGNvbmZpZzogUGFydGlhbDxSdWxlRW5naW5lQ29uZmlnPik6IFJ1bGVFbmdpbmVDb25maWcge1xuICAvLyBTRUNVUklUWSBGSVg6IEFkZCBhdWRpdCBsb2dnaW5nIGZvciBjb25maWd1cmF0aW9uIGNoYW5nZXNcbiAgU2VjdXJpdHlNb25pdG9yLmxvZ1NlY3VyaXR5RXZlbnQoe1xuICAgIHR5cGU6ICdSVUxFX0VOR0lORV9DT05GSUdfVVBEQVRFJyxcbiAgICBzZXZlcml0eTogJ0xPVycsXG4gICAgc291cmNlOiAndmFsaWRhdGVSdWxlRW5naW5lQ29uZmlnJyxcbiAgICBkZXRhaWxzOiAnUnVsZSBlbmdpbmUgY29uZmlndXJhdGlvbiB1cGRhdGUgYXR0ZW1wdGVkJ1xuICB9KTtcblxuICAvLyBEZWVwIG1lcmdlIHdpdGggZGVmYXVsdHNcbiAgY29uc3QgbWVyZ2VkID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShERUZBVUxUX1JVTEVfRU5HSU5FX0NPTkZJRykpIGFzIFJ1bGVFbmdpbmVDb25maWc7XG4gIFxuICBpZiAoY29uZmlnLnJ1bGVCYXNlZCkge1xuICAgIE9iamVjdC5hc3NpZ24obWVyZ2VkLnJ1bGVCYXNlZCwgY29uZmlnLnJ1bGVCYXNlZCk7XG4gIH1cbiAgXG4gIGlmIChjb25maWcucHJvZ3JhbW1hdGljKSB7XG4gICAgaWYgKGNvbmZpZy5wcm9ncmFtbWF0aWMuc2NvcmVXZWlnaHRzKSB7XG4gICAgICBPYmplY3QuYXNzaWduKG1lcmdlZC5wcm9ncmFtbWF0aWMuc2NvcmVXZWlnaHRzLCBjb25maWcucHJvZ3JhbW1hdGljLnNjb3JlV2VpZ2h0cyk7XG4gICAgfVxuICAgIGlmIChjb25maWcucHJvZ3JhbW1hdGljLmFjdGlvblRocmVzaG9sZHMpIHtcbiAgICAgIE9iamVjdC5hc3NpZ24obWVyZ2VkLnByb2dyYW1tYXRpYy5hY3Rpb25UaHJlc2hvbGRzLCBjb25maWcucHJvZ3JhbW1hdGljLmFjdGlvblRocmVzaG9sZHMpO1xuICAgIH1cbiAgICBpZiAoY29uZmlnLnByb2dyYW1tYXRpYy5jb25maWRlbmNlTGV2ZWxzKSB7XG4gICAgICBPYmplY3QuYXNzaWduKG1lcmdlZC5wcm9ncmFtbWF0aWMuY29uZmlkZW5jZUxldmVscywgY29uZmlnLnByb2dyYW1tYXRpYy5jb25maWRlbmNlTGV2ZWxzKTtcbiAgICB9XG4gICAgaWYgKGNvbmZpZy5wcm9ncmFtbWF0aWMucXVpY2tXaW5Ib3VycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBtZXJnZWQucHJvZ3JhbW1hdGljLnF1aWNrV2luSG91cnMgPSBjb25maWcucHJvZ3JhbW1hdGljLnF1aWNrV2luSG91cnM7XG4gICAgfVxuICAgIGlmIChjb25maWcucHJvZ3JhbW1hdGljLnN1Y2Nlc3NSYXRlVGhyZXNob2xkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG1lcmdlZC5wcm9ncmFtbWF0aWMuc3VjY2Vzc1JhdGVUaHJlc2hvbGQgPSBjb25maWcucHJvZ3JhbW1hdGljLnN1Y2Nlc3NSYXRlVGhyZXNob2xkO1xuICAgIH1cbiAgfVxuICBcbiAgaWYgKGNvbmZpZy5hY3Rpb25zKSB7XG4gICAgT2JqZWN0LmFzc2lnbihtZXJnZWQuYWN0aW9ucywgY29uZmlnLmFjdGlvbnMpO1xuICB9XG4gIFxuICAvLyBWYWxpZGF0ZSB0aHJlc2hvbGRzIGFyZSBpbiBjb3JyZWN0IG9yZGVyXG4gIGlmIChtZXJnZWQucHJvZ3JhbW1hdGljLmFjdGlvblRocmVzaG9sZHMuZXhlY3V0ZUltbWVkaWF0ZWx5IDw9IG1lcmdlZC5wcm9ncmFtbWF0aWMuYWN0aW9uVGhyZXNob2xkcy5wcm9jZWVkKSB7XG4gICAgLy8gU0VDVVJJVFkgRklYOiBMb2cgdmFsaWRhdGlvbiBmYWlsdXJlcyBmb3IgYXVkaXQgdHJhaWxcbiAgICBTZWN1cml0eU1vbml0b3IubG9nU2VjdXJpdHlFdmVudCh7XG4gICAgICB0eXBlOiAnUlVMRV9FTkdJTkVfQ09ORklHX1ZBTElEQVRJT05fRVJST1InLFxuICAgICAgc2V2ZXJpdHk6ICdNRURJVU0nLFxuICAgICAgc291cmNlOiAndmFsaWRhdGVSdWxlRW5naW5lQ29uZmlnJyxcbiAgICAgIGRldGFpbHM6ICdJbnZhbGlkIHRocmVzaG9sZCBjb25maWd1cmF0aW9uIGF0dGVtcHRlZCdcbiAgICB9KTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4ZWN1dGVJbW1lZGlhdGVseSB0aHJlc2hvbGQgbXVzdCBiZSBoaWdoZXIgdGhhbiBwcm9jZWVkIHRocmVzaG9sZCcpO1xuICB9XG4gIGlmIChtZXJnZWQucHJvZ3JhbW1hdGljLmFjdGlvblRocmVzaG9sZHMucHJvY2VlZCA8PSBtZXJnZWQucHJvZ3JhbW1hdGljLmFjdGlvblRocmVzaG9sZHMuc2NoZWR1bGUpIHtcbiAgICAvLyBTRUNVUklUWSBGSVg6IExvZyB2YWxpZGF0aW9uIGZhaWx1cmVzIGZvciBhdWRpdCB0cmFpbFxuICAgIFNlY3VyaXR5TW9uaXRvci5sb2dTZWN1cml0eUV2ZW50KHtcbiAgICAgIHR5cGU6ICdSVUxFX0VOR0lORV9DT05GSUdfVkFMSURBVElPTl9FUlJPUicsXG4gICAgICBzZXZlcml0eTogJ01FRElVTScsXG4gICAgICBzb3VyY2U6ICd2YWxpZGF0ZVJ1bGVFbmdpbmVDb25maWcnLFxuICAgICAgZGV0YWlsczogJ0ludmFsaWQgdGhyZXNob2xkIGNvbmZpZ3VyYXRpb24gYXR0ZW1wdGVkJ1xuICAgIH0pO1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2VlZCB0aHJlc2hvbGQgbXVzdCBiZSBoaWdoZXIgdGhhbiBzY2hlZHVsZSB0aHJlc2hvbGQnKTtcbiAgfVxuICBcbiAgLy8gVmFsaWRhdGUgY29uZmlkZW5jZSBsZXZlbHMgYXJlIGJldHdlZW4gMCBhbmQgMVxuICBPYmplY3QudmFsdWVzKG1lcmdlZC5ydWxlQmFzZWQuY29uZmlkZW5jZSkuZm9yRWFjaChjb25mID0+IHtcbiAgICBpZiAoY29uZiA8IDAgfHwgY29uZiA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ29uZmlkZW5jZSBsZXZlbHMgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEnKTtcbiAgICB9XG4gIH0pO1xuICBcbiAgT2JqZWN0LnZhbHVlcyhtZXJnZWQucHJvZ3JhbW1hdGljLmNvbmZpZGVuY2VMZXZlbHMpLmZvckVhY2goY29uZiA9PiB7XG4gICAgaWYgKGNvbmYgPCAwIHx8IGNvbmYgPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbmZpZGVuY2UgbGV2ZWxzIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxJyk7XG4gICAgfVxuICB9KTtcbiAgXG4gIHJldHVybiBtZXJnZWQ7XG59Il19