@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.
163 lines • 22.4 kB
JavaScript
/**
* PersonaActivationStrategy - Strategy for persona element activation
*
* Handles activation, deactivation, and status tracking for persona elements.
* Uses the PersonaManager's unique API and PersonaIndicatorService for formatting.
*/
import { ElementNotFoundError } from '../../utils/ErrorHandler.js';
import { BaseActivationStrategy } from './BaseActivationStrategy.js';
export class PersonaActivationStrategy extends BaseActivationStrategy {
personaManager;
indicatorService;
constructor(personaManager, indicatorService) {
super();
this.personaManager = personaManager;
this.indicatorService = indicatorService;
}
/**
* Get the persona indicator prefix
*/
getPersonaIndicator() {
return this.indicatorService.getPersonaIndicator();
}
/**
* Activate a persona
* Extracted from ElementCRUDHandler.ts lines 161-182
*/
async activate(name) {
const result = await this.personaManager.activatePersona(name);
if (!result.success || !result.persona) {
return {
content: [{
type: "text",
text: `${this.getPersonaIndicator()}❌ ${result.message}`
}]
};
}
const persona = result.persona;
const instructions = persona.instructions?.trim() || persona.content?.trim() || 'No instructions provided.';
const referenceContent = persona.instructions?.trim() ? persona.content?.trim() : '';
let text = `${this.getPersonaIndicator()}Persona Activated: **${persona.metadata.name}**\n\n${persona.metadata.description}\n\n**Instructions:**\n${instructions}`;
if (referenceContent) {
text += `\n\n**Reference:**\n${referenceContent}`;
}
// Issue #642: Fail-safe warning for CLI restrictions
const restrictionWarning = this.formatRestrictionWarning(persona.metadata);
if (restrictionWarning) {
text += restrictionWarning;
}
const gatekeeperWarning = this.formatGatekeeperValidityWarning(persona.metadata);
if (gatekeeperWarning) {
text += gatekeeperWarning;
}
return {
content: [{
type: "text",
text
}]
};
}
/**
* Deactivate a specific persona
* Issue #281: Updated to support multiple active personas
*
* @throws {ElementNotFoundError} When named persona does not exist
* @throws {Error} When name parameter is missing
* @see Issue #275 - Handlers return success=true for missing elements
*/
async deactivate(name) {
// Issue #275: Require name parameter for consistent error handling
if (!name || name === '') {
throw new Error('Name parameter is required for deactivate operation');
}
// Issue #275: Verify the named persona exists before deactivating
const persona = this.personaManager.findPersona(name);
if (!persona) {
throw new ElementNotFoundError('Persona', name);
}
// Issue #281: Pass the name to deactivate the specific persona
const result = this.personaManager.deactivatePersona(name);
const indicator = this.getPersonaIndicator();
if (!result.success) {
return {
content: [{
type: "text",
text: `${indicator}❌ ${result.message}`
}]
};
}
return {
content: [{
type: "text",
text: `${indicator}✅ ${result.message}`
}]
};
}
/**
* Get all active personas
* Issue #281: Updated to show all active personas (supports multiple)
*/
async getActiveElements() {
const activePersonas = this.personaManager.getActivePersonas();
const indicator = this.getPersonaIndicator();
if (activePersonas.length === 0) {
return {
content: [{
type: "text",
text: `${indicator}No personas are currently active.`
}]
};
}
const personaList = activePersonas.map(p => `🔹 **${p.metadata.name}** (${p.unique_id})\n ${p.metadata.description}\n 📁 ${p.metadata.category || 'general'} | 🎭 ${p.metadata.author || 'Unknown'}`).join('\n\n');
const header = activePersonas.length === 1
? `${indicator}Active Persona:`
: `${indicator}Active Personas (${activePersonas.length}):`;
let text = `${header}\n\n${personaList}`;
// Issue #642: Restriction summary for active personas with externalRestrictions
const restrictedPersonas = activePersonas.filter(p => p.metadata?.gatekeeper &&
p.metadata.gatekeeper?.externalRestrictions);
if (restrictedPersonas.length > 0) {
const summary = restrictedPersonas.map(p => {
const gk = p.metadata.gatekeeper;
const r = gk.externalRestrictions;
return ` **${p.metadata.name}**: ${r.description}`;
}).join('\n');
text += `\n\n**Loaded CLI Restrictions:**\n${summary}\n> Use \`get_effective_cli_policies\` for full details.`;
}
return {
content: [{
type: "text",
text
}]
};
}
/**
* Get detailed information about a persona
* Extracted from ElementCRUDHandler.ts lines 620-648
*
* @throws {ElementNotFoundError} When persona does not exist
* @see Issue #275 - Handlers return success=true for missing elements
*/
async getElementDetails(name) {
const persona = this.personaManager.findPersona(name);
const indicator = this.getPersonaIndicator();
if (!persona) {
throw new ElementNotFoundError('Persona', name);
}
const triggers = persona.metadata.triggers?.join(', ') || 'None';
const content = persona.content?.trim() || 'No instructions provided.';
return {
content: [{
type: "text",
text: `${indicator}📋 **${persona.metadata.name}** Details\n\n` +
`**Description:** ${persona.metadata.description}\n` +
`**File:** ${persona.filename}\n` +
`**Version:** ${persona.metadata.version || '1.0'}\n` +
`**Author:** ${persona.metadata.author || 'Unknown'}\n` +
`**Triggers:** ${triggers}\n\n` +
`**Full Instructions:**\n\`\`\`\n${content}\n\`\`\``
}]
};
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGVyc29uYUFjdGl2YXRpb25TdHJhdGVneS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9oYW5kbGVycy9zdHJhdGVnaWVzL1BlcnNvbmFBY3RpdmF0aW9uU3RyYXRlZ3kudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0c7QUFJSCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUdyRSxNQUFNLE9BQU8seUJBQTBCLFNBQVEsc0JBQXNCO0lBRWhEO0lBQ0E7SUFGbkIsWUFDbUIsY0FBOEIsRUFDOUIsZ0JBQXlDO1FBRTFELEtBQUssRUFBRSxDQUFDO1FBSFMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBeUI7SUFHNUQsQ0FBQztJQUVEOztPQUVHO0lBQ0ssbUJBQW1CO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFDckQsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBWTtRQUN6QixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRS9ELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3ZDLE9BQU87Z0JBQ0wsT0FBTyxFQUFFLENBQUM7d0JBQ1IsSUFBSSxFQUFFLE1BQU07d0JBQ1osSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLEtBQUssTUFBTSxDQUFDLE9BQU8sRUFBRTtxQkFDekQsQ0FBQzthQUNILENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztRQUMvQixN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QUFJLEtBQUssSUFBSTt3QkFDckQsZUFBZSxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sSUFBSSxTQUFTLElBQUk7d0JBQ3ZELGlCQUFpQixRQUFRLE1BQU07d0JBQy9CLG1DQUFtQyxPQUFPLFVBQVU7aUJBQ3ZELENBQUM7U0FDSCxDQUFDO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQZXJzb25hQWN0aXZhdGlvblN0cmF0ZWd5IC0gU3RyYXRlZ3kgZm9yIHBlcnNvbmEgZWxlbWVudCBhY3RpdmF0aW9uXG4gKlxuICogSGFuZGxlcyBhY3RpdmF0aW9uLCBkZWFjdGl2YXRpb24sIGFuZCBzdGF0dXMgdHJhY2tpbmcgZm9yIHBlcnNvbmEgZWxlbWVudHMuXG4gKiBVc2VzIHRoZSBQZXJzb25hTWFuYWdlcidzIHVuaXF1ZSBBUEkgYW5kIFBlcnNvbmFJbmRpY2F0b3JTZXJ2aWNlIGZvciBmb3JtYXR0aW5nLlxuICovXG5cbmltcG9ydCB7IFBlcnNvbmFNYW5hZ2VyIH0gZnJvbSAnLi4vLi4vcGVyc29uYS9QZXJzb25hTWFuYWdlci5qcyc7XG5pbXBvcnQgeyBQZXJzb25hSW5kaWNhdG9yU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL1BlcnNvbmFJbmRpY2F0b3JTZXJ2aWNlLmpzJztcbmltcG9ydCB7IEVsZW1lbnROb3RGb3VuZEVycm9yIH0gZnJvbSAnLi4vLi4vdXRpbHMvRXJyb3JIYW5kbGVyLmpzJztcbmltcG9ydCB7IEJhc2VBY3RpdmF0aW9uU3RyYXRlZ3kgfSBmcm9tICcuL0Jhc2VBY3RpdmF0aW9uU3RyYXRlZ3kuanMnO1xuaW1wb3J0IHsgRWxlbWVudEFjdGl2YXRpb25TdHJhdGVneSwgTUNQUmVzcG9uc2UgfSBmcm9tICcuL0VsZW1lbnRBY3RpdmF0aW9uU3RyYXRlZ3kuanMnO1xuXG5leHBvcnQgY2xhc3MgUGVyc29uYUFjdGl2YXRpb25TdHJhdGVneSBleHRlbmRzIEJhc2VBY3RpdmF0aW9uU3RyYXRlZ3kgaW1wbGVtZW50cyBFbGVtZW50QWN0aXZhdGlvblN0cmF0ZWd5IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBwZXJzb25hTWFuYWdlcjogUGVyc29uYU1hbmFnZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBpbmRpY2F0b3JTZXJ2aWNlOiBQZXJzb25hSW5kaWNhdG9yU2VydmljZVxuICApIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgcGVyc29uYSBpbmRpY2F0b3IgcHJlZml4XG4gICAqL1xuICBwcml2YXRlIGdldFBlcnNvbmFJbmRpY2F0b3IoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5pbmRpY2F0b3JTZXJ2aWNlLmdldFBlcnNvbmFJbmRpY2F0b3IoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY3RpdmF0ZSBhIHBlcnNvbmFcbiAgICogRXh0cmFjdGVkIGZyb20gRWxlbWVudENSVURIYW5kbGVyLnRzIGxpbmVzIDE2MS0xODJcbiAgICovXG4gIGFzeW5jIGFjdGl2YXRlKG5hbWU6IHN0cmluZyk6IFByb21pc2U8TUNQUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnBlcnNvbmFNYW5hZ2VyLmFjdGl2YXRlUGVyc29uYShuYW1lKTtcblxuICAgIGlmICghcmVzdWx0LnN1Y2Nlc3MgfHwgIXJlc3VsdC5wZXJzb25hKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBbe1xuICAgICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICAgIHRleHQ6IGAke3RoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpfeKdjCAke3Jlc3VsdC5tZXNzYWdlfWBcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgcGVyc29uYSA9IHJlc3VsdC5wZXJzb25hO1xuICAgIGNvbnN0IGluc3RydWN0aW9ucyA9IHBlcnNvbmEuaW5zdHJ1Y3Rpb25zPy50cmltKCkgfHwgcGVyc29uYS5jb250ZW50Py50cmltKCkgfHwgJ05vIGluc3RydWN0aW9ucyBwcm92aWRlZC4nO1xuICAgIGNvbnN0IHJlZmVyZW5jZUNvbnRlbnQgPSBwZXJzb25hLmluc3RydWN0aW9ucz8udHJpbSgpID8gcGVyc29uYS5jb250ZW50Py50cmltKCkgOiAnJztcblxuICAgIGxldCB0ZXh0ID0gYCR7dGhpcy5nZXRQZXJzb25hSW5kaWNhdG9yKCl9UGVyc29uYSBBY3RpdmF0ZWQ6ICoqJHtwZXJzb25hLm1ldGFkYXRhLm5hbWV9KipcXG5cXG4ke3BlcnNvbmEubWV0YWRhdGEuZGVzY3JpcHRpb259XFxuXFxuKipJbnN0cnVjdGlvbnM6KipcXG4ke2luc3RydWN0aW9uc31gO1xuICAgIGlmIChyZWZlcmVuY2VDb250ZW50KSB7XG4gICAgICB0ZXh0ICs9IGBcXG5cXG4qKlJlZmVyZW5jZToqKlxcbiR7cmVmZXJlbmNlQ29udGVudH1gO1xuICAgIH1cblxuICAgIC8vIElzc3VlICM2NDI6IEZhaWwtc2FmZSB3YXJuaW5nIGZvciBDTEkgcmVzdHJpY3Rpb25zXG4gICAgY29uc3QgcmVzdHJpY3Rpb25XYXJuaW5nID0gdGhpcy5mb3JtYXRSZXN0cmljdGlvbldhcm5pbmcocGVyc29uYS5tZXRhZGF0YSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KTtcbiAgICBpZiAocmVzdHJpY3Rpb25XYXJuaW5nKSB7XG4gICAgICB0ZXh0ICs9IHJlc3RyaWN0aW9uV2FybmluZztcbiAgICB9XG5cbiAgICBjb25zdCBnYXRla2VlcGVyV2FybmluZyA9IHRoaXMuZm9ybWF0R2F0ZWtlZXBlclZhbGlkaXR5V2FybmluZyhwZXJzb25hLm1ldGFkYXRhIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pO1xuICAgIGlmIChnYXRla2VlcGVyV2FybmluZykge1xuICAgICAgdGV4dCArPSBnYXRla2VlcGVyV2FybmluZztcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW3tcbiAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgIHRleHRcbiAgICAgIH1dXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWFjdGl2YXRlIGEgc3BlY2lmaWMgcGVyc29uYVxuICAgKiBJc3N1ZSAjMjgxOiBVcGRhdGVkIHRvIHN1cHBvcnQgbXVsdGlwbGUgYWN0aXZlIHBlcnNvbmFzXG4gICAqXG4gICAqIEB0aHJvd3Mge0VsZW1lbnROb3RGb3VuZEVycm9yfSBXaGVuIG5hbWVkIHBlcnNvbmEgZG9lcyBub3QgZXhpc3RcbiAgICogQHRocm93cyB7RXJyb3J9IFdoZW4gbmFtZSBwYXJhbWV0ZXIgaXMgbWlzc2luZ1xuICAgKiBAc2VlIElzc3VlICMyNzUgLSBIYW5kbGVycyByZXR1cm4gc3VjY2Vzcz10cnVlIGZvciBtaXNzaW5nIGVsZW1lbnRzXG4gICAqL1xuICBhc3luYyBkZWFjdGl2YXRlKG5hbWU6IHN0cmluZyk6IFByb21pc2U8TUNQUmVzcG9uc2U+IHtcbiAgICAvLyBJc3N1ZSAjMjc1OiBSZXF1aXJlIG5hbWUgcGFyYW1ldGVyIGZvciBjb25zaXN0ZW50IGVycm9yIGhhbmRsaW5nXG4gICAgaWYgKCFuYW1lIHx8IG5hbWUgPT09ICcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05hbWUgcGFyYW1ldGVyIGlzIHJlcXVpcmVkIGZvciBkZWFjdGl2YXRlIG9wZXJhdGlvbicpO1xuICAgIH1cblxuICAgIC8vIElzc3VlICMyNzU6IFZlcmlmeSB0aGUgbmFtZWQgcGVyc29uYSBleGlzdHMgYmVmb3JlIGRlYWN0aXZhdGluZ1xuICAgIGNvbnN0IHBlcnNvbmEgPSB0aGlzLnBlcnNvbmFNYW5hZ2VyLmZpbmRQZXJzb25hKG5hbWUpO1xuICAgIGlmICghcGVyc29uYSkge1xuICAgICAgdGhyb3cgbmV3IEVsZW1lbnROb3RGb3VuZEVycm9yKCdQZXJzb25hJywgbmFtZSk7XG4gICAgfVxuXG4gICAgLy8gSXNzdWUgIzI4MTogUGFzcyB0aGUgbmFtZSB0byBkZWFjdGl2YXRlIHRoZSBzcGVjaWZpYyBwZXJzb25hXG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy5wZXJzb25hTWFuYWdlci5kZWFjdGl2YXRlUGVyc29uYShuYW1lKTtcbiAgICBjb25zdCBpbmRpY2F0b3IgPSB0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKTtcblxuICAgIGlmICghcmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogYCR7aW5kaWNhdG9yfeKdjCAke3Jlc3VsdC5tZXNzYWdlfWBcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICB0ZXh0OiBgJHtpbmRpY2F0b3J94pyFICR7cmVzdWx0Lm1lc3NhZ2V9YFxuICAgICAgfV1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgYWN0aXZlIHBlcnNvbmFzXG4gICAqIElzc3VlICMyODE6IFVwZGF0ZWQgdG8gc2hvdyBhbGwgYWN0aXZlIHBlcnNvbmFzIChzdXBwb3J0cyBtdWx0aXBsZSlcbiAgICovXG4gIGFzeW5jIGdldEFjdGl2ZUVsZW1lbnRzKCk6IFByb21pc2U8TUNQUmVzcG9uc2U+IHtcbiAgICBjb25zdCBhY3RpdmVQZXJzb25hcyA9IHRoaXMucGVyc29uYU1hbmFnZXIuZ2V0QWN0aXZlUGVyc29uYXMoKTtcbiAgICBjb25zdCBpbmRpY2F0b3IgPSB0aGlzLmdldFBlcnNvbmFJbmRpY2F0b3IoKTtcblxuICAgIGlmIChhY3RpdmVQZXJzb25hcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogYCR7aW5kaWNhdG9yfU5vIHBlcnNvbmFzIGFyZSBjdXJyZW50bHkgYWN0aXZlLmBcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgcGVyc29uYUxpc3QgPSBhY3RpdmVQZXJzb25hcy5tYXAocCA9PlxuICAgICAgYPCflLkgKioke3AubWV0YWRhdGEubmFtZX0qKiAoJHtwLnVuaXF1ZV9pZH0pXFxuICAgJHtwLm1ldGFkYXRhLmRlc2NyaXB0aW9ufVxcbiAgIPCfk4EgJHtwLm1ldGFkYXRhLmNhdGVnb3J5IHx8ICdnZW5lcmFsJ30gfCDwn46tICR7cC5tZXRhZGF0YS5hdXRob3IgfHwgJ1Vua25vd24nfWBcbiAgICApLmpvaW4oJ1xcblxcbicpO1xuXG4gICAgY29uc3QgaGVhZGVyID0gYWN0aXZlUGVyc29uYXMubGVuZ3RoID09PSAxXG4gICAgICA/IGAke2luZGljYXRvcn1BY3RpdmUgUGVyc29uYTpgXG4gICAgICA6IGAke2luZGljYXRvcn1BY3RpdmUgUGVyc29uYXMgKCR7YWN0aXZlUGVyc29uYXMubGVuZ3RofSk6YDtcblxuICAgIGxldCB0ZXh0ID0gYCR7aGVhZGVyfVxcblxcbiR7cGVyc29uYUxpc3R9YDtcblxuICAgIC8vIElzc3VlICM2NDI6IFJlc3RyaWN0aW9uIHN1bW1hcnkgZm9yIGFjdGl2ZSBwZXJzb25hcyB3aXRoIGV4dGVybmFsUmVzdHJpY3Rpb25zXG4gICAgY29uc3QgcmVzdHJpY3RlZFBlcnNvbmFzID0gYWN0aXZlUGVyc29uYXMuZmlsdGVyKFxuICAgICAgcCA9PiAocC5tZXRhZGF0YSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KT8uZ2F0ZWtlZXBlciAmJlxuICAgICAgICAoKHAubWV0YWRhdGEgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikuZ2F0ZWtlZXBlciBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik/LmV4dGVybmFsUmVzdHJpY3Rpb25zXG4gICAgKTtcbiAgICBpZiAocmVzdHJpY3RlZFBlcnNvbmFzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHN1bW1hcnkgPSByZXN0cmljdGVkUGVyc29uYXMubWFwKHAgPT4ge1xuICAgICAgICBjb25zdCBnayA9IChwLm1ldGFkYXRhIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLmdhdGVrZWVwZXIgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgIGNvbnN0IHIgPSBnay5leHRlcm5hbFJlc3RyaWN0aW9ucyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgcmV0dXJuIGAgICoqJHtwLm1ldGFkYXRhLm5hbWV9Kio6ICR7ci5kZXNjcmlwdGlvbn1gO1xuICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICB0ZXh0ICs9IGBcXG5cXG4qKkxvYWRlZCBDTEkgUmVzdHJpY3Rpb25zOioqXFxuJHtzdW1tYXJ5fVxcbj4gVXNlIFxcYGdldF9lZmZlY3RpdmVfY2xpX3BvbGljaWVzXFxgIGZvciBmdWxsIGRldGFpbHMuYDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW3tcbiAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgIHRleHRcbiAgICAgIH1dXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgYSBwZXJzb25hXG4gICAqIEV4dHJhY3RlZCBmcm9tIEVsZW1lbnRDUlVESGFuZGxlci50cyBsaW5lcyA2MjAtNjQ4XG4gICAqXG4gICAqIEB0aHJvd3Mge0VsZW1lbnROb3RGb3VuZEVycm9yfSBXaGVuIHBlcnNvbmEgZG9lcyBub3QgZXhpc3RcbiAgICogQHNlZSBJc3N1ZSAjMjc1IC0gSGFuZGxlcnMgcmV0dXJuIHN1Y2Nlc3M9dHJ1ZSBmb3IgbWlzc2luZyBlbGVtZW50c1xuICAgKi9cbiAgYXN5bmMgZ2V0RWxlbWVudERldGFpbHMobmFtZTogc3RyaW5nKTogUHJvbWlzZTxNQ1BSZXNwb25zZT4ge1xuICAgIGNvbnN0IHBlcnNvbmEgPSB0aGlzLnBlcnNvbmFNYW5hZ2VyLmZpbmRQZXJzb25hKG5hbWUpO1xuICAgIGNvbnN0IGluZGljYXRvciA9IHRoaXMuZ2V0UGVyc29uYUluZGljYXRvcigpO1xuXG4gICAgaWYgKCFwZXJzb25hKSB7XG4gICAgICB0aHJvdyBuZXcgRWxlbWVudE5vdEZvdW5kRXJyb3IoJ1BlcnNvbmEnLCBuYW1lKTtcbiAgICB9XG5cbiAgICBjb25zdCB0cmlnZ2VycyA9IHBlcnNvbmEubWV0YWRhdGEudHJpZ2dlcnM/LmpvaW4oJywgJykgfHwgJ05vbmUnO1xuICAgIGNvbnN0IGNvbnRlbnQgPSBwZXJzb25hLmNvbnRlbnQ/LnRyaW0oKSB8fCAnTm8gaW5zdHJ1Y3Rpb25zIHByb3ZpZGVkLic7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW3tcbiAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgIHRleHQ6IGAke2luZGljYXRvcn3wn5OLICoqJHtwZXJzb25hLm1ldGFkYXRhLm5hbWV9KiogRGV0YWlsc1xcblxcbmAgK1xuICAgICAgICAgIGAqKkRlc2NyaXB0aW9uOioqICR7cGVyc29uYS5tZXRhZGF0YS5kZXNjcmlwdGlvbn1cXG5gICtcbiAgICAgICAgICBgKipGaWxlOioqICR7cGVyc29uYS5maWxlbmFtZX1cXG5gICtcbiAgICAgICAgICBgKipWZXJzaW9uOioqICR7cGVyc29uYS5tZXRhZGF0YS52ZXJzaW9uIHx8ICcxLjAnfVxcbmAgK1xuICAgICAgICAgIGAqKkF1dGhvcjoqKiAke3BlcnNvbmEubWV0YWRhdGEuYXV0aG9yIHx8ICdVbmtub3duJ31cXG5gICtcbiAgICAgICAgICBgKipUcmlnZ2VyczoqKiAke3RyaWdnZXJzfVxcblxcbmAgK1xuICAgICAgICAgIGAqKkZ1bGwgSW5zdHJ1Y3Rpb25zOioqXFxuXFxgXFxgXFxgXFxuJHtjb250ZW50fVxcblxcYFxcYFxcYGBcbiAgICAgIH1dXG4gICAgfTtcbiAgfVxufVxuIl19