UNPKG

28 kBJavaScriptView Raw
1"use strict";
2var _a;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.LegacyStackSynthesizer = void 0;
5const jsiiDeprecationWarnings = require("../../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7const cxschema = require("@aws-cdk/cloud-assembly-schema");
8const cxapi = require("@aws-cdk/cx-api");
9const cfn_fn_1 = require("../cfn-fn");
10const construct_compat_1 = require("../construct-compat");
11const asset_parameters_1 = require("../private/asset-parameters");
12const _shared_1 = require("./_shared");
13const stack_synthesizer_1 = require("./stack-synthesizer");
14/**
15 * The well-known name for the docker image asset ECR repository. All docker
16 * image assets will be pushed into this repository with an image tag based on
17 * the source hash.
18 */
19const ASSETS_ECR_REPOSITORY_NAME = 'aws-cdk/assets';
20/**
21 * This allows users to work around the fact that the ECR repository is
22 * (currently) not configurable by setting this context key to their desired
23 * repository name. The CLI will auto-create this ECR repository if it's not
24 * already created.
25 */
26const ASSETS_ECR_REPOSITORY_NAME_OVERRIDE_CONTEXT_KEY = 'assets-ecr-repository-name';
27/**
28 * Use the CDK classic way of referencing assets
29 *
30 * This synthesizer will generate CloudFormation parameters for every referenced
31 * asset, and use the CLI's current credentials to deploy the stack.
32 *
33 * - It does not support cross-account deployment (the CLI must have credentials
34 * to the account you are trying to deploy to).
35 * - It cannot be used with **CDK Pipelines**. To deploy using CDK Pipelines,
36 * you must use the `DefaultStackSynthesizer`.
37 * - Each asset will take up a CloudFormation Parameter in your template. Keep in
38 * mind that there is a maximum of 200 parameters in a CloudFormation template.
39 * To use determinstic asset locations instead, use `CliCredentialsStackSynthesizer`.
40 *
41 * Be aware that your CLI credentials must be valid for the duration of the
42 * entire deployment. If you are using session credentials, make sure the
43 * session lifetime is long enough.
44 *
45 * This is the only StackSynthesizer that supports customizing asset behavior
46 * by overriding `Stack.addFileAsset()` and `Stack.addDockerImageAsset()`.
47 */
48class LegacyStackSynthesizer extends stack_synthesizer_1.StackSynthesizer {
49 constructor() {
50 super(...arguments);
51 this.cycle = false;
52 /**
53 * The image ID of all the docker image assets that were already added to this
54 * stack (to avoid duplication).
55 */
56 this.addedImageAssets = new Set();
57 }
58 bind(stack) {
59 try {
60 jsiiDeprecationWarnings._aws_cdk_core_Stack(stack);
61 }
62 catch (error) {
63 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
64 Error.captureStackTrace(error, this.bind);
65 }
66 throw error;
67 }
68 if (this.stack !== undefined) {
69 throw new Error('A StackSynthesizer can only be used for one Stack: create a new instance to use with a different Stack');
70 }
71 this.stack = stack;
72 }
73 addFileAsset(asset) {
74 try {
75 jsiiDeprecationWarnings._aws_cdk_core_FileAssetSource(asset);
76 }
77 catch (error) {
78 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
79 Error.captureStackTrace(error, this.addFileAsset);
80 }
81 throw error;
82 }
83 _shared_1.assertBound(this.stack);
84 // Backwards compatibility hack. We have a number of conflicting goals here:
85 //
86 // - We want put the actual logic in this class
87 // - We ALSO want to keep supporting people overriding Stack.addFileAsset (for backwards compatibility,
88 // because that mechanism is currently used to make CI/CD scenarios work)
89 // - We ALSO want to allow both entry points from user code (our own framework
90 // code will always call stack.deploymentMechanism.addFileAsset() but existing users
91 // may still be calling `stack.addFileAsset()` directly.
92 //
93 // Solution: delegate call to the stack, but if the stack delegates back to us again
94 // then do the actual logic.
95 //
96 // @deprecated: this can be removed for v2
97 if (this.cycle) {
98 return this.doAddFileAsset(asset);
99 }
100 this.cycle = true;
101 try {
102 const stack = this.stack;
103 return withoutDeprecationWarnings(() => stack.addFileAsset(asset));
104 }
105 finally {
106 this.cycle = false;
107 }
108 }
109 addDockerImageAsset(asset) {
110 try {
111 jsiiDeprecationWarnings._aws_cdk_core_DockerImageAssetSource(asset);
112 }
113 catch (error) {
114 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
115 Error.captureStackTrace(error, this.addDockerImageAsset);
116 }
117 throw error;
118 }
119 _shared_1.assertBound(this.stack);
120 // See `addFileAsset` for explanation.
121 // @deprecated: this can be removed for v2
122 if (this.cycle) {
123 return this.doAddDockerImageAsset(asset);
124 }
125 this.cycle = true;
126 try {
127 const stack = this.stack;
128 return withoutDeprecationWarnings(() => stack.addDockerImageAsset(asset));
129 }
130 finally {
131 this.cycle = false;
132 }
133 }
134 /**
135 * Synthesize the associated stack to the session
136 */
137 synthesize(session) {
138 try {
139 jsiiDeprecationWarnings._aws_cdk_core_ISynthesisSession(session);
140 }
141 catch (error) {
142 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
143 Error.captureStackTrace(error, this.synthesize);
144 }
145 throw error;
146 }
147 _shared_1.assertBound(this.stack);
148 this.synthesizeStackTemplate(this.stack, session);
149 // Just do the default stuff, nothing special
150 this.emitStackArtifact(this.stack, session);
151 }
152 doAddDockerImageAsset(asset) {
153 _shared_1.assertBound(this.stack);
154 // check if we have an override from context
155 const repositoryNameOverride = this.stack.node.tryGetContext(ASSETS_ECR_REPOSITORY_NAME_OVERRIDE_CONTEXT_KEY);
156 const repositoryName = asset.repositoryName ?? repositoryNameOverride ?? ASSETS_ECR_REPOSITORY_NAME;
157 const imageTag = asset.sourceHash;
158 const assetId = asset.sourceHash;
159 // only add every image (identified by source hash) once for each stack that uses it.
160 if (!this.addedImageAssets.has(assetId)) {
161 if (!asset.directoryName) {
162 throw new Error(`LegacyStackSynthesizer does not support this type of file asset: ${JSON.stringify(asset)}`);
163 }
164 const metadata = {
165 repositoryName,
166 imageTag,
167 id: assetId,
168 packaging: 'container-image',
169 path: asset.directoryName,
170 sourceHash: asset.sourceHash,
171 buildArgs: asset.dockerBuildArgs,
172 target: asset.dockerBuildTarget,
173 file: asset.dockerFile,
174 networkMode: asset.networkMode,
175 platform: asset.platform,
176 };
177 this.stack.node.addMetadata(cxschema.ArtifactMetadataEntryType.ASSET, metadata);
178 this.addedImageAssets.add(assetId);
179 }
180 return {
181 imageUri: `${this.stack.account}.dkr.ecr.${this.stack.region}.${this.stack.urlSuffix}/${repositoryName}:${imageTag}`,
182 repositoryName,
183 };
184 }
185 doAddFileAsset(asset) {
186 _shared_1.assertBound(this.stack);
187 let params = this.assetParameters.node.tryFindChild(asset.sourceHash);
188 if (!params) {
189 params = new asset_parameters_1.FileAssetParameters(this.assetParameters, asset.sourceHash);
190 if (!asset.fileName || !asset.packaging) {
191 throw new Error(`LegacyStackSynthesizer does not support this type of file asset: ${JSON.stringify(asset)}`);
192 }
193 const metadata = {
194 path: asset.fileName,
195 id: asset.sourceHash,
196 packaging: asset.packaging,
197 sourceHash: asset.sourceHash,
198 s3BucketParameter: params.bucketNameParameter.logicalId,
199 s3KeyParameter: params.objectKeyParameter.logicalId,
200 artifactHashParameter: params.artifactHashParameter.logicalId,
201 };
202 this.stack.node.addMetadata(cxschema.ArtifactMetadataEntryType.ASSET, metadata);
203 }
204 const bucketName = params.bucketNameParameter.valueAsString;
205 // key is prefix|postfix
206 const encodedKey = params.objectKeyParameter.valueAsString;
207 const s3Prefix = cfn_fn_1.Fn.select(0, cfn_fn_1.Fn.split(cxapi.ASSET_PREFIX_SEPARATOR, encodedKey));
208 const s3Filename = cfn_fn_1.Fn.select(1, cfn_fn_1.Fn.split(cxapi.ASSET_PREFIX_SEPARATOR, encodedKey));
209 const objectKey = `${s3Prefix}${s3Filename}`;
210 const httpUrl = `https://s3.${this.stack.region}.${this.stack.urlSuffix}/${bucketName}/${objectKey}`;
211 const s3ObjectUrl = `s3://${bucketName}/${objectKey}`;
212 return { bucketName, objectKey, httpUrl, s3ObjectUrl, s3Url: httpUrl };
213 }
214 get assetParameters() {
215 _shared_1.assertBound(this.stack);
216 if (!this._assetParameters) {
217 this._assetParameters = new construct_compat_1.Construct(this.stack, 'AssetParameters');
218 }
219 return this._assetParameters;
220 }
221}
222exports.LegacyStackSynthesizer = LegacyStackSynthesizer;
223_a = JSII_RTTI_SYMBOL_1;
224LegacyStackSynthesizer[_a] = { fqn: "@aws-cdk/core.LegacyStackSynthesizer", version: "1.204.0" };
225function withoutDeprecationWarnings(block) {
226 const orig = process.env.JSII_DEPRECATED;
227 process.env.JSII_DEPRECATED = 'quiet';
228 try {
229 return block();
230 }
231 finally {
232 process.env.JSII_DEPRECATED = orig;
233 }
234}
235//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGVnYWN5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibGVnYWN5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDJEQUEyRDtBQUMzRCx5Q0FBeUM7QUFFekMsc0NBQStCO0FBQy9CLDBEQUFtRTtBQUNuRSxrRUFBa0U7QUFFbEUsdUNBQXdDO0FBQ3hDLDJEQUF1RDtBQUV2RDs7OztHQUlHO0FBQ0gsTUFBTSwwQkFBMEIsR0FBRyxnQkFBZ0IsQ0FBQztBQUVwRDs7Ozs7R0FLRztBQUNILE1BQU0sK0NBQStDLEdBQUcsNEJBQTRCLENBQUM7QUFFckY7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gsTUFBYSxzQkFBdUIsU0FBUSxvQ0FBZ0I7SUFBNUQ7O1FBRVUsVUFBSyxHQUFHLEtBQUssQ0FBQztRQU90Qjs7O1dBR0c7UUFDYyxxQkFBZ0IsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0tBeUp2RDtJQXZKUSxJQUFJLENBQUMsS0FBWTs7Ozs7Ozs7OztRQUN0QixJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFO1lBQzVCLE1BQU0sSUFBSSxLQUFLLENBQUMsd0dBQXdHLENBQUMsQ0FBQztTQUMzSDtRQUNELElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0tBQ3BCO0lBRU0sWUFBWSxDQUFDLEtBQXNCOzs7Ozs7Ozs7O1FBQ3hDLHFCQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXhCLDRFQUE0RTtRQUM1RSxFQUFFO1FBQ0YsK0NBQStDO1FBQy9DLHVHQUF1RztRQUN2Ryx5RUFBeUU7UUFDekUsOEVBQThFO1FBQzlFLG9GQUFvRjtRQUNwRix3REFBd0Q7UUFDeEQsRUFBRTtRQUNGLG9GQUFvRjtRQUNwRiw0QkFBNEI7UUFDNUIsRUFBRTtRQUNGLDBDQUEwQztRQUMxQyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDZCxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFD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S0FBSyxFQUFFLGlCQUFpQixDQUFDLENBQUM7U0FDdEU7UUFDRCxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztLQUM5Qjs7QUFyS0gsd0RBc0tDOzs7QUFFRCxTQUFTLDBCQUEwQixDQUFJLEtBQWM7SUFDbkQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUM7SUFDekMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLEdBQUcsT0FBTyxDQUFDO0lBQ3RDLElBQUk7UUFDRixPQUFPLEtBQUssRUFBRSxDQUFDO0tBQ2hCO1lBQVM7UUFDUixPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7S0FDcEM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3hzY2hlbWEgZnJvbSAnQGF3cy1jZGsvY2xvdWQtYXNzZW1ibHktc2NoZW1hJztcbmltcG9ydCAqIGFzIGN4YXBpIGZyb20gJ0Bhd3MtY2RrL2N4LWFwaSc7XG5pbXBvcnQgeyBEb2NrZXJJbWFnZUFzc2V0TG9jYXRpb24sIERvY2tlckltYWdlQXNzZXRTb3VyY2UsIEZpbGVBc3NldExvY2F0aW9uLCBGaWxlQXNzZXRTb3VyY2UgfSBmcm9tICcuLi9hc3NldHMnO1xuaW1wb3J0IHsgRm4gfSBmcm9tICcuLi9jZm4tZm4nO1xuaW1wb3J0IHsgQ29uc3RydWN0LCBJU3ludGhlc2lzU2Vzc2lvbiB9IGZyb20gJy4uL2NvbnN0cnVjdC1jb21wYXQnO1xuaW1wb3J0IHsgRmlsZUFzc2V0UGFyYW1ldGVycyB9IGZyb20gJy4uL3ByaXZhdGUvYXNzZXQtcGFyYW1ldGVycyc7XG5pbXBvcnQgeyBTdGFjayB9IGZyb20gJy4uL3N0YWNrJztcbmltcG9ydCB7IGFzc2VydEJvdW5kIH0gZnJvbSAnLi9fc2hhcmVkJztcbmltcG9ydCB7IFN0YWNrU3ludGhlc2l6ZXIgfSBmcm9tICcuL3N0YWNrLXN5bnRoZXNpemVyJztcblxuLyoqXG4gKiBUaGUgd2VsbC1rbm93biBuYW1lIGZvciB0aGUgZG9ja2VyIGltYWdlIGFzc2V0IEVDUiByZXBvc2l0b3J5LiBBbGwgZG9ja2VyXG4gKiBpbWFnZSBhc3NldHMgd2lsbCBiZSBwdXNoZWQgaW50byB0aGlzIHJlcG9zaXRvcnkgd2l0aCBhbiBpbWFnZSB0YWcgYmFzZWQgb25cbiAqIHRoZSBzb3VyY2UgaGFzaC5cbiAqL1xuY29uc3QgQVNTRVRTX0VDUl9SRVBPU0lUT1JZX05BTUUgPSAnYXdzLWNkay9hc3NldHMnO1xuXG4vKipcbiAqIFRoaXMgYWxsb3dzIHVzZXJzIHRvIHdvcmsgYXJvdW5kIHRoZSBmYWN0IHRoYXQgdGhlIEVDUiByZXBvc2l0b3J5IGlzXG4gKiAoY3VycmVudGx5KSBub3QgY29uZmlndXJhYmxlIGJ5IHNldHRpbmcgdGhpcyBjb250ZXh0IGtleSB0byB0aGVpciBkZXNpcmVkXG4gKiByZXBvc2l0b3J5IG5hbWUuIFRoZSBDTEkgd2lsbCBhdXRvLWNyZWF0ZSB0aGlzIEVDUiByZXBvc2l0b3J5IGlmIGl0J3Mgbm90XG4gKiBhbHJlYWR5IGNyZWF0ZWQuXG4gKi9cbmNvbnN0IEFTU0VUU19FQ1JfUkVQT1NJVE9SWV9OQU1FX09WRVJSSURFX0NPTlRFWFRfS0VZID0gJ2Fzc2V0cy1lY3ItcmVwb3NpdG9yeS1uYW1lJztcblxuLyoqXG4gKiBVc2UgdGhlIENESyBjbGFzc2ljIHdheSBvZiByZWZlcmVuY2luZyBhc3NldHNcbiAqXG4gKiBUaGlzIHN5bnRoZXNpemVyIHdpbGwgZ2VuZXJhdGUgQ2xvdWRGb3JtYXRpb24gcGFyYW1ldGVycyBmb3IgZXZlcnkgcmVmZXJlbmNlZFxuICogYXNzZXQsIGFuZCB1c2UgdGhlIENMSSdzIGN1cnJlbnQgY3JlZGVudGlhbHMgdG8gZGVwbG95IHRoZSBzdGFjay5cbiAqXG4gKiAtIEl0IGRvZXMgbm90IHN1cHBvcnQgY3Jvc3MtYWNjb3VudCBkZXBsb3ltZW50ICh0aGUgQ0xJIG11c3QgaGF2ZSBjcmVkZW50aWFsc1xuICogICB0byB0aGUgYWNjb3VudCB5b3UgYXJlIHRyeWluZyB0byBkZXBsb3kgdG8pLlxuICogLSBJdCBjYW5ub3QgYmUgdXNlZCB3aXRoICoqQ0RLIFBpcGVsaW5lcyoqLiBUbyBkZXBsb3kgdXNpbmcgQ0RLIFBpcGVsaW5lcyxcbiAqICAgeW91IG11c3QgdXNlIHRoZSBgRGVmYXVsdFN0YWNrU3ludGhlc2l6ZXJgLlxuICogLSBFYWNoIGFzc2V0IHdpbGwgdGFrZSB1cCBhIENsb3VkRm9ybWF0aW9uIFBhcmFtZXRlciBpbiB5b3VyIHRlbXBsYXRlLiBLZWVwIGluXG4gKiAgIG1pbmQgdGhhdCB0aGVyZSBpcyBhIG1heGltdW0gb2YgMjAwIHBhcmFtZXRlcnMgaW4gYSBDbG91ZEZvcm1hdGlvbiB0ZW1wbGF0ZS5cbiAqICAgVG8gdXNlIGRldGVybWluc3RpYyBhc3NldCBsb2NhdGlvbnMgaW5zdGVhZCwgdXNlIGBDbGlDcmVkZW50aWFsc1N0YWNrU3ludGhlc2l6ZXJgLlxuICpcbiAqIEJlIGF3YXJlIHRoYXQgeW91ciBDTEkgY3JlZGVudGlhbHMgbXVzdCBiZSB2YWxpZCBmb3IgdGhlIGR1cmF0aW9uIG9mIHRoZVxuICogZW50aXJlIGRlcGxveW1lbnQuIElmIHlvdSBhcmUgdXNpbmcgc2Vzc2lvbiBjcmVkZW50aWFscywgbWFrZSBzdXJlIHRoZVxuICogc2Vzc2lvbiBsaWZldGltZSBpcyBsb25nIGVub3VnaC5cbiAqXG4gKiBUaGlzIGlzIHRoZSBvbmx5IFN0YWNrU3ludGhlc2l6ZXIgdGhhdCBzdXBwb3J0cyBjdXN0b21pemluZyBhc3NldCBiZWhhdmlvclxuICogYnkgb3ZlcnJpZGluZyBgU3RhY2suYWRkRmlsZUFzc2V0KClgIGFuZCBgU3RhY2suYWRkRG9ja2VySW1hZ2VBc3NldCgpYC5cbiAqL1xuZXhwb3J0IGNsYXNzIExlZ2FjeVN0YWNrU3ludGhlc2l6ZXIgZXh0ZW5kcyBTdGFja1N5bnRoZXNpemVyIHtcbiAgcHJpdmF0ZSBzdGFjaz86IFN0YWNrO1xuICBwcml2YXRlIGN5Y2xlID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEluY2x1ZGVzIGFsbCBwYXJhbWV0ZXJzIHN5bnRoZXNpemVkIGZvciBhc3NldHMgKGxhenkpLlxuICAgKi9cbiAgcHJpdmF0ZSBfYXNzZXRQYXJhbWV0ZXJzPzogQ29uc3RydWN0O1xuXG4gIC8qKlxuICAgKiBUaGUgaW1hZ2UgSUQgb2YgYWxsIHRoZSBkb2NrZXIgaW1hZ2UgYXNzZXRzIHRoYXQgd2VyZSBhbHJlYWR5IGFkZGVkIHRvIHRoaXNcbiAgICogc3RhY2sgKHRvIGF2b2lkIGR1cGxpY2F0aW9uKS5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgYWRkZWRJbWFnZUFzc2V0cyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gIHB1YmxpYyBiaW5kKHN0YWNrOiBTdGFjayk6IHZvaWQge1xuICAgIGlmICh0aGlzLnN0YWNrICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQSBTdGFja1N5bnRoZXNpemVyIGNhbiBvbmx5IGJlIHVzZWQgZm9yIG9uZSBTdGFjazogY3JlYXRlIGEgbmV3IGluc3RhbmNlIHRvIHVzZSB3aXRoIGEgZGlmZmVyZW50IFN0YWNrJyk7XG4gICAgfVxuICAgIHRoaXMuc3RhY2sgPSBzdGFjaztcbiAgfVxuXG4gIHB1YmxpYyBhZGRGaWxlQXNzZXQoYXNzZXQ6IEZpbGVBc3NldFNvdXJjZSk6IEZpbGVBc3NldExvY2F0aW9uIHtcbiAgICBhc3NlcnRCb3VuZCh0aGlzLnN0YWNrKTtcblxuICAgIC8vIEJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IGhhY2suIFdlIGhhdmUgYSBudW1iZXIgb2YgY29uZmxpY3RpbmcgZ29hbHMgaGVyZTpcbiAgICAvL1xuICAgIC8vIC0gV2Ugd2FudCBwdXQgdGhlIGFjdHVhbCBsb2dpYyBpbiB0aGlzIGNsYXNzXG4gICAgLy8gLSBXZSBBTFNPIHdhbnQgdG8ga2VlcCBzdXBwb3J0aW5nIHBlb3BsZSBvdmVycmlkaW5nIFN0YWNrLmFkZEZpbGVBc3NldCAoZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LFxuICAgIC8vIGJlY2F1c2UgdGhhdCBtZWNoYW5pc20gaXMgY3VycmVudGx5IHVzZWQgdG8gbWFrZSBDSS9DRCBzY2VuYXJpb3Mgd29yaylcbiAgICAvLyAtIFdlIEFMU08gd2FudCB0byBhbGxvdyBib3RoIGVudHJ5IHBvaW50cyBmcm9tIHVzZXIgY29kZSAob3VyIG93biBmcmFtZXdvcmtcbiAgICAvLyBjb2RlIHdpbGwgYWx3YXlzIGNhbGwgc3RhY2suZGVwbG95bWVudE1lY2hhbmlzbS5hZGRGaWxlQXNzZXQoKSBidXQgZXhpc3RpbmcgdXNlcnNcbiAgICAvLyBtYXkgc3RpbGwgYmUgY2FsbGluZyBgc3RhY2suYWRkRmlsZUFzc2V0KClgIGRpcmVjdGx5LlxuICAgIC8vXG4gICAgLy8gU29sdXRpb246IGRlbGVnYXRlIGNhbGwgdG8gdGhlIHN0YWNrLCBidXQgaWYgdGhlIHN0YWNrIGRlbGVnYXRlcyBiYWNrIHRvIHVzIGFnYWluXG4gICAgLy8gdGhlbiBkbyB0aGUgYWN0dWFsIGxvZ2ljLlxuICAgIC8vXG4gICAgLy8gQGRlcHJlY2F0ZWQ6IHRoaXMgY2FuIGJlIHJlbW92ZWQgZm9yIHYyXG4gICAgaWYgKHRoaXMuY3ljbGUpIHtcbiAgICAgIHJldHVybiB0aGlzLmRvQWRkRmlsZUFzc2V0KGFzc2V0KTtcbiAgICB9XG4gICAgdGhpcy5jeWNsZSA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0YWNrID0gdGhpcy5zdGFjaztcbiAgICAgIHJldHVybiB3aXRob3V0RGVwcmVjYXRpb25XYXJuaW5ncygoKSA9PiBzdGFjay5hZGRGaWxlQXNzZXQoYXNzZXQpKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5jeWNsZSA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhZGREb2NrZXJJbWFnZUFzc2V0KGFzc2V0OiBEb2NrZXJJbWFnZUFzc2V0U291cmNlKTogRG9ja2VySW1hZ2VBc3NldExvY2F0aW9uIHtcbiAgICBhc3NlcnRCb3VuZCh0aGlzLnN0YWNrKTtcblxuICAgIC8vIFNlZSBgYWRkRmlsZUFzc2V0YCBmb3IgZXhwbGFuYXRpb24uXG4gICAgLy8gQGRlcHJlY2F0ZWQ6IHRoaXMgY2FuIGJlIHJlbW92ZWQgZm9yIHYyXG4gICAgaWYgKHRoaXMuY3ljbGUpIHtcbiAgICAgIHJldHVybiB0aGlzLmRvQWRkRG9ja2VySW1hZ2VBc3NldChhc3NldCk7XG4gICAgfVxuICAgIHRoaXMuY3ljbGUgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzdGFjayA9IHRoaXMuc3RhY2s7XG4gICAgICByZXR1cm4gd2l0aG91dERlcHJlY2F0aW9uV2FybmluZ3MoKCkgPT4gc3RhY2suYWRkRG9ja2VySW1hZ2VBc3NldChhc3NldCkpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmN5Y2xlID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN5bnRoZXNpemUgdGhlIGFzc29jaWF0ZWQgc3RhY2sgdG8gdGhlIHNlc3Npb25cbiAgICovXG4gIHB1YmxpYyBzeW50aGVzaXplKHNlc3Npb246IElTeW50aGVzaXNTZXNzaW9uKTogdm9pZCB7XG4gICAgYXNzZXJ0Qm91bmQodGhpcy5zdGFjayk7XG5cbiAgICB0aGlzLnN5bnRoZXNpemVTdGFja1RlbXBsYXRlKHRoaXMuc3RhY2ssIHNlc3Npb24pO1xuXG4gICAgLy8gSnVzdCBkbyB0aGUgZGVmYXVsdCBzdHVmZiwgbm90aGluZyBzcGVjaWFsXG4gICAgdGhpcy5lbWl0U3RhY2tBcnRpZmFjdCh0aGlzLnN0YWNrLCBzZXNzaW9uKTtcbiAgfVxuXG4gIHByaXZhdGUgZG9BZGREb2NrZXJJbWFnZUFzc2V0KGFzc2V0OiBEb2NrZXJJbWFnZUFzc2V0U291cmNlKTogRG9ja2VySW1hZ2VBc3NldExvY2F0aW9uIHtcbiAgICBhc3NlcnRCb3VuZCh0aGlzLnN0YWNrKTtcblxuICAgIC8vIGNoZWNrIGlmIHdlIGhhdmUgYW4gb3ZlcnJpZGUgZnJvbSBjb250ZXh0XG4gICAgY29uc3QgcmVwb3NpdG9yeU5hbWVPdmVycmlkZSA9IHRoaXMuc3RhY2subm9kZS50cnlHZXRDb250ZXh0KEFTU0VUU19FQ1JfUkVQT1NJVE9SWV9OQU1FX09WRVJSSURFX0NPTlRFWFRfS0VZKTtcbiAgICBjb25zdCByZXBvc2l0b3J5TmFtZSA9IGFzc2V0LnJlcG9zaXRvcnlOYW1lID8/IHJlcG9zaXRvcnlOYW1lT3ZlcnJpZGUgPz8gQVNTRVRTX0VDUl9SRVBPU0lUT1JZX05BTUU7XG4gICAgY29uc3QgaW1hZ2VUYWcgPSBhc3NldC5zb3VyY2VIYXNoO1xuICAgIGNvbnN0IGFzc2V0SWQgPSBhc3NldC5zb3VyY2VIYXNoO1xuXG4gICAgLy8gb25seSBhZGQgZXZlcnkgaW1hZ2UgKGlkZW50aWZpZWQgYnkgc291cmNlIGhhc2gpIG9uY2UgZm9yIGVhY2ggc3RhY2sgdGhhdCB1c2VzIGl0LlxuICAgIGlmICghdGhpcy5hZGRlZEltYWdlQXNzZXRzLmhhcyhhc3NldElkKSkge1xuICAgICAgaWYgKCFhc3NldC5kaXJlY3RvcnlOYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTGVnYWN5U3RhY2tTeW50aGVzaXplciBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgdHlwZSBvZiBmaWxlIGFzc2V0OiAke0pTT04uc3RyaW5naWZ5KGFzc2V0KX1gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWV0YWRhdGE6IGN4c2NoZW1hLkNvbnRhaW5lckltYWdlQXNzZXRNZXRhZGF0YUVudHJ5ID0ge1xuICAgICAgICByZXBvc2l0b3J5TmFtZSxcbiAgICAgICAgaW1hZ2VUYWcsXG4gICAgICAgIGlkOiBhc3NldElkLFxuICAgICAgICBwYWNrYWdpbmc6ICdjb250YWluZXItaW1hZ2UnLFxuICAgICAgICBwYXRoOiBhc3NldC5kaXJlY3RvcnlOYW1lLFxuICAgICAgICBzb3VyY2VIYXNoOiBhc3NldC5zb3VyY2VIYXNoLFxuICAgICAgICBidWlsZEFyZ3M6IGFzc2V0LmRvY2tlckJ1aWxkQXJncyxcbiAgICAgICAgdGFyZ2V0OiBhc3NldC5kb2NrZXJCdWlsZFRhcmdldCxcbiAgICAgICAgZmlsZTogYXNzZXQuZG9ja2VyRmlsZSxcbiAgICAgICAgbmV0d29ya01vZGU6IGFzc2V0Lm5ldHdvcmtNb2RlLFxuICAgICAgICBwbGF0Zm9ybTogYXNzZXQucGxhdGZvcm0sXG4gICAgICB9O1xuXG4gICAgICB0aGlzLnN0YWNrLm5vZGUuYWRkTWV0YWRhdGEoY3hzY2hlbWEuQXJ0aWZhY3RNZXRhZGF0YUVudHJ5VHlwZS5BU1NFVCwgbWV0YWRhdGEpO1xuICAgICAgdGhpcy5hZGRlZEltYWdlQXNzZXRzLmFkZChhc3NldElkKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgaW1hZ2VVcmk6IGAke3RoaXMuc3RhY2suYWNjb3VudH0uZGtyLmVjci4ke3RoaXMuc3RhY2sucmVnaW9ufS4ke3RoaXMuc3RhY2sudXJsU3VmZml4fS8ke3JlcG9zaXRvcnlOYW1lfToke2ltYWdlVGFnfWAsXG4gICAgICByZXBvc2l0b3J5TmFtZSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBkb0FkZEZpbGVBc3NldChhc3NldDogRmlsZUFzc2V0U291cmNlKTogRmlsZUFzc2V0TG9jYXRpb24ge1xuICAgIGFzc2VydEJvdW5kKHRoaXMuc3RhY2spO1xuXG4gICAgbGV0IHBhcmFtcyA9IHRoaXMuYXNzZXRQYXJhbWV0ZXJzLm5vZGUudHJ5RmluZENoaWxkKGFzc2V0LnNvdXJjZUhhc2gpIGFzIEZpbGVBc3NldFBhcmFtZXRlcnM7XG4gICAgaWYgKCFwYXJhbXMpIHtcbiAgICAgIHBhcmFtcyA9IG5ldyBGaWxlQXNzZXRQYXJhbWV0ZXJzKHRoaXMuYXNzZXRQYXJhbWV0ZXJzLCBhc3NldC5zb3VyY2VIYXNoKTtcblxuICAgICAgaWYgKCFhc3NldC5maWxlTmFtZSB8fCAhYXNzZXQucGFja2FnaW5nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTGVnYWN5U3RhY2tTeW50aGVzaXplciBkb2VzIG5vdCBzdXBwb3J0IHRoaXMgdHlwZSBvZiBmaWxlIGFzc2V0OiAke0pTT04uc3RyaW5naWZ5KGFzc2V0KX1gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWV0YWRhdGE6IGN4c2NoZW1hLkZpbGVBc3NldE1ldGFkYXRhRW50cnkgPSB7XG4gICAgICAgIHBhdGg6IGFzc2V0LmZpbGVOYW1lLFxuICAgICAgICBpZDogYXNzZXQuc291cmNlSGFzaCxcbiAgICAgICAgcGFja2FnaW5nOiBhc3NldC5wYWNrYWdpbmcsXG4gICAgICAgIHNvdXJjZUhhc2g6IGFzc2V0LnNvdXJjZUhhc2gsXG5cbiAgICAgICAgczNCdWNrZXRQYXJhbWV0ZXI6IHBhcmFtcy5idWNrZXROYW1lUGFyYW1ldGVyLmxvZ2ljYWxJZCxcbiAgICAgICAgczNLZXlQYXJhbWV0ZXI6IHBhcmFtcy5vYmplY3RLZXlQYXJhbWV0ZXIubG9naWNhbElkLFxuICAgICAgICBhcnRpZmFjdEhhc2hQYXJhbWV0ZXI6IHBhcmFtcy5hcnRpZmFjdEhhc2hQYXJhbWV0ZXIubG9naWNhbElkLFxuICAgICAgfTtcblxuICAgICAgdGhpcy5zdGFjay5ub2RlLmFkZE1ldGFkYXRhKGN4c2NoZW1hLkFydGlmYWN0TWV0YWRhdGFFbnRyeVR5cGUuQVNTRVQsIG1ldGFkYXRhKTtcbiAgICB9XG5cbiAgICBjb25zdCBidWNrZXROYW1lID0gcGFyYW1zLmJ1Y2tldE5hbWVQYXJhbWV0ZXIudmFsdWVBc1N0cmluZztcblxuICAgIC8vIGtleSBpcyBwcmVmaXh8cG9zdGZpeFxuICAgIGNvbnN0IGVuY29kZWRLZXkgPSBwYXJhbXMub2JqZWN0S2V5UGFyYW1ldGVyLnZhbHVlQXNTdHJpbmc7XG5cbiAgICBjb25zdCBzM1ByZWZpeCA9IEZuLnNlbGVjdCgwLCBGbi5zcGxpdChjeGFwaS5BU1NFVF9QUkVGSVhfU0VQQVJBVE9SLCBlbmNvZGVkS2V5KSk7XG4gICAgY29uc3QgczNGaWxlbmFtZSA9IEZuLnNlbGVjdCgxLCBGbi5zcGxpdChjeGFwaS5BU1NFVF9QUkVGSVhfU0VQQVJBVE9SLCBlbmNvZGVkS2V5KSk7XG4gICAgY29uc3Qgb2JqZWN0S2V5ID0gYCR7czNQcmVmaXh9JHtzM0ZpbGVuYW1lfWA7XG5cbiAgICBjb25zdCBodHRwVXJsID0gYGh0dHBzOi8vczMuJHt0aGlzLnN0YWNrLnJlZ2lvbn0uJHt0aGlzLnN0YWNrLnVybFN1ZmZpeH0vJHtidWNrZXROYW1lfS8ke29iamVjdEtleX1gO1xuICAgIGNvbnN0IHMzT2JqZWN0VXJsID0gYHMzOi8vJHtidWNrZXROYW1lfS8ke29iamVjdEtleX1gO1xuXG4gICAgcmV0dXJuIHsgYnVja2V0TmFtZSwgb2JqZWN0S2V5LCBodHRwVXJsLCBzM09iamVjdFVybCwgczNVcmw6IGh0dHBVcmwgfTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IGFzc2V0UGFyYW1ldGVycygpIHtcbiAgICBhc3NlcnRCb3VuZCh0aGlzLnN0YWNrKTtcblxuICAgIGlmICghdGhpcy5fYXNzZXRQYXJhbWV0ZXJzKSB7XG4gICAgICB0aGlzLl9hc3NldFBhcmFtZXRlcnMgPSBuZXcgQ29uc3RydWN0KHRoaXMuc3RhY2ssICdBc3NldFBhcmFtZXRlcnMnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2Fzc2V0UGFyYW1ldGVycztcbiAgfVxufVxuXG5mdW5jdGlvbiB3aXRob3V0RGVwcmVjYXRpb25XYXJuaW5nczxBPihibG9jazogKCkgPT4gQSk6IEEge1xuICBjb25zdCBvcmlnID0gcHJvY2Vzcy5lbnYuSlNJSV9ERVBSRUNBVEVEO1xuICBwcm9jZXNzLmVudi5KU0lJX0RFUFJFQ0FURUQgPSAncXVpZXQnO1xuICB0cnkge1xuICAgIHJldHVybiBibG9jaygpO1xuICB9IGZpbmFsbHkge1xuICAgIHByb2Nlc3MuZW52LkpTSUlfREVQUkVDQVRFRCA9IG9yaWc7XG4gIH1cbn1cbiJdfQ==
\No newline at end of file