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.

209 lines 29.3 kB
/** * EnsembleActivationStrategy - Strategy for ensemble element activation * * Handles activation, deactivation, and status tracking for ensemble elements. * Ensembles coordinate multiple elements and require all managers for activation. */ import { BaseActivationStrategy } from './BaseActivationStrategy.js'; export class EnsembleActivationStrategy extends BaseActivationStrategy { ensembleManager; portfolioManager; skillManager; templateManager; agentManager; memoryManager; personaManager; constructor(ensembleManager, portfolioManager, skillManager, templateManager, agentManager, memoryManager, personaManager) { super(); this.ensembleManager = ensembleManager; this.portfolioManager = portfolioManager; this.skillManager = skillManager; this.templateManager = templateManager; this.agentManager = agentManager; this.memoryManager = memoryManager; this.personaManager = personaManager; } /** * Activate an ensemble with all its constituent elements * Extracted from ElementCRUDHandler.ts lines 281-345 */ async activate(name) { // Activate via manager (which handles name tracking) const activationResult = await this.ensembleManager.activateEnsemble(name); if (!activationResult.success) { return this.createNotFoundResponse(name, 'Ensemble'); } const ensemble = activationResult.ensemble; // Activate the ensemble with all managers (orchestration) try { const result = await ensemble.activateEnsemble(this.portfolioManager, this.getManagers()); const statusEmoji = result.success ? '✅' : '⚠️'; const details = [ `${statusEmoji} Ensemble '${ensemble.metadata.name}' activated`, ``, `**Strategy**: ${ensemble.metadata.activationStrategy}`, `**Activated**: ${result.activatedElements.length} elements`, `**Failed**: ${result.failedElements.length} elements`, `**Duration**: ${result.totalDuration}ms`, ]; if (result.activatedElements.length > 0) { details.push(``, `**Active Elements**:`); result.activatedElements.forEach((elem) => { details.push(` - ${elem}`); }); } if (result.failedElements.length > 0) { details.push(``, `**Failed Elements**:`); result.failedElements.forEach((elem) => { const elementResult = result.elementResults.find((r) => r.elementName === elem && !r.success); const errorMsg = elementResult?.error?.message || 'Unknown error'; details.push(` - ${elem}: ${errorMsg}`); }); } // Issue #642: Fail-safe warning for CLI restrictions const restrictionWarning = this.formatRestrictionWarning(ensemble.metadata); if (restrictionWarning) { details.push(restrictionWarning); } const gatekeeperWarning = this.formatGatekeeperValidityWarning(ensemble.metadata); if (gatekeeperWarning) { details.push(gatekeeperWarning); } return { content: [{ type: "text", text: details.join('\n') }] }; } catch (activationError) { return { content: [{ type: "text", text: `❌ Failed to activate ensemble: ${activationError instanceof Error ? activationError.message : 'Unknown error'}` }] }; } } /** * Deactivate an ensemble * NOTE: This was missing in the original implementation - adding it now * * @throws {ElementNotFoundError} When ensemble does not exist * @see Issue #275 - Handlers return success=true for missing elements */ async deactivate(name) { // Deactivate via manager (which handles name tracking) const deactivationResult = await this.ensembleManager.deactivateEnsemble(name); if (!deactivationResult.success) { this.throwNotFoundError(name, 'Ensemble'); } if (deactivationResult.ensemble) { await this.deactivateMembers(deactivationResult.ensemble); } return this.createSuccessResponse(`✅ Ensemble '${name}' deactivated`); } getManagers() { return { skillManager: this.skillManager, templateManager: this.templateManager, agentManager: this.agentManager, memoryManager: this.memoryManager, personaManager: this.personaManager, ensembleManager: this.ensembleManager }; } async deactivateMembers(ensemble) { const deactivationPromises = (ensemble.metadata.elements || []).map((element) => this.deactivateMember(element)); await Promise.all(deactivationPromises); } async deactivateMember(element) { const normalizedType = element.element_type.toLowerCase(); switch (normalizedType) { case 'skill': case 'skills': await this.skillManager.deactivateSkill(element.element_name); return; case 'persona': case 'personas': await Promise.resolve(this.personaManager.deactivatePersona(element.element_name)); return; case 'agent': case 'agents': await this.agentManager.deactivateAgent(element.element_name); return; case 'memory': case 'memories': await this.memoryManager.deactivateMemory(element.element_name); return; case 'ensemble': case 'ensembles': await this.ensembleManager.deactivateEnsemble(element.element_name); return; case 'template': case 'templates': default: return; } } /** * Get all active ensembles * NOTE: This was missing in the original implementation - adding basic version */ async getActiveElements() { const activeEnsembles = await this.ensembleManager.getActiveEnsembles(); if (activeEnsembles.length === 0) { return { content: [{ type: "text", text: "🎭 No active ensembles" }] }; } const ensembleList = activeEnsembles.map(e => { const elementCount = e.metadata.elements?.length || 0; return `🎭 ${e.metadata.name} (${elementCount} elements)`; }).join('\n'); return { content: [{ type: "text", text: `Active ensembles:\n${ensembleList}` }] }; } /** * Get detailed information about an ensemble * Extracted from ElementCRUDHandler.ts lines 807-846 */ async getElementDetails(name) { // Use flexible finding to support both display name and filename const allEnsembles = await this.ensembleManager.list(); const ensemble = await this.findElementFlexibly(name, allEnsembles); if (!ensemble) { this.throwNotFoundError(name, 'Ensemble'); } const elementsList = ensemble.metadata.elements?.map((elem) => `- ${elem.element_name} (${elem.element_type}) - ${elem.role}, priority: ${elem.priority}, activation: ${elem.activation}`).join('\n') || 'No elements configured'; const details = [ `🎭 **${ensemble.metadata.name}**`, `${ensemble.metadata.description}`, ``, `**Status**: ${ensemble.getStatus()}`, `**Version**: ${ensemble.metadata.version || '1.0.0'}`, `**Activation Strategy**: ${ensemble.metadata.activationStrategy || 'sequential'}`, `**Conflict Resolution**: ${ensemble.metadata.conflictResolution || 'last-write'}`, `**Context Sharing**: ${ensemble.metadata.contextSharing || 'selective'}`, `**Allows Nesting**: ${ensemble.metadata.allowNested ? 'Yes' : 'No'}`, `**Max Nesting Depth**: ${ensemble.metadata.maxNestingDepth || 5}`, ``, `**Elements** (${ensemble.metadata.elements?.length || 0}):`, elementsList ]; return { content: [{ type: "text", text: details.join('\n') }] }; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRW5zZW1ibGVBY3RpdmF0aW9uU3RyYXRlZ3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaGFuZGxlcnMvc3RyYXRlZ2llcy9FbnNlbWJsZUFjdGl2YXRpb25TdHJhdGVneS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQVNILE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBS3JFLE1BQU0sT0FBTywwQkFBMkIsU0FBUSxzQkFBc0I7SUFFakQ7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFQbkIsWUFDbUIsZUFBZ0MsRUFDaEMsZ0JBQWtDLEVBQ2xDLFlBQTBCLEVBQzFCLGVBQWdDLEVBQ2hDLFlBQTBCLEVBQzFCLGFBQTRCLEVBQzVCLGNBQThCO1FBRS9DLEtBQUssRUFBRSxDQUFDO1FBUlMsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtJQUdqRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFZO1FBQ3pCLHFEQUFxRDtRQUNyRCxNQUFNLGdCQUFnQixHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUUzRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDOUIsT0FBTyxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQyxRQUFTLENBQUM7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WyIvKipcbiAqIEVuc2VtYmxlQWN0aXZhdGlvblN0cmF0ZWd5IC0gU3RyYXRlZ3kgZm9yIGVuc2VtYmxlIGVsZW1lbnQgYWN0aXZhdGlvblxuICpcbiAqIEhhbmRsZXMgYWN0aXZhdGlvbiwgZGVhY3RpdmF0aW9uLCBhbmQgc3RhdHVzIHRyYWNraW5nIGZvciBlbnNlbWJsZSBlbGVtZW50cy5cbiAqIEVuc2VtYmxlcyBjb29yZGluYXRlIG11bHRpcGxlIGVsZW1lbnRzIGFuZCByZXF1aXJlIGFsbCBtYW5hZ2VycyBmb3IgYWN0aXZhdGlvbi5cbiAqL1xuXG5pbXBvcnQgeyBFbnNlbWJsZU1hbmFnZXIgfSBmcm9tICcuLi8uLi9lbGVtZW50cy9lbnNlbWJsZXMvRW5zZW1ibGVNYW5hZ2VyLmpzJztcbmltcG9ydCB7IFNraWxsTWFuYWdlciB9IGZyb20gJy4uLy4uL2VsZW1lbnRzL3NraWxscy9pbmRleC5qcyc7XG5pbXBvcnQgeyBUZW1wbGF0ZU1hbmFnZXIgfSBmcm9tICcuLi8uLi9lbGVtZW50cy90ZW1wbGF0ZXMvVGVtcGxhdGVNYW5hZ2VyLmpzJztcbmltcG9ydCB7IEFnZW50TWFuYWdlciB9IGZyb20gJy4uLy4uL2VsZW1lbnRzL2FnZW50cy9BZ2VudE1hbmFnZXIuanMnO1xuaW1wb3J0IHsgTWVtb3J5TWFuYWdlciB9IGZyb20gJy4uLy4uL2VsZW1lbnRzL21lbW9yaWVzL01lbW9yeU1hbmFnZXIuanMnO1xuaW1wb3J0IHsgUGVyc29uYU1hbmFnZXIgfSBmcm9tICcuLi8uLi9wZXJzb25hL1BlcnNvbmFNYW5hZ2VyLmpzJztcbmltcG9ydCB7IFBvcnRmb2xpb01hbmFnZXIgfSBmcm9tICcuLi8uLi9wb3J0Zm9saW8vUG9ydGZvbGlvTWFuYWdlci5qcyc7XG5pbXBvcnQgeyBCYXNlQWN0aXZhdGlvblN0cmF0ZWd5IH0gZnJvbSAnLi9CYXNlQWN0aXZhdGlvblN0cmF0ZWd5LmpzJztcbmltcG9ydCB7IEVsZW1lbnRBY3RpdmF0aW9uU3RyYXRlZ3ksIE1DUFJlc3BvbnNlIH0gZnJvbSAnLi9FbGVtZW50QWN0aXZhdGlvblN0cmF0ZWd5LmpzJztcbmltcG9ydCB0eXBlIHsgRW5zZW1ibGUgfSBmcm9tICcuLi8uLi9lbGVtZW50cy9lbnNlbWJsZXMvRW5zZW1ibGUuanMnO1xuaW1wb3J0IHR5cGUgeyBFbGVtZW50TWFuYWdlcnMsIEVuc2VtYmxlRWxlbWVudCB9IGZyb20gJy4uLy4uL2VsZW1lbnRzL2Vuc2VtYmxlcy90eXBlcy5qcyc7XG5cbmV4cG9ydCBjbGFzcyBFbnNlbWJsZUFjdGl2YXRpb25TdHJhdGVneSBleHRlbmRzIEJhc2VBY3RpdmF0aW9uU3RyYXRlZ3kgaW1wbGVtZW50cyBFbGVtZW50QWN0aXZhdGlvblN0cmF0ZWd5IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBlbnNlbWJsZU1hbmFnZXI6IEVuc2VtYmxlTWFuYWdlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHBvcnRmb2xpb01hbmFnZXI6IFBvcnRmb2xpb01hbmFnZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBza2lsbE1hbmFnZXI6IFNraWxsTWFuYWdlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRlbXBsYXRlTWFuYWdlcjogVGVtcGxhdGVNYW5hZ2VyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYWdlbnRNYW5hZ2VyOiBBZ2VudE1hbmFnZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBtZW1vcnlNYW5hZ2VyOiBNZW1vcnlNYW5hZ2VyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcGVyc29uYU1hbmFnZXI6IFBlcnNvbmFNYW5hZ2VyXG4gICkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogQWN0aXZhdGUgYW4gZW5zZW1ibGUgd2l0aCBhbGwgaXRzIGNvbnN0aXR1ZW50IGVsZW1lbnRzXG4gICAqIEV4dHJhY3RlZCBmcm9tIEVsZW1lbnRDUlVESGFuZGxlci50cyBsaW5lcyAyODEtMzQ1XG4gICAqL1xuICBhc3luYyBhY3RpdmF0ZShuYW1lOiBzdHJpbmcpOiBQcm9taXNlPE1DUFJlc3BvbnNlPiB7XG4gICAgLy8gQWN0aXZhdGUgdmlhIG1hbmFnZXIgKHdoaWNoIGhhbmRsZXMgbmFtZSB0cmFja2luZylcbiAgICBjb25zdCBhY3RpdmF0aW9uUmVzdWx0ID0gYXdhaXQgdGhpcy5lbnNlbWJsZU1hbmFnZXIuYWN0aXZhdGVFbnNlbWJsZShuYW1lKTtcblxuICAgIGlmICghYWN0aXZhdGlvblJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVOb3RGb3VuZFJlc3BvbnNlKG5hbWUsICdFbnNlbWJsZScpO1xuICAgIH1cblxuICAgIGNvbnN0IGVuc2VtYmxlID0gYWN0aXZhdGlvblJlc3VsdC5lbnNlbWJsZSE7XG5cbiAgICAvLyBBY3RpdmF0ZSB0aGUgZW5zZW1ibGUgd2l0aCBhbGwgbWFuYWdlcnMgKG9yY2hlc3RyYXRpb24pXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGVuc2VtYmxlLmFjdGl2YXRlRW5zZW1ibGUodGhpcy5wb3J0Zm9saW9NYW5hZ2VyLCB0aGlzLmdldE1hbmFnZXJzKCkpO1xuXG4gICAgICBjb25zdCBzdGF0dXNFbW9qaSA9IHJlc3VsdC5zdWNjZXNzID8gJ+KchScgOiAn4pqg77iPJztcbiAgICAgIGNvbnN0IGRldGFpbHMgPSBbXG4gICAgICAgIGAke3N0YXR1c0Vtb2ppfSBFbnNlbWJsZSAnJHtlbnNlbWJsZS5tZXRhZGF0YS5uYW1lfScgYWN0aXZhdGVkYCxcbiAgICAgICAgYGAsXG4gICAgICAgIGAqKlN0cmF0ZWd5Kio6ICR7ZW5zZW1ibGUubWV0YWRhdGEuYWN0aXZhdGlvblN0cmF0ZWd5fWAsXG4gICAgICAgIGAqKkFjdGl2YXRlZCoqOiAke3Jlc3VsdC5hY3RpdmF0ZWRFbGVtZW50cy5sZW5ndGh9IGVsZW1lbnRzYCxcbiAgICAgICAgYCoqRmFpbGVkKio6ICR7cmVzdWx0LmZhaWxlZEVsZW1lbnRzLmxlbmd0aH0gZWxlbWVudHNgLFxuICAgICAgICBgKipEdXJhdGlvbioqOiAke3Jlc3VsdC50b3RhbER1cmF0aW9ufW1zYCxcbiAgICAgIF07XG5cbiAgICAgIGlmIChyZXN1bHQuYWN0aXZhdGVkRWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICBkZXRhaWxzLnB1c2goYGAsIGAqKkFjdGl2ZSBFbGVtZW50cyoqOmApO1xuICAgICAgICByZXN1bHQuYWN0aXZhdGVkRWxlbWVudHMuZm9yRWFjaCgoZWxlbTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgZGV0YWlscy5wdXNoKGAgIC0gJHtlbGVtfWApO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3VsdC5mYWlsZWRFbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGRldGFpbHMucHVzaChgYCwgYCoqRmFpbGVkIEVsZW1lbnRzKio6YCk7XG4gICAgICAgIHJlc3VsdC5mYWlsZWRFbGVtZW50cy5mb3JFYWNoKChlbGVtOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICBjb25zdCBlbGVtZW50UmVzdWx0ID0gcmVzdWx0LmVsZW1lbnRSZXN1bHRzLmZpbmQoKHI6IGFueSkgPT4gci5lbGVtZW50TmFtZSA9PT0gZWxlbSAmJiAhci5zdWNjZXNzKTtcbiAgICAgICAgICBjb25zdCBlcnJvck1zZyA9IGVsZW1lbnRSZXN1bHQ/LmVycm9yPy5tZXNzYWdlIHx8ICdVbmtub3duIGVycm9yJztcbiAgICAgICAgICBkZXRhaWxzLnB1c2goYCAgLSAke2VsZW19OiAke2Vycm9yTXNnfWApO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gSXNzdWUgIzY0MjogRmFpbC1zYWZlIHdhcm5pbmcgZm9yIENMSSByZXN0cmljdGlvbnNcbiAgICAgIGNvbnN0IHJlc3RyaWN0aW9uV2FybmluZyA9IHRoaXMuZm9ybWF0UmVzdHJpY3Rpb25XYXJuaW5nKGVuc2VtYmxlLm1ldGFkYXRhIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pO1xuICAgICAgaWYgKHJlc3RyaWN0aW9uV2FybmluZykge1xuICAgICAgICBkZXRhaWxzLnB1c2gocmVzdHJpY3Rpb25XYXJuaW5nKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZ2F0ZWtlZXBlcldhcm5pbmcgPSB0aGlzLmZvcm1hdEdhdGVrZWVwZXJWYWxpZGl0eVdhcm5pbmcoZW5zZW1ibGUubWV0YWRhdGEgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik7XG4gICAgICBpZiAoZ2F0ZWtlZXBlcldhcm5pbmcpIHtcbiAgICAgICAgZGV0YWlscy5wdXNoKGdhdGVrZWVwZXJXYXJuaW5nKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBkZXRhaWxzLmpvaW4oJ1xcbicpXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGFjdGl2YXRpb25FcnJvcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29udGVudDogW3tcbiAgICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgICB0ZXh0OiBg4p2MIEZhaWxlZCB0byBhY3RpdmF0ZSBlbnNlbWJsZTogJHthY3RpdmF0aW9uRXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGFjdGl2YXRpb25FcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InfWBcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlYWN0aXZhdGUgYW4gZW5zZW1ibGVcbiAgICogTk9URTogVGhpcyB3YXMgbWlzc2luZyBpbiB0aGUgb3JpZ2luYWwgaW1wbGVtZW50YXRpb24gLSBhZGRpbmcgaXQgbm93XG4gICAqXG4gICAqIEB0aHJvd3Mge0VsZW1lbnROb3RGb3VuZEVycm9yfSBXaGVuIGVuc2VtYmxlIGRvZXMgbm90IGV4aXN0XG4gICAqIEBzZWUgSXNzdWUgIzI3NSAtIEhhbmRsZXJzIHJldHVybiBzdWNjZXNzPXRydWUgZm9yIG1pc3NpbmcgZWxlbWVudHNcbiAgICovXG4gIGFzeW5jIGRlYWN0aXZhdGUobmFtZTogc3RyaW5nKTogUHJvbWlzZTxNQ1BSZXNwb25zZT4ge1xuICAgIC8vIERlYWN0aXZhdGUgdmlhIG1hbmFnZXIgKHdoaWNoIGhhbmRsZXMgbmFtZSB0cmFja2luZylcbiAgICBjb25zdCBkZWFjdGl2YXRpb25SZXN1bHQgPSBhd2FpdCB0aGlzLmVuc2VtYmxlTWFuYWdlci5kZWFjdGl2YXRlRW5zZW1ibGUobmFtZSk7XG5cbiAgICBpZiAoIWRlYWN0aXZhdGlvblJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICB0aGlzLnRocm93Tm90Rm91bmRFcnJvcihuYW1lLCAnRW5zZW1ibGUnKTtcbiAgICB9XG5cbiAgICBpZiAoZGVhY3RpdmF0aW9uUmVzdWx0LmVuc2VtYmxlKSB7XG4gICAgICBhd2FpdCB0aGlzLmRlYWN0aXZhdGVNZW1iZXJzKGRlYWN0aXZhdGlvblJlc3VsdC5lbnNlbWJsZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlU3VjY2Vzc1Jlc3BvbnNlKGDinIUgRW5zZW1ibGUgJyR7bmFtZX0nIGRlYWN0aXZhdGVkYCk7XG4gIH1cblxuICBwcml2YXRlIGdldE1hbmFnZXJzKCk6IEVsZW1lbnRNYW5hZ2VycyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNraWxsTWFuYWdlcjogdGhpcy5za2lsbE1hbmFnZXIsXG4gICAgICB0ZW1wbGF0ZU1hbmFnZXI6IHRoaXMudGVtcGxhdGVNYW5hZ2VyLFxuICAgICAgYWdlbnRNYW5hZ2VyOiB0aGlzLmFnZW50TWFuYWdlcixcbiAgICAgIG1lbW9yeU1hbmFnZXI6IHRoaXMubWVtb3J5TWFuYWdlcixcbiAgICAgIHBlcnNvbmFNYW5hZ2VyOiB0aGlzLnBlcnNvbmFNYW5hZ2VyLFxuICAgICAgZW5zZW1ibGVNYW5hZ2VyOiB0aGlzLmVuc2VtYmxlTWFuYWdlclxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGRlYWN0aXZhdGVNZW1iZXJzKGVuc2VtYmxlOiBFbnNlbWJsZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGRlYWN0aXZhdGlvblByb21pc2VzID0gKGVuc2VtYmxlLm1ldGFkYXRhLmVsZW1lbnRzIHx8IFtdKS5tYXAoKGVsZW1lbnQpID0+XG4gICAgICB0aGlzLmRlYWN0aXZhdGVNZW1iZXIoZWxlbWVudClcbiAgICApO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKGRlYWN0aXZhdGlvblByb21pc2VzKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZGVhY3RpdmF0ZU1lbWJlcihlbGVtZW50OiBFbnNlbWJsZUVsZW1lbnQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBub3JtYWxpemVkVHlwZSA9IGVsZW1lbnQuZWxlbWVudF90eXBlLnRvTG93ZXJDYXNlKCk7XG5cbiAgICBzd2l0Y2ggKG5vcm1hbGl6ZWRUeXBlKSB7XG4gICAgICBjYXNlICdza2lsbCc6XG4gICAgICBjYXNlICdza2lsbHMnOlxuICAgICAgICBhd2FpdCB0aGlzLnNraWxsTWFuYWdlci5kZWFjdGl2YXRlU2tpbGwoZWxlbWVudC5lbGVtZW50X25hbWUpO1xuICAgICAgICByZXR1cm47XG4gICAgICBjYXNlICdwZXJzb25hJzpcbiAgICAgIGNhc2UgJ3BlcnNvbmFzJzpcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5yZXNvbHZlKHRoaXMucGVyc29uYU1hbmFnZXIuZGVhY3RpdmF0ZVBlcnNvbmEoZWxlbWVudC5lbGVtZW50X25hbWUpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgY2FzZSAnYWdlbnQnOlxuICAgICAgY2FzZSAnYWdlbnRzJzpcbiAgICAgICAgYXdhaXQgdGhpcy5hZ2VudE1hbmFnZXIuZGVhY3RpdmF0ZUFnZW50KGVsZW1lbnQuZWxlbWVudF9uYW1lKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgY2FzZSAnbWVtb3J5JzpcbiAgICAgIGNhc2UgJ21lbW9yaWVzJzpcbiAgICAgICAgYXdhaXQgdGhpcy5tZW1vcnlNYW5hZ2VyLmRlYWN0aXZhdGVNZW1vcnkoZWxlbWVudC5lbGVtZW50X25hbWUpO1xuICAgICAgICByZXR1cm47XG4gICAgICBjYXNlICdlbnNlbWJsZSc6XG4gICAgICBjYXNlICdlbnNlbWJsZXMnOlxuICAgICAgICBhd2FpdCB0aGlzLmVuc2VtYmxlTWFuYWdlci5kZWFjdGl2YXRlRW5zZW1ibGUoZWxlbWVudC5lbGVtZW50X25hbWUpO1xuICAgICAgICByZXR1cm47XG4gICAgICBjYXNlICd0ZW1wbGF0ZSc6XG4gICAgICBjYXNlICd0ZW1wbGF0ZXMnOlxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIGFjdGl2ZSBlbnNlbWJsZXNcbiAgICogTk9URTogVGhpcyB3YXMgbWlzc2luZyBpbiB0aGUgb3JpZ2luYWwgaW1wbGVtZW50YXRpb24gLSBhZGRpbmcgYmFzaWMgdmVyc2lvblxuICAgKi9cbiAgYXN5bmMgZ2V0QWN0aXZlRWxlbWVudHMoKTogUHJvbWlzZTxNQ1BSZXNwb25zZT4ge1xuICAgIGNvbnN0IGFjdGl2ZUVuc2VtYmxlcyA9IGF3YWl0IHRoaXMuZW5zZW1ibGVNYW5hZ2VyLmdldEFjdGl2ZUVuc2VtYmxlcygpO1xuXG4gICAgaWYgKGFjdGl2ZUVuc2VtYmxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgICAgdGV4dDogXCLwn46tIE5vIGFjdGl2ZSBlbnNlbWJsZXNcIlxuICAgICAgICB9XVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBlbnNlbWJsZUxpc3QgPSBhY3RpdmVFbnNlbWJsZXMubWFwKGUgPT4ge1xuICAgICAgY29uc3QgZWxlbWVudENvdW50ID0gZS5tZXRhZGF0YS5lbGVtZW50cz8ubGVuZ3RoIHx8IDA7XG4gICAgICByZXR1cm4gYPCfjq0gJHtlLm1ldGFkYXRhLm5hbWV9ICgke2VsZW1lbnRDb3VudH0gZWxlbWVudHMpYDtcbiAgICB9KS5qb2luKCdcXG4nKTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb250ZW50OiBbe1xuICAgICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgICAgdGV4dDogYEFjdGl2ZSBlbnNlbWJsZXM6XFxuJHtlbnNlbWJsZUxpc3R9YFxuICAgICAgfV1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCBhbiBlbnNlbWJsZVxuICAgKiBFeHRyYWN0ZWQgZnJvbSBFbGVtZW50Q1JVREhhbmRsZXIudHMgbGluZXMgODA3LTg0NlxuICAgKi9cbiAgYXN5bmMgZ2V0RWxlbWVudERldGFpbHMobmFtZTogc3RyaW5nKTogUHJvbWlzZTxNQ1BSZXNwb25zZT4ge1xuICAgIC8vIFVzZSBmbGV4aWJsZSBmaW5kaW5nIHRvIHN1cHBvcnQgYm90aCBkaXNwbGF5IG5hbWUgYW5kIGZpbGVuYW1lXG4gICAgY29uc3QgYWxsRW5zZW1ibGVzID0gYXdhaXQgdGhpcy5lbnNlbWJsZU1hbmFnZXIubGlzdCgpO1xuICAgIGNvbnN0IGVuc2VtYmxlID0gYXdhaXQgdGhpcy5maW5kRWxlbWVudEZsZXhpYmx5KG5hbWUsIGFsbEVuc2VtYmxlcyk7XG4gICAgaWYgKCFlbnNlbWJsZSkge1xuICAgICAgdGhpcy50aHJvd05vdEZvdW5kRXJyb3IobmFtZSwgJ0Vuc2VtYmxlJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudHNMaXN0ID0gZW5zZW1ibGUubWV0YWRhdGEuZWxlbWVudHM/Lm1hcCgoZWxlbTogYW55KSA9PlxuICAgICAgYC0gJHtlbGVtLmVsZW1lbnRfbmFtZX0gKCR7ZWxlbS5lbGVtZW50X3R5cGV9KSAtICR7ZWxlbS5yb2xlfSwgcHJpb3JpdHk6ICR7ZWxlbS5wcmlvcml0eX0sIGFjdGl2YXRpb246ICR7ZWxlbS5hY3RpdmF0aW9ufWBcbiAgICApLmpvaW4oJ1xcbicpIHx8ICdObyBlbGVtZW50cyBjb25maWd1cmVkJztcblxuICAgIGNvbnN0IGRldGFpbHMgPSBbXG4gICAgICBg8J+OrSAqKiR7ZW5zZW1ibGUubWV0YWRhdGEubmFtZX0qKmAsXG4gICAgICBgJHtlbnNlbWJsZS5tZXRhZGF0YS5kZXNjcmlwdGlvbn1gLFxuICAgICAgYGAsXG4gICAgICBgKipTdGF0dXMqKjogJHtlbnNlbWJsZS5nZXRTdGF0dXMoKX1gLFxuICAgICAgYCoqVmVyc2lvbioqOiAke2Vuc2VtYmxlLm1ldGFkYXRhLnZlcnNpb24gfHwgJzEuMC4wJ31gLFxuICAgICAgYCoqQWN0aXZhdGlvbiBTdHJhdGVneSoqOiAkeyhlbnNlbWJsZS5tZXRhZGF0YSBhcyBhbnkpLmFjdGl2YXRpb25TdHJhdGVneSB8fCAnc2VxdWVudGlhbCd9YCxcbiAgICAgIGAqKkNvbmZsaWN0IFJlc29sdXRpb24qKjogJHsoZW5zZW1ibGUubWV0YWRhdGEgYXMgYW55KS5jb25mbGljdFJlc29sdXRpb24gfHwgJ2xhc3Qtd3JpdGUnfWAsXG4gICAgICBgKipDb250ZXh0IFNoYXJpbmcqKjogJHsoZW5zZW1ibGUubWV0YWRhdGEgYXMgYW55KS5jb250ZXh0U2hhcmluZyB8fCAnc2VsZWN0aXZlJ31gLFxuICAgICAgYCoqQWxsb3dzIE5lc3RpbmcqKjogJHsoZW5zZW1ibGUubWV0YWRhdGEgYXMgYW55KS5hbGxvd05lc3RlZCA/ICdZZXMnIDogJ05vJ31gLFxuICAgICAgYCoqTWF4IE5lc3RpbmcgRGVwdGgqKjogJHsoZW5zZW1ibGUubWV0YWRhdGEgYXMgYW55KS5tYXhOZXN0aW5nRGVwdGggfHwgNX1gLFxuICAgICAgYGAsXG4gICAgICBgKipFbGVtZW50cyoqICgke2Vuc2VtYmxlLm1ldGFkYXRhLmVsZW1lbnRzPy5sZW5ndGggfHwgMH0pOmAsXG4gICAgICBlbGVtZW50c0xpc3RcbiAgICBdO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IFt7XG4gICAgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICAgICB0ZXh0OiBkZXRhaWxzLmpvaW4oJ1xcbicpXG4gICAgICB9XVxuICAgIH07XG4gIH1cbn1cbiJdfQ==