UNPKG

21.7 kBJavaScriptView Raw
1"use strict";
2var _a;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.mergeBuildSpecs = exports.BuildSpec = void 0;
5const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6const core_1 = require("@aws-cdk/core");
7const yaml_cfn = require("./private/yaml-cfn");
8/**
9 * BuildSpec for CodeBuild projects
10 */
11class BuildSpec {
12 constructor() {
13 }
14 static fromObject(value) {
15 return new ObjectBuildSpec(value);
16 }
17 /**
18 * Create a buildspec from an object that will be rendered as YAML in the resulting CloudFormation template.
19 *
20 * @param value the object containing the buildspec that will be rendered as YAML
21 */
22 static fromObjectToYaml(value) {
23 return new YamlBuildSpec(value);
24 }
25 /**
26 * Use a file from the source as buildspec
27 *
28 * Use this if you want to use a file different from 'buildspec.yml'`
29 */
30 static fromSourceFilename(filename) {
31 return new FilenameBuildSpec(filename);
32 }
33}
34exports.BuildSpec = BuildSpec;
35_a = JSII_RTTI_SYMBOL_1;
36BuildSpec[_a] = { fqn: "@aws-cdk/aws-codebuild.BuildSpec", version: "1.181.1" };
37/**
38 * BuildSpec that just returns the input unchanged
39 */
40class FilenameBuildSpec extends BuildSpec {
41 constructor(filename) {
42 super();
43 this.filename = filename;
44 this.isImmediate = false;
45 }
46 toBuildSpec() {
47 return this.filename;
48 }
49 toString() {
50 return `<buildspec file: ${this.filename}>`;
51 }
52}
53/**
54 * BuildSpec that understands about structure
55 */
56class ObjectBuildSpec extends BuildSpec {
57 constructor(spec) {
58 super();
59 this.spec = spec;
60 this.isImmediate = true;
61 }
62 toBuildSpec() {
63 // We have to pretty-print the buildspec, otherwise
64 // CodeBuild will not recognize it as an inline buildspec.
65 return core_1.Lazy.uncachedString({
66 produce: (ctx) => core_1.Stack.of(ctx.scope).toJsonString(this.spec, 2),
67 });
68 }
69}
70/**
71 * BuildSpec that exports into YAML format
72 */
73class YamlBuildSpec extends BuildSpec {
74 constructor(spec) {
75 super();
76 this.spec = spec;
77 this.isImmediate = true;
78 }
79 toBuildSpec() {
80 return yaml_cfn.serialize(this.spec);
81 }
82}
83/**
84 * Merge two buildspecs into a new BuildSpec by doing a deep merge
85 *
86 * We decided to disallow merging of artifact specs, which is
87 * actually impossible since we can't merge two buildspecs with a
88 * single primary output into a buildspec with multiple outputs.
89 * In case of multiple outputs they must have identifiers but we won't have that information.
90 *
91 * In case of test reports we replace the whole object with the RHS (instead of recursively merging)
92*/
93function mergeBuildSpecs(lhs, rhs) {
94 if (!(lhs instanceof ObjectBuildSpec) || !(rhs instanceof ObjectBuildSpec)) {
95 throw new Error('Can only merge buildspecs created using BuildSpec.fromObject()');
96 }
97 if (lhs.spec.version === '0.1') {
98 throw new Error('Cannot extend buildspec at version "0.1". Set the version to "0.2" or higher instead.');
99 }
100 if (lhs.spec.artifacts && rhs.spec.artifacts) {
101 // We decided to disallow merging of artifact specs, which is
102 // actually impossible since we can't merge two buildspecs with a
103 // single primary output into a buildspec with multiple outputs.
104 // In case of multiple outputs they must have identifiers but we won't have that information.
105 throw new Error('Only one build spec is allowed to specify artifacts.');
106 }
107 const lhsSpec = JSON.parse(JSON.stringify(lhs.spec));
108 const rhsSpec = JSON.parse(JSON.stringify(rhs.spec));
109 normalizeSpec(lhsSpec);
110 normalizeSpec(rhsSpec);
111 const merged = mergeDeep(lhsSpec, rhsSpec);
112 // In case of test reports we replace the whole object with the RHS (instead of recursively merging)
113 if (lhsSpec.reports && rhsSpec.reports) {
114 merged.reports = { ...lhsSpec.reports, ...rhsSpec.reports };
115 }
116 return new ObjectBuildSpec(merged);
117}
118exports.mergeBuildSpecs = mergeBuildSpecs;
119/*
120 * Normalizes the build spec
121 * The CodeBuild runtime allows fields that are defined as string[] to be strings
122 * and interprets them as singleton lists.
123 * When merging we need to normalize this to have the correct concat semantics
124 */
125function normalizeSpec(spec) {
126 if (spec.env && typeof spec.env['exported-variables'] === 'string') {
127 spec.env['exported-variables'] = [spec.env['exported-variables']];
128 }
129 for (const key in spec.phases) {
130 if (Object.prototype.hasOwnProperty.call(spec.phases, key)) {
131 normalizeSpecPhase(spec.phases[key]);
132 }
133 }
134 if (spec.reports) {
135 for (const key in spec.reports) {
136 if (Object.prototype.hasOwnProperty.call(spec.reports, key)) {
137 const report = spec.reports[key];
138 if (typeof report.files === 'string') {
139 report.files = [report.files];
140 }
141 }
142 }
143 }
144 if (spec.artifacts) {
145 if (typeof spec.artifacts.files === 'string') {
146 spec.artifacts.files = [spec.artifacts.files];
147 }
148 for (const key in spec.artifacts['secondary-artifacts']) {
149 if (Object.prototype.hasOwnProperty.call(spec.artifacts['secondary-artifacts'], key)) {
150 const secArtifact = spec.artifacts['secondary-artifacts'][key];
151 if (typeof secArtifact.files === 'string') {
152 secArtifact.files = [secArtifact.files];
153 }
154 }
155 }
156 }
157 if (spec.cache && typeof spec.cache.paths === 'string') {
158 spec.cache.paths = [spec.cache.paths];
159 }
160}
161function normalizeSpecPhase(phase) {
162 if (phase.commands && typeof phase.commands === 'string') {
163 phase.commands = [phase.commands];
164 }
165 if (phase.finally && typeof phase.finally === 'string') {
166 phase.finally = [phase.finally];
167 }
168}
169function mergeDeep(lhs, rhs) {
170 if (Array.isArray(lhs) && Array.isArray(rhs)) {
171 return [...lhs, ...rhs];
172 }
173 if (Array.isArray(lhs) || Array.isArray(rhs)) {
174 return rhs;
175 }
176 const isObject = (obj) => obj && typeof obj === 'object';
177 if (isObject(lhs) && isObject(rhs)) {
178 const ret = { ...lhs };
179 for (const k of Object.keys(rhs)) {
180 ret[k] = k in lhs ? mergeDeep(lhs[k], rhs[k]) : rhs[k];
181 }
182 return ret;
183 }
184 return rhs;
185}
186;
187//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQtc3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImJ1aWxkLXNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSx3Q0FBNkQ7QUFDN0QsK0NBQStDO0FBRS9DOztHQUVHO0FBQ0gsTUFBc0IsU0FBUztJQTRCN0I7S0FDQztJQTVCTSxNQUFNLENBQUMsVUFBVSxDQUFDLEtBQTZCO1FBQ3BELE9BQU8sSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDbkM7SUFFRDs7OztPQUlHO0lBQ0ksTUFBTSxDQUFDLGdCQUFnQixDQUFDLEtBQTZCO1FBQzFELE9BQU8sSUFBSSxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDakM7SUFFRDs7OztPQUlHO0lBQ0ksTUFBTSxDQUFDLGtCQUFrQixDQUFDLFFBQWdCO1FBQy9DLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztLQUN4Qzs7QUFyQkgsOEJBbUNDOzs7QUFFRDs7R0FFRztBQUNILE1BQU0saUJBQWtCLFNBQVEsU0FBUztJQUd2QyxZQUE2QixRQUFnQjtRQUMzQyxLQUFLLEVBQUUsQ0FBQztRQURtQixhQUFRLEdBQVIsUUFBUSxDQUFRO1FBRjdCLGdCQUFXLEdBQVksS0FBSyxDQUFDO0tBSTVDO0lBRU0sV0FBVztRQUNoQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7S0FDdEI7SUFFTSxRQUFRO1FBQ2IsT0FBTyxvQkFBb0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDO0tBQzdDO0NBQ0Y7QUFFRDs7R0FFRztBQUNILE1BQU0sZUFBZ0IsU0FBUSxTQUFTO0lBR3JDLFlBQTRCLElBQTRCO1FBQ3RELEtBQUssRUFBRSxDQUFDO1FBRGtCLFNBQUksR0FBSixJQUFJLENBQXdCO1FBRnhDLGdCQUFXLEdBQVksSUFBSSxDQUFDO0tBSTNDO0lBRU0sV0FBVztRQUNoQixtREFBbUQ7UUFDbkQsMERBQTBEO1FBQzFELE9BQU8sV0FBSSxDQUFDLGNBQWMs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QUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ2hDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDeEQ7UUFDRCxPQUFPLEdBQUcsQ0FBQztLQUNaO0lBRUQsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQUEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IElSZXNvbHZlQ29udGV4dCwgTGF6eSwgU3RhY2sgfSBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCAqIGFzIHlhbWxfY2ZuIGZyb20gJy4vcHJpdmF0ZS95YW1sLWNmbic7XG5cbi8qKlxuICogQnVpbGRTcGVjIGZvciBDb2RlQnVpbGQgcHJvamVjdHNcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJ1aWxkU3BlYyB7XG4gIHB1YmxpYyBzdGF0aWMgZnJvbU9iamVjdCh2YWx1ZTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSk6IEJ1aWxkU3BlYyB7XG4gICAgcmV0dXJuIG5ldyBPYmplY3RCdWlsZFNwZWModmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIGJ1aWxkc3BlYyBmcm9tIGFuIG9iamVjdCB0aGF0IHdpbGwgYmUgcmVuZGVyZWQgYXMgWUFNTCBpbiB0aGUgcmVzdWx0aW5nIENsb3VkRm9ybWF0aW9uIHRlbXBsYXRlLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgdGhlIG9iamVjdCBjb250YWluaW5nIHRoZSBidWlsZHNwZWMgdGhhdCB3aWxsIGJlIHJlbmRlcmVkIGFzIFlBTUxcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbU9iamVjdFRvWWFtbCh2YWx1ZTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSk6IEJ1aWxkU3BlYyB7XG4gICAgcmV0dXJuIG5ldyBZYW1sQnVpbGRTcGVjKHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2UgYSBmaWxlIGZyb20gdGhlIHNvdXJjZSBhcyBidWlsZHNwZWNcbiAgICpcbiAgICogVXNlIHRoaXMgaWYgeW91IHdhbnQgdG8gdXNlIGEgZmlsZSBkaWZmZXJlbnQgZnJvbSAnYnVpbGRzcGVjLnltbCdgXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21Tb3VyY2VGaWxlbmFtZShmaWxlbmFtZTogc3RyaW5nKTogQnVpbGRTcGVjIHtcbiAgICByZXR1cm4gbmV3IEZpbGVuYW1lQnVpbGRTcGVjKGZpbGVuYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBidWlsZHNwZWMgaXMgZGlyZWN0bHkgYXZhaWxhYmxlIG9yIGRlZmVycmVkIHVudGlsIGJ1aWxkLXRpbWVcbiAgICovXG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSBpc0ltbWVkaWF0ZTogYm9vbGVhbjtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoKSB7XG4gIH1cblxuICAvKipcbiAgICogUmVuZGVyIHRoZSByZXByZXNlbnRlZCBCdWlsZFNwZWNcbiAgICovXG4gIHB1YmxpYyBhYnN0cmFjdCB0b0J1aWxkU3BlYygpOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQnVpbGRTcGVjIHRoYXQganVzdCByZXR1cm5zIHRoZSBpbnB1dCB1bmNoYW5nZWRcbiAqL1xuY2xhc3MgRmlsZW5hbWVCdWlsZFNwZWMgZXh0ZW5kcyBCdWlsZFNwZWMge1xuICBwdWJsaWMgcmVhZG9ubHkgaXNJbW1lZGlhdGU6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgcHVibGljIHRvQnVpbGRTcGVjKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZmlsZW5hbWU7XG4gIH1cblxuICBwdWJsaWMgdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIGA8YnVpbGRzcGVjIGZpbGU6ICR7dGhpcy5maWxlbmFtZX0+YDtcbiAgfVxufVxuXG4vKipcbiAqIEJ1aWxkU3BlYyB0aGF0IHVuZGVyc3RhbmRzIGFib3V0IHN0cnVjdHVyZVxuICovXG5jbGFzcyBPYmplY3RCdWlsZFNwZWMgZXh0ZW5kcyBCdWlsZFNwZWMge1xuICBwdWJsaWMgcmVhZG9ubHkgaXNJbW1lZGlhdGU6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSBzcGVjOiB7IFtrZXk6IHN0cmluZ106IGFueSB9KSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIHB1YmxpYyB0b0J1aWxkU3BlYygpOiBzdHJpbmcge1xuICAgIC8vIFdlIGhhdmUgdG8gcHJldHR5LXByaW50IHRoZSBidWlsZHNwZWMsIG90aGVyd2lzZVxuICAgIC8vIENvZGVCdWlsZCB3aWxsIG5vdCByZWNvZ25pemUgaXQgYXMgYW4gaW5saW5lIGJ1aWxkc3BlYy5cbiAgICByZXR1cm4gTGF6eS51bmNhY2hlZFN0cmluZyh7XG4gICAgICBwcm9kdWNlOiAoY3R4OiBJUmVzb2x2ZUNvbnRleHQpID0+XG4gICAgICAgIFN0YWNrLm9mKGN0eC5zY29wZSkudG9Kc29uU3RyaW5nKHRoaXMuc3BlYywgMiksXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBCdWlsZFNwZWMgdGhhdCBleHBvcnRzIGludG8gWUFNTCBmb3JtYXRcbiAqL1xuY2xhc3MgWWFtbEJ1aWxkU3BlYyBleHRlbmRzIEJ1aWxkU3BlYyB7XG4gIHB1YmxpYyByZWFkb25seSBpc0ltbWVkaWF0ZTogYm9vbGVhbiA9IHRydWU7XG5cbiAgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IHNwZWM6IHsgW2tleTogc3RyaW5nXTogYW55IH0pIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgcHVibGljIHRvQnVpbGRTcGVjKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHlhbWxfY2ZuLnNlcmlhbGl6ZSh0aGlzLnNwZWMpO1xuICB9XG59XG5cbi8qKlxuICogTWVyZ2UgdHdvIGJ1aWxkc3BlY3MgaW50byBhIG5ldyBCdWlsZFNwZWMgYnkgZG9pbmcgYSBkZWVwIG1lcmdlXG4gKlxuICogV2UgZGVjaWRlZCB0byBkaXNhbGxvdyBtZXJnaW5nIG9mIGFydGlmYWN0IHNwZWNzLCB3aGljaCBpc1xuICogYWN0dWFsbHkgaW1wb3NzaWJsZSBzaW5jZSB3ZSBjYW4ndCBtZXJnZSB0d28gYnVpbGRzcGVjcyB3aXRoIGFcbiAqIHNpbmdsZSBwcmltYXJ5IG91dHB1dCBpbnRvIGEgYnVpbGRzcGVjIHdpdGggbXVsdGlwbGUgb3V0cHV0cy5cbiAqIEluIGNhc2Ugb2YgbXVsdGlwbGUgb3V0cHV0cyB0aGV5IG11c3QgaGF2ZSBpZGVudGlmaWVycyBidXQgd2Ugd29uJ3QgaGF2ZSB0aGF0IGluZm9ybWF0aW9uLlxuICpcbiAqIEluIGNhc2Ugb2YgdGVzdCByZXBvcnRzIHdlIHJlcGxhY2UgdGhlIHdob2xlIG9iamVjdCB3aXRoIHRoZSBSSFMgKGluc3RlYWQgb2YgcmVjdXJzaXZlbHkgbWVyZ2luZylcbiovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VCdWlsZFNwZWNzKGxoczogQnVpbGRTcGVjLCByaHM6IEJ1aWxkU3BlYyk6IEJ1aWxkU3BlYyB7XG4gIGlmICghKGxocyBpbnN0YW5jZW9mIE9iamVjdEJ1aWxkU3BlYykgfHwgIShyaHMgaW5zdGFuY2VvZiBPYmplY3RCdWlsZFNwZWMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gb25seSBtZXJnZSBidWlsZHNwZWNzIGNyZWF0ZWQgdXNpbmcgQnVpbGRTcGVjLmZyb21PYmplY3QoKScpO1xuICB9XG5cbiAgaWYgKGxocy5zcGVjLnZlcnNpb24gPT09ICcwLjEnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgZXh0ZW5kIGJ1aWxkc3BlYyBhdCB2ZXJzaW9uIFwiMC4xXCIuIFNldCB0aGUgdmVyc2lvbiB0byBcIjAuMlwiIG9yIGhpZ2hlciBpbnN0ZWFkLicpO1xuICB9XG4gIGlmIChsaHMuc3BlYy5hcnRpZmFjdHMgJiYgcmhzLnNwZWMuYXJ0aWZhY3RzKSB7XG4gICAgLy8gV2UgZGVjaWRlZCB0byBkaXNhbGxvdyBtZXJnaW5nIG9mIGFydGlmYWN0IHNwZWNzLCB3aGljaCBpc1xuICAgIC8vIGFjdHVhbGx5IGltcG9zc2libGUgc2luY2Ugd2UgY2FuJ3QgbWVyZ2UgdHdvIGJ1aWxkc3BlY3Mgd2l0aCBhXG4gICAgLy8gc2luZ2xlIHByaW1hcnkgb3V0cHV0IGludG8gYSBidWlsZHNwZWMgd2l0aCBtdWx0aXBsZSBvdXRwdXRzLlxuICAgIC8vIEluIGNhc2Ugb2YgbXVsdGlwbGUgb3V0cHV0cyB0aGV5IG11c3QgaGF2ZSBpZGVudGlmaWVycyBidXQgd2Ugd29uJ3QgaGF2ZSB0aGF0IGluZm9ybWF0aW9uLlxuICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgYnVpbGQgc3BlYyBpcyBhbGxvd2VkIHRvIHNwZWNpZnkgYXJ0aWZhY3RzLicpO1xuICB9XG5cbiAgY29uc3QgbGhzU3BlYyA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkobGhzLnNwZWMpKTtcbiAgY29uc3QgcmhzU3BlYyA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkocmhzLnNwZWMpKTtcblxuICBub3JtYWxpemVTcGVjKGxoc1NwZWMpO1xuICBub3JtYWxpemVTcGVjKHJoc1NwZWMpO1xuXG4gIGNvbnN0IG1lcmdlZCA9IG1lcmdlRGVlcChsaHNTcGVjLCByaHNTcGVjKTtcblxuICAvLyBJbiBjYXNlIG9mIHRlc3QgcmVwb3J0cyB3ZSByZXBsYWNlIHRoZSB3aG9sZSBvYmplY3Qgd2l0aCB0aGUgUkhTIChpbnN0ZWFkIG9mIHJlY3Vyc2l2ZWx5IG1lcmdpbmcpXG4gIGlmIChsaHNTcGVjLnJlcG9ydHMgJiYgcmhzU3BlYy5yZXBvcnRzKSB7XG4gICAgbWVyZ2VkLnJlcG9ydHMgPSB7IC4uLmxoc1NwZWMucmVwb3J0cywgLi4ucmhzU3BlYy5yZXBvcnRzIH07XG4gIH1cblxuICByZXR1cm4gbmV3IE9iamVjdEJ1aWxkU3BlYyhtZXJnZWQpO1xufVxuXG4vKlxuICogTm9ybWFsaXplcyB0aGUgYnVpbGQgc3BlY1xuICogVGhlIENvZGVCdWlsZCBydW50aW1lIGFsbG93cyBmaWVsZHMgdGhhdCBhcmUgZGVmaW5lZCBhcyBzdHJpbmdbXSB0byBiZSBzdHJpbmdzXG4gKiBhbmQgaW50ZXJwcmV0cyB0aGVtIGFzIHNpbmdsZXRvbiBsaXN0cy5cbiAqIFdoZW4gbWVyZ2luZyB3ZSBuZWVkIHRvIG5vcm1hbGl6ZSB0aGlzIHRvIGhhdmUgdGhlIGNvcnJlY3QgY29uY2F0IHNlbWFudGljc1xuICovXG5mdW5jdGlvbiBub3JtYWxpemVTcGVjKHNwZWM6IHsgW2tleTogc3RyaW5nXTogYW55IH0pOiB2b2lkIHtcbiAgaWYgKHNwZWMuZW52ICYmIHR5cGVvZiBzcGVjLmVudlsnZXhwb3J0ZWQtdmFyaWFibGVzJ10gPT09ICdzdHJpbmcnKSB7XG4gICAgc3BlYy5lbnZbJ2V4cG9ydGVkLXZhcmlhYmxlcyddID0gW3NwZWMuZW52WydleHBvcnRlZC12YXJpYWJsZXMnXV07XG4gIH1cbiAgZm9yIChjb25zdCBrZXkgaW4gc3BlYy5waGFzZXMpIHtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNwZWMucGhhc2VzLCBrZXkpKSB7XG4gICAgICBub3JtYWxpemVTcGVjUGhhc2Uoc3BlYy5waGFzZXNba2V5XSk7XG4gICAgfVxuICB9XG4gIGlmIChzcGVjLnJlcG9ydHMpIHtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBzcGVjLnJlcG9ydHMpIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc3BlYy5yZXBvcnRzLCBrZXkpKSB7XG4gICAgICAgIGNvbnN0IHJlcG9ydCA9IHNwZWMucmVwb3J0c1trZXldO1xuICAgICAgICBpZiAodHlwZW9mIHJlcG9ydC5maWxlcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICByZXBvcnQuZmlsZXMgPSBbcmVwb3J0LmZpbGVzXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoc3BlYy5hcnRpZmFjdHMpIHtcbiAgICBpZiAodHlwZW9mIHNwZWMuYXJ0aWZhY3RzLmZpbGVzID09PSAnc3RyaW5nJykge1xuICAgICAgc3BlYy5hcnRpZmFjdHMuZmlsZXMgPSBbc3BlYy5hcnRpZmFjdHMuZmlsZXNdO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGtleSBpbiBzcGVjLmFydGlmYWN0c1snc2Vjb25kYXJ5LWFydGlmYWN0cyddKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNwZWMuYXJ0aWZhY3RzWydzZWNvbmRhcnktYXJ0aWZhY3RzJ10sIGtleSkpIHtcbiAgICAgICAgY29uc3Qgc2VjQXJ0aWZhY3QgPSBzcGVjLmFydGlmYWN0c1snc2Vjb25kYXJ5LWFydGlmYWN0cyddW2tleV07XG4gICAgICAgIGlmICh0eXBlb2Ygc2VjQXJ0aWZhY3QuZmlsZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgc2VjQXJ0aWZhY3QuZmlsZXMgPSBbc2VjQXJ0aWZhY3QuZmlsZXNdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmIChzcGVjLmNhY2hlICYmIHR5cGVvZiBzcGVjLmNhY2hlLnBhdGhzID09PSAnc3RyaW5nJykge1xuICAgIHNwZWMuY2FjaGUucGF0aHMgPSBbc3BlYy5jYWNoZS5wYXRoc107XG4gIH1cbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplU3BlY1BoYXNlKHBoYXNlOiB7IFtrZXk6IHN0cmluZ106IGFueSB9KTogdm9pZCB7XG4gIGlmIChwaGFzZS5jb21tYW5kcyAmJiB0eXBlb2YgcGhhc2UuY29tbWFuZHMgPT09ICdzdHJpbmcnKSB7XG4gICAgcGhhc2UuY29tbWFuZHMgPSBbcGhhc2UuY29tbWFuZHNdO1xuICB9XG4gIGlmIChwaGFzZS5maW5hbGx5ICYmIHR5cGVvZiBwaGFzZS5maW5hbGx5ID09PSAnc3RyaW5nJykge1xuICAgIHBoYXNlLmZpbmFsbHkgPSBbcGhhc2UuZmluYWxseV07XG4gIH1cbn1cblxuZnVuY3Rpb24gbWVyZ2VEZWVwKGxoczogYW55LCByaHM6IGFueSk6IGFueSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGxocykgJiYgQXJyYXkuaXNBcnJheShyaHMpKSB7XG4gICAgcmV0dXJuIFsuLi5saHMsIC4uLnJoc107XG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkobGhzKSB8fCBBcnJheS5pc0FycmF5KHJocykpIHtcbiAgICByZXR1cm4gcmhzO1xuICB9XG5cbiAgY29uc3QgaXNPYmplY3QgPSAob2JqOiBhbnkpID0+IG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JztcblxuICBpZiAoaXNPYmplY3QobGhzKSAmJiBpc09iamVjdChyaHMpKSB7XG4gICAgY29uc3QgcmV0OiBhbnkgPSB7IC4uLmxocyB9O1xuICAgIGZvciAoY29uc3QgayBvZiBPYmplY3Qua2V5cyhyaHMpKSB7XG4gICAgICByZXRba10gPSBrIGluIGxocyA/IG1lcmdlRGVlcChsaHNba10sIHJoc1trXSkgOiByaHNba107XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICByZXR1cm4gcmhzO1xufTsiXX0=
\No newline at end of file