@aws-cdk/cloudformation-diff 2.187.0 → 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.
@@ -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 types = require("../diff/types");
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
- // If we somehow cannot find the resourceType, then we'll mark it as UNKNOWN, so that can be seen in the diff.
121
- TemplateAndChangeSetDiffMerger.UNKNOWN_RESOURCE_TYPE = 'UNKNOWN_RESOURCE_TYPE';
122
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcGxhdGUtYW5kLWNoYW5nZXNldC1kaWZmLW1lcmdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlbXBsYXRlLWFuZC1jaGFuZ2VzZXQtZGlmZi1tZXJnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0EsdUNBQXVDO0FBc0J2Qzs7R0FFRztBQUNILE1BQWEsOEJBQThCO0lBQ2xDLE1BQU0sQ0FBQyxpQ0FBaUMsQ0FBQyxjQUE2QztRQUMzRixJQUFJLGNBQWMsQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDNUQsK0ZBQStGO1lBQy9GLE9BQU8sZUFBZSxDQUFDO1FBQ3pCLENBQUM7UUFFRCxJQUFJLGNBQWMsQ0FBQyxNQUFNLENBQUMsa0JBQWtCLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDMUQsUUFBUSxjQUFjLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ2xDLEtBQUssUUFBUTtvQkFDWCxPQUFPLFFBQVEsQ0FBQztnQkFDbEIsS0FBSyxTQUFTO29CQUNaLDhFQUE4RTtvQkFDOUUsK0dBQStHO29CQUMvRyxPQUFPLGVBQWUsQ0FBQztZQUMzQixDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sY0FBYyxDQUFDLE1BQU0sQ0FBQyxrQkFBNEMsQ0FBQztJQUM1RSxDQUFDO0lBUUQsWUFBWSxLQUEwQztRQUNwRCxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFDakMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxrQkFBa0IsSUFBSSxJQUFJLENBQUMsa0RBQWtELENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2hJLENBQUM7SUFFRDs7T0FFRztJQUNLLGtEQUFrRCxDQUFDLFNBQWtDO1FBQzNGLE1BQU0sa0JBQWtCLEdBQTZCLEVBQUUsQ0FBQztRQUN4RCxLQUFLLE1BQU0sY0FBYyxJQUFJLFNBQVMsQ0FBQyxPQUFPLElBQUksRUFBRSxFQUFFLENB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QUFFLENBQUM7b0JBQ2IsS0FBSyxVQUFVO3dCQUNiLHdGQUF3Rjt3QkFDeEYsTUFBTSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFTLEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7d0JBQ2hHLE1BQU07Z0JBQ1YsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxpQ0FBaUMsQ0FBQyxhQUFtRjtRQUMxSCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUMzQyxhQUFhLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxTQUFpQixFQUFFLE1BQWdDLEVBQUUsRUFBRTtZQUN0RixJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFDaEMsTUFBTSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7WUFDekIsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLG1CQUFtQjtRQUN4QixNQUFNLDBCQUEwQixHQUFHLEVBQUUsQ0FBQztRQUN0QyxLQUFLLE1BQU0sY0FBYyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQzNELElBQUksY0FBYyxDQUFDLGNBQWMsRUFBRSxNQUFNLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ3ZELDBCQUEwQixDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDbkYsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLDBCQUEwQixDQUFDO0lBQ3BDLENBQUM7O0FBOUhILHdFQStIQztBQTFHQyw4R0FBOEc7QUFDL0Ysb0RBQXFCLEdBQUcsdUJBQXVCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGUgU0RLIGlzIG9ubHkgdXNlZCB0byByZWZlcmVuY2UgYERlc2NyaWJlQ2hhbmdlU2V0T3V0cHV0YCwgc28gdGhlIFNESyBpcyBhZGRlZCBhcyBhIGRldkRlcGVuZGVuY3kuXG4vLyBUaGUgU0RLIHNob3VsZCBub3QgbWFrZSBuZXR3b3JrIGNhbGxzIGhlcmVcbmltcG9ydCB0eXBlIHsgRGVzY3JpYmVDaGFuZ2VTZXRPdXRwdXQgYXMgRGVzY3JpYmVDaGFuZ2VTZXQsIFJlc291cmNlQ2hhbmdlRGV0YWlsIGFzIFJDRCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1jbG91ZGZvcm1hdGlvbic7XG5pbXBvcnQgKiBhcyB0eXBlcyBmcm9tICcuLi9kaWZmL3R5cGVzJztcblxuZXhwb3J0IHR5cGUgRGVzY3JpYmVDaGFuZ2VTZXRPdXRwdXQgPSBEZXNjcmliZUNoYW5nZVNldDtcbnR5cGUgQ2hhbmdlU2V0UmVzb3VyY2VDaGFuZ2VEZXRhaWwgPSBSQ0Q7XG5cbmludGVyZmFjZSBUZW1wbGF0ZUFuZENoYW5nZVNldERpZmZNZXJnZXJPcHRpb25zIHtcbiAgLypcbiAgICogT25seSBzcGVjaWZpYWJsZSBmb3IgdGVzdGluZy4gT3RoZXJ3aXNlLCB0aGlzIGlzIHRoZSBkYXRhc3RydWN0dXJlIHRoYXQgdGhlIGNoYW5nZVNldCBpcyBjb252ZXJ0ZWQgaW50byBzb1xuICAgKiB0aGF0IHdlIG9ubHkgcGF5IGF0dGVudGlvbiB0byB0aGUgc3Vic2V0IG9mIGNoYW5nZVNldCBwcm9wZXJ0aWVzIHRoYXQgYXJlIHJlbGV2YW50IGZvciBjb21wdXRpbmcgdGhlIGRpZmYuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGhlIGNoYW5nZVNldCBpcyBjb252ZXJ0ZWQgaW50byB0aGlzIGRhdGFzdHJ1Y3R1cmUuXG4gICovXG4gIHJlYWRvbmx5IGNoYW5nZVNldFJlc291cmNlcz86IHR5cGVzLkNoYW5nZVNldFJlc291cmNlcztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZW1wbGF0ZUFuZENoYW5nZVNldERpZmZNZXJnZXJQcm9wcyBleHRlbmRzIFRlbXBsYXRlQW5kQ2hhbmdlU2V0RGlmZk1lcmdlck9wdGlvbnMge1xuICAvKlxuICAgKiBUaGUgY2hhbmdlc2V0IHRoYXQgd2lsbCBiZSByZWFkIGFuZCBtZXJnZWQgaW50byB0aGUgdGVtcGxhdGUgZGlmZi5cbiAgKi9cbiAgcmVhZG9ubHkgY2hhbmdlU2V0OiBEZXNjcmliZUNoYW5nZVNldE91dHB1dDtcbn1cblxuLyoqXG4gKiBUaGUgcHVycG9zZSBvZiB0aGlzIGNsYXNzIGlzIHRvIGluY2x1ZGUgZGlmZmVyZW5jZXMgZnJvbSB0aGUgQ2hhbmdlU2V0IHRvIGRpZmZlcmVuY2VzIGluIHRoZSBUZW1wbGF0ZURpZmYuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZW1wbGF0ZUFuZENoYW5nZVNldERpZmZNZXJnZXIge1xuICBwdWJsaWMgc3RhdGljIGRldGVybWluZUNoYW5nZVNldFJlcGxhY2VtZW50TW9kZShwcm9wZXJ0eUNoYW5nZTogQ2hhbmdlU2V0UmVzb3VyY2VDaGFuZ2VEZXRhaWwpOiB0eXBlcy5SZXBsYWNlbWVudE1vZGVzIHtcbiAgICBpZiAocHJvcGVydHlDaGFuZ2UuVGFyZ2V0Py5SZXF1aXJlc1JlY3JlYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gV2UgY2FuJ3QgZGV0ZXJtaW5lIGlmIHRoZSByZXNvdXJjZSB3aWxsIGJlIHJlcGxhY2VkIG9yIG5vdC4gVGhhdCdzIHdoYXQgY29uZGl0aW9uYWxseSBtZWFucy5cbiAgICAgIHJldHVybiAnQ29uZGl0aW9uYWxseSc7XG4gICAgfVxuXG4gICAgaWYgKHByb3BlcnR5Q2hhbmdlLlRhcmdldC5SZXF1aXJlc1JlY3JlYXRpb24gPT09ICdBbHdheXMnKSB7XG4gICAgICBzd2l0Y2ggKHByb3BlcnR5Q2hhbmdlLkV2YWx1YXRpb24pIHtcbiAgICAgICAgY2FzZSAnU3RhdGljJzpcbiAgICAgICAgICByZXR1cm4gJ0Fsd2F5cyc7XG4gICAgICAgIGNhc2UgJ0R5bmFtaWMnOlxuICAgICAgICAgIC8vIElmIEV2YWx1YXRpb24gaXMgJ0R5bmFtaWMnLCB0aGVuIHRoaXMgbWF5IGNhdXNlIHJlcGxhY2VtZW50LCBvciBpdCBtYXkgbm90LlxuICAgICAgICAgIC8vIHNlZSAnUmVwbGFjZW1lbnQnOiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmVzb3VyY2VDaGFuZ2UuaHRtbFxuICAgICAgICAgIHJldHVybiAnQ29uZGl0aW9uYWxseSc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb3BlcnR5Q2hhbmdlLlRhcmdldC5SZXF1aXJlc1JlY3JlYXRpb24gYXMgdHlwZXMuUmVwbGFjZW1lbnRNb2RlcztcbiAgfVxuXG4gIC8vIElmIHdlIHNvbWVob3cgY2Fubm90IGZpbmQgdGhlIHJlc291cmNlVHlwZSwgdGhlbiB3ZSdsbCBtYXJrIGl0IGFzIFVOS05PV04sIHNvIHRoYXQgY2FuIGJlIHNlZW4gaW4gdGhlIGRpZmYuXG4gIHByaXZhdGUgc3RhdGljIFVOS05PV05fUkVTT1VSQ0VfVFlQRSA9ICdVTktOT1dOX1JFU09VUkNFX1RZUEUnO1xuXG4gIHB1YmxpYyBjaGFuZ2VTZXQ6IERlc2NyaWJlQ2hhbmdlU2V0T3V0cHV0IHwgdW5kZWZpbmVkO1xuICBwdWJsaWMgY2hhbmdlU2V0UmVzb3VyY2VzOiB0eXBlcy5DaGFuZ2VTZXRSZXNvdXJjZXM7XG5cbiAgY29uc3RydWN0b3IocHJvcHM6IFRlbXBsYXRlQW5kQ2hhbmdlU2V0RGlmZk1lcmdlclByb3BzKSB7XG4gICAgdGhpcy5jaGFuZ2VTZXQgPSBwcm9wcy5jaGFuZ2VTZXQ7XG4gICAgdGhpcy5jaGFuZ2VTZXRSZXNvdXJjZXMgPSBwcm9wcy5jaGFuZ2VTZXRSZXNvdXJjZXMgPz8gdGhpcy5jb252ZXJ0RGVzY3JpYmVDaGFuZ2VTZXRPdXRwdXRUb0NoYW5nZVNldFJlc291cmNlcyh0aGlzLmNoYW5nZVNldCk7XG4gIH1cblxuICAvKipcbiAgICogUmVhZCByZXNvdXJjZXMgZnJvbSB0aGUgY2hhbmdlU2V0LCBleHRyYWN0aW5nIGluZm9ybWF0aW9uIGludG8gQ2hhbmdlU2V0UmVzb3VyY2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBjb252ZXJ0RGVzY3JpYmVDaGFuZ2VTZXRPdXRwdXRUb0NoYW5nZVNldFJlc291cmNlcyhjaGFuZ2VTZXQ6IERlc2NyaWJlQ2hhbmdlU2V0T3V0cHV0KTogdHlwZXMuQ2hhbmdlU2V0UmVzb3VyY2VzIHtcbiAgICBjb25zdCBjaGFuZ2VTZXRSZXNvdXJjZXM6IHR5cGVzLkNoYW5nZVNldFJlc291cmNlcyA9IHt9O1xuICAgIGZvciAoY29uc3QgcmVzb3VyY2VDaGFuZ2Ugb2YgY2hhbmdlU2V0LkNoYW5nZXMgPz8gW10pIHtcbiAgICAgIGlmIChyZXNvdXJjZUNoYW5nZS5SZXNvdXJjZUNoYW5nZT8uTG9naWNhbFJlc291cmNlSWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250aW51ZTsgLy8gQmVpbmcgZGVmZW5zaXZlLCBoZXJlLlxuICAgICAgfVxuXG4gICAgICBjb25zdCBwcm9wZXJ0eVJlcGxhY2VtZW50TW9kZXM6IHR5cGVzLlByb3BlcnR5UmVwbGFjZW1lbnRNb2RlTWFwID0ge307XG4gICAgICBmb3IgKGNvbnN0IHByb3BlcnR5Q2hhbmdlIG9mIHJlc291cmNlQ2hhbmdlLlJlc291cmNlQ2hhbmdlLkRldGFpbHMgPz8gW10pIHsgLy8gRGV0YWlscyBpcyBvbmx5IGluY2x1ZGVkIGlmIHJlc291cmNlQ2hhbmdlLkFjdGlvbiA9PT0gJ01vZGlmeSdcbiAgICAgICAgaWYgKHByb3BlcnR5Q2hhbmdlLlRhcmdldD8uQXR0cmlidXRlID09PSAnUHJvcGVydGllcycgJiYgcHJvcGVydHlDaGFuZ2UuVGFyZ2V0Lk5hbWUpIHtcbiAgICAgICAgICBwcm9wZXJ0eVJlcGxhY2VtZW50TW9kZXNbcHJvcGVydHlDaGFuZ2UuVGFyZ2V0Lk5hbWVdID0ge1xuICAgICAgICAgICAgcmVwbGFjZW1lbnRNb2RlOiBUZW1wbGF0ZUFuZENoYW5nZVNldERpZmZNZXJnZXIuZGV0ZXJtaW5lQ2hhbmdlU2V0UmVwbGFjZW1lbnRNb2RlKHByb3BlcnR5Q2hhbmdlKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNoYW5nZVNldFJlc291cmNlc1tyZXNvdXJjZUNoYW5nZS5SZXNvdXJjZUNoYW5nZS5Mb2dpY2FsUmVzb3VyY2VJZF0gPSB7XG4gICAgICAgIHJlc291cmNlV2FzUmVwbGFjZWQ6IHJlc291cmNlQ2hhbmdlLlJlc291cmNlQ2hhbmdlLlJlcGxhY2VtZW50ID09PSAnVHJ1ZScsXG4gICAgICAgIHJlc291cmNlVHlwZTogcmVzb3VyY2VDaGFuZ2UuUmVzb3VyY2VDaGFuZ2UuUmVzb3VyY2VUeXBlID8/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
@@ -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`