UNPKG

jsii-docgen

Version:

generates api docs for jsii modules

583 lines • 81.3 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultTypeFormatter = exports.defaultLinkFormatter = exports.defaultAnchorFormatter = exports.MarkdownRenderer = void 0;
const markdown_doc_1 = require("./markdown-doc");
const schema_1 = require("../schema");
const transpile_1 = require("../transpile/transpile");
/**
 * Generates `MarkdownDocument` instances from `API.json` or its parts.
 *
 * This class can be used in two ways:
 *
 * 1. Instantiate it via the constructor with `options`, which requires
 * passing in some global context about the module and language you are
 * generated for. (This context can be found in the top-level `metadata`
 * field of API.json.) Then, call a `visitXxx` method to generate a
 * `MarkdownDocument` for the appropriate part of the schema.
 *
 * 2. Generate a `MarkdownDocument` from the complete `API.json` using the
 * `fromSchema` static method (no instantiation needed). Global context is
 * automatically inferred from the API.json.
 *
 * Both choices allow customizing the output via `MarkdownFormattingOptions`.
 */
class MarkdownRenderer {
    static fromSchema(schema, options) {
        const documentation = new markdown_doc_1.MarkdownDocument();
        if (schema.version !== schema_1.CURRENT_SCHEMA_VERSION) {
            throw new Error(`Unexpected schema version: ${schema.version}`);
        }
        if (schema.readme) {
            const md = new markdown_doc_1.MarkdownDocument();
            md.lines(schema.readme);
            documentation.section(md);
        }
        if (schema.apiReference) {
            const renderer = new MarkdownRenderer({
                anchorFormatter: options.anchorFormatter,
                linkFormatter: options.linkFormatter,
                typeFormatter: options.typeFormatter,
                language: transpile_1.Language.fromString(schema.language),
                ...schema.metadata,
            });
            documentation.section(renderer.visitApiReference(schema.apiReference, options.header));
        }
        return documentation;
    }
    static fromSubmodules(submodules, fileSuffix, options) {
        const documentation = new markdown_doc_1.MarkdownDocument();
        const renderer = new MarkdownRenderer({
            anchorFormatter: options.anchorFormatter,
            linkFormatter: options.linkFormatter,
            typeFormatter: options.typeFormatter,
            language: options.language,
            packageName: options.packageName,
            packageVersion: options.packageVersion,
        });
        const apiRef = renderer.visitSubmodules(submodules, fileSuffix);
        documentation.section(apiRef);
        return documentation;
    }
    constructor(options) {
        var _a, _b, _c;
        this.anchorFormatter = (_a = options.anchorFormatter) !== null && _a !== void 0 ? _a : exports.defaultAnchorFormatter;
        this.linkFormatter = (_b = options.linkFormatter) !== null && _b !== void 0 ? _b : exports.defaultLinkFormatter;
        this.typeFormatter = (_c = options.typeFormatter) !== null && _c !== void 0 ? _c : exports.defaultTypeFormatter;
        this.language = options.language;
        this.metadata = {
            packageName: options.packageName,
            packageVersion: options.packageVersion,
            submodule: options.submodule,
        };
    }
    visitSubmodules(submodules, fileSuffix) {
        const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Submodules' }, id: 'submodules' });
        md.lines('The following submodules are available:');
        md.lines('');
        for (const submodule of submodules) {
            md.lines(`- [${(0, transpile_1.submoduleRelName)(submodule)}](./${(0, transpile_1.submoduleRelName)(submodule)}.${fileSuffix})`);
        }
        md.lines('');
        return md;
    }
    visitApiReference(apiRef, header = { title: 'API Reference', id: 'api-reference' }) {
        const md = new markdown_doc_1.MarkdownDocument({ header: { title: header.title }, id: header.id });
        md.section(this.visitConstructs(apiRef.constructs));
        md.section(this.visitStructs(apiRef.structs));
        md.section(this.visitClasses(apiRef.classes));
        md.section(this.visitInterfaces(apiRef.interfaces));
        md.section(this.visitEnums(apiRef.enums));
        return md;
    }
    visitConstructs(constructs) {
        if (constructs.length === 0) {
            return markdown_doc_1.MarkdownDocument.EMPTY;
        }
        const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Constructs' } });
        for (const construct of constructs) {
            md.section(this.visitConstruct(construct));
        }
        return md;
    }
    visitStructs(structs) {
        if (structs.length === 0) {
            return markdown_doc_1.MarkdownDocument.EMPTY;
        }
        const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Structs' } });
        for (const struct of structs) {
            md.section(this.visitStruct(struct));
        }
        return md;
    }
    visitClasses(classes) {
        if (classes.length === 0) {
            return markdown_doc_1.MarkdownDocument.EMPTY;
        }
        const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Classes' } });
        for (const klass of classes) {
            md.section(this.visitClass(klass));
        }
        return md;
    }
    visitInterfaces(ifaces) {
        if (ifaces.length === 0) {
            return markdown_doc_1.MarkdownDocument.EMPTY;
        }
        const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Protocols' } });
        for (const iface of ifaces) {
            md.section(this.visitInterface(iface));
        }
        return md;
    }
    visitEnums(enums) {
        if (enums.length === 0) {
            return markdown_doc_1.MarkdownDocument.EMPTY;
        }
        const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Enums' } });
        for (const enu of enums) {
            md.section(this.visitEnum(enu));
        }
        return md;
    }
    visitConstruct(construct) {
        return this.visitClass(construct);
    }
    visitStruct(struct) {
        const md = new markdown_doc_1.MarkdownDocument({
            id: this.anchorFormatter({
                id: struct.id,
                displayName: struct.displayName,
                fqn: struct.fqn,
                ...this.metadata,
            }),
            header: { title: struct.displayName },
        });
        if (struct.docs) {
            md.docs(struct.docs, this.language);
        }
        const initializer = new markdown_doc_1.MarkdownDocument({
            id: this.anchorFormatter({
                id: `${struct.id}.Initializer`,
                displayName: 'Initializer',
                fqn: `${struct.fqn}.Initializer`,
                ...this.metadata,
            }),
            header: { title: 'Initializer' },
        });
        if (struct.usage) {
            initializer.code(this.language.toString(), struct.usage);
        }
        md.section(initializer);
        md.section(this.visitProperties(struct.properties));
        return md;
    }
    visitClass(klass) {
        const md = new markdown_doc_1.MarkdownDocument({
            id: this.anchorFormatter({
                id: klass.id,
                displayName: klass.displayName,
                fqn: klass.fqn,
                ...this.metadata,
            }),
            header: { title: klass.displayName },
        });
        if (klass.interfaces.length > 0) {
            const ifaces = [];
            for (const iface of klass.interfaces) {
                ifaces.push(this.linkFormatter(iface, this.metadata));
            }
            md.bullet(`${markdown_doc_1.MarkdownDocument.italic('Implements:')} ${ifaces.join(', ')}`);
            md.lines('');
        }
        if (klass.docs) {
            md.docs(klass.docs, this.language);
        }
        if (klass.initializer) {
            md.section(this.visitInitializer(klass.initializer));
        }
        md.section(this.visitInstanceMethods(klass.instanceMethods));
        md.section(this.visitStaticFunctions(klass.staticMethods));
        md.section(this.visitProperties(klass.properties));
        md.section(this.visitConstants(klass.constants));
        return md;
    }
    visitInterface(iface) {
        const md = new markdown_doc_1.MarkdownDocument({
            id: this.anchorFormatter({
                id: iface.id,
                displayName: iface.displayName,
                fqn: iface.fqn,
                ...this.metadata,
            }),
            header: { title: iface.displayName },
        });
        if (iface.interfaces.length > 0) {
            const bases = [];
            for (const base of iface.interfaces) {
                bases.push(this.linkFormatter(base, this.metadata));
            }
            md.bullet(`${markdown_doc_1.MarkdownDocument.italic('Extends:')} ${bases.join(', ')}`);
            md.lines('');
        }
        if (iface.implementations.length > 0) {
            const impls = [];
            for (const impl of iface.implementations) {
                impls.push(this.linkFormatter(impl, this.metadata));
            }
            md.bullet(`${markdown_doc_1.MarkdownDocument.italic('Implemented By:')} ${impls.join(', ')}`);
            md.lines('');
        }
        if (iface.docs) {
            md.docs(iface.docs, this.language);
        }
        md.section(this.visitInstanceMethods(iface.instanceMethods));
        md.section(this.visitProperties(iface.properties));
        return md;
    }
    visitEnum(enu) {
        const md = new markdown_doc_1.MarkdownDocument({
            id: this.anchorFormatter({
                id: enu.id,
                displayName: enu.displayName,
                fqn: enu.fqn,
                ...this.metadata,
            }),
            header: { title: enu.displayName },
        });
        if (enu.docs) {
            md.docs(enu.docs, this.language);
        }
        md.section(this.visitEnumMembers(enu.members));
        return md;
    }
    visitEnumMembers(enus) {
        if (enus.length === 0) {
            return markdown_doc_1.MarkdownDocument.EMPTY;
        }
        const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Members' } });
        md.table(this.createTable(enus));
        md.split();
        for (const enu of enus) {
            md.section(this.visitEnumMember(enu));
        }
        return md;
    }
    visitProperties(properties) {
        if (properties.length === 0) {
            return markdown_doc_1.MarkdownDocument.EMPTY;
        }
        const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Properties' } });
        md.table(this.createTableWithTypes(properties));
        md.split();
        for (const prop of properties) {
            md.section(this.visitProperty(prop));
        }
        return md;
    }
    visitInitializer(init) {
        const md = new markdown_doc_1.MarkdownDocument({
            id: this.anchorFormatter({
                id: init.id,
                displayName: init.displayName,
                fqn: init.fqn,
                ...this.metadata,
            }),
            header: {
                title: 'Initializers',
            },
        });
        if (init.usage) {
            md.code(this.language.toString(), init.usage);
        }
        md.table(this.createTableWithTypes(init.parameters));
        md.split();
        for (const param of init.parameters) {
            md.section(this.visitParameter(param));
        }
        return md;
    }
    visitInstanceMethods(methods) {
        if (methods.length === 0) {
            return markdown_doc_1.MarkdownDocument.EMPTY;
        }
        const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Methods' } });
        md.table(this.createTable(methods));
        md.split();
        for (const method of methods) {
            md.section(this.visitInstanceMethod(method));
        }
        return md;
    }
    visitStaticFunctions(methods) {
        if (methods.length === 0) {
            return markdown_doc_1.MarkdownDocument.EMPTY;
        }
        const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Static Functions' } });
        md.table(this.createTable(methods));
        md.split();
        for (const method of methods) {
            md.section(this.visitStaticFunction(method));
        }
        return md;
    }
    visitConstants(constants) {
        if (constants.length === 0) {
            return markdown_doc_1.MarkdownDocument.EMPTY;
        }
        const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Constants' } });
        md.table(this.createTableWithTypes(constants));
        md.split();
        for (const con of constants) {
            md.section(this.visitConstant(con));
        }
        return md;
    }
    visitEnumMember(em) {
        const md = new markdown_doc_1.MarkdownDocument({
            id: this.anchorFormatter({
                id: em.id,
                displayName: em.displayName,
                fqn: em.fqn,
                ...this.metadata,
            }),
            header: {
                title: em.displayName,
                pre: true,
                strike: em.docs.deprecated,
            },
        });
        if (em.docs.deprecated) {
            md.bullet(`${markdown_doc_1.MarkdownDocument.italic('Deprecated:')} ${em.docs.deprecationReason}`);
            md.lines('');
        }
        if (em.docs) {
            md.docs(em.docs, this.language);
        }
        md.split();
        md.lines('');
        return md;
    }
    visitProperty(prop) {
        const optionality = prop.optional
            ? 'Optional'
            : 'Required';
        const md = new markdown_doc_1.MarkdownDocument({
            id: this.anchorFormatter({
                id: prop.id,
                displayName: prop.displayName,
                fqn: prop.fqn,
                ...this.metadata,
            }),
            header: {
                title: prop.displayName,
                sup: optionality,
                pre: true,
                strike: prop.docs.deprecated,
            },
        });
        if (prop.docs.deprecated) {
            md.bullet(`${markdown_doc_1.MarkdownDocument.italic('Deprecated:')} ${prop.docs.deprecationReason}`);
            md.lines('');
        }
        if (prop.usage) {
            md.code(this.language.toString(), prop.usage);
        }
        const metadata = {
            Type: this.typeFormatter(prop.type, this.metadata, this.linkFormatter),
        };
        if (prop.default) {
            const sanitized = markdown_doc_1.MarkdownDocument.sanitize(prop.default);
            metadata.Default = markdown_doc_1.MarkdownDocument.removeNewlines(sanitized);
        }
        for (const [key, value] of Object.entries(metadata)) {
            md.bullet(`${markdown_doc_1.MarkdownDocument.italic(`${key}:`)} ${value}`);
        }
        md.lines('');
        if (prop.docs) {
            md.docs(prop.docs, this.language);
        }
        md.split();
        return md;
    }
    visitParameter(parameter) {
        const optionality = parameter.optional ? 'Optional' : 'Required';
        const md = new markdown_doc_1.MarkdownDocument({
            id: this.anchorFormatter({
                id: parameter.id,
                displayName: parameter.displayName,
                fqn: parameter.fqn,
                ...this.metadata,
            }),
            header: {
                title: parameter.displayName,
                sup: optionality,
                pre: true,
                strike: parameter.docs.deprecated,
            },
        });
        if (parameter.docs.deprecated) {
            md.bullet(`${markdown_doc_1.MarkdownDocument.italic('Deprecated:')} ${parameter.docs.deprecationReason}`);
            md.lines('');
        }
        const metadata = {
            Type: this.typeFormatter(parameter.type, this.metadata, this.linkFormatter),
        };
        if (parameter.default) {
            const sanitized = markdown_doc_1.MarkdownDocument.sanitize(parameter.default);
            metadata.Default = markdown_doc_1.MarkdownDocument.removeNewlines(sanitized);
        }
        for (const [key, value] of Object.entries(metadata)) {
            md.bullet(`${markdown_doc_1.MarkdownDocument.italic(`${key}:`)} ${value}`);
        }
        md.lines('');
        if (parameter.docs) {
            md.docs(parameter.docs, this.language);
        }
        md.split();
        return md;
    }
    visitInstanceMethod(method) {
        const md = new markdown_doc_1.MarkdownDocument({
            id: this.anchorFormatter({
                id: method.id,
                displayName: method.displayName,
                fqn: method.fqn,
                ...this.metadata,
            }),
            header: {
                title: method.displayName,
                pre: true,
                strike: method.docs.deprecated,
            },
        });
        if (method.usage) {
            md.code(this.language.toString(), method.usage);
        }
        if (method.docs) {
            md.docs(method.docs, this.language);
        }
        for (const param of method.parameters) {
            md.section(this.visitParameter(param));
        }
        return md;
    }
    visitStaticFunction(method) {
        const md = new markdown_doc_1.MarkdownDocument({
            id: this.anchorFormatter({
                id: method.id,
                displayName: method.displayName,
                fqn: method.fqn,
                ...this.metadata,
            }),
            header: {
                title: method.displayName,
                pre: true,
                strike: method.docs.deprecated,
            },
        });
        if (method.usage) {
            md.code(this.language.toString(), method.usage);
        }
        if (method.docs) {
            md.docs(method.docs, this.language);
        }
        for (const param of method.parameters) {
            md.section(this.visitParameter(param));
        }
        return md;
    }
    visitConstant(constant) {
        return this.visitProperty(constant);
    }
    createTable(items) {
        var _a, _b, _c;
        const tableRows = [];
        tableRows.push(['Name', 'Description'].map(markdown_doc_1.MarkdownDocument.bold));
        for (const item of items) {
            const link = markdown_doc_1.MarkdownDocument.pre(this.linkFormatter({
                fqn: item.fqn,
                displayName: item.displayName,
                id: item.id,
                ...this.metadata,
            }, this.metadata));
            const description = ((_a = item.docs) === null || _a === void 0 ? void 0 : _a.summary) && ((_b = item.docs) === null || _b === void 0 ? void 0 : _b.summary.length) > 0
                ? (_c = item.docs) === null || _c === void 0 ? void 0 : _c.summary
                : markdown_doc_1.MarkdownDocument.italic('No description.');
            tableRows.push([link, description]);
        }
        return tableRows;
    }
    createTableWithTypes(items) {
        var _a, _b, _c;
        const tableRows = [];
        tableRows.push(['Name', 'Type', 'Description'].map(markdown_doc_1.MarkdownDocument.bold));
        for (const item of items) {
            const link = markdown_doc_1.MarkdownDocument.pre(this.linkFormatter({
                fqn: item.fqn,
                displayName: item.displayName,
                id: item.id,
                ...this.metadata,
            }, this.metadata));
            const type = markdown_doc_1.MarkdownDocument.pre(this.typeFormatter(item.type, this.metadata, this.linkFormatter));
            const description = ((_a = item.docs) === null || _a === void 0 ? void 0 : _a.summary) && ((_b = item.docs) === null || _b === void 0 ? void 0 : _b.summary.length) > 0
                ? (_c = item.docs) === null || _c === void 0 ? void 0 : _c.summary
                : markdown_doc_1.MarkdownDocument.italic('No description.');
            tableRows.push([link, type, description]);
        }
        return tableRows;
    }
}
exports.MarkdownRenderer = MarkdownRenderer;
function sanitize(str) {
    return str.replace(/ /g, '-');
}
const defaultAnchorFormatter = (type) => {
    // HTML5 allows any character in IDs /except/ whitespace
    return sanitize(type.id);
};
exports.defaultAnchorFormatter = defaultAnchorFormatter;
const defaultLinkFormatter = (type, metadata) => {
    if (type.packageName === metadata.packageName && type.submodule === metadata.submodule) {
        return `<a href="#${sanitize(type.id)}">${type.displayName}</a>`;
    }
    else {
        // do not display a link if the type isn't in this document
        return type.fqn;
    }
};
exports.defaultLinkFormatter = defaultLinkFormatter;
function isJsiiType(value) {
    return (value !== null
        && typeof value === 'object'
        && (value === null || value === void 0 ? void 0 : value.fqn)
        && (value === null || value === void 0 ? void 0 : value.id)
        && (value === null || value === void 0 ? void 0 : value.displayName));
}
const defaultTypeFormatter = (type, metadata, linkFormatter) => {
    var _a;
    let result = type.formattingPattern;
    const typeRefs = [];
    for (const typeRef of (_a = type.types) !== null && _a !== void 0 ? _a : []) {
        if (isJsiiType(typeRef)) {
            typeRefs.push(linkFormatter(typeRef, metadata));
        }
        else {
            typeRefs.push((0, exports.defaultTypeFormatter)(typeRef, metadata, linkFormatter));
        }
    }
    // substitute referred types into the original string
    const placeholderMatcher = /\%/g;
    for (const typeRef of typeRefs) {
        const matches = placeholderMatcher.exec(result);
        if (!matches) {
            // it's possible the number of %'s doesn't match the number of types provided
            // e.g. csharp unions are currently rendered to `{ name: 'object', types: [type1, type2] }`
            continue;
        }
        const insertionIdx = matches.index;
        result = result.substring(0, insertionIdx) + typeRef + result.substring(insertionIdx + 1);
    }
    return result;
};
exports.defaultTypeFormatter = defaultTypeFormatter;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFya2Rvd24tcmVuZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2RvY2dlbi9yZW5kZXIvbWFya2Rvd24tcmVuZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLGlEQUFrRDtBQUNsRCxzQ0FBNFI7QUFDNVIsc0RBQW9FO0FBb0VwRTs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILE1BQWEsZ0JBQWdCO0lBQ3BCLE1BQU0sQ0FBQyxVQUFVLENBQUMsTUFBYyxFQUFFLE9BQWtDO1FBQ3pFLE1BQU0sYUFBYSxHQUFHLElBQUksK0JBQWdCLEVBQUUsQ0FBQztRQUU3QyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEtBQUssK0JBQXNCLEVBQUUsQ0FBQztZQUM5QyxNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixNQUFNLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUNsRSxDQUFDO1FBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDbEIsTUFBTSxFQUFFLEdBQUcsSUFBSSwrQkFBZ0IsRUFBRSxDQUFDO1lBQ2xDLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3hCLGFBQWEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDNUIsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3hCLE1BQU0sUUFBUSxHQUFHLElBQUksZ0JBQWdCLENBQUM7Z0JBQ3BDLGVBQWUsRUFBRSxPQUFPLENBQUMsZUFBZTtnQkFDeEMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxhQUFhO2dCQUNwQyxhQUFhLEVBQUUsT0FBTyxDQUFDLGFBQWE7Z0JBQ3BDLFFBQVEsRUFBRSxvQkFBUSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO2dCQUM5QyxHQUFHLE1BQU0sQ0FBQyxRQUFRO2FBQ25CLENBQUMsQ0FBQztZQUVILGFBQWEsQ0FBQyxP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QztJQUNwQixLQUFLLE1BQU0sT0FBTyxJQUFJLE1BQUEsSUFBSSxDQUFDLEtBQUssbUNBQUksRUFBRSxFQUFFLENBQUM7UUFDdkMsSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUN4QixRQUFRLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNsRCxDQUFDO2FBQU0sQ0FBQztZQUNOLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBQSw0QkFBb0IsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztJQUNILENBQUM7SUFFRCxxREFBcUQ7SUFDckQsTUFBTSxrQkFBa0IsR0FBRyxLQUFLLENBQUM7SUFDakMsS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUMvQixNQUFNLE9BQU8sR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsNkVBQTZFO1lBQzdFLDJGQUEyRjtZQUMzRixTQUFTO1FBQ1gsQ0FBQztRQUNELE1BQU0sWUFBWSxHQUFXLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFDM0MsTUFBTSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxHQUFHLE9BQU8sR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUMsQ0FBQztJQUM1RixDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyxDQUFDO0FBN0JXLFFBQUEsb0JBQW9CLHdCQTZCL0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyByZWZsZWN0IGZyb20gJ2pzaWktcmVmbGVjdCc7XG5pbXBvcnQgeyBNYXJrZG93bkRvY3VtZW50IH0gZnJvbSAnLi9tYXJrZG93bi1kb2MnO1xuaW1wb3J0IHsgQXBpUmVmZXJlbmNlU2NoZW1hLCBBc3NlbWJseU1ldGFkYXRhU2NoZW1hLCBDbGFzc1NjaGVtYSwgQ29uc3RydWN0U2NoZW1hLCBFbnVtTWVtYmVyU2NoZW1hLCBFbnVtU2NoZW1hLCBJbml0aWFsaXplclNjaGVtYSwgSW50ZXJmYWNlU2NoZW1hLCBKc2lpRW50aXR5LCBNZXRob2RTY2hlbWEsIFBhcmFtZXRlclNjaGVtYSwgUHJvcGVydHlTY2hlbWEsIFNjaGVtYSwgQ1VSUkVOVF9TQ0hFTUFfVkVSU0lPTiwgU3RydWN0U2NoZW1hLCBUeXBlU2NoZW1hIH0gZnJvbSAnLi4vc2NoZW1hJztcbmltcG9ydCB7IExhbmd1YWdlLCBzdWJtb2R1bGVSZWxOYW1lIH0gZnJvbSAnLi4vdHJhbnNwaWxlL3RyYW5zcGlsZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWFya2Rvd25Gb3JtYXR0aW5nT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBIb3cganNpaSBlbnRpdHkgSURzIHNob3VsZCBiZSBmb3JtYXR0ZWQgaW50byBhbmNob3JzLiBUaGlzIHNob3VsZCBiZVxuICAgKiBjdXN0b21pemVkIGluIGNvbmp1bmN0aW9uIHdpdGggYGxpbmtGb3JtYXR0ZXJgLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIHRoZSBlbnRpdHkgd2UgYXJlIGNyZWF0aW5nIGFuIGFuY2hvciBmb3JcbiAgICpcbiAgICogQGV4cGVyaW1lbnRhbFxuICAgKiBAZGVmYXVsdCAtIHVzZSB0aGUgZnVsbCBpZFxuICAgKi9cbiAgcmVhZG9ubHkgYW5jaG9yRm9ybWF0dGVyPzogKHR5cGU6IEpzaWlFbnRpdHkpID0+IHN0cmluZztcblxuICAvKipcbiAgICogSG93IHNob3VsZCBsaW5rcyB0byBlbnRpdGllcyBiZSByZW5kZXJlZC4gRm9yIGV4YW1wbGUsIGlmIGEgY2xhc3Mgb3IgYVxuICAgKiBwcm9wZXJ0eSBpcyByZWZlcmVuY2VkIHdpdGhpbiBhIGRlc2NyaXB0aW9uIG9yIHRhYmxlLlxuICAgKlxuICAgKiBUaGUgYG1ldGFkYXRhYCBwYXJhbWV0ZXIgY2FuIGJlIG9wdGlvbmFsbHkgdXNlZCB0byBjdXN0b21pemUgbGlua3MgYmFzZWRcbiAgICogb24gd2hldGhlciBvciBub3QgdGhlIHR5cGUgYmVsb25ncyB0byB0aGUgcGFja2FnZSAvIHN1Ym1vZHVsZSB0aGF0IGlzXG4gICAqIGJlaW5nIGdlbmVyYXRlZC5cbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSB0aGUgZW50aXR5IHdlIGFyZSBjcmVhdGluZyBhIGxpbmsgZm9yXG4gICAqIEBwYXJhbSBtZXRhZGF0YSAtIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtb2R1bGUgYmVpbmcgZG9jZ2VuLWVkXG4gICAqXG4gICAqIEBleHBlcmltZW50YWxcbiAgICogQGRlZmF1bHQgLSAnPGEgaHJlZj1cIiN7dHlwZS5pZH1cIj57dHlwZS5kaXNwbGF5TmFtZX08L2E+JyBpZiB0aGUgdHlwZVxuICAgKiAgIGJlbG9uZ3MgdG8gdGhpcyBwYWNrYWdlLCAne3R5cGUuZnFufScgb3RoZXJ3aXNlXG4gICAqL1xuICByZWFkb25seSBsaW5rRm9ybWF0dGVyPzogKHR5cGU6IEpzaWlFbnRpdHksIG1ldGFkYXRhOiBBc3NlbWJseU1ldGFkYXRhU2NoZW1hKSA9PiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEhvdyB0eXBlIHNpZ25hdHVyZXMgc2hvdWxkIGJlIGZvcm1hdHRlZCwgaW5jbHVkaW5nIHRob3NlIG1hZGUgb2YgbmVzdGVkXG4gICAqIHR5cGVzIChsaWtlIGBNYXA8c3RyaW5nLCBCdWNrZXQ+YCkuXG4gICAqXG4gICAqIFRoZSBgbWV0YWRhdGFgIGFuZCBgbGlua0Zvcm1hdHRlcmAgcGFyYW1ldGVycyBhcmUgcHJvdmlkZWQgc28gdGhhdCBsaW5rc1xuICAgKiBjYW4gYmUgaW5jbHVkZWQgaW4gdGhlIGZvcm1hdHRlZCB0eXBlcyBpZiBkZXNpcmVkLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIHRoZSB0eXBlIGJlaW5nIGZvcm1hdHRlZFxuICAgKiBAcGFyYW0gbWV0YWRhdGEgLSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbW9kdWxlIGJlaW5nIGRvY2dlbi1lZFxuICAgKiBAcGFyYW0gbGlua0Zvcm1hdHRlciAtIHRoZSB0eXBlIGxpbmsgZm9ybWF0dGVyXG4gICAqXG4gICAqIEBleHBlcmltZW50YWxcbiAgICogQGRlZmF1bHQgLSBIVE1MIGNvZGUgYmxvY2sgd2l0aCB0eXBlIHJlZmVyZW5jZXMgbGlua2VkXG4gICAqIGFjY29yZGluZyB0byBgbGlua0Zvcm1hdHRlcmBcbiAgICovXG4gIHJlYWRvbmx5IHR5cGVGb3JtYXR0ZXI/OiAoXG4gICAgdHlwZTogVHlwZVNjaGVtYSxcbiAgICBtZXRhZGF0YTogQXNzZW1ibHlNZXRhZGF0YVNjaGVtYSxcbiAgICBsaW5rRm9ybWF0dGVyOiAodHlwZTogSnNpaUVudGl0eSwgbWV0YWRhdGE6IEFzc2VtYmx5TWV0YWRhdGFTY2hlbWEpID0+IHN0cmluZ1xuICApID0+IHN0cmluZztcblxuXG4gIC8qKlxuICAgKiBIb3cgdG8gcmVuZGVyIHRoZSBoZWFkZXIgb2YgdGhlIGdlbmVyYXRlZCBkb2N1bWVudGF0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGRlZmF1bHQgc2VjdGlvbiBoZWFkZXJzXG4gICAqL1xuICByZWFkb25seSBoZWFkZXI/OiB7IHRpdGxlOiBzdHJpbmc7IGlkOiBzdHJpbmcgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNYXJrZG93blJlbmRlcmVyT3B0aW9ucyBleHRlbmRzIE1hcmtkb3duRm9ybWF0dGluZ09wdGlvbnMsIEFzc2VtYmx5TWV0YWRhdGFTY2hlbWEge1xuICAvKipcbiAgICogTGFuZ3VhZ2UgdGhlIGRvY3VtZW50YXRpb24gaXMgcmVuZGVyZWQgZm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgbGFuZ3VhZ2U6IExhbmd1YWdlO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBgTWFya2Rvd25Eb2N1bWVudGAgaW5zdGFuY2VzIGZyb20gYEFQSS5qc29uYCBvciBpdHMgcGFydHMuXG4gKlxuICogVGhpcyBjbGFzcyBjYW4gYmUgdXNlZCBpbiB0d28gd2F5czpcbiAqXG4gKiAxLiBJbnN0YW50aWF0ZSBpdCB2aWEgdGhlIGNvbnN0cnVjdG9yIHdpdGggYG9wdGlvbnNgLCB3aGljaCByZXF1aXJlc1xuICogcGFzc2luZyBpbiBzb21lIGdsb2JhbCBjb250ZXh0IGFib3V0IHRoZSBtb2R1bGUgYW5kIGxhbmd1YWdlIHlvdSBhcmVcbiAqIGdlbmVyYXRlZCBmb3IuIChUaGlzIGNvbnRleHQgY2FuIGJlIGZvdW5kIGluIHRoZSB0b3AtbGV2ZWwgYG1ldGFkYXRhYFxuICogZmllbGQgb2YgQVBJLmpzb24uKSBUaGVuLCBjYWxsIGEgYHZpc2l0WHh4YCBtZXRob2QgdG8gZ2VuZXJhdGUgYVxuICogYE1hcmtkb3duRG9jdW1lbnRgIGZvciB0aGUgYXBwcm9wcmlhdGUgcGFydCBvZiB0aGUgc2NoZW1hLlxuICpcbiAqIDIuIEdlbmVyYXRlIGEgYE1hcmtkb3duRG9jdW1lbnRgIGZyb20gdGhlIGNvbXBsZXRlIGBBUEkuanNvbmAgdXNpbmcgdGhlXG4gKiBgZnJvbVNjaGVtYWAgc3RhdGljIG1ldGhvZCAobm8gaW5zdGFudGlhdGlvbiBuZWVkZWQpLiBHbG9iYWwgY29udGV4dCBpc1xuICogYXV0b21hdGljYWxseSBpbmZlcnJlZCBmcm9tIHRoZSBBUEkuanNvbi5cbiAqXG4gKiBCb3RoIGNob2ljZXMgYWxsb3cgY3VzdG9taXppbmcgdGhlIG91dHB1dCB2aWEgYE1hcmtkb3duRm9ybWF0dGluZ09wdGlvbnNgLlxuICovXG5leHBvcnQgY2xhc3MgTWFya2Rvd25SZW5kZXJlciB7XG4gIHB1YmxpYyBzdGF0aWMgZnJvbVNjaGVtYShzY2hlbWE6IFNjaGVtYSwgb3B0aW9uczogTWFya2Rvd25Gb3JtYXR0aW5nT3B0aW9ucyk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IGRvY3VtZW50YXRpb24gPSBuZXcgTWFya2Rvd25Eb2N1bWVudCgpO1xuXG4gICAgaWYgKHNjaGVtYS52ZXJzaW9uICE9PSBDVVJSRU5UX1NDSEVNQV9WRVJTSU9OKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgc2NoZW1hIHZlcnNpb246ICR7c2NoZW1hLnZlcnNpb259YCk7XG4gICAgfVxuXG4gICAgaWYgKHNjaGVtYS5yZWFkbWUpIHtcbiAgICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoKTtcbiAgICAgIG1kLmxpbmVzKHNjaGVtYS5yZWFkbWUpO1xuICAgICAgZG9jdW1lbnRhdGlvbi5zZWN0aW9uKG1kKTtcbiAgICB9XG5cbiAgICBpZiAoc2NoZW1hLmFwaVJlZmVyZW5jZSkge1xuICAgICAgY29uc3QgcmVuZGVyZXIgPSBuZXcgTWFya2Rvd25SZW5kZXJlcih7XG4gICAgICAgIGFuY2hvckZvcm1hdHRlcjogb3B0aW9ucy5hbmNob3JGb3JtYXR0ZXIsXG4gICAgICAgIGxpbmtGb3JtYXR0ZXI6IG9wdGlvbnMubGlua0Zvcm1hdHRlcixcbiAgICAgICAgdHlwZUZvcm1hdHRlcjogb3B0aW9ucy50eXBlRm9ybWF0dGVyLFxuICAgICAgICBsYW5ndWFnZTogTGFuZ3VhZ2UuZnJvbVN0cmluZyhzY2hlbWEubGFuZ3VhZ2UpLFxuICAgICAgICAuLi5zY2hlbWEubWV0YWRhdGEsXG4gICAgICB9KTtcblxuICAgICAgZG9jdW1lbnRhdGlvbi5zZWN0aW9uKHJlbmRlcmVyLnZpc2l0QXBpUmVmZXJlbmNlKHNjaGVtYS5hcGlSZWZlcmVuY2UsIG9wdGlvbnMuaGVhZGVyKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRvY3VtZW50YXRpb247XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGZyb21TdWJtb2R1bGVzKHN1Ym1vZHVsZXM6IHJlYWRvbmx5IHJlZmxlY3QuU3VibW9kdWxlW10sIGZpbGVTdWZmaXg6IHN0cmluZywgb3B0aW9uczogTWFya2Rvd25SZW5kZXJlck9wdGlvbnMpOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBjb25zdCBkb2N1bWVudGF0aW9uID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoKTtcblxuICAgIGNvbnN0IHJlbmRlcmVyID0gbmV3IE1hcmtkb3duUmVuZGVyZXIoe1xuICAgICAgYW5jaG9yRm9ybWF0dGVyOiBvcHRpb25zLmFuY2hvckZvcm1hdHRlcixcbiAgICAgIGxpbmtGb3JtYXR0ZXI6IG9wdGlvbnMubGlua0Zvcm1hdHRlcixcbiAgICAgIHR5cGVGb3JtYXR0ZXI6IG9wdGlvbnMudHlwZUZvcm1hdHRlcixcbiAgICAgIGxhbmd1YWdlOiBvcHRpb25zLmxhbmd1YWdlLFxuICAgICAgcGFja2FnZU5hbWU6IG9wdGlvbnMucGFja2FnZU5hbWUsXG4gICAgICBwYWNrYWdlVmVyc2lvbjogb3B0aW9ucy5wYWNrYWdlVmVyc2lvbixcbiAgICB9KTtcblxuICAgIGNvbnN0IGFwaVJlZiA9IHJlbmRlcmVyLnZpc2l0U3VibW9kdWxlcyhzdWJtb2R1bGVzLCBmaWxlU3VmZml4KTtcbiAgICBkb2N1bWVudGF0aW9uLnNlY3Rpb24oYXBpUmVmKTtcblxuICAgIHJldHVybiBkb2N1bWVudGF0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBhbmNob3JGb3JtYXR0ZXI6IE5vbk51bGxhYmxlPE1hcmtkb3duRm9ybWF0dGluZ09wdGlvbnNbJ2FuY2hvckZvcm1hdHRlciddPjtcbiAgcHJpdmF0ZSByZWFkb25seSBsaW5rRm9ybWF0dGVyOiBOb25OdWxsYWJsZTxNYXJrZG93bkZvcm1hdHRpbmdPcHRpb25zWydsaW5rRm9ybWF0dGVyJ10+O1xuICBwcml2YXRlIHJlYWRvbmx5IHR5cGVGb3JtYXR0ZXI6IE5vbk51bGxhYmxlPE1hcmtkb3duRm9ybWF0dGluZ09wdGlvbnNbJ3R5cGVGb3JtYXR0ZXInXT47XG4gIHByaXZhdGUgcmVhZG9ubHkgbWV0YWRhdGE6IEFzc2VtYmx5TWV0YWRhdGFTY2hlbWE7XG4gIHByaXZhdGUgcmVhZG9ubHkgbGFuZ3VhZ2U6IExhbmd1YWdlO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE1hcmtkb3duUmVuZGVyZXJPcHRpb25zKSB7XG4gICAgdGhpcy5hbmNob3JGb3JtYXR0ZXIgPSBvcHRpb25zLmFuY2hvckZvcm1hdHRlciA/PyBkZWZhdWx0QW5jaG9yRm9ybWF0dGVyO1xuICAgIHRoaXMubGlua0Zvcm1hdHRlciA9IG9wdGlvbnMubGlua0Zvcm1hdHRlciA/PyBkZWZhdWx0TGlua0Zvcm1hdHRlcjtcbiAgICB0aGlzLnR5cGVGb3JtYXR0ZXIgPSBvcHRpb25zLnR5cGVGb3JtYXR0ZXIgPz8gZGVmYXVsdFR5cGVGb3JtYXR0ZXI7XG4gICAgdGhpcy5sYW5ndWFnZSA9IG9wdGlvbnMubGFuZ3VhZ2U7XG4gICAgdGhpcy5tZXRhZGF0YSA9IHtcbiAgICAgIHBhY2thZ2VOYW1lOiBvcHRpb25zLnBhY2thZ2VOYW1lLFxuICAgICAgcGFja2FnZVZlcnNpb246IG9wdGlvbnMucGFja2FnZVZlcnNpb24sXG4gICAgICBzdWJtb2R1bGU6IG9wdGlvbnMuc3VibW9kdWxlLFxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgdmlzaXRTdWJtb2R1bGVzKHN1Ym1vZHVsZXM6IHJlYWRvbmx5IHJlZmxlY3QuU3VibW9kdWxlW10sIGZpbGVTdWZmaXg6IHN0cmluZyk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoeyBoZWFkZXI6IHsgdGl0bGU6ICdTdWJtb2R1bGVzJyB9LCBpZDogJ3N1Ym1vZHVsZXMnIH0pO1xuICAgIG1kLmxpbmVzKCdUaGUgZm9sbG93aW5nIHN1Ym1vZHVsZXMgYXJlIGF2YWlsYWJsZTonKTtcbiAgICBtZC5saW5lcygnJyk7XG4gICAgZm9yIChjb25zdCBzdWJtb2R1bGUgb2Ygc3VibW9kdWxlcykge1xuICAgICAgbWQubGluZXMoYC0gWyR7c3VibW9kdWxlUmVsTmFtZShzdWJtb2R1bGUpfV0oLi8ke3N1Ym1vZHVsZVJlbE5hbWUoc3VibW9kdWxlKX0uJHtmaWxlU3VmZml4fSlgKTtcbiAgICB9XG4gICAgbWQubGluZXMoJycpO1xuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdEFwaVJlZmVyZW5jZShcbiAgICBhcGlSZWY6IEFwaVJlZmVyZW5jZVNjaGVtYSxcbiAgICBoZWFkZXI6IHsgdGl0bGU6IHN0cmluZzsgaWQ6IHN0cmluZyB9ID0geyB0aXRsZTogJ0FQSSBSZWZlcmVuY2UnLCBpZDogJ2FwaS1yZWZlcmVuY2UnIH0sXG4gICk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoeyBoZWFkZXI6IHsgdGl0bGU6IGhlYWRlci50aXRsZSB9LCBpZDogaGVhZGVyLmlkIH0pO1xuICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdENvbnN0cnVjdHMoYXBpUmVmLmNvbnN0cnVjdHMpKTtcbiAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRTdHJ1Y3RzKGFwaVJlZi5zdHJ1Y3RzKSk7XG4gICAgbWQuc2VjdGlvbih0aGlzLnZpc2l0Q2xhc3NlcyhhcGlSZWYuY2xhc3NlcykpO1xuICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdEludGVyZmFjZXMoYXBpUmVmLmludGVyZmFjZXMpKTtcbiAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRFbnVtcyhhcGlSZWYuZW51bXMpKTtcbiAgICByZXR1cm4gbWQ7XG4gIH1cblxuICBwdWJsaWMgdmlzaXRDb25zdHJ1Y3RzKFxuICAgIGNvbnN0cnVjdHM6IENvbnN0cnVjdFNjaGVtYVtdLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBpZiAoY29uc3RydWN0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBNYXJrZG93bkRvY3VtZW50LkVNUFRZO1xuICAgIH1cblxuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoeyBoZWFkZXI6IHsgdGl0bGU6ICdDb25zdHJ1Y3RzJyB9IH0pO1xuICAgIGZvciAoY29uc3QgY29uc3RydWN0IG9mIGNvbnN0cnVjdHMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdENvbnN0cnVjdChjb25zdHJ1Y3QpKTtcbiAgICB9XG4gICAgcmV0dXJuIG1kO1xuICB9XG5cbiAgcHVibGljIHZpc2l0U3RydWN0cyhcbiAgICBzdHJ1Y3RzOiBTdHJ1Y3RTY2hlbWFbXSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgaWYgKHN0cnVjdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gTWFya2Rvd25Eb2N1bWVudC5FTVBUWTtcbiAgICB9XG5cbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHsgaGVhZGVyOiB7IHRpdGxlOiAnU3RydWN0cycgfSB9KTtcbiAgICBmb3IgKGNvbnN0IHN0cnVjdCBvZiBzdHJ1Y3RzKSB7XG4gICAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRTdHJ1Y3Qoc3RydWN0KSk7XG4gICAgfVxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdENsYXNzZXMoXG4gICAgY2xhc3NlczogQ2xhc3NTY2hlbWFbXSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgaWYgKGNsYXNzZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gTWFya2Rvd25Eb2N1bWVudC5FTVBUWTtcbiAgICB9XG5cbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHsgaGVhZGVyOiB7IHRpdGxlOiAnQ2xhc3NlcycgfSB9KTtcbiAgICBmb3IgKGNvbnN0IGtsYXNzIG9mIGNsYXNzZXMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdENsYXNzKGtsYXNzKSk7XG4gICAgfVxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdEludGVyZmFjZXMoXG4gICAgaWZhY2VzOiBJbnRlcmZhY2VTY2hlbWFbXSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgaWYgKGlmYWNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBNYXJrZG93bkRvY3VtZW50LkVNUFRZO1xuICAgIH1cblxuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoeyBoZWFkZXI6IHsgdGl0bGU6ICdQcm90b2NvbHMnIH0gfSk7XG4gICAgZm9yIChjb25zdCBpZmFjZSBvZiBpZmFjZXMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdEludGVyZmFjZShpZmFjZSkpO1xuICAgIH1cbiAgICByZXR1cm4gbWQ7XG4gIH1cblxuICBwdWJsaWMgdmlzaXRFbnVtcyhcbiAgICBlbnVtczogRW51bVNjaGVtYVtdLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBpZiAoZW51bXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gTWFya2Rvd25Eb2N1bWVudC5FTVBUWTtcbiAgICB9XG5cbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHsgaGVhZGVyOiB7IHRpdGxlOiAnRW51bXMnIH0gfSk7XG4gICAgZm9yIChjb25zdCBlbnUgb2YgZW51bXMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdEVudW0oZW51KSk7XG4gICAgfVxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdENvbnN0cnVjdChcbiAgICBjb25zdHJ1Y3Q6IENvbnN0cnVjdFNjaGVtYSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgcmV0dXJuIHRoaXMudmlzaXRDbGFzcyhjb25zdHJ1Y3QpO1xuICB9XG5cbiAgcHVibGljIHZpc2l0U3RydWN0KFxuICAgIHN0cnVjdDogU3RydWN0U2NoZW1hLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHtcbiAgICAgIGlkOiB0aGlzLmFuY2hvckZvcm1hdHRlcih7XG4gICAgICAgIGlkOiBzdHJ1Y3QuaWQsXG4gICAgICAgIGRpc3BsYXlOYW1lOiBzdHJ1Y3QuZGlzcGxheU5hbWUsXG4gICAgICAgIGZxbjogc3RydWN0LmZxbixcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIH0pLFxuICAgICAgaGVhZGVyOiB7IHRpdGxlOiBzdHJ1Y3QuZGlzcGxheU5hbWUgfSxcbiAgICB9KTtcblxuICAgIGlmIChzdHJ1Y3QuZG9jcykge1xuICAgICAgbWQuZG9jcyhzdHJ1Y3QuZG9jcywgdGhpcy5sYW5ndWFnZSk7XG4gICAgfVxuXG4gICAgY29uc3QgaW5pdGlhbGl6ZXIgPSBuZXcgTWFya2Rvd25Eb2N1bWVudCh7XG4gICAgICBpZDogdGhpcy5hbmNob3JGb3JtYXR0ZXIoe1xuICAgICAgICBpZDogYCR7c3RydWN0LmlkfS5Jbml0aWFsaXplcmAsXG4gICAgICAgIGRpc3BsYXlOYW1lOiAnSW5pdGlhbGl6ZXInLFxuICAgICAgICBmcW46IGAke3N0cnVjdC5mcW59LkluaXRpYWxpemVyYCxcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIH0pLFxuICAgICAgaGVhZGVyOiB7IHRpdGxlOiAnSW5pdGlhbGl6ZXInIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoc3RydWN0LnVzYWdlKSB7XG4gICAgICBpbml0aWFsaXplci5jb2RlKHRoaXMubGFuZ3VhZ2UudG9TdHJpbmcoKSwgc3RydWN0LnVzYWdlKTtcbiAgICB9XG5cbiAgICBtZC5zZWN0aW9uKGluaXRpYWxpemVyKTtcbiAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRQcm9wZXJ0aWVzKHN0cnVjdC5wcm9wZXJ0aWVzKSk7XG4gICAgcmV0dXJuIG1kO1xuICB9XG5cbiAgcHVibGljIHZpc2l0Q2xhc3MoXG4gICAga2xhc3M6IENsYXNzU2NoZW1hLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHtcbiAgICAgIGlkOiB0aGlzLmFuY2hvckZvcm1hdHRlcih7XG4gICAgICAgIGlkOiBrbGFzcy5pZCxcbiAgICAgICAgZGlzcGxheU5hbWU6IGtsYXNzLmRpc3BsYXlOYW1lLFxuICAgICAgICBmcW46IGtsYXNzLmZxbixcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIH0pLFxuICAgICAgaGVhZGVyOiB7IHRpdGxlOiBrbGFzcy5kaXNwbGF5TmFtZSB9LFxuICAgIH0pO1xuXG4gICAgaWYgKGtsYXNzLmludGVyZmFjZXMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgaWZhY2VzID0gW107XG4gICAgICBmb3IgKGNvbnN0IGlmYWNlIG9mIGtsYXNzLmludGVyZmFjZXMpIHtcbiAgICAgICAgaWZhY2VzLnB1c2godGhpcy5saW5rRm9ybWF0dGVyKGlmYWNlLCB0aGlzLm1ldGFkYXRhKSk7XG4gICAgICB9XG4gICAgICBtZC5idWxsZXQoYCR7TWFya2Rvd25Eb2N1bWVudC5pdGFsaWMoJ0ltcGxlbWVudHM6Jyl9ICR7aWZhY2VzLmpvaW4oJywgJyl9YCk7XG4gICAgICBtZC5saW5lcygnJyk7XG4gICAgfVxuXG4gICAgaWYgKGtsYXNzLmRvY3MpIHtcbiAgICAgIG1kLmRvY3Moa2xhc3MuZG9jcywgdGhpcy5sYW5ndWFnZSk7XG4gICAgfVxuXG4gICAgaWYgKGtsYXNzLmluaXRpYWxpemVyKSB7XG4gICAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRJbml0aWFsaXplcihrbGFzcy5pbml0aWFsaXplcikpO1xuICAgIH1cblxuICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdEluc3RhbmNlTWV0aG9kcyhrbGFzcy5pbnN0YW5jZU1ldGhvZHMpKTtcbiAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRTdGF0aWNGdW5jdGlvbnMoa2xhc3Muc3RhdGljTWV0aG9kcykpO1xuICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdFByb3BlcnRpZXMoa2xhc3MucHJvcGVydGllcykpO1xuICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdENvbnN0YW50cyhrbGFzcy5jb25zdGFudHMpKTtcbiAgICByZXR1cm4gbWQ7XG4gIH1cblxuICBwdWJsaWMgdmlzaXRJbnRlcmZhY2UoXG4gICAgaWZhY2U6IEludGVyZmFjZVNjaGVtYSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgY29uc3QgbWQgPSBuZXcgTWFya2Rvd25Eb2N1bWVudCh7XG4gICAgICBpZDogdGhpcy5hbmNob3JGb3JtYXR0ZXIoe1xuICAgICAgICBpZDogaWZhY2UuaWQsXG4gICAgICAgIGRpc3BsYXlOYW1lOiBpZmFjZS5kaXNwbGF5TmFtZSxcbiAgICAgICAgZnFuOiBpZmFjZS5mcW4sXG4gICAgICAgIC4uLnRoaXMubWV0YWRhdGEsXG4gICAgICB9KSxcbiAgICAgIGhlYWRlcjogeyB0aXRsZTogaWZhY2UuZGlzcGxheU5hbWUgfSxcbiAgICB9KTtcblxuICAgIGlmIChpZmFjZS5pbnRlcmZhY2VzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGJhc2VzID0gW107XG4gICAgICBmb3IgKGNvbnN0IGJhc2Ugb2YgaWZhY2UuaW50ZXJmYWNlcykge1xuICAgICAgICBiYXNlcy5wdXNoKHRoaXMubGlua0Zvcm1hdHRlcihiYXNlLCB0aGlzLm1ldGFkYXRhKSk7XG4gICAgICB9XG4gICAgICBtZC5idWxsZXQoYCR7TWFya2Rvd25Eb2N1bWVudC5pdGFsaWMoJ0V4dGVuZHM6Jyl9ICR7YmFzZXMuam9pbignLCAnKX1gKTtcbiAgICAgIG1kLmxpbmVzKCcnKTtcbiAgICB9XG5cbiAgICBpZiAoaWZhY2UuaW1wbGVtZW50YXRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGltcGxzID0gW107XG4gICAgICBmb3IgKGNvbnN0IGltcGwgb2YgaWZhY2UuaW1wbGVtZW50YXRpb25zKSB7XG4gICAgICAgIGltcGxzLnB1c2godGhpcy5saW5rRm9ybWF0dGVyKGltcGwsIHRoaXMubWV0YWRhdGEpKTtcbiAgICAgIH1cbiAgICAgIG1kLmJ1bGxldChgJHtNYXJrZG93bkRvY3VtZW50Lml0YWxpYygnSW1wbGVtZW50ZWQgQnk6Jyl9ICR7aW1wbHMuam9pbignLCAnKX1gKTtcbiAgICAgIG1kLmxpbmVzKCcnKTtcbiAgICB9XG5cbiAgICBpZiAoaWZhY2UuZG9jcykge1xuICAgICAgbWQuZG9jcyhpZmFjZS5kb2NzLCB0aGlzLmxhbmd1YWdlKTtcbiAgICB9XG5cbiAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRJbnN0YW5jZU1ldGhvZHMoaWZhY2UuaW5zdGFuY2VNZXRob2RzKSk7XG4gICAgbWQuc2VjdGlvbih0aGlzLnZpc2l0UHJvcGVydGllcyhpZmFjZS5wcm9wZXJ0aWVzKSk7XG4gICAgcmV0dXJuIG1kO1xuICB9XG5cbiAgcHVibGljIHZpc2l0RW51bShcbiAgICBlbnU6IEVudW1TY2hlbWEsXG4gICk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoe1xuICAgICAgaWQ6IHRoaXMuYW5jaG9yRm9ybWF0dGVyKHtcbiAgICAgICAgaWQ6IGVudS5pZCxcbiAgICAgICAgZGlzcGxheU5hbWU6IGVudS5kaXNwbGF5TmFtZSxcbiAgICAgICAgZnFuOiBlbnUuZnFuLFxuICAgICAgICAuLi50aGlzLm1ldGFkYXRhLFxuICAgICAgfSksXG4gICAgICBoZWFkZXI6IHsgdGl0bGU6IGVudS5kaXNwbGF5TmFtZSB9LFxuICAgIH0pO1xuXG4gICAgaWYgKGVudS5kb2NzKSB7XG4gICAgICBtZC5kb2NzKGVudS5kb2NzLCB0aGlzLmxhbmd1YWdlKTtcbiAgICB9XG5cbiAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRFbnVtTWVtYmVycyhlbnUubWVtYmVycykpO1xuXG4gICAgcmV0dXJuIG1kO1xuICB9XG5cbiAgcHVibGljIHZpc2l0RW51bU1lbWJlcnMoXG4gICAgZW51czogRW51bU1lbWJlclNjaGVtYVtdLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBpZiAoZW51cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBNYXJrZG93bkRvY3VtZW50LkVNUFRZO1xuICAgIH1cblxuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoeyBoZWFkZXI6IHsgdGl0bGU6ICdNZW1iZXJzJyB9IH0pO1xuXG4gICAgbWQudGFibGUodGhpcy5jcmVhdGVUYWJsZShlbnVzKSk7XG4gICAgbWQuc3BsaXQoKTtcblxuICAgIGZvciAoY29uc3QgZW51IG9mIGVudXMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdEVudW1NZW1iZXIoZW51KSk7XG4gICAgfVxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdFByb3BlcnRpZXMoXG4gICAgcHJvcGVydGllczogUHJvcGVydHlTY2hlbWFbXSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgaWYgKHByb3BlcnRpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gTWFya2Rvd25Eb2N1bWVudC5FTVBUWTtcbiAgICB9XG5cbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHsgaGVhZGVyOiB7IHRpdGxlOiAnUHJvcGVydGllcycgfSB9KTtcblxuICAgIG1kLnRhYmxlKHRoaXMuY3JlYXRlVGFibGVXaXRoVHlwZXMocHJvcGVydGllcykpO1xuICAgIG1kLnNwbGl0KCk7XG5cbiAgICBmb3IgKGNvbnN0IHByb3Agb2YgcHJvcGVydGllcykge1xuICAgICAgbWQuc2VjdGlvbih0aGlzLnZpc2l0UHJvcGVydHkocHJvcCkpO1xuICAgIH1cblxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdEluaXRpYWxpemVyKFxuICAgIGluaXQ6IEluaXRpYWxpemVyU2NoZW1hLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHtcbiAgICAgIGlkOiB0aGlzLmFuY2hvckZvcm1hdHRlcih7XG4gICAgICAgIGlkOiBpbml0LmlkLFxuICAgICAgICBkaXNwbGF5TmFtZTogaW5pdC5kaXNwbGF5TmFtZSxcbiAgICAgICAgZnFuOiBpbml0LmZxbixcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIH0pLFxuICAgICAgaGVhZGVyOiB7XG4gICAgICAgIHRpdGxlOiAnSW5pdGlhbGl6ZXJzJyxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoaW5pdC51c2FnZSkge1xuICAgICAgbWQuY29kZSh0aGlzLmxhbmd1YWdlLnRvU3RyaW5nKCksIGluaXQudXNhZ2UpO1xuICAgIH1cblxuICAgIG1kLnRhYmxlKHRoaXMuY3JlYXRlVGFibGVXaXRoVHlwZXMoaW5pdC5wYXJhbWV0ZXJzKSk7XG4gICAgbWQuc3BsaXQoKTtcblxuICAgIGZvciAoY29uc3QgcGFyYW0gb2YgaW5pdC5wYXJhbWV0ZXJzKSB7XG4gICAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRQYXJhbWV0ZXIocGFyYW0pKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWQ7XG4gIH1cblxuICBwdWJsaWMgdmlzaXRJbnN0YW5jZU1ldGhvZHMoXG4gICAgbWV0aG9kczogTWV0aG9kU2NoZW1hW10sXG4gICk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGlmIChtZXRob2RzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIE1hcmtkb3duRG9jdW1lbnQuRU1QVFk7XG4gICAgfVxuXG4gICAgY29uc3QgbWQgPSBuZXcgTWFya2Rvd25Eb2N1bWVudCh7IGhlYWRlcjogeyB0aXRsZTogJ01ldGhvZHMnIH0gfSk7XG5cbiAgICBtZC50YWJsZSh0aGlzLmNyZWF0ZVRhYmxlKG1ldGhvZHMpKTtcbiAgICBtZC5zcGxpdCgpO1xuXG4gICAgZm9yIChjb25zdCBtZXRob2Qgb2YgbWV0aG9kcykge1xuICAgICAgbWQuc2VjdGlvbih0aGlzLnZpc2l0SW5zdGFuY2VNZXRob2QobWV0aG9kKSk7XG4gICAgfVxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdFN0YXRpY0Z1bmN0aW9ucyhcbiAgICBtZXRob2RzOiBNZXRob2RTY2hlbWFbXSxcbiAgKSB7XG4gICAgaWYgKG1ldGhvZHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gTWFya2Rvd25Eb2N1bWVudC5FTVBUWTtcbiAgICB9XG5cbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHsgaGVhZGVyOiB7IHRpdGxlOiAnU3RhdGljIEZ1bmN0aW9ucycgfSB9KTtcblxuICAgIG1kLnRhYmxlKHRoaXMuY3JlYXRlVGFibGUobWV0aG9kcykpO1xuICAgIG1kLnNwbGl0KCk7XG5cbiAgICBmb3IgKGNvbnN0IG1ldGhvZCBvZiBtZXRob2RzKSB7XG4gICAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRTdGF0aWNGdW5jdGlvbihtZXRob2QpKTtcbiAgICB9XG4gICAgcmV0dXJuIG1kO1xuICB9XG5cbiAgcHVibGljIHZpc2l0Q29uc3RhbnRzKFxuICAgIGNvbnN0YW50czogUHJvcGVydHlTY2hlbWFbXSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgaWYgKGNvbnN0YW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBNYXJrZG93bkRvY3VtZW50LkVNUFRZO1xuICAgIH1cblxuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoeyBoZWFkZXI6IHsgdGl0bGU6ICdDb25zdGFudHMnIH0gfSk7XG5cbiAgICBtZC50YWJsZSh0aGlzLmNyZWF0ZVRhYmxlV2l0aFR5cGVzKGNvbnN0YW50cykpO1xuICAgIG1kLnNwbGl0KCk7XG5cbiAgICBmb3IgKGNvbnN0IGNvbiBvZiBjb25zdGFudHMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdENvbnN0YW50KGNvbikpO1xuICAgIH1cblxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdEVudW1NZW1iZXIoXG4gICAgZW06IEVudW1NZW1iZXJTY2hlbWEsXG4gICk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoe1xuICAgICAgaWQ6IHRoaXMuYW5jaG9yRm9ybWF0dGVyKHtcbiAgICAgICAgaWQ6IGVtLmlkLFxuICAgICAgICBkaXNwbGF5TmFtZTogZW0uZGlzcGxheU5hbWUsXG4gICAgICAgIGZxbjogZW0uZnFuLFxuICAgICAgICAuLi50aGlzLm1ldGFkYXRhLFxuICAgICAgfSksXG4gICAgICBoZWFkZXI6IHtcbiAgICAgICAgdGl0bGU6IGVtLmRpc3BsYXlOYW1lLFxuICAgICAgICBwcmU6IHRydWUsXG4gICAgICAgIHN0cmlrZTogZW0uZG9jcy5kZXByZWNhdGVkLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmIChlbS5kb2NzLmRlcHJlY2F0ZWQpIHtcbiAgICAgIG1kLmJ1bGxldChcbiAgICAgICAgYCR7TWFya2Rvd25Eb2N1bWVudC5pdGFsaWMoJ0RlcHJlY2F0ZWQ6Jyl9ICR7ZW0uZG9jcy5kZXByZWNhdGlvblJlYXNvbn1gLFxuICAgICAgKTtcbiAgICAgIG1kLmxpbmVzKCcnKTtcbiAgICB9XG5cbiAgICBpZiAoZW0uZG9jcykge1xuICAgICAgbWQuZG9jcyhlbS5kb2NzLCB0aGlzLmxhbmd1YWdlKTtcbiAgICB9XG5cbiAgICBtZC5zcGxpdCgpO1xuICAgIG1kLmxpbmVzKCcnKTtcblxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdFByb3BlcnR5KFxuICAgIHByb3A6IFByb3BlcnR5U2NoZW1hLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBjb25zdCBvcHRpb25hbGl0eSA9IHByb3Aub3B0aW9uYWxcbiAgICAgID8gJ09wdGlvbmFsJ1xuICAgICAgOiAnUmVxdWlyZWQnO1xuXG4gICAgY29uc3QgbWQgPSBuZXcgTWFya2Rvd25Eb2N1bWVudCh7XG4gICAgICBpZDogdGhpcy5hbmNob3JGb3JtYXR0ZXIoe1xuICAgICAgICBpZDogcHJvcC5pZCxcbiAgICAgICAgZGlzcGxheU5hbWU6IHByb3AuZGlzcGxheU5hbWUsXG4gICAgICAgIGZxbjogcHJvcC5mcW4sXG4gICAgICAgIC4uLnRoaXMubWV0YWRhdGEsXG4gICAgICB9KSxcbiAgICAgIGhlYWRlcjoge1xuICAgICAgICB0aXRsZTogcHJvcC5kaXNwbGF5TmFtZSxcbiAgICAgICAgc3VwOiBvcHRpb25hbGl0eSxcbiAgICAgICAgcHJlOiB0cnVlLFxuICAgICAgICBzdHJpa2U6IHByb3AuZG9jcy5kZXByZWNhdGVkLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmIChwcm9wLmRvY3MuZGVwcmVjYXRlZCkge1xuICAgICAgbWQuYnVsbGV0KFxuICAgICAgICBgJHtNYXJrZG93bkRvY3VtZW50Lml0YWxpYygnRGVwcmVjYXRlZDonKX0gJHtwcm9wLmRvY3MuZGVwcmVjYXRpb25SZWFzb259YCxcbiAgICAgICk7XG4gICAgICBtZC5saW5lcygnJyk7XG4gICAgfVxuXG4gICAgaWYgKHByb3AudXNhZ2UpIHtcbiAgICAgIG1kLmNvZGUodGhpcy5sYW5ndWFnZS50b1N0cmluZygpLCBwcm9wLnVzYWdlKTtcbiAgICB9XG5cbiAgICBjb25zdCBtZXRhZGF0YTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgIFR5cGU6IHRoaXMudHlwZUZvcm1hdHRlcihwcm9wLnR5cGUsIHRoaXMubWV0YWRhdGEsIHRoaXMubGlua0Zvcm1hdHRlciksXG4gICAgfTtcblxuICAgIGlmIChwcm9wLmRlZmF1bHQpIHtcbiAgICAgIGNvbnN0IHNhbml0aXplZCA9IE1hcmtkb3duRG9jdW1lbnQuc2FuaXRpemUocHJvcC5kZWZhdWx0KTtcbiAgICAgIG1ldGFkYXRhLkRlZmF1bHQgPSBNYXJrZG93bkRvY3VtZW50LnJlbW92ZU5ld2xpbmVzKHNhbml0aXplZCk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMobWV0YWRhdGEpKSB7XG4gICAgICBtZC5idWxsZXQoYCR7TWFya2Rvd25Eb2N1bWVudC5pdGFsaWMoYCR7a2V5fTpgKX0gJHt2YWx1ZX1gKTtcbiAgICB9XG4gICAgbWQubGluZXMoJycpO1xuXG4gICAgaWYgKHByb3AuZG9jcykge1xuICAgICAgbWQuZG9jcyhwcm9wLmRvY3MsIHRoaXMubGFuZ3VhZ2UpO1xuICAgIH1cblxuICAgIG1kLnNwbGl0KCk7XG5cbiAgICByZXR1cm4gbWQ7XG4gIH1cblxuICBwdWJsaWMgdmlzaXRQYXJhbWV0ZXIoXG4gICAgcGFyYW1ldGVyOiBQYXJhbWV0ZXJTY2hlbWEsXG4gICk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IG9wdGlvbmFsaXR5ID0gcGFyYW1ldGVyLm9wdGlvbmFsID8gJ09wdGlvbmFsJyA6ICdSZXF1aXJlZCc7XG5cbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHtcbiAgICAgIGlkOiB0aGlzLmFuY2hvckZvcm1hdHRlcih7XG4gICAgICAgIGlkOiBwYXJhbWV0ZXIuaWQsXG4gICAgICAgIGRpc3BsYXlOYW1lOiBwYXJhbWV0ZXIuZGlzcGxheU5hbWUsXG4gICAgICAgIGZxbjogcGFyYW1ldGVyLmZxbixcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIH0pLFxuICAgICAgaGVhZGVyOiB7XG4gICAgICAgIHRpdGxlOiBwYXJhbWV0ZXIuZGlzcGxheU5hbWUsXG4gICAgICAgIHN1cDogb3B0aW9uYWxpdHksXG4gICAgICAgIHByZTogdHJ1ZSxcbiAgICAgICAgc3RyaWtlOiBwYXJhbWV0ZXIuZG9jcy5kZXByZWNhdGVkLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmIChwYXJhbWV0ZXIuZG9jcy5kZXByZWNhdGVkKSB7XG4gICAgICBtZC5idWxsZXQoXG4gICAgICAgIGAke01hcmtkb3duRG9jdW1lbnQuaXRhbGljKCdEZXByZWNhdGVkOicpfSAke3BhcmFtZXRlci5kb2NzLmRlcHJlY2F0aW9uUmVhc29ufWAsXG4gICAgICApO1xuICAgICAgbWQubGluZXMoJycpO1xuICAgIH1cblxuXG4gICAgY29uc3QgbWV0YWRhdGE6IGFueSA9IHtcbiAgICAgIFR5cGU6IHRoaXMudHlwZUZvcm1hdHRlcihwYXJhbWV0ZXIudHlwZSwgdGhpcy5tZXRhZGF0YSwgdGhpcy5saW5rRm9ybWF0dGVyKSxcbiAgICB9O1xuXG4gICAgaWYgKHBhcmFtZXRlci5kZWZhdWx0KSB7XG4gICAgICBjb25zdCBzYW5pdGl6ZWQgPSBNYXJrZG93bkRvY3VtZW50LnNhbml0aXplKHBhcmFtZXRlci5kZWZhdWx0KTtcbiAgICAgIG1ldGFkYXRhLkRlZmF1bHQgPSBNYXJrZG93bkRvY3VtZW50LnJlbW92ZU5ld2xpbmVzKHNhbml0aXplZCk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMobWV0YWRhdGEpKSB7XG4gICAgICBtZC5idWxsZXQoYCR7TWFya2Rvd25Eb2N1bWVudC5pdGFsaWMoYCR7a2V5fTpgKX0gJHt2YWx1ZX1gKTtcbiAgICB9XG4gICAgbWQubGluZXMoJycpO1xuXG4gICAgaWYgKHBhcmFtZXRlci5kb2NzKSB7XG4gICAgICBtZC5kb2NzKHBhcmFtZXRlci5kb2NzLCB0aGlzLmxhbmd1YWdlKTtcbiAgICB9XG5cbiAgICBtZC5zcGxpdCgpO1xuXG4gICAgcmV0dXJuIG1kO1xuICB9XG5cbiAgcHVibGljIHZpc2l0SW5zdGFuY2VNZXRob2QoXG4gICAgbWV0aG9kOiBNZXRob2RTY2hlbWEsXG4gICk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoe1xuICAgICAgaWQ6IHRoaXMuYW5jaG9yRm9ybWF0dGVyKHtcbiAgICAgICAgaWQ6IG1ldGhvZC5pZCxcbiAgICAgICAgZGlzcGxheU5hbWU6IG1ldGhvZC5kaXNwbGF5TmFtZSxcbiAgICAgICAgZnFuOiBtZXRob2QuZnFuLFxuICAgICAgICAuLi50aGlzLm1ldGFkYXRhLFxuICAgICAgfSksXG4gICAgICBoZWFkZXI6IHtcbiAgICAgICAgdGl0bGU6IG1ldGhvZC5kaXNwbGF5TmFtZSxcbiAgICAgICAgcHJlOiB0cnVlLFxuICAgICAgICBzdHJpa2U6IG1ldGhvZC5kb2NzLmRlcHJlY2F0ZWQsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKG1ldGhvZC51c2FnZSkge1xuICAgICAgbWQuY29kZSh0aGlzLmxhbmd1YWdlLnRvU3RyaW5nKCksIG1ldGhvZC51c2FnZSk7XG4gICAgfVxuXG4gICAgaWYgKG1ldGhvZC5kb2NzKSB7XG4gICAgICBtZC5kb2NzKG1ldGhvZC5kb2NzLCB0aGlzLmxhbmd1YWdlKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHBhcmFtIG9mIG1ldGhvZC5wYXJhbWV0ZXJzKSB7XG4gICAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRQYXJhbWV0ZXIocGFyYW0pKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWQ7XG4gIH1cblxuICBwdWJsaWMgdmlzaXRTdGF0aWNGdW5jdGlvbihcbiAgICBtZXRob2Q6IE1ldGhvZFNjaGVtYSxcbiAgKSB7XG4gICAgY29uc3QgbWQgPSBuZXcgTWFya2Rvd25Eb2N1bWVudCh7XG4gICAgICBpZDogdGhpcy5hbmNob3JGb3JtYXR0ZXIoe1xuICAgICAgICBpZDogbWV0aG9kLmlkLFxuICAgICAgICBkaXNwbGF5TmFtZTogbWV0aG9kLmRpc3BsYXlOYW1lLFxuICAgICAgICBmcW46IG1ldGhvZC5mcW4sXG4gICAgICAgIC4uLnRoaXMubWV0YWRhdGEsXG4gICAgICB9KSxcbiAgICAgIGhlYWRlcjoge1xuICAgICAgICB0aXRsZTogbWV0aG9kLmRpc3BsYXlOYW1lLFxuICAgICAgICBwcmU6IHRydWUsXG4gICAgICAgIHN0cmlrZTogbWV0aG9kLmRvY3MuZGVwcmVjYXRlZCxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAobWV0aG9kLnVzYWdlKSB7XG4gICAgICBtZC5jb2RlKHRoaXMubGFuZ3VhZ2UudG9TdHJpbmcoKSwgbWV0aG9kLnVzYWdlKTtcbiAgICB9XG5cbiAgICBpZiAobWV0aG9kLmRvY3MpIHtcbiAgICAgIG1kLmRvY3MobWV0aG9kLmRvY3MsIHRoaXMubGFuZ3VhZ2UpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcGFyYW0gb2YgbWV0aG9kLnBhcmFtZXRlcnMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdFBhcmFtZXRlcihwYXJhbSkpO1xuICAgIH1cblxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdENvbnN0YW50KFxuICAgIGNvbnN0YW50OiBQcm9wZXJ0eVNjaGVtYSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgcmV0dXJuIHRoaXMudmlzaXRQcm9wZXJ0eShjb25zdGFudCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVRhYmxlKGl0ZW1zOiBTaW1wbGVUYWJsZUl0ZW1bXSk6IHN0cmluZ1tdW10ge1xuICAgIGNvbnN0IHRhYmxlUm93czogc3RyaW5nW11bXSA9IFtdO1xuICAgIHRhYmxlUm93cy5wdXNoKFsnTmFtZScsICdEZXNjcmlwdGlvbiddLm1hcChNYXJrZG93bkRvY3VtZW50LmJvbGQpKTtcblxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgY29uc3QgbGluayA9IE1hcmtkb3duRG9jdW1lbnQucHJlKHRoaXMubGlua0Zvcm1hdHRlcih7XG4gICAgICAgIGZxbjogaXRlbS5mcW4sXG4gICAgICAgIGRpc3BsYXlOYW1lOiBpdGVtLmRpc3BsYXlOYW1lLFxuICAgICAgICBpZDogaXRlbS5pZCxcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIH0sIHRoaXMubWV0YWRhdGEpKTtcbiAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gaXRlbS5kb2NzPy5zdW1tYXJ5ICYmIGl0ZW0uZG9jcz8uc3VtbWFyeS5sZW5ndGggPiAwXG4gICAgICAgID8gaXRlbS5kb2NzPy5zdW1tYXJ5XG4gICAgICAgIDogTWFya2Rvd25Eb2N1bWVudC5pdGFsaWMoJ05vIGRlc2NyaXB0aW9uLicpO1xuICAgICAgdGFibGVSb3dzLnB1c2goW2xpbmssIGRlc2NyaXB0aW9uXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhYmxlUm93cztcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVGFibGVXaXRoVHlwZXMoaXRlbXM6IFR5cGVUYWJsZUl0ZW1bXSk6IHN0cmluZ1tdW10ge1xuICAgIGNvbnN0IHRhYmxlUm93czogc3RyaW5nW11bXSA9IFtdO1xuICAgIHRhYmxlUm93cy5wdXNoKFsnTmFtZScsICdUeXBlJywgJ0Rlc2NyaXB0aW9uJ10ubWFwKE1hcmtkb3duRG9jdW1lbnQuYm9sZCkpO1xuXG4gICAgZm9yIChjb25zdCBpdGVtIG9mIGl0ZW1zKSB7XG4gICAgICBjb25zdCBsaW5rID0gTWFya2Rvd25Eb2N1bWVudC5wcmUodGhpcy5saW5rRm9ybWF0dGVyKHtcbiAgICAgICAgZnFuOiBpdGVtLmZxbixcbiAgICAgICAgZGlzcGxheU5hbWU6IGl0ZW0uZGlzcGxheU5hbWUsXG4gICAgICAgIGlkOiBpdGVtLmlkLFxuICAgICAgICAuLi50aGlzLm1ldGFkYXRhLFxuICAgICAgfSwgdGhpcy5tZXRhZGF0YSkpO1xuICAgICAgY29uc3QgdHlwZSA9IE1hcmtkb3duRG9jdW1lbnQucHJlKHRoaXMudHlwZUZvcm1hdHRlcihpdGVtLnR5cGUsIHRoaXMubWV0YWRhdGEsIHRoaXMubGlua0Zvcm1hdHRlcikpO1xuICAgICAgY29uc3QgZGVzY3JpcHRpb24gPSBpdGVtLmRvY3M/LnN1bW1hcnkgJiYgaXRlbS5kb2NzPy5zdW1tYXJ5Lmxlbmd0aCA+IDBcbiAgICAgICAgPyBpdGVtLmRvY3M/LnN1bW1hcnlcbiAgICAgICAgOiBNYXJrZG93bkRvY3VtZW50Lml0YWxpYygnTm8gZGVzY3JpcHRpb24uJyk7XG4gICAgICB0YWJsZVJvd3MucHVzaChbbGluaywgdHlwZSwgZGVzY3JpcHRpb25dKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGFibGVSb3dzO1xuICB9XG59XG5cbmludGVyZmFjZSBTaW1wbGVUYWJsZUl0ZW0ge1xuICByZWFkb25seSBmcW46IHN0cmluZztcbiAgcmVhZG9ubHkgZGlzcGxheU5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgZG9jcz86IHsgc3VtbWFyeT86IHN0cmluZyB9O1xufVxuXG5pbnRlcmZhY2UgVHlwZVRhYmxlSXRlbSBleHRlbmRzIFNpbXBsZVRhYmxlSXRlbSB7XG4gIHJlYWRvbmx5IHR5cGU6IFR5cGVTY2hlbWE7XG59XG5cbmZ1bmN0aW9uIHNhbml0aXplKHN0cjogc3RyaW5nKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvIC9nLCAnLScpO1xufVxuXG5leHBvcnQgY29uc3QgZGVmYXVsdEFuY2hvckZvcm1hdHRlciA9ICh0eXBlOiBKc2lpRW50aXR5KSA9PiB7XG4gIC8vIEhUTUw1IGFsbG93cyBhbnkgY2hhcmFjdGVyIGluIElEcyAvZXhjZXB0LyB3aGl0ZXNwYWNlXG4gIHJldHVybiBzYW5pdGl6ZSh0eXBlLmlkKTtcbn07XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0TGlua0Zvcm1hdHRlciA9ICh0eXBlOiBKc2lpRW50aXR5LCBtZXRhZGF0YTogQXNzZW1ibHlNZXRhZGF0YVNjaGVtYSkgPT4ge1xuICBpZiAodHlwZS5wYWNrYWdlTmFtZSA9PT0gbWV0YWRhdGEucGFja2FnZU5hbWUgJiYgdHlwZS5zdWJtb2R1bGUgPT09IG1ldGFkYXRhLnN1Ym1vZHVsZSkge1xuICAgIHJldHVybiBgPGEgaHJlZj1cIiMke3Nhbml0aXplKHR5cGUuaWQpfVwiPiR7dHlwZS5kaXNwbGF5TmFtZX08L2E+YDtcbiAgfSBlbHNlIHtcbiAgICAvLyBkbyBub3QgZGlzcGxheSBhIGxpbmsgaWYgdGhlIHR5cGUgaXNuJ3QgaW4gdGhpcyBkb2N1bWVudFxuICAgIHJldHVybiB0eXBlLmZxbjtcbiAgfVxufTtcblxuZnVuY3Rpb24gaXNKc2lpVHlwZSh2YWx1ZTogYW55KTogdmFsdWUgaXMgSnNpaUVudGl0eSB7XG4gIHJldHVybiAoXG4gICAgdmFsdWUgIT09IG51bGxcbiAgICAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnXG4gICAgJiYgdmFsdWU/LmZxblxuICAgICYmIHZhbHVlPy5pZFxuICAgICYmIHZhbHVlPy5kaXNwbGF5TmFtZVxuICApO1xufVxuXG5leHBvcnQgY29uc3QgZGVmYXVsdFR5cGVGb3JtYXR0ZXIgPSAoXG4gIHR5cGU6IFR5cGVTY2hlbWEsXG4gIG1ldGFkYXRhOiBBc3NlbWJseU1ldGFkYXRhU2NoZW1hLFxuICBsaW5rRm9ybWF0dGVyOiAodHlwZTogSnNpaUVudGl0eSwgbWV0YWRhdGE6IEFzc2VtYmx5TWV0YWRhdGFTY2hlbWEpID0+IHN0cmluZyxcbik6IHN0cmluZyA9PiB7XG4gIGxldCByZXN1bHQgPSB0eXBlLmZvcm1hdHRpbmdQYXR0ZXJuO1xuICBjb25zdCB0eXBlUmVmcyA9IFtdO1xuICBmb3IgKGNvbnN0IHR5cGVSZWYgb2YgdHlwZS50eXBlcyA/PyBbXSkge1xuICAgIGlmIChpc0pzaWlUeXBlKHR5cGVSZWYpKSB7XG4gICAgICB0eXBlUmVmcy5wdXNoKGxpbmtGb3JtYXR0ZXIodHlwZVJlZiwgbWV0YWRhdGEpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHlwZVJlZnMucHVzaChkZWZhdWx0VHlwZUZvcm1hdHRlcih0eXBlUmVmLCBtZXRhZGF0YSwgbGlua0Zvcm1hdHRlcikpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHN1YnN0aXR1dGUgcmVmZXJyZWQgdHlwZXMgaW50byB0aGUgb3JpZ2luYWwgc3RyaW5nXG4gIGNvbnN0IHBsYWNlaG9sZGVyTWF0Y2hlciA9IC9cXCUvZztcbiAgZm9yIChjb25zdCB0eXBlUmVmIG9mIHR5cGVSZWZzKSB7XG4gICAgY29uc3QgbWF0Y2hlcyA9IHBsYWNlaG9sZGVyTWF0Y2hlci5leGVjKHJlc3VsdCk7XG4gICAgaWYgKCFtYXRjaGVzKSB7XG4gICAgICAvLyBpdCdzIHBvc3NpYmxlIHRoZSBudW1iZXIgb2YgJSdzIGRvZXNuJ3QgbWF0Y2ggdGhlIG51bWJlciBvZiB0eXBlcyBwcm92aWRlZFxuICAgICAgLy8gZS5nLiBjc2hhcnAgdW5pb25zIGFyZSBjdXJyZW50bHkgcmVuZGVyZWQgdG8gYHsgbmFtZTogJ29iamVjdCcsIHR5cGVzOiBbdHlwZTEsIHR5cGUyXSB9YFxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IGluc2VydGlvbklkeDogbnVtYmVyID0gbWF0Y2hlcy5pbmRleDtcbiAgICByZXN1bHQgPSByZXN1bHQuc3Vic3RyaW5nKDAsIGluc2VydGlvbklkeCkgKyB0eXBlUmVmICsgcmVzdWx0LnN1YnN0cmluZyhpbnNlcnRpb25JZHggKyAxKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuIl19