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.

297 lines 33.4 kB
/** * Goal Template System for Agent Goal Management * * Provides pre-configured goal templates for common patterns, * making it easier to create well-structured goals with appropriate * settings for different scenarios. */ import { SecurityMonitor } from '../../security/securityMonitor.js'; // Pre-defined goal templates export const GOAL_TEMPLATES = { // Development templates 'feature-implementation': { id: 'feature-implementation', name: 'Feature Implementation', description: 'Implement a new feature with proper testing and documentation', category: 'development', defaultValues: { priority: 'high', importance: 8, urgency: 5, estimatedEffort: 8, riskLevel: 'medium', tags: ['feature', 'development', 'implementation'] }, requiredFields: ['featureName', 'specifications'], successCriteria: [ 'Code implemented and tested', 'Unit tests passing', 'Documentation updated', 'Code reviewed' ], riskMitigations: [ 'Break down into smaller tasks', 'Early prototype validation', 'Regular progress reviews' ] }, 'bug-fix-critical': { id: 'bug-fix-critical', name: 'Critical Bug Fix', description: 'Fix a critical production bug affecting users', category: 'maintenance', defaultValues: { priority: 'critical', importance: 10, urgency: 10, estimatedEffort: 2, riskLevel: 'high', tags: ['bug', 'critical', 'production'] }, requiredFields: ['bugId', 'impactDescription'], successCriteria: [ 'Bug identified and reproduced', 'Fix implemented and tested', 'Regression tests added', 'Deployed to production' ], riskMitigations: [ 'Rollback plan prepared', 'Thorough testing in staging', 'Monitor after deployment' ] }, 'research-spike': { id: 'research-spike', name: 'Research Spike', description: 'Time-boxed research to explore technical options', category: 'research', defaultValues: { priority: 'medium', importance: 7, urgency: 3, estimatedEffort: 4, riskLevel: 'low', tags: ['research', 'spike', 'exploration'] }, requiredFields: ['researchQuestion', 'timeBox'], successCriteria: [ 'Research question answered', 'Options documented', 'Recommendations provided', 'Decision criteria established' ] }, 'security-audit': { id: 'security-audit', name: 'Security Audit', description: 'Conduct security audit of system or component', category: 'operations', defaultValues: { priority: 'high', importance: 9, urgency: 6, estimatedEffort: 6, riskLevel: 'medium', tags: ['security', 'audit', 'compliance'] }, requiredFields: ['auditScope', 'complianceFramework'], successCriteria: [ 'Vulnerabilities identified', 'Risk assessment completed', 'Remediation plan created', 'Report generated' ] }, 'performance-optimization': { id: 'performance-optimization', name: 'Performance Optimization', description: 'Optimize system performance based on metrics', category: 'maintenance', defaultValues: { priority: 'medium', importance: 6, urgency: 4, estimatedEffort: 8, riskLevel: 'medium', tags: ['performance', 'optimization', 'metrics'] }, requiredFields: ['performanceMetrics', 'targetImprovement'], successCriteria: [ 'Baseline metrics captured', 'Optimizations implemented', 'Performance improved by target %', 'No regression in functionality' ] }, 'documentation-update': { id: 'documentation-update', name: 'Documentation Update', description: 'Update technical or user documentation', category: 'maintenance', defaultValues: { priority: 'low', importance: 5, urgency: 2, estimatedEffort: 3, riskLevel: 'low', tags: ['documentation', 'maintenance'] }, requiredFields: ['documentType', 'sections'], successCriteria: [ 'Documentation reviewed', 'Updates completed', 'Reviewed by stakeholders', 'Published to appropriate location' ] }, 'quarterly-planning': { id: 'quarterly-planning', name: 'Quarterly Planning', description: 'Plan goals and priorities for the quarter', category: 'planning', defaultValues: { priority: 'high', importance: 9, urgency: 7, estimatedEffort: 12, riskLevel: 'low', tags: ['planning', 'quarterly', 'strategy'] }, requiredFields: ['quarter', 'objectives'], successCriteria: [ 'Goals defined and prioritized', 'Resources allocated', 'Timeline established', 'Stakeholder alignment' ] }, 'custom-goal': { id: 'custom-goal', name: 'Custom Goal', description: 'Create a custom goal with your own parameters', category: 'custom', defaultValues: { priority: 'medium', importance: 5, urgency: 5, riskLevel: 'medium', tags: ['custom'] } } }; /** * Apply a goal template to create a new goal */ export function applyGoalTemplate(templateId, customFields) { // SECURITY FIX: Add audit logging for goal template usage SecurityMonitor.logSecurityEvent({ type: 'GOAL_TEMPLATE_APPLIED', severity: 'LOW', source: 'applyGoalTemplate', details: `Goal template '${templateId}' applied` }); const template = GOAL_TEMPLATES[templateId]; if (!template) { throw new Error(`Goal template '${templateId}' not found`); } // Validate required fields if (template.requiredFields) { for (const field of template.requiredFields) { if (!customFields[field]) { throw new Error(`Required field '${field}' missing for template '${template.name}'`); } } } // Calculate Eisenhower quadrant based on template defaults const importance = customFields.importance || template.defaultValues.importance; const urgency = customFields.urgency || template.defaultValues.urgency; const eisenhowerQuadrant = calculateEisenhowerQuadrant(importance, urgency); // Ensure description is provided const description = customFields.description || `${template.name}: ${template.requiredFields?.map(f => customFields[f]).filter(Boolean).join(' - ') || template.description}`; return { ...template.defaultValues, ...customFields, description, eisenhowerQuadrant, templateId, createdAt: new Date(), updatedAt: new Date() }; } /** * Calculate Eisenhower quadrant from importance and urgency */ function calculateEisenhowerQuadrant(importance, urgency) { if (importance >= 7 && urgency >= 7) return 'do_first'; if (importance >= 7 && urgency < 7) return 'schedule'; if (importance < 7 && urgency >= 7) return 'delegate'; return 'eliminate'; } /** * Get template recommendations based on goal description */ export function recommendGoalTemplate(description) { const lowercaseDesc = description.toLowerCase(); const recommendations = []; // Keywords mapping to templates const keywordMap = { 'feature-implementation': ['feature', 'implement', 'develop', 'build'], 'bug-fix-critical': ['bug', 'fix', 'critical', 'urgent', 'broken', 'error'], 'research-spike': ['research', 'explore', 'investigate', 'spike', 'evaluate'], 'security-audit': ['security', 'audit', 'vulnerability', 'compliance'], 'performance-optimization': ['performance', 'optimize', 'speed', 'slow', 'latency'], 'documentation-update': ['document', 'docs', 'readme', 'guide', 'manual'], 'quarterly-planning': ['plan', 'quarter', 'roadmap', 'strategy'] }; // Check for keyword matches for (const [templateId, keywords] of Object.entries(keywordMap)) { if (keywords.some(keyword => lowercaseDesc.includes(keyword))) { recommendations.push(templateId); } } // Always include custom as an option if (recommendations.length === 0) { recommendations.push('custom-goal'); } return recommendations; } /** * Validate goal against its template */ export function validateGoalAgainstTemplate(goal, // AgentGoal type templateId) { if (!templateId || !GOAL_TEMPLATES[templateId]) { return { valid: true, errors: [] }; } // SECURITY FIX: Add audit logging for template validation SecurityMonitor.logSecurityEvent({ type: 'GOAL_TEMPLATE_VALIDATION', severity: 'LOW', source: 'validateGoalAgainstTemplate', details: `Validating goal against template '${templateId}'` }); const template = GOAL_TEMPLATES[templateId]; const errors = []; // Check required fields if (template.requiredFields) { for (const field of template.requiredFields) { if (!goal[field]) { errors.push(`Missing required field: ${field}`); } } } // Validate risk level matches template category if (template.category === 'operations' && goal.riskLevel === 'high') { errors.push('High risk operations goals require additional approval'); } return { valid: errors.length === 0, errors }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ29hbFRlbXBsYXRlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9lbGVtZW50cy9hZ2VudHMvZ29hbFRlbXBsYXRlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFHSCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFxQnBFLDZCQUE2QjtBQUM3QixNQUFNLENBQUMsTUFBTSxjQUFjLEdBQWlDO0lBQzFELHdCQUF3QjtJQUN4Qix3QkFBd0IsRUFBRTtRQUN4QixFQUFFLEVBQUUsd0JBQXdCO1FBQzVCLElBQUksRUFBRSx3QkFBd0I7UUFDOUIsV0FBVyxFQUFFLCtEQUErRDtRQUM1RSxRQUFRLEVBQUUsYUFBYTtRQUN2QixhQUFhLEVBQUU7WUFDYixRQUFRLEVBQUUsTUFBTTtZQUNoQixVQUFVLEVBQUUsQ0FBQztZQUNiLE9BQU8sRUFBRSxDQUFDO1lBQ1YsZUFBZSxFQUFFLENBQUM7WUFDbEIsU0FBUyxFQUFFLFFBQVE7WUFDbkIsSUFBSSxFQUFFLENBQUMsU0FBUyxFQUFFLGFBQWEsRUFBRSxnQkFBZ0IsQ0FBQztTQUNuRDtRQUNELGNBQWMsRUFBRSxDQUFDLGFBQWEsRUFBRSxnQkFBZ0IsQ0FBQztRQUNqRCxlQUFlLEVBQUU7WUFDZiw2QkFBNkI7WUFDN0Isb0JBQW9CO1lBQ3BCLHVCQUF1QjtZQUN2QixlQUFlO1NBQ2hCO1FBQ0QsZUFBZSxFQUFFO1lBQ2YsK0JBQStCO1lBQy9CLDRCQUE0QjtZQUM1QiwwQkFBMEI7U0FDM0I7S0FDRjtJQUVELGtCQUFrQixFQUFFO1FBQ2xCLEVBQUUsRUFBRSxrQkFBa0I7UUFDdEIsSUFBSSxFQUFFLGtCQUFrQjtRQUN4QixXQUFXLEVBQUUsK0NBQStDO1FBQzVELFFBQVEsRUFBRSxhQUFhO1FBQ3ZCLGFBQWEsRUFBRTtZQUNiLFFBQVEsRUFBRSxVQUFVO1lBQ3BCLFVBQVUsRUFBRSxFQUFFO1lBQ2QsT0FBTyxFQUFFLEVBQUU7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cUNBQXFDLFVBQVUsR0FBRztLQUM1RCxDQUFDLENBQUM7SUFFSCxNQUFNLFFBQVEsR0FBRyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDNUMsTUFBTSxNQUFNLEdBQWEsRUFBRSxDQUFDO0lBRTVCLHdCQUF3QjtJQUN4QixJQUFJLFFBQVEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUM1QixLQUFLLE1BQU0sS0FBSyxJQUFJLFFBQVEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUM1QyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ2pCLE1BQU0sQ0FBQyxJQUFJLENBQUMsMkJBQTJCLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDbEQsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsZ0RBQWdEO0lBQ2hELElBQUksUUFBUSxDQUFDLFFBQVEsS0FBSyxZQUFZLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUNwRSxNQUFNLENBQUMsSUFBSSxDQUFDLHdEQUF3RCxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVELE9BQU87UUFDTCxLQUFLLEVBQUUsTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQzFCLE1BQU07S0FDUCxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR29hbCBUZW1wbGF0ZSBTeXN0ZW0gZm9yIEFnZW50IEdvYWwgTWFuYWdlbWVudFxuICogXG4gKiBQcm92aWRlcyBwcmUtY29uZmlndXJlZCBnb2FsIHRlbXBsYXRlcyBmb3IgY29tbW9uIHBhdHRlcm5zLFxuICogbWFraW5nIGl0IGVhc2llciB0byBjcmVhdGUgd2VsbC1zdHJ1Y3R1cmVkIGdvYWxzIHdpdGggYXBwcm9wcmlhdGVcbiAqIHNldHRpbmdzIGZvciBkaWZmZXJlbnQgc2NlbmFyaW9zLlxuICovXG5cbmltcG9ydCB7IEdvYWxQcmlvcml0eSwgR29hbFN0YXR1cywgRWlzZW5ob3dlclF1YWRyYW50IH0gZnJvbSAnLi90eXBlcy5qcyc7XG5pbXBvcnQgeyBTZWN1cml0eU1vbml0b3IgfSBmcm9tICcuLi8uLi9zZWN1cml0eS9zZWN1cml0eU1vbml0b3IuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEdvYWxUZW1wbGF0ZSB7XG4gIGlkOiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbiAgZGVzY3JpcHRpb246IHN0cmluZztcbiAgY2F0ZWdvcnk6ICdkZXZlbG9wbWVudCcgfCAnb3BlcmF0aW9ucycgfCAncmVzZWFyY2gnIHwgJ3BsYW5uaW5nJyB8ICdtYWludGVuYW5jZScgfCAnY3VzdG9tJztcbiAgZGVmYXVsdFZhbHVlczoge1xuICAgIHByaW9yaXR5OiBHb2FsUHJpb3JpdHk7XG4gICAgaW1wb3J0YW5jZTogbnVtYmVyOyAgLy8gMS0xMFxuICAgIHVyZ2VuY3k6IG51bWJlcjsgICAgIC8vIDEtMTBcbiAgICBlc3RpbWF0ZWRFZmZvcnQ/OiBudW1iZXI7ICAvLyBob3Vyc1xuICAgIHJpc2tMZXZlbD86ICdsb3cnIHwgJ21lZGl1bScgfCAnaGlnaCc7XG4gICAgdGFncz86IHN0cmluZ1tdO1xuICB9O1xuICByZXF1aXJlZEZpZWxkcz86IHN0cmluZ1tdO1xuICBzdWdnZXN0ZWREZXBlbmRlbmNpZXM/OiBzdHJpbmdbXTtcbiAgc3VjY2Vzc0NyaXRlcmlhPzogc3RyaW5nW107XG4gIHJpc2tNaXRpZ2F0aW9ucz86IHN0cmluZ1tdO1xufVxuXG4vLyBQcmUtZGVmaW5lZCBnb2FsIHRlbXBsYXRlc1xuZXhwb3J0IGNvbnN0IEdPQUxfVEVNUExBVEVTOiBSZWNvcmQ8c3RyaW5nLCBHb2FsVGVtcGxhdGU+ID0ge1xuICAvLyBEZXZlbG9wbWVudCB0ZW1wbGF0ZXNcbiAgJ2ZlYXR1cmUtaW1wbGVtZW50YXRpb24nOiB7XG4gICAgaWQ6ICdmZWF0dXJlLWltcGxlbWVudGF0aW9uJyxcbiAgICBuYW1lOiAnRmVhdHVyZSBJbXBsZW1lbnRhdGlvbicsXG4gICAgZGVzY3JpcHRpb246ICdJbXBsZW1lbnQgYSBuZXcgZmVhdHVyZSB3aXRoIHByb3BlciB0ZXN0aW5nIGFuZCBkb2N1bWVudGF0aW9uJyxcbiAgICBjYXRlZ29yeTogJ2RldmVsb3BtZW50JyxcbiAgICBkZWZhdWx0VmFsdWVzOiB7XG4gICAgICBwcmlvcml0eTogJ2hpZ2gnLFxuICAgICAgaW1wb3J0YW5jZTogOCxcbiAgICAgIHVyZ2VuY3k6IDUsXG4gICAgICBlc3RpbWF0ZWRFZmZvcnQ6IDgsXG4gICAgICByaXNrTGV2ZWw6ICdtZWRpdW0nLFxuICAgICAgdGFnczogWydmZWF0dXJlJywgJ2RldmVsb3BtZW50JywgJ2ltcGxlbWVudGF0aW9uJ11cbiAgICB9LFxuICAgIHJlcXVpcmVkRmllbGRzOiBbJ2ZlYXR1cmVOYW1lJywgJ3NwZWNpZmljYXRpb25zJ10sXG4gICAgc3VjY2Vzc0NyaXRlcmlhOiBbXG4gICAgICAnQ29kZSBpbXBsZW1lbnRlZCBhbmQgdGVzdGVkJyxcbiAgICAgICdVbml0IHRlc3RzIHBhc3NpbmcnLFxuICAgICAgJ0RvY3VtZW50YXRpb24gdXBkYXRlZCcsXG4gICAgICAnQ29kZSByZXZpZXdlZCdcbiAgICBdLFxuICAgIHJpc2tNaXRpZ2F0aW9uczogW1xuICAgICAgJ0JyZWFrIGRvd24gaW50byBzbWFsbGVyIHRhc2tzJyxcbiAgICAgICdFYXJseSBwcm90b3R5cGUgdmFsaWRhdGlvbicsXG4gICAgICAnUmVndWxhciBwcm9ncmVzcyByZXZpZXdzJ1xuICAgIF1cbiAgfSxcblxuICAnYnVnLWZpeC1jcml0aWNhbCc6IHtcbiAgICBpZDogJ2J1Zy1maXgtY3JpdGljYWwnLFxuICAgIG5hbWU6ICdDcml0aWNhbCBCdWcgRml4JyxcbiAgICBkZXNjcmlwdGlvbjogJ0ZpeCBhIGNyaXRpY2FsIHByb2R1Y3Rpb24gYnVnIGFmZmVjdGluZyB1c2VycycsXG4gICAgY2F0ZWdvcnk6ICdtYWludGVuYW5jZScsXG4gICAgZGVmYXVsdFZhbHVlczoge1xuICAgICAgcHJpb3JpdHk6ICdjcml0aWNhbCcsXG4gICAgICBpbXBvcnRhbmNlOiAxMCxcbiAgICAgIHVyZ2VuY3k6IDEwLFxuICAgICAgZXN0aW1hdGVkRWZmb3J0OiAyLFxuICAgICAgcmlza0xldmVsOiAnaGlnaCcsXG4gICAgICB0YWdzOiBbJ2J1ZycsICdjcml0aWNhbCcsICdwcm9kdWN0aW9uJ11cbiAgICB9LFxuICAgIHJlcXVpcmVkRmllbGRzOiBbJ2J1Z0lkJywgJ2ltcGFjdERlc2NyaXB0aW9uJ10sXG4gICAgc3VjY2Vzc0NyaXRlcmlhOiBbXG4gICAgICAnQnVnIGlkZW50aWZpZWQgYW5kIHJlcHJvZHVjZWQnLFxuICAgICAgJ0ZpeCBpbXBsZW1lbnRlZCBhbmQgdGVzdGVkJyxcbiAgICAgICdSZWdyZXNzaW9uIHRlc3RzIGFkZGVkJyxcbiAgICAgICdEZXBsb3llZCB0byBwcm9kdWN0aW9uJ1xuICAgIF0sXG4gICAgcmlza01pdGlnYXRpb25zOiBbXG4gICAgICAnUm9sbGJhY2sgcGxhbiBwcmVwYXJlZCcsXG4gICAgICAnVGhvcm91Z2ggdGVzdGluZyBpbiBzdGFnaW5nJyxcbiAgICAgICdNb25pdG9yIGFmdGVyIGRlcGxveW1lbnQnXG4gICAgXVxuICB9LFxuXG4gICdyZXNlYXJjaC1zcGlrZSc6IHtcbiAgICBpZDogJ3Jlc2VhcmNoLXNwaWtlJyxcbiAgICBuYW1lOiAnUmVzZWFyY2ggU3Bpa2UnLFxuICAgIGRlc2NyaXB0aW9uOiAnVGltZS1ib3hlZCByZXNlYXJjaCB0byBleHBsb3JlIHRlY2huaWNhbCBvcHRpb25zJyxcbiAgICBjYXRlZ29yeTogJ3Jlc2VhcmNoJyxcbiAgICBkZWZhdWx0VmFsdWVzOiB7XG4gICAgICBwcmlvcml0eTogJ21lZGl1bScsXG4gICAgICBpbXBvcnRhbmNlOiA3LFxuICAgICAgdXJnZW5jeTogMyxcbiAgICAgIGVzdGltYXRlZEVmZm9ydDogNCxcbiAgICAgIHJpc2tMZXZlbDogJ2xvdycsXG4gICAgICB0YWdzOiBbJ3Jlc2VhcmNoJywgJ3NwaWtlJywgJ2V4cGxvcmF0aW9uJ11cbiAgICB9LFxuICAgIHJlcXVpcmVkRmllbGRzOiBbJ3Jlc2VhcmNoUXVlc3Rpb24nLCAndGltZUJveCddLFxuICAgIHN1Y2Nlc3NDcml0ZXJpYTogW1xuICAgICAgJ1Jlc2VhcmNoIHF1ZXN0aW9uIGFuc3dlcmVkJyxcbiAgICAgICdPcHRpb25zIGRvY3VtZW50ZWQnLFxuICAgICAgJ1JlY29tbWVuZGF0aW9ucyBwcm92aWRlZCcsXG4gICAgICAnRGVjaXNpb24gY3JpdGVyaWEgZXN0YWJsaXNoZWQnXG4gICAgXVxuICB9LFxuXG4gICdzZWN1cml0eS1hdWRpdCc6IHtcbiAgICBpZDogJ3NlY3VyaXR5LWF1ZGl0JyxcbiAgICBuYW1lOiAnU2VjdXJpdHkgQXVkaXQnLFxuICAgIGRlc2NyaXB0aW9uOiAnQ29uZHVjdCBzZWN1cml0eSBhdWRpdCBvZiBzeXN0ZW0gb3IgY29tcG9uZW50JyxcbiAgICBjYXRlZ29yeTogJ29wZXJhdGlvbnMnLFxuICAgIGRlZmF1bHRWYWx1ZXM6IHtcbiAgICAgIHByaW9yaXR5OiAnaGlnaCcsXG4gICAgICBpbXBvcnRhbmNlOiA5LFxuICAgICAgdXJnZW5jeTogNixcbiAgICAgIGVzdGltYXRlZEVmZm9ydDogNixcbiAgICAgIHJpc2tMZXZlbDogJ21lZGl1bScsXG4gICAgICB0YWdzOiBbJ3NlY3VyaXR5JywgJ2F1ZGl0JywgJ2NvbXBsaWFuY2UnXVxuICAgIH0sXG4gICAgcmVxdWlyZWRGaWVsZHM6IFsnYXVkaXRTY29wZScsICdjb21wbGlhbmNlRnJhbWV3b3JrJ10sXG4gICAgc3VjY2Vzc0NyaXRlcmlhOiBbXG4gICAgICAnVnVsbmVyYWJpbGl0aWVzIGlkZW50aWZpZWQnLFxuICAgICAgJ1Jpc2sgYXNzZXNzbWVudCBjb21wbGV0ZWQnLFxuICAgICAgJ1JlbWVkaWF0aW9uIHBsYW4gY3JlYXRlZCcsXG4gICAgICAnUmVwb3J0IGdlbmVyYXRlZCdcbiAgICBdXG4gIH0sXG5cbiAgJ3BlcmZvcm1hbmNlLW9wdGltaXphdGlvbic6IHtcbiAgICBpZDogJ3BlcmZvcm1hbmNlLW9wdGltaXphdGlvbicsXG4gICAgbmFtZTogJ1BlcmZvcm1hbmNlIE9wdGltaXphdGlvbicsXG4gICAgZGVzY3JpcHRpb246ICdPcHRpbWl6ZSBzeXN0ZW0gcGVyZm9ybWFuY2UgYmFzZWQgb24gbWV0cmljcycsXG4gICAgY2F0ZWdvcnk6ICdtYWludGVuYW5jZScsXG4gICAgZGVmYXVsdFZhbHVlczoge1xuICAgICAgcHJpb3JpdHk6ICdtZWRpdW0nLFxuICAgICAgaW1wb3J0YW5jZTogNixcbiAgICAgIHVyZ2VuY3k6IDQsXG4gICAgICBlc3RpbWF0ZWRFZmZvcnQ6IDgsXG4gICAgICByaXNrTGV2ZWw6ICdtZWRpdW0nLFxuICAgICAgdGFnczogWydwZXJmb3JtYW5jZScsICdvcHRpbWl6YXRpb24nLCAnbWV0cmljcyddXG4gICAgfSxcbiAgICByZXF1aXJlZEZpZWxkczogWydwZXJmb3JtYW5jZU1ldHJpY3MnLCAndGFyZ2V0SW1wcm92ZW1lbnQnXSxcbiAgICBzdWNjZXNzQ3JpdGVyaWE6IFtcbiAgICAgICdCYXNlbGluZSBtZXRyaWNzIGNhcHR1cmVkJyxcbiAgICAgICdPcHRpbWl6YXRpb25zIGltcGxlbWVudGVkJyxcbiAgICAgICdQZXJmb3JtYW5jZSBpbXByb3ZlZCBieSB0YXJnZXQgJScsXG4gICAgICAnTm8gcmVncmVzc2lvbiBpbiBmdW5jdGlvbmFsaXR5J1xuICAgIF1cbiAgfSxcblxuICAnZG9jdW1lbnRhdGlvbi11cGRhdGUnOiB7XG4gICAgaWQ6ICdkb2N1bWVudGF0aW9uLXVwZGF0ZScsXG4gICAgbmFtZTogJ0RvY3VtZW50YXRpb24gVXBkYXRlJyxcbiAgICBkZXNjcmlwdGlvbjogJ1VwZGF0ZSB0ZWNobmljYWwgb3IgdXNlciBkb2N1bWVudGF0aW9uJyxcbiAgICBjYXRlZ29yeTogJ21haW50ZW5hbmNlJyxcbiAgICBkZWZhdWx0VmFsdWVzOiB7XG4gICAgICBwcmlvcml0eTogJ2xvdycsXG4gICAgICBpbXBvcnRhbmNlOiA1LFxuICAgICAgdXJnZW5jeTogMixcbiAgICAgIGVzdGltYXRlZEVmZm9ydDogMyxcbiAgICAgIHJpc2tMZXZlbDogJ2xvdycsXG4gICAgICB0YWdzOiBbJ2RvY3VtZW50YXRpb24nLCAnbWFpbnRlbmFuY2UnXVxuICAgIH0sXG4gICAgcmVxdWlyZWRGaWVsZHM6IFsnZG9jdW1lbnRUeXBlJywgJ3NlY3Rpb25zJ10sXG4gICAgc3VjY2Vzc0NyaXRlcmlhOiBbXG4gICAgICAnRG9jdW1lbnRhdGlvbiByZXZpZXdlZCcsXG4gICAgICAnVXBkYXRlcyBjb21wbGV0ZWQnLFxuICAgICAgJ1Jldmlld2VkIGJ5IHN0YWtlaG9sZGVycycsXG4gICAgICAnUHVibGlzaGVkIHRvIGFwcHJvcHJpYXRlIGxvY2F0aW9uJ1xuICAgIF1cbiAgfSxcblxuICAncXVhcnRlcmx5LXBsYW5uaW5nJzoge1xuICAgIGlkOiAncXVhcnRlcmx5LXBsYW5uaW5nJyxcbiAgICBuYW1lOiAnUXVhcnRlcmx5IFBsYW5uaW5nJyxcbiAgICBkZXNjcmlwdGlvbjogJ1BsYW4gZ29hbHMgYW5kIHByaW9yaXRpZXMgZm9yIHRoZSBxdWFydGVyJyxcbiAgICBjYXRlZ29yeTogJ3BsYW5uaW5nJyxcbiAgICBkZWZhdWx0VmFsdWVzOiB7XG4gICAgICBwcmlvcml0eTogJ2hpZ2gnLFxuICAgICAgaW1wb3J0YW5jZTogOSxcbiAgICAgIHVyZ2VuY3k6IDcsXG4gICAgICBlc3RpbWF0ZWRFZmZvcnQ6IDEyLFxuICAgICAgcmlza0xldmVsOiAnbG93JyxcbiAgICAgIHRhZ3M6IFsncGxhbm5pbmcnLCAncXVhcnRlcmx5JywgJ3N0cmF0ZWd5J11cbiAgICB9LFxuICAgIHJlcXVpcmVkRmllbGRzOiBbJ3F1YXJ0ZXInLCAnb2JqZWN0aXZlcyddLFxuICAgIHN1Y2Nlc3NDcml0ZXJpYTogW1xuICAgICAgJ0dvYWxzIGRlZmluZWQgYW5kIHByaW9yaXRpemVkJyxcbiAgICAgICdSZXNvdXJjZXMgYWxsb2NhdGVkJyxcbiAgICAgICdUaW1lbGluZSBlc3RhYmxpc2hlZCcsXG4gICAgICAnU3Rha2Vob2xkZXIgYWxpZ25tZW50J1xuICAgIF1cbiAgfSxcblxuICAnY3VzdG9tLWdvYWwnOiB7XG4gICAgaWQ6ICdjdXN0b20tZ29hbCcsXG4gICAgbmFtZTogJ0N1c3RvbSBHb2FsJyxcbiAgICBkZXNjcmlwdGlvbjogJ0NyZWF0ZSBhIGN1c3RvbSBnb2FsIHdpdGggeW91ciBvd24gcGFyYW1ldGVycycsXG4gICAgY2F0ZWdvcnk6ICdjdXN0b20nLFxuICAgIGRlZmF1bHRWYWx1ZXM6IHtcbiAgICAgIHByaW9yaXR5OiAnbWVkaXVtJyxcbiAgICAgIGltcG9ydGFuY2U6IDUsXG4gICAgICB1cmdlbmN5OiA1LFxuICAgICAgcmlza0xldmVsOiAnbWVkaXVtJyxcbiAgICAgIHRhZ3M6IFsnY3VzdG9tJ11cbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogQXBwbHkgYSBnb2FsIHRlbXBsYXRlIHRvIGNyZWF0ZSBhIG5ldyBnb2FsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseUdvYWxUZW1wbGF0ZShcbiAgdGVtcGxhdGVJZDogc3RyaW5nLFxuICBjdXN0b21GaWVsZHM6IFJlY29yZDxzdHJpbmcsIGFueT5cbik6IFBhcnRpYWw8YW55PiB7ICAvLyBSZXR1cm5zIHBhcnRpYWwgQWdlbnRHb2FsXG4gIC8vIFNFQ1VSSVRZIEZJWDogQWRkIGF1ZGl0IGxvZ2dpbmcgZm9yIGdvYWwgdGVtcGxhdGUgdXNhZ2VcbiAgU2VjdXJpdHlNb25pdG9yLmxvZ1NlY3VyaXR5RXZlbnQoe1xuICAgIHR5cGU6ICdHT0FMX1RFTVBMQVRFX0FQUExJRUQnLFxuICAgIHNldmVyaXR5OiAnTE9XJyxcbiAgICBzb3VyY2U6ICdhcHBseUdvYWxUZW1wbGF0ZScsXG4gICAgZGV0YWlsczogYEdvYWwgdGVtcGxhdGUgJyR7dGVtcGxhdGVJZH0nIGFwcGxpZWRgXG4gIH0pO1xuXG4gIGNvbnN0IHRlbXBsYXRlID0gR09BTF9URU1QTEFURVNbdGVtcGxhdGVJZF07XG4gIGlmICghdGVtcGxhdGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEdvYWwgdGVtcGxhdGUgJyR7dGVtcGxhdGVJZH0nIG5vdCBmb3VuZGApO1xuICB9XG5cbiAgLy8gVmFsaWRhdGUgcmVxdWlyZWQgZmllbGRzXG4gIGlmICh0ZW1wbGF0ZS5yZXF1aXJlZEZpZWxkcykge1xuICAgIGZvciAoY29uc3QgZmllbGQgb2YgdGVtcGxhdGUucmVxdWlyZWRGaWVsZHMpIHtcbiAgICAgIGlmICghY3VzdG9tRmllbGRzW2ZpZWxkXSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlcXVpcmVkIGZpZWxkICcke2ZpZWxkfScgbWlzc2luZyBmb3IgdGVtcGxhdGUgJyR7dGVtcGxhdGUubmFtZX0nYCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gQ2FsY3VsYXRlIEVpc2VuaG93ZXIgcXVhZHJhbnQgYmFzZWQgb24gdGVtcGxhdGUgZGVmYXVsdHNcbiAgY29uc3QgaW1wb3J0YW5jZSA9IGN1c3RvbUZpZWxkcy5pbXBvcnRhbmNlIHx8IHRlbXBsYXRlLmRlZmF1bHRWYWx1ZXMuaW1wb3J0YW5jZTtcbiAgY29uc3QgdXJnZW5jeSA9IGN1c3RvbUZpZWxkcy51cmdlbmN5IHx8IHRlbXBsYXRlLmRlZmF1bHRWYWx1ZXMudXJnZW5jeTtcbiAgY29uc3QgZWlzZW5ob3dlclF1YWRyYW50ID0gY2FsY3VsYXRlRWlzZW5ob3dlclF1YWRyYW50KGltcG9ydGFuY2UsIHVyZ2VuY3kpO1xuXG4gIC8vIEVuc3VyZSBkZXNjcmlwdGlvbiBpcyBwcm92aWRlZFxuICBjb25zdCBkZXNjcmlwdGlvbiA9IGN1c3RvbUZpZWxkcy5kZXNjcmlwdGlvbiB8fCBcbiAgICBgJHt0ZW1wbGF0ZS5uYW1lfTogJHt0ZW1wbGF0ZS5yZXF1aXJlZEZpZWxkcz8ubWFwKGYgPT4gY3VzdG9tRmllbGRzW2ZdKS5maWx0ZXIoQm9vbGVhbikuam9pbignIC0gJykgfHwgdGVtcGxhdGUuZGVzY3JpcHRpb259YDtcblxuICByZXR1cm4ge1xuICAgIC4uLnRlbXBsYXRlLmRlZmF1bHRWYWx1ZXMsXG4gICAgLi4uY3VzdG9tRmllbGRzLFxuICAgIGRlc2NyaXB0aW9uLFxuICAgIGVpc2VuaG93ZXJRdWFkcmFudCxcbiAgICB0ZW1wbGF0ZUlkLFxuICAgIGNyZWF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICB1cGRhdGVkQXQ6IG5ldyBEYXRlKClcbiAgfTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgRWlzZW5ob3dlciBxdWFkcmFudCBmcm9tIGltcG9ydGFuY2UgYW5kIHVyZ2VuY3lcbiAqL1xuZnVuY3Rpb24gY2FsY3VsYXRlRWlzZW5ob3dlclF1YWRyYW50KGltcG9ydGFuY2U6IG51bWJlciwgdXJnZW5jeTogbnVtYmVyKTogRWlzZW5ob3dlclF1YWRyYW50IHtcbiAgaWYgKGltcG9ydGFuY2UgPj0gNyAmJiB1cmdlbmN5ID49IDcpIHJldHVybiAnZG9fZmlyc3QnO1xuICBpZiAoaW1wb3J0YW5jZSA+PSA3ICYmIHVyZ2VuY3kgPCA3KSByZXR1cm4gJ3NjaGVkdWxlJztcbiAgaWYgKGltcG9ydGFuY2UgPCA3ICYmIHVyZ2VuY3kgPj0gNykgcmV0dXJuICdkZWxlZ2F0ZSc7XG4gIHJldHVybiAnZWxpbWluYXRlJztcbn1cblxuLyoqXG4gKiBHZXQgdGVtcGxhdGUgcmVjb21tZW5kYXRpb25zIGJhc2VkIG9uIGdvYWwgZGVzY3JpcHRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlY29tbWVuZEdvYWxUZW1wbGF0ZShkZXNjcmlwdGlvbjogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBsb3dlcmNhc2VEZXNjID0gZGVzY3JpcHRpb24udG9Mb3dlckNhc2UoKTtcbiAgY29uc3QgcmVjb21tZW5kYXRpb25zOiBzdHJpbmdbXSA9IFtdO1xuXG4gIC8vIEtleXdvcmRzIG1hcHBpbmcgdG8gdGVtcGxhdGVzXG4gIGNvbnN0IGtleXdvcmRNYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiA9IHtcbiAgICAnZmVhdHVyZS1pbXBsZW1lbnRhdGlvbic6IFsnZmVhdHVyZScsICdpbXBsZW1lbnQnLCAnZGV2ZWxvcCcsICdidWlsZCddLFxuICAgICdidWctZml4LWNyaXRpY2FsJzogWydidWcnLCAnZml4JywgJ2NyaXRpY2FsJywgJ3VyZ2VudCcsICdicm9rZW4nLCAnZXJyb3InXSxcbiAgICAncmVzZWFyY2gtc3Bpa2UnOiBbJ3Jlc2VhcmNoJywgJ2V4cGxvcmUnLCAnaW52ZXN0aWdhdGUnLCAnc3Bpa2UnLCAnZXZhbHVhdGUnXSxcbiAgICAnc2VjdXJpdHktYXVkaXQnOiBbJ3NlY3VyaXR5JywgJ2F1ZGl0JywgJ3Z1bG5lcmFiaWxpdHknLCAnY29tcGxpYW5jZSddLFxuICAgICdwZXJmb3JtYW5jZS1vcHRpbWl6YXRpb24nOiBbJ3BlcmZvcm1hbmNlJywgJ29wdGltaXplJywgJ3NwZWVkJywgJ3Nsb3cnLCAnbGF0ZW5jeSddLFxuICAgICdkb2N1bWVudGF0aW9uLXVwZGF0ZSc6IFsnZG9jdW1lbnQnLCAnZG9jcycsICdyZWFkbWUnLCAnZ3VpZGUnLCAnbWFudWFsJ10sXG4gICAgJ3F1YXJ0ZXJseS1wbGFubmluZyc6IFsncGxhbicsICdxdWFydGVyJywgJ3JvYWRtYXAnLCAnc3RyYXRlZ3knXVxuICB9O1xuXG4gIC8vIENoZWNrIGZvciBrZXl3b3JkIG1hdGNoZXNcbiAgZm9yIChjb25zdCBbdGVtcGxhdGVJZCwga2V5d29yZHNdIG9mIE9iamVjdC5lbnRyaWVzKGtleXdvcmRNYXApKSB7XG4gICAgaWYgKGtleXdvcmRzLnNvbWUoa2V5d29yZCA9PiBsb3dlcmNhc2VEZXNjLmluY2x1ZGVzKGtleXdvcmQpKSkge1xuICAgICAgcmVjb21tZW5kYXRpb25zLnB1c2godGVtcGxhdGVJZCk7XG4gICAgfVxuICB9XG5cbiAgLy8gQWx3YXlzIGluY2x1ZGUgY3VzdG9tIGFzIGFuIG9wdGlvblxuICBpZiAocmVjb21tZW5kYXRpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgIHJlY29tbWVuZGF0aW9ucy5wdXNoKCdjdXN0b20tZ29hbCcpO1xuICB9XG5cbiAgcmV0dXJuIHJlY29tbWVuZGF0aW9ucztcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBnb2FsIGFnYWluc3QgaXRzIHRlbXBsYXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUdvYWxBZ2FpbnN0VGVtcGxhdGUoXG4gIGdvYWw6IGFueSwgIC8vIEFnZW50R29hbCB0eXBlXG4gIHRlbXBsYXRlSWQ/OiBzdHJpbmdcbik6IHsgdmFsaWQ6IGJvb2xlYW47IGVycm9yczogc3RyaW5nW10gfSB7XG4gIGlmICghdGVtcGxhdGVJZCB8fCAhR09BTF9URU1QTEFURVNbdGVtcGxhdGVJZF0pIHtcbiAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgZXJyb3JzOiBbXSB9O1xuICB9XG5cbiAgLy8gU0VDVVJJVFkgRklYOiBBZGQgYXVkaXQgbG9nZ2luZyBmb3IgdGVtcGxhdGUgdmFsaWRhdGlvblxuICBTZWN1cml0eU1vbml0b3IubG9nU2VjdXJpdHlFdmVudCh7XG4gICAgdHlwZTogJ0dPQUxfVEVNUExBVEVfVkFMSURBVElPTicsXG4gICAgc2V2ZXJpdHk6ICdMT1cnLFxuICAgIHNvdXJjZTogJ3ZhbGlkYXRlR29hbEFnYWluc3RUZW1wbGF0ZScsXG4gICAgZGV0YWlsczogYFZhbGlkYXRpbmcgZ29hbCBhZ2FpbnN0IHRlbXBsYXRlICcke3RlbXBsYXRlSWR9J2BcbiAgfSk7XG5cbiAgY29uc3QgdGVtcGxhdGUgPSBHT0FMX1RFTVBMQVRFU1t0ZW1wbGF0ZUlkXTtcbiAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIC8vIENoZWNrIHJlcXVpcmVkIGZpZWxkc1xuICBpZiAodGVtcGxhdGUucmVxdWlyZWRGaWVsZHMpIHtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHRlbXBsYXRlLnJlcXVpcmVkRmllbGRzKSB7XG4gICAgICBpZiAoIWdvYWxbZmllbGRdKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKGBNaXNzaW5nIHJlcXVpcmVkIGZpZWxkOiAke2ZpZWxkfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFZhbGlkYXRlIHJpc2sgbGV2ZWwgbWF0Y2hlcyB0ZW1wbGF0ZSBjYXRlZ29yeVxuICBpZiAodGVtcGxhdGUuY2F0ZWdvcnkgPT09ICdvcGVyYXRpb25zJyAmJiBnb2FsLnJpc2tMZXZlbCA9PT0gJ2hpZ2gnKSB7XG4gICAgZXJyb3JzLnB1c2goJ0hpZ2ggcmlzayBvcGVyYXRpb25zIGdvYWxzIHJlcXVpcmUgYWRkaXRpb25hbCBhcHByb3ZhbCcpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB2YWxpZDogZXJyb3JzLmxlbmd0aCA9PT0gMCxcbiAgICBlcnJvcnNcbiAgfTtcbn0iXX0=