@selfage/generator_cli
Version:
Code generation for message, service, and database.
212 lines • 37 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateService = generateService;
exports.generateRemoteCallsGroup = generateRemoteCallsGroup;
exports.generateRemoteCall = generateRemoteCall;
const output_content_builder_1 = require("./output_content_builder");
const util_1 = require("./util");
let PRIMITIVE_TYPE_BYTES = "bytes";
let PRIMITIVE_TYPES = new Set([PRIMITIVE_TYPE_BYTES]);
function generateService(definitionModulePath, serviceDefinition, outputContentMap) {
let contentBuilder = output_content_builder_1.TsContentBuilder.get(outputContentMap, definitionModulePath);
if (!serviceDefinition.name) {
throw new Error(`"name" is missing on a service.`);
}
if (!serviceDefinition.path) {
throw new Error(`"path" is missing on service ${serviceDefinition.name}.`);
}
contentBuilder.importFromServiceDescriptor(`ServiceDescriptor`);
contentBuilder.push(`
export let ${(0, util_1.toUppercaseSnaked)(serviceDefinition.name)}: ServiceDescriptor = {
name: "${serviceDefinition.name}",
path: "${serviceDefinition.path}",
}
`);
}
function generateRemoteCallsGroup(definitionModulePath, remoteCallsGroupDefinition, definitionResolver, outputContentMap) {
let descriptorContentBuilder = output_content_builder_1.TsContentBuilder.get(outputContentMap, definitionModulePath);
if (!remoteCallsGroupDefinition.service) {
throw new Error(`"service" is missing on remote calls group ${remoteCallsGroupDefinition.name}.`);
}
let definition = definitionResolver.resolve(`When looking for service definition for remote calls group ${remoteCallsGroupDefinition.name},`, remoteCallsGroupDefinition.service, remoteCallsGroupDefinition.importService);
if (definition.kind !== "Service") {
throw new Error(`Service name ${remoteCallsGroupDefinition.service} on remote calls group ${remoteCallsGroupDefinition.name} is not a service.`);
}
let serviceName = (0, util_1.toUppercaseSnaked)(remoteCallsGroupDefinition.service);
descriptorContentBuilder.importFromDefinition(remoteCallsGroupDefinition.importService, serviceName);
if (!remoteCallsGroupDefinition.outputClient) {
throw new Error(`"outputClient" is missing on remote calls group ${remoteCallsGroupDefinition.name}.`);
}
let clientContentBuilder = output_content_builder_1.TsContentBuilder.get(outputContentMap, definitionModulePath, remoteCallsGroupDefinition.outputClient);
if (!remoteCallsGroupDefinition.outputHandler) {
throw new Error(`"outputHandler" is missing on remote calls group ${remoteCallsGroupDefinition.name}.`);
}
let handlerContentBuilder = output_content_builder_1.TsContentBuilder.get(outputContentMap, definitionModulePath, remoteCallsGroupDefinition.outputHandler);
if (!remoteCallsGroupDefinition.calls) {
throw new Error(`"calls" is either missing or not an array on remote calls group ${remoteCallsGroupDefinition.name}.`);
}
for (let remoteCall of remoteCallsGroupDefinition.calls) {
generateRemoteCall(definitionModulePath, remoteCall, serviceName, definitionResolver, descriptorContentBuilder, clientContentBuilder, handlerContentBuilder);
}
}
function generateRemoteCall(definitionModulePath, remoteCallDefinition, serviceName, definitionResolver, descriptorContentBuilder, clientContentBuilder, handlerContentBuilder) {
if (!remoteCallDefinition.name) {
throw new Error(`"name" is missing on a RemoteCall.`);
}
let loggingPrefix = `When generating descriptor for remote call ${remoteCallDefinition.name},`;
let bodyDescriptor = "";
if (!remoteCallDefinition.body) {
throw new Error(`${loggingPrefix} "body" is missing.`);
}
if (PRIMITIVE_TYPES.has(remoteCallDefinition.body)) {
descriptorContentBuilder.importFromServiceDescriptor("PrimitveTypeForBody");
bodyDescriptor = `
body: {
primitiveType: PrimitveTypeForBody.${remoteCallDefinition.body.toUpperCase()},
},`;
}
else {
let requesBodytDefinition = definitionResolver.resolve(loggingPrefix, remoteCallDefinition.body, remoteCallDefinition.importBody);
if (requesBodytDefinition.kind !== "Message") {
throw new Error(`${loggingPrefix} request body ${remoteCallDefinition.body} is not a message.`);
}
let requestBodyDescriptorName = (0, util_1.toUppercaseSnaked)(remoteCallDefinition.body);
descriptorContentBuilder.importFromDefinition(remoteCallDefinition.importBody, requestBodyDescriptorName);
bodyDescriptor = `
body: {
messageType: ${requestBodyDescriptorName},
},`;
}
let metadataDescriptor = "";
if (remoteCallDefinition.metadata) {
if (!remoteCallDefinition.metadata.type) {
throw new Error(`${loggingPrefix} "type" is missing in the "metadata" field.`);
}
let metadataDefinition = definitionResolver.resolve(loggingPrefix, remoteCallDefinition.metadata.type, remoteCallDefinition.metadata.import);
if (metadataDefinition.kind !== "Message") {
throw new Error(`${loggingPrefix} metadata type ${remoteCallDefinition.metadata.type} is not a message.`);
}
let metadataDescriptorName = (0, util_1.toUppercaseSnaked)(remoteCallDefinition.metadata.type);
descriptorContentBuilder.importFromDefinition(remoteCallDefinition.metadata.import, metadataDescriptorName);
if (!remoteCallDefinition.metadata.key) {
throw new Error(`${loggingPrefix} "key" is missing in the "metadata" field.`);
}
metadataDescriptor = `
metadata: {
key: "${remoteCallDefinition.metadata.key}",
type: ${metadataDescriptorName},
},`;
}
let authKey = "";
if (remoteCallDefinition.authKey) {
authKey = `
authKey: "${remoteCallDefinition.authKey}",`;
}
if (!remoteCallDefinition.response) {
throw new Error(`${loggingPrefix} "response" is missing.`);
}
let responseDefinition = definitionResolver.resolve(loggingPrefix, remoteCallDefinition.response, remoteCallDefinition.importResponse);
if (responseDefinition.kind !== "Message") {
throw new Error(`${loggingPrefix} response type ${remoteCallDefinition.response} is not a message.`);
}
let responseDescriptorName = (0, util_1.toUppercaseSnaked)(remoteCallDefinition.response);
descriptorContentBuilder.importFromDefinition(remoteCallDefinition.importResponse, responseDescriptorName);
let responseDescriptor = `
response: {
messageType: ${responseDescriptorName},
},`;
descriptorContentBuilder.importFromServiceDescriptor("RemoteCallDescriptor");
let remoteCallDescriptorName = (0, util_1.toUppercaseSnaked)(remoteCallDefinition.name);
descriptorContentBuilder.push(`
export let ${remoteCallDescriptorName}: RemoteCallDescriptor = {
name: "${remoteCallDefinition.name}",
service: ${serviceName},
path: "${remoteCallDefinition.path}",${bodyDescriptor}${metadataDescriptor}${authKey}${responseDescriptor}
}
`);
generateClient(definitionModulePath, remoteCallDefinition, clientContentBuilder);
generateHandler(definitionModulePath, remoteCallDefinition, handlerContentBuilder);
}
function generateClient(definitionModulePath, remoteCallDefinition, clientContentBuilder) {
let loggingPrefix = `When generating client for ${remoteCallDefinition.name},`;
let bodyParam = "";
if (PRIMITIVE_TYPES.has(remoteCallDefinition.body)) {
if (remoteCallDefinition.body === PRIMITIVE_TYPE_BYTES) {
bodyParam = `
body: Blob,`;
}
else {
throw new Error(`${loggingPrefix} there is a new primitive type needs to be handled for its request body.`);
}
}
else {
clientContentBuilder.importFromDefinition(remoteCallDefinition.importBody, remoteCallDefinition.body);
bodyParam = `
body: ${remoteCallDefinition.body},`;
}
let metadataParam = "";
let metdataVariable = "";
if (remoteCallDefinition.metadata) {
clientContentBuilder.importFromDefinition(remoteCallDefinition.metadata.import, remoteCallDefinition.metadata.type);
metadataParam = `
metadata: ${remoteCallDefinition.metadata.type},`;
metdataVariable = `
metadata,`;
}
clientContentBuilder.importFromDefinition(remoteCallDefinition.importResponse, remoteCallDefinition.response);
let remoteCallDescriptorName = (0, util_1.toUppercaseSnaked)(remoteCallDefinition.name);
clientContentBuilder.importFromDefinition(definitionModulePath, remoteCallDescriptorName);
clientContentBuilder.importFromServiceClientRequestInterface("ClientRequestInterface");
clientContentBuilder.push(`
export function new${remoteCallDefinition.name}Request(${bodyParam}${metadataParam}
): ClientRequestInterface<${remoteCallDefinition.response}> {
return {
descriptor: ${remoteCallDescriptorName},
body,${metdataVariable}
};
}
`);
}
function generateHandler(definitionModulePath, remoteCallDefinition, handlerContentBuilder) {
let loggingPrefix = `When generating handler for ${remoteCallDefinition.name},`;
let bodyParam = "";
if (PRIMITIVE_TYPES.has(remoteCallDefinition.body)) {
if (remoteCallDefinition.body === PRIMITIVE_TYPE_BYTES) {
handlerContentBuilder.importFromStream("Readable");
bodyParam = `
body: Readable,`;
}
else {
throw new Error(`${loggingPrefix} there is a new primitive type needs to be handled for its request body.`);
}
}
else {
handlerContentBuilder.importFromDefinition(remoteCallDefinition.importBody, remoteCallDefinition.body);
bodyParam = `
body: ${remoteCallDefinition.body},`;
}
let metadataParam = "";
if (remoteCallDefinition.metadata) {
handlerContentBuilder.importFromDefinition(remoteCallDefinition.metadata.import, remoteCallDefinition.metadata.type);
metadataParam = `
metadata: ${remoteCallDefinition.metadata.type},`;
}
let authStrParam = "";
if (remoteCallDefinition.authKey) {
authStrParam = `
authStr: string,`;
}
let remoteCallDescriptorName = (0, util_1.toUppercaseSnaked)(remoteCallDefinition.name);
handlerContentBuilder.importFromDefinition(definitionModulePath, remoteCallDescriptorName);
handlerContentBuilder.importFromDefinition(remoteCallDefinition.importResponse, remoteCallDefinition.response);
handlerContentBuilder.importFromServiceRemoteCallHandlerInterface("RemoteCallHandlerInterface");
handlerContentBuilder.push(`
export abstract class ${remoteCallDefinition.name}HandlerInterface implements RemoteCallHandlerInterface {
public descriptor = ${remoteCallDescriptorName};
public abstract handle(
loggingPrefix: string,${bodyParam}${metadataParam}${authStrParam}
): Promise<${remoteCallDefinition.response}>;
}
`);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZV9nZW5lcmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzZXJ2aWNlX2dlbmVyYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWVBLDBDQXNCQztBQUVELDREQXFFQztBQUVELGdEQW9JQztBQTVPRCxxRUFHa0M7QUFDbEMsaUNBQTJDO0FBRTNDLElBQUksb0JBQW9CLEdBQUcsT0FBTyxDQUFDO0FBQ25DLElBQUksZUFBZSxHQUFHLElBQUksR0FBRyxDQUFTLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDO0FBRTlELFNBQWdCLGVBQWUsQ0FDN0Isb0JBQTRCLEVBQzVCLGlCQUFvQyxFQUNwQyxnQkFBbUQ7SUFFbkQsSUFBSSxjQUFjLEdBQUcseUNBQWdCLENBQUMsR0FBRyxDQUN2QyxnQkFBZ0IsRUFDaEIsb0JBQW9CLENBQ3JCLENBQUM7SUFDRixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDNUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFDRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDNUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsaUJBQWlCLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztJQUM3RSxDQUFDO0lBQ0QsY0FBYyxDQUFDLDJCQUEyQixDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDaEUsY0FBYyxDQUFDLElBQUksQ0FBQzthQUNULElBQUEsd0JBQWlCLEVBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDO1dBQzNDLGlCQUFpQixDQUFDLElBQUk7V0FDdEIsaUJBQWlCLENBQUMsSUFBSTs7Q0FFaEMsQ0FBQyxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQWdCLHdCQUF3QixDQUN0QyxvQkFBNEIsRUFDNUIsMEJBQXNELEVBQ3RELGtCQUFzQyxFQUN0QyxnQkFBbUQ7SUFFbkQsSUFBSSx3QkFBd0IsR0FB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RUFBRSxDQUFDO1FBQ2pDLFlBQVksR0FBRztxQkFDRSxDQUFDO0lBQ3BCLENBQUM7SUFFRCxJQUFJLHdCQUF3QixHQUFHLElBQUEsd0JBQWlCLEVBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUUscUJBQXFCLENBQUMsb0JBQW9CLENBQ3hDLG9CQUFvQixFQUNwQix3QkFBd0IsQ0FDekIsQ0FBQztJQUNGLHFCQUFxQixDQUFDLG9CQUFvQixDQUN4QyxvQkFBb0IsQ0FBQyxjQUFjLEVBQ25DLG9CQUFvQixDQUFDLFFBQVEsQ0FDOUIsQ0FBQztJQUNGLHFCQUFxQixDQUFDLDJDQUEyQyxDQUMvRCw0QkFBNEIsQ0FDN0IsQ0FBQztJQUNGLHFCQUFxQixDQUFDLElBQUksQ0FBQzt3QkFDTCxvQkFBb0IsQ0FBQyxJQUFJO3dCQUN6Qix3QkFBd0I7OzRCQUVwQixTQUFTLEdBQUcsYUFBYSxHQUFHLFlBQVk7ZUFDckQsb0JBQW9CLENBQUMsUUFBUTs7Q0FFM0MsQ0FBQyxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIFJlbW90ZUNhbGxEZWZpbml0aW9uLFxuICBSZW1vdGVDYWxsc0dyb3VwRGVmaW5pdGlvbixcbiAgU2VydmljZURlZmluaXRpb24sXG59IGZyb20gXCIuL2RlZmluaXRpb25cIjtcbmltcG9ydCB7IERlZmluaXRpb25SZXNvbHZlciB9IGZyb20gXCIuL2RlZmluaXRpb25fcmVzb2x2ZXJcIjtcbmltcG9ydCB7XG4gIE91dHB1dENvbnRlbnRCdWlsZGVyLFxuICBUc0NvbnRlbnRCdWlsZGVyLFxufSBmcm9tIFwiLi9vdXRwdXRfY29udGVudF9idWlsZGVyXCI7XG5pbXBvcnQgeyB0b1VwcGVyY2FzZVNuYWtlZCB9IGZyb20gXCIuL3V0aWxcIjtcblxubGV0IFBSSU1JVElWRV9UWVBFX0JZVEVTID0gXCJieXRlc1wiO1xubGV0IFBSSU1JVElWRV9UWVBFUyA9IG5ldyBTZXQ8c3RyaW5nPihbUFJJTUlUSVZFX1RZUEVfQllURVNdKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlU2VydmljZShcbiAgZGVmaW5pdGlvbk1vZHVsZVBhdGg6IHN0cmluZyxcbiAgc2VydmljZURlZmluaXRpb246IFNlcnZpY2VEZWZpbml0aW9uLFxuICBvdXRwdXRDb250ZW50TWFwOiBNYXA8c3RyaW5nLCBPdXRwdXRDb250ZW50QnVpbGRlcj4sXG4pOiB2b2lkIHtcbiAgbGV0IGNvbnRlbnRCdWlsZGVyID0gVHNDb250ZW50QnVpbGRlci5nZXQoXG4gICAgb3V0cHV0Q29udGVudE1hcCxcbiAgICBkZWZpbml0aW9uTW9kdWxlUGF0aCxcbiAgKTtcbiAgaWYgKCFzZXJ2aWNlRGVmaW5pdGlvbi5uYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBcIm5hbWVcIiBpcyBtaXNzaW5nIG9uIGEgc2VydmljZS5gKTtcbiAgfVxuICBpZiAoIXNlcnZpY2VEZWZpbml0aW9uLnBhdGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFwicGF0aFwiIGlzIG1pc3Npbmcgb24gc2VydmljZSAke3NlcnZpY2VEZWZpbml0aW9uLm5hbWV9LmApO1xuICB9XG4gIGNvbnRlbnRCdWlsZGVyLmltcG9ydEZyb21TZXJ2aWNlRGVzY3JpcHRvcihgU2VydmljZURlc2NyaXB0b3JgKTtcbiAgY29udGVudEJ1aWxkZXIucHVzaChgXG5leHBvcnQgbGV0ICR7dG9VcHBlcmNhc2VTbmFrZWQoc2VydmljZURlZmluaXRpb24ubmFtZSl9OiBTZXJ2aWNlRGVzY3JpcHRvciA9IHtcbiAgbmFtZTogXCIke3NlcnZpY2VEZWZpbml0aW9uLm5hbWV9XCIsXG4gIHBhdGg6IFwiJHtzZXJ2aWNlRGVmaW5pdGlvbi5wYXRofVwiLFxufVxuYCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVJlbW90ZUNhbGxzR3JvdXAoXG4gIGRlZmluaXRpb25Nb2R1bGVQYXRoOiBzdHJpbmcsXG4gIHJlbW90ZUNhbGxzR3JvdXBEZWZpbml0aW9uOiBSZW1vdGVDYWxsc0dyb3VwRGVmaW5pdGlvbixcbiAgZGVmaW5pdGlvblJlc29sdmVyOiBEZWZpbml0aW9uUmVzb2x2ZXIsXG4gIG91dHB1dENvbnRlbnRNYXA6IE1hcDxzdHJpbmcsIE91dHB1dENvbnRlbnRCdWlsZGVyPixcbik6IHZvaWQge1xuICBsZXQgZGVzY3JpcHRvckNvbnRlbnRCdWlsZGVyID0gVHNDb250ZW50QnVpbGRlci5nZXQoXG4gICAgb3V0cHV0Q29udGVudE1hcCxcbiAgICBkZWZpbml0aW9uTW9kdWxlUGF0aCxcbiAgKTtcbiAgaWYgKCFyZW1vdGVDYWxsc0dyb3VwRGVmaW5pdGlvbi5zZXJ2aWNlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFwic2VydmljZVwiIGlzIG1pc3Npbmcgb24gcmVtb3RlIGNhbGxzIGdyb3VwICR7cmVtb3RlQ2FsbHNHcm91cERlZmluaXRpb24ubmFtZX0uYCxcbiAgICApO1xuICB9XG4gIGxldCBkZWZpbml0aW9uID0gZGVmaW5pdGlvblJlc29sdmVyLnJlc29sdmUoXG4gICAgYFdoZW4gbG9va2luZyBmb3Igc2VydmljZSBkZWZpbml0aW9uIGZvciByZW1vdGUgY2FsbHMgZ3JvdXAgJHtyZW1vdGVDYWxsc0dyb3VwRGVmaW5pdGlvbi5uYW1lfSxgLFxuICAgIHJlbW90ZUNhbGxzR3JvdXBEZWZpbml0aW9uLnNlcnZpY2UsXG4gICAgcmVtb3RlQ2FsbHNHcm91cERlZmluaXRpb24uaW1wb3J0U2VydmljZSxcbiAgKTtcbiAgaWYgKGRlZmluaXRpb24ua2luZCAhPT0gXCJTZXJ2aWNlXCIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgU2VydmljZSBuYW1lICR7cmVtb3RlQ2FsbHNHcm91cERlZmluaXRpb24uc2VydmljZX0gb24gcmVtb3RlIGNhbGxzIGdyb3VwICR7cmVtb3RlQ2FsbHNHcm91cERlZmluaXRpb24ubmFtZX0gaXMgbm90IGEgc2VydmljZS5gLFxuICAgICk7XG4gIH1cbiAgbGV0IHNlcnZpY2VOYW1lID0gdG9VcHBlcmNhc2VTbmFrZWQocmVtb3RlQ2FsbHNHcm91cERlZmluaXRpb24uc2VydmljZSk7XG4gIGRlc2NyaXB0b3JDb250ZW50QnVpbGRlci5pbXBvcnRGcm9tRGVmaW5pdGlvbihcbiAgICByZW1vdGVDYWxsc0dyb3VwRGVmaW5pdGlvbi5pbXBvcnRTZXJ2aWNlLFxuICAgIHNlcnZpY2VOYW1lLFxuICApO1xuXG4gIGlmICghcmVtb3RlQ2FsbHNHcm91cERlZmluaXRpb24ub3V0cHV0Q2xpZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFwib3V0cHV0Q2xpZW50XCIgaXMgbWlzc2luZyBvbiByZW1vdGUgY2FsbHMgZ3JvdXAgJHtyZW1vdGVDYWxsc0dyb3VwRGVmaW5pdGlvbi5uYW1lfS5gLFxuICAgICk7XG4gIH1cbiAgbGV0IGNsaWVudENvbnRlbnRCdWlsZGVyID0gVHNDb250ZW50QnVpbGRlci5nZXQoXG4gICAgb3V0cHV0Q29udGVudE1hcCxcbiAgICBkZWZpbml0aW9uTW9kdWxlUGF0aCxcbiAgICByZW1vdGVDYWxsc0dyb3VwRGVmaW5pdGlvbi5vdXRwdXRDbGllbnQsXG4gICk7XG5cbiAgaWYgKCFyZW1vdGVDYWxsc0dyb3VwRGVmaW5pdGlvbi5vdXRwdXRIYW5kbGVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFwib3V0cHV0SGFuZGxlclwiIGlzIG1pc3Npbmcgb24gcmVtb3RlIGNhbGxzIGdyb3VwICR7cmVtb3RlQ2FsbHNHcm91cERlZmluaXRpb24ubmFtZX0uYCxcbiAgICApO1xuICB9XG4gIGxldCBoYW5kbGVyQ29udGVudEJ1aWxkZXIgPSBUc0NvbnRlbnRCdWlsZGVyLmdldChcbiAgICBvdXRwdXRDb250ZW50TWFwLFxuICAgIGRlZmluaXRpb25Nb2R1bGVQYXRoLFxuICAgIHJlbW90ZUNhbGxzR3JvdXBEZWZpbml0aW9uLm91dHB1dEhhbmRsZXIsXG4gICk7XG5cbiAgaWYgKCFyZW1vdGVDYWxsc0dyb3VwRGVmaW5pdGlvbi5jYWxscykge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBcImNhbGxzXCIgaXMgZWl0aGVyIG1pc3Npbmcgb3Igbm90IGFuIGFycmF5IG9uIHJlbW90ZSBjYWxscyBncm91cCAke3JlbW90ZUNhbGxzR3JvdXBEZWZpbml0aW9uLm5hbWV9LmAsXG4gICAgKTtcbiAgfVxuICBmb3IgKGxldCByZW1vdGVDYWxsIG9mIHJlbW90ZUNhbGxzR3JvdXBEZWZpbml0aW9uLmNhbGxzKSB7XG4gICAgZ2VuZXJhdGVSZW1vdGVDYWxsKFxuICAgICAgZGVmaW5pdGlvbk1vZHVsZVBhdGgsXG4gICAgICByZW1vdGVDYWxsLFxuICAgICAgc2VydmljZU5hbWUsXG4gICAgICBkZWZpbml0aW9uUmVzb2x2ZXIsXG4gICAgICBkZXNjcmlwdG9yQ29udGVudEJ1aWxkZXIsXG4gICAgICBjbGllbnRDb250ZW50QnVpbGRlcixcbiAgICAgIGhhbmRsZXJDb250ZW50QnVpbGRlcixcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVJlbW90ZUNhbGwoXG4gIGRlZmluaXRpb25Nb2R1bGVQYXRoOiBzdHJpbmcsXG4gIHJlbW90ZUNhbGxEZWZpbml0aW9uOiBSZW1vdGVDYWxsRGVmaW5pdGlvbixcbiAgc2VydmljZU5hbWU6IHN0cmluZyxcbiAgZGVmaW5pdGlvblJlc29sdmVyOiBEZWZpbml0aW9uUmVzb2x2ZXIsXG4gIGRlc2NyaXB0b3JDb250ZW50QnVpbGRlcjogVHNDb250ZW50QnVpbGRlcixcbiAgY2xpZW50Q29udGVudEJ1aWxkZXI6IFRzQ29udGVudEJ1aWxkZXIsXG4gIGhhbmRsZXJDb250ZW50QnVpbGRlcjogVHNDb250ZW50QnVpbGRlcixcbik6IHZvaWQge1xuICBpZiAoIXJlbW90ZUNhbGxEZWZpbml0aW9uLm5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFwibmFtZVwiIGlzIG1pc3Npbmcgb24gYSBSZW1vdGVDYWxsLmApO1xuICB9XG4gIGxldCBsb2dnaW5nUHJlZml4ID0gYFdoZW4gZ2VuZXJhdGluZyBkZXNjcmlwdG9yIGZvciByZW1vdGUgY2FsbCAke3JlbW90ZUNhbGxEZWZpbml0aW9uLm5hbWV9LGA7XG4gIGxldCBib2R5RGVzY3JpcHRvciA9IFwiXCI7XG4gIGlmICghcmVtb3RlQ2FsbERlZmluaXRpb24uYm9keSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtsb2dnaW5nUHJlZml4fSBcImJvZHlcIiBpcyBtaXNzaW5nLmApO1xuICB9XG4gIGlmIChQUklNSVRJVkVfVFlQRVMuaGFzKHJlbW90ZUNhbGxEZWZpbml0aW9uLmJvZHkpKSB7XG4gICAgZGVzY3JpcHRvckNvbnRlbnRCdWlsZGVyLmltcG9ydEZyb21TZXJ2aWNlRGVzY3JpcHRvcihcIlByaW1pdHZlVHlwZUZvckJvZHlcIik7XG4gICAgYm9keURlc2NyaXB0b3IgPSBgXG4gIGJvZHk6IHtcbiAgICBwcmltaXRpdmVUeXBlOiBQcmltaXR2ZVR5cGVGb3JCb2R5LiR7cmVtb3RlQ2FsbERlZmluaXRpb24uYm9keS50b1VwcGVyQ2FzZSgpfSxcbiAgfSxgO1xuICB9IGVsc2Uge1xuICAgIGxldCByZXF1ZXNCb2R5dERlZmluaXRpb24gPSBkZWZpbml0aW9uUmVzb2x2ZXIucmVzb2x2ZShcbiAgICAgIGxvZ2dpbmdQcmVmaXgsXG4gICAgICByZW1vdGVDYWxsRGVmaW5pdGlvbi5ib2R5LFxuICAgICAgcmVtb3RlQ2FsbERlZmluaXRpb24uaW1wb3J0Qm9keSxcbiAgICApO1xuICAgIGlmIChyZXF1ZXNCb2R5dERlZmluaXRpb24ua2luZCAhPT0gXCJNZXNzYWdlXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYCR7bG9nZ2luZ1ByZWZpeH0gcmVxdWVzdCBib2R5ICR7cmVtb3RlQ2FsbERlZmluaXRpb24uYm9keX0gaXMgbm90IGEgbWVzc2FnZS5gLFxuICAgICAgKTtcbiAgICB9XG4gICAgbGV0IHJlcXVlc3RCb2R5RGVzY3JpcHRvck5hbWUgPSB0b1VwcGVyY2FzZVNuYWtlZChcbiAgICAgIHJlbW90ZUNhbGxEZWZpbml0aW9uLmJvZHksXG4gICAgKTtcbiAgICBkZXNjcmlwdG9yQ29udGVudEJ1aWxkZXIuaW1wb3J0RnJvbURlZmluaXRpb24oXG4gICAgICByZW1vdGVDYWxsRGVmaW5pdGlvbi5pbXBvcnRCb2R5LFxuICAgICAgcmVxdWVzdEJvZHlEZXNjcmlwdG9yTmFtZSxcbiAgICApO1xuICAgIGJvZHlEZXNjcmlwdG9yID0gYFxuICBib2R5OiB7XG4gICAgbWVzc2FnZVR5cGU6ICR7cmVxdWVzdEJvZHlEZXNjcmlwdG9yTmFtZX0sXG4gIH0sYDtcbiAgfVxuXG4gIGxldCBtZXRhZGF0YURlc2NyaXB0b3IgPSBcIlwiO1xuICBpZiAocmVtb3RlQ2FsbERlZmluaXRpb24ubWV0YWRhdGEpIHtcbiAgICBpZiAoIXJlbW90ZUNhbGxEZWZpbml0aW9uLm1ldGFkYXRhLnR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYCR7bG9nZ2luZ1ByZWZpeH0gXCJ0eXBlXCIgaXMgbWlzc2luZyBpbiB0aGUgXCJtZXRhZGF0YVwiIGZpZWxkLmAsXG4gICAgICApO1xuICAgIH1cbiAgICBsZXQgbWV0YWRhdGFEZWZpbml0aW9uID0gZGVmaW5pdGlvblJlc29sdmVyLnJlc29sdmUoXG4gICAgICBsb2dnaW5nUHJlZml4LFxuICAgICAgcmVtb3RlQ2FsbERlZmluaXRpb24ubWV0YWRhdGEudHlwZSxcbiAgICAgIHJlbW90ZUNhbGxEZWZpbml0aW9uLm1ldGFkYXRhLmltcG9ydCxcbiAgICApO1xuICAgIGlmIChtZXRhZGF0YURlZmluaXRpb24ua2luZCAhPT0gXCJNZXNzYWdlXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYCR7bG9nZ2luZ1ByZWZpeH0gbWV0YWRhdGEgdHlwZSAke3JlbW90ZUNhbGxEZWZpbml0aW9uLm1ldGFkYXRhLnR5cGV9IGlzIG5vdCBhIG1lc3NhZ2UuYCxcbiAgICAgICk7XG4gICAgfVxuICAgIGxldCBtZXRhZGF0YURlc2NyaXB0b3JOYW1lID0gdG9VcHBlcmNhc2VTbmFrZWQoXG4gICAgICByZW1vdGVDYWxsRGVmaW5pdGlvbi5tZXRhZGF0YS50eXBlLFxuICAgICk7XG4gICAgZGVzY3JpcHRvckNvbnRlbnRCdWlsZGVyLmltcG9ydEZyb21EZWZpbml0aW9uKFxuICAgICAgcmVtb3RlQ2FsbERlZmluaXRpb24ubWV0YWRhdGEuaW1wb3J0LFxuICAgICAgbWV0YWRhdGFEZXNjcmlwdG9yTmFtZSxcbiAgICApO1xuICAgIGlmICghcmVtb3RlQ2FsbERlZmluaXRpb24ubWV0YWRhdGEua2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGAke2xvZ2dpbmdQcmVmaXh9IFwia2V5XCIgaXMgbWlzc2luZyBpbiB0aGUgXCJtZXRhZGF0YVwiIGZpZWxkLmAsXG4gICAgICApO1xuICAgIH1cbiAgICBtZXRhZGF0YURlc2NyaXB0b3IgPSBgXG4gIG1ldGFkYXRhOiB7XG4gICAga2V5OiBcIiR7cmVtb3RlQ2FsbERlZmluaXRpb24ubWV0YWRhdGEua2V5fVwiLFxuICAgIHR5cGU6ICR7bWV0YWRhdGFEZXNjcmlwdG9yTmFtZX0sXG4gIH0sYDtcbiAgfVxuXG4gIGxldCBhdXRoS2V5ID0gXCJcIjtcbiAgaWYgKHJlbW90ZUNhbGxEZWZpbml0aW9uLmF1dGhLZXkpIHtcbiAgICBhdXRoS2V5ID0gYFxuICBhdXRoS2V5OiBcIiR7cmVtb3RlQ2FsbERlZmluaXRpb24uYXV0aEtleX1cIixgO1xuICB9XG5cbiAgaWYgKCFyZW1vdGVDYWxsRGVmaW5pdGlvbi5yZXNwb25zZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtsb2dnaW5nUHJlZml4fSBcInJlc3BvbnNlXCIgaXMgbWlzc2luZy5gKTtcbiAgfVxuICBsZXQgcmVzcG9uc2VEZWZpbml0aW9uID0gZGVmaW5pdGlvblJlc29sdmVyLnJlc29sdmUoXG4gICAgbG9nZ2luZ1ByZWZpeCxcbiAgICByZW1vdGVDYWxsRGVmaW5pdGlvbi5yZXNwb25zZSxcbiAgICByZW1vdGVDYWxsRGVmaW5pdGlvbi5pbXBvcnRSZXNwb25zZSxcbiAgKTtcbiAgaWYgKHJlc3BvbnNlRGVmaW5pdGlvbi5raW5kICE9PSBcIk1lc3NhZ2VcIikge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGAke2xvZ2dpbmdQcmVmaXh9IHJlc3BvbnNlIHR5cGUgJHtyZW1vdGVDYWxsRGVmaW5pdGlvbi5yZXNwb25zZX0gaXMgbm90IGEgbWVzc2FnZS5gLFxuICAgICk7XG4gIH1cbiAgbGV0IHJlc3BvbnNlRGVzY3JpcHRvck5hbWUgPSB0b1VwcGVyY2FzZVNuYWtlZChyZW1vdGVDYWxsRGVmaW5pdGlvbi5yZXNwb25zZSk7XG4gIGRlc2NyaXB0b3JDb250ZW50QnVpbGRlci5pbXBvcnRGcm9tRGVmaW5pdGlvbihcbiAgICByZW1vdGVDYWxsRGVmaW5pdGlvbi5pbXBvcnRSZXNwb25zZSxcbiAgICByZXNwb25zZURlc2NyaXB0b3JOYW1lLFxuICApO1xuICBsZXQgcmVzcG9uc2VEZXNjcmlwdG9yID0gYFxuICByZXNwb25zZToge1xuICAgIG1lc3NhZ2VUeXBlOiAke3Jlc3BvbnNlRGVzY3JpcHRvck5hbWV9LFxuICB9LGA7XG5cbiAgZGVzY3JpcHRvckNvbnRlbnRCdWlsZGVyLmltcG9ydEZyb21TZXJ2aWNlRGVzY3JpcHRvcihcIlJlbW90ZUNhbGxEZXNjcmlwdG9yXCIpO1xuICBsZXQgcmVtb3RlQ2FsbERlc2NyaXB0b3JOYW1lID0gdG9VcHBlcmNhc2VTbmFrZWQocmVtb3RlQ2FsbERlZmluaXRpb24ubmFtZSk7XG4gIGRlc2NyaXB0b3JDb250ZW50QnVpbGRlci5wdXNoKGBcbmV4cG9ydCBsZXQgJHtyZW1vdGVDYWxsRGVzY3JpcHRvck5hbWV9OiBSZW1vdGVDYWxsRGVzY3JpcHRvciA9IHtcbiAgbmFtZTogXCIke3JlbW90ZUNhbGxEZWZpbml0aW9uLm5hbWV9XCIsXG4gIHNlcnZpY2U6ICR7c2VydmljZU5hbWV9LFxuICBwYXRoOiBcIiR7cmVtb3RlQ2FsbERlZmluaXRpb24ucGF0aH1cIiwke2JvZHlEZXNjcmlwdG9yfSR7bWV0YWRhdGFEZXNjcmlwdG9yfSR7YXV0aEtleX0ke3Jlc3BvbnNlRGVzY3JpcHRvcn1cbn1cbmApO1xuXG4gIGdlbmVyYXRlQ2xpZW50KFxuICAgIGRlZmluaXRpb25Nb2R1bGVQYXRoLFxuICAgIHJlbW90ZUNhbGxEZWZpbml0aW9uLFxuICAgIGNsaWVudENvbnRlbnRCdWlsZGVyLFxuICApO1xuICBnZW5lcmF0ZUhhbmRsZXIoXG4gICAgZGVmaW5pdGlvbk1vZHVsZVBhdGgsXG4gICAgcmVtb3RlQ2FsbERlZmluaXRpb24sXG4gICAgaGFuZGxlckNvbnRlbnRCdWlsZGVyLFxuICApO1xufVxuXG5mdW5jdGlvbiBnZW5lcmF0ZUNsaWVudChcbiAgZGVmaW5pdGlvbk1vZHVsZVBhdGg6IHN0cmluZyxcbiAgcmVtb3RlQ2FsbERlZmluaXRpb246IFJlbW90ZUNhbGxEZWZpbml0aW9uLFxuICBjbGllbnRDb250ZW50QnVpbGRlcjogVHNDb250ZW50QnVpbGRlcixcbik6IHZvaWQge1xuICBsZXQgbG9nZ2luZ1ByZWZpeCA9IGBXaGVuIGdlbmVyYXRpbmcgY2xpZW50IGZvciAke3JlbW90ZUNhbGxEZWZpbml0aW9uLm5hbWV9LGA7XG4gIGxldCBib2R5UGFyYW0gPSBcIlwiO1xuICBpZiAoUFJJTUlUSVZFX1RZUEVTLmhhcyhyZW1vdGVDYWxsRGVmaW5pdGlvbi5ib2R5KSkge1xuICAgIGlmIChyZW1vdGVDYWxsRGVmaW5pdGlvbi5ib2R5ID09PSBQUklNSVRJVkVfVFlQRV9CWVRFUykge1xuICAgICAgYm9keVBhcmFtID0gYFxuICBib2R5OiBCbG9iLGA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYCR7bG9nZ2luZ1ByZWZpeH0gdGhlcmUgaXMgYSBuZXcgcHJpbWl0aXZlIHR5cGUgbmVlZHMgdG8gYmUgaGFuZGxlZCBmb3IgaXRzIHJlcXVlc3QgYm9keS5gLFxuICAgICAgKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgY2xpZW50Q29udGVudEJ1aWxkZXIuaW1wb3J0RnJvbURlZmluaXRpb24oXG4gICAgICByZW1vdGVDYWxsRGVmaW5pdGlvbi5pbXBvcnRCb2R5LFxuICAgICAgcmVtb3RlQ2FsbERlZmluaXRpb24uYm9keSxcbiAgICApO1xuICAgIGJvZHlQYXJhbSA9IGBcbiAgYm9keTogJHtyZW1vdGVDYWxsRGVmaW5pdGlvbi5ib2R5fSxgO1xuICB9XG5cbiAgbGV0IG1ldGFkYXRhUGFyYW0gPSBcIlwiO1xuICBsZXQgbWV0ZGF0YVZhcmlhYmxlID0gXCJcIjtcbiAgaWYgKHJlbW90ZUNhbGxEZWZpbml0aW9uLm1ldGFkYXRhKSB7XG4gICAgY2xpZW50Q29udGVudEJ1aWxkZXIuaW1wb3J0RnJvbURlZmluaXRpb24oXG4gICAgICByZW1vdGVDYWxsRGVmaW5pdGlvbi5tZXRhZGF0YS5pbXBvcnQsXG4gICAgICByZW1vdGVDYWxsRGVmaW5pdGlvbi5tZXRhZGF0YS50eXBlLFxuICAgICk7XG4gICAgbWV0YWRhdGFQYXJhbSA9IGBcbiAgbWV0YWRhdGE6ICR7cmVtb3RlQ2FsbERlZmluaXRpb24ubWV0YWRhdGEudHlwZX0sYDtcbiAgICBtZXRkYXRhVmFyaWFibGUgPSBgXG4gICAgICBtZXRhZGF0YSxgO1xuICB9XG5cbiAgY2xpZW50Q29udGVudEJ1aWxkZXIuaW1wb3J0RnJvbURlZmluaXRpb24oXG4gICAgcmVtb3RlQ2FsbERlZmluaXRpb24uaW1wb3J0UmVzcG9uc2UsXG4gICAgcmVtb3RlQ2FsbERlZmluaXRpb24ucmVzcG9uc2UsXG4gICk7XG4gIGxldCByZW1vdGVDYWxsRGVzY3JpcHRvck5hbWUgPSB0b1VwcGVyY2FzZVNuYWtlZChyZW1vdGVDYWxsRGVmaW5pdGlvbi5uYW1lKTtcbiAgY2xpZW50Q29udGVudEJ1aWxkZXIuaW1wb3J0RnJvbURlZmluaXRpb24oXG4gICAgZGVmaW5pdGlvbk1vZHVsZVBhdGgsXG4gICAgcmVtb3RlQ2FsbERlc2NyaXB0b3JOYW1lLFxuICApO1xuICBjbGllbnRDb250ZW50QnVpbGRlci5pbXBvcnRGcm9tU2VydmljZUNsaWVudFJlcXVlc3RJbnRlcmZhY2UoXG4gICAgXCJDbGllbnRSZXF1ZXN0SW50ZXJmYWNlXCIsXG4gICk7XG4gIGNsaWVudENvbnRlbnRCdWlsZGVyLnB1c2goYFxuZXhwb3J0IGZ1bmN0aW9uIG5ldyR7cmVtb3RlQ2FsbERlZmluaXRpb24ubmFtZX1SZXF1ZXN0KCR7Ym9keVBhcmFtfSR7bWV0YWRhdGFQYXJhbX1cbik6IENsaWVudFJlcXVlc3RJbnRlcmZhY2U8JHtyZW1vdGVDYWxsRGVmaW5pdGlvbi5yZXNwb25zZX0+IHtcbiAgcmV0dXJuIHtcbiAgICBkZXNjcmlwdG9yOiAke3JlbW90ZUNhbGxEZXNjcmlwdG9yTmFtZX0sXG4gICAgYm9keSwke21ldGRhdGFWYXJpYWJsZX1cbiAgfTtcbn1cbmApO1xufVxuXG5mdW5jdGlvbiBnZW5lcmF0ZUhhbmRsZXIoXG4gIGRlZmluaXRpb25Nb2R1bGVQYXRoOiBzdHJpbmcsXG4gIHJlbW90ZUNhbGxEZWZpbml0aW9uOiBSZW1vdGVDYWxsRGVmaW5pdGlvbixcbiAgaGFuZGxlckNvbnRlbnRCdWlsZGVyOiBUc0NvbnRlbnRCdWlsZGVyLFxuKTogdm9pZCB7XG4gIGxldCBsb2dnaW5nUHJlZml4ID0gYFdoZW4gZ2VuZXJhdGluZyBoYW5kbGVyIGZvciAke3JlbW90ZUNhbGxEZWZpbml0aW9uLm5hbWV9LGA7XG4gIGxldCBib2R5UGFyYW0gPSBcIlwiO1xuICBpZiAoUFJJTUlUSVZFX1RZUEVTLmhhcyhyZW1vdGVDYWxsRGVmaW5pdGlvbi5ib2R5KSkge1xuICAgIGlmIChyZW1vdGVDYWxsRGVmaW5pdGlvbi5ib2R5ID09PSBQUklNSVRJVkVfVFlQRV9CWVRFUykge1xuICAgICAgaGFuZGxlckNvbnRlbnRCdWlsZGVyLmltcG9ydEZyb21TdHJlYW0oXCJSZWFkYWJsZVwiKTtcbiAgICAgIGJvZHlQYXJhbSA9IGBcbiAgICBib2R5OiBSZWFkYWJsZSxgO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGAke2xvZ2dpbmdQcmVmaXh9IHRoZXJlIGlzIGEgbmV3IHByaW1pdGl2ZSB0eXBlIG5lZWRzIHRvIGJlIGhhbmRsZWQgZm9yIGl0cyByZXF1ZXN0IGJvZHkuYCxcbiAgICAgICk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGhhbmRsZXJDb250ZW50QnVpbGRlci5pbXBvcnRGcm9tRGVmaW5pdGlvbihcbiAgICAgIHJlbW90ZUNhbGxEZWZpbml0aW9uLmltcG9ydEJvZHksXG4gICAgICByZW1vdGVDYWxsRGVmaW5pdGlvbi5ib2R5LFxuICAgICk7XG4gICAgYm9keVBhcmFtID0gYFxuICAgIGJvZHk6ICR7cmVtb3RlQ2FsbERlZmluaXRpb24uYm9keX0sYDtcbiAgfVxuXG4gIGxldCBtZXRhZGF0YVBhcmFtID0gXCJcIjtcbiAgaWYgKHJlbW90ZUNhbGxEZWZpbml0aW9uLm1ldGFkYXRhKSB7XG4gICAgaGFuZGxlckNvbnRlbnRCdWlsZGVyLmltcG9ydEZyb21EZWZpbml0aW9uKFxuICAgICAgcmVtb3RlQ2FsbERlZmluaXRpb24ubWV0YWRhdGEuaW1wb3J0LFxuICAgICAgcmVtb3RlQ2FsbERlZmluaXRpb24ubWV0YWRhdGEudHlwZSxcbiAgICApO1xuICAgIG1ldGFkYXRhUGFyYW0gPSBgXG4gICAgbWV0YWRhdGE6ICR7cmVtb3RlQ2FsbERlZmluaXRpb24ubWV0YWRhdGEudHlwZX0sYDtcbiAgfVxuXG4gIGxldCBhdXRoU3RyUGFyYW0gPSBcIlwiO1xuICBpZiAocmVtb3RlQ2FsbERlZmluaXRpb24uYXV0aEtleSkge1xuICAgIGF1dGhTdHJQYXJhbSA9IGBcbiAgICBhdXRoU3RyOiBzdHJpbmcsYDtcbiAgfVxuXG4gIGxldCByZW1vdGVDYWxsRGVzY3JpcHRvck5hbWUgPSB0b1VwcGVyY2FzZVNuYWtlZChyZW1vdGVDYWxsRGVmaW5pdGlvbi5uYW1lKTtcbiAgaGFuZGxlckNvbnRlbnRCdWlsZGVyLmltcG9ydEZyb21EZWZpbml0aW9uKFxuICAgIGRlZmluaXRpb25Nb2R1bGVQYXRoLFxuICAgIHJlbW90ZUNhbGxEZXNjcmlwdG9yTmFtZSxcbiAgKTtcbiAgaGFuZGxlckNvbnRlbnRCdWlsZGVyLmltcG9ydEZyb21EZWZpbml0aW9uKFxuICAgIHJlbW90ZUNhbGxEZWZpbml0aW9uLmltcG9ydFJlc3BvbnNlLFxuICAgIHJlbW90ZUNhbGxEZWZpbml0aW9uLnJlc3BvbnNlLFxuICApO1xuICBoYW5kbGVyQ29udGVudEJ1aWxkZXIuaW1wb3J0RnJvbVNlcnZpY2VSZW1vdGVDYWxsSGFuZGxlckludGVyZmFjZShcbiAgICBcIlJlbW90ZUNhbGxIYW5kbGVySW50ZXJmYWNlXCIsXG4gICk7XG4gIGhhbmRsZXJDb250ZW50QnVpbGRlci5wdXNoKGBcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyAke3JlbW90ZUNhbGxEZWZpbml0aW9uLm5hbWV9SGFuZGxlckludGVyZmFjZSBpbXBsZW1lbnRzIFJlbW90ZUNhbGxIYW5kbGVySW50ZXJmYWNlIHtcbiAgcHVibGljIGRlc2NyaXB0b3IgPSAke3JlbW90ZUNhbGxEZXNjcmlwdG9yTmFtZX07XG4gIHB1YmxpYyBhYnN0cmFjdCBoYW5kbGUoXG4gICAgbG9nZ2luZ1ByZWZpeDogc3RyaW5nLCR7Ym9keVBhcmFtfSR7bWV0YWRhdGFQYXJhbX0ke2F1dGhTdHJQYXJhbX1cbiAgKTogUHJvbWlzZTwke3JlbW90ZUNhbGxEZWZpbml0aW9uLnJlc3BvbnNlfT47XG59XG5gKTtcbn1cbiJdfQ==