UNPKG

@selfage/generator_cli

Version:

Code generation for message, service, and database.

212 lines 37 kB
"use strict"; 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==