@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.
148 lines • 19 kB
JavaScript
/**
* MemoryActivationStrategy - Strategy for memory element activation
*
* Handles activation, deactivation, and status tracking for memory elements.
* Issue #18 Phase 4: Context-loading strategy with state management
*/
import { BaseActivationStrategy } from './BaseActivationStrategy.js';
export class MemoryActivationStrategy extends BaseActivationStrategy {
memoryManager;
constructor(memoryManager) {
super();
this.memoryManager = memoryManager;
}
/**
* Activate a memory
* Issue #18 Phase 4: Context-loading activation strategy
* - Load memory entries into active context
* - Apply retention policies if configured
* - Track activation in manager's active set
*/
async activate(name, context) {
// Use the manager's activation method which tracks active memories
const result = await this.memoryManager.activateMemory(name);
if (!result.success || !result.memory) {
return this.createNotFoundResponse(name, 'Memory');
}
const memory = result.memory;
// Get memory statistics for context loading information
const stats = memory.getStats();
const retentionDays = memory.metadata.retentionDays || 'permanent';
const tags = memory.metadata.tags?.join(', ') || 'none';
// Build activation response with context-loading information
const parts = [
`✅ Memory '${memory.metadata.name}' activated - ${stats.totalEntries} entries loaded into context`,
''
];
// Check if context was provided for additional activation options
const hasActivationContext = context && Object.keys(context).length > 0;
const autoLoadRequested = context?.autoLoad === true;
if (autoLoadRequested) {
// Auto-load activation context
parts.push('Memory activates and automatically loads entries');
}
else if (hasActivationContext) {
// Other activation contexts
parts.push('Memory context loaded and applied with specified options');
}
else {
// Default activation
parts.push('Memory becomes active, context loaded into working set');
}
parts.push('');
parts.push(`**Retention**: ${retentionDays} days`);
parts.push(`**Tags**: ${tags}`);
parts.push(`**Entries**: ${stats.totalEntries}`);
if (stats.totalSize > 0) {
parts.push(`**Size**: ${stats.totalSize} bytes`);
}
parts.push('');
parts.push('This memory is now available for context and will be used to enhance responses.');
const gatekeeperWarning = this.formatGatekeeperValidityWarning(memory.metadata);
if (gatekeeperWarning) {
parts.push(gatekeeperWarning);
}
return {
content: [{
type: "text",
text: parts.join('\n')
}]
};
}
/**
* Deactivate a memory
* Issue #18 Phase 4: Use manager's deactivation method
*
* @throws {ElementNotFoundError} When memory does not exist
* @see Issue #275 - Handlers return success=true for missing elements
*/
async deactivate(name) {
const result = await this.memoryManager.deactivateMemory(name);
if (!result.success) {
this.throwNotFoundError(name, 'Memory');
}
return this.createSuccessResponse(result.message);
}
/**
* Get all active memories
* Issue #18 Phase 4: Use manager's getActiveMemories method
*/
async getActiveElements() {
// Use the manager's method to get active memories directly
const activeMemories = await this.memoryManager.getActiveMemories();
if (activeMemories.length === 0) {
return {
content: [{
type: "text",
text: "🧠 No active memories"
}]
};
}
const memoryList = activeMemories.map(m => {
const tags = m.metadata.tags?.join(', ') || 'none';
const retentionDays = m.metadata.retentionDays || 'permanent';
return `🧠 ${m.metadata.name} (Tags: ${tags}) - ${retentionDays} days retention`;
}).join('\n');
return {
content: [{
type: "text",
text: `Active memories:\n${memoryList}`
}]
};
}
/**
* Get detailed information about a memory
* Extracted from ElementCRUDHandler.ts lines 772-805
*
* @throws {ElementNotFoundError} When memory does not exist
* @see Issue #275 - Handlers return success=true for missing elements
*/
async getElementDetails(name) {
// Use flexible finding to support both display name and filename
const allMemories = await this.memoryManager.list();
const memory = await this.findElementFlexibly(name, allMemories);
if (!memory) {
this.throwNotFoundError(name, 'Memory');
}
const details = [
`🧠 **${memory.metadata.name}**`,
`${memory.metadata.description}`,
``,
`**Status**: ${memory.getStatus()}`,
`**Retention**: ${memory.metadata.retentionDays || 'permanent'} days`,
`**Tags**: ${memory.metadata.tags?.join(', ') || 'none'}`,
`**Storage Backend**: ${memory.metadata.storageBackend || 'file'}`,
`**Privacy Level**: ${memory.metadata.privacyLevel || 'private'}`,
``,
`**Content**:`,
memory.content || 'No content stored'
];
return {
content: [{
type: "text",
text: details.join('\n')
}]
};
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWVtb3J5QWN0aXZhdGlvblN0cmF0ZWd5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2hhbmRsZXJzL3N0cmF0ZWdpZXMvTWVtb3J5QWN0aXZhdGlvblN0cmF0ZWd5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBR0gsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFHckUsTUFBTSxPQUFPLHdCQUF5QixTQUFRLHNCQUFzQjtJQUNyQztJQUE3QixZQUE2QixhQUE0QjtRQUN2RCxLQUFLLEVBQUUsQ0FBQztRQURtQixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtJQUV6RCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFZLEVBQUUsT0FBNkI7UUFDeEQsbUVBQW1FO1FBQ25FLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFN0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDdEMsT0FBTyxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO1FBRTdCLHdEQUF3RDtRQUN4RCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDaEMsTUFBTSxhQUFhLEdBQUksTUFBTSxDQUFDLFFBQWdCLENBQUMsYUFBYSxJQUFJLFdBQVcsQ0FBQztRQUM1RSxNQUFNLElBQUksR0FBSSxNQUFNLENBQUMsUUFBZ0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQztRQUVqRSw2REFBNkQ7UUFDN0QsTUFBTSxLQUFLLEdBQUc7WUFD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QUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxNQUFNLEVBQUU7WUFDbEUsd0JBQXlCLE1BQU0sQ0FBQyxRQUFnQixDQUFDLGNBQWMsSUFBSSxNQUFNLEVBQUU7WUFDM0Usc0JBQXVCLE1BQU0sQ0FBQyxRQUFnQixDQUFDLFlBQVksSUFBSSxTQUFTLEVBQUU7WUFDMUUsRUFBRTtZQUNGLGNBQWM7WUFDZCxNQUFNLENBQUMsT0FBTyxJQUFJLG1CQUFtQjtTQUN0QyxDQUFDO1FBRUYsT0FBTztZQUNMLE9BQU8sRUFBRSxDQUFDO29CQUNSLElBQUksRUFBRSxNQUFNO29CQUNaLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztpQkFDekIsQ0FBQztTQUNILENBQUM7SUFDSixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1lbW9yeUFjdGl2YXRpb25TdHJhdGVneSAtIFN0cmF0ZWd5IGZvciBtZW1vcnkgZWxlbWVudCBhY3RpdmF0aW9uXG4gKlxuICogSGFuZGxlcyBhY3RpdmF0aW9uLCBkZWFjdGl2YXRpb24sIGFuZCBzdGF0dXMgdHJhY2tpbmcgZm9yIG1lbW9yeSBlbGVtZW50cy5cbiAqIElzc3VlICMxOCBQaGFzZSA0OiBDb250ZXh0LWxvYWRpbmcgc3RyYXRlZ3kgd2l0aCBzdGF0ZSBtYW5hZ2VtZW50XG4gKi9cblxuaW1wb3J0IHsgTWVtb3J5TWFuYWdlciB9IGZyb20gJy4uLy4uL2VsZW1lbnRzL21lbW9yaWVzL01lbW9yeU1hbmFnZXIuanMnO1xuaW1wb3J0IHsgQmFzZUFjdGl2YXRpb25TdHJhdGVneSB9IGZyb20gJy4vQmFzZUFjdGl2YXRpb25TdHJhdGVneS5qcyc7XG5pbXBvcnQgeyBFbGVtZW50QWN0aXZhdGlvblN0cmF0ZWd5LCBNQ1BSZXNwb25zZSB9IGZyb20gJy4vRWxlbWVudEFjdGl2YXRpb25TdHJhdGVneS5qcyc7XG5cbmV4cG9ydCBjbGFzcyBNZW1vcnlBY3RpdmF0aW9uU3RyYXRlZ3kgZXh0ZW5kcyBCYXNlQWN0aXZhdGlvblN0cmF0ZWd5IGltcGxlbWVudHMgRWxlbWVudEFjdGl2YXRpb25TdHJhdGVneSB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgbWVtb3J5TWFuYWdlcjogTWVtb3J5TWFuYWdlcikge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogQWN0aXZhdGUgYSBtZW1vcnlcbiAgICogSXNzdWUgIzE4IFBoYXNlIDQ6IENvbnRleHQtbG9hZGluZyBhY3RpdmF0aW9uIHN0cmF0ZWd5XG4gICAqIC0gTG9hZCBtZW1vcnkgZW50cmllcyBpbnRvIGFjdGl2ZSBjb250ZXh0XG4gICAqIC0gQXBwbHkgcmV0ZW50aW9uIHBvbGljaWVzIGlmIGNvbmZpZ3VyZWRcbiAgICogLSBUcmFjayBhY3RpdmF0aW9uIGluIG1hbmFnZXIncyBhY3RpdmUgc2V0XG4gICAqL1xuICBhc3luYyBhY3RpdmF0ZShuYW1lOiBzdHJpbmcsIGNvbnRleHQ/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KTogUHJvbWlzZTxNQ1BSZXNwb25zZT4ge1xuICAgIC8vIFVzZSB0aGUgbWFuYWdlcidzIGFjdGl2YXRpb24gbWV0aG9kIHdoaWNoIHRyYWNrcyBhY3RpdmUgbWVtb3JpZXNcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLm1lbW9yeU1hbmFnZXIuYWN0aXZhdGVNZW1vcnkobmFtZSk7XG5cbiAgICBpZiAoIXJlc3VsdC5zdWNjZXNzIHx8ICFyZXN1bHQubWVtb3J5KSB7XG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVOb3RGb3VuZFJlc3BvbnNlKG5hbWUsICdNZW1vcnknKTtcbiAgICB9XG5cbiAgICBjb25zdCBtZW1vcnkgPSByZXN1bHQubWVtb3J5O1xuXG4gICAgLy8gR2V0IG1lbW9yeSBzdGF0aXN0aWNzIGZvciBjb250ZXh0IGxvYWRpbmcgaW5mb3JtYXRpb25cbiAgICBjb25zdCBzdGF0cyA9IG1lbW9yeS5nZXRTdGF0cygpO1xuICAgIGNvbnN0IHJldGVudGlvbkRheXMgPSAobWVtb3J5Lm1ldGFkYXRhIGFzIGFueSkucmV0ZW50aW9uRGF5cyB8fCAncGVybWFuZW50JztcbiAgICBjb25zdCB0YWdzID0gKG1lbW9yeS5tZXRhZGF0YSBhcyBhbnkpLnRhZ3M/LmpvaW4oJywgJykgfHwgJ25vbmUnO1xuXG4gICAgLy8gQnVpbGQgYWN0aXZhdGlvbiByZXNwb25zZSB3aXRoIGNvbnRleHQtbG9hZGluZyBpbmZvcm1hdGlvblxuICAgIGNvbnN0IHBhcnRzID0gW1xuICAgICAgYOKchSBNZW1vcnkgJyR7bWVtb3J5Lm1ldGFkYXRhLm5hbWV9JyBhY3RpdmF0ZWQgLSAke3N0YXRzLnRvdGFsRW50cmllc30gZW50cmllcyBsb2FkZWQgaW50byBjb250ZXh0YCxcbiAgICAgICcnXG4gICAgXTtcblxuICAgIC8vIENoZWNrIGlmIGNvbnRleHQgd2FzIHByb3ZpZGVkIGZvciBhZGRpdGlvbmFsIGFjdGl2YXRpb24gb3B0aW9uc1xuICAgIGNvbnN0IGhhc0FjdGl2YXRpb25Db250ZXh0ID0gY29udGV4dCAmJiBPYmplY3Qua2V5cyhjb250ZXh0KS5sZW5ndGggPiAwO1xuICAgIGNvbnN0IGF1dG9Mb2FkUmVxdWVzdGVkID0gY29udGV4dD8uYXV0b0xvYWQgPT09IHRydWU7XG5cbiAgICBpZiAoYXV0b0xvYWRSZXF1ZXN0ZWQpIHtcbiAgICAgIC8vIEF1dG8tbG9hZCBhY3RpdmF0aW9uIGNvbnRleHRcbiAgICAgIHBhcnRzLnB1c2goJ01lbW9yeSBhY3RpdmF0ZXMgYW5kIGF1dG9tYXRpY2FsbHkgbG9hZHMgZW50cmllcycpO1xuICAgIH0gZWxzZSBpZiAoaGFzQWN0aXZhdGlvbkNvbnRleHQpIHtcbiAgICAgIC8vIE90aGVyIGFjdGl2YXRpb24gY29udGV4dHNcbiAgICAgIHBhcnRzLnB1c2goJ01lbW9yeSBjb250ZXh0IGxvYWRlZCBhbmQgYXBwbGllZCB3aXRoIHNwZWNpZmllZCBvcHRpb25zJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZmF1bHQgYWN0aXZhdGlvblxuICAgICAgcGFydHMucHVzaCgnTWVtb3J5IGJlY29tZXMgYWN0aXZlLCBjb250ZXh0IGxvYWRlZCBpbnRvIHdvcmtpbmcgc2V0Jyk7XG4gICAgfVxuXG4gICAgcGFydHMucHVzaCgnJyk7XG4gICAgcGFydHMucHVzaChgKipSZXRlbnRpb24qKjogJHtyZXRlbnRpb25EYXlzfSBkYXlzYCk7XG4gICAgcGFydHMucHVzaChgKipUYWdzKio6ICR7dGFnc31gKTtcbiAgICBwYXJ0cy5wdXNoKGAqKkVudHJpZXMqKjogJHtzdGF0cy50b3RhbEVudHJpZXN9YCk7XG5cbiAgICBpZiAoc3RhdHMudG90YWxTaXplID4gMCkge1xuICAgICAgcGFydHMucHVzaChgKipTaXplKio6ICR7c3RhdHMudG90YWxTaXplfSBieXRlc2ApO1xuICAgIH1cblxuICAgIHBhcnRzLnB1c2goJycpO1xuICAgIHBhcnRzLnB1c2goJ1RoaXMgbWVtb3J5IGlzIG5vdyBhdmFpbGFibGUgZm9yIGNvbnRleHQgYW5kIHdpbGwgYmUgdXNlZCB0byBlbmhhbmNlIHJlc3BvbnNlcy4nKTtcblxuICAgIGNvbnN0IGdhdGVrZWVwZXJXYXJuaW5nID0gdGhpcy5mb3JtYXRHYXRla2VlcGVyVmFsaWRpdHlXYXJuaW5nKG1lbW9yeS5tZXRhZGF0YSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KTtcbiAgICBpZiAoZ2F0ZWtlZXBlcldhcm5pbmcpIHtcbiAgICAgIHBhcnRzLnB1c2goZ2F0ZWtlZXBlcldhcm5pbmcpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbe1xuICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgdGV4dDogcGFydHMuam9pbignXFxuJylcbiAgICAgIH1dXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWFjdGl2YXRlIGEgbWVtb3J5XG4gICAqIElzc3VlICMxOCBQaGFzZSA0OiBVc2UgbWFuYWdlcidzIGRlYWN0aXZhdGlvbiBtZXRob2RcbiAgICpcbiAgICogQHRocm93cyB7RWxlbWVudE5vdEZvdW5kRXJyb3J9IFdoZW4gbWVtb3J5IGRvZXMgbm90IGV4aXN0XG4gICAqIEBzZWUgSXNzdWUgIzI3NSAtIEhhbmRsZXJzIHJldHVybiBzdWNjZXNzPXRydWUgZm9yIG1pc3NpbmcgZWxlbWVudHNcbiAgICovXG4gIGFzeW5jIGRlYWN0aXZhdGUobmFtZTogc3RyaW5nKTogUHJvbWlzZTxNQ1BSZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMubWVtb3J5TWFuYWdlci5kZWFjdGl2YXRlTWVtb3J5KG5hbWUpO1xuXG4gICAgaWYgKCFyZXN1bHQuc3VjY2Vzcykge1xuICAgICAgdGhpcy50aHJvd05vdEZvdW5kRXJyb3IobmFtZSwgJ01lbW9yeScpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNyZWF0ZVN1Y2Nlc3NSZXNwb25zZShyZXN1bHQubWVzc2FnZSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCBhY3RpdmUgbWVtb3JpZXNcbiAgICogSXNzdWUgIzE4IFBoYXNlIDQ6IFVzZSBtYW5hZ2VyJ3MgZ2V0QWN0aXZlTWVtb3JpZXMgbWV0aG9kXG4gICAqL1xuICBhc3luYyBnZXRBY3RpdmVFbGVtZW50cygpOiBQcm9taXNlPE1DUFJlc3BvbnNlPiB7XG4gICAgLy8gVXNlIHRoZSBtYW5hZ2VyJ3MgbWV0aG9kIHRvIGdldCBhY3RpdmUgbWVtb3JpZXMgZGlyZWN0bHlcbiAgICBjb25zdCBhY3RpdmVNZW1vcmllcyA9IGF3YWl0IHRoaXMubWVtb3J5TWFuYWdlci5nZXRBY3RpdmVNZW1vcmllcygpO1xuXG4gICAgaWYgKGFjdGl2ZU1lbW9yaWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBcIvCfp6AgTm8gYWN0aXZlIG1lbW9yaWVzXCJcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgbWVtb3J5TGlzdCA9IGFjdGl2ZU1lbW9yaWVzLm1hcChtID0+IHtcbiAgICAgIGNvbnN0IHRhZ3MgPSAobS5tZXRhZGF0YSBhcyBhbnkpLnRhZ3M/LmpvaW4oJywgJykgfHwgJ25vbmUnO1xuICAgICAgY29uc3QgcmV0ZW50aW9uRGF5cyA9IChtLm1ldGFkYXRhIGFzIGFueSkucmV0ZW50aW9uRGF5cyB8fCAncGVybWFuZW50JztcbiAgICAgIHJldHVybiBg8J+noCAke20ubWV0YWRhdGEubmFtZX0gKFRhZ3M6ICR7dGFnc30pIC0gJHtyZXRlbnRpb25EYXlzfSBkYXlzIHJldGVudGlvbmA7XG4gICAgfSkuam9pbignXFxuJyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW3tcbiAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgIHRleHQ6IGBBY3RpdmUgbWVtb3JpZXM6XFxuJHttZW1vcnlMaXN0fWBcbiAgICAgIH1dXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgYSBtZW1vcnlcbiAgICogRXh0cmFjdGVkIGZyb20gRWxlbWVudENSVURIYW5kbGVyLnRzIGxpbmVzIDc3Mi04MDVcbiAgICpcbiAgICogQHRocm93cyB7RWxlbWVudE5vdEZvdW5kRXJyb3J9IFdoZW4gbWVtb3J5IGRvZXMgbm90IGV4aXN0XG4gICAqIEBzZWUgSXNzdWUgIzI3NSAtIEhhbmRsZXJzIHJldHVybiBzdWNjZXNzPXRydWUgZm9yIG1pc3NpbmcgZWxlbWVudHNcbiAgICovXG4gIGFzeW5jIGdldEVsZW1lbnREZXRhaWxzKG5hbWU6IHN0cmluZyk6IFByb21pc2U8TUNQUmVzcG9uc2U+IHtcbiAgICAvLyBVc2UgZmxleGlibGUgZmluZGluZyB0byBzdXBwb3J0IGJvdGggZGlzcGxheSBuYW1lIGFuZCBmaWxlbmFtZVxuICAgIGNvbnN0IGFsbE1lbW9yaWVzID0gYXdhaXQgdGhpcy5tZW1vcnlNYW5hZ2VyLmxpc3QoKTtcbiAgICBjb25zdCBtZW1vcnkgPSBhd2FpdCB0aGlzLmZpbmRFbGVtZW50RmxleGlibHkobmFtZSwgYWxsTWVtb3JpZXMpO1xuICAgIGlmICghbWVtb3J5KSB7XG4gICAgICB0aGlzLnRocm93Tm90Rm91bmRFcnJvcihuYW1lLCAnTWVtb3J5Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgZGV0YWlscyA9IFtcbiAgICAgIGDwn6egICoqJHttZW1vcnkubWV0YWRhdGEubmFtZX0qKmAsXG4gICAgICBgJHttZW1vcnkubWV0YWRhdGEuZGVzY3JpcHRpb259YCxcbiAgICAgIGBgLFxuICAgICAgYCoqU3RhdHVzKio6ICR7bWVtb3J5LmdldFN0YXR1cygpfWAsXG4gICAgICBgKipSZXRlbnRpb24qKjogJHsobWVtb3J5Lm1ldGFkYXRhIGFzIGFueSkucmV0ZW50aW9uRGF5cyB8fCAncGVybWFuZW50J30gZGF5c2AsXG4gICAgICBgKipUYWdzKio6ICR7KG1lbW9yeS5tZXRhZGF0YSBhcyBhbnkpLnRhZ3M/LmpvaW4oJywgJykgfHwgJ25vbmUnfWAsXG4gICAgICBgKipTdG9yYWdlIEJhY2tlbmQqKjogJHsobWVtb3J5Lm1ldGFkYXRhIGFzIGFueSkuc3RvcmFnZUJhY2tlbmQgfHwgJ2ZpbGUnfWAsXG4gICAgICBgKipQcml2YWN5IExldmVsKio6ICR7KG1lbW9yeS5tZXRhZGF0YSBhcyBhbnkpLnByaXZhY3lMZXZlbCB8fCAncHJpdmF0ZSd9YCxcbiAgICAgIGBgLFxuICAgICAgYCoqQ29udGVudCoqOmAsXG4gICAgICBtZW1vcnkuY29udGVudCB8fCAnTm8gY29udGVudCBzdG9yZWQnXG4gICAgXTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbe1xuICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgdGV4dDogZGV0YWlscy5qb2luKCdcXG4nKVxuICAgICAgfV1cbiAgICB9O1xuICB9XG59XG4iXX0=