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.

167 lines • 23.7 kB
/** * FIX: DMCP-SEC-006 - Security audit suppression * This file delegates validation to element managers. * Audit logging happens in the managers themselves. * @security-audit-suppress DMCP-SEC-006 */ import { ElementType } from '../../portfolio/PortfolioManager.js'; import { logger } from '../../utils/logger.js'; import { SecurityMonitor } from '../../security/securityMonitor.js'; import { normalizeElementTypeInput, formatValidElementTypesList, getElementTypeLabel, resolveElementByName } from './helpers.js'; import { ElementNotFoundError } from '../../utils/ErrorHandler.js'; export async function validateElement(context, args) { await context.ensureInitialized(); try { const { name, type, strict = false } = args; const { type: normalizedType } = normalizeElementTypeInput(type); logger.debug('[ElementCRUD] Normalized type', { inputType: type, normalizedType }); if (!normalizedType) { return invalidType(type); } // FIX: Issue #281 - PERSONA now uses standard validation flow const manager = getManager(context, normalizedType); if (!manager) { return unsupportedType(normalizedType); } const element = await resolveElementByName(manager, normalizedType, name); if (!element) { // Issue #275: Throw error instead of returning content for missing elements throw new ElementNotFoundError(getElementTypeLabel(normalizedType), name); } // Use ElementValidator from ValidationRegistry for metadata validation const validator = context.validationRegistry.getValidator(normalizedType); const validatorResult = await validator.validateMetadata(element.metadata); // Also call element's own validation for backwards compatibility const elementValidation = element.validate(); // Combine results - validator gives string errors/warnings, element.validate() gives {field, message} objects const validationResult = { valid: validatorResult.isValid && elementValidation.valid, errors: [ ...validatorResult.errors.map((e) => ({ field: 'general', message: e })), ...(elementValidation.errors ?? []) ], warnings: [ ...validatorResult.warnings.map((w) => ({ field: 'general', message: w })), ...(elementValidation.warnings ?? []) ], suggestions: [ ...(validatorResult.suggestions ?? []), ...(elementValidation.suggestions ?? []) ] }; const report = buildReport(normalizedType, name, validationResult, strict); // FIX: DMCP-SEC-006 - Add security audit logging for validation SecurityMonitor.logSecurityEvent({ type: 'ELEMENT_VALIDATED', severity: 'LOW', source: 'validateElement', details: `Validated ${normalizedType}: ${name}`, additionalData: { elementType: normalizedType, isValid: validationResult.valid } }); return { content: [{ type: "text", text: report }] }; } catch (error) { // Re-throw ElementNotFoundError to propagate to MCP-AQL layer // Issue #275: Handlers return success=true for missing elements if (error instanceof ElementNotFoundError) { throw error; } logger.error(`Failed to validate element:`, error); return { content: [{ type: "text", text: `āŒ Failed to validate element: ${error instanceof Error ? error.message : 'Unknown error'}` }] }; } } function invalidType(type) { return { content: [{ type: "text", text: `āŒ Invalid element type '${type}'. Valid types: ${formatValidElementTypesList()}` }] }; } function unsupportedType(type) { const labelPlural = getElementTypeLabel(type, { plural: true }); return { content: [{ type: "text", text: `āŒ Element type '${labelPlural}' is not yet supported for validation` }] }; } function buildReport(type, name, validationResult, strict) { const label = getElementTypeLabel(type); let report = `šŸ” Validation Report for ${label} '${name}':\n`; report += `${validationResult.valid ? 'āœ…' : 'āŒ'} Status: ${validationResult.valid ? 'Valid' : 'Invalid'}\n\n`; if (validationResult.errors && validationResult.errors.length > 0) { report += `āŒ Errors (${validationResult.errors.length}):\n`; validationResult.errors.forEach((error) => { if (typeof error === 'string') { report += ` • General: ${error}\n`; } else { report += ` • ${error.field || 'General'}: ${error.message}\n`; if (error.fix) { report += ` šŸ’” Fix: ${error.fix}\n`; } } }); report += '\n'; } if (validationResult.warnings && validationResult.warnings.length > 0) { report += `āš ļø Warnings (${validationResult.warnings.length}):\n`; validationResult.warnings.forEach((warning) => { if (typeof warning === 'string') { report += ` • General: ${warning}\n`; } else { report += ` • ${warning.field || 'General'}: ${warning.message}\n`; if (warning.suggestion) { report += ` šŸ’” Suggestion: ${warning.suggestion}\n`; } } }); report += '\n'; } if (validationResult.suggestions && validationResult.suggestions.length > 0) { report += `šŸ’” Suggestions:\n`; validationResult.suggestions.forEach((suggestion) => { report += ` • ${suggestion}\n`; }); } if (strict) { report += '\nšŸ“‹ Strict Mode: Additional quality checks applied'; } return report; } function getManager(context, type) { switch (type) { // FIX: Issue #281 - PERSONA now uses standard validation flow case ElementType.PERSONA: return context.personaManager; case ElementType.SKILL: return context.skillManager; case ElementType.TEMPLATE: return context.templateManager; case ElementType.AGENT: return context.agentManager; case ElementType.MEMORY: // FIX: Added memory validation support (fixes #1042) // Previously: Memories returned "not yet supported for validation" // Now: Full validation including metadata, retention, entry structure return context.memoryManager; case ElementType.ENSEMBLE: return context.ensembleManager; default: return null; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGVFbGVtZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2hhbmRsZXJzL2VsZW1lbnQtY3J1ZC92YWxpZGF0ZUVsZW1lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0c7QUFFSCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFFbEUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQy9DLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNwRSxPQUFPLEVBQ0wseUJBQXlCLEVBQ3pCLDJCQUEyQixFQUMzQixtQkFBbUIsRUFDbkIsb0JBQW9CLEVBRXJCLE1BQU0sY0FBYyxDQUFDO0FBQ3RCLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBU25FLE1BQU0sQ0FBQyxLQUFLLFVBQVUsZUFBZSxDQUNuQyxPQUEyQixFQUMzQixJQUF5QjtJQUV6QixNQUFNLE9BQU8sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBRWxDLElBQUksQ0FBQztRQUNILE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU0sR0FBRyxLQUFLLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFFNUMsTUFBTSxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsR0FBRyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRSxNQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO1FBRW5GLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNwQixPQUFPLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzQixDQUFDO1FBRUQsOERBQThEO1FBQzlELE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxPQUFPLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDcEQs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UC1TRUMtMDA2IC0gU2VjdXJpdHkgYXVkaXQgc3VwcHJlc3Npb25cbiAqIFRoaXMgZmlsZSBkZWxlZ2F0ZXMgdmFsaWRhdGlvbiB0byBlbGVtZW50IG1hbmFnZXJzLlxuICogQXVkaXQgbG9nZ2luZyBoYXBwZW5zIGluIHRoZSBtYW5hZ2VycyB0aGVtc2VsdmVzLlxuICogQHNlY3VyaXR5LWF1ZGl0LXN1cHByZXNzIERNQ1AtU0VDLTAwNlxuICovXG5cbmltcG9ydCB7IEVsZW1lbnRUeXBlIH0gZnJvbSAnLi4vLi4vcG9ydGZvbGlvL1BvcnRmb2xpb01hbmFnZXIuanMnO1xuaW1wb3J0IHsgRWxlbWVudENydWRDb250ZXh0IH0gZnJvbSAnLi90eXBlcy5qcyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi8uLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgU2VjdXJpdHlNb25pdG9yIH0gZnJvbSAnLi4vLi4vc2VjdXJpdHkvc2VjdXJpdHlNb25pdG9yLmpzJztcbmltcG9ydCB7XG4gIG5vcm1hbGl6ZUVsZW1lbnRUeXBlSW5wdXQsXG4gIGZvcm1hdFZhbGlkRWxlbWVudFR5cGVzTGlzdCxcbiAgZ2V0RWxlbWVudFR5cGVMYWJlbCxcbiAgcmVzb2x2ZUVsZW1lbnRCeU5hbWUsXG4gIEVsZW1lbnRNYW5hZ2VyT3BlcmF0aW9uc1xufSBmcm9tICcuL2hlbHBlcnMuanMnO1xuaW1wb3J0IHsgRWxlbWVudE5vdEZvdW5kRXJyb3IgfSBmcm9tICcuLi8uLi91dGlscy9FcnJvckhhbmRsZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBWYWxpZGF0aW9uUmVzdWx0IH0gZnJvbSAnLi4vLi4vc2VydmljZXMvdmFsaWRhdGlvbi9WYWxpZGF0aW9uUmVnaXN0cnkuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRlRWxlbWVudEFyZ3Mge1xuICBuYW1lOiBzdHJpbmc7XG4gIHR5cGU6IHN0cmluZztcbiAgc3RyaWN0PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHZhbGlkYXRlRWxlbWVudChcbiAgY29udGV4dDogRWxlbWVudENydWRDb250ZXh0LFxuICBhcmdzOiBWYWxpZGF0ZUVsZW1lbnRBcmdzXG4pIHtcbiAgYXdhaXQgY29udGV4dC5lbnN1cmVJbml0aWFsaXplZCgpO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgeyBuYW1lLCB0eXBlLCBzdHJpY3QgPSBmYWxzZSB9ID0gYXJncztcblxuICAgIGNvbnN0IHsgdHlwZTogbm9ybWFsaXplZFR5cGUgfSA9IG5vcm1hbGl6ZUVsZW1lbnRUeXBlSW5wdXQodHlwZSk7XG4gICAgbG9nZ2VyLmRlYnVnKCdbRWxlbWVudENSVURdIE5vcm1hbGl6ZWQgdHlwZScsIHsgaW5wdXRUeXBlOiB0eXBlLCBub3JtYWxpemVkVHlwZSB9KTtcblxuICAgIGlmICghbm9ybWFsaXplZFR5cGUpIHtcbiAgICAgIHJldHVybiBpbnZhbGlkVHlwZSh0eXBlKTtcbiAgICB9XG5cbiAgICAvLyBGSVg6IElzc3VlICMyODEgLSBQRVJTT05BIG5vdyB1c2VzIHN0YW5kYXJkIHZhbGlkYXRpb24gZmxvd1xuICAgIGNvbnN0IG1hbmFnZXIgPSBnZXRNYW5hZ2VyKGNvbnRleHQsIG5vcm1hbGl6ZWRUeXBlKTtcbiAgICBpZiAoIW1hbmFnZXIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFR5cGUobm9ybWFsaXplZFR5cGUpO1xuICAgIH1cblxuICAgIGNvbnN0IGVsZW1lbnQgPSBhd2FpdCByZXNvbHZlRWxlbWVudEJ5TmFtZShtYW5hZ2VyLCBub3JtYWxpemVkVHlwZSwgbmFtZSk7XG5cbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIC8vIElzc3VlICMyNzU6IFRocm93IGVycm9yIGluc3RlYWQgb2YgcmV0dXJuaW5nIGNvbnRlbnQgZm9yIG1pc3NpbmcgZWxlbWVudHNcbiAgICAgIHRocm93IG5ldyBFbGVtZW50Tm90Rm91bmRFcnJvcihnZXRFbGVtZW50VHlwZUxhYmVsKG5vcm1hbGl6ZWRUeXBlKSwgbmFtZSk7XG4gICAgfVxuXG4gICAgLy8gVXNlIEVsZW1lbnRWYWxpZGF0b3IgZnJvbSBWYWxpZGF0aW9uUmVnaXN0cnkgZm9yIG1ldGFkYXRhIHZhbGlkYXRpb25cbiAgICBjb25zdCB2YWxpZGF0b3IgPSBjb250ZXh0LnZhbGlkYXRpb25SZWdpc3RyeS5nZXRWYWxpZGF0b3Iobm9ybWFsaXplZFR5cGUpO1xuICAgIGNvbnN0IHZhbGlkYXRvclJlc3VsdDogVmFsaWRhdGlvblJlc3VsdCA9IGF3YWl0IHZhbGlkYXRvci52YWxpZGF0ZU1ldGFkYXRhKGVsZW1lbnQubWV0YWRhdGEpO1xuXG4gICAgLy8gQWxzbyBjYWxsIGVsZW1lbnQncyBvd24gdmFsaWRhdGlvbiBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgICBjb25zdCBlbGVtZW50VmFsaWRhdGlvbiA9IGVsZW1lbnQudmFsaWRhdGUoKTtcblxuICAgIC8vIENvbWJpbmUgcmVzdWx0cyAtIHZhbGlkYXRvciBnaXZlcyBzdHJpbmcgZXJyb3JzL3dhcm5pbmdzLCBlbGVtZW50LnZhbGlkYXRlKCkgZ2l2ZXMge2ZpZWxkLCBtZXNzYWdlfSBvYmplY3RzXG4gICAgY29uc3QgdmFsaWRhdGlvblJlc3VsdCA9IHtcbiAgICAgIHZhbGlkOiB2YWxpZGF0b3JSZXN1bHQuaXNWYWxpZCAmJiBlbGVtZW50VmFsaWRhdGlvbi52YWxpZCxcbiAgICAgIGVycm9yczogW1xuICAgICAgICAuLi52YWxpZGF0b3JSZXN1bHQuZXJyb3JzLm1hcCgoZTogc3RyaW5nKSA9PiAoeyBmaWVsZDogJ2dlbmVyYWwnLCBtZXNzYWdlOiBlIH0pKSxcbiAgICAgICAgLi4uKGVsZW1lbnRWYWxpZGF0aW9uLmVycm9ycyA/PyBbXSlcbiAgICAgIF0sXG4gICAgICB3YXJuaW5nczogW1xuICAgICAgICAuLi52YWxpZGF0b3JSZXN1bHQud2FybmluZ3MubWFwKCh3OiBzdHJpbmcpID0+ICh7IGZpZWxkOiAnZ2VuZXJhbCcsIG1lc3NhZ2U6IHcgfSkpLFxuICAgICAgICAuLi4oZWxlbWVudFZhbGlkYXRpb24ud2FybmluZ3MgPz8gW10pXG4gICAgICBdLFxuICAgICAgc3VnZ2VzdGlvbnM6IFtcbiAgICAgICAgLi4uKHZhbGlkYXRvclJlc3VsdC5zdWdnZXN0aW9ucyA/PyBbXSksXG4gICAgICAgIC4uLihlbGVtZW50VmFsaWRhdGlvbi5zdWdnZXN0aW9ucyA/PyBbXSlcbiAgICAgIF1cbiAgICB9O1xuXG4gICAgY29uc3QgcmVwb3J0ID0gYnVpbGRSZXBvcnQobm9ybWFsaXplZFR5cGUsIG5hbWUsIHZhbGlkYXRpb25SZXN1bHQsIHN0cmljdCk7XG5cbiAgICAvLyBGSVg6IERNQ1AtU0VDLTAwNiAtIEFkZCBzZWN1cml0eSBhdWRpdCBsb2dnaW5nIGZvciB2YWxpZGF0aW9uXG4gICAgU2VjdXJpdHlNb25pdG9yLmxvZ1NlY3VyaXR5RXZlbnQoe1xuICAgICAgdHlwZTogJ0VMRU1FTlRfVkFMSURBVEVEJyxcbiAgICAgIHNldmVyaXR5OiAnTE9XJyxcbiAgICAgIHNvdXJjZTogJ3ZhbGlkYXRlRWxlbWVudCcsXG4gICAgICBkZXRhaWxzOiBgVmFsaWRhdGVkICR7bm9ybWFsaXplZFR5cGV9OiAke25hbWV9YCxcbiAgICAgIGFkZGl0aW9uYWxEYXRhOiB7IGVsZW1lbnRUeXBlOiBub3JtYWxpemVkVHlwZSwgaXNWYWxpZDogdmFsaWRhdGlvblJlc3VsdC52YWxpZCB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW3tcbiAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgIHRleHQ6IHJlcG9ydFxuICAgICAgfV1cbiAgICB9O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIC8vIFJlLXRocm93IEVsZW1lbnROb3RGb3VuZEVycm9yIHRvIHByb3BhZ2F0ZSB0byBNQ1AtQVFMIGxheWVyXG4gICAgLy8gSXNzdWUgIzI3NTogSGFuZGxlcnMgcmV0dXJuIHN1Y2Nlc3M9dHJ1ZSBmb3IgbWlzc2luZyBlbGVtZW50c1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVsZW1lbnROb3RGb3VuZEVycm9yKSB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG5cbiAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byB2YWxpZGF0ZSBlbGVtZW50OmAsIGVycm9yKTtcbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDogW3tcbiAgICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgIHRleHQ6IGDinYwgRmFpbGVkIHRvIHZhbGlkYXRlIGVsZW1lbnQ6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiAnVW5rbm93biBlcnJvcid9YFxuICAgICAgfV1cbiAgICB9O1xuICB9XG59XG5cbmZ1bmN0aW9uIGludmFsaWRUeXBlKHR5cGU6IHN0cmluZykge1xuICByZXR1cm4ge1xuICAgIGNvbnRlbnQ6IFt7XG4gICAgICB0eXBlOiBcInRleHRcIixcbiAgICAgIHRleHQ6IGDinYwgSW52YWxpZCBlbGVtZW50IHR5cGUgJyR7dHlwZX0nLiBWYWxpZCB0eXBlczogJHtmb3JtYXRWYWxpZEVsZW1lbnRUeXBlc0xpc3QoKX1gXG4gICAgfV1cbiAgfTtcbn1cblxuZnVuY3Rpb24gdW5zdXBwb3J0ZWRUeXBlKHR5cGU6IEVsZW1lbnRUeXBlKSB7XG4gIGNvbnN0IGxhYmVsUGx1cmFsID0gZ2V0RWxlbWVudFR5cGVMYWJlbCh0eXBlLCB7IHBsdXJhbDogdHJ1ZSB9KTtcbiAgcmV0dXJuIHtcbiAgICBjb250ZW50OiBbe1xuICAgICAgdHlwZTogXCJ0ZXh0XCIsXG4gICAgICB0ZXh0OiBg4p2MIEVsZW1lbnQgdHlwZSAnJHtsYWJlbFBsdXJhbH0nIGlzIG5vdCB5ZXQgc3VwcG9ydGVkIGZvciB2YWxpZGF0aW9uYFxuICAgIH1dXG4gIH07XG59XG5cbmZ1bmN0aW9uIGJ1aWxkUmVwb3J0KFxuICB0eXBlOiBFbGVtZW50VHlwZSxcbiAgbmFtZTogc3RyaW5nLFxuICB2YWxpZGF0aW9uUmVzdWx0OiBhbnksXG4gIHN0cmljdDogYm9vbGVhblxuKSB7XG4gIGNvbnN0IGxhYmVsID0gZ2V0RWxlbWVudFR5cGVMYWJlbCh0eXBlKTtcbiAgbGV0IHJlcG9ydCA9IGDwn5SNIFZhbGlkYXRpb24gUmVwb3J0IGZvciAke2xhYmVsfSAnJHtuYW1lfSc6XFxuYDtcbiAgcmVwb3J0ICs9IGAke3ZhbGlkYXRpb25SZXN1bHQudmFsaWQgPyAn4pyFJyA6ICfinYwnfSBTdGF0dXM6ICR7dmFsaWRhdGlvblJlc3VsdC52YWxpZCA/ICdWYWxpZCcgOiAnSW52YWxpZCd9XFxuXFxuYDtcblxuICBpZiAodmFsaWRhdGlvblJlc3VsdC5lcnJvcnMgJiYgdmFsaWRhdGlvblJlc3VsdC5lcnJvcnMubGVuZ3RoID4gMCkge1xuICAgIHJlcG9ydCArPSBg4p2MIEVycm9ycyAoJHt2YWxpZGF0aW9uUmVzdWx0LmVycm9ycy5sZW5ndGh9KTpcXG5gO1xuICAgIHZhbGlkYXRpb25SZXN1bHQuZXJyb3JzLmZvckVhY2goKGVycm9yOiBhbnkpID0+IHtcbiAgICAgIGlmICh0eXBlb2YgZXJyb3IgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJlcG9ydCArPSBgICAg4oCiIEdlbmVyYWw6ICR7ZXJyb3J9XFxuYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlcG9ydCArPSBgICAg4oCiICR7ZXJyb3IuZmllbGQgfHwgJ0dlbmVyYWwnfTogJHtlcnJvci5tZXNzYWdlfVxcbmA7XG4gICAgICAgIGlmIChlcnJvci5maXgpIHtcbiAgICAgICAgICByZXBvcnQgKz0gYCAgICAg8J+SoSBGaXg6ICR7ZXJyb3IuZml4fVxcbmA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXBvcnQgKz0gJ1xcbic7XG4gIH1cblxuICBpZiAodmFsaWRhdGlvblJlc3VsdC53YXJuaW5ncyAmJiB2YWxpZGF0aW9uUmVzdWx0Lndhcm5pbmdzLmxlbmd0aCA+IDApIHtcbiAgICByZXBvcnQgKz0gYOKaoO+4jyAgV2FybmluZ3MgKCR7dmFsaWRhdGlvblJlc3VsdC53YXJuaW5ncy5sZW5ndGh9KTpcXG5gO1xuICAgIHZhbGlkYXRpb25SZXN1bHQud2FybmluZ3MuZm9yRWFjaCgod2FybmluZzogYW55KSA9PiB7XG4gICAgICBpZiAodHlwZW9mIHdhcm5pbmcgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJlcG9ydCArPSBgICAg4oCiIEdlbmVyYWw6ICR7d2FybmluZ31cXG5gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVwb3J0ICs9IGAgICDigKIgJHt3YXJuaW5nLmZpZWxkIHx8ICdHZW5lcmFsJ306ICR7d2FybmluZy5tZXNzYWdlfVxcbmA7XG4gICAgICAgIGlmICh3YXJuaW5nLnN1Z2dlc3Rpb24pIHtcbiAgICAgICAgICByZXBvcnQgKz0gYCAgICAg8J+SoSBTdWdnZXN0aW9uOiAke3dhcm5pbmcuc3VnZ2VzdGlvbn1cXG5gO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmVwb3J0ICs9ICdcXG4nO1xuICB9XG5cbiAgaWYgKHZhbGlkYXRpb25SZXN1bHQuc3VnZ2VzdGlvbnMgJiYgdmFsaWRhdGlvblJlc3VsdC5zdWdnZXN0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgcmVwb3J0ICs9IGDwn5KhIFN1Z2dlc3Rpb25zOlxcbmA7XG4gICAgdmFsaWRhdGlvblJlc3VsdC5zdWdnZXN0aW9ucy5mb3JFYWNoKChzdWdnZXN0aW9uOiBzdHJpbmcpID0+IHtcbiAgICAgIHJlcG9ydCArPSBgICAg4oCiICR7c3VnZ2VzdGlvbn1cXG5gO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHN0cmljdCkge1xuICAgIHJlcG9ydCArPSAnXFxu8J+TiyBTdHJpY3QgTW9kZTogQWRkaXRpb25hbCBxdWFsaXR5IGNoZWNrcyBhcHBsaWVkJztcbiAgfVxuXG4gIHJldHVybiByZXBvcnQ7XG59XG5cbmZ1bmN0aW9uIGdldE1hbmFnZXIoY29udGV4dDogRWxlbWVudENydWRDb250ZXh0LCB0eXBlOiBFbGVtZW50VHlwZSk6IEVsZW1lbnRNYW5hZ2VyT3BlcmF0aW9uczxhbnk+IHwgbnVsbCB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIC8vIEZJWDogSXNzdWUgIzI4MSAtIFBFUlNPTkEgbm93IHVzZXMgc3RhbmRhcmQgdmFsaWRhdGlvbiBmbG93XG4gICAgY2FzZSBFbGVtZW50VHlwZS5QRVJTT05BOlxuICAgICAgcmV0dXJuIGNvbnRleHQucGVyc29uYU1hbmFnZXI7XG4gICAgY2FzZSBFbGVtZW50VHlwZS5TS0lMTDpcbiAgICAgIHJldHVybiBjb250ZXh0LnNraWxsTWFuYWdlcjtcbiAgICBjYXNlIEVsZW1lbnRUeXBlLlRFTVBMQVRFOlxuICAgICAgcmV0dXJuIGNvbnRleHQudGVtcGxhdGVNYW5hZ2VyO1xuICAgIGNhc2UgRWxlbWVudFR5cGUuQUdFTlQ6XG4gICAgICByZXR1cm4gY29udGV4dC5hZ2VudE1hbmFnZXI7XG4gICAgY2FzZSBFbGVtZW50VHlwZS5NRU1PUlk6XG4gICAgICAvLyBGSVg6IEFkZGVkIG1lbW9yeSB2YWxpZGF0aW9uIHN1cHBvcnQgKGZpeGVzICMxMDQyKVxuICAgICAgLy8gUHJldmlvdXNseTogTWVtb3JpZXMgcmV0dXJuZWQgXCJub3QgeWV0IHN1cHBvcnRlZCBmb3IgdmFsaWRhdGlvblwiXG4gICAgICAvLyBOb3c6IEZ1bGwgdmFsaWRhdGlvbiBpbmNsdWRpbmcgbWV0YWRhdGEsIHJldGVudGlvbiwgZW50cnkgc3RydWN0dXJlXG4gICAgICByZXR1cm4gY29udGV4dC5tZW1vcnlNYW5hZ2VyO1xuICAgIGNhc2UgRWxlbWVudFR5cGUuRU5TRU1CTEU6XG4gICAgICByZXR1cm4gY29udGV4dC5lbnNlbWJsZU1hbmFnZXI7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBudWxsO1xuICB9XG59XG4iXX0=