UNPKG

cdk8s-cli

Version:

This is the command line tool for Cloud Development Kit (CDK) for Kubernetes (cdk8s).

143 lines • 19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.findApiObjectDefinitions = exports.ImportKubernetesApi = exports.DEFAULT_API_VERSION = void 0; const json2jsii_1 = require("json2jsii"); const base_1 = require("./base"); const codegen_1 = require("./codegen"); const k8s_util_1 = require("./k8s-util"); const util_1 = require("../util"); exports.DEFAULT_API_VERSION = '1.25.0'; const DEFAULT_CLASS_NAME_PREFIX = 'Kube'; class ImportKubernetesApi extends base_1.ImportBase { static async match(importSpec, argv) { var _a; const { source } = importSpec; if (source !== 'k8s' && !source.startsWith('k8s@')) { return undefined; } let k8sVersion = (_a = source.split('@')[1]) !== null && _a !== void 0 ? _a : exports.DEFAULT_API_VERSION; const k8sVersionRegex = /^\d+\.\d+\.\d+$/; if (!k8sVersionRegex.test(k8sVersion)) { throw new Error(`Expected k8s version "${k8sVersion}" to match format "<major>.<minor>.<patch>".`); } console.error(`Importing k8s v${k8sVersion}...`); return { apiVersion: k8sVersion, exclude: argv.exclude, }; } constructor(options) { super(); this.options = options; } get moduleNames() { return ['k8s']; } async generateTypeScript(code, moduleName, options) { var _a; const schema = await downloadSchema(this.options.apiVersion); if (moduleName !== 'k8s') { throw new Error(`unexpected module name "${moduleName}" when importing k8s types (expected "k8s")`); } const prefix = (_a = options.classNamePrefix) !== null && _a !== void 0 ? _a : DEFAULT_CLASS_NAME_PREFIX; const topLevelObjects = findApiObjectDefinitions(schema, prefix); const typeGenerator = new json2jsii_1.TypeGenerator({ definitions: schema.definitions, exclude: this.options.exclude, renderTypeName: (def) => { const parsed = (0, k8s_util_1.parseApiTypeName)(def); if (!parsed.version) { // not a versioned api type. return basename return parsed.basename; } return (0, codegen_1.getTypeName)(false, parsed.basename, parsed.version.raw); }, }); // rename "Props" type from their original name based on the API object kind // (e.g. `Deployment`) to their actual props type (`KubeDeploymentProps`) in // order to avoid confusion between constructs (`KubeDeployment`) and those // types. This is done by simply replacing their definition in the schema // with a $ref to the definition of the props type. for (const o of topLevelObjects) { typeGenerator.addDefinition(o.fqn, { $ref: `#/definitions/${(0, codegen_1.getPropsTypeName)(o)}` }); } // emit construct types (recursive) for (const o of topLevelObjects) { (0, codegen_1.generateConstruct)(typeGenerator, o); } (0, codegen_1.emitHeader)(code, false); code.line(typeGenerator.render()); } } exports.ImportKubernetesApi = ImportKubernetesApi; /** * Returns a map of all API objects in the spec (objects that have the * 'x-kubernetes-group-version-kind' annotation). * * The key is the base name of the type (i.e. `Deployment`). Since API objects * may have multiple versions, each value in the map is an array of type definitions * along with version information. * * @see https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-versioning */ function findApiObjectDefinitions(schema, prefix) { const result = new Array(); for (const [typename, apischema] of Object.entries(schema.definitions || {})) { const objectName = tryGetObjectName(apischema); if (!objectName) { continue; } const type = (0, k8s_util_1.parseApiTypeName)(typename); if (!type.version) { throw new Error(`Unable to parse version for type: ${typename}`); } result.push({ custom: false, fqn: type.fullname, group: objectName.group, kind: objectName.kind, version: objectName.version, schema: apischema, prefix, }); } return result; } exports.findApiObjectDefinitions = findApiObjectDefinitions; function tryGetObjectName(def) { var _a; const objectNames = def[X_GROUP_VERSION_KIND]; if (!objectNames) { return undefined; } const objectName = objectNames[0]; if (!objectName) { return undefined; } // skip definitions without "metadata". they are not API objects that can be defined // in manifests (example: io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions) // they will be treated as data types if (!((_a = def.properties) === null || _a === void 0 ? void 0 : _a.metadata)) { return undefined; } return objectName; } const X_GROUP_VERSION_KIND = 'x-kubernetes-group-version-kind'; async function downloadSchema(apiVersion) { const url = `https://raw.githubusercontent.com/cdk8s-team/cdk8s/master/kubernetes-schemas/v${apiVersion}/_definitions.json`; let output; try { output = await (0, util_1.download)(url); } catch (e) { console.error(`Could not find a schema for k8s version ${apiVersion}. The current list of available schemas is at https://github.com/cdk8s-team/cdk8s/tree/master/kubernetes-schemas.`); throw e; } try { return (0, k8s_util_1.safeParseJsonSchema)(output); } catch (e) { throw new Error(`Unable to parse schema at ${url}: ${e}`); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiazhzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ltcG9ydC9rOHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBTUEseUNBQTBDO0FBQzFDLGlDQUFxRDtBQUNyRCx1Q0FBOEc7QUFDOUcseUNBQW1FO0FBRW5FLGtDQUFtQztBQUd0QixRQUFBLG1CQUFtQixHQUFHLFFBQVEsQ0FBQztBQUU1QyxNQUFNLHlCQUF5QixHQUFHLE1BQU0sQ0FBQztBQWdCekMsTUFBYSxtQkFBb0IsU0FBUSxpQkFBVTtJQUUxQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxVQUFzQixFQUFFLElBQVM7O1FBQ3pELE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxVQUFVLENBQUM7UUFDOUIsSUFBSSxNQUFNLEtBQUssS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNsRCxPQUFPLFNBQVMsQ0FBQztTQUNsQjtRQUVELElBQUksVUFBVSxHQUFHLE1BQUEsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsbUNBQUksMkJBQW1CLENBQUM7UUFFN0QsTUFBTSxlQUFlLEdBQUcsaUJBQWlCLENBQUM7UUFDMUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDckMsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsVUFBVSw4Q0FBOEMsQ0FBQyxDQUFDO1NBQ3BHO1FBRUQsT0FBTyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsVUFBVSxLQUFLLENBQUMsQ0FBQztRQUVqRCxPQUFPO1lBQ0wsVUFBVSxFQUFFLFVBQVU7WUFDdEIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1NBQ3RCLENBQUM7SUFDSixDQUFDO0lBRUQsWUFBNkIsT0FBbUM7UUFDOUQsS0FBSyxFQUFFLENBQUM7UUFEbUIsWUFBTyxHQUFQLE9BQU8sQ0FBNEI7SUFFaEUs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SUFBQyxPQUFPLENBQUMsRUFBRTtRQUNWLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0tBQzNEO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvZGVNYWtlciB9IGZyb20gJ2NvZGVtYWtlcic7XG5cbi8vIHdlIGp1c3QgbmVlZCB0aGUgdHlwZXMgZnJvbSBqc29uLXNjaGVtYVxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llc1xuaW1wb3J0IHsgSlNPTlNjaGVtYTQgfSBmcm9tICdqc29uLXNjaGVtYSc7XG5cbmltcG9ydCB7IFR5cGVHZW5lcmF0b3IgfSBmcm9tICdqc29uMmpzaWknO1xuaW1wb3J0IHsgR2VuZXJhdGVPcHRpb25zLCBJbXBvcnRCYXNlIH0gZnJvbSAnLi9iYXNlJztcbmltcG9ydCB7IEFwaU9iamVjdERlZmluaXRpb24sIGVtaXRIZWFkZXIsIGdlbmVyYXRlQ29uc3RydWN0LCBnZXRQcm9wc1R5cGVOYW1lLCBnZXRUeXBlTmFtZSB9IGZyb20gJy4vY29kZWdlbic7XG5pbXBvcnQgeyBwYXJzZUFwaVR5cGVOYW1lLCBzYWZlUGFyc2VKc29uU2NoZW1hIH0gZnJvbSAnLi9rOHMtdXRpbCc7XG5pbXBvcnQgeyBJbXBvcnRTcGVjIH0gZnJvbSAnLi4vY29uZmlnJztcbmltcG9ydCB7IGRvd25sb2FkIH0gZnJvbSAnLi4vdXRpbCc7XG5cblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfQVBJX1ZFUlNJT04gPSAnMS4yNS4wJztcblxuY29uc3QgREVGQVVMVF9DTEFTU19OQU1FX1BSRUZJWCA9ICdLdWJlJztcblxuZXhwb3J0IGludGVyZmFjZSBJbXBvcnRLdWJlcm5ldGVzQXBpT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgQVBJIHZlcnNpb24gdG8gZ2VuZXJhdGUuXG4gICAqL1xuICByZWFkb25seSBhcGlWZXJzaW9uOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIERvIG5vdCBpbXBvcnQgdGhlc2UgdHlwZXMuIEluc3RlYWQsIHJlcHJlc2VudCB0aGVtIGFzIFwiYW55XCIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gaW5jbHVkZSBhbGwgdHlwZXMgdGhhdCBkZXJpdmUgZnJvbSB0aGUgcm9vdCB0eXBlcy5cbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGU/OiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGNsYXNzIEltcG9ydEt1YmVybmV0ZXNBcGkgZXh0ZW5kcyBJbXBvcnRCYXNlIHtcblxuICBwdWJsaWMgc3RhdGljIGFzeW5jIG1hdGNoKGltcG9ydFNwZWM6IEltcG9ydFNwZWMsIGFyZ3Y6IGFueSk6IFByb21pc2U8SW1wb3J0S3ViZXJuZXRlc0FwaU9wdGlvbnMgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCB7IHNvdXJjZSB9ID0gaW1wb3J0U3BlYztcbiAgICBpZiAoc291cmNlICE9PSAnazhzJyAmJiAhc291cmNlLnN0YXJ0c1dpdGgoJ2s4c0AnKSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBsZXQgazhzVmVyc2lvbiA9IHNvdXJjZS5zcGxpdCgnQCcpWzFdID8/IERFRkFVTFRfQVBJX1ZFUlNJT047XG5cbiAgICBjb25zdCBrOHNWZXJzaW9uUmVnZXggPSAvXlxcZCtcXC5cXGQrXFwuXFxkKyQvO1xuICAgIGlmICghazhzVmVyc2lvblJlZ2V4LnRlc3QoazhzVmVyc2lvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgazhzIHZlcnNpb24gXCIke2s4c1ZlcnNpb259XCIgdG8gbWF0Y2ggZm9ybWF0IFwiPG1ham9yPi48bWlub3I+LjxwYXRjaD5cIi5gKTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmVycm9yKGBJbXBvcnRpbmcgazhzIHYke2s4c1ZlcnNpb259Li4uYCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgYXBpVmVyc2lvbjogazhzVmVyc2lvbixcbiAgICAgIGV4Y2x1ZGU6IGFyZ3YuZXhjbHVkZSxcbiAgICB9O1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBvcHRpb25zOiBJbXBvcnRLdWJlcm5ldGVzQXBpT3B0aW9ucykge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IG1vZHVsZU5hbWVzKCkge1xuICAgIHJldHVybiBbJ2s4cyddO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdlbmVyYXRlVHlwZVNjcmlwdChjb2RlOiBDb2RlTWFrZXIsIG1vZHVsZU5hbWU6IHN0cmluZywgb3B0aW9uczogR2VuZXJhdGVPcHRpb25zKSB7XG4gICAgY29uc3Qgc2NoZW1hID0gYXdhaXQgZG93bmxvYWRTY2hlbWEodGhpcy5vcHRpb25zLmFwaVZlcnNpb24pO1xuXG4gICAgaWYgKG1vZHVsZU5hbWUgIT09ICdrOHMnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuZXhwZWN0ZWQgbW9kdWxlIG5hbWUgXCIke21vZHVsZU5hbWV9XCIgd2hlbiBpbXBvcnRpbmcgazhzIHR5cGVzIChleHBlY3RlZCBcIms4c1wiKWApO1xuICAgIH1cblxuICAgIGNvbnN0IHByZWZpeCA9IG9wdGlvbnMuY2xhc3NOYW1lUHJlZml4ID8/IERFRkFVTFRfQ0xBU1NfTkFNRV9QUkVGSVg7XG4gICAgY29uc3QgdG9wTGV2ZWxPYmplY3RzID0gZmluZEFwaU9iamVjdERlZmluaXRpb25zKHNjaGVtYSwgcHJlZml4KTtcblxuICAgIGNvbnN0IHR5cGVHZW5lcmF0b3IgPSBuZXcgVHlwZUdlbmVyYXRvcih7XG4gICAgICBkZWZpbml0aW9uczogc2NoZW1hLmRlZmluaXRpb25zLFxuICAgICAgZXhjbHVkZTogdGhpcy5vcHRpb25zLmV4Y2x1ZGUsXG4gICAgICByZW5kZXJUeXBlTmFtZTogKGRlZjogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlQXBpVHlwZU5hbWUoZGVmKTtcbiAgICAgICAgaWYgKCFwYXJzZWQudmVyc2lvbikge1xuICAgICAgICAgIC8vIG5vdCBhIHZlcnNpb25lZCBhcGkgdHlwZS4gcmV0dXJuIGJhc2VuYW1lXG4gICAgICAgICAgcmV0dXJuIHBhcnNlZC5iYXNlbmFtZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZ2V0VHlwZU5hbWUoZmFsc2UsIHBhcnNlZC5iYXNlbmFtZSwgcGFyc2VkLnZlcnNpb24ucmF3KTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyByZW5hbWUgXCJQcm9wc1wiIHR5cGUgZnJvbSB0aGVpciBvcmlnaW5hbCBuYW1lIGJhc2VkIG9uIHRoZSBBUEkgb2JqZWN0IGtpbmRcbiAgICAvLyAoZS5nLiBgRGVwbG95bWVudGApIHRvIHRoZWlyIGFjdHVhbCBwcm9wcyB0eXBlIChgS3ViZURlcGxveW1lbnRQcm9wc2ApIGluXG4gICAgLy8gb3JkZXIgdG8gYXZvaWQgY29uZnVzaW9uIGJldHdlZW4gY29uc3RydWN0cyAoYEt1YmVEZXBsb3ltZW50YCkgYW5kIHRob3NlXG4gICAgLy8gdHlwZXMuIFRoaXMgaXMgZG9uZSBieSBzaW1wbHkgcmVwbGFjaW5nIHRoZWlyIGRlZmluaXRpb24gaW4gdGhlIHNjaGVtYVxuICAgIC8vIHdpdGggYSAkcmVmIHRvIHRoZSBkZWZpbml0aW9uIG9mIHRoZSBwcm9wcyB0eXBlLlxuICAgIGZvciAoY29uc3QgbyBvZiB0b3BMZXZlbE9iamVjdHMpIHtcbiAgICAgIHR5cGVHZW5lcmF0b3IuYWRkRGVmaW5pdGlvbihvLmZxbiwgeyAkcmVmOiBgIy9kZWZpbml0aW9ucy8ke2dldFByb3BzVHlwZU5hbWUobyl9YCB9KTtcbiAgICB9XG5cbiAgICAvLyBlbWl0IGNvbnN0cnVjdCB0eXBlcyAocmVjdXJzaXZlKVxuICAgIGZvciAoY29uc3QgbyBvZiB0b3BMZXZlbE9iamVjdHMpIHtcbiAgICAgIGdlbmVyYXRlQ29uc3RydWN0KHR5cGVHZW5lcmF0b3IsIG8pO1xuICAgIH1cblxuICAgIGVtaXRIZWFkZXIoY29kZSwgZmFsc2UpO1xuXG4gICAgY29kZS5saW5lKHR5cGVHZW5lcmF0b3IucmVuZGVyKCkpO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBhIG1hcCBvZiBhbGwgQVBJIG9iamVjdHMgaW4gdGhlIHNwZWMgKG9iamVjdHMgdGhhdCBoYXZlIHRoZVxuICogJ3gta3ViZXJuZXRlcy1ncm91cC12ZXJzaW9uLWtpbmQnIGFubm90YXRpb24pLlxuICpcbiAqIFRoZSBrZXkgaXMgdGhlIGJhc2UgbmFtZSBvZiB0aGUgdHlwZSAoaS5lLiBgRGVwbG95bWVudGApLiBTaW5jZSBBUEkgb2JqZWN0c1xuICogbWF5IGhhdmUgbXVsdGlwbGUgdmVyc2lvbnMsIGVhY2ggdmFsdWUgaW4gdGhlIG1hcCBpcyBhbiBhcnJheSBvZiB0eXBlIGRlZmluaXRpb25zXG4gKiBhbG9uZyB3aXRoIHZlcnNpb24gaW5mb3JtYXRpb24uXG4gKlxuICogQHNlZSBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9jb25jZXB0cy9vdmVydmlldy9rdWJlcm5ldGVzLWFwaS8jYXBpLXZlcnNpb25pbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRBcGlPYmplY3REZWZpbml0aW9ucyhzY2hlbWE6IEpTT05TY2hlbWE0LCBwcmVmaXg6IHN0cmluZyk6IEFwaU9iamVjdERlZmluaXRpb25bXSB7XG4gIGNvbnN0IHJlc3VsdCA9IG5ldyBBcnJheTxBcGlPYmplY3REZWZpbml0aW9uPigpO1xuXG4gIGZvciAoY29uc3QgW3R5cGVuYW1lLCBhcGlzY2hlbWFdIG9mIE9iamVjdC5lbnRyaWVzKHNjaGVtYS5kZWZpbml0aW9ucyB8fCB7IH0pKSB7XG4gICAgY29uc3Qgb2JqZWN0TmFtZSA9IHRyeUdldE9iamVjdE5hbWUoYXBpc2NoZW1hKTtcbiAgICBpZiAoIW9iamVjdE5hbWUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHR5cGUgPSBwYXJzZUFwaVR5cGVOYW1lKHR5cGVuYW1lKTtcbiAgICBpZiAoIXR5cGUudmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gcGFyc2UgdmVyc2lvbiBmb3IgdHlwZTogJHt0eXBlbmFtZX1gKTtcbiAgICB9XG4gICAgcmVzdWx0LnB1c2goe1xuICAgICAgY3VzdG9tOiBmYWxzZSwgLy8gbm90IGEgQ1JEXG4gICAgICBmcW46IHR5cGUuZnVsbG5hbWUsXG4gICAgICBncm91cDogb2JqZWN0TmFtZS5ncm91cCxcbiAgICAgIGtpbmQ6IG9iamVjdE5hbWUua2luZCxcbiAgICAgIHZlcnNpb246IG9iamVjdE5hbWUudmVyc2lvbixcbiAgICAgIHNjaGVtYTogYXBpc2NoZW1hLFxuICAgICAgcHJlZml4LFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gdHJ5R2V0T2JqZWN0TmFtZShkZWY6IEpTT05TY2hlbWE0KTogR3JvdXBWZXJzaW9uS2luZCB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IG9iamVjdE5hbWVzID0gZGVmW1hfR1JPVVBfVkVSU0lPTl9LSU5EXSBhcyBHcm91cFZlcnNpb25LaW5kW107XG4gIGlmICghb2JqZWN0TmFtZXMpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3Qgb2JqZWN0TmFtZSA9IG9iamVjdE5hbWVzWzBdO1xuICBpZiAoIW9iamVjdE5hbWUpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gc2tpcCBkZWZpbml0aW9ucyB3aXRob3V0IFwibWV0YWRhdGFcIi4gdGhleSBhcmUgbm90IEFQSSBvYmplY3RzIHRoYXQgY2FuIGJlIGRlZmluZWRcbiAgLy8gaW4gbWFuaWZlc3RzIChleGFtcGxlOiBpby5rOHMuYXBpbWFjaGluZXJ5LnBrZy5hcGlzLm1ldGEudjEuRGVsZXRlT3B0aW9ucylcbiAgLy8gdGhleSB3aWxsIGJlIHRyZWF0ZWQgYXMgZGF0YSB0eXBlc1xuICBpZiAoIWRlZi5wcm9wZXJ0aWVzPy5tZXRhZGF0YSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICByZXR1cm4gb2JqZWN0TmFtZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHcm91cFZlcnNpb25LaW5kIHtcbiAgcmVhZG9ubHkgZ3JvdXA6IHN0cmluZztcbiAgcmVhZG9ubHkga2luZDogc3RyaW5nO1xuICByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG59XG5cbmNvbnN0IFhfR1JPVVBfVkVSU0lPTl9LSU5EID0gJ3gta3ViZXJuZXRlcy1ncm91cC12ZXJzaW9uLWtpbmQnO1xuXG5hc3luYyBmdW5jdGlvbiBkb3dubG9hZFNjaGVtYShhcGlWZXJzaW9uOiBzdHJpbmcpIHtcbiAgY29uc3QgdXJsID0gYGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9jZGs4cy10ZWFtL2NkazhzL21hc3Rlci9rdWJlcm5ldGVzLXNjaGVtYXMvdiR7YXBpVmVyc2lvbn0vX2RlZmluaXRpb25zLmpzb25gO1xuICBsZXQgb3V0cHV0O1xuICB0cnkge1xuICAgIG91dHB1dCA9IGF3YWl0IGRvd25sb2FkKHVybCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKGBDb3VsZCBub3QgZmluZCBhIHNjaGVtYSBmb3IgazhzIHZlcnNpb24gJHthcGlWZXJzaW9ufS4gVGhlIGN1cnJlbnQgbGlzdCBvZiBhdmFpbGFibGUgc2NoZW1hcyBpcyBhdCBodHRwczovL2dpdGh1Yi5jb20vY2RrOHMtdGVhbS9jZGs4cy90cmVlL21hc3Rlci9rdWJlcm5ldGVzLXNjaGVtYXMuYCk7XG4gICAgdGhyb3cgZTtcbiAgfVxuICB0cnkge1xuICAgIHJldHVybiBzYWZlUGFyc2VKc29uU2NoZW1hKG91dHB1dCkgYXMgSlNPTlNjaGVtYTQ7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBwYXJzZSBzY2hlbWEgYXQgJHt1cmx9OiAke2V9YCk7XG4gIH1cbn1cbiJdfQ==