@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.
244 lines • 35.2 kB
JavaScript
/**
* Element Display Formatter Utility
*
* Provides consistent formatting for element display output across the codebase.
* Extracted from listElements.ts to eliminate duplication between query and legacy paths.
*
* This utility produces character-for-character identical output to the original
* formatting logic to ensure backward compatibility.
*
* Note: This is separate from ElementFormatter.ts which handles file formatting/cleaning.
*/
import { ElementType } from '../portfolio/PortfolioManager.js';
import { UnicodeValidator } from '../security/validators/unicodeValidator.js';
/** Default values for element formatting */
const DEFAULTS = {
VERSION: '1.0.0',
VERSION_SHORT: '1.0',
AUTHOR: 'Unknown',
CATEGORY: 'general',
PRICE: 'free',
COMPLEXITY: 'beginner',
DOMAINS: 'general',
RETENTION: 'permanent',
STRATEGY: 'sequential',
DESCRIPTION: 'No description provided.',
TRIGGERS: 'None',
TAGS: 'none',
VARIABLES: 'none',
SPECIALIZATIONS: 'general',
STATUS: 'unknown',
};
/**
* Static utility class for formatting element display output
*/
export class ElementDisplayFormatter {
/**
* Normalize a string value using Unicode validation
* Protects against homograph attacks and other Unicode-based exploits
*
* @param value The string to normalize
* @returns Normalized string, or empty string if value is undefined
*/
static normalize(value) {
if (!value)
return '';
const result = UnicodeValidator.normalize(value);
return result.normalizedContent;
}
/**
* Format a single element for display based on its type
*
* @param element The element to format
* @param type The element type
* @param config Optional configuration (e.g., active persona ID)
* @returns Formatted string representation of the element
*/
static formatElement(element, type, config) {
switch (type) {
case ElementType.PERSONA:
return this.formatPersona(element, config?.activePersonaId ?? null);
case ElementType.SKILL:
return this.formatSkill(element);
case ElementType.TEMPLATE:
return this.formatTemplate(element);
case ElementType.AGENT:
return this.formatAgent(element);
case ElementType.MEMORY:
return this.formatMemory(element);
case ElementType.ENSEMBLE:
return this.formatEnsemble(element);
default:
return `• ${this.normalize(element.metadata?.name) || 'Unknown'} - ${this.normalize(element.metadata?.description) || 'No description'}`;
}
}
/**
* Format multiple elements for display
*
* @param elements The elements to format
* @param type The element type
* @param config Optional configuration (e.g., active persona ID)
* @returns Formatted string with all elements separated by double newlines
*/
static formatElements(elements, type, config) {
return elements
.map((element) => this.formatElement(element, type, config))
.join('\n\n');
}
/**
* Format a persona element for display
*
* @param element The persona element to format
* @param activePersonaId The currently active persona ID (filename)
* @returns Formatted string representation
*
* @example
* // Returns:
* // 🔹 **Creative Writer** (creative-writer)
* // A creative writing assistant
* // 📁 creative | 🎭 John Doe | 🔖 premium
* // Version: 2.0 | Triggers: write, story, creative
*
* Output format:
* 🔹/▫️ **Name** (unique_id)
* Description
* 📁 category | 🎭 author | 🔖 price
* Version: version | Triggers: triggers
*/
static formatPersona(element, activePersonaId) {
const isActive = element.filename === activePersonaId;
const price = this.normalize(element.metadata.price) || DEFAULTS.PRICE;
const author = this.normalize(element.metadata.author) || DEFAULTS.AUTHOR;
const category = this.normalize(element.metadata.category) || DEFAULTS.CATEGORY;
const version = this.normalize(element.metadata.version) || DEFAULTS.VERSION_SHORT;
const triggers = element.metadata.triggers?.map(t => this.normalize(t)).join(', ') || DEFAULTS.TRIGGERS;
const description = this.normalize(element.metadata.description) || DEFAULTS.DESCRIPTION;
const name = this.normalize(element.metadata.name);
const uniqueId = this.normalize(element.unique_id);
return (`${isActive ? '🔹' : '▫️'} **${name}** (${uniqueId})\n` +
` ${description}\n` +
` 📁 ${category} | 🎭 ${author} | 🔖 ${price}\n` +
` Version: ${version} | Triggers: ${triggers}`);
}
/**
* Format a skill element for display
*
* @param element The skill element to format
* @returns Formatted string representation
*
* @example
* // Returns:
* // 🛠️ Code Review (v3.2.1) - Reviews code for quality
* // Complexity: intermediate | Domains: code, quality, review
*
* Output format:
* 🛠️ Name (vVersion) - Description
* Complexity: complexity | Domains: domains
*/
static formatSkill(element) {
const complexity = this.normalize(element.metadata.complexity) || DEFAULTS.COMPLEXITY;
const domains = element.metadata.domains?.map(d => this.normalize(d)).join(', ') || DEFAULTS.DOMAINS;
const version = this.normalize(element.version) || this.normalize(element.metadata.version) || DEFAULTS.VERSION;
const name = this.normalize(element.metadata.name);
const description = this.normalize(element.metadata.description);
return (`🛠️ ${name} (v${version}) - ${description}\n` +
` Complexity: ${complexity} | Domains: ${domains}`);
}
/**
* Format a template element for display
*
* @param element The template element to format
* @returns Formatted string representation
*
* @example
* // Returns:
* // 📄 Meeting Notes (v1.2.0) - Template for meeting notes
* // Variables: title, date, attendees
*
* Output format:
* 📄 Name (vVersion) - Description
* Variables: variables
*/
static formatTemplate(element) {
const variables = element.metadata.variables?.map((v) => this.normalize(v.name)).join(', ') || DEFAULTS.VARIABLES;
const version = this.normalize(element.version) || this.normalize(element.metadata.version) || DEFAULTS.VERSION;
const name = this.normalize(element.metadata.name);
const description = this.normalize(element.metadata.description);
return (`📄 ${name} (v${version}) - ${description}\n` +
` Variables: ${variables}`);
}
/**
* Format an agent element for display
*
* @param element The agent element to format
* @returns Formatted string representation
*
* @example
* // Returns:
* // 🤖 Task Manager (v2.1.0) - Manages tasks automatically
* // Status: active | Specializations: planning, execution, monitoring
*
* Output format:
* 🤖 Name (vVersion) - Description
* Status: status | Specializations: specializations
*/
static formatAgent(element) {
const specializations = element.metadata.specializations?.map(s => this.normalize(s)).join(', ') || DEFAULTS.SPECIALIZATIONS;
// getStatus() returns ElementStatus enum, convert to string
const status = element.getStatus ? element.getStatus().toString() : DEFAULTS.STATUS;
const version = this.normalize(element.version) || this.normalize(element.metadata.version) || DEFAULTS.VERSION;
const name = this.normalize(element.metadata.name);
const description = this.normalize(element.metadata.description);
return (`🤖 ${name} (v${version}) - ${description}\n` +
` Status: ${status} | Specializations: ${specializations}`);
}
/**
* Format a memory element for display
*
* @param element The memory element to format
* @returns Formatted string representation
*
* @example
* // Returns:
* // 🧠 Project Context (v1.1.0) - Context about the current project
* // Retention: 90 days | Tags: project, context, important
*
* Output format:
* 🧠 Name (vVersion) - Description
* Retention: retentionDays days | Tags: tags
*/
static formatMemory(element) {
const retentionDays = element.metadata.retentionDays?.toString() || DEFAULTS.RETENTION;
const tags = element.metadata.tags?.map(t => this.normalize(t)).join(', ') || DEFAULTS.TAGS;
const version = this.normalize(element.version) || this.normalize(element.metadata.version) || DEFAULTS.VERSION;
const name = this.normalize(element.metadata.name);
const description = this.normalize(element.metadata.description);
return (`🧠 ${name} (v${version}) - ${description}\n` +
` Retention: ${retentionDays} days | Tags: ${tags}`);
}
/**
* Format an ensemble element for display
*
* @param element The ensemble element to format
* @returns Formatted string representation
*
* @example
* // Returns:
* // 🎭 Research Team (v1.0.0) - Coordinated research workflow
* // Elements: 3 | Strategy: parallel
*
* Output format:
* 🎭 Name (vVersion) - Description
* Elements: elementCount | Strategy: strategy
*/
static formatEnsemble(element) {
const elementCount = element.metadata.elements?.length || 0;
const strategy = this.normalize(element.metadata.activationStrategy) || DEFAULTS.STRATEGY;
const version = this.normalize(element.version) || this.normalize(element.metadata.version) || DEFAULTS.VERSION;
const name = this.normalize(element.metadata.name);
const description = this.normalize(element.metadata.description);
return (`🎭 ${name} (v${version}) - ${description}\n` +
` Elements: ${elementCount} | Strategy: ${strategy}`);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRWxlbWVudERpc3BsYXlGb3JtYXR0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvRWxlbWVudERpc3BsYXlGb3JtYXR0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7R0FVRztBQUVILE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUUvRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUU5RSw0Q0FBNEM7QUFDNUMsTUFBTSxRQUFRLEdBQUc7SUFDZixPQUFPLEVBQUUsT0FBTztJQUNoQixhQUFhLEVBQUUsS0FBSztJQUNwQixNQUFNLEVBQUUsU0FBUztJQUNqQixRQUFRLEVBQUUsU0FBUztJQUNuQixLQUFLLEVBQUUsTUFBTTtJQUNiLFVBQVUsRUFBRSxVQUFVO0lBQ3RCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLFNBQVMsRUFBRSxXQUFXO0lBQ3RCLFFBQVEsRUFBRSxZQUFZO0lBQ3RCLFdBQVcsRUFBRSwwQkFBMEI7SUFDdkMsUUFBUSxFQUFFLE1BQU07SUFDaEIsSUFBSSxFQUFFLE1BQU07SUFDWixTQUFTLEVBQUUsTUFBTTtJQUNqQixlQUFlLEVBQUUsU0FBUztJQUMxQixNQUFNLEVBQUUsU0FBUztDQUNULENBQUM7QUF5RVg7O0dBRUc7QUFDSCxNQUFNLE9BQU8sdUJBQXVCO0lBQ2xDOzs7Ozs7T0FNRztJQUNLLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBeUI7UUFDaEQsSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFPLEVBQUUsQ0FBQztRQUN0QixNQUFNLE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakQsT0FBTyxNQUFNLENBQUMsaUJBQWlCLENBQUM7SUFDbEMsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxNQUFNLENBQUMsYUFBYSxDQUNsQixPQUFpQixFQUNqQixJQUFpQixFQUNqQixN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LFlBQVksZ0JBQWdCLFFBQVEsRUFBRSxDQUN2RCxDQUFDO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBFbGVtZW50IERpc3BsYXkgRm9ybWF0dGVyIFV0aWxpdHlcbiAqXG4gKiBQcm92aWRlcyBjb25zaXN0ZW50IGZvcm1hdHRpbmcgZm9yIGVsZW1lbnQgZGlzcGxheSBvdXRwdXQgYWNyb3NzIHRoZSBjb2RlYmFzZS5cbiAqIEV4dHJhY3RlZCBmcm9tIGxpc3RFbGVtZW50cy50cyB0byBlbGltaW5hdGUgZHVwbGljYXRpb24gYmV0d2VlbiBxdWVyeSBhbmQgbGVnYWN5IHBhdGhzLlxuICpcbiAqIFRoaXMgdXRpbGl0eSBwcm9kdWNlcyBjaGFyYWN0ZXItZm9yLWNoYXJhY3RlciBpZGVudGljYWwgb3V0cHV0IHRvIHRoZSBvcmlnaW5hbFxuICogZm9ybWF0dGluZyBsb2dpYyB0byBlbnN1cmUgYmFja3dhcmQgY29tcGF0aWJpbGl0eS5cbiAqXG4gKiBOb3RlOiBUaGlzIGlzIHNlcGFyYXRlIGZyb20gRWxlbWVudEZvcm1hdHRlci50cyB3aGljaCBoYW5kbGVzIGZpbGUgZm9ybWF0dGluZy9jbGVhbmluZy5cbiAqL1xuXG5pbXBvcnQgeyBFbGVtZW50VHlwZSB9IGZyb20gJy4uL3BvcnRmb2xpby9Qb3J0Zm9saW9NYW5hZ2VyLmpzJztcbmltcG9ydCB7IElFbGVtZW50IH0gZnJvbSAnLi4vdHlwZXMvZWxlbWVudHMvSUVsZW1lbnQuanMnO1xuaW1wb3J0IHsgVW5pY29kZVZhbGlkYXRvciB9IGZyb20gJy4uL3NlY3VyaXR5L3ZhbGlkYXRvcnMvdW5pY29kZVZhbGlkYXRvci5qcyc7XG5cbi8qKiBEZWZhdWx0IHZhbHVlcyBmb3IgZWxlbWVudCBmb3JtYXR0aW5nICovXG5jb25zdCBERUZBVUxUUyA9IHtcbiAgVkVSU0lPTjogJzEuMC4wJyxcbiAgVkVSU0lPTl9TSE9SVDogJzEuMCcsXG4gIEFVVEhPUjogJ1Vua25vd24nLFxuICBDQVRFR09SWTogJ2dlbmVyYWwnLFxuICBQUklDRTogJ2ZyZWUnLFxuICBDT01QTEVYSVRZOiAnYmVnaW5uZXInLFxuICBET01BSU5TOiAnZ2VuZXJhbCcsXG4gIFJFVEVOVElPTjogJ3Blcm1hbmVudCcsXG4gIFNUUkFURUdZOiAnc2VxdWVudGlhbCcsXG4gIERFU0NSSVBUSU9OOiAnTm8gZGVzY3JpcHRpb24gcHJvdmlkZWQuJyxcbiAgVFJJR0dFUlM6ICdOb25lJyxcbiAgVEFHUzogJ25vbmUnLFxuICBWQVJJQUJMRVM6ICdub25lJyxcbiAgU1BFQ0lBTElaQVRJT05TOiAnZ2VuZXJhbCcsXG4gIFNUQVRVUzogJ3Vua25vd24nLFxufSBhcyBjb25zdDtcblxuLyoqXG4gKiBUeXBlZCBpbnRlcmZhY2UgZm9yIFBlcnNvbmEgZWxlbWVudHNcbiAqL1xuaW50ZXJmYWNlIFBlcnNvbmFFbGVtZW50IGV4dGVuZHMgSUVsZW1lbnQge1xuICBmaWxlbmFtZT86IHN0cmluZztcbiAgdW5pcXVlX2lkPzogc3RyaW5nO1xuICBtZXRhZGF0YTogSUVsZW1lbnRbJ21ldGFkYXRhJ10gJiB7XG4gICAgcHJpY2U/OiBzdHJpbmc7XG4gICAgY2F0ZWdvcnk/OiBzdHJpbmc7XG4gICAgdHJpZ2dlcnM/OiBzdHJpbmdbXTtcbiAgfTtcbn1cblxuLyoqXG4gKiBUeXBlZCBpbnRlcmZhY2UgZm9yIFNraWxsIGVsZW1lbnRzXG4gKi9cbmludGVyZmFjZSBTa2lsbEVsZW1lbnQgZXh0ZW5kcyBJRWxlbWVudCB7XG4gIG1ldGFkYXRhOiBJRWxlbWVudFsnbWV0YWRhdGEnXSAmIHtcbiAgICBjb21wbGV4aXR5Pzogc3RyaW5nO1xuICAgIGRvbWFpbnM/OiBzdHJpbmdbXTtcbiAgfTtcbn1cblxuLyoqXG4gKiBUeXBlZCBpbnRlcmZhY2UgZm9yIFRlbXBsYXRlIGVsZW1lbnRzXG4gKi9cbmludGVyZmFjZSBUZW1wbGF0ZUVsZW1lbnQgZXh0ZW5kcyBJRWxlbWVudCB7XG4gIG1ldGFkYXRhOiBJRWxlbWVudFsnbWV0YWRhdGEnXSAmIHtcbiAgICB2YXJpYWJsZXM/OiBBcnJheTx7IG5hbWU6IHN0cmluZzsgdHlwZT86IHN0cmluZzsgcmVxdWlyZWQ/OiBib29sZWFuIH0+O1xuICB9O1xufVxuXG4vKipcbiAqIFR5cGVkIGludGVyZmFjZSBmb3IgQWdlbnQgZWxlbWVudHNcbiAqL1xuaW50ZXJmYWNlIEFnZW50RWxlbWVudCBleHRlbmRzIElFbGVtZW50IHtcbiAgbWV0YWRhdGE6IElFbGVtZW50WydtZXRhZGF0YSddICYge1xuICAgIHNwZWNpYWxpemF0aW9ucz86IHN0cmluZ1tdO1xuICB9O1xufVxuXG4vKipcbiAqIFR5cGVkIGludGVyZmFjZSBmb3IgTWVtb3J5IGVsZW1lbnRzXG4gKi9cbmludGVyZmFjZSBNZW1vcnlFbGVtZW50IGV4dGVuZHMgSUVsZW1lbnQge1xuICBtZXRhZGF0YTogSUVsZW1lbnRbJ21ldGFkYXRhJ10gJiB7XG4gICAgcmV0ZW50aW9uRGF5cz86IG51bWJlciB8IHN0cmluZztcbiAgfTtcbn1cblxuLyoqXG4gKiBUeXBlZCBpbnRlcmZhY2UgZm9yIEVuc2VtYmxlIGVsZW1lbnRzXG4gKi9cbmludGVyZmFjZSBFbnNlbWJsZUVsZW1lbnQgZXh0ZW5kcyBJRWxlbWVudCB7XG4gIG1ldGFkYXRhOiBJRWxlbWVudFsnbWV0YWRhdGEnXSAmIHtcbiAgICBlbGVtZW50cz86IHN0cmluZ1tdO1xuICAgIGFjdGl2YXRpb25TdHJhdGVneT86IHN0cmluZztcbiAgfTtcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciBlbGVtZW50IGRpc3BsYXkgZm9ybWF0dGluZ1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEVsZW1lbnREaXNwbGF5Rm9ybWF0dGVyQ29uZmlnIHtcbiAgLyoqXG4gICAqIFRoZSBjdXJyZW50bHkgYWN0aXZlIHBlcnNvbmEgSUQgKGZpbGVuYW1lKSwgdXNlZCB0byBkaXNwbGF5IGFjdGl2ZSBpbmRpY2F0b3JcbiAgICogT25seSByZWxldmFudCBmb3IgcGVyc29uYSBmb3JtYXR0aW5nXG4gICAqL1xuICBhY3RpdmVQZXJzb25hSWQ/OiBzdHJpbmcgfCBudWxsO1xufVxuXG4vKipcbiAqIFN0YXRpYyB1dGlsaXR5IGNsYXNzIGZvciBmb3JtYXR0aW5nIGVsZW1lbnQgZGlzcGxheSBvdXRwdXRcbiAqL1xuZXhwb3J0IGNsYXNzIEVsZW1lbnREaXNwbGF5Rm9ybWF0dGVyIHtcbiAgLyoqXG4gICAqIE5vcm1hbGl6ZSBhIHN0cmluZyB2YWx1ZSB1c2luZyBVbmljb2RlIHZhbGlkYXRpb25cbiAgICogUHJvdGVjdHMgYWdhaW5zdCBob21vZ3JhcGggYXR0YWNrcyBhbmQgb3RoZXIgVW5pY29kZS1iYXNlZCBleHBsb2l0c1xuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cmluZyB0byBub3JtYWxpemVcbiAgICogQHJldHVybnMgTm9ybWFsaXplZCBzdHJpbmcsIG9yIGVtcHR5IHN0cmluZyBpZiB2YWx1ZSBpcyB1bmRlZmluZWRcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIG5vcm1hbGl6ZSh2YWx1ZTogc3RyaW5nIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcbiAgICBpZiAoIXZhbHVlKSByZXR1cm4gJyc7XG4gICAgY29uc3QgcmVzdWx0ID0gVW5pY29kZVZhbGlkYXRvci5ub3JtYWxpemUodmFsdWUpO1xuICAgIHJldHVybiByZXN1bHQubm9ybWFsaXplZENvbnRlbnQ7XG4gIH1cblxuICAvKipcbiAgICogRm9ybWF0IGEgc2luZ2xlIGVsZW1lbnQgZm9yIGRpc3BsYXkgYmFzZWQgb24gaXRzIHR5cGVcbiAgICpcbiAgICogQHBhcmFtIGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gZm9ybWF0XG4gICAqIEBwYXJhbSB0eXBlIFRoZSBlbGVtZW50IHR5cGVcbiAgICogQHBhcmFtIGNvbmZpZyBPcHRpb25hbCBjb25maWd1cmF0aW9uIChlLmcuLCBhY3RpdmUgcGVyc29uYSBJRClcbiAgICogQHJldHVybnMgRm9ybWF0dGVkIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZWxlbWVudFxuICAgKi9cbiAgc3RhdGljIGZvcm1hdEVsZW1lbnQoXG4gICAgZWxlbWVudDogSUVsZW1lbnQsXG4gICAgdHlwZTogRWxlbWVudFR5cGUsXG4gICAgY29uZmlnPzogRWxlbWVudERpc3BsYXlGb3JtYXR0ZXJDb25maWdcbiAgKTogc3RyaW5nIHtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgRWxlbWVudFR5cGUuUEVSU09OQTpcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0UGVyc29uYShlbGVtZW50IGFzIFBlcnNvbmFFbGVtZW50LCBjb25maWc/LmFjdGl2ZVBlcnNvbmFJZCA/PyBudWxsKTtcblxuICAgICAgY2FzZSBFbGVtZW50VHlwZS5TS0lMTDpcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0U2tpbGwoZWxlbWVudCBhcyBTa2lsbEVsZW1lbnQpO1xuXG4gICAgICBjYXNlIEVsZW1lbnRUeXBlLlRFTVBMQVRFOlxuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRUZW1wbGF0ZShlbGVtZW50IGFzIFRlbXBsYXRlRWxlbWVudCk7XG5cbiAgICAgIGNhc2UgRWxlbWVudFR5cGUuQUdFTlQ6XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1hdEFnZW50KGVsZW1lbnQgYXMgQWdlbnRFbGVtZW50KTtcblxuICAgICAgY2FzZSBFbGVtZW50VHlwZS5NRU1PUlk6XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1hdE1lbW9yeShlbGVtZW50IGFzIE1lbW9yeUVsZW1lbnQpO1xuXG4gICAgICBjYXNlIEVsZW1lbnRUeXBlLkVOU0VNQkxFOlxuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRFbnNlbWJsZShlbGVtZW50IGFzIEVuc2VtYmxlRWxlbWVudCk7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBg4oCiICR7dGhpcy5ub3JtYWxpemUoZWxlbWVudC5tZXRhZGF0YT8ubmFtZSkgfHwgJ1Vua25vd24nfSAtICR7dGhpcy5ub3JtYWxpemUoZWxlbWVudC5tZXRhZGF0YT8uZGVzY3JpcHRpb24pIHx8ICdObyBkZXNjcmlwdGlvbid9YDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRm9ybWF0IG11bHRpcGxlIGVsZW1lbnRzIGZvciBkaXNwbGF5XG4gICAqXG4gICAqIEBwYXJhbSBlbGVtZW50cyBUaGUgZWxlbWVudHMgdG8gZm9ybWF0XG4gICAqIEBwYXJhbSB0eXBlIFRoZSBlbGVtZW50IHR5cGVcbiAgICogQHBhcmFtIGNvbmZpZyBPcHRpb25hbCBjb25maWd1cmF0aW9uIChlLmcuLCBhY3RpdmUgcGVyc29uYSBJRClcbiAgICogQHJldHVybnMgRm9ybWF0dGVkIHN0cmluZyB3aXRoIGFsbCBlbGVtZW50cyBzZXBhcmF0ZWQgYnkgZG91YmxlIG5ld2xpbmVzXG4gICAqL1xuICBzdGF0aWMgZm9ybWF0RWxlbWVudHMoXG4gICAgZWxlbWVudHM6IElFbGVtZW50W10sXG4gICAgdHlwZTogRWxlbWVudFR5cGUsXG4gICAgY29uZmlnPzogRWxlbWVudERpc3BsYXlGb3JtYXR0ZXJDb25maWdcbiAgKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZWxlbWVudHNcbiAgICAgIC5tYXAoKGVsZW1lbnQpID0+IHRoaXMuZm9ybWF0RWxlbWVudChlbGVtZW50LCB0eXBlLCBjb25maWcpKVxuICAgICAgLmpvaW4oJ1xcblxcbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdCBhIHBlcnNvbmEgZWxlbWVudCBmb3IgZGlzcGxheVxuICAgKlxuICAgKiBAcGFyYW0gZWxlbWVudCBUaGUgcGVyc29uYSBlbGVtZW50IHRvIGZvcm1hdFxuICAgKiBAcGFyYW0gYWN0aXZlUGVyc29uYUlkIFRoZSBjdXJyZW50bHkgYWN0aXZlIHBlcnNvbmEgSUQgKGZpbGVuYW1lKVxuICAgKiBAcmV0dXJucyBGb3JtYXR0ZWQgc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIFJldHVybnM6XG4gICAqIC8vIPCflLkgKipDcmVhdGl2ZSBXcml0ZXIqKiAoY3JlYXRpdmUtd3JpdGVyKVxuICAgKiAvLyAgICBBIGNyZWF0aXZlIHdyaXRpbmcgYXNzaXN0YW50XG4gICAqIC8vICAgIPCfk4EgY3JlYXRpdmUgfCDwn46tIEpvaG4gRG9lIHwg8J+UliBwcmVtaXVtXG4gICAqIC8vICAgIFZlcnNpb246IDIuMCB8IFRyaWdnZXJzOiB3cml0ZSwgc3RvcnksIGNyZWF0aXZlXG4gICAqXG4gICAqIE91dHB1dCBmb3JtYXQ6XG4gICAqIPCflLkv4par77iPICoqTmFtZSoqICh1bmlxdWVfaWQpXG4gICAqICAgIERlc2NyaXB0aW9uXG4gICAqICAgIPCfk4EgY2F0ZWdvcnkgfCDwn46tIGF1dGhvciB8IPCflJYgcHJpY2VcbiAgICogICAgVmVyc2lvbjogdmVyc2lvbiB8IFRyaWdnZXJzOiB0cmlnZ2Vyc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZm9ybWF0UGVyc29uYShlbGVtZW50OiBQZXJzb25hRWxlbWVudCwgYWN0aXZlUGVyc29uYUlkOiBzdHJpbmcgfCBudWxsKTogc3RyaW5nIHtcbiAgICBjb25zdCBpc0FjdGl2ZSA9IGVsZW1lbnQuZmlsZW5hbWUgPT09IGFjdGl2ZVBlcnNvbmFJZDtcbiAgICBjb25zdCBwcmljZSA9IHRoaXMubm9ybWFsaXplKGVsZW1lbnQubWV0YWRhdGEucHJpY2UpIHx8IERFRkFVTFRTLlBSSUNFO1xuICAgIGNvbnN0IGF1dGhvciA9IHRoaXMubm9ybWFsaXplKGVsZW1lbnQubWV0YWRhdGEuYXV0aG9yKSB8fCBERUZBVUxUUy5BVVRIT1I7XG4gICAgY29uc3QgY2F0ZWdvcnkgPSB0aGlzLm5vcm1hbGl6ZShlbGVtZW50Lm1ldGFkYXRhLmNhdGVnb3J5KSB8fCBERUZBVUxUUy5DQVRFR09SWTtcbiAgICBjb25zdCB2ZXJzaW9uID0gdGhpcy5ub3JtYWxpemUoZWxlbWVudC5tZXRhZGF0YS52ZXJzaW9uKSB8fCBERUZBVUxUUy5WRVJTSU9OX1NIT1JUO1xuICAgIGNvbnN0IHRyaWdnZXJzID0gZWxlbWVudC5tZXRhZGF0YS50cmlnZ2Vycz8ubWFwKHQgPT4gdGhpcy5ub3JtYWxpemUodCkpLmpvaW4oJywgJykgfHwgREVGQVVMVFMuVFJJR0dFUlM7XG4gICAgY29uc3QgZGVzY3JpcHRpb24gPSB0aGlzLm5vcm1hbGl6ZShlbGVtZW50Lm1ldGFkYXRhLmRlc2NyaXB0aW9uKSB8fCBERUZBVUxUUy5ERVNDUklQVElPTjtcbiAgICBjb25zdCBuYW1lID0gdGhpcy5ub3JtYWxpemUoZWxlbWVudC5tZXRhZGF0YS5uYW1lKTtcbiAgICBjb25zdCB1bmlxdWVJZCA9IHRoaXMubm9ybWFsaXplKGVsZW1lbnQudW5pcXVlX2lkKTtcblxuICAgIHJldHVybiAoXG4gICAgICBgJHtpc0FjdGl2ZSA/ICfwn5S5JyA6ICfilqvvuI8nfSAqKiR7bmFtZX0qKiAoJHt1bmlxdWVJZH0pXFxuYCArXG4gICAgICBgICAgJHtkZXNjcmlwdGlvbn1cXG5gICtcbiAgICAgIGAgICDwn5OBICR7Y2F0ZWdvcnl9IHwg8J+OrSAke2F1dGhvcn0gfCDwn5SWICR7cHJpY2V9XFxuYCArXG4gICAgICBgICAgVmVyc2lvbjogJHt2ZXJzaW9ufSB8IFRyaWdnZXJzOiAke3RyaWdnZXJzfWBcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdCBhIHNraWxsIGVsZW1lbnQgZm9yIGRpc3BsYXlcbiAgICpcbiAgICogQHBhcmFtIGVsZW1lbnQgVGhlIHNraWxsIGVsZW1lbnQgdG8gZm9ybWF0XG4gICAqIEByZXR1cm5zIEZvcm1hdHRlZCBzdHJpbmcgcmVwcmVzZW50YXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogLy8gUmV0dXJuczpcbiAgICogLy8g8J+boO+4jyBDb2RlIFJldmlldyAodjMuMi4xKSAtIFJldmlld3MgY29kZSBmb3IgcXVhbGl0eVxuICAgKiAvLyAgICBDb21wbGV4aXR5OiBpbnRlcm1lZGlhdGUgfCBEb21haW5zOiBjb2RlLCBxdWFsaXR5LCByZXZpZXdcbiAgICpcbiAgICogT3V0cHV0IGZvcm1hdDpcbiAgICog8J+boO+4jyBOYW1lICh2VmVyc2lvbikgLSBEZXNjcmlwdGlvblxuICAgKiAgICBDb21wbGV4aXR5OiBjb21wbGV4aXR5IHwgRG9tYWluczogZG9tYWluc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZm9ybWF0U2tpbGwoZWxlbWVudDogU2tpbGxFbGVtZW50KTogc3RyaW5nIHtcbiAgICBjb25zdCBjb21wbGV4aXR5ID0gdGhpcy5ub3JtYWxpemUoZWxlbWVudC5tZXRhZGF0YS5jb21wbGV4aXR5KSB8fCBERUZBVUxUUy5DT01QTEVYSVRZO1xuICAgIGNvbnN0IGRvbWFpbnMgPSBlbGVtZW50Lm1ldGFkYXRhLmRvbWFpbnM/Lm1hcChkID0+IHRoaXMubm9ybWFsaXplKGQpKS5qb2luKCcsICcpIHx8IERFRkFVTFRTLkRPTUFJTlM7XG4gICAgY29uc3QgdmVyc2lvbiA9IHRoaXMubm9ybWFsaXplKGVsZW1lbnQudmVyc2lvbikgfHwgdGhpcy5ub3JtYWxpemUoZWxlbWVudC5tZXRhZGF0YS52ZXJzaW9uKSB8fCBERUZBVUxUUy5WRVJTSU9OO1xuICAgIGNvbnN0IG5hbWUgPSB0aGlzLm5vcm1hbGl6ZShlbGVtZW50Lm1ldGFkYXRhLm5hbWUpO1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gdGhpcy5ub3JtYWxpemUoZWxlbWVudC5tZXRhZGF0YS5kZXNjcmlwdGlvbik7XG5cbiAgICByZXR1cm4gKFxuICAgICAgYPCfm6DvuI8gJHtuYW1lfSAodiR7dmVyc2lvbn0pIC0gJHtkZXNjcmlwdGlvbn1cXG5gICtcbiAgICAgIGAgICBDb21wbGV4aXR5OiAke2NvbXBsZXhpdHl9IHwgRG9tYWluczogJHtkb21haW5zfWBcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdCBhIHRlbXBsYXRlIGVsZW1lbnQgZm9yIGRpc3BsYXlcbiAgICpcbiAgICogQHBhcmFtIGVsZW1lbnQgVGhlIHRlbXBsYXRlIGVsZW1lbnQgdG8gZm9ybWF0XG4gICAqIEByZXR1cm5zIEZvcm1hdHRlZCBzdHJpbmcgcmVwcmVzZW50YXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogLy8gUmV0dXJuczpcbiAgICogLy8g8J+ThCBNZWV0aW5nIE5vdGVzICh2MS4yLjApIC0gVGVtcGxhdGUgZm9yIG1lZXRpbmcgbm90ZXNcbiAgICogLy8gICAgVmFyaWFibGVzOiB0aXRsZSwgZGF0ZSwgYXR0ZW5kZWVzXG4gICAqXG4gICAqIE91dHB1dCBmb3JtYXQ6XG4gICAqIPCfk4QgTmFtZSAodlZlcnNpb24pIC0gRGVzY3JpcHRpb25cbiAgICogICAgVmFyaWFibGVzOiB2YXJpYWJsZXNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGZvcm1hdFRlbXBsYXRlKGVsZW1lbnQ6IFRlbXBsYXRlRWxlbWVudCk6IHN0cmluZyB7XG4gICAgY29uc3QgdmFyaWFibGVzID0gZWxlbWVudC5tZXRhZGF0YS52YXJpYWJsZXM/Lm1hcCgodikgPT4gdGhpcy5ub3JtYWxpemUodi5uYW1lKSkuam9pbignLCAnKSB8fCBERUZBVUxUUy5WQVJJQUJMRVM7XG4gICAgY29uc3QgdmVyc2lvbiA9IHRoaXMubm9ybWFsaXplKGVsZW1lbnQudmVyc2lvbikgfHwgdGhpcy5ub3JtYWxpemUoZWxlbWVudC5tZXRhZGF0YS52ZXJzaW9uKSB8fCBERUZBVUxUUy5WRVJTSU9OO1xuICAgIGNvbnN0IG5hbWUgPSB0aGlzLm5vcm1hbGl6ZShlbGVtZW50Lm1ldGFkYXRhLm5hbWUpO1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gdGhpcy5ub3JtYWxpemUoZWxlbWVudC5tZXRhZGF0YS5kZXNjcmlwdGlvbik7XG5cbiAgICByZXR1cm4gKFxuICAgICAgYPCfk4QgJHtuYW1lfSAodiR7dmVyc2lvbn0pIC0gJHtkZXNjcmlwdGlvbn1cXG5gICtcbiAgICAgIGAgICBWYXJpYWJsZXM6ICR7dmFyaWFibGVzfWBcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdCBhbiBhZ2VudCBlbGVtZW50IGZvciBkaXNwbGF5XG4gICAqXG4gICAqIEBwYXJhbSBlbGVtZW50IFRoZSBhZ2VudCBlbGVtZW50IHRvIGZvcm1hdFxuICAgKiBAcmV0dXJucyBGb3JtYXR0ZWQgc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIFJldHVybnM6XG4gICAqIC8vIPCfpJYgVGFzayBNYW5hZ2VyICh2Mi4xLjApIC0gTWFuYWdlcyB0YXNrcyBhdXRvbWF0aWNhbGx5XG4gICAqIC8vICAgIFN0YXR1czogYWN0aXZlIHwgU3BlY2lhbGl6YXRpb25zOiBwbGFubmluZywgZXhlY3V0aW9uLCBtb25pdG9yaW5nXG4gICAqXG4gICAqIE91dHB1dCBmb3JtYXQ6XG4gICAqIPCfpJYgTmFtZSAodlZlcnNpb24pIC0gRGVzY3JpcHRpb25cbiAgICogICAgU3RhdHVzOiBzdGF0dXMgfCBTcGVjaWFsaXphdGlvbnM6IHNwZWNpYWxpemF0aW9uc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZm9ybWF0QWdlbnQoZWxlbWVudDogQWdlbnRFbGVtZW50KTogc3RyaW5nIHtcbiAgICBjb25zdCBzcGVjaWFsaXphdGlvbnMgPSBlbGVtZW50Lm1ldGFkYXRhLnNwZWNpYWxpemF0aW9ucz8ubWFwKHMgPT4gdGhpcy5ub3JtYWxpemUocykpLmpvaW4oJywgJykgfHwgREVGQVVMVFMuU1BFQ0lBTElaQVRJT05TO1xuICAgIC8vIGdldFN0YXR1cygpIHJldHVybnMgRWxlbWVudFN0YXR1cyBlbnVtLCBjb252ZXJ0IHRvIHN0cmluZ1xuICAgIGNvbnN0IHN0YXR1cyA9IGVsZW1lbnQuZ2V0U3RhdHVzID8gZWxlbWVudC5nZXRTdGF0dXMoKS50b1N0cmluZygpIDogREVGQVVMVFMuU1RBVFVTO1xuICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLm5vcm1hbGl6ZShlbGVtZW50LnZlcnNpb24pIHx8IHRoaXMubm9ybWFsaXplKGVsZW1lbnQubWV0YWRhdGEudmVyc2lvbikgfHwgREVGQVVMVFMuVkVSU0lPTjtcbiAgICBjb25zdCBuYW1lID0gdGhpcy5ub3JtYWxpemUoZWxlbWVudC5tZXRhZGF0YS5uYW1lKTtcbiAgICBjb25zdCBkZXNjcmlwdGlvbiA9IHRoaXMubm9ybWFsaXplKGVsZW1lbnQubWV0YWRhdGEuZGVzY3JpcHRpb24pO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIGDwn6SWICR7bmFtZX0gKHYke3ZlcnNpb259KSAtICR7ZGVzY3JpcHRpb259XFxuYCArXG4gICAgICBgICAgU3RhdHVzOiAke3N0YXR1c30gfCBTcGVjaWFsaXphdGlvbnM6ICR7c3BlY2lhbGl6YXRpb25zfWBcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdCBhIG1lbW9yeSBlbGVtZW50IGZvciBkaXNwbGF5XG4gICAqXG4gICAqIEBwYXJhbSBlbGVtZW50IFRoZSBtZW1vcnkgZWxlbWVudCB0byBmb3JtYXRcbiAgICogQHJldHVybnMgRm9ybWF0dGVkIHN0cmluZyByZXByZXNlbnRhdGlvblxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBSZXR1cm5zOlxuICAgKiAvLyDwn6egIFByb2plY3QgQ29udGV4dCAodjEuMS4wKSAtIENvbnRleHQgYWJvdXQgdGhlIGN1cnJlbnQgcHJvamVjdFxuICAgKiAvLyAgICBSZXRlbnRpb246IDkwIGRheXMgfCBUYWdzOiBwcm9qZWN0LCBjb250ZXh0LCBpbXBvcnRhbnRcbiAgICpcbiAgICogT3V0cHV0IGZvcm1hdDpcbiAgICog8J+noCBOYW1lICh2VmVyc2lvbikgLSBEZXNjcmlwdGlvblxuICAgKiAgICBSZXRlbnRpb246IHJldGVudGlvbkRheXMgZGF5cyB8IFRhZ3M6IHRhZ3NcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGZvcm1hdE1lbW9yeShlbGVtZW50OiBNZW1vcnlFbGVtZW50KTogc3RyaW5nIHtcbiAgICBjb25zdCByZXRlbnRpb25EYXlzID0gZWxlbWVudC5tZXRhZGF0YS5yZXRlbnRpb25EYXlzPy50b1N0cmluZygpIHx8IERFRkFVTFRTLlJFVEVOVElPTjtcbiAgICBjb25zdCB0YWdzID0gZWxlbWVudC5tZXRhZGF0YS50YWdzPy5tYXAodCA9PiB0aGlzLm5vcm1hbGl6ZSh0KSkuam9pbignLCAnKSB8fCBERUZBVUxUUy5UQUdTO1xuICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLm5vcm1hbGl6ZShlbGVtZW50LnZlcnNpb24pIHx8IHRoaXMubm9ybWFsaXplKGVsZW1lbnQubWV0YWRhdGEudmVyc2lvbikgfHwgREVGQVVMVFMuVkVSU0lPTjtcbiAgICBjb25zdCBuYW1lID0gdGhpcy5ub3JtYWxpemUoZWxlbWVudC5tZXRhZGF0YS5uYW1lKTtcbiAgICBjb25zdCBkZXNjcmlwdGlvbiA9IHRoaXMubm9ybWFsaXplKGVsZW1lbnQubWV0YWRhdGEuZGVzY3JpcHRpb24pO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIGDwn6egICR7bmFtZX0gKHYke3ZlcnNpb259KSAtICR7ZGVzY3JpcHRpb259XFxuYCArXG4gICAgICBgICAgUmV0ZW50aW9uOiAke3JldGVudGlvbkRheXN9IGRheXMgfCBUYWdzOiAke3RhZ3N9YFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRm9ybWF0IGFuIGVuc2VtYmxlIGVsZW1lbnQgZm9yIGRpc3BsYXlcbiAgICpcbiAgICogQHBhcmFtIGVsZW1lbnQgVGhlIGVuc2VtYmxlIGVsZW1lbnQgdG8gZm9ybWF0XG4gICAqIEByZXR1cm5zIEZvcm1hdHRlZCBzdHJpbmcgcmVwcmVzZW50YXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogLy8gUmV0dXJuczpcbiAgICogLy8g8J+OrSBSZXNlYXJjaCBUZWFtICh2MS4wLjApIC0gQ29vcmRpbmF0ZWQgcmVzZWFyY2ggd29ya2Zsb3dcbiAgICogLy8gICAgRWxlbWVudHM6IDMgfCBTdHJhdGVneTogcGFyYWxsZWxcbiAgICpcbiAgICogT3V0cHV0IGZvcm1hdDpcbiAgICog8J+OrSBOYW1lICh2VmVyc2lvbikgLSBEZXNjcmlwdGlvblxuICAgKiAgICBFbGVtZW50czogZWxlbWVudENvdW50IHwgU3RyYXRlZ3k6IHN0cmF0ZWd5XG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBmb3JtYXRFbnNlbWJsZShlbGVtZW50OiBFbnNlbWJsZUVsZW1lbnQpOiBzdHJpbmcge1xuICAgIGNvbnN0IGVsZW1lbnRDb3VudCA9IGVsZW1lbnQubWV0YWRhdGEuZWxlbWVudHM/Lmxlbmd0aCB8fCAwO1xuICAgIGNvbnN0IHN0cmF0ZWd5ID0gdGhpcy5ub3JtYWxpemUoZWxlbWVudC5tZXRhZGF0YS5hY3RpdmF0aW9uU3RyYXRlZ3kpIHx8IERFRkFVTFRTLlNUUkFURUdZO1xuICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLm5vcm1hbGl6ZShlbGVtZW50LnZlcnNpb24pIHx8IHRoaXMubm9ybWFsaXplKGVsZW1lbnQubWV0YWRhdGEudmVyc2lvbikgfHwgREVGQVVMVFMuVkVSU0lPTjtcbiAgICBjb25zdCBuYW1lID0gdGhpcy5ub3JtYWxpemUoZWxlbWVudC5tZXRhZGF0YS5uYW1lKTtcbiAgICBjb25zdCBkZXNjcmlwdGlvbiA9IHRoaXMubm9ybWFsaXplKGVsZW1lbnQubWV0YWRhdGEuZGVzY3JpcHRpb24pO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIGDwn46tICR7bmFtZX0gKHYke3ZlcnNpb259KSAtICR7ZGVzY3JpcHRpb259XFxuYCArXG4gICAgICBgICAgRWxlbWVudHM6ICR7ZWxlbWVudENvdW50fSB8IFN0cmF0ZWd5OiAke3N0cmF0ZWd5fWBcbiAgICApO1xuICB9XG59XG4iXX0=