UNPKG

aws-cdk-neuronx-patterns

Version:
97 lines 19.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SageMakerInferenceToolkitTnxCompiler = exports.SageMakerInferenceToolkitTnxCompileImage = void 0; const deploy_time_build_1 = require("@cdklabs/deploy-time-build"); const constructs_1 = require("constructs"); const path_1 = require("path"); const neuronx_1 = require("../base/neuronx"); const neuronx_compiler_1 = require("../base/neuronx-compiler"); /** * Compile image for SageMakerInferenceToolkitTnxCompile. * @example * new SageMakerInferenceToolkitTnxCompileImage(scope, 'CompileImage', PytorchTrainingNeuronxImage.LATEST); */ class SageMakerInferenceToolkitTnxCompileImage { constructor(scope, id, neruonxImage) { const build = new deploy_time_build_1.ContainerImageBuild(scope, id, { directory: (0, path_1.join)(__dirname, "../../scripts/compile/sagemaker-inference-toolkit-tnx"), buildArgs: { IMAGE_NAME: neruonxImage.imageName, IMAGE_TAG: neruonxImage.imageTag, }, }); this.image = build.toEcsDockerImageCode(); this.neuronSdkVersion = neruonxImage.neuronSdkVersion; } } exports.SageMakerInferenceToolkitTnxCompileImage = SageMakerInferenceToolkitTnxCompileImage; /** * Neuronx compile construct. Compile the model to work with Inferentia2 and Trainium1 and upload it to an S3 bucket. */ class SageMakerInferenceToolkitTnxCompiler extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); const optLevel = props.compileOptions?.optLevel ?? neuronx_1.OptLevel.BEST_BALANCE; const batchSize = props.compileOptions?.batchSize ?? 1; const nPositions = props.compileOptions?.nPositions ?? 4096; const quantDtype = props.compileOptions?.quantDtype; const memoryFootprint = props.model.options.config ? (0, neuronx_1.calcMemoryFootprint)(props.model.options.config.embeddingDimension, props.model.options.config.layers, neuronx_1.DataTypeBits.BF16_OR_FP16, nPositions, batchSize) : (0, neuronx_1.inferMemoryFootprintFromParameters)(props.model.options.parameters, nPositions, batchSize); const neuronxInstanceTypes = props.neuronxInstanceType ? [props.neuronxInstanceType] : [ neuronx_1.NeuronxInstanceType.INF2_8XLARGE, neuronx_1.NeuronxInstanceType.INF2_24XLARGE, neuronx_1.NeuronxInstanceType.INF2_48XLARGE, ]; const availableInstancePatterns = neuronxInstanceTypes .flatMap((neuronxInstanceType) => (0, neuronx_1.calcTensorParallel)(neuronxInstanceType, memoryFootprint, props.model.options.config?.attentionHeads).map((v) => ({ neuronxInstanceType, ...v, }))) .filter((pattern) => !props.compileOptions?.tpDegree || pattern.tp === props.compileOptions.tpDegree); if (availableInstancePatterns.length === 0) { throw new Error(`No available instance type. You can use tpDegree are ${availableInstancePatterns.map((p) => p.tp).join(", ")}.`); } const tpDegree = availableInstancePatterns[0].tp; const image = props.image ?? new SageMakerInferenceToolkitTnxCompileImage(this, "CompileImage", neuronx_1.PytorchTrainingNeuronxImage.LATEST); let compiledArtifactPathPrefix = `${props.model.modelId}/neuronx-${image.neuronSdkVersion}/tp${tpDegree}-np${nPositions}-opt${optLevel}`; if (quantDtype) { compiledArtifactPathPrefix = `${compiledArtifactPathPrefix}-quant${quantDtype}`; } const compiler = new neuronx_compiler_1.NeuronxNativeCompiler(this, "Resource", { ...props, neuronxInstanceType: availableInstancePatterns[0].neuronxInstanceType, artifactS3Prefix: "test", image: image, environment: { MODEL_ID: props.model.modelId, TP_DEGREE: tpDegree.toString(), N_POSITIONS: nPositions.toString(), OPT_LEVEL: optLevel.toString(), QUANT_DTYPE: quantDtype?.toString() ?? "", ARTIFACT_S3_URL: props.bucket.s3UrlForObject(compiledArtifactPathPrefix), }, }); this.tpDegree = tpDegree; this.nPositions = nPositions; this.quantDtype = quantDtype; this.optLevel = optLevel; this.model = props.model; this.compiler = compiler; } compile() { return { ...this.compiler.compile(), tpDegree: this.tpDegree, optLevel: this.optLevel, nPositions: this.nPositions, quantDtype: this.quantDtype, }; } } exports.SageMakerInferenceToolkitTnxCompiler = SageMakerInferenceToolkitTnxCompiler; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FnZW1ha2VyLWluZmVyZW5jZS10b29sa2l0LXRueC1jb21waWxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zYWdlbWFrZXItaW5mZXJlbmNlLXRvb2xraXQtdG54L3NhZ2VtYWtlci1pbmZlcmVuY2UtdG9vbGtpdC10bngtY29tcGlsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsa0VBQWlFO0FBS2pFLDJDQUF1QztBQUN2QywrQkFBNEI7QUFDNUIsNkNBWXlCO0FBQ3pCLCtEQUlrQztBQXdDbEM7Ozs7R0FJRztBQUNILE1BQWEsd0NBQXdDO0lBR25ELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsWUFBMkI7UUFDbkUsTUFBTSxLQUFLLEdBQUcsSUFBSSx1Q0FBbUIsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQy9DLFNBQVMsRUFBRSxJQUFBLFdBQUksRUFDYixTQUFTLEVBQ1QsdURBQXVELENBQ3hEO1lBQ0QsU0FBUyxFQUFFO2dCQUNULFVBQVUsRUFBRSxZQUFZLENBQUMsU0FBUztnQkFDbEMsU0FBUyxFQUFFLFlBQVksQ0FBQyxRQUFRO2FBQ2pDO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUMxQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsWUFBWSxDQUFDLGdCQUFnQixDQUFDO0lBQ3hELENBQUM7Q0FDRjtBQWpCRCw0RkFpQkM7QUFtREQ7O0dBRUc7QUFDSCxNQUFhLG9DQUFxQyxTQUFRLHNCQUFTO0lBT2pFLFlBQ0UsS0FBZ0IsRUFDaEIsRUFBVSxFQUNWLEtBQWdEO1FBRWhELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakIsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLGNBQWMsRUFBRSxRQUFRLElBQUksa0JBQVEsQ0FBQyxZQUFZLENBQUM7UUFDekUsTUFBTSxTQUFTLEdBQUcsS0FB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Z0JBQ1gsUUFBUSxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTztnQkFDN0IsU0FBUyxFQUFFLFFBQVEsQ0FBQyxRQUFRLEVBQUU7Z0JBQzlCLFdBQVcsRUFBRSxVQUFVLENBQUMsUUFBUSxFQUFFO2dCQUNsQyxTQUFTLEVBQUUsUUFBUSxDQUFDLFFBQVEsRUFBRTtnQkFDOUIsV0FBVyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFO2dCQUN6QyxlQUFlLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQzFDLDBCQUEwQixDQUMzQjthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO0lBQzNCLENBQUM7SUFDRCxPQUFPO1FBQ0wsT0FBTztZQUNMLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUU7WUFDMUIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1lBQ3ZCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtZQUN2QixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7WUFDM0IsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1NBQzVCLENBQUM7SUFDSixDQUFDO0NBQ0Y7QUF0R0Qsb0ZBc0dDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29udGFpbmVySW1hZ2VCdWlsZCB9IGZyb20gXCJAY2RrbGFicy9kZXBsb3ktdGltZS1idWlsZFwiO1xuaW1wb3J0IHsgU2l6ZSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0ICogYXMgZWMyIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZWMyXCI7XG5pbXBvcnQgeyBDb250YWluZXJJbWFnZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZWNzXCI7XG5pbXBvcnQgeyBJQnVja2V0IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zM1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHtcbiAgY2FsY01lbW9yeUZvb3RwcmludCxcbiAgY2FsY1RlbnNvclBhcmFsbGVsLFxuICBEYXRhVHlwZUJpdHMsXG4gIElOZXVyb254SW1hZ2UsXG4gIElOZXVyb254SW5zdGFuY2VUeXBlLFxuICBpbmZlck1lbW9yeUZvb3RwcmludEZyb21QYXJhbWV0ZXJzLFxuICBNb2RlbCxcbiAgTmV1cm9ueEluc3RhbmNlVHlwZSxcbiAgT3B0TGV2ZWwsXG4gIFB5dG9yY2hUcmFpbmluZ05ldXJvbnhJbWFnZSxcbiAgUXVhbnREdHlwZSxcbn0gZnJvbSBcIi4uL2Jhc2UvbmV1cm9ueFwiO1xuaW1wb3J0IHtcbiAgSU5ldXJvbnhDb250YWluZXJJbWFnZSxcbiAgTmV1cm9ueENvbXBpbGVkTW9kZWwsXG4gIE5ldXJvbnhOYXRpdmVDb21waWxlcixcbn0gZnJvbSBcIi4uL2Jhc2UvbmV1cm9ueC1jb21waWxlclwiO1xuXG4vKipcbiAqIENvbXBpbGUgb3B0aW9ucy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTYWdlTWFrZXJJbmZlcmVuY2VUb29sa2l0VG54Q29tcGlsZU9wdGlvbnMge1xuICAvKipcbiAgICogTnVtYmVyIG9mIHRlbnNvciBwYXJhbGxlbCBncm91cHMuXG4gICAqIEBkZWZhdWx0IC0gY2FsYyBmcm9tIHBhcmFtZXRlcnMgYW5kIHF1YW50RHR5cGVcbiAgICovXG4gIHJlYWRvbmx5IHRwRGVncmVlPzogbnVtYmVyO1xuICAvKipcbiAgICogTWF4aW11bSBudW1iZXIgb2Ygc2VxdWVuY2VzIHBlciBpdGVyYXRpb24uXG4gICAqIEBkZWZhdWx0IDFcbiAgICovXG4gIHJlYWRvbmx5IGJhdGNoU2l6ZT86IG51bWJlcjtcbiAgLyoqXG4gICAqIEBkZWZhdWx0IC0gTm8gcXVhbnRcbiAgICovXG4gIHJlYWRvbmx5IHF1YW50RHR5cGU/OiBRdWFudER0eXBlO1xuICAvKipcbiAgICogQGRlZmF1bHQgNDA5NlxuICAgKi9cbiAgcmVhZG9ubHkgblBvc2l0aW9ucz86IG51bWJlcjtcbiAgLyoqXG4gICAqIEBkZWZhdWx0IE9wdExldmVsLkJFU1RfQkFMQU5DRVxuICAgKi9cbiAgcmVhZG9ubHkgb3B0TGV2ZWw/OiBPcHRMZXZlbDtcbn1cblxuLyoqXG4gKiBUaGUgbW9kZWwgY29tcGlsZWQgYnkgTmV1cm9ueCBjb21waWxlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTYWdlTWFrZXJJbmZlcmVuY2VUb29sa2l0VG54Q29tcGlsZWRNb2RlbCBleHRlbmRzIE5ldXJvbnhDb21waWxlZE1vZGVsIHtcbiAgcmVhZG9ubHkgcXVhbnREdHlwZT86IFF1YW50RHR5cGU7XG4gIHJlYWRvbmx5IG9wdExldmVsPzogT3B0TGV2ZWw7XG4gIHJlYWRvbmx5IHRwRGVncmVlOiBudW1iZXI7XG4gIHJlYWRvbmx5IG5Qb3NpdGlvbnM6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBDb21waWxlIGltYWdlIGZvciBTYWdlTWFrZXJJbmZlcmVuY2VUb29sa2l0VG54Q29tcGlsZS5cbiAqIEBleGFtcGxlXG4gKiBuZXcgU2FnZU1ha2VySW5mZXJlbmNlVG9vbGtpdFRueENvbXBpbGVJbWFnZShzY29wZSwgJ0NvbXBpbGVJbWFnZScsIFB5dG9yY2hUcmFpbmluZ05ldXJvbnhJbWFnZS5MQVRFU1QpO1xuICovXG5leHBvcnQgY2xhc3MgU2FnZU1ha2VySW5mZXJlbmNlVG9vbGtpdFRueENvbXBpbGVJbWFnZSBpbXBsZW1lbnRzIElOZXVyb254Q29udGFpbmVySW1hZ2Uge1xuICByZWFkb25seSBpbWFnZTogQ29udGFpbmVySW1hZ2U7XG4gIHJlYWRvbmx5IG5ldXJvblNka1ZlcnNpb246IHN0cmluZztcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgbmVydW9ueEltYWdlOiBJTmV1cm9ueEltYWdlKSB7XG4gICAgY29uc3QgYnVpbGQgPSBuZXcgQ29udGFpbmVySW1hZ2VCdWlsZChzY29wZSwgaWQsIHtcbiAgICAgIGRpcmVjdG9yeTogam9pbihcbiAgICAgICAgX19kaXJuYW1lLFxuICAgICAgICBcIi4uLy4uL3NjcmlwdHMvY29tcGlsZS9zYWdlbWFrZXItaW5mZXJlbmNlLXRvb2xraXQtdG54XCIsXG4gICAgICApLFxuICAgICAgYnVpbGRBcmdzOiB7XG4gICAgICAgIElNQUdFX05BTUU6IG5lcnVvbnhJbWFnZS5pbWFnZU5hbWUsXG4gICAgICAgIElNQUdFX1RBRzogbmVydW9ueEltYWdlLmltYWdlVGFnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICB0aGlzLmltYWdlID0gYnVpbGQudG9FY3NEb2NrZXJJbWFnZUNvZGUoKTtcbiAgICB0aGlzLm5ldXJvblNka1ZlcnNpb24gPSBuZXJ1b254SW1hZ2UubmV1cm9uU2RrVmVyc2lvbjtcbiAgfVxufVxuXG4vKipcbiAqIFByb3BzIG9mIE5ldXJvbnhDb21waWxlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNhZ2VNYWtlckluZmVyZW5jZVRvb2xraXRUbnhDb21waWxlclByb3BzIHtcbiAgLyoqXG4gICAqIFZQQyBpbiB3aGljaCB0aGlzIHdpbGwgbGF1bmNoIGNvbXBpbGUgd29ya2VyIGluc3RhbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjOiBlYzIuSVZwYztcbiAgLyoqXG4gICAqIFRoZSBidWNrZXQgdG8gdXBsb2FkIGNvbXBpbGVkIGFydGlmYWN0cy5cbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldDogSUJ1Y2tldDtcbiAgLyoqXG4gICAqIFRoZSBtb2RlbCB0byBiZSBjb21waWxlZC5cbiAgICovXG4gIHJlYWRvbmx5IG1vZGVsOiBNb2RlbDtcbiAgLyoqXG4gICAqIFRoZSBpbnN0YW5jZSB0eXBlIG9mIGNvbXBpbGUgd29ya2VyIGluc3RhbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgbmV1cm9ueEluc3RhbmNlVHlwZT86IElOZXVyb254SW5zdGFuY2VUeXBlO1xuICAvKipcbiAgICogVGhlIHJvb3Qgdm9sdW1lIG9mIHdvcmtlciBpbnN0YW5jZS5cbiAgICogQGRlZmF1bHQgLSBOIGJpbGlvbiBwYXJhbWV0ZXJzICogNUdpQiBFQlNcbiAgICovXG4gIHJlYWRvbmx5IHZvbHVtZVNpemU/OiBTaXplO1xuICAvKipcbiAgICogQ29tcGlsZSBydW50aW1lIGltYWdlLlxuICAgKiBAZGVmYXVsdCAtIGxhdGVzdCBpbWFnZVxuICAgKi9cbiAgcmVhZG9ubHkgaW1hZ2U/OiBTYWdlTWFrZXJJbmZlcmVuY2VUb29sa2l0VG54Q29tcGlsZUltYWdlO1xuICAvKipcbiAgICogTmV1cm9ueCBjb21waWxlIG9wdGlvbnMuXG4gICAqIEBkZWZhdWx0IC0gRWFjaCBwcm9wZXJ0aWVzIGFyZSBzZXQgZGVmYXVsdC5cbiAgICovXG4gIHJlYWRvbmx5IGNvbXBpbGVPcHRpb25zPzogU2FnZU1ha2VySW5mZXJlbmNlVG9vbGtpdFRueENvbXBpbGVPcHRpb25zO1xuICAvKipcbiAgICogV2hldGhlciBvciBub3QgdG8gdXNlIHNwb3QgaW5zdGFuY2VzLiBTcG90IGluc3RhbmNlcyBhcmUgbGVzcyBleHBlbnNpdmUgRUMyIGluc3RhbmNlcyB0aGF0IGNhbiBiZSByZWNsYWltZWQgYnkgRUMyIGF0IGFueSB0aW1lOyB5b3VyIGpvYiB3aWxsIGJlIGdpdmVuIHR3byBtaW51dGVzIG9mIG5vdGljZSBiZWZvcmUgcmVjbGFtYXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBzcG90PzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFRoZSBWUEMgU3VibmV0cyB0aGlzIENvbXB1dGUgRW52aXJvbm1lbnQgd2lsbCBsYXVuY2ggaW5zdGFuY2VzIGluLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5ldyBzdWJuZXRzIHdpbGwgYmUgY3JlYXRlZFxuICAgKi9cbiAgcmVhZG9ubHkgdnBjU3VibmV0cz86IGVjMi5TdWJuZXRTZWxlY3Rpb247XG59XG5cbi8qKlxuICogTmV1cm9ueCBjb21waWxlIGNvbnN0cnVjdC4gQ29tcGlsZSB0aGUgbW9kZWwgdG8gd29yayB3aXRoIEluZmVyZW50aWEyIGFuZCBUcmFpbml1bTEgYW5kIHVwbG9hZCBpdCB0byBhbiBTMyBidWNrZXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBTYWdlTWFrZXJJbmZlcmVuY2VUb29sa2l0VG54Q29tcGlsZXIgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICByZWFkb25seSBxdWFudER0eXBlPzogUXVhbnREdHlwZTtcbiAgcmVhZG9ubHkgb3B0TGV2ZWw/OiBPcHRMZXZlbDtcbiAgcmVhZG9ubHkgdHBEZWdyZWU6IG51bWJlcjtcbiAgcmVhZG9ubHkgblBvc2l0aW9uczogbnVtYmVyO1xuICBtb2RlbDogTW9kZWw7XG4gIHByaXZhdGUgcmVhZG9ubHkgY29tcGlsZXI6IE5ldXJvbnhOYXRpdmVDb21waWxlcjtcbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IENvbnN0cnVjdCxcbiAgICBpZDogc3RyaW5nLFxuICAgIHByb3BzOiBTYWdlTWFrZXJJbmZlcmVuY2VUb29sa2l0VG54Q29tcGlsZXJQcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICBjb25zdCBvcHRMZXZlbCA9IHByb3BzLmNvbXBpbGVPcHRpb25zPy5vcHRMZXZlbCA/PyBPcHRMZXZlbC5CRVNUX0JBTEFOQ0U7XG4gICAgY29uc3QgYmF0Y2hTaXplID0gcHJvcHMuY29tcGlsZU9wdGlvbnM/LmJhdGNoU2l6ZSA/PyAxO1xuICAgIGNvbnN0IG5Qb3NpdGlvbnMgPSBwcm9wcy5jb21waWxlT3B0aW9ucz8ublBvc2l0aW9ucyA/PyA0MDk2O1xuICAgIGNvbnN0IHF1YW50RHR5cGUgPSBwcm9wcy5jb21waWxlT3B0aW9ucz8ucXVhbnREdHlwZTtcbiAgICBjb25zdCBtZW1vcnlGb290cHJpbnQgPSBwcm9wcy5tb2RlbC5vcHRpb25zLmNvbmZpZ1xuICAgICAgPyBjYWxjTWVtb3J5Rm9vdHByaW50KFxuICAgICAgICAgIHByb3BzLm1vZGVsLm9wdGlvbnMuY29uZmlnLmVtYmVkZGluZ0RpbWVuc2lvbixcbiAgICAgICAgICBwcm9wcy5tb2RlbC5vcHRpb25zLmNvbmZpZy5sYXllcnMsXG4gICAgICAgICAgRGF0YVR5cGVCaXRzLkJGMTZfT1JfRlAxNixcbiAgICAgICAgICBuUG9zaXRpb25zLFxuICAgICAgICAgIGJhdGNoU2l6ZSxcbiAgICAgICAgKVxuICAgICAgOiBpbmZlck1lbW9yeUZvb3RwcmludEZyb21QYXJhbWV0ZXJzKFxuICAgICAgICAgIHByb3BzLm1vZGVsLm9wdGlvbnMucGFyYW1ldGVycyxcbiAgICAgICAgICBuUG9zaXRpb25zLFxuICAgICAgICAgIGJhdGNoU2l6ZSxcbiAgICAgICAgKTtcbiAgICBjb25zdCBuZXVyb254SW5zdGFuY2VUeXBlcyA9IHByb3BzLm5ldXJvbnhJbnN0YW5jZVR5cGVcbiAgICAgID8gW3Byb3BzLm5ldXJvbnhJbnN0YW5jZVR5cGVdXG4gICAgICA6IFtcbiAgICAgICAgICBOZXVyb254SW5zdGFuY2VUeXBlLklORjJfOFhMQVJHRSxcbiAgICAgICAgICBOZXVyb254SW5zdGFuY2VUeXBlLklORjJfMjRYTEFSR0UsXG4gICAgICAgICAgTmV1cm9ueEluc3RhbmNlVHlwZS5JTkYyXzQ4WExBUkdFLFxuICAgICAgICBdO1xuICAgIGNvbnN0IGF2YWlsYWJsZUluc3RhbmNlUGF0dGVybnMgPSBuZXVyb254SW5zdGFuY2VUeXBlc1xuICAgICAgLmZsYXRNYXAoKG5ldXJvbnhJbnN0YW5jZVR5cGUpID0+XG4gICAgICAgIGNhbGNUZW5zb3JQYXJhbGxlbChcbiAgICAgICAgICBuZXVyb254SW5zdGFuY2VUeXBlLFxuICAgICAgICAgIG1lbW9yeUZvb3RwcmludCxcbiAgICAgICAgICBwcm9wcy5tb2RlbC5vcHRpb25zLmNvbmZpZz8uYXR0ZW50aW9uSGVhZHMsXG4gICAgICAgICkubWFwKCh2KSA9PiAoe1xuICAgICAgICAgIG5ldXJvbnhJbnN0YW5jZVR5cGUsXG4gICAgICAgICAgLi4udixcbiAgICAgICAgfSkpLFxuICAgICAgKVxuICAgICAgLmZpbHRlcihcbiAgICAgICAgKHBhdHRlcm4pID0+XG4gICAgICAgICAgIXByb3BzLmNvbXBpbGVPcHRpb25zPy50cERlZ3JlZSB8fFxuICAgICAgICAgIHBhdHRlcm4udHAgPT09IHByb3BzLmNvbXBpbGVPcHRpb25zLnRwRGVncmVlLFxuICAgICAgKTtcbiAgICBpZiAoYXZhaWxhYmxlSW5zdGFuY2VQYXR0ZXJucy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYE5vIGF2YWlsYWJsZSBpbnN0YW5jZSB0eXBlLiBZb3UgY2FuIHVzZSB0cERlZ3JlZSBhcmUgJHthdmFpbGFibGVJbnN0YW5jZVBhdHRlcm5zLm1hcCgocCkgPT4gcC50cCkuam9pbihcIiwgXCIpfS5gLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgdHBEZWdyZWUgPSBhdmFpbGFibGVJbnN0YW5jZVBhdHRlcm5zWzBdLnRwO1xuICAgIGNvbnN0IGltYWdlID1cbiAgICAgIHByb3BzLmltYWdlID8/XG4gICAgICBuZXcgU2FnZU1ha2VySW5mZXJlbmNlVG9vbGtpdFRueENvbXBpbGVJbWFnZShcbiAgICAgICAgdGhpcyxcbiAgICAgICAgXCJDb21waWxlSW1hZ2VcIixcbiAgICAgICAgUHl0b3JjaFRyYWluaW5nTmV1cm9ueEltYWdlLkxBVEVTVCxcbiAgICAgICk7XG4gICAgbGV0IGNvbXBpbGVkQXJ0aWZhY3RQYXRoUHJlZml4ID0gYCR7cHJvcHMubW9kZWwubW9kZWxJZH0vbmV1cm9ueC0ke2ltYWdlLm5ldXJvblNka1ZlcnNpb259L3RwJHt0cERlZ3JlZX0tbnAke25Qb3NpdGlvbnN9LW9wdCR7b3B0TGV2ZWx9YDtcbiAgICBpZiAocXVhbnREdHlwZSEhKSB7XG4gICAgICBjb21waWxlZEFydGlmYWN0UGF0aFByZWZpeCA9IGAke2NvbXBpbGVkQXJ0aWZhY3RQYXRoUHJlZml4fS1xdWFudCR7cXVhbnREdHlwZX1gO1xuICAgIH1cbiAgICBjb25zdCBjb21waWxlciA9IG5ldyBOZXVyb254TmF0aXZlQ29tcGlsZXIodGhpcywgXCJSZXNvdXJjZVwiLCB7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIG5ldXJvbnhJbnN0YW5jZVR5cGU6IGF2YWlsYWJsZUluc3RhbmNlUGF0dGVybnNbMF0ubmV1cm9ueEluc3RhbmNlVHlwZSxcbiAgICAgIGFydGlmYWN0UzNQcmVmaXg6IFwidGVzdFwiLFxuICAgICAgaW1hZ2U6IGltYWdlLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgTU9ERUxfSUQ6IHByb3BzLm1vZGVsLm1vZGVsSWQsXG4gICAgICAgIFRQX0RFR1JFRTogdHBEZWdyZWUudG9TdHJpbmcoKSxcbiAgICAgICAgTl9QT1NJVElPTlM6IG5Qb3NpdGlvbnMudG9TdHJpbmcoKSxcbiAgICAgICAgT1BUX0xFVkVMOiBvcHRMZXZlbC50b1N0cmluZygpLFxuICAgICAgICBRVUFOVF9EVFlQRTogcXVhbnREdHlwZT8udG9TdHJpbmcoKSA/PyBcIlwiLFxuICAgICAgICBBUlRJRkFDVF9TM19VUkw6IHByb3BzLmJ1Y2tldC5zM1VybEZvck9iamVjdChcbiAgICAgICAgICBjb21waWxlZEFydGlmYWN0UGF0aFByZWZpeCxcbiAgICAgICAgKSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgdGhpcy50cERlZ3JlZSA9IHRwRGVncmVlO1xuICAgIHRoaXMublBvc2l0aW9ucyA9IG5Qb3NpdGlvbnM7XG4gICAgdGhpcy5xdWFudER0eXBlID0gcXVhbnREdHlwZTtcbiAgICB0aGlzLm9wdExldmVsID0gb3B0TGV2ZWw7XG4gICAgdGhpcy5tb2RlbCA9IHByb3BzLm1vZGVsO1xuICAgIHRoaXMuY29tcGlsZXIgPSBjb21waWxlcjtcbiAgfVxuICBjb21waWxlKCk6IFNhZ2VNYWtlckluZmVyZW5jZVRvb2xraXRUbnhDb21waWxlZE1vZGVsIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5jb21waWxlci5jb21waWxlKCksXG4gICAgICB0cERlZ3JlZTogdGhpcy50cERlZ3JlZSxcbiAgICAgIG9wdExldmVsOiB0aGlzLm9wdExldmVsLFxuICAgICAgblBvc2l0aW9uczogdGhpcy5uUG9zaXRpb25zLFxuICAgICAgcXVhbnREdHlwZTogdGhpcy5xdWFudER0eXBlLFxuICAgIH07XG4gIH1cbn1cbiJdfQ==