UNPKG

25.6 kBJavaScriptView Raw
1"use strict";
2var _a;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.LinuxGpuBuildImage = void 0;
5const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7const ecr = require("@aws-cdk/aws-ecr");
8const core = require("@aws-cdk/core");
9const region_info_1 = require("@aws-cdk/region-info");
10const run_script_linux_build_spec_1 = require("./private/run-script-linux-build-spec");
11const project_1 = require("./project");
12/**
13 * A CodeBuild GPU image running Linux.
14 *
15 * This class has public constants that represent the most popular GPU images from AWS Deep Learning Containers.
16 *
17 * @see https://aws.amazon.com/releasenotes/available-deep-learning-containers-images
18 */
19class LinuxGpuBuildImage {
20 constructor(repositoryName, tag, account) {
21 this.repositoryName = repositoryName;
22 this.account = account;
23 this.type = 'LINUX_GPU_CONTAINER';
24 this.defaultComputeType = project_1.ComputeType.LARGE;
25 this.imagePullPrincipalType = project_1.ImagePullPrincipalType.SERVICE_ROLE;
26 const imageAccount = account ?? core.Lazy.string({
27 produce: () => {
28 if (this._imageAccount === undefined) {
29 throw new Error('Make sure this \'LinuxGpuBuildImage\' is used in a CodeBuild Project construct');
30 }
31 return this._imageAccount;
32 },
33 });
34 // The value of imageId below *should* have been `Lazy.stringValue(() => repository.repositoryUriForTag(this.tag))`,
35 // but we can't change that anymore because someone somewhere might at this point have written code
36 // to do `image.imageId.includes('pytorch')` and changing this to a full-on token would break them.
37 this.imageId = `${imageAccount}.dkr.ecr.${core.Aws.REGION}.${core.Aws.URL_SUFFIX}/${repositoryName}:${tag}`;
38 }
39 /**
40 * Returns a Linux GPU build image from AWS Deep Learning Containers.
41 *
42 * @param repositoryName the name of the repository,
43 * for example "pytorch-inference"
44 * @param tag the tag of the image, for example "1.5.0-gpu-py36-cu101-ubuntu16.04"
45 * @param account the AWS account ID where the DLC repository for this region is hosted in.
46 * In many cases, the CDK can infer that for you, but for some newer region our information
47 * might be out of date; in that case, you can specify the region explicitly using this optional parameter
48 * @see https://aws.amazon.com/releasenotes/available-deep-learning-containers-images
49 */
50 static awsDeepLearningContainersImage(repositoryName, tag, account) {
51 return new LinuxGpuBuildImage(repositoryName, tag, account);
52 }
53 /**
54 * Returns a GPU image running Linux from an ECR repository.
55 *
56 * NOTE: if the repository is external (i.e. imported), then we won't be able to add
57 * a resource policy statement for it so CodeBuild can pull the image.
58 *
59 * @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-ecr.html
60 *
61 * @param repository The ECR repository
62 * @param tag Image tag (default "latest")
63 */
64 static fromEcrRepository(repository, tag = 'latest') {
65 return new LinuxGpuBuildImage(repository.repositoryName, tag, repository.env.account);
66 }
67 bind(scope, project, _options) {
68 try {
69 jsiiDeprecationWarnings._aws_cdk_aws_codebuild_IProject(project);
70 jsiiDeprecationWarnings._aws_cdk_aws_codebuild_BuildImageBindOptions(_options);
71 }
72 catch (error) {
73 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
74 Error.captureStackTrace(error, this.bind);
75 }
76 throw error;
77 }
78 const account = this.account ?? core.Stack.of(scope).regionalFact(region_info_1.FactName.DLC_REPOSITORY_ACCOUNT);
79 const repository = ecr.Repository.fromRepositoryAttributes(scope, 'AwsDlcRepositoryCodeBuild', {
80 repositoryName: this.repositoryName,
81 repositoryArn: ecr.Repository.arnForLocalRepository(this.repositoryName, scope, account),
82 });
83 repository.grantPull(project);
84 this._imageAccount = account;
85 return {};
86 }
87 validate(buildEnvironment) {
88 try {
89 jsiiDeprecationWarnings._aws_cdk_aws_codebuild_BuildEnvironment(buildEnvironment);
90 }
91 catch (error) {
92 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
93 Error.captureStackTrace(error, this.validate);
94 }
95 throw error;
96 }
97 const ret = [];
98 if (buildEnvironment.computeType &&
99 buildEnvironment.computeType !== project_1.ComputeType.LARGE) {
100 ret.push(`GPU images only support ComputeType '${project_1.ComputeType.LARGE}' - ` +
101 `'${buildEnvironment.computeType}' was given`);
102 }
103 return ret;
104 }
105 runScriptBuildspec(entrypoint) {
106 return run_script_linux_build_spec_1.runScriptLinuxBuildSpec(entrypoint);
107 }
108}
109exports.LinuxGpuBuildImage = LinuxGpuBuildImage;
110_a = JSII_RTTI_SYMBOL_1;
111LinuxGpuBuildImage[_a] = { fqn: "@aws-cdk/aws-codebuild.LinuxGpuBuildImage", version: "1.181.1" };
112/** Tensorflow 1.14.0 GPU image from AWS Deep Learning Containers. */
113LinuxGpuBuildImage.DLC_TENSORFLOW_1_14_0 = LinuxGpuBuildImage.awsDeepLearningContainersImage('tensorflow-training', '1.14.0-gpu-py36-cu100-ubuntu16.04');
114/** Tensorflow 1.15.0 GPU image from AWS Deep Learning Containers. */
115LinuxGpuBuildImage.DLC_TENSORFLOW_1_15_0 = LinuxGpuBuildImage.awsDeepLearningContainersImage('tensorflow-training', '1.15.0-gpu-py36-cu100-ubuntu18.04');
116/** Tensorflow 1.15.2 GPU training image from AWS Deep Learning Containers. */
117LinuxGpuBuildImage.DLC_TENSORFLOW_1_15_2_TRAINING = LinuxGpuBuildImage.awsDeepLearningContainersImage('tensorflow-training', '1.15.2-gpu-py37-cu100-ubuntu18.04');
118/** Tensorflow 1.15.2 GPU inference image from AWS Deep Learning Containers. */
119LinuxGpuBuildImage.DLC_TENSORFLOW_1_15_2_INFERENCE = LinuxGpuBuildImage.awsDeepLearningContainersImage('tensorflow-inference', '1.15.2-gpu-py36-cu100-ubuntu18.04');
120/** Tensorflow 2.0.0 GPU image from AWS Deep Learning Containers. */
121LinuxGpuBuildImage.DLC_TENSORFLOW_2_0_0 = LinuxGpuBuildImage.awsDeepLearningContainersImage('tensorflow-training', '2.0.0-gpu-py36-cu100-ubuntu18.04');
122/** Tensorflow 2.0.1 GPU image from AWS Deep Learning Containers. */
123LinuxGpuBuildImage.DLC_TENSORFLOW_2_0_1 = LinuxGpuBuildImage.awsDeepLearningContainersImage('tensorflow-training', '2.0.1-gpu-py36-cu100-ubuntu18.04');
124/** Tensorflow 2.1.0 GPU training image from AWS Deep Learning Containers. */
125LinuxGpuBuildImage.DLC_TENSORFLOW_2_1_0_TRAINING = LinuxGpuBuildImage.awsDeepLearningContainersImage('tensorflow-training', '2.1.0-gpu-py36-cu101-ubuntu18.04');
126/** Tensorflow 2.1.0 GPU inference image from AWS Deep Learning Containers. */
127LinuxGpuBuildImage.DLC_TENSORFLOW_2_1_0_INFERENCE = LinuxGpuBuildImage.awsDeepLearningContainersImage('tensorflow-inference', '2.1.0-gpu-py36-cu101-ubuntu18.04');
128/** Tensorflow 2.2.0 GPU training image from AWS Deep Learning Containers. */
129LinuxGpuBuildImage.DLC_TENSORFLOW_2_2_0_TRAINING = LinuxGpuBuildImage.awsDeepLearningContainersImage('tensorflow-training', '2.2.0-gpu-py37-cu101-ubuntu18.04');
130/** PyTorch 1.2.0 GPU image from AWS Deep Learning Containers. */
131LinuxGpuBuildImage.DLC_PYTORCH_1_2_0 = LinuxGpuBuildImage.awsDeepLearningContainersImage('pytorch-training', '1.2.0-gpu-py36-cu100-ubuntu16.04');
132/** PyTorch 1.3.1 GPU image from AWS Deep Learning Containers. */
133LinuxGpuBuildImage.DLC_PYTORCH_1_3_1 = LinuxGpuBuildImage.awsDeepLearningContainersImage('pytorch-training', '1.3.1-gpu-py36-cu101-ubuntu16.04');
134/** PyTorch 1.4.0 GPU training image from AWS Deep Learning Containers. */
135LinuxGpuBuildImage.DLC_PYTORCH_1_4_0_TRAINING = LinuxGpuBuildImage.awsDeepLearningContainersImage('pytorch-training', '1.4.0-gpu-py36-cu101-ubuntu16.04');
136/** PyTorch 1.4.0 GPU inference image from AWS Deep Learning Containers. */
137LinuxGpuBuildImage.DLC_PYTORCH_1_4_0_INFERENCE = LinuxGpuBuildImage.awsDeepLearningContainersImage('pytorch-inference', '1.4.0-gpu-py36-cu101-ubuntu16.04');
138/** PyTorch 1.5.0 GPU training image from AWS Deep Learning Containers. */
139LinuxGpuBuildImage.DLC_PYTORCH_1_5_0_TRAINING = LinuxGpuBuildImage.awsDeepLearningContainersImage('pytorch-training', '1.5.0-gpu-py36-cu101-ubuntu16.04');
140/** PyTorch 1.5.0 GPU inference image from AWS Deep Learning Containers. */
141LinuxGpuBuildImage.DLC_PYTORCH_1_5_0_INFERENCE = LinuxGpuBuildImage.awsDeepLearningContainersImage('pytorch-inference', '1.5.0-gpu-py36-cu101-ubuntu16.04');
142/** MXNet 1.4.1 GPU image from AWS Deep Learning Containers. */
143LinuxGpuBuildImage.DLC_MXNET_1_4_1 = LinuxGpuBuildImage.awsDeepLearningContainersImage('mxnet-training', '1.4.1-gpu-py36-cu100-ubuntu16.04');
144/** MXNet 1.6.0 GPU image from AWS Deep Learning Containers. */
145LinuxGpuBuildImage.DLC_MXNET_1_6_0 = LinuxGpuBuildImage.awsDeepLearningContainersImage('mxnet-training', '1.6.0-gpu-py36-cu101-ubuntu16.04');
146//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGludXgtZ3B1LWJ1aWxkLWltYWdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibGludXgtZ3B1LWJ1aWxkLWltYWdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHdDQUF3QztBQUN4QyxzQ0FBc0M7QUFDdEMsc0RBQWdEO0FBRWhELHVGQUFnRjtBQUNoRix1Q0FHbUI7QUFNbkI7Ozs7OztHQU1HO0FBQ0gsTUFBYSxrQkFBa0I7SUE2RjdCLFlBQXFDLGNBQXNCLEVBQUUsR0FBVyxFQUFtQixPQUEyQjtRQUFqRixtQkFBYyxHQUFkLGNBQWMsQ0FBUTtRQUFnQyxZQUFPLEdBQVAsT0FBTyxDQUFvQjtRQVB0RyxTQUFJLEdBQUcscUJBQXFCLENBQUM7UUFDN0IsdUJBQWtCLEdBQUcscUJBQVcsQ0FBQyxLQUFLLENBQUM7UUFDdkMsMkJBQXNCLEdBQTRCLGdDQUFzQixDQUFDLFlBQVksQ0FBQztRQU1wRyxNQUFNLFlBQVksR0FBRyxPQUFPLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDL0MsT0FBTyxFQUFFLEdBQUcsRUFBRTtnQkFDWixJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssU0FBUyxFQUFFO29CQUNwQyxNQUFNLElBQUksS0FBSyxDQUFDLGdGQUFnRixDQUFDLENBQUM7aUJBQ25HO2dCQUNELE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztZQUM1QixDQUFDO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsb0hBQW9IO1FBQ3BILG1HQUFtRztRQUNuRyxtR0FBbUc7UUFDbkcsSUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLFlBQVksWUFBWSxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxjQUFjLElBQUksR0FBRyxFQUFFLENBQUM7S0FDN0c7SUFwREQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLE1BQU0sQ0FBQyw4QkFBOEIsQ0FBQyxjQUFzQixFQUFFLEdBQVcs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QWtCLENBQUMsOEJBQThCLENBQUMscUJBQXFCLEVBQzVILGtDQUFrQyxDQUFDLENBQUM7QUFFdEMsaUVBQWlFO0FBQzFDLG9DQUFpQixHQUFHLGtCQUFrQixDQUFDLDhCQUE4QixDQUFDLGtCQUFrQixFQUM3RyxrQ0FBa0MsQ0FBQyxDQUFDO0FBQ3RDLGlFQUFpRTtBQUMxQyxvQ0FBaUIsR0FBRyxrQkFBa0IsQ0FBQyw4QkFBOEIsQ0FBQyxrQkFBa0IsRUFDN0csa0NBQWtDLENBQUMsQ0FBQztBQUN0QywwRUFBMEU7QUFDbkQsNkNBQTBCLEdBQUcsa0JBQWtCLENBQUMsOEJBQThCLENBQUMsa0JBQWtCLEVBQ3RILGtDQUFrQyxDQUFDLENBQUM7QUFDdEMsMkVBQTJFO0FBQ3BELDhDQUEyQixHQUFHLGtCQUFrQixDQUFDLDhCQUE4QixDQUFDLG1CQUFtQixFQUN4SCxrQ0FBa0MsQ0FBQyxDQUFDO0FBQ3RDLDBFQUEwRTtBQUNuRCw2Q0FBMEIsR0FBRyxrQkFBa0IsQ0FBQyw4QkFBOEIsQ0FBQyxrQkFBa0IsRUFDdEgsa0NBQWtDLENBQUMsQ0FBQztBQUN0QywyRUFBMkU7QUFDcEQsOENBQTJCLEdBQUcsa0JBQWtCLENBQUMsOEJBQThCLENBQUMsbUJBQW1CLEVBQ3hILGtDQUFrQyxDQUFDLENBQUM7QUFFdEMsK0RBQStEO0FBQ3hDLGtDQUFlLEdBQUcsa0JBQWtCLENBQUMsOEJBQThCLENBQUMsZ0JBQWdCLEVBQ3pHLGtDQUFrQyxDQUFDLENBQUM7QUFDdEMsK0RBQStEO0FBQ3hDLGtDQUFlLEdBQUcsa0JBQWtCLENBQUMsOEJBQThCLENBQUMsZ0JBQWdCLEVBQ3pHLGtDQUFrQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBlY3IgZnJvbSAnQGF3cy1jZGsvYXdzLWVjcic7XG5pbXBvcnQgKiBhcyBjb3JlIGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1xuaW1wb3J0IHsgRmFjdE5hbWUgfSBmcm9tICdAYXdzLWNkay9yZWdpb24taW5mbyc7XG5pbXBvcnQgeyBCdWlsZFNwZWMgfSBmcm9tICcuL2J1aWxkLXNwZWMnO1xuaW1wb3J0IHsgcnVuU2NyaXB0TGludXhCdWlsZFNwZWMgfSBmcm9tICcuL3ByaXZhdGUvcnVuLXNjcmlwdC1saW51eC1idWlsZC1zcGVjJztcbmltcG9ydCB7XG4gIEJ1aWxkRW52aXJvbm1lbnQsIEJ1aWxkSW1hZ2VCaW5kT3B0aW9ucywgQnVpbGRJbWFnZUNvbmZpZywgQ29tcHV0ZVR5cGUsIElCaW5kYWJsZUJ1aWxkSW1hZ2UsIElCdWlsZEltYWdlLFxuICBJbWFnZVB1bGxQcmluY2lwYWxUeXBlLCBJUHJvamVjdCxcbn0gZnJvbSAnLi9wcm9qZWN0JztcblxuLy8ga2VlcCB0aGlzIGltcG9ydCBzZXBhcmF0ZSBmcm9tIG90aGVyIGltcG9ydHMgdG8gcmVkdWNlIGNoYW5jZSBmb3IgbWVyZ2UgY29uZmxpY3RzIHdpdGggdjItbWFpblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWR1cGxpY2F0ZS1pbXBvcnRzLCBpbXBvcnQvb3JkZXJcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1xuXG4vKipcbiAqIEEgQ29kZUJ1aWxkIEdQVSBpbWFnZSBydW5uaW5nIExpbnV4LlxuICpcbiAqIFRoaXMgY2xhc3MgaGFzIHB1YmxpYyBjb25zdGFudHMgdGhhdCByZXByZXNlbnQgdGhlIG1vc3QgcG9wdWxhciBHUFUgaW1hZ2VzIGZyb20gQVdTIERlZXAgTGVhcm5pbmcgQ29udGFpbmVycy5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vYXdzLmFtYXpvbi5jb20vcmVsZWFzZW5vdGVzL2F2YWlsYWJsZS1kZWVwLWxlYXJuaW5nLWNvbnRhaW5lcnMtaW1hZ2VzXG4gKi9cbmV4cG9ydCBjbGFzcyBMaW51eEdwdUJ1aWxkSW1hZ2UgaW1wbGVtZW50cyBJQmluZGFibGVCdWlsZEltYWdlIHtcbiAgLyoqIFRlbnNvcmZsb3cgMS4xNC4wIEdQVSBpbWFnZSBmcm9tIEFXUyBEZWVwIExlYXJuaW5nIENvbnRhaW5lcnMuICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgRExDX1RFTlNPUkZMT1dfMV8xNF8wID0gTGludXhHcHVCdWlsZEltYWdlLmF3c0RlZXBMZWFybmluZ0NvbnRhaW5lcnNJbWFnZSgndGVuc29yZmxvdy10cmFpbmluZycsXG4gICAgJzEuMTQuMC1ncHUtcHkzNi1jdTEwMC11YnVudHUxNi4wNCcpO1xuICAvKiogVGVuc29yZmxvdyAxLjE1LjAgR1BVIGltYWdlIGZyb20gQVdTIERlZXAgTGVhcm5pbmcgQ29udGFpbmVycy4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBETENfVEVOU09SRkxPV18xXzE1XzAgPSBMaW51eEdwdUJ1aWxkSW1hZ2UuYXdzRGVlcExlYXJuaW5nQ29udGFpbmVyc0ltYWdlKCd0ZW5zb3JmbG93LXRyYWluaW5nJyxcbiAgICAnMS4xNS4wLWdwdS1weTM2LWN1MTAwLXVidW50dTE4LjA0Jyk7XG4gIC8qKiBUZW5zb3JmbG93IDEuMTUuMiBHUFUgdHJhaW5pbmcgaW1hZ2UgZnJvbSBBV1MgRGVlcCBMZWFybmluZyBDb250YWluZXJzLiAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERMQ19URU5TT1JGTE9XXzFfMTVfMl9UUkFJTklORyA9IExpbnV4R3B1QnVpbGRJbWFnZS5hd3NEZWVwTGVhcm5pbmdDb250YWluZXJzSW1hZ2UoJ3RlbnNvcmZsb3ctdHJhaW5pbmcnLFxuICAgICcxLjE1LjItZ3B1LXB5MzctY3UxMDAtdWJ1bnR1MTguMDQnKTtcbiAgLyoqIFRlbnNvcmZsb3cgMS4xNS4yIEdQVSBpbmZlcmVuY2UgaW1hZ2UgZnJvbSBBV1MgRGVlcCBMZWFybmluZyBDb250YWluZXJzLiAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERMQ19URU5TT1JGTE9XXzFfMTVfMl9JTkZFUkVOQ0UgPSBMaW51eEdwdUJ1aWxkSW1hZ2UuYXdzRGVlcExlYXJuaW5nQ29udGFpbmVyc0ltYWdlKCd0ZW5zb3JmbG93LWluZmVyZW5jZScsXG4gICAgJzEuMTUuMi1ncHUtcHkzNi1jdTEwMC11YnVudHUxOC4wNCcpO1xuICAvKiogVGVuc29yZmxvdyAyLjAuMCBHUFUgaW1hZ2UgZnJvbSBBV1MgRGVlcCBMZWFybmluZyBDb250YWluZXJzLiAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERMQ19URU5TT1JGTE9XXzJfMF8wID0gTGludXhHcHVCdWlsZEltYWdlLmF3c0RlZXBMZWFybmluZ0NvbnRhaW5lcnNJbWFnZSgndGVuc29yZmxvdy10cmFpbmluZycsXG4gICAgJzIuMC4wLWdwdS1weTM2LWN1MTAwLXVidW50dTE4LjA0Jyk7XG4gIC8qKiBUZW5zb3JmbG93IDIuMC4xIEdQVSBpbWFnZSBmcm9tIEFXUyBEZWVwIExlYXJuaW5nIENvbnRhaW5lcnMuICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgRExDX1RFTlNPUkZMT1dfMl8wXzEgPSBMaW51eEdwdUJ1aWxkSW1hZ2UuYXdzRGVlcExlYXJuaW5nQ29udGFpbmVyc0ltYWdlKCd0ZW5zb3JmbG93LXRyYWluaW5nJyxcbiAgICAnMi4wLjEtZ3B1LXB5MzYtY3UxMDAtdWJ1bnR1MTguMDQnKTtcbiAgLyoqIFRlbnNvcmZsb3cgMi4xLjAgR1BVIHRyYWluaW5nIGltYWdlIGZyb20gQVdTIERlZXAgTGVhcm5pbmcgQ29udGFpbmVycy4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBETENfVEVOU09SRkxPV18yXzFfMF9UUkFJTklORyA9IExpbnV4R3B1QnVpbGRJbWFnZS5hd3NEZWVwTGVhcm5pbmdDb250YWluZXJzSW1hZ2UoJ3RlbnNvcmZsb3ctdHJhaW5pbmcnLFxuICAgICcyLjEuMC1ncHUtcHkzNi1jdTEwMS11YnVudHUxOC4wNCcpO1xuICAvKiogVGVuc29yZmxvdyAyLjEuMCBHUFUgaW5mZXJlbmNlIGltYWdlIGZyb20gQVdTIERlZXAgTGVhcm5pbmcgQ29udGFpbmVycy4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBETENfVEVOU09SRkxPV18yXzFfMF9JTkZFUkVOQ0UgPSBMaW51eEdwdUJ1aWxkSW1hZ2UuYXdzRGVlcExlYXJuaW5nQ29udGFpbmVyc0ltYWdlKCd0ZW5zb3JmbG93LWluZmVyZW5jZScsXG4gICAgJzIuMS4wLWdwdS1weTM2LWN1MTAxLXVidW50dTE4LjA0Jyk7XG4gIC8qKiBUZW5zb3JmbG93IDIuMi4wIEdQVSB0cmFpbmluZyBpbWFnZSBmcm9tIEFXUyBEZWVwIExlYXJuaW5nIENvbnRhaW5lcnMuICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgRExDX1RFTlNPUkZMT1dfMl8yXzBfVFJBSU5JTkcgPSBMaW51eEdwdUJ1aWxkSW1hZ2UuYXdzRGVlcExlYXJuaW5nQ29udGFpbmVyc0ltYWdlKCd0ZW5zb3JmbG93LXRyYWluaW5nJyxcbiAgICAnMi4yLjAtZ3B1LXB5MzctY3UxMDEtdWJ1bnR1MTguMDQnKTtcblxuICAvKiogUHlUb3JjaCAxLjIuMCBHUFUgaW1hZ2UgZnJvbSBBV1MgRGVlcCBMZWFybmluZyBDb250YWluZXJzLiAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERMQ19QWVRPUkNIXzFfMl8wID0gTGludXhHcHVCdWlsZEltYWdlLmF3c0RlZXBMZWFybmluZ0NvbnRhaW5lcnNJbWFnZSgncHl0b3JjaC10cmFpbmluZycsXG4gICAgJzEuMi4wLWdwdS1weTM2LWN1MTAwLXVidW50dTE2LjA0Jyk7XG4gIC8qKiBQeVRvcmNoIDEuMy4xIEdQVSBpbWFnZSBmcm9tIEFXUyBEZWVwIExlYXJuaW5nIENvbnRhaW5lcnMuICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgRExDX1BZVE9SQ0hfMV8zXzEgPSBMaW51eEdwdUJ1aWxkSW1hZ2UuYXdzRGVlcExlYXJuaW5nQ29udGFpbmVyc0ltYWdlKCdweXRvcmNoLXRyYWluaW5nJyxcbiAgICAnMS4zLjEtZ3B1LXB5MzYtY3UxMDEtdWJ1bnR1MTYuMDQnKTtcbiAgLyoqIFB5VG9yY2ggMS40LjAgR1BVIHRyYWluaW5nIGltYWdlIGZyb20gQVdTIERlZXAgTGVhcm5pbmcgQ29udGFpbmVycy4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBETENfUFlUT1JDSF8xXzRfMF9UUkFJTklORyA9IExpbnV4R3B1QnVpbGRJbWFnZS5hd3NEZWVwTGVhcm5pbmdDb250YWluZXJzSW1hZ2UoJ3B5dG9yY2gtdHJhaW5pbmcnLFxuICAgICcxLjQuMC1ncHUtcHkzNi1jdTEwMS11YnVudHUxNi4wNCcpO1xuICAvKiogUHlUb3JjaCAxLjQuMCBHUFUgaW5mZXJlbmNlIGltYWdlIGZyb20gQVdTIERlZXAgTGVhcm5pbmcgQ29udGFpbmVycy4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBETENfUFlUT1JDSF8xXzRfMF9JTkZFUkVOQ0UgPSBMaW51eEdwdUJ1aWxkSW1hZ2UuYXdzRGVlcExlYXJuaW5nQ29udGFpbmVyc0ltYWdlKCdweXRvcmNoLWluZmVyZW5jZScsXG4gICAgJzEuNC4wLWdwdS1weTM2LWN1MTAxLXVidW50dTE2LjA0Jyk7XG4gIC8qKiBQeVRvcmNoIDEuNS4wIEdQVSB0cmFpbmluZyBpbWFnZSBmcm9tIEFXUyBEZWVwIExlYXJuaW5nIENvbnRhaW5lcnMuICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgRExDX1BZVE9SQ0hfMV81XzBfVFJBSU5JTkcgPSBMaW51eEdwdUJ1aWxkSW1hZ2UuYXdzRGVlcExlYXJuaW5nQ29udGFpbmVyc0ltYWdlKCdweXRvcmNoLXRyYWluaW5nJyxcbiAgICAnMS41LjAtZ3B1LXB5MzYtY3UxMDEtdWJ1bnR1MTYuMDQnKTtcbiAgLyoqIFB5VG9yY2ggMS41LjAgR1BVIGluZmVyZW5jZSBpbWFnZSBmcm9tIEFXUyBEZWVwIExlYXJuaW5nIENvbnRhaW5lcnMuICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgRExDX1BZVE9SQ0hfMV81XzBfSU5GRVJFTkNFID0gTGludXhHcHVCdWlsZEltYWdlLmF3c0RlZXBMZWFybmluZ0NvbnRhaW5lcnNJbWFnZSgncHl0b3JjaC1pbmZlcmVuY2UnLFxuICAgICcxLjUuMC1ncHUtcHkzNi1jdTEwMS11YnVudHUxNi4wNCcpO1xuXG4gIC8qKiBNWE5ldCAxLjQuMSBHUFUgaW1hZ2UgZnJvbSBBV1MgRGVlcCBMZWFybmluZyBDb250YWluZXJzLiAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERMQ19NWE5FVF8xXzRfMSA9IExpbnV4R3B1QnVpbGRJbWFnZS5hd3NEZWVwTGVhcm5pbmdDb250YWluZXJzSW1hZ2UoJ214bmV0LXRyYWluaW5nJyxcbiAgICAnMS40LjEtZ3B1LXB5MzYtY3UxMDAtdWJ1bnR1MTYuMDQnKTtcbiAgLyoqIE1YTmV0IDEuNi4wIEdQVSBpbWFnZSBmcm9tIEFXUyBEZWVwIExlYXJuaW5nIENvbnRhaW5lcnMuICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgRExDX01YTkVUXzFfNl8wID0gTGludXhHcHVCdWlsZEltYWdlLmF3c0RlZXBMZWFybmluZ0NvbnRhaW5lcnNJbWFnZSgnbXhuZXQtdHJhaW5pbmcnLFxuICAgICcxLjYuMC1ncHUtcHkzNi1jdTEwMS11YnVudHUxNi4wNCcpO1xuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgTGludXggR1BVIGJ1aWxkIGltYWdlIGZyb20gQVdTIERlZXAgTGVhcm5pbmcgQ29udGFpbmVycy5cbiAgICpcbiAgICogQHBhcmFtIHJlcG9zaXRvcnlOYW1lIHRoZSBuYW1lIG9mIHRoZSByZXBvc2l0b3J5LFxuICAgKiAgIGZvciBleGFtcGxlIFwicHl0b3JjaC1pbmZlcmVuY2VcIlxuICAgKiBAcGFyYW0gdGFnIHRoZSB0YWcgb2YgdGhlIGltYWdlLCBmb3IgZXhhbXBsZSBcIjEuNS4wLWdwdS1weTM2LWN1MTAxLXVidW50dTE2LjA0XCJcbiAgICogQHBhcmFtIGFjY291bnQgdGhlIEFXUyBhY2NvdW50IElEIHdoZXJlIHRoZSBETEMgcmVwb3NpdG9yeSBmb3IgdGhpcyByZWdpb24gaXMgaG9zdGVkIGluLlxuICAgKiAgIEluIG1hbnkgY2FzZXMsIHRoZSBDREsgY2FuIGluZmVyIHRoYXQgZm9yIHlvdSwgYnV0IGZvciBzb21lIG5ld2VyIHJlZ2lvbiBvdXIgaW5mb3JtYXRpb25cbiAgICogICBtaWdodCBiZSBvdXQgb2YgZGF0ZTsgaW4gdGhhdCBjYXNlLCB5b3UgY2FuIHNwZWNpZnkgdGhlIHJlZ2lvbiBleHBsaWNpdGx5IHVzaW5nIHRoaXMgb3B0aW9uYWwgcGFyYW1ldGVyXG4gICAqIEBzZWUgaHR0cHM6Ly9hd3MuYW1hem9uLmNvbS9yZWxlYXNlbm90ZXMvYXZhaWxhYmxlLWRlZXAtbGVhcm5pbmctY29udGFpbmVycy1pbWFnZXNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXdzRGVlcExlYXJuaW5nQ29udGFpbmVyc0ltYWdlKHJlcG9zaXRvcnlOYW1lOiBzdHJpbmcsIHRhZzogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nKTogSUJ1aWxkSW1hZ2Uge1xuICAgIHJldHVybiBuZXcgTGludXhHcHVCdWlsZEltYWdlKHJlcG9zaXRvcnlOYW1lLCB0YWcsIGFjY291bnQpO1xuICB9XG5cblxuICAvKipcbiAgICogUmV0dXJucyBhIEdQVSBpbWFnZSBydW5uaW5nIExpbnV4IGZyb20gYW4gRUNSIHJlcG9zaXRvcnkuXG4gICAqXG4gICAqIE5PVEU6IGlmIHRoZSByZXBvc2l0b3J5IGlzIGV4dGVybmFsIChpLmUuIGltcG9ydGVkKSwgdGhlbiB3ZSB3b24ndCBiZSBhYmxlIHRvIGFkZFxuICAgKiBhIHJlc291cmNlIHBvbGljeSBzdGF0ZW1lbnQgZm9yIGl0IHNvIENvZGVCdWlsZCBjYW4gcHVsbCB0aGUgaW1hZ2UuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NvZGVidWlsZC9sYXRlc3QvdXNlcmd1aWRlL3NhbXBsZS1lY3IuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gcmVwb3NpdG9yeSBUaGUgRUNSIHJlcG9zaXRvcnlcbiAgICogQHBhcmFtIHRhZyBJbWFnZSB0YWcgKGRlZmF1bHQgXCJsYXRlc3RcIilcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbUVjclJlcG9zaXRvcnkocmVwb3NpdG9yeTogZWNyLklSZXBvc2l0b3J5LCB0YWc6IHN0cmluZyA9ICdsYXRlc3QnKTogSUJ1aWxkSW1hZ2Uge1xuICAgIHJldHVybiBuZXcgTGludXhHcHVCdWlsZEltYWdlKHJlcG9zaXRvcnkucmVwb3NpdG9yeU5hbWUsIHRhZywgcmVwb3NpdG9yeS5lbnYuYWNjb3VudCk7XG4gIH1cblxuICBwdWJsaWMgcmVhZG9ubHkgdHlwZSA9ICdMSU5VWF9HUFVfQ09OVEFJTkVSJztcbiAgcHVibGljIHJlYWRvbmx5IGRlZmF1bHRDb21wdXRlVHlwZSA9IENvbXB1dGVUeXBlLkxBUkdFO1xuICBwdWJsaWMgcmVhZG9ubHkgaW1hZ2VQdWxsUHJpbmNpcGFsVHlwZT86IEltYWdlUHVsbFByaW5jaXBhbFR5cGUgPSBJbWFnZVB1bGxQcmluY2lwYWxUeXBlLlNFUlZJQ0VfUk9MRTtcbiAgcHVibGljIHJlYWRvbmx5IGltYWdlSWQ6IHN0cmluZztcblxuICBwcml2YXRlIF9pbWFnZUFjY291bnQ/OiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHJlcG9zaXRvcnlOYW1lOiBzdHJpbmcsIHRhZzogc3RyaW5nLCBwcml2YXRlIHJlYWRvbmx5IGFjY291bnQ6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IGltYWdlQWNjb3VudCA9IGFjY291bnQgPz8gY29yZS5MYXp5LnN0cmluZyh7XG4gICAgICBwcm9kdWNlOiAoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLl9pbWFnZUFjY291bnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWFrZSBzdXJlIHRoaXMgXFwnTGludXhHcHVCdWlsZEltYWdlXFwnIGlzIHVzZWQgaW4gYSBDb2RlQnVpbGQgUHJvamVjdCBjb25zdHJ1Y3QnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5faW1hZ2VBY2NvdW50O1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIFRoZSB2YWx1ZSBvZiBpbWFnZUlkIGJlbG93ICpzaG91bGQqIGhhdmUgYmVlbiBgTGF6eS5zdHJpbmdWYWx1ZSgoKSA9PiByZXBvc2l0b3J5LnJlcG9zaXRvcnlVcmlGb3JUYWcodGhpcy50YWcpKWAsXG4gICAgLy8gYnV0IHdlIGNhbid0IGNoYW5nZSB0aGF0IGFueW1vcmUgYmVjYXVzZSBzb21lb25lIHNvbWV3aGVyZSBtaWdodCBhdCB0aGlzIHBvaW50IGhhdmUgd3JpdHRlbiBjb2RlXG4gICAgLy8gdG8gZG8gYGltYWdlLmltYWdlSWQuaW5jbHVkZXMoJ3B5dG9yY2gnKWAgYW5kIGNoYW5naW5nIHRoaXMgdG8gYSBmdWxsLW9uIHRva2VuIHdvdWxkIGJyZWFrIHRoZW0uXG4gICAgdGhpcy5pbWFnZUlkID0gYCR7aW1hZ2VBY2NvdW50fS5ka3IuZWNyLiR7Y29yZS5Bd3MuUkVHSU9OfS4ke2NvcmUuQXdzLlVSTF9TVUZGSVh9LyR7cmVwb3NpdG9yeU5hbWV9OiR7dGFnfWA7XG4gIH1cblxuICBwdWJsaWMgYmluZChzY29wZTogQ29uc3RydWN0LCBwcm9qZWN0OiBJUHJvamVjdCwgX29wdGlvbnM6IEJ1aWxkSW1hZ2VCaW5kT3B0aW9ucyk6IEJ1aWxkSW1hZ2VDb25maWcge1xuICAgIGNvbnN0IGFjY291bnQgPSB0aGlzLmFjY291bnQgPz8gY29yZS5TdGFjay5vZihzY29wZSkucmVnaW9uYWxGYWN0KEZhY3ROYW1lLkRMQ19SRVBPU0lUT1JZX0FDQ09VTlQpO1xuICAgIGNvbnN0IHJlcG9zaXRvcnkgPSBlY3IuUmVwb3NpdG9yeS5mcm9tUmVwb3NpdG9yeUF0dHJpYnV0ZXMoc2NvcGUsICdBd3NEbGNSZXBvc2l0b3J5Q29kZUJ1aWxkJywge1xuICAgICAgcmVwb3NpdG9yeU5hbWU6IHRoaXMucmVwb3NpdG9yeU5hbWUsXG4gICAgICByZXBvc2l0b3J5QXJuOiBlY3IuUmVwb3NpdG9yeS5hcm5Gb3JMb2NhbFJlcG9zaXRvcnkodGhpcy5yZXBvc2l0b3J5TmFtZSwgc2NvcGUsIGFjY291bnQpLFxuICAgIH0pO1xuXG4gICAgcmVwb3NpdG9yeS5ncmFudFB1bGwocHJvamVjdCk7XG5cbiAgICB0aGlzLl9pbWFnZUFjY291bnQgPSBhY2NvdW50O1xuXG4gICAgcmV0dXJuIHtcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIHZhbGlkYXRlKGJ1aWxkRW52aXJvbm1lbnQ6IEJ1aWxkRW52aXJvbm1lbnQpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgcmV0ID0gW107XG4gICAgaWYgKGJ1aWxkRW52aXJvbm1lbnQuY29tcHV0ZVR5cGUgJiZcbiAgICAgICAgYnVpbGRFbnZpcm9ubWVudC5jb21wdXRlVHlwZSAhPT0gQ29tcHV0ZVR5cGUuTEFSR0UpIHtcbiAgICAgIHJldC5wdXNoKGBHUFUgaW1hZ2VzIG9ubHkgc3VwcG9ydCBDb21wdXRlVHlwZSAnJHtDb21wdXRlVHlwZS5MQVJHRX0nIC0gYCArXG4gICAgICAgIGAnJHtidWlsZEVudmlyb25tZW50LmNvbXB1dGVUeXBlfScgd2FzIGdpdmVuYCk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICBwdWJsaWMgcnVuU2NyaXB0QnVpbGRzcGVjKGVudHJ5cG9pbnQ6IHN0cmluZyk6IEJ1aWxkU3BlYyB7XG4gICAgcmV0dXJuIHJ1blNjcmlwdExpbnV4QnVpbGRTcGVjKGVudHJ5cG9pbnQpO1xuICB9XG59XG4iXX0=
\No newline at end of file