@aws-cdk/cloudformation-diff 2.187.1 → 2.187.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/diff/index.js +35 -2
- package/lib/diff/template-and-changeset-diff-merger.d.ts +75 -0
- package/lib/diff/template-and-changeset-diff-merger.js +330 -4
- package/lib/diff/types.d.ts +11 -0
- package/lib/diff/types.js +66 -1
- package/lib/diff-template.js +50 -7
- package/lib/diffable.js +5 -7
- package/lib/format-foreach.js +13 -10
- package/lib/format-table.js +41 -5
- package/lib/format.js +38 -32
- package/lib/iam/iam-changes.js +34 -31
- package/lib/iam/iam-identity-center.js +16 -1
- package/lib/iam/managed-policy.js +3 -1
- package/lib/iam/statement.js +34 -1
- package/lib/mappings.js +9 -6
- package/lib/network/security-group-changes.js +8 -5
- package/lib/network/security-group-rule.js +21 -1
- package/package.json +9 -9
|
@@ -1,7 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.TemplateAndChangeSetDiffMerger = void 0;
|
|
4
|
-
const
|
|
37
|
+
const diff_1 = require("../diff");
|
|
38
|
+
const types = __importStar(require("../diff/types"));
|
|
5
39
|
/**
|
|
6
40
|
* The purpose of this class is to include differences from the ChangeSet to differences in the TemplateDiff.
|
|
7
41
|
*/
|
|
@@ -23,6 +57,10 @@ class TemplateAndChangeSetDiffMerger {
|
|
|
23
57
|
}
|
|
24
58
|
return propertyChange.Target.RequiresRecreation;
|
|
25
59
|
}
|
|
60
|
+
// If we somehow cannot find the resourceType, then we'll mark it as UNKNOWN, so that can be seen in the diff.
|
|
61
|
+
static UNKNOWN_RESOURCE_TYPE = 'UNKNOWN_RESOURCE_TYPE';
|
|
62
|
+
changeSet;
|
|
63
|
+
changeSetResources;
|
|
26
64
|
constructor(props) {
|
|
27
65
|
this.changeSet = props.changeSet;
|
|
28
66
|
this.changeSetResources = props.changeSetResources ?? this.convertDescribeChangeSetOutputToChangeSetResources(this.changeSet);
|
|
@@ -98,6 +136,243 @@ class TemplateAndChangeSetDiffMerger {
|
|
|
98
136
|
}
|
|
99
137
|
});
|
|
100
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Adds property changes that the change set reports for a resource that the template diff already
|
|
141
|
+
* surfaced, but that the template diff did not pick up on its own.
|
|
142
|
+
*
|
|
143
|
+
* Without this, a resource that has an ordinary (textual) change to one property would hide a
|
|
144
|
+
* second change to a *different* property that is only resolved at deploy time (e.g. a property
|
|
145
|
+
* whose value comes from an SSM parameter or a CloudFormation dynamic reference). That hidden
|
|
146
|
+
* change might even be a replacement, so silently dropping it is exactly the class of bug that
|
|
147
|
+
* issue #641 is about - just on a resource that happens to also have a visible change.
|
|
148
|
+
*
|
|
149
|
+
* This complements `addChangeSetResourcesNotInTemplateDiff`, which handles resources that are
|
|
150
|
+
* entirely absent from the template diff.
|
|
151
|
+
*
|
|
152
|
+
* @param logicalId - the logical ID of the resource (already present in the template diff)
|
|
153
|
+
* @param change - the resource difference to augment (mutated in place)
|
|
154
|
+
*/
|
|
155
|
+
addChangeSetPropertiesNotInTemplateDiff(logicalId, change) {
|
|
156
|
+
// Same guard as the impact-refinement path: the change set describes the post-transform
|
|
157
|
+
// resource for SAM, so its property information does not line up with the template.
|
|
158
|
+
// `resourceType` getter throws if the type changed, so check that first.
|
|
159
|
+
if ((change.resourceTypeChanged === true) || change.resourceType?.includes('AWS::Serverless')) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const propertyReplacementModes = this.changeSetResources[logicalId]?.propertyReplacementModes;
|
|
163
|
+
if (!propertyReplacementModes) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const resourceChange = this.findResourceChange(logicalId);
|
|
167
|
+
for (const [propertyName, { replacementMode }] of Object.entries(propertyReplacementModes)) {
|
|
168
|
+
// Properties the template diff already flagged are owned by the impact-refinement path.
|
|
169
|
+
if (propertyName in change.propertyUpdates) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
const changeImpact = changeImpactForReplacementMode(replacementMode);
|
|
173
|
+
if (changeImpact === undefined) {
|
|
174
|
+
// The change set does not actually consider this a (meaningful) change.
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
const { oldValue, newValue } = this.changeSetPropertyValues(resourceChange, propertyName);
|
|
178
|
+
const propertyDiff = new types.PropertyDifference(oldValue, newValue, { changeImpact });
|
|
179
|
+
propertyDiff.isDifferent = true;
|
|
180
|
+
change.setPropertyChange(propertyName, propertyDiff);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Adds resources to the template diff that the change set reports as changing, but that the
|
|
185
|
+
* template diff did not surface on its own.
|
|
186
|
+
*
|
|
187
|
+
* This happens when the local template is byte-for-byte identical between the current and
|
|
188
|
+
* target state, yet a value that is only resolved at deploy time changes - for example an
|
|
189
|
+
* SSM parameter referenced through `AWS::SSM::Parameter::Value<...>` or a CloudFormation
|
|
190
|
+
* dynamic reference (`{{resolve:ssm:...}}`). CloudFormation detects these in the change set
|
|
191
|
+
* even though a pure template diff cannot, so we synthesize a `ResourceDifference` from the
|
|
192
|
+
* change set's before/after data.
|
|
193
|
+
*
|
|
194
|
+
* @param resourceDiffs - the resource differences to add to (mutated in place)
|
|
195
|
+
* @param resourcesInTemplateDiff - the logical IDs that the template diff already reported as
|
|
196
|
+
* changed, captured *before* any change-set overrides were applied. Those resources are
|
|
197
|
+
* owned by the override path and are skipped here so we never clobber more accurate
|
|
198
|
+
* template-derived information with change-set-only data.
|
|
199
|
+
*/
|
|
200
|
+
addChangeSetResourcesNotInTemplateDiff(resourceDiffs, resourcesInTemplateDiff) {
|
|
201
|
+
for (const resourceChange of this.changeSet?.Changes ?? []) {
|
|
202
|
+
const rc = resourceChange.ResourceChange;
|
|
203
|
+
const logicalId = rc?.LogicalResourceId;
|
|
204
|
+
if (!rc || !logicalId) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
// Additions, removals and imports are already reflected in the template diff (a new or
|
|
208
|
+
// deleted resource shows up textually), or are handled by the dedicated import path. We
|
|
209
|
+
// only need to synthesize changes for modifications that are invisible to a textual diff.
|
|
210
|
+
if (rc.Action !== 'Modify') {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
// The template diff already produced a difference for this resource, so the override path
|
|
214
|
+
// is responsible for it. Don't replace it with change-set-only data.
|
|
215
|
+
if (resourcesInTemplateDiff.has(logicalId)) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
// CFN applies the SAM transform before creating the changeset, so changeset entries for
|
|
219
|
+
// SAM resources describe the transformed (e.g. Lambda) resource and won't line up with the
|
|
220
|
+
// SAM resource in the template. Skip them to avoid rendering a bogus diff.
|
|
221
|
+
if (rc.ResourceType?.includes('AWS::Serverless')) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const resourceDiff = this.resourceDifferenceFromChangeSetResource(rc);
|
|
225
|
+
if (resourceDiff?.isDifferent) {
|
|
226
|
+
resourceDiffs.set(logicalId, resourceDiff);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Build a `ResourceDifference` purely from a change set's `ResourceChange`.
|
|
232
|
+
*
|
|
233
|
+
* Prefers the rich `BeforeContext`/`AfterContext` (the full resource definition before and
|
|
234
|
+
* after the change, included when the change set is described with `IncludePropertyValues`),
|
|
235
|
+
* and falls back to the per-property `BeforeValue`/`AfterValue` carried in the change details.
|
|
236
|
+
*
|
|
237
|
+
* @returns the synthesized difference, or `undefined` if there is not enough information to
|
|
238
|
+
* build a meaningful before/after comparison.
|
|
239
|
+
*/
|
|
240
|
+
resourceDifferenceFromChangeSetResource(rc) {
|
|
241
|
+
const resourceType = rc.ResourceType;
|
|
242
|
+
let oldResource;
|
|
243
|
+
let newResource;
|
|
244
|
+
const oldFromContext = this.parseResourceContext(rc.BeforeContext, resourceType);
|
|
245
|
+
const newFromContext = this.parseResourceContext(rc.AfterContext, resourceType);
|
|
246
|
+
if (oldFromContext !== undefined && newFromContext !== undefined) {
|
|
247
|
+
oldResource = oldFromContext;
|
|
248
|
+
newResource = newFromContext;
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
// The full before/after context was not requested/returned; reconstruct the resource
|
|
252
|
+
// from the individual property changes instead.
|
|
253
|
+
const fromDetails = this.resourcesFromChangeDetails(rc, resourceType);
|
|
254
|
+
oldResource = fromDetails.oldResource;
|
|
255
|
+
newResource = fromDetails.newResource;
|
|
256
|
+
}
|
|
257
|
+
if (oldResource === undefined || newResource === undefined) {
|
|
258
|
+
return undefined;
|
|
259
|
+
}
|
|
260
|
+
const resourceDiff = (0, diff_1.diffResource)(oldResource, newResource, rc.LogicalResourceId);
|
|
261
|
+
// Refine the change impact (replacement vs. update) using the change set, exactly like we do
|
|
262
|
+
// for resources that originate from the template diff.
|
|
263
|
+
this.overrideDiffResourceChangeImpactWithChangeSetChangeImpact(rc.LogicalResourceId, resourceDiff);
|
|
264
|
+
return resourceDiff;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Parse a change set `BeforeContext`/`AfterContext` into a resource object.
|
|
268
|
+
*
|
|
269
|
+
* The context is the resource's definition (Properties, Metadata, etc.) but does *not* include
|
|
270
|
+
* the resource `Type`, so we splice it back in (using the change set's reported type) to allow
|
|
271
|
+
* the diff machinery to compare like-for-like and look up replacement information.
|
|
272
|
+
*/
|
|
273
|
+
parseResourceContext(context, resourceType) {
|
|
274
|
+
if (context === undefined || context === null) {
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
277
|
+
let parsed;
|
|
278
|
+
if (typeof context === 'string') {
|
|
279
|
+
try {
|
|
280
|
+
parsed = JSON.parse(context);
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
return undefined;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
parsed = context;
|
|
288
|
+
}
|
|
289
|
+
if (typeof parsed !== 'object' || parsed === null) {
|
|
290
|
+
return undefined;
|
|
291
|
+
}
|
|
292
|
+
return {
|
|
293
|
+
Type: resourceType ?? TemplateAndChangeSetDiffMerger.UNKNOWN_RESOURCE_TYPE,
|
|
294
|
+
...parsed,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Reconstruct (partial) before/after resource definitions from the per-property change details.
|
|
299
|
+
*
|
|
300
|
+
* This is the fallback used when `BeforeContext`/`AfterContext` are not available (for example
|
|
301
|
+
* when the change set was described without `IncludePropertyValues`). Only properties that
|
|
302
|
+
* carry a before or after value contribute to the reconstructed resources.
|
|
303
|
+
*/
|
|
304
|
+
resourcesFromChangeDetails(rc, resourceType) {
|
|
305
|
+
const oldProperties = {};
|
|
306
|
+
const newProperties = {};
|
|
307
|
+
let hasData = false;
|
|
308
|
+
for (const detail of rc.Details ?? []) {
|
|
309
|
+
const target = detail.Target;
|
|
310
|
+
if (target?.Attribute !== 'Properties' || !target.Name) {
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
if (target.BeforeValue !== undefined) {
|
|
314
|
+
oldProperties[target.Name] = tryJsonParse(target.BeforeValue);
|
|
315
|
+
hasData = true;
|
|
316
|
+
}
|
|
317
|
+
if (target.AfterValue !== undefined) {
|
|
318
|
+
newProperties[target.Name] = tryJsonParse(target.AfterValue);
|
|
319
|
+
hasData = true;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (!hasData) {
|
|
323
|
+
return { oldResource: undefined, newResource: undefined };
|
|
324
|
+
}
|
|
325
|
+
const type = resourceType ?? TemplateAndChangeSetDiffMerger.UNKNOWN_RESOURCE_TYPE;
|
|
326
|
+
return {
|
|
327
|
+
oldResource: { Type: type, Properties: oldProperties },
|
|
328
|
+
newResource: { Type: type, Properties: newProperties },
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Find the raw `ResourceChange` for a given logical ID in the change set.
|
|
333
|
+
*/
|
|
334
|
+
findResourceChange(logicalId) {
|
|
335
|
+
for (const resourceChange of this.changeSet?.Changes ?? []) {
|
|
336
|
+
if (resourceChange.ResourceChange?.LogicalResourceId === logicalId) {
|
|
337
|
+
return resourceChange.ResourceChange;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return undefined;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Determine the before/after value of a single property from the change set.
|
|
344
|
+
*
|
|
345
|
+
* Prefers the per-property `BeforeValue`/`AfterValue` carried in the change details, then the
|
|
346
|
+
* `BeforeContext`/`AfterContext` resource snapshots, and finally falls back to empty-object
|
|
347
|
+
* placeholders so the property still renders as a change (with the impact derived from the
|
|
348
|
+
* change set) even when no concrete values were returned.
|
|
349
|
+
*/
|
|
350
|
+
changeSetPropertyValues(resourceChange, propertyName) {
|
|
351
|
+
let oldValue;
|
|
352
|
+
let newValue;
|
|
353
|
+
for (const detail of resourceChange?.Details ?? []) {
|
|
354
|
+
const target = detail.Target;
|
|
355
|
+
if (target?.Attribute === 'Properties' && target.Name === propertyName) {
|
|
356
|
+
if (target.BeforeValue !== undefined) {
|
|
357
|
+
oldValue = tryJsonParse(target.BeforeValue);
|
|
358
|
+
}
|
|
359
|
+
if (target.AfterValue !== undefined) {
|
|
360
|
+
newValue = tryJsonParse(target.AfterValue);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (oldValue === undefined) {
|
|
365
|
+
oldValue = contextProperties(resourceChange?.BeforeContext)?.[propertyName];
|
|
366
|
+
}
|
|
367
|
+
if (newValue === undefined) {
|
|
368
|
+
newValue = contextProperties(resourceChange?.AfterContext)?.[propertyName];
|
|
369
|
+
}
|
|
370
|
+
// PropertyDifference requires at least one defined side; use a placeholder otherwise.
|
|
371
|
+
return {
|
|
372
|
+
oldValue: oldValue !== undefined ? oldValue : {},
|
|
373
|
+
newValue: newValue !== undefined ? newValue : {},
|
|
374
|
+
};
|
|
375
|
+
}
|
|
101
376
|
addImportInformationFromChangeset(resourceDiffs) {
|
|
102
377
|
const imports = this.findResourceImports();
|
|
103
378
|
resourceDiffs.forEachDifference((logicalId, change) => {
|
|
@@ -117,6 +392,57 @@ class TemplateAndChangeSetDiffMerger {
|
|
|
117
392
|
}
|
|
118
393
|
}
|
|
119
394
|
exports.TemplateAndChangeSetDiffMerger = TemplateAndChangeSetDiffMerger;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcGxhdGUtYW5kLWNoYW5nZXNldC1kaWZmLW1lcmdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlbXBsYXRlLWFuZC1jaGFuZ2VzZXQtZGlmZi1tZXJnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0EsdUNBQXVDO0FBc0J2Qzs7R0FFRztBQUNILE1BQWEsOEJBQThCO0lBQ2xDLE1BQU0sQ0FBQyxpQ0FBaUMsQ0FBQyxjQUE2QztRQUMzRixJQUFJLGNBQWMsQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDNUQsK0ZBQStGO1lBQy9GLE9BQU8sZUFBZSxDQUFDO1FBQ3pCLENBQUM7UUFFRCxJQUFJLGNBQWMsQ0FBQyxNQUFNLENBQUMsa0JBQWtCLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDMUQsUUFBUSxjQUFjLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ2xDLEtBQUssUUFBUTtvQkFDWCxPQUFPLFFBQVEsQ0FBQztnQkFDbEIsS0FBSyxTQUFTO29CQUNaLDhFQUE4RTtvQkFDOUUsK0dBQStHO29CQUMvRyxPQUFPLGVBQWUsQ0FBQztZQUMzQixDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sY0FBYyxDQUFDLE1BQU0sQ0FBQyxrQkFBNEMsQ0FBQztJQUM1RSxDQUFDO0lBUUQsWUFBWSxLQUEwQztRQUNwRCxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFDakMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxrQkFBa0IsSUFBSSxJQUFJLENBQUMsa0RBQWtELENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2hJLENBQUM7SUFFRDs7T0FFRztJQUNLLGtEQUFrRCxDQUFDLFNBQWtDO1FBQzNGLE1BQU0sa0JBQWtCLEdBQTZCLEVBQUUsQ0FBQztRQUN4RCxLQUFLLE1BQU0sY0FBYyxJQUFJLFNBQVMsQ0FBQyxPQUFPLElBQUksRUFBRSxFQUFFLENBQUM7WUFDckQsSUFBSSxjQUFjLENBQUMsY0FBYyxFQUFFLGlCQUFpQixLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNuRSxTQUFTLENBQUMseUJBQXlCO1lBQ3JDLENBQUM7WUFFRCxNQUFNLHdCQUF3QixHQUFxQyxFQUFFLENBQUM7WUFDdEUsS0FBSyxNQUFNLGNBQWMsSUFBSSxjQUFjLENBQUMsY0FBYyxDQUFDLE9BQU8sSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLGlFQUFpRTtnQkFDM0ksSUFBSSxjQUFjLENBQUMsTUFBTSxFQUFFLFNBQVMsS0FBSyxZQUFZLElBQUksY0FBYyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDcEYsd0JBQXdCLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRzt3QkFDckQsZUFBZSxFQUFFLDhCQUE4QixDQUFDLGlDQUFpQyxDQUFDLGNBQWMsQ0FBQztxQkFDbEcsQ0FBQztnQkFDSixDQUFDO1lBQ0gsQ0FBQztZQUVELGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsaUJBQWlCLENBQUMsR0FBRztnQkFDcEUsbUJBQW1CLEVBQUUsY0FBYyxDQUFDLGNBQWMsQ0FBQyxXQUFXLEtBQUssTUFBTTtnQkFDekUsWUFBWSxFQUFFLGNBQWMsQ0FBQyxjQUFjLENBQUMsWUFBWSxJQUFJLDhCQUE4QixDQUFDLHFCQUFxQixFQUFFLGdFQUFnRTtnQkFDbEwsd0JBQXdCLEVBQUUsd0JBQXdCO2FBQ25ELENBQUM7UUFDSixDQUFDO1FBRUQsT0FBTyxrQkFBa0IsQ0FBQztJQUM1QixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLHlEQUF5RCxDQUFDLFNBQWlCLEVBQUUsTUFBZ0M7UUFDbEgsNkRBQTZEO1FBQzdELElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLEtBQUssSUFBSSxDQUFDLElBQUksTUFBTSxDQUFDLFlBQVksRUFBRSxRQUFRLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDO1lBQzlGLDRIQUE0SDtZQUM1SCxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLElBQTBCLEVBQUUsSUFBWSxFQUFFLEtBQTRELEVBQUUsRUFBRTtZQUNsSSxJQUFJLElBQUksS0FBSyxVQUFVLEVBQUUsQ0FBQztnQkFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO29CQUN2QyxLQUF1QyxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQztvQkFDdEYsS0FBdUMsQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO29CQUM3RCxPQUFPO2dCQUNULENBQUM7Z0JBRUQsTUFBTSx5Q0FBeUMsR0FBRyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyx3QkFBd0IsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxlQUFlLENBQUM7Z0JBQzdJLFFBQVEseUNBQXlDLEVBQUUsQ0FBQztvQkFDbEQsS0FBSyxRQUFRO3dCQUNWLEtBQXVDLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDO3dCQUMxRixNQUFNO29CQUNSLEtBQUssT0FBTzt3QkFDVCxLQUF1QyxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQzt3QkFDekYsTUFBTTtvQkFDUixLQUFLLGVBQWU7d0JBQ2pCLEtBQXVDLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDO3dCQUN6RixNQUFNO29CQUNSLEtBQUssU0FBUzt3QkFDWCxLQUF1QyxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQzt3QkFDdEYsS0FBdUMsQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO3dCQUM3RCxNQUFNO29CQUNSLDhEQUE4RDtnQkFDaEUsQ0FBQztZQUNILENBQUM7aUJBQU0sSUFBSSxJQUFJLEtBQUssT0FBTyxFQUFFLENBQUM7Z0JBQzVCLFFBQVEsSUFBSSxFQUFFLENBQUM7b0JBQ2IsS0FBSyxVQUFVO3dCQUNiLHdGQUF3Rjt3QkFDeEYsTUFBTSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFTLEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7d0JBQ2hHLE1BQU07Z0JBQ1YsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxpQ0FBaUMsQ0FBQyxhQUFtRjtRQUMxSCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUMzQyxhQUFhLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxTQUFpQixFQUFFLE1BQWdDLEVBQUUsRUFBRTtZQUN0RixJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFDaEMsTUFBTSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7WUFDekIsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLG1CQUFtQjtRQUN4QixNQUFNLDBCQUEwQixHQUFHLEVBQUUsQ0FBQztRQUN0QyxLQUFLLE1BQU0sY0FBYyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQzNELElBQUksY0FBYyxDQUFDLGNBQWMsRUFBRSxNQUFNLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ3ZELDBCQUEwQixDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDbkYsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLDBCQUEwQixDQUFDO0lBQ3BDLENBQUM7O0FBOUhILHdFQStIQztBQTFHQyw4R0FBOEc7QUFDL0Ysb0RBQXFCLEdBQUcsdUJBQXVCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGUgU0RLIGlzIG9ubHkgdXNlZCB0byByZWZlcmVuY2UgYERlc2NyaWJlQ2hhbmdlU2V0T3V0cHV0YCwgc28gdGhlIFNESyBpcyBhZGRlZCBhcyBhIGRldkRlcGVuZGVuY3kuXG4vLyBUaGUgU0RLIHNob3VsZCBub3QgbWFrZSBuZXR3b3JrIGNhbGxzIGhlcmVcbmltcG9ydCB0eXBlIHsgRGVzY3JpYmVDaGFuZ2VTZXRPdXRwdXQgYXMgRGVzY3JpYmVDaGFuZ2VTZXQsIFJlc291cmNlQ2hhbmdlRGV0YWlsIGFzIFJDRCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1jbG91ZGZvcm1hdGlvbic7XG5pbXBvcnQgKiBhcyB0eXBlcyBmcm9tICcuLi9kaWZmL3R5cGVzJztcblxuZXhwb3J0IHR5cGUgRGVzY3JpYmVDaGFuZ2VTZXRPdXRwdXQgPSBEZXNjcmliZUNoYW5nZVNldDtcbnR5cGUgQ2hhbmdlU2V0UmVzb3VyY2VDaGFuZ2VEZXRhaWwgPSBSQ0Q7XG5cbmludGVyZmFjZSBUZW1wbGF0ZUFuZENoYW5nZVNldERpZmZNZXJnZXJPcHRpb25zIHtcbiAgLypcbiAgICogT25seSBzcGVjaWZpYWJsZSBmb3IgdGVzdGluZy4gT3RoZXJ3aXNlLCB0aGlzIGlzIHRoZSBkYXRhc3RydWN0dXJlIHRoYXQgdGhlIGNoYW5nZVNldCBpcyBjb252ZXJ0ZWQgaW50byBzb1xuICAgKiB0aGF0IHdlIG9ubHkgcGF5IGF0dGVudGlvbiB0byB0aGUgc3Vic2V0IG9mIGNoYW5nZVNldCBwcm9wZXJ0aWVzIHRoYXQgYXJlIHJlbGV2YW50IGZvciBjb21wdXRpbmcgdGhlIGRpZmYuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGhlIGNoYW5nZVNldCBpcyBjb252ZXJ0ZWQgaW50byB0aGlzIGRhdGFzdHJ1Y3R1cmUuXG4gICovXG4gIHJlYWRvbmx5IGNoYW5nZVNldFJlc291cmNlcz86IHR5cGVzLkNoYW5nZVNldFJlc291cmNlcztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW1wbGF0ZUFuZENoYW5nZVNldERpZmZNZXJnZXJQcm9wcyBleHRlbmRzIFRlbXBsYXRlQW5kQ2hhbmdlU2V0RGlmZk1lcmdlck9wdGlvbnMge1xuICAvKlxuICAgKiBUaGUgY2hhbmdlc2V0IHRoYXQgd2lsbCBiZSByZWFkIGFuZCBtZXJnZWQgaW50byB0aGUgdGVtcGxhdGUgZGlmZi5cbiAgKi9cbiAgcmVhZG9ubHkgY2hhbmdlU2V0OiBEZXNjcmliZUNoYW5nZVNldE91dHB1dDtcbn1cblxuLyoqXG4gKiBUaGUgcHVycG9zZSBvZiB0aGlzIGNsYXNzIGlzIHRvIGluY2x1ZGUgZGlmZmVyZW5jZXMgZnJvbSB0aGUgQ2hhbmdlU2V0IHRvIGRpZmZlcmVuY2VzIGluIHRoZSBUZW1wbGF0ZURpZmYuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZW1wbGF0ZUFuZENoYW5nZVNldERpZmZNZXJnZXIge1xuICBwdWJsaWMgc3RhdGljIGRldGVybWluZUNoYW5nZVNldFJlcGxhY2VtZW50TW9kZShwcm9wZXJ0eUNoYW5nZTogQ2hhbmdlU2V0UmVzb3VyY2VDaGFuZ2VEZXRhaWwpOiB0eXBlcy5SZXBsYWNlbWVudE1vZGVzIHtcbiAgICBpZiAocHJvcGVydHlDaGFuZ2UuVGFyZ2V0Py5SZXF1aXJlc1JlY3JlYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gV2UgY2FuJ3QgZGV0ZXJtaW5lIGlmIHRoZSByZXNvdXJjZSB3aWxsIGJlIHJlcGxhY2VkIG9yIG5vdC4gVGhhdCdzIHdoYXQgY29uZGl0aW9uYWxseSBtZWFucy5cbiAgICAgIHJldHVybiAnQ29uZGl0aW9uYWxseSc7XG4gICAgfVxuXG4gICAgaWYgKHByb3BlcnR5Q2hhbmdlLlRhcmdldC5SZXF1aXJlc1JlY3JlYXRpb24gPT09ICdBbHdheXMnKSB7XG4gICAgICBzd2l0Y2ggKHByb3BlcnR5Q2hhbmdlLkV2YWx1YXRpb24pIHtcbiAgICAgICAgY2FzZSAnU3RhdGljJzpcbiAgICAgICAgICByZXR1cm4gJ0Fsd2F5cyc7XG4gICAgICAgIGNhc2UgJ0R5bmFtaWMnOlxuICAgICAgICAgIC8vIElmIEV2YWx1YXRpb24gaXMgJ0R5bmFtaWMnLCB0aGVuIHRoaXMgbWF5IGNhdXNlIHJlcGxhY2VtZW50LCBvciBpdCBtYXkgbm90LlxuICAgICAgICAgIC8vIHNlZSAnUmVwbGFjZW1lbnQnOiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmVzb3VyY2VDaGFuZ2UuaHRtbFxuICAgICAgICAgIHJldHVybiAnQ29uZGl0aW9uYWxseSc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb3BlcnR5Q2hhbmdlLlRhcmdldC5SZXF1aXJlc1JlY3JlYXRpb24gYXMgdHlwZXMuUmVwbGFjZW1lbnRNb2RlcztcbiAgfVxuXG4gIC8vIElmIHdlIHNvbWVob3cgY2Fubm90IGZpbmQgdGhlIHJlc291cmNlVHlwZSwgdGhlbiB3ZSdsbCBtYXJrIGl0IGFzIFVOS05PV04sIHNvIHRoYXQgY2FuIGJlIHNlZW4gaW4gdGhlIGRpZmYuXG4gIHByaXZhdGUgc3RhdGljIFVOS05PV05fUkVTT1VSQ0VfVFlQRSA9ICdVTktOT1dOX1JFU09VUkNFX1RZUEUnO1xuXG4gIHB1YmxpYyBjaGFuZ2VTZXQ6IERlc2NyaWJlQ2hhbmdlU2V0T3V0cHV0IHwgdW5kZWZpbmVkO1xuICBwdWJsaWMgY2hhbmdlU2V0UmVzb3VyY2VzOiB0eXBlcy5DaGFuZ2VTZXRSZXNvdXJjZXM7XG5cbiAgY29uc3RydWN0b3IocHJvcHM6IFRlbXBsYXRlQW5kQ2hhbmdlU2V0RGlmZk1lcmdlclByb3BzKSB7XG4gICAgdGhpcy5jaGFuZ2VTZXQgPSBwcm9wcy5jaGFuZ2VTZXQ7XG4gICAgdGhpcy5jaGFuZ2VTZXRSZXNvdXJjZXMgPSBwcm9wcy5jaGFuZ2VTZXRSZXNvdXJjZXMgPz8gdGhpcy5jb252ZXJ0RGVzY3JpYmVDaGFuZ2VTZXRPdXRwdXRUb0NoYW5nZVNldFJlc291cmNlcyh0aGlzLmNoYW5nZVNldCk7XG4gIH1cblxuICAvKipcbiAgICogUmVhZCByZXNvdXJjZXMgZnJvbSB0aGUgY2hhbmdlU2V0LCBleHRyYWN0aW5nIGluZm9ybWF0aW9uIGludG8gQ2hhbmdlU2V0UmVzb3VyY2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBjb252ZXJ0RGVzY3JpYmVDaGFuZ2VTZXRPdXRwdXRUb0NoYW5nZVNldFJlc291cmNlcyhjaGFuZ2VTZXQ6IERlc2NyaWJlQ2hhbmdlU2V0T3V0cHV0KTogdHlwZXMuQ2hhbmdlU2V0UmVzb3VyY2VzIHtcbiAgICBjb25zdCBjaGFuZ2VTZXRSZXNvdXJjZXM6IHR5cGVzLkNoYW5nZVNldFJlc291cmNlcyA9IHt9O1xuICAgIGZvciAoY29uc3QgcmVzb3VyY2VDaGFuZ2Ugb2YgY2hhbmdlU2V0LkNoYW5nZXMgPz8gW10pIHtcbiAgICAgIGlmIChyZXNvdXJjZUNoYW5nZS5SZXNvdXJjZUNoYW5nZT8uTG9naWNhbFJlc291cmNlSWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250aW51ZTsgLy8gQmVpbmcgZGVmZW5zaXZlLCBoZXJlLlxuICAgICAgfVxuXG4gICAgICBjb25zdCBwcm9wZXJ0eVJlcGxhY2VtZW50TW9kZXM6IHR5cGVzLlByb3BlcnR5UmVwbGFjZW1lbnRNb2RlTWFwID0ge307XG4gICAgICBmb3IgKGNvbnN0IHByb3BlcnR5Q2hhbmdlIG9mIHJlc291cmNlQ2hhbmdlLlJlc291cmNlQ2hhbmdlLkRldGFpbHMgPz8gW10pIHsgLy8gRGV0YWlscyBpcyBvbmx5IGluY2x1ZGVkIGlmIHJlc291cmNlQ2hhbmdlLkFjdGlvbiA9PT0gJ01vZGlmeSdcbiAgICAgICAgaWYgKHByb3BlcnR5Q2hhbmdlLlRhcmdldD8uQXR0cmlidXRlID09PSAnUHJvcGVydGllcycgJiYgcHJvcGVydHlDaGFuZ2UuVGFyZ2V0Lk5hbWUpIHtcbiAgICAgICAgICBwcm9wZXJ0eVJlcGxhY2VtZW50TW9kZXNbcHJvcGVydHlDaGFuZ2UuVGFyZ2V0Lk5hbWVdID0ge1xuICAgICAgICAgICAgcmVwbGFjZW1lbnRNb2RlOiBUZW1wbGF0ZUFuZENoYW5nZVNldERpZmZNZXJnZXIuZGV0ZXJtaW5lQ2hhbmdlU2V0UmVwbGFjZW1lbnRNb2RlKHByb3BlcnR5Q2hhbmdlKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNoYW5nZVNldFJlc291cmNlc1tyZXNvdXJjZUNoYW5nZS5SZXNvdXJjZUNoYW5nZS5Mb2dpY2FsUmVzb3VyY2VJZF0gPSB7XG4gICAgICAgIHJlc291cmNlV2FzUmVwbGFjZWQ6IHJlc291cmNlQ2hhbmdlLlJlc291cmNlQ2hhbmdlLlJlcGxhY2VtZW50ID09PSAnVHJ1ZScsXG4gICAgICAgIHJlc291cmNlVHlwZTogcmVzb3VyY2VDaGFuZ2UuUmVzb3VyY2VDaGFuZ2UuUmVzb3VyY2VUeXBlID8/IFRlbXBsYXRlQW5kQ2hhbmdlU2V0RGlmZk1lcmdlci5VTktOT1dOX1JFU09VUkNFX1RZUEUsIC8vIERlc2NyaWJlQ2hhbmdlU2V0IGRvZXNuJ3QgcHJvbWlzZSB0byBoYXZlIHRoZSBSZXNvdXJjZVR5cGUuLi5cbiAgICAgICAgcHJvcGVydHlSZXBsYWNlbWVudE1vZGVzOiBwcm9wZXJ0eVJlcGxhY2VtZW50TW9kZXMsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBjaGFuZ2VTZXRSZXNvdXJjZXM7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBpcyB3cml0aW5nIG92ZXIgdGhlIFwiQ2hhbmdlSW1wYWN0XCIgdGhhdCB3YXMgY29tcHV0ZWQgZnJvbSB0aGUgdGVtcGxhdGUgZGlmZmVyZW5jZSwgYW5kIGluc3RlYWQgdXNpbmcgdGhlIENoYW5nZUltcGFjdCB0aGF0IGlzIGluY2x1ZGVkIGZyb20gdGhlIENoYW5nZVNldC5cbiAgICogVXNpbmcgdGhlIENoYW5nZVNldCBDaGFuZ2VJbXBhY3QgaXMgbW9yZSBhY2N1cmF0ZS4gVGhlIENoYW5nZUltcGFjdCB0ZWxscyB1cyB3aGF0IHRoZSBjb25zZXF1ZW5jZSBpcyBvZiBjaGFuZ2luZyB0aGUgZmllbGQuIElmIGNoYW5naW5nIHRoZSBmaWVsZCBjYXVzZXMgcmVzb3VyY2VcbiAgICogcmVwbGFjZW1lbnQgKGUuZy4sIGNoYW5naW5nIHRoZSBuYW1lIG9mIGFuIElBTSByb2xlIHJlcXVpcmVzIGRlbGV0aW5nIGFuZCByZXBsYWNpbmcgdGhlIHJvbGUpLCB0aGVuIENoYW5nZUltcGFjdCBpcyBcIkFsd2F5c1wiLlxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlRGlmZlJlc291cmNlQ2hhbmdlSW1wYWN0V2l0aENoYW5nZVNldENoYW5nZUltcGFjdChsb2dpY2FsSWQ6IHN0cmluZywgY2hhbmdlOiB0eXBlcy5SZXNvdXJjZURpZmZlcmVuY2UpIHtcbiAgICAvLyByZXNvdXJjZVR5cGUgZ2V0dGVyIHRocm93cyBhbiBlcnJvciBpZiByZXNvdXJjZVR5cGVDaGFuZ2VkXG4gICAgaWYgKChjaGFuZ2UucmVzb3VyY2VUeXBlQ2hhbmdlZCA9PT0gdHJ1ZSkgfHwgY2hhbmdlLnJlc291cmNlVHlwZT8uaW5jbHVkZXMoJ0FXUzo6U2VydmVybGVzcycpKSB7XG4gICAgICAvLyBDRk4gYXBwbGllcyB0aGUgU0FNIHRyYW5zZm9ybSBiZWZvcmUgY3JlYXRpbmcgdGhlIGNoYW5nZXNldCwgc28gdGhlIGNoYW5nZXNldCBjb250YWlucyBubyBpbmZvcm1hdGlvbiBhYm91dCBTQU0gcmVzb3VyY2VzXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNoYW5nZS5mb3JFYWNoRGlmZmVyZW5jZSgodHlwZTogJ1Byb3BlcnR5JyB8ICdPdGhlcicsIG5hbWU6IHN0cmluZywgdmFsdWU6IHR5cGVzLkRpZmZlcmVuY2U8YW55PiB8IHR5cGVzLlByb3BlcnR5RGlmZmVyZW5jZTxhbnk+KSA9PiB7XG4gICAgICBpZiAodHlwZSA9PT0gJ1Byb3BlcnR5Jykge1xuICAgICAgICBpZiAoIXRoaXMuY2hhbmdlU2V0UmVzb3VyY2VzW2xvZ2ljYWxJZF0pIHtcbiAgICAgICAgICAodmFsdWUgYXMgdHlwZXMuUHJvcGVydHlEaWZmZXJlbmNlPGFueT4pLmNoYW5nZUltcGFjdCA9IHR5cGVzLlJlc291cmNlSW1wYWN0Lk5PX0NIQU5HRTtcbiAgICAgICAgICAodmFsdWUgYXMgdHlwZXMuUHJvcGVydHlEaWZmZXJlbmNlPGFueT4pLmlzRGlmZmVyZW50ID0gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2hhbmdpbmdQcm9wZXJ0eUNhdXNlc1Jlc291cmNlUmVwbGFjZW1lbnQgPSAodGhpcy5jaGFuZ2VTZXRSZXNvdXJjZXNbbG9naWNhbElkXS5wcm9wZXJ0eVJlcGxhY2VtZW50TW9kZXMgPz8ge30pW25hbWVdPy5yZXBsYWNlbWVudE1vZGU7XG4gICAgICAgIHN3aXRjaCAoY2hhbmdpbmdQcm9wZXJ0eUNhdXNlc1Jlc291cmNlUmVwbGFjZW1lbnQpIHtcbiAgICAgICAgICBjYXNlICdBbHdheXMnOlxuICAgICAgICAgICAgKHZhbHVlIGFzIHR5cGVzLlByb3BlcnR5RGlmZmVyZW5jZTxhbnk+KS5jaGFuZ2VJbXBhY3QgPSB0eXBlcy5SZXNvdXJjZUltcGFjdC5XSUxMX1JFUExBQ0U7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdOZXZlcic6XG4gICAgICAgICAgICAodmFsdWUgYXMgdHlwZXMuUHJvcGVydHlEaWZmZXJlbmNlPGFueT4pLmNoYW5nZUltcGFjdCA9IHR5cGVzLlJlc291cmNlSW1wYWN0LldJTExfVVBEQVRFO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnQ29uZGl0aW9uYWxseSc6XG4gICAgICAgICAgICAodmFsdWUgYXMgdHlwZXMuUHJvcGVydHlEaWZmZXJlbmNlPGFueT4pLmNoYW5nZUltcGFjdCA9IHR5cGVzLlJlc291cmNlSW1wYWN0Lk1BWV9SRVBMQUNFO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSB1bmRlZmluZWQ6XG4gICAgICAgICAgICAodmFsdWUgYXMgdHlwZXMuUHJvcGVydHlEaWZmZXJlbmNlPGFueT4pLmNoYW5nZUltcGFjdCA9IHR5cGVzLlJlc291cmNlSW1wYWN0Lk5PX0NIQU5HRTtcbiAgICAgICAgICAgICh2YWx1ZSBhcyB0eXBlcy5Qcm9wZXJ0eURpZmZlcmVuY2U8YW55PikuaXNEaWZmZXJlbnQgPSBmYWxzZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIC8vIG90aGVyd2lzZSwgZGVmZXIgdG8gdGhlIGNoYW5nZUltcGFjdCBmcm9tIHRoZSB0ZW1wbGF0ZSBkaWZmXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ090aGVyJykge1xuICAgICAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgICAgICBjYXNlICdNZXRhZGF0YSc6XG4gICAgICAgICAgICAvLyB3ZSB3YW50IHRvIGlnbm9yZSBtZXRhZGF0YSBjaGFuZ2VzIGluIHRoZSBkaWZmLCBzbyBjb21wYXJlIG5ld1ZhbHVlIGFnYWluc3QgbmV3VmFsdWUuXG4gICAgICAgICAgICBjaGFuZ2Uuc2V0T3RoZXJDaGFuZ2UoJ01ldGFkYXRhJywgbmV3IHR5cGVzLkRpZmZlcmVuY2U8c3RyaW5nPih2YWx1ZS5uZXdWYWx1ZSwgdmFsdWUubmV3VmFsdWUpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYWRkSW1wb3J0SW5mb3JtYXRpb25Gcm9tQ2hhbmdlc2V0KHJlc291cmNlRGlmZnM6IHR5cGVzLkRpZmZlcmVuY2VDb2xsZWN0aW9uPHR5cGVzLlJlc291cmNlLCB0eXBlcy5SZXNvdXJjZURpZmZlcmVuY2U+KSB7XG4gICAgY29uc3QgaW1wb3J0cyA9IHRoaXMuZmluZFJlc291cmNlSW1wb3J0cygpO1xuICAgIHJlc291cmNlRGlmZnMuZm9yRWFjaERpZmZlcmVuY2UoKGxvZ2ljYWxJZDogc3RyaW5nLCBjaGFuZ2U6IHR5cGVzLlJlc291cmNlRGlmZmVyZW5jZSkgPT4ge1xuICAgICAgaWYgKGltcG9ydHMuaW5jbHVkZXMobG9naWNhbElkKSkge1xuICAgICAgICBjaGFuZ2UuaXNJbXBvcnQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGZpbmRSZXNvdXJjZUltcG9ydHMoKTogKHN0cmluZyB8IHVuZGVmaW5lZClbXSB7XG4gICAgY29uc3QgaW1wb3J0ZWRSZXNvdXJjZUxvZ2ljYWxJZHMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IHJlc291cmNlQ2hhbmdlIG9mIHRoaXMuY2hhbmdlU2V0Py5DaGFuZ2VzID8/IFtdKSB7XG4gICAgICBpZiAocmVzb3VyY2VDaGFuZ2UuUmVzb3VyY2VDaGFuZ2U/LkFjdGlvbiA9PT0gJ0ltcG9ydCcpIHtcbiAgICAgICAgaW1wb3J0ZWRSZXNvdXJjZUxvZ2ljYWxJZHMucHVzaChyZXNvdXJjZUNoYW5nZS5SZXNvdXJjZUNoYW5nZS5Mb2dpY2FsUmVzb3VyY2VJZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGltcG9ydGVkUmVzb3VyY2VMb2dpY2FsSWRzO1xuICB9XG59XG4iXX0=
|
|
395
|
+
/**
|
|
396
|
+
* Parse a change set property value as JSON, falling back to the raw value.
|
|
397
|
+
*
|
|
398
|
+
* Change set property values (e.g. `BeforeValue`/`AfterValue`) are always strings. Some of them
|
|
399
|
+
* are serialized JSON (such as an IAM `PolicyDocument`), while others are plain scalars. Parsing
|
|
400
|
+
* lets us compare structured values structurally; if parsing fails we keep the original string.
|
|
401
|
+
*/
|
|
402
|
+
function tryJsonParse(value) {
|
|
403
|
+
try {
|
|
404
|
+
return JSON.parse(value);
|
|
405
|
+
}
|
|
406
|
+
catch {
|
|
407
|
+
return value;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Map a change set replacement mode to the corresponding diff `ResourceImpact`.
|
|
412
|
+
*
|
|
413
|
+
* Returns `undefined` when the change set does not consider the property a (meaningful) change.
|
|
414
|
+
*/
|
|
415
|
+
function changeImpactForReplacementMode(replacementMode) {
|
|
416
|
+
switch (replacementMode) {
|
|
417
|
+
case 'Always':
|
|
418
|
+
return types.ResourceImpact.WILL_REPLACE;
|
|
419
|
+
case 'Never':
|
|
420
|
+
return types.ResourceImpact.WILL_UPDATE;
|
|
421
|
+
case 'Conditionally':
|
|
422
|
+
return types.ResourceImpact.MAY_REPLACE;
|
|
423
|
+
default:
|
|
424
|
+
return undefined;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Parse the `Properties` block out of a change set `BeforeContext`/`AfterContext` snapshot.
|
|
429
|
+
*/
|
|
430
|
+
function contextProperties(context) {
|
|
431
|
+
if (context === undefined || context === null) {
|
|
432
|
+
return undefined;
|
|
433
|
+
}
|
|
434
|
+
let parsed;
|
|
435
|
+
if (typeof context === 'string') {
|
|
436
|
+
try {
|
|
437
|
+
parsed = JSON.parse(context);
|
|
438
|
+
}
|
|
439
|
+
catch {
|
|
440
|
+
return undefined;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
parsed = context;
|
|
445
|
+
}
|
|
446
|
+
return parsed && typeof parsed === 'object' ? parsed.Properties : undefined;
|
|
447
|
+
}
|
|
448
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcGxhdGUtYW5kLWNoYW5nZXNldC1kaWZmLW1lcmdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlbXBsYXRlLWFuZC1jaGFuZ2VzZXQtZGlmZi1tZXJnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBR0Esa0NBQXVDO0FBQ3ZDLHFEQUF1QztBQXVCdkM7O0dBRUc7QUFDSCxNQUFhLDhCQUE4QjtJQUNsQyxNQUFNLENBQUMsaUNBQWlDLENBQUMsY0FBNkM7UUFDM0YsSUFBSSxjQUFjLENBQUMsTUFBTSxFQUFFLGtCQUFrQixLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzVELCtGQUErRjtZQUMvRixPQUFPLGVBQWUsQ0FBQztRQUN6QixDQUFDO1FBRUQsSUFBSSxjQUFjLENBQUMsTUFBTSxDQUFDLGtCQUFrQixLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzFELFFBQVEsY0FBYyxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUNsQyxLQUFLLFFBQVE7b0JBQ1gsT0FBTyxRQUFRLENBQUM7Z0JBQ2xCLEtBQUssU0FBUztvQkFDWiw4RUFBOEU7b0JBQzlFLCtHQUErRztvQkFDL0csT0FBTyxlQUFlLENBQUM7WUFDM0IsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLGNBQWMsQ0FBQyxNQUFNLENBQUMsa0JBQTRDLENBQUM7SUFDNUUsQ0FBQztJQUVELDhHQUE4RztJQUN0RyxNQUFNLENBQUMscUJBQXFCLEdBQUcsdUJBQXVCLENBQUM7SUFFeEQsU0FBUyxDQUFzQztJQUMvQyxrQkFBa0IsQ0FBMkI7SUFFcEQsWUFBWSxLQUEwQztRQUNwRCxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFDakMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxrQkFBa0IsSUFBSSxJQUFJLENBQUMsa0RBQWtELENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lB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QUMsU0FBUyxDQUFDO0FBQzlFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGUgU0RLIGlzIG9ubHkgdXNlZCB0byByZWZlcmVuY2UgYERlc2NyaWJlQ2hhbmdlU2V0T3V0cHV0YCwgc28gdGhlIFNESyBpcyBhZGRlZCBhcyBhIGRldkRlcGVuZGVuY3kuXG4vLyBUaGUgU0RLIHNob3VsZCBub3QgbWFrZSBuZXR3b3JrIGNhbGxzIGhlcmVcbmltcG9ydCB0eXBlIHsgRGVzY3JpYmVDaGFuZ2VTZXRPdXRwdXQgYXMgRGVzY3JpYmVDaGFuZ2VTZXQsIFJlc291cmNlQ2hhbmdlIGFzIFJDLCBSZXNvdXJjZUNoYW5nZURldGFpbCBhcyBSQ0QgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtY2xvdWRmb3JtYXRpb24nO1xuaW1wb3J0IHsgZGlmZlJlc291cmNlIH0gZnJvbSAnLi4vZGlmZic7XG5pbXBvcnQgKiBhcyB0eXBlcyBmcm9tICcuLi9kaWZmL3R5cGVzJztcblxuZXhwb3J0IHR5cGUgRGVzY3JpYmVDaGFuZ2VTZXRPdXRwdXQgPSBEZXNjcmliZUNoYW5nZVNldDtcbnR5cGUgQ2hhbmdlU2V0UmVzb3VyY2VDaGFuZ2VEZXRhaWwgPSBSQ0Q7XG50eXBlIENoYW5nZVNldFJlc291cmNlQ2hhbmdlID0gUkM7XG5cbmludGVyZmFjZSBUZW1wbGF0ZUFuZENoYW5nZVNldERpZmZNZXJnZXJPcHRpb25zIHtcbiAgLypcbiAgICogT25seSBzcGVjaWZpYWJsZSBmb3IgdGVzdGluZy4gT3RoZXJ3aXNlLCB0aGlzIGlzIHRoZSBkYXRhc3RydWN0dXJlIHRoYXQgdGhlIGNoYW5nZVNldCBpcyBjb252ZXJ0ZWQgaW50byBzb1xuICAgKiB0aGF0IHdlIG9ubHkgcGF5IGF0dGVudGlvbiB0byB0aGUgc3Vic2V0IG9mIGNoYW5nZVNldCBwcm9wZXJ0aWVzIHRoYXQgYXJlIHJlbGV2YW50IGZvciBjb21wdXRpbmcgdGhlIGRpZmYuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGhlIGNoYW5nZVNldCBpcyBjb252ZXJ0ZWQgaW50byB0aGlzIGRhdGFzdHJ1Y3R1cmUuXG4gICovXG4gIHJlYWRvbmx5IGNoYW5nZVNldFJlc291cmNlcz86IHR5cGVzLkNoYW5nZVNldFJlc291cmNlcztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW1wbGF0ZUFuZENoYW5nZVNldERpZmZNZXJnZXJQcm9wcyBleHRlbmRzIFRlbXBsYXRlQW5kQ2hhbmdlU2V0RGlmZk1lcmdlck9wdGlvbnMge1xuICAvKlxuICAgKiBUaGUgY2hhbmdlc2V0IHRoYXQgd2lsbCBiZSByZWFkIGFuZCBtZXJnZWQgaW50byB0aGUgdGVtcGxhdGUgZGlmZi5cbiAgKi9cbiAgcmVhZG9ubHkgY2hhbmdlU2V0OiBEZXNjcmliZUNoYW5nZVNldE91dHB1dDtcbn1cblxuLyoqXG4gKiBUaGUgcHVycG9zZSBvZiB0aGlzIGNsYXNzIGlzIHRvIGluY2x1ZGUgZGlmZmVyZW5jZXMgZnJvbSB0aGUgQ2hhbmdlU2V0IHRvIGRpZmZlcmVuY2VzIGluIHRoZSBUZW1wbGF0ZURpZmYuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZW1wbGF0ZUFuZENoYW5nZVNldERpZmZNZXJnZXIge1xuICBwdWJsaWMgc3RhdGljIGRldGVybWluZUNoYW5nZVNldFJlcGxhY2VtZW50TW9kZShwcm9wZXJ0eUNoYW5nZTogQ2hhbmdlU2V0UmVzb3VyY2VDaGFuZ2VEZXRhaWwpOiB0eXBlcy5SZXBsYWNlbWVudE1vZGVzIHtcbiAgICBpZiAocHJvcGVydHlDaGFuZ2UuVGFyZ2V0Py5SZXF1aXJlc1JlY3JlYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gV2UgY2FuJ3QgZGV0ZXJtaW5lIGlmIHRoZSByZXNvdXJjZSB3aWxsIGJlIHJlcGxhY2VkIG9yIG5vdC4gVGhhdCdzIHdoYXQgY29uZGl0aW9uYWxseSBtZWFucy5cbiAgICAgIHJldHVybiAnQ29uZGl0aW9uYWxseSc7XG4gICAgfVxuXG4gICAgaWYgKHByb3BlcnR5Q2hhbmdlLlRhcmdldC5SZXF1aXJlc1JlY3JlYXRpb24gPT09ICdBbHdheXMnKSB7XG4gICAgICBzd2l0Y2ggKHByb3BlcnR5Q2hhbmdlLkV2YWx1YXRpb24pIHtcbiAgICAgICAgY2FzZSAnU3RhdGljJzpcbiAgICAgICAgICByZXR1cm4gJ0Fsd2F5cyc7XG4gICAgICAgIGNhc2UgJ0R5bmFtaWMnOlxuICAgICAgICAgIC8vIElmIEV2YWx1YXRpb24gaXMgJ0R5bmFtaWMnLCB0aGVuIHRoaXMgbWF5IGNhdXNlIHJlcGxhY2VtZW50LCBvciBpdCBtYXkgbm90LlxuICAgICAgICAgIC8vIHNlZSAnUmVwbGFjZW1lbnQnOiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmVzb3VyY2VDaGFuZ2UuaHRtbFxuICAgICAgICAgIHJldHVybiAnQ29uZGl0aW9uYWxseSc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb3BlcnR5Q2hhbmdlLlRhcmdldC5SZXF1aXJlc1JlY3JlYXRpb24gYXMgdHlwZXMuUmVwbGFjZW1lbnRNb2RlcztcbiAgfVxuXG4gIC8vIElmIHdlIHNvbWVob3cgY2Fubm90IGZpbmQgdGhlIHJlc291cmNlVHlwZSwgdGhlbiB3ZSdsbCBtYXJrIGl0IGFzIFVOS05PV04sIHNvIHRoYXQgY2FuIGJlIHNlZW4gaW4gdGhlIGRpZmYuXG4gIHByaXZhdGUgc3RhdGljIFVOS05PV05fUkVTT1VSQ0VfVFlQRSA9ICdVTktOT1dOX1JFU09VUkNFX1RZUEUnO1xuXG4gIHB1YmxpYyBjaGFuZ2VTZXQ6IERlc2NyaWJlQ2hhbmdlU2V0T3V0cHV0IHwgdW5kZWZpbmVkO1xuICBwdWJsaWMgY2hhbmdlU2V0UmVzb3VyY2VzOiB0eXBlcy5DaGFuZ2VTZXRSZXNvdXJjZXM7XG5cbiAgY29uc3RydWN0b3IocHJvcHM6IFRlbXBsYXRlQW5kQ2hhbmdlU2V0RGlmZk1lcmdlclByb3BzKSB7XG4gICAgdGhpcy5jaGFuZ2VTZXQgPSBwcm9wcy5jaGFuZ2VTZXQ7XG4gICAgdGhpcy5jaGFuZ2VTZXRSZXNvdXJjZXMgPSBwcm9wcy5jaGFuZ2VTZXRSZXNvdXJjZXMgPz8gdGhpcy5jb252ZXJ0RGVzY3JpYmVDaGFuZ2VTZXRPdXRwdXRUb0NoYW5nZVNldFJlc291cmNlcyh0aGlzLmNoYW5nZVNldCk7XG4gIH1cblxuICAvKipcbiAgICogUmVhZCByZXNvdXJjZXMgZnJvbSB0aGUgY2hhbmdlU2V0LCBleHRyYWN0aW5nIGluZm9ybWF0aW9uIGludG8gQ2hhbmdlU2V0UmVzb3VyY2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBjb252ZXJ0RGVzY3JpYmVDaGFuZ2VTZXRPdXRwdXRUb0NoYW5nZVNldFJlc291cmNlcyhjaGFuZ2VTZXQ6IERlc2NyaWJlQ2hhbmdlU2V0T3V0cHV0KTogdHlwZXMuQ2hhbmdlU2V0UmVzb3VyY2VzIHtcbiAgICBjb25zdCBjaGFuZ2VTZXRSZXNvdXJjZXM6IHR5cGVzLkNoYW5nZVNldFJlc291cmNlcyA9IHt9O1xuICAgIGZvciAoY29uc3QgcmVzb3VyY2VDaGFuZ2Ugb2YgY2hhbmdlU2V0LkNoYW5nZXMgPz8gW10pIHtcbiAgICAgIGlmIChyZXNvdXJjZUNoYW5nZS5SZXNvdXJjZUNoYW5nZT8uTG9naWNhbFJlc291cmNlSWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250aW51ZTsgLy8gQmVpbmcgZGVmZW5zaXZlLCBoZXJlLlxuICAgICAgfVxuXG4gICAgICBjb25zdCBwcm9wZXJ0eVJlcGxhY2VtZW50TW9kZXM6IHR5cGVzLlByb3BlcnR5UmVwbGFjZW1lbnRNb2RlTWFwID0ge307XG4gICAgICBmb3IgKGNvbnN0IHByb3BlcnR5Q2hhbmdlIG9mIHJlc291cmNlQ2hhbmdlLlJlc291cmNlQ2hhbmdlLkRldGFpbHMgPz8gW10pIHsgLy8gRGV0YWlscyBpcyBvbmx5IGluY2x1ZGVkIGlmIHJlc291cmNlQ2hhbmdlLkFjdGlvbiA9PT0gJ01vZGlmeSdcbiAgICAgICAgaWYgKHByb3BlcnR5Q2hhbmdlLlRhcmdldD8uQXR0cmlidXRlID09PSAnUHJvcGVydGllcycgJiYgcHJvcGVydHlDaGFuZ2UuVGFyZ2V0Lk5hbWUpIHtcbiAgICAgICAgICBwcm9wZXJ0eVJlcGxhY2VtZW50TW9kZXNbcHJvcGVydHlDaGFuZ2UuVGFyZ2V0Lk5hbWVdID0ge1xuICAgICAgICAgICAgcmVwbGFjZW1lbnRNb2RlOiBUZW1wbGF0ZUFuZENoYW5nZVNldERpZmZNZXJnZXIuZGV0ZXJtaW5lQ2hhbmdlU2V0UmVwbGFjZW1lbnRNb2RlKHByb3BlcnR5Q2hhbmdlKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNoYW5nZVNldFJlc291cmNlc1tyZXNvdXJjZUNoYW5nZS5SZXNvdXJjZUNoYW5nZS5Mb2dpY2FsUmVzb3VyY2VJZF0gPSB7XG4gICAgICAgIHJlc291cmNlV2FzUmVwbGFjZWQ6IHJlc291cmNlQ2hhbmdlLlJlc291cmNlQ2hhbmdlLlJlcGxhY2VtZW50ID09PSAnVHJ1ZScsXG4gICAgICAgIHJlc291cmNlVHlwZTogcmVzb3VyY2VDaGFuZ2UuUmVzb3VyY2VDaGFuZ2UuUmVzb3VyY2VUeXBlID8/IFRlbXBsYXRlQW5kQ2hhbmdlU2V0RGlmZk1lcmdlci5VTktOT1dOX1JFU09VUkNFX1RZUEUsIC8vIERlc2NyaWJlQ2hhbmdlU2V0IGRvZXNuJ3QgcHJvbWlzZSB0byBoYXZlIHRoZSBSZXNvdXJjZVR5cGUuLi5cbiAgICAgICAgcHJvcGVydHlSZXBsYWNlbWVudE1vZGVzOiBwcm9wZXJ0eVJlcGxhY2VtZW50TW9kZXMsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBjaGFuZ2VTZXRSZXNvdXJjZXM7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBpcyB3cml0aW5nIG92ZXIgdGhlIFwiQ2hhbmdlSW1wYWN0XCIgdGhhdCB3YXMgY29tcHV0ZWQgZnJvbSB0aGUgdGVtcGxhdGUgZGlmZmVyZW5jZSwgYW5kIGluc3RlYWQgdXNpbmcgdGhlIENoYW5nZUltcGFjdCB0aGF0IGlzIGluY2x1ZGVkIGZyb20gdGhlIENoYW5nZVNldC5cbiAgICogVXNpbmcgdGhlIENoYW5nZVNldCBDaGFuZ2VJbXBhY3QgaXMgbW9yZSBhY2N1cmF0ZS4gVGhlIENoYW5nZUltcGFjdCB0ZWxscyB1cyB3aGF0IHRoZSBjb25zZXF1ZW5jZSBpcyBvZiBjaGFuZ2luZyB0aGUgZmllbGQuIElmIGNoYW5naW5nIHRoZSBmaWVsZCBjYXVzZXMgcmVzb3VyY2VcbiAgICogcmVwbGFjZW1lbnQgKGUuZy4sIGNoYW5naW5nIHRoZSBuYW1lIG9mIGFuIElBTSByb2xlIHJlcXVpcmVzIGRlbGV0aW5nIGFuZCByZXBsYWNpbmcgdGhlIHJvbGUpLCB0aGVuIENoYW5nZUltcGFjdCBpcyBcIkFsd2F5c1wiLlxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlRGlmZlJlc291cmNlQ2hhbmdlSW1wYWN0V2l0aENoYW5nZVNldENoYW5nZUltcGFjdChsb2dpY2FsSWQ6IHN0cmluZywgY2hhbmdlOiB0eXBlcy5SZXNvdXJjZURpZmZlcmVuY2UpIHtcbiAgICAvLyByZXNvdXJjZVR5cGUgZ2V0dGVyIHRocm93cyBhbiBlcnJvciBpZiByZXNvdXJjZVR5cGVDaGFuZ2VkXG4gICAgaWYgKChjaGFuZ2UucmVzb3VyY2VUeXBlQ2hhbmdlZCA9PT0gdHJ1ZSkgfHwgY2hhbmdlLnJlc291cmNlVHlwZT8uaW5jbHVkZXMoJ0FXUzo6U2VydmVybGVzcycpKSB7XG4gICAgICAvLyBDRk4gYXBwbGllcyB0aGUgU0FNIHRyYW5zZm9ybSBiZWZvcmUgY3JlYXRpbmcgdGhlIGNoYW5nZXNldCwgc28gdGhlIGNoYW5nZXNldCBjb250YWlucyBubyBpbmZvcm1hdGlvbiBhYm91dCBTQU0gcmVzb3VyY2VzXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNoYW5nZS5mb3JFYWNoRGlmZmVyZW5jZSgodHlwZTogJ1Byb3BlcnR5JyB8ICdPdGhlcicsIG5hbWU6IHN0cmluZywgdmFsdWU6IHR5cGVzLkRpZmZlcmVuY2U8YW55PiB8IHR5cGVzLlByb3BlcnR5RGlmZmVyZW5jZTxhbnk+KSA9PiB7XG4gICAgICBpZiAodHlwZSA9PT0gJ1Byb3BlcnR5Jykge1xuICAgICAgICBpZiAoIXRoaXMuY2hhbmdlU2V0UmVzb3VyY2VzW2xvZ2ljYWxJZF0pIHtcbiAgICAgICAgICAodmFsdWUgYXMgdHlwZXMuUHJvcGVydHlEaWZmZXJlbmNlPGFueT4pLmNoYW5nZUltcGFjdCA9IHR5cGVzLlJlc291cmNlSW1wYWN0Lk5PX0NIQU5HRTtcbiAgICAgICAgICAodmFsdWUgYXMgdHlwZXMuUHJvcGVydHlEaWZmZXJlbmNlPGFueT4pLmlzRGlmZmVyZW50ID0gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2hhbmdpbmdQcm9wZXJ0eUNhdXNlc1Jlc291cmNlUmVwbGFjZW1lbnQgPSAodGhpcy5jaGFuZ2VTZXRSZXNvdXJjZXNbbG9naWNhbElkXS5wcm9wZXJ0eVJlcGxhY2VtZW50TW9kZXMgPz8ge30pW25hbWVdPy5yZXBsYWNlbWVudE1vZGU7XG4gICAgICAgIHN3aXRjaCAoY2hhbmdpbmdQcm9wZXJ0eUNhdXNlc1Jlc291cmNlUmVwbGFjZW1lbnQpIHtcbiAgICAgICAgICBjYXNlICdBbHdheXMnOlxuICAgICAgICAgICAgKHZhbHVlIGFzIHR5cGVzLlByb3BlcnR5RGlmZmVyZW5jZTxhbnk+KS5jaGFuZ2VJbXBhY3QgPSB0eXBlcy5SZXNvdXJjZUltcGFjdC5XSUxMX1JFUExBQ0U7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdOZXZlcic6XG4gICAgICAgICAgICAodmFsdWUgYXMgdHlwZXMuUHJvcGVydHlEaWZmZXJlbmNlPGFueT4pLmNoYW5nZUltcGFjdCA9IHR5cGVzLlJlc291cmNlSW1wYWN0LldJTExfVVBEQVRFO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnQ29uZGl0aW9uYWxseSc6XG4gICAgICAgICAgICAodmFsdWUgYXMgdHlwZXMuUHJvcGVydHlEaWZmZXJlbmNlPGFueT4pLmNoYW5nZUltcGFjdCA9IHR5cGVzLlJlc291cmNlSW1wYWN0Lk1BWV9SRVBMQUNFO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSB1bmRlZmluZWQ6XG4gICAgICAgICAgICAodmFsdWUgYXMgdHlwZXMuUHJvcGVydHlEaWZmZXJlbmNlPGFueT4pLmNoYW5nZUltcGFjdCA9IHR5cGVzLlJlc291cmNlSW1wYWN0Lk5PX0NIQU5HRTtcbiAgICAgICAgICAgICh2YWx1ZSBhcyB0eXBlcy5Qcm9wZXJ0eURpZmZlcmVuY2U8YW55PikuaXNEaWZmZXJlbnQgPSBmYWxzZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIC8vIG90aGVyd2lzZSwgZGVmZXIgdG8gdGhlIGNoYW5nZUltcGFjdCBmcm9tIHRoZSB0ZW1wbGF0ZSBkaWZmXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ090aGVyJykge1xuICAgICAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgICAgICBjYXNlICdNZXRhZGF0YSc6XG4gICAgICAgICAgICAvLyB3ZSB3YW50IHRvIGlnbm9yZSBtZXRhZGF0YSBjaGFuZ2VzIGluIHRoZSBkaWZmLCBzbyBjb21wYXJlIG5ld1ZhbHVlIGFnYWluc3QgbmV3VmFsdWUuXG4gICAgICAgICAgICBjaGFuZ2Uuc2V0T3RoZXJDaGFuZ2UoJ01ldGFkYXRhJywgbmV3IHR5cGVzLkRpZmZlcmVuY2U8c3RyaW5nPih2YWx1ZS5uZXdWYWx1ZSwgdmFsdWUubmV3VmFsdWUpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBwcm9wZXJ0eSBjaGFuZ2VzIHRoYXQgdGhlIGNoYW5nZSBzZXQgcmVwb3J0cyBmb3IgYSByZXNvdXJjZSB0aGF0IHRoZSB0ZW1wbGF0ZSBkaWZmIGFscmVhZHlcbiAgICogc3VyZmFjZWQsIGJ1dCB0aGF0IHRoZSB0ZW1wbGF0ZSBkaWZmIGRpZCBub3QgcGljayB1cCBvbiBpdHMgb3duLlxuICAgKlxuICAgKiBXaXRob3V0IHRoaXMsIGEgcmVzb3VyY2UgdGhhdCBoYXMgYW4gb3JkaW5hcnkgKHRleHR1YWwpIGNoYW5nZSB0byBvbmUgcHJvcGVydHkgd291bGQgaGlkZSBhXG4gICAqIHNlY29uZCBjaGFuZ2UgdG8gYSAqZGlmZmVyZW50KiBwcm9wZXJ0eSB0aGF0IGlzIG9ubHkgcmVzb2x2ZWQgYXQgZGVwbG95IHRpbWUgKGUuZy4gYSBwcm9wZXJ0eVxuICAgKiB3aG9zZSB2YWx1ZSBjb21lcyBmcm9tIGFuIFNTTSBwYXJhbWV0ZXIgb3IgYSBDbG91ZEZvcm1hdGlvbiBkeW5hbWljIHJlZmVyZW5jZSkuIFRoYXQgaGlkZGVuXG4gICAqIGNoYW5nZSBtaWdodCBldmVuIGJlIGEgcmVwbGFjZW1lbnQsIHNvIHNpbGVudGx5IGRyb3BwaW5nIGl0IGlzIGV4YWN0bHkgdGhlIGNsYXNzIG9mIGJ1ZyB0aGF0XG4gICAqIGlzc3VlICM2NDEgaXMgYWJvdXQgLSBqdXN0IG9uIGEgcmVzb3VyY2UgdGhhdCBoYXBwZW5zIHRvIGFsc28gaGF2ZSBhIHZpc2libGUgY2hhbmdlLlxuICAgKlxuICAgKiBUaGlzIGNvbXBsZW1lbnRzIGBhZGRDaGFuZ2VTZXRSZXNvdXJjZXNOb3RJblRlbXBsYXRlRGlmZmAsIHdoaWNoIGhhbmRsZXMgcmVzb3VyY2VzIHRoYXQgYXJlXG4gICAqIGVudGlyZWx5IGFic2VudCBmcm9tIHRoZSB0ZW1wbGF0ZSBkaWZmLlxuICAgKlxuICAgKiBAcGFyYW0gbG9naWNhbElkIC0gdGhlIGxvZ2ljYWwgSUQgb2YgdGhlIHJlc291cmNlIChhbHJlYWR5IHByZXNlbnQgaW4gdGhlIHRlbXBsYXRlIGRpZmYpXG4gICAqIEBwYXJhbSBjaGFuZ2UgLSB0aGUgcmVzb3VyY2UgZGlmZmVyZW5jZSB0byBhdWdtZW50IChtdXRhdGVkIGluIHBsYWNlKVxuICAgKi9cbiAgcHVibGljIGFkZENoYW5nZVNldFByb3BlcnRpZXNOb3RJblRlbXBsYXRlRGlmZihsb2dpY2FsSWQ6IHN0cmluZywgY2hhbmdlOiB0eXBlcy5SZXNvdXJjZURpZmZlcmVuY2UpIHtcbiAgICAvLyBTYW1lIGd1YXJkIGFzIHRoZSBpbXBhY3QtcmVmaW5lbWVudCBwYXRoOiB0aGUgY2hhbmdlIHNldCBkZXNjcmliZXMgdGhlIHBvc3QtdHJhbnNmb3JtXG4gICAgLy8gcmVzb3VyY2UgZm9yIFNBTSwgc28gaXRzIHByb3BlcnR5IGluZm9ybWF0aW9uIGRvZXMgbm90IGxpbmUgdXAgd2l0aCB0aGUgdGVtcGxhdGUuXG4gICAgLy8gYHJlc291cmNlVHlwZWAgZ2V0dGVyIHRocm93cyBpZiB0aGUgdHlwZSBjaGFuZ2VkLCBzbyBjaGVjayB0aGF0IGZpcnN0LlxuICAgIGlmICgoY2hhbmdlLnJlc291cmNlVHlwZUNoYW5nZWQgPT09IHRydWUpIHx8IGNoYW5nZS5yZXNvdXJjZVR5cGU/LmluY2x1ZGVzKCdBV1M6OlNlcnZlcmxlc3MnKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHByb3BlcnR5UmVwbGFjZW1lbnRNb2RlcyA9IHRoaXMuY2hhbmdlU2V0UmVzb3VyY2VzW2xvZ2ljYWxJZF0/LnByb3BlcnR5UmVwbGFjZW1lbnRNb2RlcztcbiAgICBpZiAoIXByb3BlcnR5UmVwbGFjZW1lbnRNb2Rlcykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc291cmNlQ2hhbmdlID0gdGhpcy5maW5kUmVzb3VyY2VDaGFuZ2UobG9naWNhbElkKTtcblxuICAgIGZvciAoY29uc3QgW3Byb3BlcnR5TmFtZSwgeyByZXBsYWNlbWVudE1vZGUgfV0gb2YgT2JqZWN0LmVudHJpZXMocHJvcGVydHlSZXBsYWNlbWVudE1vZGVzKSkge1xuICAgICAgLy8gUHJvcGVydGllcyB0aGUgdGVtcGxhdGUgZGlmZiBhbHJlYWR5IGZsYWdnZWQgYXJlIG93bmVkIGJ5IHRoZSBpbXBhY3QtcmVmaW5lbWVudCBwYXRoLlxuICAgICAgaWYgKHByb3BlcnR5TmFtZSBpbiBjaGFuZ2UucHJvcGVydHlVcGRhdGVzKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjaGFuZ2VJbXBhY3QgPSBjaGFuZ2VJbXBhY3RGb3JSZXBsYWNlbWVudE1vZGUocmVwbGFjZW1lbnRNb2RlKTtcbiAgICAgIGlmIChjaGFuZ2VJbXBhY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBUaGUgY2hhbmdlIHNldCBkb2VzIG5vdCBhY3R1YWxseSBjb25zaWRlciB0aGlzIGEgKG1lYW5pbmdmdWwpIGNoYW5nZS5cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgb2xkVmFsdWUsIG5ld1ZhbHVlIH0gPSB0aGlzLmNoYW5nZVNldFByb3BlcnR5VmFsdWVzKHJlc291cmNlQ2hhbmdlLCBwcm9wZXJ0eU5hbWUpO1xuICAgICAgY29uc3QgcHJvcGVydHlEaWZmID0gbmV3IHR5cGVzLlByb3BlcnR5RGlmZmVyZW5jZTxhbnk+KG9sZFZhbHVlLCBuZXdWYWx1ZSwgeyBjaGFuZ2VJbXBhY3QgfSk7XG4gICAgICBwcm9wZXJ0eURpZmYuaXNEaWZmZXJlbnQgPSB0cnVlO1xuICAgICAgY2hhbmdlLnNldFByb3BlcnR5Q2hhbmdlKHByb3BlcnR5TmFtZSwgcHJvcGVydHlEaWZmKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWRkcyByZXNvdXJjZXMgdG8gdGhlIHRlbXBsYXRlIGRpZmYgdGhhdCB0aGUgY2hhbmdlIHNldCByZXBvcnRzIGFzIGNoYW5naW5nLCBidXQgdGhhdCB0aGVcbiAgICogdGVtcGxhdGUgZGlmZiBkaWQgbm90IHN1cmZhY2Ugb24gaXRzIG93bi5cbiAgICpcbiAgICogVGhpcyBoYXBwZW5zIHdoZW4gdGhlIGxvY2FsIHRlbXBsYXRlIGlzIGJ5dGUtZm9yLWJ5dGUgaWRlbnRpY2FsIGJldHdlZW4gdGhlIGN1cnJlbnQgYW5kXG4gICAqIHRhcmdldCBzdGF0ZSwgeWV0IGEgdmFsdWUgdGhhdCBpcyBvbmx5IHJlc29sdmVkIGF0IGRlcGxveSB0aW1lIGNoYW5nZXMgLSBmb3IgZXhhbXBsZSBhblxuICAgKiBTU00gcGFyYW1ldGVyIHJlZmVyZW5jZWQgdGhyb3VnaCBgQVdTOjpTU006OlBhcmFtZXRlcjo6VmFsdWU8Li4uPmAgb3IgYSBDbG91ZEZvcm1hdGlvblxuICAgKiBkeW5hbWljIHJlZmVyZW5jZSAoYHt7cmVzb2x2ZTpzc206Li4ufX1gKS4gQ2xvdWRGb3JtYXRpb24gZGV0ZWN0cyB0aGVzZSBpbiB0aGUgY2hhbmdlIHNldFxuICAgKiBldmVuIHRob3VnaCBhIHB1cmUgdGVtcGxhdGUgZGlmZiBjYW5ub3QsIHNvIHdlIHN5bnRoZXNpemUgYSBgUmVzb3VyY2VEaWZmZXJlbmNlYCBmcm9tIHRoZVxuICAgKiBjaGFuZ2Ugc2V0J3MgYmVmb3JlL2FmdGVyIGRhdGEuXG4gICAqXG4gICAqIEBwYXJhbSByZXNvdXJjZURpZmZzIC0gdGhlIHJlc291cmNlIGRpZmZlcmVuY2VzIHRvIGFkZCB0byAobXV0YXRlZCBpbiBwbGFjZSlcbiAgICogQHBhcmFtIHJlc291cmNlc0luVGVtcGxhdGVEaWZmIC0gdGhlIGxvZ2ljYWwgSURzIHRoYXQgdGhlIHRlbXBsYXRlIGRpZmYgYWxyZWFkeSByZXBvcnRlZCBhc1xuICAgKiAgIGNoYW5nZWQsIGNhcHR1cmVkICpiZWZvcmUqIGFueSBjaGFuZ2Utc2V0IG92ZXJyaWRlcyB3ZXJlIGFwcGxpZWQuIFRob3NlIHJlc291cmNlcyBhcmVcbiAgICogICBvd25lZCBieSB0aGUgb3ZlcnJpZGUgcGF0aCBhbmQgYXJlIHNraXBwZWQgaGVyZSBzbyB3ZSBuZXZlciBjbG9iYmVyIG1vcmUgYWNjdXJhdGVcbiAgICogICB0ZW1wbGF0ZS1kZXJpdmVkIGluZm9ybWF0aW9uIHdpdGggY2hhbmdlLXNldC1vbmx5IGRhdGEuXG4gICAqL1xuICBwdWJsaWMgYWRkQ2hhbmdlU2V0UmVzb3VyY2VzTm90SW5UZW1wbGF0ZURpZmYoXG4gICAgcmVzb3VyY2VEaWZmczogdHlwZXMuRGlmZmVyZW5jZUNvbGxlY3Rpb248dHlwZXMuUmVzb3VyY2UsIHR5cGVzLlJlc291cmNlRGlmZmVyZW5jZT4sXG4gICAgcmVzb3VyY2VzSW5UZW1wbGF0ZURpZmY6IFNldDxzdHJpbmc+LFxuICApIHtcbiAgICBmb3IgKGNvbnN0IHJlc291cmNlQ2hhbmdlIG9mIHRoaXMuY2hhbmdlU2V0Py5DaGFuZ2VzID8/IFtdKSB7XG4gICAgICBjb25zdCByYyA9IHJlc291cmNlQ2hhbmdlLlJlc291cmNlQ2hhbmdlO1xuICAgICAgY29uc3QgbG9naWNhbElkID0gcmM/LkxvZ2ljYWxSZXNvdXJjZUlkO1xuICAgICAgaWYgKCFyYyB8fCAhbG9naWNhbElkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBBZGRpdGlvbnMsIHJlbW92YWxzIGFuZCBpbXBvcnRzIGFyZSBhbHJlYWR5IHJlZmxlY3RlZCBpbiB0aGUgdGVtcGxhdGUgZGlmZiAoYSBuZXcgb3JcbiAgICAgIC8vIGRlbGV0ZWQgcmVzb3VyY2Ugc2hvd3MgdXAgdGV4dHVhbGx5KSwgb3IgYXJlIGhhbmRsZWQgYnkgdGhlIGRlZGljYXRlZCBpbXBvcnQgcGF0aC4gV2VcbiAgICAgIC8vIG9ubHkgbmVlZCB0byBzeW50aGVzaXplIGNoYW5nZXMgZm9yIG1vZGlmaWNhdGlvbnMgdGhhdCBhcmUgaW52aXNpYmxlIHRvIGEgdGV4dHVhbCBkaWZmLlxuICAgICAgaWYgKHJjLkFjdGlvbiAhPT0gJ01vZGlmeScpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIFRoZSB0ZW1wbGF0ZSBkaWZmIGFscmVhZHkgcHJvZHVjZWQgYSBkaWZmZXJlbmNlIGZvciB0aGlzIHJlc291cmNlLCBzbyB0aGUgb3ZlcnJpZGUgcGF0aFxuICAgICAgLy8gaXMgcmVzcG9uc2libGUgZm9yIGl0LiBEb24ndCByZXBsYWNlIGl0IHdpdGggY2hhbmdlLXNldC1vbmx5IGRhdGEuXG4gICAgICBpZiAocmVzb3VyY2VzSW5UZW1wbGF0ZURpZmYuaGFzKGxvZ2ljYWxJZCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIENGTiBhcHBsaWVzIHRoZSBTQU0gdHJhbnNmb3JtIGJlZm9yZSBjcmVhdGluZyB0aGUgY2hhbmdlc2V0LCBzbyBjaGFuZ2VzZXQgZW50cmllcyBmb3JcbiAgICAgIC8vIFNBTSByZXNvdXJjZXMgZGVzY3JpYmUgdGhlIHRyYW5zZm9ybWVkIChlLmcuIExhbWJkYSkgcmVzb3VyY2UgYW5kIHdvbid0IGxpbmUgdXAgd2l0aCB0aGVcbiAgICAgIC8vIFNBTSByZXNvdXJjZSBpbiB0aGUgdGVtcGxhdGUuIFNraXAgdGhlbSB0byBhdm9pZCByZW5kZXJpbmcgYSBib2d1cyBkaWZmLlxuICAgICAgaWYgKHJjLlJlc291cmNlVHlwZT8uaW5jbHVkZXMoJ0FXUzo6U2VydmVybGVzcycpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZXNvdXJjZURpZmYgPSB0aGlzLnJlc291cmNlRGlmZmVyZW5jZUZyb21DaGFuZ2VTZXRSZXNvdXJjZShyYyk7XG4gICAgICBpZiAocmVzb3VyY2VEaWZmPy5pc0RpZmZlcmVudCkge1xuICAgICAgICByZXNvdXJjZURpZmZzLnNldChsb2dpY2FsSWQsIHJlc291cmNlRGlmZik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGEgYFJlc291cmNlRGlmZmVyZW5jZWAgcHVyZWx5IGZyb20gYSBjaGFuZ2Ugc2V0J3MgYFJlc291cmNlQ2hhbmdlYC5cbiAgICpcbiAgICogUHJlZmVycyB0aGUgcmljaCBgQmVmb3JlQ29udGV4dGAvYEFmdGVyQ29udGV4dGAgKHRoZSBmdWxsIHJlc291cmNlIGRlZmluaXRpb24gYmVmb3JlIGFuZFxuICAgKiBhZnRlciB0aGUgY2hhbmdlLCBpbmNsdWRlZCB3aGVuIHRoZSBjaGFuZ2Ugc2V0IGlzIGRlc2NyaWJlZCB3aXRoIGBJbmNsdWRlUHJvcGVydHlWYWx1ZXNgKSxcbiAgICogYW5kIGZhbGxzIGJhY2sgdG8gdGhlIHBlci1wcm9wZXJ0eSBgQmVmb3JlVmFsdWVgL2BBZnRlclZhbHVlYCBjYXJyaWVkIGluIHRoZSBjaGFuZ2UgZGV0YWlscy5cbiAgICpcbiAgICogQHJldHVybnMgdGhlIHN5bnRoZXNpemVkIGRpZmZlcmVuY2UsIG9yIGB1bmRlZmluZWRgIGlmIHRoZXJlIGlzIG5vdCBlbm91Z2ggaW5mb3JtYXRpb24gdG9cbiAgICogICBidWlsZCBhIG1lYW5pbmdmdWwgYmVmb3JlL2FmdGVyIGNvbXBhcmlzb24uXG4gICAqL1xuICBwcml2YXRlIHJlc291cmNlRGlmZmVyZW5jZUZyb21DaGFuZ2VTZXRSZXNvdXJjZShyYzogQ2hhbmdlU2V0UmVzb3VyY2VDaGFuZ2UpOiB0eXBlcy5SZXNvdXJjZURpZmZlcmVuY2UgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHJlc291cmNlVHlwZSA9IHJjLlJlc291cmNlVHlwZTtcblxuICAgIGxldCBvbGRSZXNvdXJjZTogdHlwZXMuUmVzb3VyY2UgfCB1bmRlZmluZWQ7XG4gICAgbGV0IG5ld1Jlc291cmNlOiB0eXBlcy5SZXNvdXJjZSB8IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IG9sZEZyb21Db250ZXh0ID0gdGhpcy5wYXJzZVJlc291cmNlQ29udGV4dChyYy5CZWZvcmVDb250ZXh0LCByZXNvdXJjZVR5cGUpO1xuICAgIGNvbnN0IG5ld0Zyb21Db250ZXh0ID0gdGhpcy5wYXJzZVJlc291cmNlQ29udGV4dChyYy5BZnRlckNvbnRleHQsIHJlc291cmNlVHlwZSk7XG4gICAgaWYgKG9sZEZyb21Db250ZXh0ICE9PSB1bmRlZmluZWQgJiYgbmV3RnJvbUNvbnRleHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb2xkUmVzb3VyY2UgPSBvbGRGcm9tQ29udGV4dDtcbiAgICAgIG5ld1Jlc291cmNlID0gbmV3RnJvbUNvbnRleHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRoZSBmdWxsIGJlZm9yZS9hZnRlciBjb250ZXh0IHdhcyBub3QgcmVxdWVzdGVkL3JldHVybmVkOyByZWNvbnN0cnVjdCB0aGUgcmVzb3VyY2VcbiAgICAgIC8vIGZyb20gdGhlIGluZGl2aWR1YWwgcHJvcGVydHkgY2hhbmdlcyBpbnN0ZWFkLlxuICAgICAgY29uc3QgZnJvbURldGFpbHMgPSB0aGlzLnJlc291cmNlc0Zyb21DaGFuZ2VEZXRhaWxzKHJjLCByZXNvdXJjZVR5cGUpO1xuICAgICAgb2xkUmVzb3VyY2UgPSBmcm9tRGV0YWlscy5vbGRSZXNvdXJjZTtcbiAgICAgIG5ld1Jlc291cmNlID0gZnJvbURldGFpbHMubmV3UmVzb3VyY2U7XG4gICAgfVxuXG4gICAgaWYgKG9sZFJlc291cmNlID09PSB1bmRlZmluZWQgfHwgbmV3UmVzb3VyY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCByZXNvdXJjZURpZmYgPSBkaWZmUmVzb3VyY2Uob2xkUmVzb3VyY2UsIG5ld1Jlc291cmNlLCByYy5Mb2dpY2FsUmVzb3VyY2VJZCk7XG5cbiAgICAvLyBSZWZpbmUgdGhlIGNoYW5nZSBpbXBhY3QgKHJlcGxhY2VtZW50IHZzLiB1cGRhdGUpIHVzaW5nIHRoZSBjaGFuZ2Ugc2V0LCBleGFjdGx5IGxpa2Ugd2UgZG9cbiAgICAvLyBmb3IgcmVzb3VyY2VzIHRoYXQgb3JpZ2luYXRlIGZyb20gdGhlIHRlbXBsYXRlIGRpZmYuXG4gICAgdGhpcy5vdmVycmlkZURpZmZSZXNvdXJjZUNoYW5nZUltcGFjdFdpdGhDaGFuZ2VTZXRDaGFuZ2VJbXBhY3QocmMuTG9naWNhbFJlc291cmNlSWQhLCByZXNvdXJjZURpZmYpO1xuXG4gICAgcmV0dXJuIHJlc291cmNlRGlmZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZSBhIGNoYW5nZSBzZXQgYEJlZm9yZUNvbnRleHRgL2BBZnRlckNvbnRleHRgIGludG8gYSByZXNvdXJjZSBvYmplY3QuXG4gICAqXG4gICAqIFRoZSBjb250ZXh0IGlzIHRoZSByZXNvdXJjZSdzIGRlZmluaXRpb24gKFByb3BlcnRpZXMsIE1ldGFkYXRhLCBldGMuKSBidXQgZG9lcyAqbm90KiBpbmNsdWRlXG4gICAqIHRoZSByZXNvdXJjZSBgVHlwZWAsIHNvIHdlIHNwbGljZSBpdCBiYWNrIGluICh1c2luZyB0aGUgY2hhbmdlIHNldCdzIHJlcG9ydGVkIHR5cGUpIHRvIGFsbG93XG4gICAqIHRoZSBkaWZmIG1hY2hpbmVyeSB0byBjb21wYXJlIGxpa2UtZm9yLWxpa2UgYW5kIGxvb2sgdXAgcmVwbGFjZW1lbnQgaW5mb3JtYXRpb24uXG4gICAqL1xuICBwcml2YXRlIHBhcnNlUmVzb3VyY2VDb250ZXh0KGNvbnRleHQ6IHN0cmluZyB8IG9iamVjdCB8IHVuZGVmaW5lZCwgcmVzb3VyY2VUeXBlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiB0eXBlcy5SZXNvdXJjZSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKGNvbnRleHQgPT09IHVuZGVmaW5lZCB8fCBjb250ZXh0ID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGxldCBwYXJzZWQ6IGFueTtcbiAgICBpZiAodHlwZW9mIGNvbnRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBwYXJzZWQgPSBKU09OLnBhcnNlKGNvbnRleHQpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhcnNlZCA9IGNvbnRleHQ7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBwYXJzZWQgIT09ICdvYmplY3QnIHx8IHBhcnNlZCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgVHlwZTogcmVzb3VyY2VUeXBlID8/IFRlbXBsYXRlQW5kQ2hhbmdlU2V0RGlmZk1lcmdlci5VTktOT1dOX1JFU09VUkNFX1RZUEUsXG4gICAgICAuLi5wYXJzZWQsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvbnN0cnVjdCAocGFydGlhbCkgYmVmb3JlL2FmdGVyIHJlc291cmNlIGRlZmluaXRpb25zIGZyb20gdGhlIHBlci1wcm9wZXJ0eSBjaGFuZ2UgZGV0YWlscy5cbiAgICpcbiAgICogVGhpcyBpcyB0aGUgZmFsbGJhY2sgdXNlZCB3aGVuIGBCZWZvcmVDb250ZXh0YC9gQWZ0ZXJDb250ZXh0YCBhcmUgbm90IGF2YWlsYWJsZSAoZm9yIGV4YW1wbGVcbiAgICogd2hlbiB0aGUgY2hhbmdlIHNldCB3YXMgZGVzY3JpYmVkIHdpdGhvdXQgYEluY2x1ZGVQcm9wZXJ0eVZhbHVlc2ApLiBPbmx5IHByb3BlcnRpZXMgdGhhdFxuICAgKiBjYXJyeSBhIGJlZm9yZSBvciBhZnRlciB2YWx1ZSBjb250cmlidXRlIHRvIHRoZSByZWNvbnN0cnVjdGVkIHJlc291cmNlcy5cbiAgICovXG4gIHByaXZhdGUgcmVzb3VyY2VzRnJvbUNoYW5nZURldGFpbHMoXG4gICAgcmM6IENoYW5nZVNldFJlc291cmNlQ2hhbmdlLFxuICAgIHJlc291cmNlVHlwZTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICApOiB7IG9sZFJlc291cmNlOiB0eXBlcy5SZXNvdXJjZSB8IHVuZGVmaW5lZDsgbmV3UmVzb3VyY2U6IHR5cGVzLlJlc291cmNlIHwgdW5kZWZpbmVkIH0ge1xuICAgIGNvbnN0IG9sZFByb3BlcnRpZXM6IHR5cGVzLlByb3BlcnR5TWFwID0ge307XG4gICAgY29uc3QgbmV3UHJvcGVydGllczogdHlwZXMuUHJvcGVydHlNYXAgPSB7fTtcbiAgICBsZXQgaGFzRGF0YSA9IGZhbHNlO1xuXG4gICAgZm9yIChjb25zdCBkZXRhaWwgb2YgcmMuRGV0YWlscyA/PyBbXSkge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZGV0YWlsLlRhcmdldDtcbiAgICAgIGlmICh0YXJnZXQ/LkF0dHJpYnV0ZSAhPT0gJ1Byb3BlcnRpZXMnIHx8ICF0YXJnZXQuTmFtZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICh0YXJnZXQuQmVmb3JlVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBvbGRQcm9wZXJ0aWVzW3RhcmdldC5OYW1lXSA9IHRyeUpzb25QYXJzZSh0YXJnZXQuQmVmb3JlVmFsdWUpO1xuICAgICAgICBoYXNEYXRhID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmICh0YXJnZXQuQWZ0ZXJWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG5ld1Byb3BlcnRpZXNbdGFyZ2V0Lk5hbWVdID0gdHJ5SnNvblBhcnNlKHRhcmdldC5BZnRlclZhbHVlKTtcbiAgICAgICAgaGFzRGF0YSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFoYXNEYXRhKSB7XG4gICAgICByZXR1cm4geyBvbGRSZXNvdXJjZTogdW5kZWZpbmVkLCBuZXdSZXNvdXJjZTogdW5kZWZpbmVkIH07XG4gICAgfVxuXG4gICAgY29uc3QgdHlwZSA9IHJlc291cmNlVHlwZSA/PyBUZW1wbGF0ZUFuZENoYW5nZVNldERpZmZNZXJnZXIuVU5LTk9XTl9SRVNPVVJDRV9UWVBFO1xuICAgIHJldHVybiB7XG4gICAgICBvbGRSZXNvdXJjZTogeyBUeXBlOiB0eXBlLCBQcm9wZXJ0aWVzOiBvbGRQcm9wZXJ0aWVzIH0sXG4gICAgICBuZXdSZXNvdXJjZTogeyBUeXBlOiB0eXBlLCBQcm9wZXJ0aWVzOiBuZXdQcm9wZXJ0aWVzIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIHRoZSByYXcgYFJlc291cmNlQ2hhbmdlYCBmb3IgYSBnaXZlbiBsb2dpY2FsIElEIGluIHRoZSBjaGFuZ2Ugc2V0LlxuICAgKi9cbiAgcHJpdmF0ZSBmaW5kUmVzb3VyY2VDaGFuZ2UobG9naWNhbElkOiBzdHJpbmcpOiBDaGFuZ2VTZXRSZXNvdXJjZUNoYW5nZSB8IHVuZGVmaW5lZCB7XG4gICAgZm9yIChjb25zdCByZXNvdXJjZUNoYW5nZSBvZiB0aGlzLmNoYW5nZVNldD8uQ2hhbmdlcyA/PyBbXSkge1xuICAgICAgaWYgKHJlc291cmNlQ2hhbmdlLlJlc291cmNlQ2hhbmdlPy5Mb2dpY2FsUmVzb3VyY2VJZCA9PT0gbG9naWNhbElkKSB7XG4gICAgICAgIHJldHVybiByZXNvdXJjZUNoYW5nZS5SZXNvdXJjZUNoYW5nZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgdGhlIGJlZm9yZS9hZnRlciB2YWx1ZSBvZiBhIHNpbmdsZSBwcm9wZXJ0eSBmcm9tIHRoZSBjaGFuZ2Ugc2V0LlxuICAgKlxuICAgKiBQcmVmZXJzIHRoZSBwZXItcHJvcGVydHkgYEJlZm9yZVZhbHVlYC9gQWZ0ZXJWYWx1ZWAgY2FycmllZCBpbiB0aGUgY2hhbmdlIGRldGFpbHMsIHRoZW4gdGhlXG4gICAqIGBCZWZvcmVDb250ZXh0YC9gQWZ0ZXJDb250ZXh0YCByZXNvdXJjZSBzbmFwc2hvdHMsIGFuZCBmaW5hbGx5IGZhbGxzIGJhY2sgdG8gZW1wdHktb2JqZWN0XG4gICAqIHBsYWNlaG9sZGVycyBzbyB0aGUgcHJvcGVydHkgc3RpbGwgcmVuZGVycyBhcyBhIGNoYW5nZSAod2l0aCB0aGUgaW1wYWN0IGRlcml2ZWQgZnJvbSB0aGVcbiAgICogY2hhbmdlIHNldCkgZXZlbiB3aGVuIG5vIGNvbmNyZXRlIHZhbHVlcyB3ZXJlIHJldHVybmVkLlxuICAgKi9cbiAgcHJpdmF0ZSBjaGFuZ2VTZXRQcm9wZXJ0eVZhbHVlcyhcbiAgICByZXNvdXJjZUNoYW5nZTogQ2hhbmdlU2V0UmVzb3VyY2VDaGFuZ2UgfCB1bmRlZmluZWQsXG4gICAgcHJvcGVydHlOYW1lOiBzdHJpbmcsXG4gICk6IHsgb2xkVmFsdWU6IGFueTsgbmV3VmFsdWU6IGFueSB9IHtcbiAgICBsZXQgb2xkVmFsdWU6IGFueTtcbiAgICBsZXQgbmV3VmFsdWU6IGFueTtcblxuICAgIGZvciAoY29uc3QgZGV0YWlsIG9mIHJlc291cmNlQ2hhbmdlPy5EZXRhaWxzID8/IFtdKSB7XG4gICAgICBjb25zdCB0YXJnZXQgPSBkZXRhaWwuVGFyZ2V0O1xuICAgICAgaWYgKHRhcmdldD8uQXR0cmlidXRlID09PSAnUHJvcGVydGllcycgJiYgdGFyZ2V0Lk5hbWUgPT09IHByb3BlcnR5TmFtZSkge1xuICAgICAgICBpZiAodGFyZ2V0LkJlZm9yZVZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBvbGRWYWx1ZSA9IHRyeUpzb25QYXJzZSh0YXJnZXQuQmVmb3JlVmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0YXJnZXQuQWZ0ZXJWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbmV3VmFsdWUgPSB0cnlKc29uUGFyc2UodGFyZ2V0LkFmdGVyVmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9sZFZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG9sZFZhbHVlID0gY29udGV4dFByb3BlcnRpZXMocmVzb3VyY2VDaGFuZ2U/LkJlZm9yZUNvbnRleHQpPy5bcHJvcGVydHlOYW1lXTtcbiAgICB9XG4gICAgaWYgKG5ld1ZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG5ld1ZhbHVlID0gY29udGV4dFByb3BlcnRpZXMocmVzb3VyY2VDaGFuZ2U/LkFmdGVyQ29udGV4dCk/Lltwcm9wZXJ0eU5hbWVdO1xuICAgIH1cblxuICAgIC8vIFByb3BlcnR5RGlmZmVyZW5jZSByZXF1aXJlcyBhdCBsZWFzdCBvbmUgZGVmaW5lZCBzaWRlOyB1c2UgYSBwbGFjZWhvbGRlciBvdGhlcndpc2UuXG4gICAgcmV0dXJuIHtcbiAgICAgIG9sZFZhbHVlOiBvbGRWYWx1ZSAhPT0gdW5kZWZpbmVkID8gb2xkVmFsdWUgOiB7fSxcbiAgICAgIG5ld1ZhbHVlOiBuZXdWYWx1ZSAhPT0gdW5kZWZpbmVkID8gbmV3VmFsdWUgOiB7fSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIGFkZEltcG9ydEluZm9ybWF0aW9uRnJvbUNoYW5nZXNldChyZXNvdXJjZURpZmZzOiB0eXBlcy5EaWZmZXJlbmNlQ29sbGVjdGlvbjx0eXBlcy5SZXNvdXJjZSwgdHlwZXMuUmVzb3VyY2VEaWZmZXJlbmNlPikge1xuICAgIGNvbnN0IGltcG9ydHMgPSB0aGlzLmZpbmRSZXNvdXJjZUltcG9ydHMoKTtcbiAgICByZXNvdXJjZURpZmZzLmZvckVhY2hEaWZmZXJlbmNlKChsb2dpY2FsSWQ6IHN0cmluZywgY2hhbmdlOiB0eXBlcy5SZXNvdXJjZURpZmZlcmVuY2UpID0+IHtcbiAgICAgIGlmIChpbXBvcnRzLmluY2x1ZGVzKGxvZ2ljYWxJZCkpIHtcbiAgICAgICAgY2hhbmdlLmlzSW1wb3J0ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBmaW5kUmVzb3VyY2VJbXBvcnRzKCk6IChzdHJpbmcgfCB1bmRlZmluZWQpW10ge1xuICAgIGNvbnN0IGltcG9ydGVkUmVzb3VyY2VMb2dpY2FsSWRzID0gW107XG4gICAgZm9yIChjb25zdCByZXNvdXJjZUNoYW5nZSBvZiB0aGlzLmNoYW5nZVNldD8uQ2hhbmdlcyA/PyBbXSkge1xuICAgICAgaWYgKHJlc291cmNlQ2hhbmdlLlJlc291cmNlQ2hhbmdlPy5BY3Rpb24gPT09ICdJbXBvcnQnKSB7XG4gICAgICAgIGltcG9ydGVkUmVzb3VyY2VMb2dpY2FsSWRzLnB1c2gocmVzb3VyY2VDaGFuZ2UuUmVzb3VyY2VDaGFuZ2UuTG9naWNhbFJlc291cmNlSWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBpbXBvcnRlZFJlc291cmNlTG9naWNhbElkcztcbiAgfVxufVxuXG4vKipcbiAqIFBhcnNlIGEgY2hhbmdlIHNldCBwcm9wZXJ0eSB2YWx1ZSBhcyBKU09OLCBmYWxsaW5nIGJhY2sgdG8gdGhlIHJhdyB2YWx1ZS5cbiAqXG4gKiBDaGFuZ2Ugc2V0IHByb3BlcnR5IHZhbHVlcyAoZS5nLiBgQmVmb3JlVmFsdWVgL2BBZnRlclZhbHVlYCkgYXJlIGFsd2F5cyBzdHJpbmdzLiBTb21lIG9mIHRoZW1cbiAqIGFyZSBzZXJpYWxpemVkIEpTT04gKHN1Y2ggYXMgYW4gSUFNIGBQb2xpY3lEb2N1bWVudGApLCB3aGlsZSBvdGhlcnMgYXJlIHBsYWluIHNjYWxhcnMuIFBhcnNpbmdcbiAqIGxldHMgdXMgY29tcGFyZSBzdHJ1Y3R1cmVkIHZhbHVlcyBzdHJ1Y3R1cmFsbHk7IGlmIHBhcnNpbmcgZmFpbHMgd2Uga2VlcCB0aGUgb3JpZ2luYWwgc3RyaW5nLlxuICovXG5mdW5jdGlvbiB0cnlKc29uUGFyc2UodmFsdWU6IHN0cmluZyk6IGFueSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UodmFsdWUpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBNYXAgYSBjaGFuZ2Ugc2V0IHJlcGxhY2VtZW50IG1vZGUgdG8gdGhlIGNvcnJlc3BvbmRpbmcgZGlmZiBgUmVzb3VyY2VJbXBhY3RgLlxuICpcbiAqIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiB0aGUgY2hhbmdlIHNldCBkb2VzIG5vdCBjb25zaWRlciB0aGUgcHJvcGVydHkgYSAobWVhbmluZ2Z1bCkgY2hhbmdlLlxuICovXG5mdW5jdGlvbiBjaGFuZ2VJbXBhY3RGb3JSZXBsYWNlbWVudE1vZGUocmVwbGFjZW1lbnRNb2RlOiB0eXBlcy5SZXBsYWNlbWVudE1vZGVzIHwgdW5kZWZpbmVkKTogdHlwZXMuUmVzb3VyY2VJbXBhY3QgfCB1bmRlZmluZWQge1xuICBzd2l0Y2ggKHJlcGxhY2VtZW50TW9kZSkge1xuICAgIGNhc2UgJ0Fsd2F5cyc6XG4gICAgICByZXR1cm4gdHlwZXMuUmVzb3VyY2VJbXBhY3QuV0lMTF9SRVBMQUNFO1xuICAgIGNhc2UgJ05ldmVyJzpcbiAgICAgIHJldHVybiB0eXBlcy5SZXNvdXJjZUltcGFjdC5XSUxMX1VQREFURTtcbiAgICBjYXNlICdDb25kaXRpb25hbGx5JzpcbiAgICAgIHJldHVybiB0eXBlcy5SZXNvdXJjZUltcGFjdC5NQVlfUkVQTEFDRTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIFBhcnNlIHRoZSBgUHJvcGVydGllc2AgYmxvY2sgb3V0IG9mIGEgY2hhbmdlIHNldCBgQmVmb3JlQ29udGV4dGAvYEFmdGVyQ29udGV4dGAgc25hcHNob3QuXG4gKi9cbmZ1bmN0aW9uIGNvbnRleHRQcm9wZXJ0aWVzKGNvbnRleHQ6IHN0cmluZyB8IG9iamVjdCB8IHVuZGVmaW5lZCk6IHsgW25hbWU6IHN0cmluZ106IGFueSB9IHwgdW5kZWZpbmVkIHtcbiAgaWYgKGNvbnRleHQgPT09IHVuZGVmaW5lZCB8fCBjb250ZXh0ID09PSBudWxsKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBsZXQgcGFyc2VkOiBhbnk7XG4gIGlmICh0eXBlb2YgY29udGV4dCA9PT0gJ3N0cmluZycpIHtcbiAgICB0cnkge1xuICAgICAgcGFyc2VkID0gSlNPTi5wYXJzZShjb250ZXh0KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHBhcnNlZCA9IGNvbnRleHQ7XG4gIH1cbiAgcmV0dXJuIHBhcnNlZCAmJiB0eXBlb2YgcGFyc2VkID09PSAnb2JqZWN0JyA/IHBhcnNlZC5Qcm9wZXJ0aWVzIDogdW5kZWZpbmVkO1xufVxuIl19
|
package/lib/diff/types.d.ts
CHANGED
|
@@ -188,6 +188,17 @@ export declare class DifferenceCollection<V, T extends IDifference<V>> {
|
|
|
188
188
|
get differenceCount(): number;
|
|
189
189
|
get(logicalId: string): T;
|
|
190
190
|
remove(logicalId: string): void;
|
|
191
|
+
/**
|
|
192
|
+
* Whether a difference (changed or not) is tracked for the given logical ID.
|
|
193
|
+
*
|
|
194
|
+
* Note this is different from `logicalIds`, which only returns IDs that have
|
|
195
|
+
* an actual change. A logical ID may be present here with a "no-op" difference.
|
|
196
|
+
*/
|
|
197
|
+
has(logicalId: string): boolean;
|
|
198
|
+
/**
|
|
199
|
+
* Set (or replace) the difference tracked for the given logical ID.
|
|
200
|
+
*/
|
|
201
|
+
set(logicalId: string, diff: T): void;
|
|
191
202
|
get logicalIds(): string[];
|
|
192
203
|
/**
|
|
193
204
|
* Returns a new TemplateDiff which only contains changes for which `predicate`
|