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.

163 lines 22.4 kB
/** * 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