@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.
223 lines • 30.6 kB
JavaScript
/**
* Persona element class implementing IElement interface.
* Represents a behavioral profile that defines AI personality and interaction style.
*/
import { BaseElement } from '../elements/BaseElement.js';
import { ElementType } from '../portfolio/types.js';
import { logger } from '../utils/logger.js';
import matter from 'gray-matter';
export class PersonaElement extends BaseElement {
content;
filename;
constructor(metadata, content = '', filename = '') {
super(ElementType.PERSONA, metadata);
this.content = content;
this.filename = filename;
// Ensure persona-specific metadata
this.metadata = {
...this.metadata,
triggers: metadata.triggers || [],
category: metadata.category || 'personal',
age_rating: metadata.age_rating || 'all',
content_flags: metadata.content_flags || [],
ai_generated: metadata.ai_generated || false,
generation_method: metadata.generation_method || 'human',
price: metadata.price || 'free',
license: metadata.license || 'CC-BY-SA-4.0',
created_date: metadata.created_date || new Date().toISOString().split('T')[0]
};
}
/**
* Create PersonaElement from legacy Persona interface
*/
static fromLegacy(legacyPersona) {
const metadata = {
name: legacyPersona.metadata.name,
description: legacyPersona.metadata.description,
author: legacyPersona.metadata.author,
version: legacyPersona.metadata.version,
triggers: legacyPersona.metadata.triggers,
category: legacyPersona.metadata.category,
age_rating: legacyPersona.metadata.age_rating,
content_flags: legacyPersona.metadata.content_flags,
ai_generated: legacyPersona.metadata.ai_generated,
generation_method: legacyPersona.metadata.generation_method,
price: legacyPersona.metadata.price,
revenue_split: legacyPersona.metadata.revenue_split,
license: legacyPersona.metadata.license,
created_date: legacyPersona.metadata.created_date
};
const persona = new PersonaElement(metadata, legacyPersona.content, legacyPersona.filename);
// Preserve the legacy unique_id as the element id
persona.id = legacyPersona.unique_id;
return persona;
}
/**
* Convert to legacy Persona interface for backward compatibility
*/
toLegacy() {
const legacyMetadata = {
name: this.metadata.name,
description: this.metadata.description,
unique_id: this.id,
author: this.metadata.author,
triggers: this.metadata.triggers,
version: this.metadata.version,
category: this.metadata.category,
age_rating: this.metadata.age_rating,
content_flags: this.metadata.content_flags,
ai_generated: this.metadata.ai_generated,
generation_method: this.metadata.generation_method,
price: this.metadata.price,
revenue_split: this.metadata.revenue_split,
license: this.metadata.license,
created_date: this.metadata.created_date
};
return {
metadata: legacyMetadata,
content: this.content,
filename: this.filename,
unique_id: this.id
};
}
/**
* Persona-specific validation
*/
validate() {
const result = super.validate();
// Initialize arrays if not present
if (!result.errors)
result.errors = [];
if (!result.warnings)
result.warnings = [];
// Add persona-specific validation rules
// Content should not be empty
if (!this.content || this.content.trim().length === 0) {
result.errors.push({
field: 'content',
message: 'Persona content cannot be empty',
code: 'EMPTY_CONTENT'
});
}
// Content should be reasonable length
if (this.content && this.content.length > 10000) {
result.warnings.push({
field: 'content',
message: 'Persona content is very long, consider breaking it down',
severity: 'medium'
});
}
// Triggers should be reasonable
if (this.metadata.triggers && this.metadata.triggers.length > 10) {
result.warnings.push({
field: 'triggers',
message: 'Many triggers may cause activation conflicts',
severity: 'medium'
});
}
// Check for adult content flags
if (this.metadata.age_rating === '18+' && !this.metadata.content_flags?.includes('adult')) {
result.warnings.push({
field: 'content_flags',
message: '18+ content should include "adult" in content_flags',
severity: 'low'
});
}
// Update the valid flag based on final errors
result.valid = (result.errors?.length || 0) === 0;
return result;
}
/**
* Serialize persona to markdown format
*/
serialize() {
const frontmatter = {
name: this.metadata.name,
description: this.metadata.description,
unique_id: this.id,
author: this.metadata.author,
triggers: this.metadata.triggers,
version: this.metadata.version,
category: this.metadata.category,
age_rating: this.metadata.age_rating,
content_flags: this.metadata.content_flags,
ai_generated: this.metadata.ai_generated,
generation_method: this.metadata.generation_method,
price: this.metadata.price,
revenue_split: this.metadata.revenue_split,
license: this.metadata.license,
created_date: this.metadata.created_date
};
// Remove undefined values
const cleanFrontmatter = Object.fromEntries(Object.entries(frontmatter).filter(([_, value]) => value !== undefined));
const yamlFrontmatter = Object.entries(cleanFrontmatter)
.map(([key, value]) => {
if (Array.isArray(value)) {
if (value.length === 0)
return `${key}: []`;
return `${key}:\n${value.map(item => ` - ${item}`).join('\n')}`;
}
return `${key}: ${JSON.stringify(value)}`;
})
.join('\n');
return `---\n${yamlFrontmatter}\n---\n\n${this.content}`;
}
/**
* Deserialize persona from markdown format
*/
deserialize(data) {
try {
const parsed = matter(data);
const metadata = parsed.data;
// Update metadata
this.metadata = {
...this.metadata,
name: metadata.name,
description: metadata.description,
author: metadata.author,
version: metadata.version,
triggers: metadata.triggers,
category: metadata.category,
age_rating: metadata.age_rating,
content_flags: metadata.content_flags,
ai_generated: metadata.ai_generated,
generation_method: metadata.generation_method,
price: metadata.price,
revenue_split: metadata.revenue_split,
license: metadata.license,
created_date: metadata.created_date
};
// Update content (trim to remove leading/trailing whitespace)
this.content = parsed.content.trim();
// Update ID if provided
if (metadata.unique_id) {
this.id = metadata.unique_id;
}
this._isDirty = true;
logger.debug(`Deserialized persona: ${this.metadata.name}`);
}
catch (error) {
logger.error(`Failed to deserialize persona: ${error}`);
throw new Error(`Deserialization failed: ${error}`);
}
}
/**
* Persona activation lifecycle
*/
async activate() {
logger.info(`Activating persona: ${this.metadata.name} (${this.id})`);
// Personas don't need special activation logic currently
// But this provides a hook for future enhancements
await super.activate?.();
}
/**
* Persona deactivation lifecycle
*/
async deactivate() {
logger.info(`Deactivating persona: ${this.metadata.name} (${this.id})`);
// Personas don't need special deactivation logic currently
// But this provides a hook for future enhancements
await super.deactivate?.();
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGVyc29uYUVsZW1lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGVyc29uYS9QZXJzb25hRWxlbWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFekQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXBELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QyxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFnQmpDLE1BQU0sT0FBTyxjQUFlLFNBQVEsV0FBVztJQUN0QyxPQUFPLENBQVM7SUFDaEIsUUFBUSxDQUFTO0lBR3hCLFlBQVksUUFBeUMsRUFBRSxVQUFrQixFQUFFLEVBQUUsV0FBbUIsRUFBRTtRQUNoRyxLQUFLLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUV6QixtQ0FBbUM7UUFDbkMsSUFBSSxDQUFDLFFBQVEsR0FBRztZQUNkLEdBQUcsSUFBSSxDQUFDLFFBQVE7WUFDaEIsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRLElBQUksRUFBRTtZQUNqQyxRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsSUFBSSxVQUFVO1lBQ3pDLFVBQVUsRUFBRSxRQUFRLENBQUMsVUFBVSxJQUFJLEtBQUs7WUFDeEMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxhQUFhLElBQUksRUFBRTtZQUMzQyxZQUFZLEVBQUUsUUFBUSxDQUFDLFlBQVksSUFBSSxLQUFLO1lBQzVDLGlCQUFpQixFQUFFLFFBQVEsQ0FBQyxpQkFBaUIsSUFBSSxPQUFPO1lBQ3hELEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxJQUFJLE1BQU07WUFDL0IsT0FB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QVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRTlELENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxDQUFDLEtBQUssQ0FBQyxrQ0FBa0MsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUN4RCxNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDYSxLQUFLLENBQUMsUUFBUTtRQUM1QixNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUV0RSx5REFBeUQ7UUFDekQsbURBQW1EO1FBRW5ELE1BQU0sS0FBSyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVEOztPQUVHO0lBQ2EsS0FBSyxDQUFDLFVBQVU7UUFDOUIsTUFBTSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFFeEUsMkRBQTJEO1FBQzNELG1EQUFtRDtRQUVuRCxNQUFNLEtBQUssQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDO0lBQzdCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUGVyc29uYSBlbGVtZW50IGNsYXNzIGltcGxlbWVudGluZyBJRWxlbWVudCBpbnRlcmZhY2UuXG4gKiBSZXByZXNlbnRzIGEgYmVoYXZpb3JhbCBwcm9maWxlIHRoYXQgZGVmaW5lcyBBSSBwZXJzb25hbGl0eSBhbmQgaW50ZXJhY3Rpb24gc3R5bGUuXG4gKi9cblxuaW1wb3J0IHsgQmFzZUVsZW1lbnQgfSBmcm9tICcuLi9lbGVtZW50cy9CYXNlRWxlbWVudC5qcyc7XG5pbXBvcnQgeyBJRWxlbWVudCwgSUVsZW1lbnRNZXRhZGF0YSwgRWxlbWVudFZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICcuLi90eXBlcy9lbGVtZW50cy9pbmRleC5qcyc7XG5pbXBvcnQgeyBFbGVtZW50VHlwZSB9IGZyb20gJy4uL3BvcnRmb2xpby90eXBlcy5qcyc7XG5pbXBvcnQgeyBQZXJzb25hTWV0YWRhdGEgfSBmcm9tICcuLi90eXBlcy9wZXJzb25hLmpzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL3V0aWxzL2xvZ2dlci5qcyc7XG5pbXBvcnQgbWF0dGVyIGZyb20gJ2dyYXktbWF0dGVyJztcblxuLy8gRXh0ZW5kIElFbGVtZW50TWV0YWRhdGEgd2l0aCBwZXJzb25hLXNwZWNpZmljIGZpZWxkc1xuZXhwb3J0IGludGVyZmFjZSBQZXJzb25hRWxlbWVudE1ldGFkYXRhIGV4dGVuZHMgSUVsZW1lbnRNZXRhZGF0YSB7XG4gIHRyaWdnZXJzPzogc3RyaW5nW107XG4gIGNhdGVnb3J5Pzogc3RyaW5nO1xuICBhZ2VfcmF0aW5nPzogJ2FsbCcgfCAnMTMrJyB8ICcxOCsnO1xuICBjb250ZW50X2ZsYWdzPzogc3RyaW5nW107XG4gIGFpX2dlbmVyYXRlZD86IGJvb2xlYW47XG4gIGdlbmVyYXRpb25fbWV0aG9kPzogJ2h1bWFuJyB8ICdDaGF0R1BUJyB8ICdDbGF1ZGUnIHwgJ2h5YnJpZCc7XG4gIHByaWNlPzogc3RyaW5nO1xuICByZXZlbnVlX3NwbGl0Pzogc3RyaW5nO1xuICBsaWNlbnNlPzogc3RyaW5nO1xuICBjcmVhdGVkX2RhdGU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBQZXJzb25hRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IGltcGxlbWVudHMgSUVsZW1lbnQge1xuICBwdWJsaWMgY29udGVudDogc3RyaW5nO1xuICBwdWJsaWMgZmlsZW5hbWU6IHN0cmluZztcbiAgcHVibGljIGRlY2xhcmUgbWV0YWRhdGE6IFBlcnNvbmFFbGVtZW50TWV0YWRhdGE7XG5cbiAgY29uc3RydWN0b3IobWV0YWRhdGE6IFBhcnRpYWw8UGVyc29uYUVsZW1lbnRNZXRhZGF0YT4sIGNvbnRlbnQ6IHN0cmluZyA9ICcnLCBmaWxlbmFtZTogc3RyaW5nID0gJycpIHtcbiAgICBzdXBlcihFbGVtZW50VHlwZS5QRVJTT05BLCBtZXRhZGF0YSk7XG4gICAgdGhpcy5jb250ZW50ID0gY29udGVudDtcbiAgICB0aGlzLmZpbGVuYW1lID0gZmlsZW5hbWU7XG4gICAgXG4gICAgLy8gRW5zdXJlIHBlcnNvbmEtc3BlY2lmaWMgbWV0YWRhdGFcbiAgICB0aGlzLm1ldGFkYXRhID0ge1xuICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIHRyaWdnZXJzOiBtZXRhZGF0YS50cmlnZ2VycyB8fCBbXSxcbiAgICAgIGNhdGVnb3J5OiBtZXRhZGF0YS5jYXRlZ29yeSB8fCAncGVyc29uYWwnLFxuICAgICAgYWdlX3JhdGluZzogbWV0YWRhdGEuYWdlX3JhdGluZyB8fCAnYWxsJyxcbiAgICAgIGNvbnRlbnRfZmxhZ3M6IG1ldGFkYXRhLmNvbnRlbnRfZmxhZ3MgfHwgW10sXG4gICAgICBhaV9nZW5lcmF0ZWQ6IG1ldGFkYXRhLmFpX2dlbmVyYXRlZCB8fCBmYWxzZSxcbiAgICAgIGdlbmVyYXRpb25fbWV0aG9kOiBtZXRhZGF0YS5nZW5lcmF0aW9uX21ldGhvZCB8fCAnaHVtYW4nLFxuICAgICAgcHJpY2U6IG1ldGFkYXRhLnByaWNlIHx8ICdmcmVlJyxcbiAgICAgIGxpY2Vuc2U6IG1ldGFkYXRhLmxpY2Vuc2UgfHwgJ0NDLUJZLVNBLTQuMCcsXG4gICAgICBjcmVhdGVkX2RhdGU6IG1ldGFkYXRhLmNyZWF0ZWRfZGF0ZSB8fCBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkuc3BsaXQoJ1QnKVswXVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIFBlcnNvbmFFbGVtZW50IGZyb20gbGVnYWN5IFBlcnNvbmEgaW50ZXJmYWNlXG4gICAqL1xuICBzdGF0aWMgZnJvbUxlZ2FjeShsZWdhY3lQZXJzb25hOiB7IG1ldGFkYXRhOiBQZXJzb25hTWV0YWRhdGE7IGNvbnRlbnQ6IHN0cmluZzsgZmlsZW5hbWU6IHN0cmluZzsgdW5pcXVlX2lkOiBzdHJpbmcgfSk6IFBlcnNvbmFFbGVtZW50IHtcbiAgICBjb25zdCBtZXRhZGF0YTogUGFydGlhbDxQZXJzb25hRWxlbWVudE1ldGFkYXRhPiA9IHtcbiAgICAgIG5hbWU6IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEubmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBsZWdhY3lQZXJzb25hLm1ldGFkYXRhLmRlc2NyaXB0aW9uLFxuICAgICAgYXV0aG9yOiBsZWdhY3lQZXJzb25hLm1ldGFkYXRhLmF1dGhvcixcbiAgICAgIHZlcnNpb246IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEudmVyc2lvbixcbiAgICAgIHRyaWdnZXJzOiBsZWdhY3lQZXJzb25hLm1ldGFkYXRhLnRyaWdnZXJzLFxuICAgICAgY2F0ZWdvcnk6IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEuY2F0ZWdvcnksXG4gICAgICBhZ2VfcmF0aW5nOiBsZWdhY3lQZXJzb25hLm1ldGFkYXRhLmFnZV9yYXRpbmcsXG4gICAgICBjb250ZW50X2ZsYWdzOiBsZWdhY3lQZXJzb25hLm1ldGFkYXRhLmNvbnRlbnRfZmxhZ3MsXG4gICAgICBhaV9nZW5lcmF0ZWQ6IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEuYWlfZ2VuZXJhdGVkLFxuICAgICAgZ2VuZXJhdGlvbl9tZXRob2Q6IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEuZ2VuZXJhdGlvbl9tZXRob2QsXG4gICAgICBwcmljZTogbGVnYWN5UGVyc29uYS5tZXRhZGF0YS5wcmljZSxcbiAgICAgIHJldmVudWVfc3BsaXQ6IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEucmV2ZW51ZV9zcGxpdCxcbiAgICAgIGxpY2Vuc2U6IGxlZ2FjeVBlcnNvbmEubWV0YWRhdGEubGljZW5zZSxcbiAgICAgIGNyZWF0ZWRfZGF0ZTogbGVnYWN5UGVyc29uYS5tZXRhZGF0YS5jcmVhdGVkX2RhdGVcbiAgICB9O1xuXG4gICAgY29uc3QgcGVyc29uYSA9IG5ldyBQZXJzb25hRWxlbWVudChtZXRhZGF0YSwgbGVnYWN5UGVyc29uYS5jb250ZW50LCBsZWdhY3lQZXJzb25hLmZpbGVuYW1lKTtcbiAgICBcbiAgICAvLyBQcmVzZXJ2ZSB0aGUgbGVnYWN5IHVuaXF1ZV9pZCBhcyB0aGUgZWxlbWVudCBpZFxuICAgIHBlcnNvbmEuaWQgPSBsZWdhY3lQZXJzb25hLnVuaXF1ZV9pZDtcbiAgICBcbiAgICByZXR1cm4gcGVyc29uYTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IHRvIGxlZ2FjeSBQZXJzb25hIGludGVyZmFjZSBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eVxuICAgKi9cbiAgdG9MZWdhY3koKTogeyBtZXRhZGF0YTogUGVyc29uYU1ldGFkYXRhOyBjb250ZW50OiBzdHJpbmc7IGZpbGVuYW1lOiBzdHJpbmc7IHVuaXF1ZV9pZDogc3RyaW5nIH0ge1xuICAgIGNvbnN0IGxlZ2FjeU1ldGFkYXRhOiBQZXJzb25hTWV0YWRhdGEgPSB7XG4gICAgICBuYW1lOiB0aGlzLm1ldGFkYXRhLm5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogdGhpcy5tZXRhZGF0YS5kZXNjcmlwdGlvbixcbiAgICAgIHVuaXF1ZV9pZDogdGhpcy5pZCxcbiAgICAgIGF1dGhvcjogdGhpcy5tZXRhZGF0YS5hdXRob3IsXG4gICAgICB0cmlnZ2VyczogdGhpcy5tZXRhZGF0YS50cmlnZ2VycyxcbiAgICAgIHZlcnNpb246IHRoaXMubWV0YWRhdGEudmVyc2lvbixcbiAgICAgIGNhdGVnb3J5OiB0aGlzLm1ldGFkYXRhLmNhdGVnb3J5LFxuICAgICAgYWdlX3JhdGluZzogdGhpcy5tZXRhZGF0YS5hZ2VfcmF0aW5nLFxuICAgICAgY29udGVudF9mbGFnczogdGhpcy5tZXRhZGF0YS5jb250ZW50X2ZsYWdzLFxuICAgICAgYWlfZ2VuZXJhdGVkOiB0aGlzLm1ldGFkYXRhLmFpX2dlbmVyYXRlZCxcbiAgICAgIGdlbmVyYXRpb25fbWV0aG9kOiB0aGlzLm1ldGFkYXRhLmdlbmVyYXRpb25fbWV0aG9kLFxuICAgICAgcHJpY2U6IHRoaXMubWV0YWRhdGEucHJpY2UsXG4gICAgICByZXZlbnVlX3NwbGl0OiB0aGlzLm1ldGFkYXRhLnJldmVudWVfc3BsaXQsXG4gICAgICBsaWNlbnNlOiB0aGlzLm1ldGFkYXRhLmxpY2Vuc2UsXG4gICAgICBjcmVhdGVkX2RhdGU6IHRoaXMubWV0YWRhdGEuY3JlYXRlZF9kYXRlXG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBtZXRhZGF0YTogbGVnYWN5TWV0YWRhdGEsXG4gICAgICBjb250ZW50OiB0aGlzLmNvbnRlbnQsXG4gICAgICBmaWxlbmFtZTogdGhpcy5maWxlbmFtZSxcbiAgICAgIHVuaXF1ZV9pZDogdGhpcy5pZFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUGVyc29uYS1zcGVjaWZpYyB2YWxpZGF0aW9uXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgdmFsaWRhdGUoKTogRWxlbWVudFZhbGlkYXRpb25SZXN1bHQge1xuICAgIGNvbnN0IHJlc3VsdCA9IHN1cGVyLnZhbGlkYXRlKCk7XG4gICAgXG4gICAgLy8gSW5pdGlhbGl6ZSBhcnJheXMgaWYgbm90IHByZXNlbnRcbiAgICBpZiAoIXJlc3VsdC5lcnJvcnMpIHJlc3VsdC5lcnJvcnMgPSBbXTtcbiAgICBpZiAoIXJlc3VsdC53YXJuaW5ncykgcmVzdWx0Lndhcm5pbmdzID0gW107XG4gICAgXG4gICAgLy8gQWRkIHBlcnNvbmEtc3BlY2lmaWMgdmFsaWRhdGlvbiBydWxlc1xuICAgIFxuICAgIC8vIENvbnRlbnQgc2hvdWxkIG5vdCBiZSBlbXB0eVxuICAgIGlmICghdGhpcy5jb250ZW50IHx8IHRoaXMuY29udGVudC50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXN1bHQuZXJyb3JzLnB1c2goe1xuICAgICAgICBmaWVsZDogJ2NvbnRlbnQnLFxuICAgICAgICBtZXNzYWdlOiAnUGVyc29uYSBjb250ZW50IGNhbm5vdCBiZSBlbXB0eScsXG4gICAgICAgIGNvZGU6ICdFTVBUWV9DT05URU5UJ1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQ29udGVudCBzaG91bGQgYmUgcmVhc29uYWJsZSBsZW5ndGhcbiAgICBpZiAodGhpcy5jb250ZW50ICYmIHRoaXMuY29udGVudC5sZW5ndGggPiAxMDAwMCkge1xuICAgICAgcmVzdWx0Lndhcm5pbmdzLnB1c2goe1xuICAgICAgICBmaWVsZDogJ2NvbnRlbnQnLFxuICAgICAgICBtZXNzYWdlOiAnUGVyc29uYSBjb250ZW50IGlzIHZlcnkgbG9uZywgY29uc2lkZXIgYnJlYWtpbmcgaXQgZG93bicsXG4gICAgICAgIHNldmVyaXR5OiAnbWVkaXVtJ1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gVHJpZ2dlcnMgc2hvdWxkIGJlIHJlYXNvbmFibGVcbiAgICBpZiAodGhpcy5tZXRhZGF0YS50cmlnZ2VycyAmJiB0aGlzLm1ldGFkYXRhLnRyaWdnZXJzLmxlbmd0aCA+IDEwKSB7XG4gICAgICByZXN1bHQud2FybmluZ3MucHVzaCh7XG4gICAgICAgIGZpZWxkOiAndHJpZ2dlcnMnLFxuICAgICAgICBtZXNzYWdlOiAnTWFueSB0cmlnZ2VycyBtYXkgY2F1c2UgYWN0aXZhdGlvbiBjb25mbGljdHMnLFxuICAgICAgICBzZXZlcml0eTogJ21lZGl1bSdcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGZvciBhZHVsdCBjb250ZW50IGZsYWdzXG4gICAgaWYgKHRoaXMubWV0YWRhdGEuYWdlX3JhdGluZyA9PT0gJzE4KycgJiYgIXRoaXMubWV0YWRhdGEuY29udGVudF9mbGFncz8uaW5jbHVkZXMoJ2FkdWx0JykpIHtcbiAgICAgIHJlc3VsdC53YXJuaW5ncy5wdXNoKHtcbiAgICAgICAgZmllbGQ6ICdjb250ZW50X2ZsYWdzJyxcbiAgICAgICAgbWVzc2FnZTogJzE4KyBjb250ZW50IHNob3VsZCBpbmNsdWRlIFwiYWR1bHRcIiBpbiBjb250ZW50X2ZsYWdzJyxcbiAgICAgICAgc2V2ZXJpdHk6ICdsb3cnXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgdGhlIHZhbGlkIGZsYWcgYmFzZWQgb24gZmluYWwgZXJyb3JzXG4gICAgcmVzdWx0LnZhbGlkID0gKHJlc3VsdC5lcnJvcnM/Lmxlbmd0aCB8fCAwKSA9PT0gMDtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogU2VyaWFsaXplIHBlcnNvbmEgdG8gbWFya2Rvd24gZm9ybWF0XG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgc2VyaWFsaXplKCk6IHN0cmluZyB7XG4gICAgY29uc3QgZnJvbnRtYXR0ZXIgPSB7XG4gICAgICBuYW1lOiB0aGlzLm1ldGFkYXRhLm5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogdGhpcy5tZXRhZGF0YS5kZXNjcmlwdGlvbixcbiAgICAgIHVuaXF1ZV9pZDogdGhpcy5pZCxcbiAgICAgIGF1dGhvcjogdGhpcy5tZXRhZGF0YS5hdXRob3IsXG4gICAgICB0cmlnZ2VyczogdGhpcy5tZXRhZGF0YS50cmlnZ2VycyxcbiAgICAgIHZlcnNpb246IHRoaXMubWV0YWRhdGEudmVyc2lvbixcbiAgICAgIGNhdGVnb3J5OiB0aGlzLm1ldGFkYXRhLmNhdGVnb3J5LFxuICAgICAgYWdlX3JhdGluZzogdGhpcy5tZXRhZGF0YS5hZ2VfcmF0aW5nLFxuICAgICAgY29udGVudF9mbGFnczogdGhpcy5tZXRhZGF0YS5jb250ZW50X2ZsYWdzLFxuICAgICAgYWlfZ2VuZXJhdGVkOiB0aGlzLm1ldGFkYXRhLmFpX2dlbmVyYXRlZCxcbiAgICAgIGdlbmVyYXRpb25fbWV0aG9kOiB0aGlzLm1ldGFkYXRhLmdlbmVyYXRpb25fbWV0aG9kLFxuICAgICAgcHJpY2U6IHRoaXMubWV0YWRhdGEucHJpY2UsXG4gICAgICByZXZlbnVlX3NwbGl0OiB0aGlzLm1ldGFkYXRhLnJldmVudWVfc3BsaXQsXG4gICAgICBsaWNlbnNlOiB0aGlzLm1ldGFkYXRhLmxpY2Vuc2UsXG4gICAgICBjcmVhdGVkX2RhdGU6IHRoaXMubWV0YWRhdGEuY3JlYXRlZF9kYXRlXG4gICAgfTtcblxuICAgIC8vIFJlbW92ZSB1bmRlZmluZWQgdmFsdWVzXG4gICAgY29uc3QgY2xlYW5Gcm9udG1hdHRlciA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIE9iamVjdC5lbnRyaWVzKGZyb250bWF0dGVyKS5maWx0ZXIoKFtfLCB2YWx1ZV0pID0+IHZhbHVlICE9PSB1bmRlZmluZWQpXG4gICAgKTtcblxuICAgIGNvbnN0IHlhbWxGcm9udG1hdHRlciA9IE9iamVjdC5lbnRyaWVzKGNsZWFuRnJvbnRtYXR0ZXIpXG4gICAgICAubWFwKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGAke2tleX06IFtdYDtcbiAgICAgICAgICByZXR1cm4gYCR7a2V5fTpcXG4ke3ZhbHVlLm1hcChpdGVtID0+IGAgIC0gJHtpdGVtfWApLmpvaW4oJ1xcbicpfWA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGAke2tleX06ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfWA7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJ1xcbicpO1xuXG4gICAgcmV0dXJuIGAtLS1cXG4ke3lhbWxGcm9udG1hdHRlcn1cXG4tLS1cXG5cXG4ke3RoaXMuY29udGVudH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIERlc2VyaWFsaXplIHBlcnNvbmEgZnJvbSBtYXJrZG93biBmb3JtYXRcbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBkZXNlcmlhbGl6ZShkYXRhOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFyc2VkID0gbWF0dGVyKGRhdGEpO1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSBwYXJzZWQuZGF0YSBhcyBQZXJzb25hTWV0YWRhdGE7XG4gICAgICBcbiAgICAgIC8vIFVwZGF0ZSBtZXRhZGF0YVxuICAgICAgdGhpcy5tZXRhZGF0YSA9IHtcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgICAgbmFtZTogbWV0YWRhdGEubmFtZSxcbiAgICAgICAgZGVzY3JpcHRpb246IG1ldGFkYXRhLmRlc2NyaXB0aW9uLFxuICAgICAgICBhdXRob3I6IG1ldGFkYXRhLmF1dGhvcixcbiAgICAgICAgdmVyc2lvbjogbWV0YWRhdGEudmVyc2lvbixcbiAgICAgICAgdHJpZ2dlcnM6IG1ldGFkYXRhLnRyaWdnZXJzLFxuICAgICAgICBjYXRlZ29yeTogbWV0YWRhdGEuY2F0ZWdvcnksXG4gICAgICAgIGFnZV9yYXRpbmc6IG1ldGFkYXRhLmFnZV9yYXRpbmcsXG4gICAgICAgIGNvbnRlbnRfZmxhZ3M6IG1ldGFkYXRhLmNvbnRlbnRfZmxhZ3MsXG4gICAgICAgIGFpX2dlbmVyYXRlZDogbWV0YWRhdGEuYWlfZ2VuZXJhdGVkLFxuICAgICAgICBnZW5lcmF0aW9uX21ldGhvZDogbWV0YWRhdGEuZ2VuZXJhdGlvbl9tZXRob2QsXG4gICAgICAgIHByaWNlOiBtZXRhZGF0YS5wcmljZSxcbiAgICAgICAgcmV2ZW51ZV9zcGxpdDogbWV0YWRhdGEucmV2ZW51ZV9zcGxpdCxcbiAgICAgICAgbGljZW5zZTogbWV0YWRhdGEubGljZW5zZSxcbiAgICAgICAgY3JlYXRlZF9kYXRlOiBtZXRhZGF0YS5jcmVhdGVkX2RhdGVcbiAgICAgIH07XG4gICAgICBcbiAgICAgIC8vIFVwZGF0ZSBjb250ZW50ICh0cmltIHRvIHJlbW92ZSBsZWFkaW5nL3RyYWlsaW5nIHdoaXRlc3BhY2UpXG4gICAgICB0aGlzLmNvbnRlbnQgPSBwYXJzZWQuY29udGVudC50cmltKCk7XG4gICAgICBcbiAgICAgIC8vIFVwZGF0ZSBJRCBpZiBwcm92aWRlZFxuICAgICAgaWYgKG1ldGFkYXRhLnVuaXF1ZV9pZCkge1xuICAgICAgICB0aGlzLmlkID0gbWV0YWRhdGEudW5pcXVlX2lkO1xuICAgICAgfVxuICAgICAgXG4gICAgICB0aGlzLl9pc0RpcnR5ID0gdHJ1ZTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgRGVzZXJpYWxpemVkIHBlcnNvbmE6ICR7dGhpcy5tZXRhZGF0YS5uYW1lfWApO1xuICAgICAgXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGRlc2VyaWFsaXplIHBlcnNvbmE6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYERlc2VyaWFsaXphdGlvbiBmYWlsZWQ6ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBlcnNvbmEgYWN0aXZhdGlvbiBsaWZlY3ljbGVcbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBhc3luYyBhY3RpdmF0ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2dnZXIuaW5mbyhgQWN0aXZhdGluZyBwZXJzb25hOiAke3RoaXMubWV0YWRhdGEubmFtZX0gKCR7dGhpcy5pZH0pYCk7XG4gICAgXG4gICAgLy8gUGVyc29uYXMgZG9uJ3QgbmVlZCBzcGVjaWFsIGFjdGl2YXRpb24gbG9naWMgY3VycmVudGx5XG4gICAgLy8gQnV0IHRoaXMgcHJvdmlkZXMgYSBob29rIGZvciBmdXR1cmUgZW5oYW5jZW1lbnRzXG4gICAgXG4gICAgYXdhaXQgc3VwZXIuYWN0aXZhdGU/LigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcnNvbmEgZGVhY3RpdmF0aW9uIGxpZmVjeWNsZVxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIGFzeW5jIGRlYWN0aXZhdGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nZ2VyLmluZm8oYERlYWN0aXZhdGluZyBwZXJzb25hOiAke3RoaXMubWV0YWRhdGEubmFtZX0gKCR7dGhpcy5pZH0pYCk7XG4gICAgXG4gICAgLy8gUGVyc29uYXMgZG9uJ3QgbmVlZCBzcGVjaWFsIGRlYWN0aXZhdGlvbiBsb2dpYyBjdXJyZW50bHlcbiAgICAvLyBCdXQgdGhpcyBwcm92aWRlcyBhIGhvb2sgZm9yIGZ1dHVyZSBlbmhhbmNlbWVudHNcbiAgICBcbiAgICBhd2FpdCBzdXBlci5kZWFjdGl2YXRlPy4oKTtcbiAgfVxufSJdfQ==